[macruby-changes] [3534] MacRuby/branches/icu

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 15 16:56:50 PST 2010


Revision: 3534
          http://trac.macosforge.org/projects/ruby/changeset/3534
Author:   lsansonetti at apple.com
Date:     2010-02-15 16:56:49 -0800 (Mon, 15 Feb 2010)
Log Message:
-----------
import vincent's work

Modified Paths:
--------------
    MacRuby/branches/icu/encoding.c
    MacRuby/branches/icu/rakelib/builder/builder.rb
    MacRuby/branches/icu/rakelib/builder/options.rb
    MacRuby/branches/icu/string.c

Added Paths:
-----------
    MacRuby/branches/icu/encoding.h
    MacRuby/branches/icu/ucnv.c
    MacRuby/branches/icu/unicode/
    MacRuby/branches/icu/unicode/brkiter.h
    MacRuby/branches/icu/unicode/caniter.h
    MacRuby/branches/icu/unicode/chariter.h
    MacRuby/branches/icu/unicode/dbbi.h
    MacRuby/branches/icu/unicode/docmain.h
    MacRuby/branches/icu/unicode/locid.h
    MacRuby/branches/icu/unicode/normlzr.h
    MacRuby/branches/icu/unicode/parseerr.h
    MacRuby/branches/icu/unicode/parsepos.h
    MacRuby/branches/icu/unicode/platform.h
    MacRuby/branches/icu/unicode/ppalmos.h
    MacRuby/branches/icu/unicode/putil.h
    MacRuby/branches/icu/unicode/pwin32.h
    MacRuby/branches/icu/unicode/rbbi.h
    MacRuby/branches/icu/unicode/rep.h
    MacRuby/branches/icu/unicode/resbund.h
    MacRuby/branches/icu/unicode/schriter.h
    MacRuby/branches/icu/unicode/strenum.h
    MacRuby/branches/icu/unicode/symtable.h
    MacRuby/branches/icu/unicode/ubidi.h
    MacRuby/branches/icu/unicode/ubrk.h
    MacRuby/branches/icu/unicode/ucasemap.h
    MacRuby/branches/icu/unicode/ucat.h
    MacRuby/branches/icu/unicode/uchar.h
    MacRuby/branches/icu/unicode/uchriter.h
    MacRuby/branches/icu/unicode/uclean.h
    MacRuby/branches/icu/unicode/ucnv.h
    MacRuby/branches/icu/unicode/ucnv_cb.h
    MacRuby/branches/icu/unicode/ucnv_err.h
    MacRuby/branches/icu/unicode/uconfig.h
    MacRuby/branches/icu/unicode/udata.h
    MacRuby/branches/icu/unicode/udeprctd.h
    MacRuby/branches/icu/unicode/udraft.h
    MacRuby/branches/icu/unicode/uenum.h
    MacRuby/branches/icu/unicode/uidna.h
    MacRuby/branches/icu/unicode/uintrnal.h
    MacRuby/branches/icu/unicode/uiter.h
    MacRuby/branches/icu/unicode/uloc.h
    MacRuby/branches/icu/unicode/umachine.h
    MacRuby/branches/icu/unicode/umisc.h
    MacRuby/branches/icu/unicode/unifilt.h
    MacRuby/branches/icu/unicode/unifunct.h
    MacRuby/branches/icu/unicode/unimatch.h
    MacRuby/branches/icu/unicode/uniset.h
    MacRuby/branches/icu/unicode/unistr.h
    MacRuby/branches/icu/unicode/unorm.h
    MacRuby/branches/icu/unicode/uobject.h
    MacRuby/branches/icu/unicode/uobslete.h
    MacRuby/branches/icu/unicode/urbtok.h
    MacRuby/branches/icu/unicode/urename.h
    MacRuby/branches/icu/unicode/urep.h
    MacRuby/branches/icu/unicode/ures.h
    MacRuby/branches/icu/unicode/uscript.h
    MacRuby/branches/icu/unicode/uset.h
    MacRuby/branches/icu/unicode/usetiter.h
    MacRuby/branches/icu/unicode/ushape.h
    MacRuby/branches/icu/unicode/usprep.h
    MacRuby/branches/icu/unicode/ustring.h
    MacRuby/branches/icu/unicode/usystem.h
    MacRuby/branches/icu/unicode/utext.h
    MacRuby/branches/icu/unicode/utf.h
    MacRuby/branches/icu/unicode/utf16.h
    MacRuby/branches/icu/unicode/utf32.h
    MacRuby/branches/icu/unicode/utf8.h
    MacRuby/branches/icu/unicode/utf_old.h
    MacRuby/branches/icu/unicode/utrace.h
    MacRuby/branches/icu/unicode/utypes.h
    MacRuby/branches/icu/unicode/uversion.h

Modified: MacRuby/branches/icu/encoding.c
===================================================================
--- MacRuby/branches/icu/encoding.c	2010-02-16 00:49:17 UTC (rev 3533)
+++ MacRuby/branches/icu/encoding.c	2010-02-16 00:56:49 UTC (rev 3534)
@@ -1,602 +1,270 @@
-/* 
- * MacRuby implementation of Ruby 1.9's encoding.c.
- *
- * This file is covered by the Ruby license. See COPYING for more details.
- * 
- * Copyright (C) 2007-2010, Apple Inc. All rights reserved.
- * Copyright (C) 1993-2007 Yukihiro Matsumoto
- * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- * Copyright (C) 2000 Information-technology Promotion Agency, Japan
- */
+#include "encoding.h"
+#include <string.h>
 
-#include "ruby/ruby.h"
-#include "ruby/encoding.h"
-#include "regenc.h"
-#include <ctype.h>
-#ifdef HAVE_LANGINFO_H
-#include <langinfo.h>
-#endif
+// TODO:
+// - use rb_usascii_str_new_cstr instead of rb_str_new2
 
-static ID id_encoding, id_base_encoding;
-VALUE rb_cEncoding;
+VALUE rb_cMREncoding = 0;
 
-static CFMutableDictionaryRef __encodings = NULL;
+#define ENC(x) ((encoding_t *)(x))
+#define OBJC_CLASS(x) (*(VALUE *)(x))
 
-static VALUE
-enc_new(const CFStringEncoding *enc)
-{
-    return Data_Wrap_Struct(rb_cEncoding, NULL, NULL, (void *)enc);
-}
+encoding_t *default_internal = NULL;
+encoding_t *default_external = NULL;
+encoding_t *encodings[ENCODINGS_COUNT];
 
-static void
-enc_init_db(void)
-{
-    const CFStringEncoding *e;
+static void str_undefined_update_flags(string_t *self) { abort(); }
+static void str_undefined_make_data_binary(string_t *self) { abort(); }
+static bool str_undefined_try_making_data_uchars(string_t *self) { abort(); }
+static long str_undefined_length(string_t *self, bool ucs2_mode) { abort(); }
+static long str_undefined_bytesize(string_t *self) { abort(); }
+static character_boundaries_t str_undefined_get_character_boundaries(string_t *self, long index, bool ucs2_mode) { abort(); }
+static long str_undefined_offset_in_bytes_to_index(string_t *self, long offset_in_bytes, bool ucs2_mode) { abort(); }
 
-    __encodings = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
-    
-    /* XXX CFStringGetListOfAvailableEncodings() is a costly call and should
-     * be called on demand and not by default when the interpreter starts.
-     */
-    e = CFStringGetListOfAvailableEncodings();
-    while (e != NULL && *e != kCFStringEncodingInvalidId) {
-	VALUE iana;
-	VALUE encoding;
-
-	encoding = enc_new(e);
-
-	iana = (VALUE)CFStringConvertEncodingToIANACharSetName(*e);
-	if (iana != 0) {
-	    const char *name;
-
-	    name = RSTRING_PTR(iana);
-
-	    // new_name = name.gsub(/-/, '_').upcase
-	    char *new_name = alloca(strlen(name));
-	    strcpy(new_name, name);
-	    char *p = strchr(name, '-');
-	    if (p != NULL) {
-		p = new_name + (p - name);
-		do {
-		    *p = '_';
-		    p++;
-		    p = strchr(p, '-');	
-		}
-		while (p != NULL);
-	    }
-	    p = new_name;
-	    while (*p != '\0') {
-		if (islower(*p)) {
-		    *p = toupper(*p);
-		}
-		p++;
-	    }
-
-	    ID encoding_id = rb_intern(new_name);
-	    if (!rb_const_defined(rb_cEncoding, encoding_id)) {
-		rb_const_set(rb_cEncoding, encoding_id, encoding);
-	    }
-	}
-	CFDictionarySetValue(__encodings, (const void *)iana, 
-	    (const void *)encoding);
-	e++;
-    }
-
-    assert(CFDictionaryGetCount((CFDictionaryRef)__encodings) > 0);
-
-    // Define shortcuts.
-    rb_define_const(rb_cEncoding, "ASCII_8BIT",
-	    rb_const_get(rb_cEncoding, rb_intern("US_ASCII")));
-    rb_define_const(rb_cEncoding, "BINARY",
-	    rb_const_get(rb_cEncoding, rb_intern("US_ASCII")));
-}
-
 static VALUE
-enc_make(const CFStringEncoding *enc)
+mr_enc_s_list(VALUE klass, SEL sel)
 {
-    VALUE iana, v;
-
-    assert(enc != NULL);
-    iana = (VALUE)CFStringConvertEncodingToIANACharSetName(*enc);
-    v = (VALUE)CFDictionaryGetValue((CFDictionaryRef)__encodings, 
-	(const void *)iana);
-    assert(v != 0);
-    return v;
-}
-
-VALUE
-rb_enc_from_encoding(rb_encoding *enc)
-{
-    return enc_make(enc);
-}
-
-static inline CFStringEncoding
-rb_enc_to_enc(VALUE v)
-{
-    return *(CFStringEncoding *)DATA_PTR(v);
-}
-
-static inline CFStringEncoding *
-rb_enc_to_enc_ptr(VALUE v)
-{
-    return (CFStringEncoding *)DATA_PTR(v);
-}
-
-rb_encoding *
-rb_to_encoding(VALUE v)
-{
-    if (TYPE(v) == T_STRING)
-	return rb_enc_find2(v);
-    return rb_enc_to_enc_ptr(v);
-}
-
-/*
- * call-seq:
- *   enc.dummy? => true or false
- *
- * Returns true for dummy encodings.
- * A dummy encoding is an encoding for which character handling is not properly
- * implemented.
- * It is used for stateful encodings.
- *
- *   Encoding::ISO_2022_JP.dummy?       #=> true
- *   Encoding::UTF_8.dummy?             #=> false
- *
- */
-static VALUE
-enc_dummy_p(VALUE enc, SEL sel)
-{
-    return rb_enc_dummy_p(rb_to_encoding(enc)) ? Qtrue : Qfalse;
-}
-
-ID
-rb_id_encoding(void)
-{
-    if (!id_encoding) {
-	id_encoding = rb_intern("encoding");
+    VALUE ary = rb_ary_new2(ENCODINGS_COUNT);
+    for (unsigned int i = 0; i < ENCODINGS_COUNT; ++i) {
+	rb_ary_push(ary, (VALUE)encodings[i]);
     }
-    return id_encoding;
+    return ary;
 }
 
-rb_encoding*
-rb_enc_compatible(VALUE str1, VALUE str2)
-{
-    /* TODO */
-    rb_encoding *enc = rb_enc_get(str1);
-    if (enc == rb_enc_get(str2))
-	return enc;
-    return NULL;
-}
-
-/*
- *  call-seq:
- *     obj.encoding   => encoding
- *
- *  Returns the Encoding object that represents the encoding of obj.
- */
-
-VALUE
-rb_obj_encoding(VALUE obj, SEL sel)
-{
-    rb_encoding *enc = rb_enc_get(obj);
-    if (!enc) {
-	rb_raise(rb_eTypeError, "unknown encoding");
-    }
-    return rb_enc_from_encoding(enc);
-}
-
-/*
- * call-seq:
- *   enc.inspect => string
- *
- * Returns a string which represents the encoding for programmers.
- *
- *   Encoding::UTF_8.inspect       #=> "#<Encoding:UTF-8>"
- *   Encoding::ISO_2022_JP.inspect #=> "#<Encoding:ISO-2022-JP (dummy)>"
- */
 static VALUE
-enc_inspect(VALUE self, SEL sel)
+mr_enc_s_name_list(VALUE klass, SEL sel)
 {
-    char buffer[512];
-    VALUE enc_name;
-    long n;
-
-    enc_name = (VALUE)CFStringGetNameOfEncoding(rb_enc_to_enc(self));
-    
-    n = snprintf(buffer, sizeof buffer, "#<%s:%s>", rb_obj_classname(self),
-	RSTRING_PTR(enc_name));
-
-    return rb_str_new(buffer, n);
-}
-
-/*
- * call-seq:
- *   enc.name => string
- *
- * Returns the name of the encoding.
- *
- *   Encoding::UTF_8.name       => "UTF-8"
- */
-static VALUE
-enc_name(VALUE self, SEL sel)
-{
-    return rb_enc_name2(rb_enc_to_enc_ptr(self));
-}
-
-static VALUE
-enc_base_encoding(VALUE self, SEL sel)
-{
-    return rb_attr_get(self, id_base_encoding);
-}
-
-/*
- * call-seq:
- *   Encoding.list => [enc1, enc2, ...]
- *
- * Returns the list of loaded encodings.
- *
- *   Encoding.list
- *   => [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
- *       #<Encoding:ISO-2022-JP (dummy)>]
- *
- *   Encoding.find("US-ASCII")
- *   => #<Encoding:US-ASCII>
- *
- *   Encoding.list
- *   => [#<Encoding:ASCII-8BIT>, #<Encoding:UTF-8>,
- *       #<Encoding:US-ASCII>, #<Encoding:ISO-2022-JP (dummy)>]
- *
- */
-static VALUE
-enc_list(VALUE klass, SEL sel)
-{
-    VALUE ary;
-    const CFStringEncoding *e;
-
-    ary = rb_ary_new();
-    e = CFStringGetListOfAvailableEncodings();
-    while (e != NULL && *e != kCFStringEncodingInvalidId) {
-	rb_ary_push(ary, enc_make(e));
-	e++;
+    VALUE ary = rb_ary_new();
+    for (unsigned int i = 0; i < ENCODINGS_COUNT; ++i) {
+	encoding_t *encoding = ENC(encodings[i]);
+	// TODO: use US-ASCII strings
+	rb_ary_push(ary, rb_str_new2(encoding->public_name));
+	for (unsigned int j = 0; j < encoding->aliases_count; ++j) {
+	    rb_ary_push(ary, rb_str_new2(encoding->aliases[j]));
+	}
     }
     return ary;
 }
 
-/*
- * call-seq:
- *   Encoding.find(string) => enc
- *   Encoding.find(symbol) => enc
- *
- * Search the encoding with specified <i>name</i>.
- * <i>name</i> should be a string or symbol.
- *
- *   Encoding.find("US-ASCII")  => #<Encoding:US-ASCII>
- *   Encoding.find(:Shift_JIS)  => #<Encoding:Shift_JIS>
- *
- */
 static VALUE
-enc_find2(VALUE enc)
+mr_enc_s_aliases(VALUE klass, SEL sel)
 {
-    CFStringRef str;
-    CFStringEncoding e;
-
-    str = (CFStringRef)StringValue(enc);
-    if (CFStringCompare(str, CFSTR("ASCII-8BIT"), 
-			kCFCompareCaseInsensitive) == 0) {
-	str = CFSTR("ASCII");
+    VALUE hash = rb_hash_new();
+    for (unsigned int i = 0; i < ENCODINGS_COUNT; ++i) {
+	encoding_t *encoding = ENC(encodings[i]);
+	for (unsigned int j = 0; j < encoding->aliases_count; ++j) {
+	    rb_hash_aset(hash,
+		    rb_str_new2(encoding->aliases[j]),
+		    rb_str_new2(encoding->public_name));
+	}
     }
-    else if (CFStringCompare(str, CFSTR("SJIS"), 
-	     kCFCompareCaseInsensitive) == 0) {
-	str = CFSTR("Shift-JIS");
-    }
-
-    e = CFStringConvertIANACharSetNameToEncoding(str);
-    if (e == kCFStringEncodingInvalidId)
-	return Qnil;
-    return enc_make(&e);
+    return hash;
 }
 
 static VALUE
-enc_find(VALUE klass, SEL sel, VALUE enc)
+mr_enc_s_default_internal(VALUE klass, SEL sel)
 {
-    VALUE e = enc_find2(enc);
-    if (e == Qnil) {
-	rb_raise(rb_eArgError, "unknown encoding name - %s", RSTRING_PTR(enc));
-    }
-    return e;
+    return (VALUE)default_internal;
 }
 
-/*
- * call-seq:
- *   Encoding.compatible?(str1, str2) => enc or nil
- *
- * Checks the compatibility of two strings.
- * If they are compatible, means concatenatable, 
- * returns an encoding which the concatinated string will be.
- * If they are not compatible, nil is returned.
- *
- *   Encoding.compatible?("\xa1".force_encoding("iso-8859-1"), "b")
- *   => #<Encoding:ISO-8859-1>
- *
- *   Encoding.compatible?(
- *     "\xa1".force_encoding("iso-8859-1"),
- *     "\xa1\xa1".force_encoding("euc-jp"))
- *   => nil
- *
- */
 static VALUE
-enc_compatible_p(VALUE klass, SEL sel, VALUE str1, VALUE str2)
+mr_enc_s_default_external(VALUE klass, SEL sel)
 {
-    rb_encoding *enc = rb_enc_compatible(str1, str2);
-    VALUE encoding = Qnil;
-    if (!enc || !(encoding = rb_enc_from_encoding(enc)))
-	encoding = Qnil;
-    return encoding;
+    return (VALUE)default_external;
 }
 
-/* :nodoc: */
 static VALUE
-enc_dump(VALUE self, SEL sel, int argc, VALUE *argv)
+mr_enc_name(VALUE self, SEL sel)
 {
-    rb_scan_args(argc, argv, "01", 0);
-    return enc_name(self, 0);
+    return rb_str_new2(ENC(self)->public_name);
 }
 
-/* :nodoc: */
 static VALUE
-enc_load(VALUE klass, SEL sel, VALUE str)
+mr_enc_inspect(VALUE self, SEL sel)
 {
-    return enc_find(klass, 0, str);
+    return rb_sprintf("#<%s:%s>", rb_obj_classname(self), ENC(self)->public_name);
 }
 
-static rb_encoding *default_external;
-    
-rb_encoding *
-rb_default_external_encoding(void)
+static VALUE
+mr_enc_names(VALUE self, SEL sel)
 {
-    return default_external;
-}
+    encoding_t *encoding = ENC(self);
 
-VALUE
-rb_enc_default_external(void)
-{
-    return enc_make(default_external);
+    VALUE ary = rb_ary_new2(encoding->aliases_count + 1);
+    rb_ary_push(ary, rb_str_new2(encoding->public_name));
+    for (unsigned int i = 0; i < encoding->aliases_count; ++i) {
+	rb_ary_push(ary, rb_str_new2(encoding->aliases[i]));
+    }
+    return ary;
 }
 
-/*
- * call-seq:
- *   Encoding.default_external => enc
- *
- * Returns default external encoding.
- *
- * It is initialized by the locale or -E option.
- */
 static VALUE
-get_default_external(VALUE klass, SEL sel)
+mr_enc_ascii_compatible_p(VALUE self, SEL sel)
 {
-    return rb_enc_default_external();
+    return ENC(self)->ascii_compatible ? Qtrue : Qfalse;
 }
 
 static VALUE
-set_default_external(VALUE klass, SEL sel, VALUE enc)
+mr_enc_dummy_p(VALUE self, SEL sel)
 {
-    // TODO
-    return enc;
+    return Qfalse;
 }
 
-void
-rb_enc_set_default_external(VALUE encoding)
+static void
+define_encoding_constant(const char *name, encoding_t *encoding)
 {
-    default_external = rb_enc_to_enc_ptr(encoding);
-}
+    char c = name[0];
+    if ((c >= '0') && (c <= '9')) {
+	// constants can't start with a number
+	return;
+    }
 
-/*
- * call-seq:
- *   Encoding.locale_charmap => string
- *
- * Returns the locale charmap name.
- *
- *   Debian GNU/Linux
- *     LANG=C
- *       Encoding.locale_charmap  => "ANSI_X3.4-1968"
- *     LANG=ja_JP.EUC-JP
- *       Encoding.locale_charmap  => "EUC-JP"
- *
- *   SunOS 5
- *     LANG=C
- *       Encoding.locale_charmap  => "646"
- *     LANG=ja
- *       Encoding.locale_charmap  => "eucJP"
- *
- */
-static VALUE
-rb_locale_charmap(VALUE klass, SEL sel)
-{
-    CFStringEncoding enc = CFStringGetSystemEncoding();
-    return (VALUE)CFStringConvertEncodingToIANACharSetName(enc);
-}
-
-/*
- * call-seq:
- *   Encoding.name_list => ["enc1", "enc2", ...]
- *
- * Returns the list of available encoding names.
- *
- *   Encoding.name_list
- *   => ["US-ASCII", "ASCII-8BIT", "UTF-8",
- *       "ISO-8859-1", "Shift_JIS", "EUC-JP",
- *       "Windows-31J",
- *       "BINARY", "CP932", "eucJP"]
- *
- * This list doesn't include dummy encodings.
- *
- */
-
-static VALUE
-rb_enc_name_list(VALUE klass, SEL sel)
-{
-    VALUE ary, list;
-    long i, count;
-
-    ary = rb_ary_new();
-    list = enc_list(klass, 0);
-    for (i = 0, count = RARRAY_LEN(list); i < count; i++) {
-	rb_ary_push(ary, enc_name(RARRAY_AT(list, i), 0));
+    char *name_copy = strdup(name);
+    if ((c >= 'a') && (c <= 'z')) {
+	// the first character must be upper case
+	name_copy[0] = c - ('a' - 'A');
     }
-    return ary;
-}
 
-/*
- * call-seq:
- *   Encoding.aliases => {"alias1" => "orig1", "alias2" => "orig2", ...}
- *
- * Returns the hash of available encoding alias and original encoding name.
- *
- *   Encoding.aliases
- *   => {"BINARY"=>"ASCII-8BIT", "ASCII"=>"US-ASCII", "ANSI_X3.4-1986"=>"US-ASCII",
- *       "SJIS"=>"Shift_JIS", "eucJP"=>"EUC-JP", "CP932"=>"Windows-31J"}
- *
- */
-
-static VALUE
-rb_enc_aliases(VALUE klass, SEL sel)
-{
-    /* TODO: the CFString IANA <-> charset code does support aliases, we should
-     * find a way to return them here. 
-     */
-    return rb_hash_new();
-}
-
-VALUE
-rb_enc_name2(rb_encoding *enc)
-{
-    if (enc != NULL) {
-	CFStringRef str = CFStringConvertEncodingToIANACharSetName(*enc);
-	if (str != NULL) {
-	    VALUE name = rb_str_dup((VALUE)str);
-	    CFStringUppercase((CFMutableStringRef)name, NULL);
-	    return name;
+    // '.' and '-' must be transformed into '_'
+    for (int i = 0; name_copy[i]; ++i) {
+	if ((name_copy[i] == '.') || (name_copy[i] == '-')) {
+	    name_copy[i] = '_';
 	}
     }
-    return Qnil;
+    rb_define_const(rb_cMREncoding, name_copy, (VALUE)encoding);
+    free(name_copy);
 }
 
-const char *
-rb_enc_name(rb_encoding *enc)
-{
-    VALUE str = rb_enc_name2(enc);
-    return str == Qnil ? NULL : RSTRING_PTR(str);
-}
+extern void enc_init_ucnv_encoding(encoding_t *encoding);
 
-long 
-rb_enc_mbminlen(rb_encoding *enc)
-{
-    return rb_enc_mbmaxlen(enc);
-}
+enum {
+    ENCODING_TYPE_SPECIAL = 0,
+    ENCODING_TYPE_UCNV
+};
 
-long
-rb_enc_mbmaxlen(rb_encoding *enc)
+static void
+add_encoding(
+	unsigned int encoding_index, // index of the encoding in the encodings array
+	unsigned int encoding_type,
+	const char *public_name, // public name for the encoding
+	unsigned char min_char_size,
+	bool single_byte_encoding, // in the encoding a character takes only one byte
+	bool ascii_compatible, // is the encoding ASCII compatible or not
+	... // aliases for the encoding (should no include the public name) - must end with a NULL
+	)
 {
-    return enc == NULL
-	? 1 : CFStringGetMaximumSizeForEncoding(1, *enc);
-}
+    assert(encoding_index < ENCODINGS_COUNT);
 
-rb_encoding *
-rb_enc_find(const char *name)
-{
-    return rb_enc_find2(rb_str_new2(name));
-}
+    // create an array for the aliases
+    unsigned int aliases_count = 0;
+    va_list va_aliases;
+    va_start(va_aliases, ascii_compatible);
+    while (va_arg(va_aliases, const char *) != NULL) {
+	++aliases_count;
+    }
+    va_end(va_aliases);
+    const char **aliases = (const char **) malloc(sizeof(const char *) * aliases_count);
+    va_start(va_aliases, ascii_compatible);
+    for (unsigned int i = 0; i < aliases_count; ++i) {
+	aliases[i] = va_arg(va_aliases, const char *);
+    }
+    va_end(va_aliases);
 
-rb_encoding *
-rb_enc_find2(VALUE name)
-{
-    VALUE e = enc_find2(name);
-    return e == Qnil ? NULL : rb_enc_to_enc_ptr(e);
-}
+    // create the MacRuby object
+    NEWOBJ(encoding, encoding_t);
+    encoding->basic.flags = 0;
+    encoding->basic.klass = rb_cMREncoding;
+    encodings[encoding_index] = encoding;
+    rb_objc_retain(encoding); // it should never be deallocated
 
-rb_encoding *
-rb_enc_get(VALUE obj)
-{
-    CFStringEncoding enc = kCFStringEncodingInvalidId;
+    // fill the fields
+    encoding->index = encoding_index;
+    encoding->public_name = public_name;
+    encoding->min_char_size = min_char_size;
+    encoding->single_byte_encoding = single_byte_encoding;
+    encoding->ascii_compatible = ascii_compatible;
+    encoding->aliases_count = aliases_count;
+    encoding->aliases = aliases;
 
-    switch (TYPE(obj)) {
-	case T_STRING:
-	    enc = *(VALUE *)obj == rb_cByteString
-		? kCFStringEncodingASCII
-		: CFStringGetFastestEncoding((CFStringRef)obj);
+    // fill the default implementations with aborts
+    encoding->methods.update_flags = str_undefined_update_flags;
+    encoding->methods.make_data_binary = str_undefined_make_data_binary;
+    encoding->methods.try_making_data_uchars = str_undefined_try_making_data_uchars;
+    encoding->methods.length = str_undefined_length;
+    encoding->methods.bytesize = str_undefined_bytesize;
+    encoding->methods.get_character_boundaries = str_undefined_get_character_boundaries;
+    encoding->methods.offset_in_bytes_to_index = str_undefined_offset_in_bytes_to_index;
+
+    switch (encoding_type) {
+	case ENCODING_TYPE_SPECIAL:
 	    break;
+	case ENCODING_TYPE_UCNV:
+	    enc_init_ucnv_encoding(encoding);
+	    break;
+	default:
+	    abort();
     }
 
-    if (enc == kCFStringEncodingInvalidId) {
-	return NULL;
+    // create constants
+    define_encoding_constant(public_name, encoding);
+    for (unsigned int i = 0; i < aliases_count; ++i) {
+	define_encoding_constant(aliases[i], encoding);
     }
-    return rb_enc_to_enc_ptr(enc_make(&enc));
-}
 
-rb_encoding *
-rb_locale_encoding(void)
-{
-    CFStringEncoding enc = CFStringGetSystemEncoding();
-    return rb_enc_to_enc_ptr(enc_make(&enc));
+    free(aliases);
 }
 
-void
-Init_Encoding(void)
+static void
+create_encodings(void)
 {
-    id_base_encoding = rb_intern("#base_encoding");
+    add_encoding(ENCODING_BINARY,    ENCODING_TYPE_SPECIAL, "ASCII-8BIT",  1, true,  true,  "BINARY", NULL);
+    add_encoding(ENCODING_ASCII,     ENCODING_TYPE_UCNV,    "US-ASCII",    1, true,  true,  "ASCII", "ANSI_X3.4-1968", "646", NULL);
+    add_encoding(ENCODING_UTF8,      ENCODING_TYPE_UCNV,    "UTF-8",       1, false, true,  "CP65001", NULL);
+    add_encoding(ENCODING_UTF16BE,   ENCODING_TYPE_UCNV,    "UTF-16BE",    2, false, false, NULL);
+    add_encoding(ENCODING_UTF16LE,   ENCODING_TYPE_UCNV,    "UTF-16LE",    2, false, false, NULL);
+    add_encoding(ENCODING_UTF32BE,   ENCODING_TYPE_UCNV,    "UTF-32BE",    4, false, false, "UCS-4BE", NULL);
+    add_encoding(ENCODING_UTF32LE,   ENCODING_TYPE_UCNV,    "UTF-32LE",    4, false, false, "UCS-4LE", NULL);
+    add_encoding(ENCODING_ISO8859_1, ENCODING_TYPE_UCNV,    "ISO-8859-1",  1, true,  true,  "ISO8859-1", NULL);
+    add_encoding(ENCODING_MACROMAN,  ENCODING_TYPE_UCNV,    "macRoman",    1, true,  true,  NULL);
+    // FIXME: the ICU conversion tables do not seem to match Ruby's Japanese conversion tables
+    //add_encoding(ENCODING_EUCJP,     ENCODING_TYPE_RUBY, "EUC-JP",      1, false, true,  "eucJP", NULL);
+    //add_encoding(ENCODING_SJIS,      ENCODING_TYPE_RUBY, "Shift_JIS",   1, false, true, "SJIS", NULL);
+    //add_encoding(ENCODING_CP932,     ENCODING_TYPE_RUBY, "Windows-31J", 1, false, true, "CP932", "csWindows31J", NULL);
 
-    rb_cEncoding = rb_define_class("Encoding", rb_cObject);
-    rb_undef_alloc_func(rb_cEncoding);
-    rb_objc_define_method(rb_cEncoding, "to_s", enc_name, 0);
-    rb_objc_define_method(rb_cEncoding, "inspect", enc_inspect, 0);
-    rb_objc_define_method(rb_cEncoding, "name", enc_name, 0);
-    rb_objc_define_method(rb_cEncoding, "base_encoding", enc_base_encoding, 0);
-    rb_objc_define_method(rb_cEncoding, "dummy?", enc_dummy_p, 0);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "list", enc_list, 0);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "name_list", rb_enc_name_list, 0);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "aliases", rb_enc_aliases, 0);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "find", enc_find, 1);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "compatible?", enc_compatible_p, 2);
-
-    rb_objc_define_method(rb_cEncoding, "_dump", enc_dump, -1);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "_load", enc_load, 1);
-
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "default_external", get_default_external, 0);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "default_external=", set_default_external, 1);
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "default_internal", get_default_external, 0); // TODO
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "default_internal=", set_default_external, 1); // TODO
-    rb_objc_define_method(*(VALUE *)rb_cEncoding, "locale_charmap", rb_locale_charmap, 0);
-
-    enc_init_db();
+    default_external = encodings[ENCODING_UTF8];
+    default_internal = encodings[ENCODING_UTF16_NATIVE];
 }
 
-/* locale insensitive functions */
+VALUE
+mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2);
 
-#define ctype_test(c, ctype) \
-    (rb_isascii(c) && ONIGENC_IS_ASCII_CODE_CTYPE((c), ctype))
+void
+Init_MREncoding(void)
+{
+    rb_cMREncoding = rb_define_class("MREncoding", rb_cObject);
+    rb_undef_alloc_func(rb_cMREncoding);
 
-int rb_isalnum(int c) { return ctype_test(c, ONIGENC_CTYPE_ALNUM); }
-int rb_isalpha(int c) { return ctype_test(c, ONIGENC_CTYPE_ALPHA); }
-int rb_isblank(int c) { return ctype_test(c, ONIGENC_CTYPE_BLANK); }
-int rb_iscntrl(int c) { return ctype_test(c, ONIGENC_CTYPE_CNTRL); }
-int rb_isdigit(int c) { return ctype_test(c, ONIGENC_CTYPE_DIGIT); }
-int rb_isgraph(int c) { return ctype_test(c, ONIGENC_CTYPE_GRAPH); }
-int rb_islower(int c) { return ctype_test(c, ONIGENC_CTYPE_LOWER); }
-int rb_isprint(int c) { return ctype_test(c, ONIGENC_CTYPE_PRINT); }
-int rb_ispunct(int c) { return ctype_test(c, ONIGENC_CTYPE_PUNCT); }
-int rb_isspace(int c) { return ctype_test(c, ONIGENC_CTYPE_SPACE); }
-int rb_isupper(int c) { return ctype_test(c, ONIGENC_CTYPE_UPPER); }
-int rb_isxdigit(int c) { return ctype_test(c, ONIGENC_CTYPE_XDIGIT); }
+    rb_objc_define_method(rb_cMREncoding, "to_s", mr_enc_name, 0);
+    rb_objc_define_method(rb_cMREncoding, "inspect", mr_enc_inspect, 0);
+    rb_objc_define_method(rb_cMREncoding, "name", mr_enc_name, 0);
+    rb_objc_define_method(rb_cMREncoding, "names", mr_enc_names, 0);
+    rb_objc_define_method(rb_cMREncoding, "dummy?", mr_enc_dummy_p, 0);
+    rb_objc_define_method(rb_cMREncoding, "ascii_compatible?", mr_enc_ascii_compatible_p, 0);
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "list", mr_enc_s_list, 0);
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "name_list", mr_enc_s_name_list, 0);
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "aliases", mr_enc_s_aliases, 0);
+    //rb_define_singleton_method(rb_cMREncoding, "find", enc_find, 1);
+    // it's defined on Encoding, but it requires String's internals so it's defined with String
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "compatible?", mr_enc_s_is_compatible, 2);
 
-int
-rb_tolower(int c)
-{
-    return rb_isascii(c) ? ONIGENC_ASCII_CODE_TO_LOWER_CASE(c) : c;
-}
+    //rb_define_method(rb_cEncoding, "_dump", enc_dump, -1);
+    //rb_define_singleton_method(rb_cEncoding, "_load", enc_load, 1);
 
-int
-rb_toupper(int c)
-{
-    return rb_isascii(c) ? ONIGENC_ASCII_CODE_TO_UPPER_CASE(c) : c;
-}
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "default_external", mr_enc_s_default_external, 0);
+    //rb_define_singleton_method(rb_cMREncoding, "default_external=", set_default_external, 1);
+    rb_objc_define_method(OBJC_CLASS(rb_cMREncoding), "default_internal", mr_enc_s_default_internal, 0);
+    //rb_define_singleton_method(rb_cMREncoding, "default_internal=", set_default_internal, 1);
+    //rb_define_singleton_method(rb_cMREncoding, "locale_charmap", rb_locale_charmap, 0);
 
+    create_encodings();
+}

Added: MacRuby/branches/icu/encoding.h
===================================================================
--- MacRuby/branches/icu/encoding.h	                        (rev 0)
+++ MacRuby/branches/icu/encoding.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,230 @@
+#ifndef __ENCODING_H_
+#define __ENCODING_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "ruby.h"
+#include <stdbool.h>
+#include "unicode/ustring.h"
+
+#if __LITTLE_ENDIAN__
+#define ENCODING_UTF16_NATIVE ENCODING_UTF16LE
+#define ENCODING_UTF32_NATIVE ENCODING_UTF32LE
+#define ENCODING_UTF16_NON_NATIVE ENCODING_UTF16BE
+#define ENCODING_UTF32_NON_NATIVE ENCODING_UTF32BE
+#else
+#define ENCODING_UTF16_NATIVE ENCODING_UTF16BE
+#define ENCODING_UTF32_NATIVE ENCODING_UTF32BE
+#define ENCODING_UTF16_NON_NATIVE ENCODING_UTF16LE
+#define ENCODING_UTF32_NON_NATIVE ENCODING_UTF32LE
+#endif
+
+#define NATIVE_UTF16_ENC(encoding) ((encoding) == encodings[ENCODING_UTF16_NATIVE])
+#define NON_NATIVE_UTF16_ENC(encoding) ((encoding) == encodings[ENCODING_UTF16_NON_NATIVE])
+#define UTF16_ENC(encoding) (NATIVE_UTF16_ENC(encoding) || NON_NATIVE_UTF16_ENC(encoding))
+#define NATIVE_UTF32_ENC(encoding) ((encoding) == encodings[ENCODING_UTF32_NATIVE])
+#define NON_NATIVE_UTF32_ENC(encoding) ((encoding) == encodings[ENCODING_UTF32_NON_NATIVE])
+#define UTF32_ENC(encoding) (NATIVE_UTF32_ENC(encoding) || NON_NATIVE_UTF32_ENC(encoding))
+#define BINARY_ENC(encoding) ((encoding) == encodings[ENCODING_BINARY])
+
+typedef uint8_t str_flag_t;
+
+typedef struct  {
+    struct RBasic basic;
+    struct encoding_s *encoding;
+    long capacity_in_bytes;
+    long length_in_bytes;
+    union {
+	char *bytes;
+	UChar *uchars;
+    } data;
+    str_flag_t flags;
+} string_t;
+
+typedef struct {
+    long start_offset_in_bytes;
+    long end_offset_in_bytes;
+} character_boundaries_t;
+
+typedef struct {
+    void (*update_flags)(string_t *);
+    void (*make_data_binary)(string_t *);
+    bool (*try_making_data_uchars)(string_t *);
+    long (*length)(string_t *, bool);
+    long (*bytesize)(string_t *);
+    character_boundaries_t (*get_character_boundaries)(string_t *, long, bool);
+    long (*offset_in_bytes_to_index)(string_t *, long, bool);
+} encoding_methods_t;
+
+typedef struct encoding_s {
+    struct RBasic basic;
+    unsigned int index;
+    const char *public_name;
+    const char **aliases;
+    unsigned int aliases_count;
+    unsigned char min_char_size;
+    bool single_byte_encoding : 1;
+    bool ascii_compatible : 1;
+    encoding_methods_t methods;
+    void *private_data;
+} encoding_t;
+
+enum {
+    ENCODING_BINARY = 0,
+    ENCODING_ASCII,
+    ENCODING_UTF8,
+    ENCODING_UTF16BE,
+    ENCODING_UTF16LE,
+    ENCODING_UTF32BE,
+    ENCODING_UTF32LE,
+    ENCODING_ISO8859_1,
+    ENCODING_MACROMAN,
+    //ENCODING_EUCJP,
+    //ENCODING_SJIS,
+    //ENCODING_CP932,
+
+    ENCODINGS_COUNT
+};
+
+extern encoding_t *encodings[ENCODINGS_COUNT];
+
+extern VALUE rb_cMREncoding;
+
+#define STRING_HAS_SUPPLEMENTARY     0x020
+#define STRING_HAS_SUPPLEMENTARY_SET 0x010
+#define STRING_ASCII_ONLY            0x008
+#define STRING_ASCII_ONLY_SET        0x010
+#define STRING_ASCII_ONLY            0x008
+#define STRING_VALID_ENCODING_SET    0x004
+#define STRING_VALID_ENCODING        0x002
+#define STRING_STORED_IN_UCHARS      0x001
+
+#define STRING_REQUIRED_FLAGS STRING_STORED_IN_UCHARS
+
+#define STR(x) ((string_t *)(x))
+
+#define BYTES_TO_UCHARS(len) ((len) / sizeof(UChar))
+#define UCHARS_TO_BYTES(len) ((len) * sizeof(UChar))
+
+#define ODD_NUMBER(x) ((x) & 0x1)
+
+static inline long
+div_round_up(long a, long b)
+{
+    return ((a) + (b - 1)) / b;
+}
+
+void
+str_update_flags(string_t *self);
+
+static inline void
+str_unset_facultative_flags(string_t *self)
+{
+    self->flags &= ~STRING_HAS_SUPPLEMENTARY_SET & ~STRING_ASCII_ONLY_SET & ~STRING_VALID_ENCODING_SET;
+}
+
+static inline bool
+str_known_to_have_an_invalid_encoding(string_t *self)
+{
+    return (self->flags & (STRING_VALID_ENCODING_SET | STRING_VALID_ENCODING)) == STRING_VALID_ENCODING_SET;
+}
+
+static inline bool
+str_known_not_to_have_any_supplementary(string_t *self)
+{
+    return (self->flags & (STRING_HAS_SUPPLEMENTARY_SET | STRING_HAS_SUPPLEMENTARY)) == STRING_HAS_SUPPLEMENTARY_SET;
+}
+
+static inline bool
+str_check_flag_and_update_if_needed(string_t *self, str_flag_t flag_set, str_flag_t flag)
+{
+    if (!(self->flags & flag_set)) {
+	str_update_flags(self);
+	assert(self->flags & flag_set);
+    }
+    return self->flags & flag;
+}
+
+static inline bool
+str_is_valid_encoding(string_t *self)
+{
+    return str_check_flag_and_update_if_needed(self, STRING_VALID_ENCODING_SET, STRING_VALID_ENCODING);
+}
+
+static inline bool
+str_is_ascii_only(string_t *self)
+{
+    return str_check_flag_and_update_if_needed(self, STRING_ASCII_ONLY_SET, STRING_ASCII_ONLY);
+}
+
+static inline bool
+str_is_ruby_ascii_only(string_t *self)
+{
+    // for MRI, a string in a non-ASCII-compatible encoding (like UTF-16)
+    // containing only ASCII characters is not "ASCII only" though for us it is internally
+    if (!self->encoding->ascii_compatible) {
+	return false;
+    }
+
+    return str_is_ascii_only(self);
+}
+
+static inline bool
+str_is_stored_in_uchars(string_t *self)
+{
+    return self->flags & STRING_STORED_IN_UCHARS;
+}
+
+static inline void
+str_negate_stored_in_uchars(string_t *self)
+{
+    self->flags ^= STRING_STORED_IN_UCHARS;
+}
+
+static inline void
+str_set_stored_in_uchars(string_t *self, bool status)
+{
+    if (status) {
+	self->flags |= STRING_STORED_IN_UCHARS;
+    }
+    else {
+	self->flags &= ~STRING_STORED_IN_UCHARS;
+    }
+}
+
+static inline void
+str_set_facultative_flag(string_t *self, bool status, str_flag_t flag_set, str_flag_t flag)
+{
+    if (status) {
+	self->flags = self->flags | flag_set | flag;
+    }
+    else {
+	self->flags = (self->flags | flag_set) & ~flag;
+    }
+}
+
+static inline void
+str_set_has_supplementary(string_t *self, bool status)
+{
+    str_set_facultative_flag(self, status, STRING_HAS_SUPPLEMENTARY_SET, STRING_HAS_SUPPLEMENTARY);
+}
+
+static inline void
+str_set_ascii_only(string_t *self, bool status)
+{
+    str_set_facultative_flag(self, status, STRING_ASCII_ONLY_SET, STRING_ASCII_ONLY);
+}
+
+static inline void
+str_set_valid_encoding(string_t *self, bool status)
+{
+    str_set_facultative_flag(self, status, STRING_VALID_ENCODING_SET, STRING_VALID_ENCODING);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ENCODING_H_ */

Modified: MacRuby/branches/icu/rakelib/builder/builder.rb
===================================================================
--- MacRuby/branches/icu/rakelib/builder/builder.rb	2010-02-16 00:49:17 UTC (rev 3533)
+++ MacRuby/branches/icu/rakelib/builder/builder.rb	2010-02-16 00:56:49 UTC (rev 3534)
@@ -9,7 +9,7 @@
   onig/enc/utf8 onig/enc/euc_jp onig/enc/sjis onig/enc/iso8859_1
   onig/enc/utf16_be onig/enc/utf16_le onig/enc/utf32_be onig/enc/utf32_le
   ruby signal sprintf st string struct time transcode util variable version
-  thread id objc bs encoding main dln dmyext marshal gcd
+  thread id objc bs ucnv encoding main dln dmyext marshal gcd
   vm_eval prelude miniprelude gc-stub bridgesupport compiler dispatcher vm
   debugger MacRuby MacRubyDebuggerConnector NSArray NSDictionary
 }

Modified: MacRuby/branches/icu/rakelib/builder/options.rb
===================================================================
--- MacRuby/branches/icu/rakelib/builder/options.rb	2010-02-16 00:49:17 UTC (rev 3533)
+++ MacRuby/branches/icu/rakelib/builder/options.rb	2010-02-16 00:56:49 UTC (rev 3534)
@@ -102,6 +102,7 @@
 CC = '/usr/bin/gcc'
 CXX = '/usr/bin/g++'
 CFLAGS = "-I. -I./include -I./onig -I/usr/include/libxml2 #{ARCHFLAGS} -fno-common -pipe -O3 -g -Wall -fexceptions"
+CFLAGS << " -I./unicode" # TODO use /usr/local/include/unicode on FNI installs...
 CFLAGS << " -Wno-parentheses -Wno-deprecated-declarations -Werror" if NO_WARN_BUILD
 OBJC_CFLAGS = CFLAGS + " -fobjc-gc-only"
 CXXFLAGS = `#{LLVM_CONFIG} --cxxflags #{LLVM_MODULES}`.sub(/-DNDEBUG/, '').strip
@@ -109,7 +110,7 @@
 CXXFLAGS << " -Wno-parentheses -Wno-deprecated-declarations -Werror" if NO_WARN_BUILD
 CXXFLAGS << " -DLLVM_TOT" if ENV['LLVM_TOT']
 LDFLAGS = `#{LLVM_CONFIG} --ldflags --libs #{LLVM_MODULES}`.strip.gsub(/\n/, '')
-LDFLAGS << " -lpthread -ldl -lxml2 -lobjc -lauto -framework Foundation"
+LDFLAGS << " -lpthread -ldl -lxml2 -lobjc -lauto -licucore -framework Foundation"
 DLDFLAGS = "-dynamiclib -undefined suppress -flat_namespace -install_name #{INSTALL_NAME} -current_version #{MACRUBY_VERSION} -compatibility_version #{MACRUBY_VERSION}"
 DLDFLAGS << " -unexported_symbols_list #{UNEXPORTED_SYMBOLS_LIST}" if UNEXPORTED_SYMBOLS_LIST
 CFLAGS << " -std=c99" # we add this one later to not conflict with C++ flags

Modified: MacRuby/branches/icu/string.c
===================================================================
--- MacRuby/branches/icu/string.c	2010-02-16 00:49:17 UTC (rev 3533)
+++ MacRuby/branches/icu/string.c	2010-02-16 00:56:49 UTC (rev 3534)
@@ -3,5848 +3,1312 @@
  *
  * This file is covered by the Ruby license. See COPYING for more details.
  * 
- * Copyright (C) 2007-2010, Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009, Apple Inc. All rights reserved.
  * Copyright (C) 1993-2007 Yukihiro Matsumoto
  * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
  * Copyright (C) 2000 Information-technology Promotion Agency, Japan
  */
-
-#include "ruby/ruby.h"
-#include "ruby/re.h"
-#include "ruby/encoding.h"
-#include "id.h"
+#include "encoding.h"
 #include "objc.h"
-#include "ruby/node.h"
-#include "vm.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
 
-#define BEG(no) regs->beg[no]
-#define END(no) regs->end[no]
+#define OBJC_CLASS(x) (*(VALUE *)(x))
 
-#include <math.h>
-#include <ctype.h>
+VALUE rb_cMRString;
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-VALUE rb_cString;
-VALUE rb_cCFString;
-VALUE rb_cNSString;
-VALUE rb_cNSMutableString;
-VALUE rb_cSymbol;
-VALUE rb_cByteString;
-
-typedef struct {
-    struct RBasic basic;
-    CFMutableDataRef data;
-} rb_bstr_t;
-
-VALUE
-rb_str_freeze(VALUE str)
+#undef TYPE // TODO: remove this when MRString has become a child of NSString
+extern VALUE rb_cMRString;
+static inline int
+rb_type2(VALUE obj)
 {
-    rb_obj_freeze(str);
-    return str;
-}
-
-#define is_ascii_string(str) (1)
-#define is_broken_string(str) (0)
-#define STR_ENC_GET(str) (NULL)
-#define str_mod_check(x,y,z)
-
-VALUE rb_fs;
-
-static inline void
-str_frozen_check(VALUE s)
-{
-    if (OBJ_FROZEN(s)) {
-	rb_raise(rb_eRuntimeError, "string frozen");
+    if (CLASS_OF(obj) == rb_cMRString) {
+	return T_STRING;
     }
-}
-
-static inline void
-str_change_class(VALUE str, VALUE klass)
-{
-    if (klass != 0 
-	&& klass != rb_cNSString 
-	&& klass != rb_cNSMutableString
-	&& klass != rb_cSymbol
-	&& klass != rb_cByteString) {
-	*(VALUE *)str = (VALUE)klass;
+    else {
+	return rb_type(obj);
     }
 }
+#define TYPE(obj) rb_type2(obj)
 
-static inline VALUE
-str_alloc(VALUE klass)
-{
-    VALUE str = (VALUE)CFStringCreateMutable(NULL, 0);
-    str_change_class(str, klass);
-    CFMakeCollectable((CFTypeRef)str);
 
-    return (VALUE)str;
-}
-
-VALUE
-rb_str_new_empty(void)
+static void
+str_update_flags_utf16(string_t *self)
 {
-    return str_alloc(0);
-}
+    assert(str_is_stored_in_uchars(self) || NON_NATIVE_UTF16_ENC(self->encoding));
 
-VALUE
-rb_str_new_fast(int argc, ...)
-{
-    VALUE str = str_alloc(0);
-
-    if (argc > 0) {
-	va_list ar;
-	va_start(ar, argc);
-	for (int i = 0; i < argc; ++i) {
-	    VALUE fragment = va_arg(ar, VALUE);
-	    switch (TYPE(fragment)) {
-		case T_FIXNUM:
-		    CFStringAppendFormat((CFMutableStringRef)str, NULL, CFSTR("%ld"),
-			    FIX2LONG(fragment));
-		    break;
-
-		default:
-		    fragment = rb_obj_as_string(fragment);
-		    // fall through
-
-		case T_STRING:
-		    CFStringAppend((CFMutableStringRef)str, (CFStringRef)fragment);
-		    break;
-	    }
-	}
-	va_end(ar);
+    bool ascii_only = true;
+    bool has_supplementary = false;
+    bool valid_encoding = true;
+    // if the length is an odd number, it can't be valid UTF-16
+    if (ODD_NUMBER(self->length_in_bytes)) {
+	valid_encoding = false;
     }
 
-    return str;
-}
-
-static VALUE
-str_new(VALUE klass, const char *ptr, long len)
-{
-    VALUE str;
-
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative string size (or size too big)");
-    }
-
-    if (ptr != NULL && len > 0) {
-	const long slen = len == 1
-	    ? 1 /* XXX in the case ptr is actually a pointer to a single char
-		   character, which is not NULL-terminated. */
-	    : strlen(ptr);
-
-	if (len <= slen) {
-	    str = str_alloc(klass);
-	    CFStringAppendCString((CFMutableStringRef)str, ptr, 
-		    kCFStringEncodingUTF8);
-	    if (len < slen) {
-		CFStringPad((CFMutableStringRef)str, NULL, len, 0);
-	    }
-	    if (CFStringGetLength((CFStringRef)str) != len) {
-		str = rb_bytestring_new_with_data((const UInt8 *)ptr, len);
-	    }
+    UChar *uchars = self->data.uchars;
+    long uchars_count = BYTES_TO_UCHARS(self->length_in_bytes);
+    bool native_byte_order = str_is_stored_in_uchars(self);
+    UChar32 lead = 0;
+    for (int i = 0; i < uchars_count; ++i) {
+	UChar32 c;
+	if (native_byte_order) {
+	    c = uchars[i];
 	}
 	else {
-	    str = rb_bytestring_new_with_data((const UInt8 *)ptr, len);
+	    uint8_t *bytes = (uint8_t *)&uchars[i];
+	    c = (uint16_t)bytes[0] << 8 | (uint16_t)bytes[1];
 	}
-    }
-    else {
-	if (len == 0) {
-	    str = str_alloc(klass);
+	if (U16_IS_SURROGATE(c)) { // surrogate
+	    if (U16_IS_SURROGATE_LEAD(c)) { // lead surrogate
+		// a lead surrogate should not be
+		// after an other lead surrogate
+		if (lead != 0) {
+		    valid_encoding = false;
+		}
+		lead = c;
+	    }
+	    else { // trail surrogate
+		// a trail surrogate must follow a lead surrogate
+		if (lead == 0) {
+		    valid_encoding = false;
+		}
+		else {
+		    has_supplementary = true;
+		    c = U16_GET_SUPPLEMENTARY(lead, c);
+		    if (!U_IS_UNICODE_CHAR(c)) {
+			valid_encoding = false;
+		    }
+		}
+		lead = 0;
+	    }
 	}
-	else {
-	    str = rb_bytestring_new();
-	    rb_bytestring_resize(str, len);
+	else { // not a surrogate
+	    // a non-surrogate character should not be after a lead surrogate
+	    // and it should be a valid Unicode character
+	    // Warning: Ruby 1.9 does not do the IS_UNICODE_CHAR check
+	    // (for 1.9, 0xffff is valid though it's not a Unicode character)
+	    if ((lead != 0) || !U_IS_UNICODE_CHAR(c)) {
+		valid_encoding = false;
+	    }
+
+	    if (c > 127) {
+		ascii_only = false;
+	    }
 	}
     }
-
-    return str;
-}
-
-VALUE
-rb_unicode_str_new(const UniChar *ptr, const size_t len)
-{
-    VALUE str = str_alloc(rb_cString);
-    CFStringAppendCharacters((CFMutableStringRef)str,
-	    ptr, len);
-    return str;
-}
-
-VALUE
-rb_str_new(const char *ptr, long len)
-{
-    return str_new(rb_cString, ptr, len);
-}
-
-VALUE
-rb_usascii_str_new(const char *ptr, long len)
-{
-    return str_new(rb_cString, ptr, len);
-}
-
-VALUE
-rb_enc_str_new(const char *ptr, long len, rb_encoding *enc)
-{
-    return str_new(rb_cString, ptr, len);
-}
-
-VALUE
-rb_str_new2(const char *ptr)
-{
-    long len;
-    if (!ptr) {
-	rb_raise(rb_eArgError, "NULL pointer given");
+    // the last character should not be a lead surrogate
+    if (lead != 0) {
+	valid_encoding = false;
     }
-    len = strlen(ptr);
-    return rb_str_new(len == 0 ? NULL : ptr, len);
-}
 
-VALUE
-rb_usascii_str_new2(const char *ptr)
-{
-    if (!ptr) {
-	rb_raise(rb_eArgError, "NULL pointer given");
+    str_set_has_supplementary(self, has_supplementary);
+    if (valid_encoding) {
+	str_set_valid_encoding(self, true);
+	str_set_ascii_only(self, ascii_only);
     }
-    return rb_usascii_str_new(ptr, strlen(ptr));
-}
-
-VALUE
-rb_tainted_str_new(const char *ptr, long len)
-{
-    VALUE str = rb_str_new(ptr, len);
-    OBJ_TAINT(str);
-    return str;
-}
-
-VALUE
-rb_tainted_str_new2(const char *ptr)
-{
-    VALUE str = rb_str_new2(ptr);
-    OBJ_TAINT(str);
-    return str;
-}
-
-static inline VALUE
-str_new3(VALUE klass, VALUE str)
-{
-    VALUE str2 = rb_str_dup(str);
-    str_change_class(str2, klass);
-    return str2;
-}
-
-VALUE
-rb_str_new3(VALUE str)
-{
-    return str_new3(rb_obj_class(str), str);
-}
-
-VALUE
-rb_str_new4(VALUE orig)
-{
-    return rb_str_new3(orig);
-}
-
-VALUE
-rb_str_new5(VALUE obj, const char *ptr, long len)
-{
-    return str_new(rb_obj_class(obj), ptr, len);
-}
-
-#define STR_BUF_MIN_SIZE 128
-
-VALUE
-rb_str_buf_new(long capa)
-{
-    return rb_str_new2("");
-#if 0
-    return rb_bytestring_new();
-#endif
-}
-
-VALUE
-rb_str_buf_new2(const char *ptr)
-{
-    return rb_str_new2(ptr);
-#if 0
-    VALUE str = rb_bytestring_new();
-    long len = strlen(ptr);
-    if (ptr != NULL && len > 0) {
-	CFDataAppendBytes(rb_bytestring_wrapped_data(str), (const UInt8 *)ptr, len);
+    else {
+	str_set_valid_encoding(self, false);
+	str_set_ascii_only(self, false);
     }
-    return str;
-#endif
 }
 
-VALUE
-rb_str_tmp_new(long len)
-{
-    VALUE str = rb_bytestring_new();
-    rb_bytestring_resize(str, len);
-    return str;
-}
-
-VALUE
-rb_str_to_str(VALUE str)
-{
-    return rb_convert_type(str, T_STRING, "String", "to_str");
-}
-
 void
-rb_str_shared_replace(VALUE str, VALUE str2)
+str_update_flags(string_t *self)
 {
-    rb_str_modify(str);
-    CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)str2);
-}
-
-static ID id_to_s;
-
-VALUE
-rb_obj_as_string(VALUE obj)
-{
-    VALUE str;
-
-    if (TYPE(obj) == T_STRING || TYPE(obj) == T_SYMBOL) {
-	return obj;
+    if (self->length_in_bytes == 0) {
+	str_set_valid_encoding(self, true);
+	str_set_ascii_only(self, true);
+	str_set_has_supplementary(self, false);
     }
-    //str = rb_funcall(obj, id_to_s, 0);
-    str = rb_vm_call(obj, selToS, 0, NULL, false);
-    if (TYPE(str) != T_STRING) {
-	return rb_any_to_s(obj);
-    }
-    if (OBJ_TAINTED(obj)) {
-	OBJ_TAINT(str);
-    }
-    return str;
-}
-
-static VALUE rb_str_replace(VALUE, VALUE);
-
-static VALUE
-rb_str_dup_imp(VALUE str, SEL sel)
-{
-    VALUE dup;
-    VALUE klass = *(VALUE *)str;
-
-    if (klass == rb_cByteString) {
-	dup = rb_bytestring_copy(str);
-    }
-    else if (klass == rb_cCFString) {
-	dup = (VALUE)CFStringCreateMutableCopy(NULL, 0, (CFStringRef)str);
-	CFMakeCollectable((CFTypeRef)dup);
-	if (*(VALUE *)str != rb_cSymbol) {
-	    *(VALUE *)dup = *(VALUE *)str;
+    else if (BINARY_ENC(self->encoding)) {
+	str_set_valid_encoding(self, true);
+	str_set_has_supplementary(self, false);
+	bool ascii_only = true;
+	for (long i = 0; i < self->length_in_bytes; ++i) {
+	    if ((uint8_t)self->data.bytes[i] > 127) {
+		ascii_only = false;
+		break;
+	    }
 	}
+	str_set_ascii_only(self, ascii_only);
     }
+    else if (str_is_stored_in_uchars(self) || UTF16_ENC(self->encoding)) {
+	str_update_flags_utf16(self);
+    }
     else {
-	dup = (VALUE)objc_msgSend((void *)str, selMutableCopy);
+	self->encoding->methods.update_flags(self);
     }
-
-    if (OBJ_TAINTED(str)) {
-	OBJ_TAINT(dup);
-    }
-
-    return dup;
 }
 
-VALUE
-rb_str_dup(VALUE str)
+static void
+str_invert_byte_order(string_t *self)
 {
-    return rb_str_dup_imp(str, 0);
-}
+    assert(NON_NATIVE_UTF16_ENC(self->encoding));
 
-static VALUE
-rb_str_clone(VALUE str, SEL sel)
-{
-    VALUE clone = rb_str_dup(str);
-    if (OBJ_FROZEN(str)) {
-	OBJ_FREEZE(clone);
-    }
-    return clone;
-}
+    long length_in_bytes = self->length_in_bytes;
+    char *bytes = self->data.bytes;
 
-/*
- *  call-seq:
- *     String.new(str="")   => new_str
- *  
- *  Returns a new string object containing a copy of <i>str</i>.
- */
-
-static VALUE
-rb_str_init(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE orig;
-
-    str = (VALUE)objc_msgSend((id)str, selInit);
-
-    if (argc > 0 && rb_scan_args(argc, argv, "01", &orig) == 1) {
-	if (str != orig) {
-	    rb_str_replace(str, orig);
-	}
+    if (ODD_NUMBER(length_in_bytes)) {
+	--length_in_bytes;
     }
-    return str;
-}
 
-static long
-str_strlen(VALUE str, rb_encoding *enc)
-{
-    /* TODO should use CFStringGetMaximumSizeForEncoding too */
-    return RSTRING_LEN(str);
-}
-
-/*
- *  call-seq:
- *     str.length   => integer
- *     str.size     => integer
- *  
- *  Returns the character length of <i>str</i>.
- */
-
-static VALUE
-rb_str_length_imp(VALUE str, SEL sel)
-{
-    int len;
-
-    len = str_strlen(str, STR_ENC_GET(str));
-    return INT2NUM(len);
-}
-
-VALUE
-rb_str_length(VALUE str)
-{
-    return rb_str_length_imp(str, 0);
-}
-
-/*
- *  call-seq:
- *     str.bytesize  => integer
- *  
- *  Returns the length of <i>str</i> in bytes.
- */
-
-static VALUE
-rb_str_bytesize(VALUE str, SEL sel)
-{
-    // TODO Not super accurate...
-    CFStringEncoding encoding = CFStringGetSmallestEncoding((CFStringRef)str);
-    long size = CFStringGetMaximumSizeForEncoding(RSTRING_LEN(str), encoding);
-    return LONG2NUM(size);
-}
-
-/*
- *  call-seq:
- *     str.empty?   => true or false
- *  
- *  Returns <code>true</code> if <i>str</i> has a length of zero.
- *     
- *     "hello".empty?   #=> false
- *     "".empty?        #=> true
- */
-
-static VALUE
-rb_str_empty(VALUE str, SEL sel)
-{
-    return RSTRING_LEN(str) == 0 ? Qtrue : Qfalse;
-}
-
-/*
- *  call-seq:
- *     str + other_str   => new_str
- *  
- *  Concatenation---Returns a new <code>String</code> containing
- *  <i>other_str</i> concatenated to <i>str</i>.
- *     
- *     "Hello from " + self.to_s   #=> "Hello from main"
- */
-
-static VALUE
-rb_str_plus_imp(VALUE str1, SEL sel, VALUE str2)
-{
-    StringValue(str2);
-    VALUE str3 = rb_str_new(0, 0);
-    rb_str_buf_append(str3, str1);
-    rb_str_buf_append(str3, str2);
-    if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2)) {
-	OBJ_TAINT(str3);
+    for (long i = 0; i < length_in_bytes; i += 2) {
+	char tmp = bytes[i];
+	bytes[i] = bytes[i+1];
+	bytes[i+1] = tmp;
     }
-    return str3;
+    str_negate_stored_in_uchars(self);
 }
 
-VALUE
-rb_str_plus(VALUE str1, VALUE str2)
+static encoding_t *
+str_compatible_encoding(string_t *str1, string_t *str2)
 {
-    return rb_str_plus_imp(str1, 0, str2);
-}
-
-
-/*
- *  call-seq:
- *     str * integer   => new_str
- *  
- *  Copy---Returns a new <code>String</code> containing <i>integer</i> copies of
- *  the receiver.
- *     
- *     "Ho! " * 3   #=> "Ho! Ho! Ho! "
- */
-
-static VALUE
-rb_str_times(VALUE str, SEL sel, VALUE times)
-{
-    const long n = RSTRING_LEN(str);
-    const long len = NUM2LONG(times);
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative argument");
+    if (str1->encoding == str2->encoding) {
+	return str1->encoding;
     }
-    if (len && LONG_MAX/len < n) {
-	rb_raise(rb_eArgError, "argument too big");
+    if (str2->length_in_bytes == 0) {
+	return str1->encoding;
     }
-
-    VALUE str2 = rb_str_new3(str);
-    CFStringPad((CFMutableStringRef)str2, (CFStringRef)str,
-	    len * n, 0);
-    if (OBJ_TAINTED(str)) {
-	OBJ_TAINT(str2);
+    if (str1->length_in_bytes == 0) {
+	return str2->encoding;
     }
-
-    return str2;
-}
-
-/*
- *  call-seq:
- *     str % arg   => new_str
- *  
- *  Format---Uses <i>str</i> as a format specification, and returns the result
- *  of applying it to <i>arg</i>. If the format specification contains more than
- *  one substitution, then <i>arg</i> must be an <code>Array</code> containing
- *  the values to be substituted. See <code>Kernel::sprintf</code> for details
- *  of the format string.
- *     
- *     "%05d" % 123                              #=> "00123"
- *     "%-5s: %08x" % [ "ID", self.object_id ]   #=> "ID   : 200e14d6"
- */
-
-static VALUE
-rb_str_format_m(VALUE str, SEL sel, VALUE arg)
-{
-    VALUE tmp = rb_check_array_type(arg);
-
-    if (!NIL_P(tmp)) {
-	return rb_str_format(RARRAY_LEN(tmp), RARRAY_PTR(tmp), str);
+    if (!str1->encoding->ascii_compatible || !str2->encoding->ascii_compatible) {
+	return NULL;
     }
-    return rb_str_format(1, &arg, str);
-}
-
-static inline void
-str_modifiable(VALUE str)
-{
-    long mask = rb_objc_flag_get_mask((void *)str);
-    if (RSTRING_IMMUTABLE(str)) {
-	mask |= FL_FREEZE;
+    if (str_is_ruby_ascii_only(str1) && str_is_ruby_ascii_only(str2)) {
+	return str1->encoding;
     }
-    if ((mask & FL_FREEZE) == FL_FREEZE) {
-	rb_raise(rb_eRuntimeError, "can't modify frozen/immutable string");
-    }
-    if ((mask & FL_TAINT) == FL_TAINT && rb_safe_level() >= 4) {
-	rb_raise(rb_eSecurityError, "Insecure: can't modify string");
-    }
+    return NULL;
 }
 
-void
-rb_str_modify(VALUE str)
+static encoding_t *
+str_must_have_compatible_encoding(string_t *str1, string_t *str2)
 {
-#if WITH_OBJC
-    str_modifiable(str);
-#else
-    if (!str_independent(str)) {
-	str_make_independent(str);
+    encoding_t *new_encoding = str_compatible_encoding(str1, str2);
+    if (new_encoding == NULL) {
+	rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
+		str1->encoding->public_name, str2->encoding->public_name);
     }
-    ENC_CODERANGE_CLEAR(str);
-#endif
+    return new_encoding;
 }
 
-void
-rb_str_associate(VALUE str, VALUE add)
-{
-    /* sanity check */
-    if (OBJ_FROZEN(str)) rb_error_frozen("string");
-}
 
-VALUE
-rb_str_associated(VALUE str)
+static string_t *
+str_alloc(void)
 {
-    return Qfalse;
+    NEWOBJ(str, string_t);
+    str->basic.flags = 0;
+    str->basic.klass = rb_cMRString;
+    str->encoding = encodings[ENCODING_BINARY];
+    str->capacity_in_bytes = 0;
+    str->length_in_bytes = 0;
+    str->data.bytes = NULL;
+    str->flags = 0;
+    return str;
 }
 
-VALUE
-rb_string_value(volatile VALUE *ptr)
+extern VALUE rb_cString;
+extern VALUE rb_cCFString;
+extern VALUE rb_cNSString;
+extern VALUE rb_cNSMutableString;
+extern VALUE rb_cSymbol;
+extern VALUE rb_cByteString;
+
+static void
+str_replace_with_string(string_t *self, string_t *source)
 {
-    VALUE s = *ptr;
-    if (TYPE(s) != T_STRING) {
-	s = rb_str_to_str(s);
-	*ptr = s;
+    if (self == source) {
+	return;
     }
-#if 0 // Apparently not needed...
-    else if (CLASS_OF(s) == rb_cByteString) {
-	s = (VALUE)rb_bytestring_resolve_cfstring(s);
+    self->flags = 0;
+    self->encoding = source->encoding;
+    self->capacity_in_bytes = self->length_in_bytes = source->length_in_bytes;
+    self->flags = source->flags;
+    if (self->length_in_bytes != 0) {
+	GC_WB(&self->data.bytes, xmalloc(self->length_in_bytes));
+	memcpy(self->data.bytes, source->data.bytes, self->length_in_bytes);
     }
-#endif
-    return s;
 }
 
-char *
-rb_string_value_ptr(volatile VALUE *ptr)
+static void
+str_replace_with_cfstring(string_t *self, CFStringRef source)
 {
-    return (char *)RSTRING_PTR(rb_string_value(ptr));
-}
-
-const char *
-rb_str_cstr(VALUE ptr)
-{
-    if (*(VALUE *)ptr == rb_cSymbol) {
-	return RSYMBOL(ptr)->str;
+    self->flags = 0;
+    self->encoding = encodings[ENCODING_UTF16_NATIVE];
+    self->capacity_in_bytes = self->length_in_bytes = UCHARS_TO_BYTES(CFStringGetLength(source));
+    if (self->length_in_bytes != 0) {
+	GC_WB(&self->data.uchars, xmalloc(self->length_in_bytes));
+	CFStringGetCharacters((CFStringRef)source, CFRangeMake(0, BYTES_TO_UCHARS(self->length_in_bytes)), self->data.uchars);
+	str_set_stored_in_uchars(self, true);
     }
-    if (*(VALUE *)ptr == rb_cByteString) {
-	return (const char *)rb_bytestring_byte_pointer(ptr);
-    }
-
-    if (RSTRING_LEN(ptr) == 0) {
-	return "";
-    }
-
-    char *cptr = (char *)CFStringGetCStringPtr((CFStringRef)ptr, 0);
-    if (cptr != NULL) {
-	return cptr;
-    }
-
-    // XXX this is quite inefficient, but we don't really have a choice.
-
-    const long max = CFStringGetMaximumSizeForEncoding(
-	    CFStringGetLength((CFStringRef)ptr),
-	    kCFStringEncodingUTF8);
-
-    cptr = (char *)xmalloc(max + 1);
-    if (!CFStringGetCString((CFStringRef)ptr, cptr,
-		max + 1, kCFStringEncodingUTF8)) {
-	// Probably an UTF16 string...
-	xfree(cptr);
-	return NULL;
-    }
-
-    return cptr;
 }
 
-long
-rb_str_clen(VALUE ptr)
+static void
+str_replace(string_t *self, VALUE arg)
 {
-    return CFStringGetLength((CFStringRef)ptr);
-}
-
-char *
-rb_string_value_cstr(volatile VALUE *ptr)
-{
-    VALUE str = rb_string_value(ptr);
-    return (char *)rb_str_cstr(str);
-}
-
-VALUE
-rb_check_string_type(VALUE str)
-{
-    str = rb_check_convert_type(str, T_STRING, "String", "to_str");
-    return str;
-}
-
-/*
- *  call-seq:
- *     String.try_convert(obj) -> string or nil
- *
- *  Try to convert <i>obj</i> into a String, using to_str method.
- *  Returns converted regexp or nil if <i>obj</i> cannot be converted
- *  for any reason.
- *
- *     String.try_convert("str")     # => str
- *     String.try_convert(/re/)      # => nil
- */
-static VALUE
-rb_str_s_try_convert(VALUE dummy, SEL sel, VALUE str)
-{
-    return rb_check_string_type(str);
-}
-
-/* byte offset to char offset */
-long
-rb_str_sublen(VALUE str, long pos)
-{
-    return pos;
-}
-
-VALUE
-rb_str_subseq(VALUE str, long beg, long len)
-{
-    if (len < 0) {
-	return Qnil;
+    VALUE klass = CLASS_OF(arg);
+    if (klass == rb_cMRString) {
+	str_replace_with_string(self, STR(arg));
     }
-
-    const long n = CFStringGetLength((CFStringRef)str);
-
-    if (beg < 0) {
-	beg += n;
+    else if (klass == rb_cByteString) {
+	self->encoding = encodings[ENCODING_BINARY];
+	self->capacity_in_bytes = self->length_in_bytes = rb_bytestring_length(arg);
+	if (self->length_in_bytes != 0) {
+	    GC_WB(&self->data.bytes, xmalloc(self->length_in_bytes));
+	    assert(self->data.bytes != NULL);
+	    memcpy(self->data.bytes, rb_bytestring_byte_pointer(arg), self->length_in_bytes);
+	}
     }
-    if (beg > n || beg < 0) {
-	return Qnil;
+    else if (TYPE(arg) == T_STRING) {
+	str_replace_with_cfstring(self, (CFStringRef)arg);
     }
-    if (beg + len > n) {
-	len = n - beg;
+    else if (klass == rb_cSymbol) {
+	abort(); // TODO
     }
-
-    if (*(VALUE *)str == rb_cByteString) {
-	UInt8 *str_data = rb_bytestring_byte_pointer(str);
-	return rb_bytestring_new_with_data(str_data + beg, len);
-    }
-
-    CFMutableStringRef substr = CFStringCreateMutable(NULL, 0);
-
-    if (len == 1) {
-	UniChar c = CFStringGetCharacterAtIndex((CFStringRef)str, beg);
-	CFStringAppendCharacters(substr, &c, 1);
-    }
     else {
-	UniChar *buffer = alloca(sizeof(UniChar) * len);
-	CFStringGetCharacters((CFStringRef)str, CFRangeMake(beg, len), 
-		buffer);
-	CFStringAppendCharacters(substr, buffer, len);
+	str_replace(self, rb_str_to_str(arg));
     }
-
-    CFMakeCollectable(substr);
-
-    return (VALUE)substr;
 }
 
-VALUE
-rb_str_substr(VALUE str, long beg, long len)
+static string_t *
+str_dup(VALUE source)
 {
-    return rb_str_subseq(str, beg, len);
+    string_t *destination = str_alloc();
+    str_replace(destination, source);
+    return destination;
 }
 
-VALUE
-rb_str_dup_frozen(VALUE str)
+static void
+str_clear(string_t *self)
 {
-    str = rb_str_dup(str);
-    rb_str_freeze(str);
-    return str;
+    self->length_in_bytes = 0;
 }
 
-VALUE
-rb_str_locktmp(VALUE str)
+static string_t *
+str_new_from_string(string_t *source)
 {
-    return str;
+    string_t *destination = str_alloc();
+    str_replace_with_string(destination, source);
+    return destination;
 }
 
-VALUE
-rb_str_unlocktmp(VALUE str)
+static string_t *
+str_new_from_cfstring(CFStringRef source)
 {
-    return str;
+    string_t *destination = str_alloc();
+    str_replace_with_cfstring(destination, source);
+    return destination;
 }
 
-void
-rb_str_set_len(VALUE str, long len)
-{
-    rb_str_resize(str, len);    
-}
 
-VALUE
-rb_str_resize(VALUE str, long len)
-{
-    long slen;
-
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative string size (or size too big)");
-    }
-
-    rb_str_modify(str);
-    slen = RSTRING_LEN(str);
-    if (slen != len) {
-	CFStringPad((CFMutableStringRef)str, CFSTR(" "), len, 0);
-    }
-    return str;
-}
-
 static void
-rb_objc_str_cat(VALUE str, const char *ptr, long len, int cfstring_encoding)
+str_make_data_binary(string_t *self)
 {
-    if (*(VALUE *)str == rb_cByteString) {
-	CFMutableDataRef data = rb_bytestring_wrapped_data(str);
-	CFDataAppendBytes(data, (const UInt8 *)ptr, len);
+    if (!str_is_stored_in_uchars(self) || NATIVE_UTF16_ENC(self->encoding)) {
+	// nothing to do
+	return;
     }
-    else {
-	long plen = strlen(ptr);
-	if (plen >= len) {
-	    const char *cstr;
-	    if (plen > len) {
-		// Sometimes the given string is bigger than the given length.
-		char *tmp = alloca(len + 1);
-		strncpy(tmp, ptr, len);
-		tmp[len] = '\0';
-		cstr = (const char *)tmp;
-	    }
-	    else {
-		cstr = ptr;
-	    }
-	    CFStringAppendCString((CFMutableStringRef)str, cstr,
-		    cfstring_encoding);
-	}
-	else {
-	    // Promoting as bytestring!
-	    CFDataRef data = CFStringCreateExternalRepresentation(NULL,
-		    (CFStringRef)str, kCFStringEncodingUTF8, 0);
-	    assert(data != NULL);
-	    CFMutableDataRef mdata = CFDataCreateMutableCopy(NULL, 0, data);
-	    CFRelease(data);
 
-	    rb_bstr_t *bstr = (rb_bstr_t *)str;
-	    bstr->basic.klass = rb_cByteString;
-	    bstr->basic.flags = 0;
-	    GC_WB(&bstr->data, mdata);
-
-	    CFMakeCollectable(mdata);
-	}
+    if (NON_NATIVE_UTF16_ENC(self->encoding)) {
+	// Doing the conversion ourself is faster, and anyway ICU's converter
+	// does not like non-paired surrogates.
+	str_invert_byte_order(self);
+	return;
     }
-}
 
-VALUE
-rb_str_buf_cat(VALUE str, const char *ptr, long len)
-{
-    rb_objc_str_cat(str, ptr, len, kCFStringEncodingASCII);
-
-    return str;
+    self->encoding->methods.make_data_binary(self);
 }
 
-VALUE
-rb_str_buf_cat2(VALUE str, const char *ptr)
+static bool
+str_try_making_data_uchars(string_t *self)
 {
-    return rb_str_buf_cat(str, ptr, strlen(ptr));
-}
-
-VALUE
-rb_str_cat(VALUE str, const char *ptr, long len)
-{
-    if (len < 0) {
-	rb_raise(rb_eArgError, "negative string size (or size too big)");
+    if (str_is_stored_in_uchars(self)) {
+	return true;
     }
-
-    return rb_str_buf_cat(str, ptr, len);
-}
-
-VALUE
-rb_str_cat2(VALUE str, const char *ptr)
-{
-    return rb_str_cat(str, ptr, strlen(ptr));
-}
-
-VALUE
-rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *ptr_enc)
-{
-    rb_objc_str_cat(str, ptr, len, kCFStringEncodingUTF8);
-    return str;
-}
-
-VALUE
-rb_str_buf_cat_ascii(VALUE str, const char *ptr)
-{
-    rb_objc_str_cat(str, ptr, strlen(ptr), kCFStringEncodingASCII);
-    return str;
-}
-
-static inline VALUE
-rb_str_buf_append0(VALUE str, VALUE str2)
-{
-    if (TYPE(str2) != T_SYMBOL) {
-	Check_Type(str2, T_STRING);
+    else if (NON_NATIVE_UTF16_ENC(self->encoding)) {
+	str_invert_byte_order(self);
+	return true;
     }
-
-    CFStringAppend((CFMutableStringRef)str, (CFStringRef)str2);
-
-#if 0
-    const char *ptr;
-    long len;
-
-    ptr = RSTRING_PTR(str2);
-    len = RSTRING_LEN(str2);
-
-    rb_objc_str_cat(str, ptr, len, kCFStringEncodingASCII);
-#endif
-
-    return str;
-}
-
-VALUE
-rb_str_buf_append(VALUE str, VALUE str2)
-{
-   return rb_str_buf_append0(str, str2);
-}
-
-VALUE
-rb_str_append(VALUE str, VALUE str2)
-{
-    StringValue(str2);
-    rb_str_modify(str);
-    return rb_str_buf_append0(str, str2);
-}
-
-
-/*
- *  call-seq:
- *     str << fixnum        => str
- *     str.concat(fixnum)   => str
- *     str << obj           => str
- *     str.concat(obj)      => str
- *  
- *  Append---Concatenates the given object to <i>str</i>. If the object is a
- *  <code>Fixnum</code>, it is considered as a codepoint, and is converted
- *  to a character before concatenation.
- *     
- *     a = "hello "
- *     a << "world"   #=> "hello world"
- *     a.concat(33)   #=> "hello world!"
- */
-
-static VALUE
-rb_str_concat_imp(VALUE str1, SEL sel, VALUE str2)
-{
-    if (FIXNUM_P(str2)) {
-        int c = FIX2INT(str2);
-	char buf[2];
-
-	rb_str_modify(str1);
-	buf[0] = (char)c;
-	buf[1] = '\0';
-	CFStringAppendCString((CFMutableStringRef)str1, buf, 
-			      kCFStringEncodingUTF8);
-	return str1;
+    else if (BINARY_ENC(self->encoding)) {
+	// you can't convert binary to anything
+	return false;
     }
-    return rb_str_append(str1, str2);
-}
+    else if (self->length_in_bytes == 0) {
+	// for empty strings, nothing to convert
+	str_set_stored_in_uchars(self, true);
+	return true;
+    }
+    else if (str_known_to_have_an_invalid_encoding(self)) {
+	return false;
+    }
 
-VALUE
-rb_str_concat(VALUE str1, VALUE str2)
-{
-    return rb_str_concat_imp(str1, 0, str2);
+    return self->encoding->methods.try_making_data_uchars(self);
 }
 
-int
-rb_memhash(const void *ptr, long len)
+static void
+str_make_same_format(string_t *str1, string_t *str2)
 {
-    CFDataRef data;
-    int code;
-
-    data = CFDataCreate(NULL, (const UInt8 *)ptr, len);
-    code = CFHash(data);
-    CFRelease((CFTypeRef)data);
-    return code;
-}
-
-int
-rb_str_hash(VALUE str)
-{
-    return CFHash((CFTypeRef)str);
-}
-
-int
-rb_str_hash_cmp(VALUE str1, VALUE str2)
-{
-    return CFEqual((CFTypeRef)str1, (CFTypeRef)str2) ? 0 : 1;
-}
-
-#define lesser(a,b) (((a)>(b))?(b):(a))
-
-int
-rb_str_comparable(VALUE str1, VALUE str2)
-{
-    return Qtrue;
-}
-
-int
-rb_str_cmp(VALUE str1, VALUE str2)
-{
-    return CFStringCompare((CFStringRef)str1, (CFStringRef)str2, 0);
-}
-
-bool rb_objc_str_is_pure(VALUE);
-
-/*
- *  call-seq:
- *     str == obj   => true or false
- *  
- *  Equality---If <i>obj</i> is not a <code>String</code>, returns
- *  <code>false</code>. Otherwise, returns <code>true</code> if <i>str</i>
- *  <code><=></code> <i>obj</i> returns zero.
- */
-
-static VALUE
-rb_str_equal_imp(VALUE str1, SEL sel, VALUE str2)
-{
-    if (str1 == str2) {
-	return Qtrue;
-    }
-    if (TYPE(str2) != T_STRING) {
-	if (!rb_respond_to(str2, rb_intern("to_str"))) {
-	    return Qfalse;
+    if (str_is_stored_in_uchars(str1) != str_is_stored_in_uchars(str2)) {
+	if (str_is_stored_in_uchars(str1)) {
+	    if (!str_try_making_data_uchars(str2)) {
+		str_make_data_binary(str1);
+	    }
 	}
-	return rb_equal(str2, str1);
-    }
-    if (*(VALUE *)str1 == *(VALUE *)str2) {
-	if (RSTRING_LEN(str1) != RSTRING_LEN(str2)) {
-	    return Qfalse;
+	else {
+	    str_make_data_binary(str2);
 	}
     }
-    if (!rb_objc_str_is_pure(str2)) {
-	/* This is to work around a strange bug in CFEqual's objc 
-	 * dispatching.
-	 */
-	VALUE tmp = str1;
-	str1 = str2;
-	str2 = tmp;
-    }
-    return CFEqual((CFTypeRef)str1, (CFTypeRef)str2) ? Qtrue : Qfalse;
 }
 
-VALUE
-rb_str_equal(VALUE str1, VALUE str2)
+static long
+str_length(string_t *self, bool ucs2_mode)
 {
-    return rb_str_equal_imp(str1, 0, str2);
-}
-
-/*
- * call-seq:
- *   str.eql?(other)   => true or false
- *
- * Two strings are equal if the have the same length and content.
- */
-
-static VALUE
-rb_str_eql(VALUE str1, SEL sel, VALUE str2)
-{
-    if (TYPE(str2) != T_STRING) {
-	return Qfalse;
+    if (self->length_in_bytes == 0) {
+	return 0;
     }
-
-    if (CFEqual((CFTypeRef)str1, (CFTypeRef)str2)) {
-	return Qtrue;
-    }
-
-    return Qfalse;
-}
-
-/*
- *  call-seq:
- *     str <=> other_str   => -1, 0, +1
- *  
- *  Comparison---Returns -1 if <i>other_str</i> is less than, 0 if
- *  <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than
- *  <i>str</i>. If the strings are of different lengths, and the strings are
- *  equal when compared up to the shortest length, then the longer string is
- *  considered greater than the shorter one. In older versions of Ruby, setting
- *  <code>$=</code> allowed case-insensitive comparisons; this is now deprecated
- *  in favor of using <code>String#casecmp</code>.
- *
- *  <code><=></code> is the basis for the methods <code><</code>,
- *  <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>,
- *  included from module <code>Comparable</code>.  The method
- *  <code>String#==</code> does not use <code>Comparable#==</code>.
- *     
- *     "abcdef" <=> "abcde"     #=> 1
- *     "abcdef" <=> "abcdef"    #=> 0
- *     "abcdef" <=> "abcdefg"   #=> -1
- *     "abcdef" <=> "ABCDEF"    #=> 1
- */
-
-static VALUE
-rb_str_cmp_m(VALUE str1, SEL sel, VALUE str2)
-{
-    long result;
-
-    if (TYPE(str2) != T_STRING) {
-	if (!rb_respond_to(str2, rb_intern("to_str"))) {
-	    return Qnil;
+    if (str_is_stored_in_uchars(self)) {
+	long length;
+	if (ucs2_mode) {
+	    length = BYTES_TO_UCHARS(self->length_in_bytes);
 	}
-	else if (!rb_respond_to(str2, rb_intern("<=>"))) {
-	    return Qnil;
+	else {
+	    // we must return the length in Unicode code points,
+	    // not the number of UChars, even if the probability
+	    // we have surrogates is very low
+	    length = u_countChar32(self->data.uchars, BYTES_TO_UCHARS(self->length_in_bytes));
 	}
+	if (ODD_NUMBER(self->length_in_bytes)) {
+	    return length + 1;
+	}
 	else {
-	    VALUE tmp = rb_funcall(str2, rb_intern("<=>"), 1, str1);
-
-	    if (NIL_P(tmp)) return Qnil;
-	    if (!FIXNUM_P(tmp)) {
-		return rb_funcall(LONG2FIX(0), '-', 1, tmp);
-	    }
-	    result = -FIX2LONG(tmp);
+	    return length;
 	}
     }
     else {
-	result = rb_str_cmp(str1, str2);
-    }
-    return LONG2NUM(result);
-}
-
-/*
- *  call-seq:
- *     str.casecmp(other_str)   => -1, 0, +1
- *  
- *  Case-insensitive version of <code>String#<=></code>.
- *     
- *     "abcdef".casecmp("abcde")     #=> 1
- *     "aBcDeF".casecmp("abcdef")    #=> 0
- *     "abcdef".casecmp("abcdefg")   #=> -1
- *     "abcdef".casecmp("ABCDEF")    #=> 0
- */
-
-static VALUE
-rb_str_casecmp(VALUE str1, SEL sel, VALUE str2)
-{
-    return INT2FIX(CFStringCompare((CFStringRef)str1, (CFStringRef)str2,
-	kCFCompareCaseInsensitive));
-}
-
-static long
-rb_str_index(VALUE str, VALUE sub, long offset)
-{
-    CFRange r;
-    return (CFStringFindWithOptions((CFStringRef)str, 
-		(CFStringRef)sub,
-		CFRangeMake(offset, CFStringGetLength((CFStringRef)str) - offset),
-		0,
-		&r))
-	? r.location : -1;
-}
-
-/*
- *  call-seq:
- *     str.index(substring [, offset])   => fixnum or nil
- *     str.index(fixnum [, offset])      => fixnum or nil
- *     str.index(regexp [, offset])      => fixnum or nil
- *  
- *  Returns the index of the first occurrence of the given <i>substring</i>,
- *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
- *  <code>nil</code> if not found. If the second parameter is present, it
- *  specifies the position in the string to begin the search.
- *     
- *     "hello".index('e')             #=> 1
- *     "hello".index('lo')            #=> 3
- *     "hello".index('a')             #=> nil
- *     "hello".index(?e)              #=> 1
- *     "hello".index(101)             #=> 1
- *     "hello".index(/[aeiou]/, -3)   #=> 4
- */
-
-static VALUE
-rb_str_index_m(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE sub;
-    VALUE initpos;
-    long pos;
-
-    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
-	pos = NUM2LONG(initpos);
-    }
-    else {
-	pos = 0;
-    }
-    if (pos < 0) {
-	pos += str_strlen(str, STR_ENC_GET(str));
-	if (pos < 0) {
-	    if (TYPE(sub) == T_REGEXP) {
-		rb_backref_set(Qnil);
-	    }
-	    return Qnil;
+	if (self->encoding->single_byte_encoding) {
+	    return self->length_in_bytes;
 	}
-    }
-
-    switch (TYPE(sub)) {
-      case T_REGEXP:
-	pos = rb_reg_adjust_startpos(sub, str, pos, 0);
-	pos = rb_reg_search(sub, str, pos, 0);
-	pos = rb_str_sublen(str, pos);
-	break;
-
-      default: {
-	VALUE tmp;
-
-	tmp = rb_check_string_type(sub);
-	if (NIL_P(tmp)) {
-	    rb_raise(rb_eTypeError, "type mismatch: %s given",
-		     rb_obj_classname(sub));
+	else if (ucs2_mode && NON_NATIVE_UTF16_ENC(self->encoding)) {
+	    return div_round_up(self->length_in_bytes, 2);
 	}
-	sub = tmp;
-      }
-	/* fall through */
-      case T_STRING:
-	pos = rb_str_index(str, sub, pos);
-	pos = rb_str_sublen(str, pos);
-	break;
+	else {
+	    return self->encoding->methods.length(self, ucs2_mode);
+	}
     }
-
-    if (pos == -1) return Qnil;
-    return LONG2NUM(pos);
 }
 
 static long
-rb_str_rindex(VALUE str, VALUE sub, long pos)
+str_bytesize(string_t *self)
 {
-    CFRange r;
-    long sublen, strlen;
-    sublen = RSTRING_LEN(sub);
-    strlen = RSTRING_LEN(str);
-    if (sublen == 0 && strlen == 0)
-	return 0;
-    if (pos <= sublen) {
-	pos = strlen < sublen ? strlen : sublen;
-    }
-    return (CFStringFindWithOptions((CFStringRef)str, 
-		(CFStringRef)sub,
-		CFRangeMake(0, pos+1),
-		kCFCompareBackwards,
-		&r))
-	? r.location : -1;
-}
-
-
-/*
- *  call-seq:
- *     str.rindex(substring [, fixnum])   => fixnum or nil
- *     str.rindex(fixnum [, fixnum])   => fixnum or nil
- *     str.rindex(regexp [, fixnum])   => fixnum or nil
- *  
- *  Returns the index of the last occurrence of the given <i>substring</i>,
- *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
- *  <code>nil</code> if not found. If the second parameter is present, it
- *  specifies the position in the string to end the search---characters beyond
- *  this point will not be considered.
- *     
- *     "hello".rindex('e')             #=> 1
- *     "hello".rindex('l')             #=> 3
- *     "hello".rindex('a')             #=> nil
- *     "hello".rindex(?e)              #=> 1
- *     "hello".rindex(101)             #=> 1
- *     "hello".rindex(/[aeiou]/, -2)   #=> 1
- */
-
-static VALUE
-rb_str_rindex_m(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE sub;
-    VALUE vpos;
-    rb_encoding *enc = STR_ENC_GET(str);
-    long pos, len = str_strlen(str, enc);
-
-    if (rb_scan_args(argc, argv, "11", &sub, &vpos) == 2) {
-	pos = NUM2LONG(vpos);
-	if (pos < 0) {
-	    pos += len;
-	    if (pos < 0) {
-		if (TYPE(sub) == T_REGEXP) {
-		    rb_backref_set(Qnil);
-		}
-		return Qnil;
-	    }
+    if (str_is_stored_in_uchars(self)) {
+	if (UTF16_ENC(self->encoding)) {
+	    return self->length_in_bytes;
 	}
-	if (pos > len) pos = len;
+	else {
+	    return self->encoding->methods.bytesize(self);
+	}
     }
     else {
-	pos = len;
+	return self->length_in_bytes;
     }
-
-    switch (TYPE(sub)) {
-      case T_REGEXP:
-	/* enc = rb_get_check(str, sub); */
-	if (RREGEXP(sub)->len) {
-	    pos = rb_reg_adjust_startpos(sub, str, pos, 1);
-	    pos = rb_reg_search(sub, str, pos, 1);
-	    pos = rb_str_sublen(str, pos);
-	}
-	if (pos >= 0) return LONG2NUM(pos);
-	break;
-
-      default:
-	StringValue(sub);
-	/* fall through */
-      case T_STRING:
-	pos = rb_str_rindex(str, sub, pos);
-	if (pos >= 0) return LONG2NUM(pos);
-	break;
-    }
-    return Qnil;
 }
 
-/*
- *  call-seq:
- *     str =~ obj   => fixnum or nil
- *  
- *  Match---If <i>obj</i> is a <code>Regexp</code>, use it as a pattern to match
- *  against <i>str</i>,and returns the position the match starts, or 
- *  <code>nil</code> if there is no match. Otherwise, invokes
- *  <i>obj.=~</i>, passing <i>str</i> as an argument. The default
- *  <code>=~</code> in <code>Object</code> returns <code>false</code>.
- *     
- *     "cat o' 9 tails" =~ /\d/   #=> 7
- *     "cat o' 9 tails" =~ 9      #=> nil
- */
-
-static VALUE
-rb_str_match(VALUE x, SEL sel, VALUE y)
+static bool
+str_getbyte(string_t *self, long index, unsigned char *c)
 {
-    switch (TYPE(y)) {
-      case T_STRING:
-	rb_raise(rb_eTypeError, "type mismatch: String given");
-
-      case T_REGEXP:
-	return rb_reg_match(y, x);
-
-      default:
-	return rb_funcall(y, rb_intern("=~"), 1, x);
-    }
-}
-
-
-static VALUE get_pat(VALUE, int);
-
-
-/*
- *  call-seq:
- *     str.match(pattern)   => matchdata or nil
- *  
- *  Converts <i>pattern</i> to a <code>Regexp</code> (if it isn't already one),
- *  then invokes its <code>match</code> method on <i>str</i>.  If the second
- *  parameter is present, it specifies the position in the string to begin the
- *  search.
- *     
- *     'hello'.match('(.)\1')      #=> #<MatchData "ll" 1:"l">
- *     'hello'.match('(.)\1')[0]   #=> "ll"
- *     'hello'.match(/(.)\1/)[0]   #=> "ll"
- *     'hello'.match('xx')         #=> nil
- *     
- *  If a block is given, invoke the block with MatchData if match succeed, so
- *  that you can write
- *     
- *     str.match(pat) {|m| ...}
- *     
- *  instead of
- *      
- *     if m = str.match(pat)
- *       ...
- *     end
- *      
- *  The return value is a value from block execution in this case.
- */
-
-VALUE rb_reg_match_m(VALUE re, SEL sel, int argc, VALUE *argv);
-
-static VALUE
-rb_str_match_m(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    if (argc < 1) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
-    }
-    VALUE re = argv[0];
-    argv[0] = str;
-    VALUE result = rb_reg_match_m(get_pat(re, 0), 0, argc, argv);
-    if (!NIL_P(result) && rb_block_given_p()) {
-	return rb_yield(result);
-    }
-    return result;
-}
-
-/*
- *  call-seq:
- *     str.succ   => new_str
- *     str.next   => new_str
- *  
- *  Returns the successor to <i>str</i>. The successor is calculated by
- *  incrementing characters starting from the rightmost alphanumeric (or
- *  the rightmost character if there are no alphanumerics) in the
- *  string. Incrementing a digit always results in another digit, and
- *  incrementing a letter results in another letter of the same case.
- *  Incrementing nonalphanumerics uses the underlying character set's
- *  collating sequence.
- *     
- *  If the increment generates a ``carry,'' the character to the left of
- *  it is incremented. This process repeats until there is no carry,
- *  adding an additional character if necessary.
- *     
- *     "abcd".succ        #=> "abce"
- *     "THX1138".succ     #=> "THX1139"
- *     "<<koala>>".succ   #=> "<<koalb>>"
- *     "1999zzz".succ     #=> "2000aaa"
- *     "ZZZ9999".succ     #=> "AAAA0000"
- *     "***".succ         #=> "**+"
- */
-
-static VALUE
-rb_str_succ(VALUE orig, SEL sel)
-{
-    UniChar *buf;
-    UniChar carry;
-    long i, len;
-    bool modified;
-
-    len = CFStringGetLength((CFStringRef)orig);
-    if (len == 0)
-	return orig;
-
-    buf = (UniChar *)alloca(sizeof(UniChar) * (len + 1));
-    buf++;
-    
-    CFStringGetCharacters((CFStringRef)orig, CFRangeMake(0, len), buf);
-    modified = false;
-    carry = 0;
-
-    for (i = len - 1; i >= 0; i--) {
-	UniChar c = buf[i];
-	if (iswdigit(c)) {
-	    modified = true;
-	    if (c != '9') {
-		buf[i]++;
-		carry = 0;
-		break;
+    if (str_is_stored_in_uchars(self) && NATIVE_UTF16_ENC(self->encoding)) {
+	if (index < 0) {
+	    index += self->length_in_bytes;
+	    if (index < 0) {
+		return false;
 	    }
-	    else {
-		buf[i] = '0';
-		carry = '1';
-	    }
 	}
-	else if (iswalpha(c)) {
-	    bool lower = islower(c);
-	    UniChar e = lower ? 'z' : 'Z';
-	    modified = true;
-	    if (c != e) {
-		buf[i]++;
-		carry = 0;
-		break;
+	if (index >= self->length_in_bytes) {
+	    return false;
+	}
+	if (NATIVE_UTF16_ENC(self->encoding)) {
+	    *c = self->data.bytes[index];
+	}
+	else { // non native byte-order UTF-16
+	    if ((index & 1) == 0) { // even
+		*c = self->data.bytes[index+1];
 	    }
-	    else {
-		carry = buf[i] = lower ? 'a' : 'A';
+	    else { // odd
+		*c = self->data.bytes[index-1];
 	    }
 	}
     }
+    else {
+	// work with a binary string
+	// (UTF-16 strings could be converted to their binary form
+	//  on the fly but that would just add complexity)
+	str_make_data_binary(self);
 
-    if (!modified) {
-	buf[len-1]++;
-    }
-    else if (carry != 0) {
-	buf--;
-	*buf = carry;
-	len++;
-    }
-
-    CFMutableStringRef newstr;
-
-    newstr = CFStringCreateMutable(NULL, 0);
-    CFStringAppendCharacters(newstr, buf, len);
-    CFMakeCollectable(newstr);
-
-    return (VALUE)newstr;
-}
-
-
-/*
- *  call-seq:
- *     str.succ!   => str
- *     str.next!   => str
- *  
- *  Equivalent to <code>String#succ</code>, but modifies the receiver in
- *  place.
- */
-
-static VALUE
-rb_str_succ_bang(VALUE str, SEL sel)
-{
-    rb_str_shared_replace(str, rb_str_succ(str, 0));
-
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.upto(other_str, exclusive=false) {|s| block }   => str
- *  
- *  Iterates through successive values, starting at <i>str</i> and
- *  ending at <i>other_str</i> inclusive, passing each value in turn to
- *  the block. The <code>String#succ</code> method is used to generate
- *  each value.  If optional second argument exclusive is omitted or is <code>false</code>,
- *  the last value will be included; otherwise it will be excluded.
- *     
- *     "a8".upto("b6") {|s| print s, ' ' }
- *     for s in "a8".."b6"
- *       print s, ' '
- *     end
- *     
- *  <em>produces:</em>
- *     
- *     a8 a9 b0 b1 b2 b3 b4 b5 b6
- *     a8 a9 b0 b1 b2 b3 b4 b5 b6
- */
-
-static VALUE
-rb_str_upto(VALUE beg, SEL sel, int argc, VALUE *argv)
-{
-    VALUE end, exclusive;
-    VALUE current, after_end;
-    ID succ;
-    int n, excl;
-
-    rb_scan_args(argc, argv, "11", &end, &exclusive);
-    excl = RTEST(exclusive);
-    succ = rb_intern("succ");
-    StringValue(end);
-    if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1) {
-	UniChar c = CFStringGetCharacterAtIndex((CFStringRef)beg, 0);
-	UniChar e = CFStringGetCharacterAtIndex((CFStringRef)end, 0);
-	
-	if (c > e || (excl && c == e)) 
-	    return beg;
-	for (;;) {
-	    CFMutableStringRef substr;
-	    substr = CFStringCreateMutable(NULL, 0);
-	    CFStringAppendCharacters(substr, &c, 1);
-	    CFMakeCollectable(substr);
-	    rb_yield((VALUE)substr);
-	    RETURN_IF_BROKEN();
-	    if (!excl && c == e) 
-		break;
-	    c++;
-	    if (excl && c == e) 
-		break;
-	}
-	return beg;
-    }
-    n = rb_str_cmp(beg, end);
-    if (n > 0 || (excl && n == 0)) return beg;
-	
-    after_end = rb_funcall(end, succ, 0, 0);
-    current = beg;
-    while (!rb_str_equal(current, after_end)) {
-	rb_yield(current);
-	RETURN_IF_BROKEN();
-	if (!excl && rb_str_equal(current, end)) break;
-	current = rb_funcall(current, succ, 0, 0);
-	StringValue(current);
-	if (excl && rb_str_equal(current, end)) break;
-	if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0)
-	    break;
-    }
-
-    return beg;
-}
-
-static VALUE
-rb_str_subpat(VALUE str, VALUE re, int nth)
-{
-    if (rb_reg_search(re, str, 0, 0) >= 0) {
-	return rb_reg_nth_match(nth, rb_backref_get());
-    }
-    return Qnil;
-}
-
-static VALUE
-rb_str_aref(VALUE str, VALUE indx)
-{
-    long idx;
-
-    switch (TYPE(indx)) {
-      case T_FIXNUM:
-	idx = FIX2LONG(indx);
-
-      num_index:
-	str = rb_str_substr(str, idx, 1);
-	if (!NIL_P(str) && RSTRING_LEN(str) == 0) return Qnil;
-	return str;
-
-      case T_REGEXP:
-	return rb_str_subpat(str, indx, 0);
-
-      case T_STRING:
-	if (rb_str_index(str, indx, 0) != -1)
-	    return rb_str_dup(indx);
-	return Qnil;
-
-      default:
-	/* check if indx is Range */
-	{
-	    long beg, len;
-	    VALUE tmp;
-
-	    len = str_strlen(str, STR_ENC_GET(str));
-	    switch (rb_range_beg_len(indx, &beg, &len, len, 0)) {
-	      case Qfalse:
-		break;
-	      case Qnil:
-		return Qnil;
-	      default:
-		tmp = rb_str_substr(str, beg, len);
-		return tmp;
+	if (index < 0) {
+	    index += self->length_in_bytes;
+	    if (index < 0) {
+		return false;
 	    }
 	}
-	idx = NUM2LONG(indx);
-	goto num_index;
-    }
-    return Qnil;		/* not reached */
-}
-
-
-/*
- *  call-seq:
- *     str[fixnum]                 => new_str or nil
- *     str[fixnum, fixnum]         => new_str or nil
- *     str[range]                  => new_str or nil
- *     str[regexp]                 => new_str or nil
- *     str[regexp, fixnum]         => new_str or nil
- *     str[other_str]              => new_str or nil
- *     str.slice(fixnum)           => new_str or nil
- *     str.slice(fixnum, fixnum)   => new_str or nil
- *     str.slice(range)            => new_str or nil
- *     str.slice(regexp)           => new_str or nil
- *     str.slice(regexp, fixnum)   => new_str or nil
- *     str.slice(other_str)        => new_str or nil
- *  
- *  Element Reference---If passed a single <code>Fixnum</code>, returns a
- *  substring of one character at that position. If passed two <code>Fixnum</code>
- *  objects, returns a substring starting at the offset given by the first, and
- *  a length given by the second. If given a range, a substring containing
- *  characters at offsets given by the range is returned. In all three cases, if
- *  an offset is negative, it is counted from the end of <i>str</i>. Returns
- *  <code>nil</code> if the initial offset falls outside the string, the length
- *  is negative, or the beginning of the range is greater than the end.
- *     
- *  If a <code>Regexp</code> is supplied, the matching portion of <i>str</i> is
- *  returned. If a numeric parameter follows the regular expression, that
- *  component of the <code>MatchData</code> is returned instead. If a
- *  <code>String</code> is given, that string is returned if it occurs in
- *  <i>str</i>. In both cases, <code>nil</code> is returned if there is no
- *  match.
- *     
- *     a = "hello there"
- *     a[1]                   #=> "e"
- *     a[1,3]                 #=> "ell"
- *     a[1..3]                #=> "ell"
- *     a[-3,2]                #=> "er"
- *     a[-4..-2]              #=> "her"
- *     a[12..-1]              #=> nil
- *     a[-2..-4]              #=> ""
- *     a[/[aeiou](.)\1/]      #=> "ell"
- *     a[/[aeiou](.)\1/, 0]   #=> "ell"
- *     a[/[aeiou](.)\1/, 1]   #=> "l"
- *     a[/[aeiou](.)\1/, 2]   #=> nil
- *     a["lo"]                #=> "lo"
- *     a["bye"]               #=> nil
- */
-
-static VALUE
-rb_str_aref_m(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    if (argc == 2) {
-	if (TYPE(argv[0]) == T_REGEXP) {
-	    return rb_str_subpat(str, argv[0], NUM2INT(argv[1]));
+	if (index >= self->length_in_bytes) {
+	    return false;
 	}
-	return rb_str_substr(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]));
+	*c = self->data.bytes[index];
     }
-    if (argc != 1) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
-    }
-    return rb_str_aref(str, argv[0]);
+    return true;
 }
 
 static void
-rb_str_splice_0(VALUE str, long beg, long len, VALUE val)
+str_setbyte(string_t *self, long index, unsigned char value)
 {
-    rb_str_modify(str);
-    CFStringReplace((CFMutableStringRef)str, CFRangeMake(beg, len), 
-	(CFStringRef)val);
-}
-
-static void
-rb_str_splice(VALUE str, long beg, long len, VALUE val)
-{
-    long slen;
-
-    if (len < 0) {
-	rb_raise(rb_eIndexError, "negative length %ld", len);
+    str_make_data_binary(self);
+    if ((index < -self->length_in_bytes) || (index >= self->length_in_bytes)) {
+	rb_raise(rb_eIndexError, "index %ld out of string", index);
     }
-
-    StringValue(val);
-    rb_str_modify(str);
-    slen = CFStringGetLength((CFStringRef)str);
-
-    if (slen < beg) {
-out_of_range:
-	rb_raise(rb_eIndexError, "index %ld out of string", beg);
+    if (index < 0) {
+	index += self->length_in_bytes;
     }
-    if (beg < 0) {
-	if (-beg > slen) {
-	    goto out_of_range;
-	}
-	beg += slen;
-    }
-    if (slen < len || slen < beg + len) {
-	len = slen - beg;
-    }
-    rb_str_splice_0(str, beg, len, val);
-
-    if (OBJ_TAINTED(val)) {
-	OBJ_TAINT(str);
-    }
+    self->data.bytes[index] = value;
 }
 
-void
-rb_str_update(VALUE str, long beg, long len, VALUE val)
-{
-    rb_str_splice(str, beg, len, val);
-}
-
 static void
-rb_str_subpat_set(VALUE str, VALUE re, int nth, VALUE val)
+str_force_encoding(string_t *self, encoding_t *enc)
 {
-    VALUE match;
-    long start, end, len;
-    struct re_registers *regs;
-
-    if (rb_reg_search(re, str, 0, 0) < 0) {
-	rb_raise(rb_eIndexError, "regexp not matched");
+    if (enc == self->encoding) {
+	return;
     }
-    match = rb_backref_get();
-    regs = RMATCH_REGS(match);
-    if (nth >= regs->num_regs) {
-      out_of_range:
-	rb_raise(rb_eIndexError, "index %d out of regexp", nth);
+    str_make_data_binary(self);
+    if (NATIVE_UTF16_ENC(self->encoding)) {
+	str_set_stored_in_uchars(self, false);
     }
-    if (nth < 0) {
-	if (-nth >= regs->num_regs) {
-	    goto out_of_range;
-	}
-	nth += regs->num_regs;
+    self->encoding = enc;
+    str_unset_facultative_flags(self);
+    if (NATIVE_UTF16_ENC(self->encoding)) {
+	str_set_stored_in_uchars(self, true);
     }
-
-    start = BEG(nth);
-    if (start == -1) {
-	rb_raise(rb_eIndexError, "regexp group %d not matched", nth);
-    }
-    end = END(nth);
-    len = end - start;
-    StringValue(val);
-    rb_str_splice_0(str, start, len, val);
 }
 
-static VALUE
-rb_str_aset(VALUE str, VALUE indx, VALUE val)
+static string_t *
+str_new_similar_empty_string(string_t *self)
 {
-    long idx, beg;
-
-    switch (TYPE(indx)) {
-	case T_FIXNUM:
-	    idx = FIX2LONG(indx);
-num_index:
-	    rb_str_splice(str, idx, 1, val);
-	    return val;
-
-	case T_REGEXP:
-	    rb_str_subpat_set(str, indx, 0, val);
-	    return val;
-
-	case T_STRING:
-	    beg = rb_str_index(str, indx, 0);
-	    if (beg < 0) {
-		rb_raise(rb_eIndexError, "string not matched");
-	    }
-	    beg = rb_str_sublen(str, beg);
-	    rb_str_splice(str, beg, str_strlen(indx, 0), val);
-	    return val;
-
-	default:
-	    /* check if indx is Range */
-	    {
-		long beg, len;
-		if (rb_range_beg_len(indx, &beg, &len, str_strlen(str, 0), 2)) {
-		    rb_str_splice(str, beg, len, val);
-		    return val;
-		}
-	    }
-	    idx = NUM2LONG(indx);
-	    goto num_index;
-    }
+    string_t *str = str_alloc();
+    str->encoding = self->encoding;
+    str->flags = self->flags & STRING_REQUIRED_FLAGS;
+    return str;
 }
 
-/*
- *  call-seq:
- *     str[fixnum] = new_str
- *     str[fixnum, fixnum] = new_str
- *     str[range] = aString
- *     str[regexp] = new_str
- *     str[regexp, fixnum] = new_str
- *     str[other_str] = new_str
- *  
- *  Element Assignment---Replaces some or all of the content of <i>str</i>. The
- *  portion of the string affected is determined using the same criteria as
- *  <code>String#[]</code>. If the replacement string is not the same length as
- *  the text it is replacing, the string will be adjusted accordingly. If the
- *  regular expression or string is used as the index doesn't match a position
- *  in the string, <code>IndexError</code> is raised. If the regular expression
- *  form is used, the optional second <code>Fixnum</code> allows you to specify
- *  which portion of the match to replace (effectively using the
- *  <code>MatchData</code> indexing rules. The forms that take a
- *  <code>Fixnum</code> will raise an <code>IndexError</code> if the value is
- *  out of range; the <code>Range</code> form will raise a
- *  <code>RangeError</code>, and the <code>Regexp</code> and <code>String</code>
- *  forms will silently ignore the assignment.
- */
-
-static VALUE
-rb_str_aset_m(VALUE str, SEL sel, int argc, VALUE *argv)
+static string_t *
+str_new_copy_of_part(string_t *self, long offset_in_bytes, long length_in_bytes)
 {
-    if (argc == 3) {
-	if (TYPE(argv[0]) == T_REGEXP) {
-	    rb_str_subpat_set(str, argv[0], NUM2INT(argv[1]), argv[2]);
-	}
-	else {
-	    rb_str_splice(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
-	}
-	return argv[2];
-    }
-    if (argc != 2) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
-    }
-    return rb_str_aset(str, argv[0], argv[1]);
-}
-
-/*
- *  call-seq:
- *     str.insert(index, other_str)   => str
- *  
- *  Inserts <i>other_str</i> before the character at the given
- *  <i>index</i>, modifying <i>str</i>. Negative indices count from the
- *  end of the string, and insert <em>after</em> the given character.
- *  The intent is insert <i>aString</i> so that it starts at the given
- *  <i>index</i>.
- *     
- *     "abcd".insert(0, 'X')    #=> "Xabcd"
- *     "abcd".insert(3, 'X')    #=> "abcXd"
- *     "abcd".insert(4, 'X')    #=> "abcdX"
- *     "abcd".insert(-3, 'X')   #=> "abXcd"
- *     "abcd".insert(-1, 'X')   #=> "abcdX"
- */
-
-static VALUE
-rb_str_insert(VALUE str, SEL sel, VALUE idx, VALUE str2)
-{
-    long pos = NUM2LONG(idx);
-
-    if (pos == -1) {
-	return rb_str_append(str, str2);
-    }
-    else if (pos < 0) {
-	pos++;
-    }
-    rb_str_splice(str, pos, 0, str2);
+    string_t *str = str_alloc();
+    str->encoding = self->encoding;
+    str->capacity_in_bytes = str->length_in_bytes = length_in_bytes;
+    str->flags = self->flags & STRING_REQUIRED_FLAGS;
+    GC_WB(&str->data.bytes, xmalloc(length_in_bytes));
+    memcpy(str->data.bytes, &self->data.bytes[offset_in_bytes], length_in_bytes);
     return str;
 }
 
-
-/*
- *  call-seq:
- *     str.slice!(fixnum)           => fixnum or nil
- *     str.slice!(fixnum, fixnum)   => new_str or nil
- *     str.slice!(range)            => new_str or nil
- *     str.slice!(regexp)           => new_str or nil
- *     str.slice!(other_str)        => new_str or nil
- *  
- *  Deletes the specified portion from <i>str</i>, and returns the portion
- *  deleted.
- *     
- *     string = "this is a string"
- *     string.slice!(2)        #=> "i"
- *     string.slice!(3..6)     #=> " is "
- *     string.slice!(/s.*t/)   #=> "sa st"
- *     string.slice!("r")      #=> "r"
- *     string                  #=> "thing"
- */
-
-static VALUE
-rb_str_slice_bang(VALUE str, SEL sel, int argc, VALUE *argv)
+// you cannot cut a surrogate in an encoding that is not UTF-16
+// (it's in theory possible to store the surrogate in
+//  UTF-8 or UTF-32 but that would be incorrect Unicode)
+NORETURN(static void
+str_cannot_cut_surrogate(void))
 {
-    VALUE result;
-    VALUE buf[3];
-    int i;
-
-    if (argc < 1 || 2 < argc) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
-    }
-    for (i=0; i<argc; i++) {
-	buf[i] = argv[i];
-    }
-    rb_str_modify(str);
-    buf[i] = rb_str_new(0,0);
-    result = rb_str_aref_m(str, 0, argc, buf);
-    if (!NIL_P(result)) {
-	rb_str_aset_m(str, 0, argc+1, buf);
-    }
-    return result;
+    rb_raise(rb_eIndexError, "You can't cut a surrogate in two in an encoding that is not UTF-16");
 }
 
-static VALUE
-get_pat(VALUE pat, int quote)
+static character_boundaries_t
+str_get_character_boundaries(string_t *self, long index, bool ucs2_mode)
 {
-    VALUE val;
+    character_boundaries_t boundaries = {-1, -1};
 
-    switch (TYPE(pat)) {
-      case T_REGEXP:
-	return pat;
-
-      case T_STRING:
-	break;
-
-      default:
-	val = rb_check_string_type(pat);
-	if (NIL_P(val)) {
-	    Check_Type(pat, T_REGEXP);
-	}
-	pat = val;
-    }
-
-    if (quote) {
-	pat = rb_reg_quote(pat);
-    }
-
-    return rb_reg_regcomp(pat);
-}
-
-
-/*
- *  call-seq:
- *     str.sub!(pattern, replacement)          => str or nil
- *     str.sub!(pattern) {|match| block }      => str or nil
- *  
- *  Performs the substitutions of <code>String#sub</code> in place,
- *  returning <i>str</i>, or <code>nil</code> if no substitutions were
- *  performed.
- */
-
-static VALUE
-rb_str_sub_bang(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE repl, hash = Qnil;
-    bool iter = false;
-    bool tainted = false;
-
-    if (argc == 1 && rb_block_given_p()) {
-	iter = true;
-    }
-    else if (argc == 2) {
-	repl = argv[1];
-	hash = rb_check_convert_type(argv[1], T_HASH, "Hash", "to_hash");
-	if (NIL_P(hash)) {
-	    StringValue(repl);
-	}
-	if (OBJ_TAINTED(repl)) {
-	    tainted = true;
-	}
-    }
-    else {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
-    }
-
-    VALUE pat = get_pat(argv[0], 1);
-    if (rb_reg_search(pat, str, 0, 0) >= 0) {
-	VALUE match = rb_backref_get();
-	struct re_registers *regs = RMATCH_REGS(match);
-
-	if (iter || !NIL_P(hash)) {
-            if (iter) {
-                rb_match_busy(match);
-                repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
-            }
-            else {
-                repl = rb_hash_aref(hash, rb_str_subseq(str, BEG(0),
-			    END(0) - BEG(0)));
-                repl = rb_obj_as_string(repl);
-            }
-	    str_frozen_check(str);
-	    if (iter) {
-		rb_backref_set(match);
+    if (str_is_stored_in_uchars(self)) {
+	if (ucs2_mode || str_known_not_to_have_any_supplementary(self)) {
+	    if (index < 0) {
+		index += div_round_up(self->length_in_bytes, 2);
+		if (index < 0) {
+		    return boundaries;
+		}
 	    }
+	    boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(index);
+	    boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 2;
+	    if (!UTF16_ENC(self->encoding)) {
+		long length = BYTES_TO_UCHARS(self->length_in_bytes);
+		if ((index < length) && U16_IS_SURROGATE(self->data.uchars[index])) {
+		    if (U16_IS_SURROGATE_LEAD(self->data.uchars[index])) {
+			boundaries.end_offset_in_bytes = -1;
+		    }
+		    else { // U16_IS_SURROGATE_TRAIL
+			boundaries.start_offset_in_bytes = -1;
+		    }
+		}
+	    }
 	}
 	else {
-	    repl = rb_reg_regsub(repl, str, regs, pat);
-	}
-
-	rb_str_modify(str);
-	rb_str_splice_0(str, BEG(0), END(0) - BEG(0), repl);
-	if (OBJ_TAINTED(repl)) {
-	    tainted = true;
-	}
-
-	if (tainted) {
-	    OBJ_TAINT(str);
-	}
-	return str;
-    }
-    return Qnil;
-}
-
-/*
- *  call-seq:
- *     str.sub(pattern, replacement)         => new_str
- *     str.sub(pattern) {|match| block }     => new_str
- *  
- *  Returns a copy of <i>str</i> with the <em>first</em> occurrence of
- *  <i>pattern</i> replaced with either <i>replacement</i> or the value of the
- *  block. The <i>pattern</i> will typically be a <code>Regexp</code>; if it is
- *  a <code>String</code> then no regular expression metacharacters will be
- *  interpreted (that is <code>/\d/</code> will match a digit, but
- *  <code>'\d'</code> will match a backslash followed by a 'd').
- *     
- *  If the method call specifies <i>replacement</i>, special variables such as
- *  <code>$&</code> will not be useful, as substitution into the string occurs
- *  before the pattern match starts. However, the sequences <code>\1</code>,
- *  <code>\2</code>, <code>\k<group_name></code>, etc., may be used.
- *     
- *  In the block form, the current match string is passed in as a parameter, and
- *  variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,
- *  <code>$&</code>, and <code>$'</code> will be set appropriately. The value
- *  returned by the block will be substituted for the match on each call.
- *     
- *  The result inherits any tainting in the original string or any supplied
- *  replacement string.
- *     
- *     "hello".sub(/[aeiou]/, '*')                  #=> "h*llo"
- *     "hello".sub(/([aeiou])/, '<\1>')             #=> "h<e>llo"
- *     "hello".sub(/./) {|s| s[0].ord.to_s + ' ' }  #=> "104 ello"
- *     "hello".sub(/(?<foo>[aeiou])/, '*\k<foo>*')  #=> "h*e*llo"
- */
-
-static VALUE
-rb_str_sub(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    str = rb_str_new3(str);
-    rb_str_sub_bang(str, 0, argc, argv);
-    return str;
-}
-
-static VALUE
-str_gsub(SEL sel, int argc, VALUE *argv, VALUE str, bool bang)
-{
-    bool iter = false;
-    bool tainted = false;
-    VALUE hash = Qnil, repl = Qnil;
- 
-    switch (argc) {
-	case 1:
-	    RETURN_ENUMERATOR(str, argc, argv);
-	    iter = true;
-	    break;
-
-	case 2:
-	    repl = argv[1];
-	    hash = rb_check_convert_type(argv[1], T_HASH, "Hash", "to_hash");
-	    if (NIL_P(hash)) {
-		StringValue(repl);
+	    // we don't have the length of the string, just the number of UChars
+	    // (uchars_count >= number of characters)
+	    long uchars_count = BYTES_TO_UCHARS(self->length_in_bytes);
+	    if ((index < -uchars_count) || (index >= uchars_count)) {
+		return boundaries;
 	    }
-	    if (OBJ_TAINTED(repl)) {
-		tainted = true;
+	    const UChar *uchars = self->data.uchars;
+	    long offset;
+	    if (index < 0) {
+		// count the characters from the end
+		offset = uchars_count;
+		while ((offset > 0) && (index < 0)) {
+		    --offset;
+		    // if the next character is a paired surrogate
+		    // we need to go to the start of the whole surrogate
+		    if (U16_IS_TRAIL(uchars[offset]) && (offset > 0) && U16_IS_LEAD(uchars[offset-1])) {
+			--offset;
+		    }
+		    ++index;
+		}
+		// ended before the index got to 0
+		if (index != 0) {
+		    return boundaries;
+		}
+		assert(offset >= 0);
 	    }
-	    break;
+	    else {
+		// count the characters from the start
+		offset = 0;
+		U16_FWD_N(uchars, offset, uchars_count, index);
+		if (offset >= uchars_count) {
+		    return boundaries;
+		}
+	    }
 
-	default:
-	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)",
-		    argc);
-    }
-
-    VALUE pat = get_pat(argv[0], 1);
-    long offset = 0;
-    long beg = rb_reg_search(pat, str, 0, 0);
-    if (beg < 0) {
-	if (bang) {
-	    return Qnil;	/* no match, no substitution */
+	    long length_in_bytes;
+	    if (U16_IS_LEAD(uchars[offset]) && (offset < uchars_count - 1) && (U16_IS_TRAIL(uchars[offset+1]))) {
+		// if it's a lead surrogate we must also copy the trail surrogate
+		length_in_bytes = UCHARS_TO_BYTES(2);
+	    }
+	    else {
+		length_in_bytes = UCHARS_TO_BYTES(1);
+	    }
+	    boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(offset);
+	    boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + length_in_bytes;
 	}
-	return rb_str_new3(str);
     }
-
-    VALUE dest = rb_str_new5(str, NULL, 0);
-    long slen = RSTRING_LEN(str);
-    VALUE match;
-
-    do {
-	match = rb_backref_get();
-	struct re_registers *regs = RMATCH_REGS(match);
-        VALUE val;
-
-	if (iter || !NIL_P(hash)) {
-            if (iter) {
-                rb_match_busy(match);
-                val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
-            }
-            else {
-                val = rb_hash_aref(hash, rb_str_subseq(str, BEG(0),
-			    END(0) - BEG(0)));
-                val = rb_obj_as_string(val);
-            }
-	    str_mod_check(str, sp, slen);
-	    if (bang) {
-		str_frozen_check(str);
+    else { // data in binary
+	if (self->encoding->single_byte_encoding) {
+	    if (index < 0) {
+		index += self->length_in_bytes;
+		if (index < 0) {
+		    return boundaries;
+		}
 	    }
-	    if (val == dest) { 	/* paranoid check [ruby-dev:24827] */
-		rb_raise(rb_eRuntimeError, "block should not cheat");
+	    boundaries.start_offset_in_bytes = index;
+	    boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 1;
+	}
+	else if (UTF32_ENC(self->encoding) && (!ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+	    if (index < 0) {
+		index += div_round_up(self->length_in_bytes, 4);
+		if (index < 0) {
+		    return boundaries;
+		}
 	    }
-	    if (iter) {
-		rb_backref_set(match);
-		RETURN_IF_BROKEN();
+	    boundaries.start_offset_in_bytes = index * 4;
+	    boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 4;
+	}
+	else if (NON_NATIVE_UTF16_ENC(self->encoding) && (ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+	    if (index < 0) {
+		index += div_round_up(self->length_in_bytes, 2);
+		if (index < 0) {
+		    return boundaries;
+		}
 	    }
+	    boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(index);
+	    boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 2;
 	}
 	else {
-	    val = rb_reg_regsub(repl, str, regs, pat);
+	    boundaries = self->encoding->methods.get_character_boundaries(self, index, ucs2_mode);
 	}
-
-
-	if (OBJ_TAINTED(val)) {
-	    tainted = true;
-	}
-
-	long len = beg - offset;  /* copy pre-match substr */
-        if (len > 0) {
-	    rb_str_buf_append(dest, rb_str_subseq(str, offset, len));
-	    //rb_enc_str_buf_cat(dest, cp, len, str_enc);
-        }
-
-        rb_str_buf_append(dest, val);
-
-	offset = END(0);
-	if (BEG(0) == END(0)) {
-	    /*
-	     * Always consume at least one character of the input string
-	     * in order to prevent infinite loops.
-	     */
-	    if (slen <= END(0)) {
-		break;
-	    }
-	    len = 1;
-	    rb_str_buf_append(dest, rb_str_subseq(str, END(0), len));
-            //rb_enc_str_buf_cat(dest, sp+END(0), len, str_enc);
-	    offset = END(0) + len;
-	}
-	if (offset > slen) {
-	    break;
-	}
-	beg = rb_reg_search(pat, str, offset, 0);
     }
-    while (beg >= 0);
 
-    if (slen > offset) {
-	rb_str_buf_append(dest, rb_str_subseq(str, offset, slen - offset));
-        //rb_enc_str_buf_cat(dest, cp, slen - offset, str_enc);
-    }
-    rb_backref_set(match);
-    if (bang) {
-	rb_str_modify(str);
-	CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)dest);
-    }
-    else {
-    	if (!tainted && OBJ_TAINTED(str)) {
-	    tainted = true;
-	}
-	str = dest;
-    }
-
-    if (tainted) {
-	OBJ_TAINT(str);
-    }
-    return str;
+    return boundaries;
 }
 
-
-/*
- *  call-seq:
- *     str.gsub!(pattern, replacement)        => str or nil
- *     str.gsub!(pattern) {|match| block }    => str or nil
- *  
- *  Performs the substitutions of <code>String#gsub</code> in place, returning
- *  <i>str</i>, or <code>nil</code> if no substitutions were performed.
- */
-
-static VALUE
-rb_str_gsub_bang(VALUE str, SEL sel, int argc, VALUE *argv)
+static string_t *
+str_get_characters(string_t *self, long first, long last, bool ucs2_mode)
 {
-    // XXX This rb_str_modify() call is disabled because it breaks mkmf.rb for
-    // a reason, must investigate.
-    //rb_str_modify(str);
-    return str_gsub(sel, argc, argv, str, true);
-}
-
-
-/*
- *  call-seq:
- *     str.gsub(pattern, replacement)       => new_str
- *     str.gsub(pattern) {|match| block }   => new_str
- *  
- *  Returns a copy of <i>str</i> with <em>all</em> occurrences of <i>pattern</i>
- *  replaced with either <i>replacement</i> or the value of the block. The
- *  <i>pattern</i> will typically be a <code>Regexp</code>; if it is a
- *  <code>String</code> then no regular expression metacharacters will be
- *  interpreted (that is <code>/\d/</code> will match a digit, but
- *  <code>'\d'</code> will match a backslash followed by a 'd').
- *     
- *  If a string is used as the replacement, special variables from the match
- *  (such as <code>$&</code> and <code>$1</code>) cannot be substituted into it,
- *  as substitution into the string occurs before the pattern match
- *  starts. However, the sequences <code>\1</code>, <code>\2</code>,
- *  <code>\k<group_name></code>, and so on may be used to interpolate
- *  successive groups in the match.
- *     
- *  In the block form, the current match string is passed in as a parameter, and
- *  variables such as <code>$1</code>, <code>$2</code>, <code>$`</code>,
- *  <code>$&</code>, and <code>$'</code> will be set appropriately. The value
- *  returned by the block will be substituted for the match on each call.
- *     
- *  The result inherits any tainting in the original string or any supplied
- *  replacement string.
- *     
- *     "hello".gsub(/[aeiou]/, '*')                  #=> "h*ll*"
- *     "hello".gsub(/([aeiou])/, '<\1>')             #=> "h<e>ll<o>"
- *     "hello".gsub(/./) {|s| s[0].ord.to_s + ' '}   #=> "104 101 108 108 111 "
- *     "hello".gsub(/(?<foo>[aeiou])/, '{\k<foo>}')  #=> "h{e}ll{o}"
- */
-
-static VALUE
-rb_str_gsub(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    return str_gsub(sel, argc, argv, str, false);
-}
-
-
-/*
- *  call-seq:
- *     str.replace(other_str)   => str
- *  
- *  Replaces the contents and taintedness of <i>str</i> with the corresponding
- *  values in <i>other_str</i>.
- *     
- *     s = "hello"         #=> "hello"
- *     s.replace "world"   #=> "world"
- */
-
-static VALUE
-rb_str_replace_imp(VALUE str, SEL sel, VALUE str2)
-{
-    rb_str_modify(str);
-    if (str == str2) {
-	return str;
+    if (self->length_in_bytes == 0) {
+	if (first == 0) {
+	    return str_new_similar_empty_string(self);
+	}
+	else {
+	    return NULL;
+	}
     }
-    StringValue(str2);
-    CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)str2);
-    if (OBJ_TAINTED(str2)) {
-	OBJ_TAINT(str);
+    if (!self->encoding->single_byte_encoding && !str_is_stored_in_uchars(self)) {
+	str_try_making_data_uchars(self);
     }
-    return str;
-}
+    character_boundaries_t first_boundaries = str_get_character_boundaries(self, first, ucs2_mode);
+    character_boundaries_t last_boundaries = str_get_character_boundaries(self, last, ucs2_mode);
 
-VALUE
-rb_str_replace(VALUE str, VALUE str2)
-{
-    return rb_str_replace_imp(str, 0, str2);
-}
-
-/*
- *  call-seq:
- *     string.clear    ->  string
- *
- *  Makes string empty.
- *
- *     a = "abcde"
- *     a.clear    #=> ""
- */
-
-static VALUE
-rb_str_clear(VALUE str, SEL sel)
-{
-    rb_str_modify(str);
-    CFStringDelete((CFMutableStringRef)str, 
-	CFRangeMake(0, CFStringGetLength((CFStringRef)str)));
-    return str;
-}
-
-/*
- *  call-seq:
- *     string.chr    ->  string
- *
- *  Returns a one-character string at the beginning of the string.
- *
- *     a = "abcde"
- *     a.chr    #=> "a"
- */
-
-static VALUE
-rb_str_chr(VALUE str, SEL sel)
-{
-    return rb_str_substr(str, 0, 1);
-}
-
-/*
- *  call-seq:
- *     str.getbyte(index)          => 0 .. 255
- *
- *  returns the <i>index</i>th byte as an integer.
- */
-static VALUE
-rb_str_getbyte(VALUE str, SEL sel, VALUE index)
-{
-    if (*(VALUE *)str != rb_cByteString) {
-	rb_raise(rb_eArgError,
-		"#getbyte is only implemented for ByteString objects");
+    if (first_boundaries.start_offset_in_bytes == -1) {
+	if (last_boundaries.end_offset_in_bytes == -1) {
+	    // you cannot cut a surrogate in an encoding that is not UTF-16
+	    str_cannot_cut_surrogate();
+	}
+	else {
+	    return NULL;
+	}
     }
-
-    long pos = NUM2LONG(index);
-    const long n = rb_bytestring_length(str);
-    if (pos < 0) {
-	pos += n;
+    else if (last_boundaries.end_offset_in_bytes == -1) {
+	// you cannot cut a surrogate in an encoding that is not UTF-16
+	str_cannot_cut_surrogate();
     }
-    if (pos < 0 || pos >= n) {
-	return Qnil;
-    }
-    return INT2FIX(rb_bytestring_byte_pointer(str)[pos]);
-}
 
-/*
- *  call-seq:
- *     str.setbyte(index, int) => int
- *
- *  modifies the <i>index</i>th byte as <i>int</i>.
- */
-static VALUE
-rb_str_setbyte(VALUE str, SEL sel, VALUE index, VALUE value)
-{
-    if (*(VALUE *)str != rb_cByteString) {
-	rb_raise(rb_eArgError,
-		"#setbyte is only implemented for ByteString objects");
+    if (first_boundaries.start_offset_in_bytes == self->length_in_bytes) {
+	return str_new_similar_empty_string(self);
     }
-
-    long pos = NUM2LONG(index);
-    const int byte = NUM2INT(value);
-    const long n = rb_bytestring_length(str);
-
-    rb_str_modify(str);
-
-    if (pos < -n || n <= pos) {
-        rb_raise(rb_eIndexError, "index %ld out of string", pos);
+    else if (first_boundaries.start_offset_in_bytes > self->length_in_bytes) {
+	return NULL;
     }
-    if (pos < 0) {
-        pos += n;
+    if (last_boundaries.end_offset_in_bytes >= self->length_in_bytes) {
+	last_boundaries.end_offset_in_bytes = self->length_in_bytes;
     }
 
-    rb_bytestring_byte_pointer(str)[pos] = byte;
-
-    return value;
+    return str_new_copy_of_part(self, first_boundaries.start_offset_in_bytes,
+	    last_boundaries.end_offset_in_bytes - first_boundaries.start_offset_in_bytes);
 }
 
-
-/*
- *  call-seq:
- *     str.reverse!   => str
- *  
- *  Reverses <i>str</i> in place.
- */
-
-static VALUE
-rb_str_reverse_bang(VALUE str, SEL sel)
+static string_t *
+str_get_character_at(string_t *self, long index, bool ucs2_mode)
 {
-    rb_str_modify(str);
-
-    const long n = CFStringGetLength((CFStringRef)str);
-    if (n <= 1) {
-	return rb_str_dup(str);
+    if (self->length_in_bytes == 0) {
+	return NULL;
     }
-
-#if 1
-    // HACK
-    const char *ptr = CFStringGetCStringPtr((CFStringRef)str, 0);
-    if (ptr != NULL) {
-	char *beg = (char *)ptr;
-	char *end = (char *)&ptr[n - 1];
-	while (beg < end) {
-	    char c = *beg;
-	    *beg++ = *end;
-	    *end-- = c;
-	}
-	return str;
+    if (!self->encoding->single_byte_encoding && !str_is_stored_in_uchars(self)) {
+	// if we can't access the bytes directly,
+	// try to convert the string in UTF-16
+	str_try_making_data_uchars(self);
     }
-    const UniChar *ptr2 = CFStringGetCharactersPtr((CFStringRef)str);
-    if (ptr2 != NULL) {
-	UniChar *beg = (UniChar *)ptr2;
-	UniChar *end = (UniChar *)&ptr2[n - 1];
-	while (beg < end) {
-	    UniChar c = *beg;
-	    *beg++ = *end;
-	    *end-- = c;
+    character_boundaries_t boundaries = str_get_character_boundaries(self, index, ucs2_mode);
+    if (boundaries.start_offset_in_bytes == -1) {
+	if (boundaries.end_offset_in_bytes == -1) {
+	    return NULL;
 	}
-	return str;
+	else {
+	    // you cannot cut a surrogate in an encoding that is not UTF-16
+	    str_cannot_cut_surrogate();
+	}
     }
-#endif
- 
-    UniChar *buffer = (UniChar *)alloca(sizeof(UniChar) * n);
-    CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, n), buffer);
-    UniChar *beg = buffer;
-    UniChar *end = &buffer[n - 1];
-    while (beg < end) {
-	UniChar c = *beg;
-	*beg++ = *end;
-	*end-- = c;
+    else if (boundaries.end_offset_in_bytes == -1) {
+	// you cannot cut a surrogate in an encoding that is not UTF-16
+	str_cannot_cut_surrogate();
     }
 
-#if 0
-    CFStringDelete((CFMutableStringRef)str, CFRangeMake(0, n));
-    CFStringAppendCharacters((CFMutableStringRef)str, (const UniChar *)buffer, n);
-#else
-    CFStringRef tmp = CFStringCreateWithCharactersNoCopy(kCFAllocatorMalloc,
-	    buffer, n, kCFAllocatorNull);
-    CFStringReplaceAll((CFMutableStringRef)str, tmp);
-    CFRelease(tmp);
-#endif
-
-    return str;
-}
-
-/*
- *  call-seq:
- *     str.reverse   => new_str
- *  
- *  Returns a new string with the characters from <i>str</i> in reverse order.
- *     
- *     "stressed".reverse   #=> "desserts"
- */
-
-static VALUE
-rb_str_reverse(VALUE str, SEL sel)
-{
-    VALUE obj = rb_str_dup(str);
-    rb_str_reverse_bang(obj, 0);
-    return obj;
-}
-
-/*
- *  call-seq:
- *     str.include? other_str   => true or false
- *     str.include? fixnum      => true or false
- *  
- *  Returns <code>true</code> if <i>str</i> contains the given string or
- *  character.
- *     
- *     "hello".include? "lo"   #=> true
- *     "hello".include? "ol"   #=> false
- *     "hello".include? ?h     #=> true
- */
-
-static VALUE
-rb_str_include(VALUE str, SEL sel, VALUE arg)
-{
-    long i;
-
-    StringValue(arg);
-    i = rb_str_index(str, arg, 0);
-
-    return (i == -1) ? Qfalse : Qtrue;
-}
-
-
-/*
- *  call-seq:
- *     str.to_i(base=10)   => integer
- *  
- *  Returns the result of interpreting leading characters in <i>str</i> as an
- *  integer base <i>base</i> (between 2 and 36). Extraneous characters past the
- *  end of a valid number are ignored. If there is not a valid number at the
- *  start of <i>str</i>, <code>0</code> is returned. This method never raises an
- *  exception.
- *     
- *     "12345".to_i             #=> 12345
- *     "99 red balloons".to_i   #=> 99
- *     "0a".to_i                #=> 0
- *     "0a".to_i(16)            #=> 10
- *     "hello".to_i             #=> 0
- *     "1100101".to_i(2)        #=> 101
- *     "1100101".to_i(8)        #=> 294977
- *     "1100101".to_i(10)       #=> 1100101
- *     "1100101".to_i(16)       #=> 17826049
- */
-
-static VALUE
-rb_str_to_i(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    int base;
-
-    if (argc == 0) base = 10;
-    else {
-	VALUE b;
-
-	rb_scan_args(argc, argv, "01", &b);
-	base = NUM2INT(b);
+    if (boundaries.start_offset_in_bytes >= self->length_in_bytes) {
+	return NULL;
     }
-    if (base < 0) {
-	rb_raise(rb_eArgError, "invalid radix %d", base);
+    if (boundaries.end_offset_in_bytes >= self->length_in_bytes) {
+	boundaries.end_offset_in_bytes = self->length_in_bytes;
     }
-    return rb_str_to_inum(str, base, Qfalse);
-}
 
-
-/*
- *  call-seq:
- *     str.to_f   => float
- *  
- *  Returns the result of interpreting leading characters in <i>str</i> as a
- *  floating point number. Extraneous characters past the end of a valid number
- *  are ignored. If there is not a valid number at the start of <i>str</i>,
- *  <code>0.0</code> is returned. This method never raises an exception.
- *     
- *     "123.45e1".to_f        #=> 1234.5
- *     "45.67 degrees".to_f   #=> 45.67
- *     "thx1138".to_f         #=> 0.0
- */
-
-static VALUE
-rb_str_to_f(VALUE str, SEL sel)
-{
-    return DOUBLE2NUM(rb_str_to_dbl(str, Qfalse));
+    return str_new_copy_of_part(self, boundaries.start_offset_in_bytes, boundaries.end_offset_in_bytes - boundaries.start_offset_in_bytes);
 }
 
-
-/*
- *  call-seq:
- *     str.to_s     => str
- *     str.to_str   => str
- *  
- *  Returns the receiver.
- */
-
-static VALUE
-rb_str_to_s(VALUE str, SEL sel)
+static string_t *
+str_plus_string(string_t *str1, string_t *str2)
 {
-    if (!rb_objc_str_is_pure(str) && *(VALUE *)str != rb_cByteString) {
-	VALUE dup = str_alloc(rb_cString);
-	CFStringReplaceAll((CFMutableStringRef)dup, (CFStringRef)str);
-	if (OBJ_TAINTED(str)) {
-	    OBJ_TAINT(dup);
-	}
-	return dup;
+    encoding_t *new_encoding = str_must_have_compatible_encoding(str1, str2);
+
+    string_t *new_str = str_alloc();
+    new_str->encoding = new_encoding;
+    if ((str1->length_in_bytes == 0) && (str2->length_in_bytes == 0)) {
+	return new_str;
     }
-    return str;
-}
 
-#if 0
-static void
-str_cat_char(VALUE str, int c, rb_encoding *enc)
-{
-    char buf[2];
-    buf[0] = (char)c;
-    buf[1] = '\0';
-    CFStringAppendCString((CFMutableStringRef)str, buf, kCFStringEncodingUTF8);
-}
+    str_make_same_format(str1, str2);
 
-static void
-prefix_escape(VALUE str, int c, rb_encoding *enc)
-{
-    str_cat_char(str, '\\', enc);
-    str_cat_char(str, c, enc);
-}
-#endif
-
-/*
- * call-seq:
- *   str.inspect   => string
- *
- * Returns a printable version of _str_, surrounded by quote marks,
- * with special characters escaped.
- *
- *    str = "hello"
- *    str[3] = "\b"
- *    str.inspect       #=> "\"hel\\bo\""
- */
-
-static inline void
-__append(CFMutableStringRef out, UniChar c)
-{
-    CFStringAppendCharacters(out, &c, 1);
-}
-
-static inline void
-__append_escape(CFMutableStringRef out, UniChar c)
-{
-    __append(out, '\\');
-    __append(out, c);
-}
-
-static VALUE
-__rb_str_inspect(VALUE str, bool dump)
-{
-    const long len = CFStringGetLength((CFStringRef)str);
-    CFStringInlineBuffer buf; 
-    CFStringInitInlineBuffer((CFStringRef)str, &buf, CFRangeMake(0, len));
-
-    CFMutableStringRef out = CFStringCreateMutable(NULL, 0);
-    __append(out, '"');
-
-    for (long i = 0; i < len; i++) {
-	UniChar c = CFStringGetCharacterFromInlineBuffer(&buf, i);
-	if (iswprint(c)) {
-	    if (c == '"'|| c == '\\') {
-		__append_escape(out, c);
-	    }
-	    else if (dump && c == '#' && i + 1 < len) {
-		UniChar c2 = CFStringGetCharacterFromInlineBuffer(&buf, i + 1);
-		if (c2 == '$' || c2 == '@' || c2 == '{') {
-		    __append_escape(out, c);
-		}
-		else {
-		    __append(out, c);
-		}
-	    }
-	    else {
-		__append(out, c);
-	    }
-	}
-	else if (c == '\n') {
-	    __append_escape(out, 'n');
-	}
-	else if (c == '\r') {
-	    __append_escape(out, 'r');
-	}
-	else if (c == '\t') {
-	    __append_escape(out, 't');
-	}
-	else if (c == '\f') {
-	    __append_escape(out, 'f');
-	}
-	else if (c == '\013') {
-	    __append_escape(out, 'v');
-	}
-	else if (c == '\010') {
-	    __append_escape(out, 'b');
-	}
-	else if (c == '\007') {
-	    __append_escape(out, 'a');
-	}
-	else if (c == 033) {
-	    __append_escape(out, 'e');
-	}
-	else {
-	    CFStringAppendFormat(out, NULL, CFSTR("\\x%02X"), c);
-	}
+    str_set_stored_in_uchars(new_str, str_is_stored_in_uchars(str1));
+    long length_in_bytes = str1->length_in_bytes + str2->length_in_bytes;
+    new_str->data.bytes = xmalloc(length_in_bytes);
+    if (str1->length_in_bytes > 0) {
+	memcpy(new_str->data.bytes, str1->data.bytes, str1->length_in_bytes);
     }
-    __append(out, '"');
-
-    VALUE res = (VALUE)CFMakeCollectable(out);
-    if (OBJ_TAINTED(str)) {
-	OBJ_TAINT(res);
+    if (str2->length_in_bytes > 0) {
+	memcpy(new_str->data.bytes + str1->length_in_bytes, str2->data.bytes, str2->length_in_bytes);
     }
-    return res;
-}
+    new_str->capacity_in_bytes = new_str->length_in_bytes = length_in_bytes;
 
-VALUE
-rb_str_inspect(VALUE str, SEL sel)
-{
-    return __rb_str_inspect(str, false);
+    return new_str;
 }
 
-/*
- *  call-seq:
- *     str.dump   => new_str
- *  
- *  Produces a version of <i>str</i> with all nonprinting characters replaced by
- *  <code>\nnn</code> notation and all special characters escaped.
- */
-
-static VALUE
-rb_str_dump(VALUE str, SEL sel)
+static void
+str_concat_string(string_t *self, string_t *str)
 {
-    VALUE res = __rb_str_inspect(str, true);
-    if (*(VALUE *)str != rb_cByteString) {
-	*(VALUE *)res = *(VALUE *)str;
+    if (str->length_in_bytes == 0) {
+	return;
     }
-    return res;
-}
-
-/*
- *  call-seq:
- *     str.upcase!   => str or nil
- *  
- *  Upcases the contents of <i>str</i>, returning <code>nil</code> if no changes
- *  were made.
- *  Note: case replacement is effective only in ASCII region.
- */
-
-static VALUE
-rb_str_upcase_bang(VALUE str, SEL sel)
-{
-    CFHashCode h;
-    rb_str_modify(str);
-    h = CFHash((CFTypeRef)str);
-    CFStringUppercase((CFMutableStringRef)str, NULL);
-    if (h == CFHash((CFTypeRef)str)) {
-	return Qnil;
+    if (self->length_in_bytes == 0) {
+	str_replace_with_string(self, str);
+	return;
     }
-    return str;
-}
 
+    str_must_have_compatible_encoding(self, str);
+    str_make_same_format(self, str);
 
-/*
- *  call-seq:
- *     str.upcase   => new_str
- *  
- *  Returns a copy of <i>str</i> with all lowercase letters replaced with their
- *  uppercase counterparts. The operation is locale insensitive---only
- *  characters ``a'' to ``z'' are affected.
- *  Note: case replacement is effective only in ASCII region.
- *     
- *     "hEllO".upcase   #=> "HELLO"
- */
-
-static VALUE
-rb_str_upcase(VALUE str, SEL sel)
-{
-    str = rb_str_new3(str);
-    rb_str_upcase_bang(str, 0);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.downcase!   => str or nil
- *  
- *  Downcases the contents of <i>str</i>, returning <code>nil</code> if no
- *  changes were made.
- *  Note: case replacement is effective only in ASCII region.
- */
-
-static VALUE
-rb_str_downcase_bang(VALUE str, SEL sel)
-{
-    CFHashCode h;
-    rb_str_modify(str);
-    h = CFHash((CFTypeRef)str);
-    CFStringLowercase((CFMutableStringRef)str, NULL);
-    if (h == CFHash((CFTypeRef)str)) {
-	return Qnil;
+    long new_length_in_bytes = self->length_in_bytes + str->length_in_bytes;
+    // TODO: we should maybe merge flags
+    // (if both are ASCII-only, the concatenation is ASCII-only,
+    //  though I'm not sure all the tests required are worth doing)
+    str_unset_facultative_flags(self);
+    if (self->capacity_in_bytes < new_length_in_bytes) {
+	uint8_t *bytes = xmalloc(new_length_in_bytes);
+	memcpy(bytes, self->data.bytes, self->length_in_bytes);
+	GC_WB(&self->data.bytes, bytes);
+	self->capacity_in_bytes = new_length_in_bytes;
     }
-    return str;
+    memcpy(self->data.bytes + self->length_in_bytes, str->data.bytes, str->length_in_bytes);
+    self->length_in_bytes = new_length_in_bytes;
 }
 
-
-/*
- *  call-seq:
- *     str.downcase   => new_str
- *  
- *  Returns a copy of <i>str</i> with all uppercase letters replaced with their
- *  lowercase counterparts. The operation is locale insensitive---only
- *  characters ``A'' to ``Z'' are affected.
- *  Note: case replacement is effective only in ASCII region.
- *     
- *     "hEllO".downcase   #=> "hello"
- */
-
-static VALUE
-rb_str_downcase(VALUE str, SEL sel)
+static bool
+str_is_equal_to_string(string_t *self, string_t *str)
 {
-    str = rb_str_new3(str);
-    rb_str_downcase_bang(str, 0);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.capitalize!   => str or nil
- *  
- *  Modifies <i>str</i> by converting the first character to uppercase and the
- *  remainder to lowercase. Returns <code>nil</code> if no changes are made.
- *  Note: case conversion is effective only in ASCII region.
- *     
- *     a = "hello"
- *     a.capitalize!   #=> "Hello"
- *     a               #=> "Hello"
- *     a.capitalize!   #=> nil
- */
-
-static VALUE
-rb_str_capitalize_bang(VALUE str, SEL sel)
-{
-    CFStringRef tmp;
-    long i, n;
-    bool changed;
-    UniChar *buffer;
-
-    rb_str_modify(str);
-    n = CFStringGetLength((CFStringRef)str);
-    if (n == 0) {
-	return Qnil;
+    if (self == str) {
+	return true;
     }
-    buffer = (UniChar *)alloca(sizeof(UniChar) * n);
-    CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, n), buffer);
-    changed = false;
-    if (iswascii(buffer[0]) && iswlower(buffer[0])) {
-	buffer[0] = towupper(buffer[0]);
-	changed = true;
-    }
-    for (i = 1; i < n; i++) {
-	if (iswascii(buffer[0]) && iswupper(buffer[i])) {
-	    buffer[i] = towlower(buffer[i]);
-	    changed = true;
-	}
-    }
-    if (!changed) {
-	return Qnil;
-    }
-    tmp = CFStringCreateWithCharacters(NULL, buffer, n);
-    CFStringReplaceAll((CFMutableStringRef)str, tmp);
-    CFRelease(tmp);
-    return str;
-}
 
-
-/*
- *  call-seq:
- *     str.capitalize   => new_str
- *  
- *  Returns a copy of <i>str</i> with the first character converted to uppercase
- *  and the remainder to lowercase.
- *  Note: case conversion is effective only in ASCII region.
- *     
- *     "hello".capitalize    #=> "Hello"
- *     "HELLO".capitalize    #=> "Hello"
- *     "123ABC".capitalize   #=> "123abc"
- */
-
-static VALUE
-rb_str_capitalize(VALUE str, SEL sel)
-{
-    str = rb_str_new3(str);
-    rb_str_capitalize_bang(str, 0);
-    return str;
-}
-
-
-/*
- *  call-seq: 
-*     str.swapcase!   => str or nil
- *  
- *  Equivalent to <code>String#swapcase</code>, but modifies the receiver in
- *  place, returning <i>str</i>, or <code>nil</code> if no changes were made.
- *  Note: case conversion is effective only in ASCII region.
- */
-
-static VALUE
-rb_str_swapcase_bang(VALUE str, SEL sel)
-{
-    CFIndex i, n;
-    UniChar *buffer;
-    bool changed;
-
-    rb_str_modify(str);
-
-    n = CFStringGetLength((CFStringRef)str);
-    if (n == 0) {
-	return Qnil;
-    }
-   
-    buffer = (UniChar *)CFStringGetCharactersPtr((CFStringRef)str);
-    if (buffer == NULL) {
-	buffer = (UniChar *)alloca(sizeof(UniChar) * n);
-    	CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, n), buffer);
-    }
-    for (i = 0, changed = false; i < n; i++) {
-	UniChar c = buffer[i];
-	if (!iswascii(c)) {
-	    continue;
+    if (self->length_in_bytes == 0) {
+	if (str->length_in_bytes == 0) {
+	    // both strings are empty
+	    return true;
 	}
-	if (iswlower(c)) {
-	    c = towupper(c);
-	}
-	else if (iswupper(c)) {
-	    c = towlower(c);
-	}
 	else {
-	    continue;
+	    // only self is empty
+	    return false;
 	}
-	changed = true;
-	buffer[i] = c;
     }
-    if (!changed) {
-	return Qnil;
+    else if (str->length_in_bytes == 0) {
+	// only str is empty
+	return false;
     }
-    CFStringDelete((CFMutableStringRef)str, CFRangeMake(0, n));
-    CFStringAppendCharacters((CFMutableStringRef)str,
-	    (const UniChar *)buffer, n);
-    return str;
-}
 
-
-/*
- *  call-seq:
- *     str.swapcase   => new_str
- *  
- *  Returns a copy of <i>str</i> with uppercase alphabetic characters converted
- *  to lowercase and lowercase characters converted to uppercase.
- *  Note: case conversion is effective only in ASCII region.
- *     
- *     "Hello".swapcase          #=> "hELLO"
- *     "cYbEr_PuNk11".swapcase   #=> "CyBeR_pUnK11"
- */
-
-static VALUE
-rb_str_swapcase(VALUE str, SEL sel)
-{
-    str = rb_str_new3(str);
-    rb_str_swapcase_bang(str, 0);
-    return str;
-}
-
-typedef void str_charset_find_cb
-(CFRange *, const CFRange *, CFStringRef, UniChar, void *);
-
-static void
-str_charset_find(CFStringRef str, VALUE *charsets, int charset_count,
-		 bool squeeze_mode, str_charset_find_cb *cb, void *ctx)
-{
-    int i;
-    long n;
-    CFMutableCharacterSetRef charset;
-    CFRange search_range, result_range; 
-
-    if (charset_count == 0)
-	return;
-
-    n = CFStringGetLength((CFStringRef)str);
-    if (n == 0)
-    	return;
-
-    charset = NULL;
-    for (i = 0; i < charset_count; i++) {
-	VALUE s = charsets[i];
-	bool exclude;
-	const char *sptr, *p;
-
-	StringValue(s);
-
-	sptr = RSTRING_PTR(s);
-	exclude = sptr[0] == '^';
-
-	p = NULL;
-	if (exclude || (p = strchr(sptr, '-')) != NULL) {
-	    CFMutableCharacterSetRef subset;
-	    const char *b, *e;
-
-	    b = exclude ? sptr + 1 : sptr;
-	    e = sptr + strlen(sptr) - 1;
-	    subset = CFCharacterSetCreateMutable(NULL);
-	    if (p == NULL) {
-		p = strchr(b, '-');
+    if (str_compatible_encoding(self, str) != NULL) {
+	if (str_is_stored_in_uchars(self) == str_is_stored_in_uchars(str)) {
+	    if (self->length_in_bytes != str->length_in_bytes) {
+		return false;
 	    }
-	    while (p != NULL) {
-		if (p > b && *(p - 1) != '\\' && *(p + 1) != '\0') {
-		    CFCharacterSetAddCharactersInRange(subset,
-			    CFRangeMake(*(p - 1), *(p + 1) - *(p - 1) + 1));
-		}
-		if (p > b) {
-		    CFStringRef substr;
-		    substr = CFStringCreateWithBytes(NULL,
-			    (const UInt8 *)b,
-			    (CFIndex)p - (CFIndex)b,
-			    kCFStringEncodingUTF8,
-			    false);
-		    assert(substr != NULL);
-		    CFCharacterSetAddCharactersInString(subset, substr);
-		    CFRelease(substr);
-		}
-		if (p == b) {
-		    p = NULL; 
-		}
-		else {
-		    b = p + 2;
-		    p = strchr(b, '-');
-		}
-	    }
-	    if (b <= e) {
-		CFStringRef substr;
-		substr = CFStringCreateWithBytes(NULL,
-			(const UInt8 *)b,
-			(CFIndex)e - (CFIndex)b + 1,
-			kCFStringEncodingUTF8,
-			false);
-		assert(substr != NULL);
-		CFCharacterSetAddCharactersInString(subset, substr);
-		CFRelease(substr);
-	    }
-
-	    if (exclude) {
-		CFCharacterSetInvert(subset);
-	    }
-
-	    if (charset == NULL) {
-		charset = subset;
-	    }
 	    else {
-		CFCharacterSetIntersect(charset, subset);
-		CFRelease(subset);
+		return (memcmp(self->data.bytes, str->data.bytes, self->length_in_bytes) == 0);
 	    }
 	}
-	else {
-	    if (charset == NULL) {
-		charset = CFCharacterSetCreateMutable(NULL);
-		CFCharacterSetAddCharactersInString(charset, (CFStringRef)s);
+	else { // one is in uchars and the other is in binary
+	    if (!str_try_making_data_uchars(self) || !str_try_making_data_uchars(str)) {
+		// one is in uchars but the other one can't be converted in uchars
+		return false;
 	    }
+	    if (self->length_in_bytes != str->length_in_bytes) {
+		return false;
+	    }
 	    else {
-		CFCharacterSetRef subset;
-		subset = CFCharacterSetCreateWithCharactersInString(NULL,
-			(CFStringRef)s);
-		CFCharacterSetIntersect(charset, subset);
-		CFRelease(subset);	
+		return (memcmp(self->data.bytes, str->data.bytes, self->length_in_bytes) == 0);
 	    }
 	}
     }
+    else { // incompatible encodings
+	return false;
+    }
+}
 
-    search_range = CFRangeMake(0, n);
-#if 0 
-    while (search_range.length != 0 
-	    && CFStringFindCharacterFromSet(
-		(CFStringRef)str,
-		(CFCharacterSetRef)charset,
-		search_range,
-		0,
-		&result_range)) {
-	(*cb)(&search_range, (const CFRange *)&result_range, str, ctx);
+static long
+str_offset_in_bytes_to_index(string_t *self, long offset_in_bytes, bool ucs2_mode)
+{
+    if ((offset_in_bytes >= self->length_in_bytes) || (offset_in_bytes < 0)) {
+	return -1;
     }
-#else
-    CFStringInlineBuffer buf;
-    UniChar previous_char = 0;
-    CFStringInitInlineBuffer((CFStringRef)str, &buf, search_range);
-    do {
-        long i;
-	bool mutated = false;
+    if (offset_in_bytes == 0) {
+	return 0;
+    }
 
-	if (search_range.location + search_range.length < n) {
-	    n = search_range.location + search_range.length;
-	    CFStringInitInlineBuffer((CFStringRef)str, &buf, CFRangeMake(0, n));
+    if (str_is_stored_in_uchars(self)) {
+	if (ucs2_mode || str_known_not_to_have_any_supplementary(self)) {
+	    return BYTES_TO_UCHARS(offset_in_bytes);
 	}
-
-	result_range.length = 0;
-
-	for (i = search_range.location;
-	     i < search_range.location + search_range.length; 
-	     i++) {
-
-	    UniChar c;
-
-	    c = CFStringGetCharacterFromInlineBuffer(&buf, i);
-	    if (CFCharacterSetIsCharacterMember((CFCharacterSetRef)charset, 
-						c)) {
-		if (result_range.length == 0) {
-		    result_range.location = i;
-		    result_range.length = 1;
-		    previous_char = c;
+	else {
+	    long length = BYTES_TO_UCHARS(self->length_in_bytes);
+	    long index = 0, i = 0;
+	    for (;;) {
+		if (U16_IS_LEAD(self->data.uchars[i]) && (i+1 < length) && U16_IS_TRAIL(self->data.uchars[i+1])) {
+		    i += 2;
 		}
 		else {
-		    if (result_range.location + result_range.length == i
-			&& (!squeeze_mode || previous_char == c)) {
-			result_range.length++;
-		    }
-		    else {
-			(*cb)(&search_range, (const CFRange *)&result_range, 
-			    str, previous_char, ctx);
-			result_range.location = i;
-			result_range.length = 1;
-			previous_char = c;
-			if (search_range.location + search_range.length < n) {
-			    result_range.location -= n 
-				- (search_range.location + search_range.length);
-			    mutated = true;
-			    break;
-			}
-		    }
+		    ++i;
 		}
+		if (offset_in_bytes < i) {
+		    return index;
+		}
+		++index;
+		if (offset_in_bytes == i) {
+		    return index;
+		}
 	    }
 	}
-	if (!mutated) {
-	    if (result_range.length != 0) {
-		(*cb)(&search_range, (const CFRange *)&result_range, str, 
-			previous_char, ctx);
-		result_range.length = 0;
-		previous_char = 0;
-	    }
-	}
     }
-    while (search_range.length != 0 && result_range.length != 0); 
-#endif
-
-    CFRelease(charset);	
-}
-
-struct tr_trans_cb_ctx {
-    VALUE orepl;
-    const char *src;
-    long src_len;
-    const char *repl;
-    long repl_len;
-    int sflag;
-    bool changed;
-    CFStringRef opt;
-};
-
-static inline void
-trans_replace(CFMutableStringRef str, const CFRange *result_range, 
-	      CFStringRef substr, CFRange *search_range, int sflag)
-{
-    assert(result_range->location + result_range->length 
-	<= CFStringGetLength((CFStringRef)str));
-    if (sflag == 0) {
-	long n;
-	for (n = result_range->location; 
-	     n < result_range->location + result_range->length; 
-	     n++)
-	    CFStringReplace(str, CFRangeMake(n, 1), substr);
-    }
     else {
-	CFStringReplace(str, *result_range, substr);
-	search_range->location = result_range->location + 1;
-	search_range->length = RSTRING_LEN(str) - search_range->location;
-    }	    
-}
-
-static void
-rb_str_trans_cb(CFRange *search_range, const CFRange *result_range, 
-    CFStringRef str, UniChar character, void *ctx)
-{
-    struct tr_trans_cb_ctx *_ctx;
-
-    _ctx = (struct tr_trans_cb_ctx *)ctx;
-    if (_ctx->repl_len == 0) {
-	CFStringDelete((CFMutableStringRef)str, *result_range);
-	search_range->length -= result_range->length 
-	    + (result_range->location - search_range->location);
-	search_range->location = result_range->location;
-    }
-    else if (_ctx->repl_len == 1) {
-	trans_replace((CFMutableStringRef)str, result_range, 
-	    (CFStringRef)_ctx->orepl, search_range, _ctx->sflag);
-    }
-    else if (_ctx->repl_len > 1) {
-	if (_ctx->src_len == 1) {
-	    if (_ctx->opt == NULL) {
-		_ctx->opt = CFStringCreateWithBytes(NULL, 
-		    (const UInt8 *)_ctx->repl, 1, kCFStringEncodingUTF8,
-		    false);
-	    }
-	    trans_replace((CFMutableStringRef)str, result_range, 
-	        (CFStringRef)_ctx->opt, search_range, _ctx->sflag);
+	if (self->encoding->single_byte_encoding) {
+	    return offset_in_bytes;
 	}
+	else if (UTF32_ENC(self->encoding) && (!ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+	    return offset_in_bytes / 4;
+	}
+	else if (NON_NATIVE_UTF16_ENC(self->encoding) && (ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+	    return BYTES_TO_UCHARS(offset_in_bytes);
+	}
 	else {
-	    /* TODO: support all syntaxes */
-	    char sb, se, rb, re;
-	    bool s_is_range, r_is_range;
-	    CFStringRef substr;
-	    bool release_substr;
-	    long delta;
-
-	    sb = se = rb = re = 0;
-
-	    if (_ctx->src_len == 3 && _ctx->src[1] == '-') {
-		sb = _ctx->src[0];
-		se = _ctx->src[2];
-		s_is_range = true;
-	    }
-	    else {
-		s_is_range = false;
-		if (_ctx->src[0] == '^' || strchr(_ctx->src, '-') != NULL)
-		    rb_raise(rb_eRuntimeError, "src argument value (%s) not " \
-			    "supported yet", _ctx->src);
-	    }
-
-	    if (_ctx->repl_len == 3 && _ctx->repl[1] == '-') {
-		rb = _ctx->repl[0];
-		re = _ctx->repl[2];
-		r_is_range = true;
-	    }
-	    else {
-		r_is_range = false;
-		if (_ctx->repl[0] == '^' || strchr(_ctx->repl, '-') != NULL)
-		    rb_raise(rb_eRuntimeError, "repl argument value (%s) not " \
-			    "supported yet", _ctx->repl);
-	    }
-
-	    if (s_is_range) {
-		assert(sb <= character && se >= character);
-		delta = character - sb;
-	    }
-	    else {
-		char *p;
-		p = strchr(_ctx->src, character);
-		assert(p != NULL);
-		delta = (long)p - (long)_ctx->src;
-	    }
-
-	    if ((r_is_range && delta > (re - rb))
-		    || (!r_is_range && delta > _ctx->repl_len)) {
-		if (_ctx->opt == NULL) {
-		    _ctx->opt = CFStringCreateWithBytes(NULL, 
-			    (const UInt8 *)&_ctx->repl[_ctx->repl_len - 1], 
-			    1, 
-			    kCFStringEncodingUTF8,
-			    false);
-		}
-		substr = _ctx->opt;
-		release_substr = false;
-	    }
-	    else {
-		const char r = r_is_range
-		    ? rb + delta : _ctx->repl[delta];
-		substr = CFStringCreateWithBytes(NULL, (const UInt8 *)&r, 1, 
-			kCFStringEncodingUTF8, false);
-		release_substr = true;
-	    }
-
-	    trans_replace((CFMutableStringRef)str, result_range, 
-	        (CFStringRef)substr, search_range, _ctx->sflag);
-
-	    if (release_substr)
-		CFRelease(substr);
+	    return self->encoding->methods.offset_in_bytes_to_index(self, offset_in_bytes, ucs2_mode);
 	}
     }
-    _ctx->changed = true;
 }
 
-static VALUE
-tr_trans(VALUE str, VALUE src, VALUE repl, int sflag)
+static long
+str_offset_in_bytes_for_string(string_t *self, string_t *searched, long start_offset_in_bytes)
 {
-    struct tr_trans_cb_ctx _ctx;
-
-    StringValue(src);
-    StringValue(repl);
-    
-    if (RSTRING_LEN(str) == 0)
-       return Qnil;
-  
-    rb_str_modify(str);
-
-    _ctx.orepl = repl; 
-    _ctx.src = RSTRING_PTR(src);
-    _ctx.repl = RSTRING_PTR(repl);
-
-    /* TODO: support non-8-bit src/repl */
-    assert(_ctx.src != NULL && _ctx.repl != NULL);
-
-    _ctx.src_len = strlen(_ctx.src);
-    _ctx.repl_len = strlen(_ctx.repl);
-    _ctx.sflag = sflag;
-    _ctx.changed = false;
-    _ctx.opt = NULL;
-
-    str_charset_find((CFStringRef)str, &src, 1, _ctx.repl_len > 1,
-	rb_str_trans_cb, &_ctx); 
-
-    if (_ctx.opt != NULL)
-	CFRelease(_ctx.opt);
-
-    return _ctx.changed ? str : Qnil;
-}
-
-/*
- *  call-seq:
- *     str.tr!(from_str, to_str)   => str or nil
- *  
- *  Translates <i>str</i> in place, using the same rules as
- *  <code>String#tr</code>. Returns <i>str</i>, or <code>nil</code> if no
- *  changes were made.
- */
-
-static VALUE
-rb_str_tr_bang(VALUE str, SEL sel, VALUE src, VALUE repl)
-{
-    return tr_trans(str, src, repl, 0);
-}
-
-
-/*
- *  call-seq:
- *     str.tr(from_str, to_str)   => new_str
- *  
- *  Returns a copy of <i>str</i> with the characters in <i>from_str</i> replaced
- *  by the corresponding characters in <i>to_str</i>. If <i>to_str</i> is
- *  shorter than <i>from_str</i>, it is padded with its last character. Both
- *  strings may use the c1--c2 notation to denote ranges of characters, and
- *  <i>from_str</i> may start with a <code>^</code>, which denotes all
- *  characters except those listed.
- *     
- *     "hello".tr('aeiou', '*')    #=> "h*ll*"
- *     "hello".tr('^aeiou', '*')   #=> "*e**o"
- *     "hello".tr('el', 'ip')      #=> "hippo"
- *     "hello".tr('a-y', 'b-z')    #=> "ifmmp"
- */
-
-static VALUE
-rb_str_tr(VALUE str, SEL sel, VALUE src, VALUE repl)
-{
-    str = rb_str_new3(str);
-    rb_str_tr_bang(str, 0, src, repl);
-    return str;
-}
-
-/*
- *  call-seq:
- *     str.delete!([other_str]+)   => str or nil
- *  
- *  Performs a <code>delete</code> operation in place, returning <i>str</i>, or
- *  <code>nil</code> if <i>str</i> was not modified.
- */
-
-static void
-rb_str_delete_bang_cb(CFRange *search_range, const CFRange *result_range, 
-    CFStringRef str, UniChar character, void *ctx)
-{
-    CFStringDelete((CFMutableStringRef)str, *result_range);
-    search_range->length -= result_range->length 
-	+ (result_range->location - search_range->location);
-    search_range->location = result_range->location;
-    *(bool *)ctx = true;
-}
-
-static VALUE
-rb_str_delete_bang(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    bool changed;
-    if (argc < 1) {
-	rb_raise(rb_eArgError, "wrong number of arguments");
+    if (start_offset_in_bytes >= self->length_in_bytes) {
+	return -1;
     }
-    rb_str_modify(str);
-    changed = false;
-    str_charset_find((CFStringRef)str, argv, argc, false,
-	rb_str_delete_bang_cb, &changed);
-    if (!changed) {
-    	return Qnil;
+    if ((self == searched) && (start_offset_in_bytes == 0)) {
+	return 0;
     }
-    return str;
-}
-
-/*
- *  call-seq:
- *     str.delete([other_str]+)   => new_str
- *  
- *  Returns a copy of <i>str</i> with all characters in the intersection of its
- *  arguments deleted. Uses the same rules for building the set of characters as
- *  <code>String#count</code>.
- *     
- *     "hello".delete "l","lo"        #=> "heo"
- *     "hello".delete "lo"            #=> "he"
- *     "hello".delete "aeiou", "^e"   #=> "hell"
- *     "hello".delete "ej-m"          #=> "ho"
- */
-
-static VALUE
-rb_str_delete(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    str = rb_str_new3(str);
-    rb_str_delete_bang(str, 0, argc, argv);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.squeeze!([other_str]*)   => str or nil
- *  
- *  Squeezes <i>str</i> in place, returning either <i>str</i>, or
- *  <code>nil</code> if no changes were made.
- */
-
-static void
-rb_str_squeeze_bang_cb(CFRange *search_range, const CFRange *result_range, 
-    CFStringRef str, UniChar character, void *ctx)
-{
-    if (result_range->length > 1) {
-	CFRange to_delete = *result_range;
-	to_delete.length--;
-	CFStringDelete((CFMutableStringRef)str, to_delete);
-	search_range->length -= result_range->length 
-	    + (result_range->location - search_range->location);
-	search_range->location = result_range->location + 1;
-	*(bool *)ctx = true;
+    if (searched->length_in_bytes == 0) {
+	return start_offset_in_bytes;
     }
-}
-
-static VALUE
-rb_str_squeeze_bang(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    bool changed;
-    VALUE all_chars;
-    if (argc == 0) {
-	argc = 1;
-	all_chars = (VALUE)CFSTR("a-z");
-	argv = &all_chars;
+    str_must_have_compatible_encoding(self, searched);
+    str_make_same_format(self, searched);
+    if (searched->length_in_bytes > self->length_in_bytes) {
+	return -1;
     }
-    rb_str_modify(str);
-    changed = false;
-    str_charset_find((CFStringRef)str, argv, argc, true,
-	rb_str_squeeze_bang_cb, &changed);
-    if (!changed)
-    	return Qnil;
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.squeeze([other_str]*)    => new_str
- *  
- *  Builds a set of characters from the <i>other_str</i> parameter(s) using the
- *  procedure described for <code>String#count</code>. Returns a new string
- *  where runs of the same character that occur in this set are replaced by a
- *  single character. If no arguments are given, all runs of identical
- *  characters are replaced by a single character.
- *     
- *     "yellow moon".squeeze                  #=> "yelow mon"
- *     "  now   is  the".squeeze(" ")         #=> " now is the"
- *     "putters shoot balls".squeeze("m-z")   #=> "puters shot balls"
- */
-
-static VALUE
-rb_str_squeeze(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    str = rb_str_new3(str);
-    rb_str_squeeze_bang(str, 0, argc, argv);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.tr_s!(from_str, to_str)   => str or nil
- *  
- *  Performs <code>String#tr_s</code> processing on <i>str</i> in place,
- *  returning <i>str</i>, or <code>nil</code> if no changes were made.
- */
-
-static VALUE
-rb_str_tr_s_bang(VALUE str, SEL sel, VALUE src, VALUE repl)
-{
-    return tr_trans(str, src, repl, 1);
-}
-
-
-/*
- *  call-seq:
- *     str.tr_s(from_str, to_str)   => new_str
- *  
- *  Processes a copy of <i>str</i> as described under <code>String#tr</code>,
- *  then removes duplicate characters in regions that were affected by the
- *  translation.
- *     
- *     "hello".tr_s('l', 'r')     #=> "hero"
- *     "hello".tr_s('el', '*')    #=> "h*o"
- *     "hello".tr_s('el', 'hx')   #=> "hhxo"
- */
-
-static VALUE
-rb_str_tr_s(VALUE str, SEL sel, VALUE src, VALUE repl)
-{
-    str = rb_str_new3(str);
-    rb_str_tr_s_bang(str, 0, src, repl);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.count([other_str]+)   => fixnum
- *  
- *  Each <i>other_str</i> parameter defines a set of characters to count.  The
- *  intersection of these sets defines the characters to count in
- *  <i>str</i>. Any <i>other_str</i> that starts with a caret (^) is
- *  negated. The sequence c1--c2 means all characters between c1 and c2.
- *     
- *     a = "hello world"
- *     a.count "lo"            #=> 5
- *     a.count "lo", "o"       #=> 2
- *     a.count "hello", "^l"   #=> 4
- *     a.count "ej-m"          #=> 4
- */
-
-static void
-rb_str_count_cb(CFRange *search_range, const CFRange *result_range, 
-    CFStringRef str, UniChar character, void *ctx)
-{
-    (*(int *)ctx) += result_range->length;
-}
-
-static VALUE
-rb_str_count(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    int count;
-    if (argc < 1) {
-	rb_raise(rb_eArgError, "wrong number of arguments");
+    long increment;
+    if (str_is_stored_in_uchars(self)) {
+	increment = 2;
     }
-    count = 0;
-    str_charset_find((CFStringRef)str, argv, argc, false,
-	rb_str_count_cb, &count); 
-    return INT2NUM(count);
+    else {
+	increment = self->encoding->min_char_size;
+    }
+    long max_offset_in_bytes = self->length_in_bytes - searched->length_in_bytes + 1;
+    for (long offset_in_bytes = start_offset_in_bytes; offset_in_bytes < max_offset_in_bytes; offset_in_bytes += increment) {
+	if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes, searched->length_in_bytes) == 0) {
+	    return offset_in_bytes;
+	}
+    }
+    return -1;
 }
 
-/*
- *  call-seq:
- *     str.split(pattern=$;, [limit])   => anArray
- *  
- *  Divides <i>str</i> into substrings based on a delimiter, returning an array
- *  of these substrings.
- *     
- *  If <i>pattern</i> is a <code>String</code>, then its contents are used as
- *  the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
- *  space, <i>str</i> is split on whitespace, with leading whitespace and runs
- *  of contiguous whitespace characters ignored.
- *     
- *  If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
- *  pattern matches. Whenever the pattern matches a zero-length string,
- *  <i>str</i> is split into individual characters. If <i>pattern</i> contains
- *  groups, the respective matches will be returned in the array as well.
- *     
- *  If <i>pattern</i> is omitted, the value of <code>$;</code> is used.  If
- *  <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
- *  split on whitespace as if ` ' were specified.
- *     
- *  If the <i>limit</i> parameter is omitted, trailing null fields are
- *  suppressed. If <i>limit</i> is a positive number, at most that number of
- *  fields will be returned (if <i>limit</i> is <code>1</code>, the entire
- *  string is returned as the only entry in an array). If negative, there is no
- *  limit to the number of fields returned, and trailing null fields are not
- *  suppressed.
- *     
- *     " now's  the time".split        #=> ["now's", "the", "time"]
- *     " now's  the time".split(' ')   #=> ["now's", "the", "time"]
- *     " now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
- *     "1, 2.34,56, 7".split(%r{,\s*}) #=> ["1", "2.34", "56", "7"]
- *     "hello".split(//)               #=> ["h", "e", "l", "l", "o"]
- *     "hello".split(//, 3)            #=> ["h", "e", "llo"]
- *     "hi mom".split(%r{\s*})         #=> ["h", "i", "m", "o", "m"]
- *     
- *     "mellow yellow".split("ello")   #=> ["m", "w y", "w"]
- *     "1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
- *     "1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
- *     "1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]
- */
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
-static inline bool
-CFStringIsSurrogateHighCharacter(UniChar character)
+static long
+str_index_for_string(string_t *self, string_t *searched, long start_index, bool ucs2_mode)
 {
-    return ((character >= 0xD800UL) && (character <= 0xDBFFUL) ? true : false);
-}
-#endif
+    str_must_have_compatible_encoding(self, searched);
+    str_make_same_format(self, searched);
 
-static VALUE
-rb_str_split_m(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    rb_encoding *enc;
-    VALUE spat;
-    VALUE limit;
-    int awk_split = Qfalse;
-    int spat_string = Qfalse;
-    long beg, end, i = 0;
-    int lim = 0;
-    VALUE result, tmp;
-    long clen;
-
-    clen = RSTRING_LEN(str);
-
-    if (rb_scan_args(argc, argv, "02", &spat, &limit) == 2) {
-	lim = NUM2INT(limit);
-	if (lim <= 0) {
-	    limit = Qnil;
-	}
-	else if (lim == 1) {
-	    if (clen == 0) {
-		return rb_ary_new2(0);
-	    }
-	    return rb_ary_new3(1, str);
-	}
-	i = 1;
+    long start_offset_in_bytes;
+    if (start_index == 0) {
+	start_offset_in_bytes = 0;
     }
-
-    enc = STR_ENC_GET(str);
-    result = rb_ary_new();
-    if (NIL_P(spat)) {
-	if (!NIL_P(rb_fs)) {
-	    spat = rb_fs;
-	    goto fs_set;
-	}
-	awk_split = Qtrue;
-    }
     else {
-      fs_set:
-	if (TYPE(spat) == T_STRING) {
-	    spat_string = Qtrue;
-	    if (RSTRING_LEN(spat) == 1
-		&& CFStringGetCharacterAtIndex((CFStringRef)spat, 0) == ' ') {
-		awk_split = Qtrue;
+	character_boundaries_t boundaries = str_get_character_boundaries(self, start_index, ucs2_mode);
+	if (boundaries.start_offset_in_bytes == -1) {
+	    if (boundaries.end_offset_in_bytes == -1) {
+		return -1;
 	    }
-	}
-	else {
-	    spat = get_pat(spat, 1);
-	}
-    }
-
-    beg = 0;
-    if (awk_split || spat_string) {
-	CFRange search_range;
-	CFCharacterSetRef charset = NULL;
-	long spat_len = 0;
-	if (spat == Qnil) {
-	    charset = CFCharacterSetGetPredefined(
-		    kCFCharacterSetWhitespaceAndNewline);
-	}
-	else {
-            spat_len = RSTRING_LEN(spat);
-	}
-	search_range = CFRangeMake(0, clen);
-	do {
-	    CFRange result_range;
-	    CFRange substr_range;
-	    if (spat != Qnil) {
-	        if (spat_len == 0) {
-                    if (search_range.location + 1 < clen && search_range.length > 0) {
-                        result_range.location = search_range.location + 1;
-                        result_range.length = 0;
-                        UniChar c = CFStringGetCharacterAtIndex((CFStringRef)str,
-                                        search_range.location);
-                        if (CFStringIsSurrogateHighCharacter(c)) {
-                            if (result_range.location + 1 < clen) {
-                                ++result_range.location;
-                            }
-                            else {
-                                break;
-                            }
-                        }
-                    }
-                    else {
-                        break;
-                    }
-	        }
-	        else if (!CFStringFindWithOptions((CFStringRef)str, 
-			    (CFStringRef)spat,
-			    search_range,
-			    0,
-			    &result_range)) {
-		    break;
-		}
-	    }
 	    else {
-		if (!CFStringFindCharacterFromSet((CFStringRef)str,
-			    charset, 
-			    search_range,
-			    0,
-			    &result_range)) {
-		    break;
-		}
+		// you cannot cut a surrogate in an encoding that is not UTF-16
+		str_cannot_cut_surrogate();
 	    }
-
-	    substr_range.location = search_range.location;
-	    substr_range.length = result_range.location 
-		- search_range.location;
-
-	    if (awk_split == Qfalse || substr_range.length > 0) {
-		VALUE substr = rb_str_subseq(str, substr_range.location,
-		    substr_range.length);
-
-		if (awk_split == Qtrue) {
-		    CFStringTrimWhitespace((CFMutableStringRef)substr);
-		    if (CFStringGetLength((CFStringRef)substr) > 0) {
-			rb_ary_push(result, substr);
-		    }
-		}
-		else {
-		    rb_ary_push(result, substr);
-		}
-	    }
-
-	    search_range.location = result_range.location + result_range.length;
-	    search_range.length = clen - search_range.location;
 	}
-	while ((limit == Qnil || --lim > 1));
-	beg = search_range.location;
+	start_offset_in_bytes = boundaries.start_offset_in_bytes;
     }
-    else {
-	long start = beg;
-	bool last_null = false;
-	struct re_registers *regs;
 
-	while ((end = rb_reg_search2(spat, str, start, 0, false)) >= 0) {
-	    regs = RMATCH_REGS(rb_backref_get());
-	    if (start == end && BEG(0) == END(0)) {
-		if (0) {
-		    break;
-		}
-		else if (last_null) {
-		    rb_ary_push(result, rb_str_subseq(str, beg, 1));
-		    beg = start;
-		}
-		else {
-		    start++;
-		    last_null = true;
-		    continue;
-		}
-	    }
-	    else {
-		rb_ary_push(result, rb_str_subseq(str, beg, end-beg));
-		beg = start = END(0);
-	    }
-	    last_null = false;
+    long offset_in_bytes = str_offset_in_bytes_for_string(STR(self), searched, start_offset_in_bytes);
 
-	    for (long idx = 1; idx < regs->num_regs; idx++) {
-		if (BEG(idx) == -1) {
-		    continue;
-		}
-		if (BEG(idx) == END(idx)) {
-		    tmp = rb_str_new5(str, 0, 0);
-		}
-		else {
-		    tmp = rb_str_subseq(str, BEG(idx), END(idx) - BEG(idx));
-		}
-		rb_ary_push(result, tmp);
-	    }
-	    if (!NIL_P(limit) && lim <= ++i) {
-		break;
-	    }
-	}
+    if (offset_in_bytes == -1) {
+	return -1;
     }
-    if (clen > 0 && (!NIL_P(limit) || clen > beg || lim < 0)) {
-	if (clen == beg) {
-	    tmp = rb_str_new5(str, 0, 0);
-	}
-	else {
-	    tmp = rb_str_subseq(str, beg, clen-beg);
-	}
-	rb_ary_push(result, tmp);
-    }
-    if (NIL_P(limit) && lim == 0) {
-	while (RARRAY_LEN(result) > 0 &&
-	       RSTRING_LEN(RARRAY_AT(result, RARRAY_LEN(result)-1)) == 0)
-	    rb_ary_pop(result);
-    }
-
-    return result;
+    return str_offset_in_bytes_to_index(STR(self), offset_in_bytes, ucs2_mode);
 }
 
-VALUE
-rb_str_split(VALUE str, const char *sep0)
+static bool
+str_include_string(string_t *self, string_t *searched)
 {
-    VALUE sep;
-
-    StringValue(str);
-    sep = rb_str_new2(sep0);
-    return rb_str_split_m(str, 0, 1, &sep);
+    return (str_offset_in_bytes_for_string(self, searched, 0) != -1);
 }
 
-VALUE
-rb_str_split2(VALUE str, VALUE sep)
+static string_t *
+str_need_string(VALUE str)
 {
-    StringValue(str);
-    StringValue(sep);
-    return rb_str_split_m(str, 0, 1, &sep);
-}
-
-/*
- *  Document-method: lines
- *  call-seq:
- *     str.lines(separator=$/)   => anEnumerator
- *     str.lines(separator=$/) {|substr| block }        => str
- *  
- *  Returns an enumerator that gives each line in the string.  If a block is
- *  given, it iterates over each line in the string.
- *     
- *     "foo\nbar\n".lines.to_a   #=> ["foo\n", "bar\n"]
- *     "foo\nb ar".lines.sort    #=> ["b ar", "foo\n"]
- */
-
-/*
- *  Document-method: each_line
- *  call-seq:
- *     str.each_line(separator=$/) {|substr| block }   => str
- *  
- *  Splits <i>str</i> using the supplied parameter as the record separator
- *  (<code>$/</code> by default), passing each substring in turn to the supplied
- *  block. If a zero-length record separator is supplied, the string is split
- *  into paragraphs delimited by multiple successive newlines.
- *     
- *     print "Example one\n"
- *     "hello\nworld".each {|s| p s}
- *     print "Example two\n"
- *     "hello\nworld".each('l') {|s| p s}
- *     print "Example three\n"
- *     "hello\n\n\nworld".each('') {|s| p s}
- *     
- *  <em>produces:</em>
- *     
- *     Example one
- *     "hello\n"
- *     "world"
- *     Example two
- *     "hel"
- *     "l"
- *     "o\nworl"
- *     "d"
- *     Example three
- *     "hello\n\n\n"
- *     "world"
- */
-
-static VALUE
-rb_str_each_line(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE rs;
-    long n;
-    CFStringRef substr;
-    CFRange sub_range, search_range, res_range;
-    bool zero_sep;
-
-    if (rb_scan_args(argc, argv, "01", &rs) == 0) {
-	rs = rb_rs;
+    if (CLASS_OF(str) == rb_cMRString) {
+	return (string_t *)str;
     }
-    RETURN_ENUMERATOR(str, argc, argv);
-    if (NIL_P(rs)) {
-	rb_yield(str);
-	return str;
-    }
-    StringValue(rs);
-    zero_sep = CFStringGetLength((CFStringRef)rs) == 0;
-    if (zero_sep) {
-	rs = rb_default_rs;
-    }
-    n = CFStringGetLength((CFStringRef)str);
-    search_range = CFRangeMake(0, n);
-    sub_range = CFRangeMake(0, 0);
 
-    const bool tainted = OBJ_TAINTED(str);
-
-#define YIELD_SUBSTR(range) \
-    do { \
-	VALUE mcopy; \
-	substr = CFStringCreateWithSubstring(NULL, (CFStringRef)str,  \
-	    range); \
-	mcopy = (VALUE)CFStringCreateMutableCopy(NULL, 0, \
-	    (CFStringRef)substr); \
-	CFMakeCollectable((CFTypeRef)mcopy); \
-	if (tainted) { \
-	    OBJ_TAINT(mcopy); \
-	} \
-	rb_yield(mcopy); \
-	RETURN_IF_BROKEN(); \
-    } \
-    while (0)
-
-    while (CFStringFindWithOptions((CFStringRef)str, (CFStringRef)rs,
-	search_range, 0, &res_range)) {
-	if (zero_sep
-	    && sub_range.length > 0 
-	    && sub_range.location + sub_range.length 
-	       == res_range.location) {
-	    sub_range.length += res_range.length;
-	}		
-	else {
-	    if (sub_range.length > 0)
-		YIELD_SUBSTR(sub_range);
-	    sub_range = CFRangeMake(search_range.location, 
-		res_range.location - search_range.location + res_range.length);
-	}
-	search_range.location = res_range.location + res_range.length;
-	search_range.length = n - search_range.location;
+    if (TYPE(str) != T_STRING) {
+	str = rb_str_to_str(str);
     }
-
-    if (sub_range.length != 0)
-	YIELD_SUBSTR(sub_range);
-
-    if (search_range.location < n)
-	YIELD_SUBSTR(CFRangeMake(search_range.location, 
-	    n - search_range.location));
-
-#undef YIELD_SUBSTR
-
-    return str;
-}
-
-/*
- *  Document-method: bytes
- *  call-seq:
- *     str.bytes   => anEnumerator
- *     str.bytes {|fixnum| block }    => str
- *  
- *  Returns an enumerator that gives each byte in the string.  If a block is
- *  given, it iterates over each byte in the string.
- *     
- *     "hello".bytes.to_a        #=> [104, 101, 108, 108, 111]
- */
-
-/*
- *  Document-method: each_byte
- *  call-seq:
- *     str.each_byte {|fixnum| block }    => str
- *  
- *  Passes each byte in <i>str</i> to the given block.
- *     
- *     "hello".each_byte {|c| print c, ' ' }
- *     
- *  <em>produces:</em>
- *     
- *     104 101 108 108 111
- */
-
-static VALUE
-rb_str_each_byte(VALUE str, SEL sel)
-{
-    RETURN_ENUMERATOR(str, 0, 0);
-
-    long n = RSTRING_LEN(str);
-    if (n == 0) {
-	return str;
+    if (OBJC_CLASS(str) != rb_cMRString) {
+	return str_new_from_cfstring((CFStringRef)str);
     }
-
-    CFStringEncoding encoding = CFStringGetSmallestEncoding((CFStringRef)str);
-    const long buflen = CFStringGetMaximumSizeForEncoding(n, encoding);
-    UInt8 *buffer = (UInt8 *)alloca(buflen + 1);
-    long used_buflen = 0;
-
-    CFStringGetBytes((CFStringRef)str,
-	    CFRangeMake(0, n),
-	    encoding,
-	    0,
-	    false,
-	    buffer,
-	    buflen+1,
-	    &used_buflen);
-
-    long i;
-    for (i = 0; i < used_buflen; i++) {
-	rb_yield(INT2FIX(buffer[i]));
-	RETURN_IF_BROKEN();
+    else {
+	return (string_t *)str;
     }
-
-    return str;
 }
 
+//----------------------------------------------
+// Functions called by MacRuby
 
-/*
- *  Document-method: chars
- *  call-seq:
- *     str.chars                   => anEnumerator
- *     str.chars {|substr| block } => str
- *  
- *  Returns an enumerator that gives each character in the string.
- *  If a block is given, it iterates over each character in the string.
- *     
- *     "foo".chars.to_a   #=> ["f","o","o"]
- */
-
-/*
- *  Document-method: each_char
- *  call-seq:
- *     str.each_char {|cstr| block }    => str
- *  
- *  Passes each character in <i>str</i> to the given block.
- *     
- *     "hello".each_char {|c| print c, ' ' }
- *     
- *  <em>produces:</em>
- *     
- *     h e l l o 
- */
-
-static VALUE
-rb_str_each_char(VALUE str, SEL sel)
+VALUE
+mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2)
 {
-    CFStringInlineBuffer buf;
-    long i, n;
-
-    RETURN_ENUMERATOR(str, 0, 0);
-    n = CFStringGetLength((CFStringRef)str);
-    CFStringInitInlineBuffer((CFStringRef)str, &buf, CFRangeMake(0, n));
-    for (i = 0; i < n; i++) {
-	UniChar c;
-	VALUE s;
-
-	c = CFStringGetCharacterFromInlineBuffer(&buf, i);
-	s = rb_str_new(NULL, 0);
-	CFStringAppendCharacters((CFMutableStringRef)s, &c, 1);
-	rb_yield(s);
-	RETURN_IF_BROKEN();
-    }
-    return str;
-}
-
-/*
- *  call-seq:
- *     str.chop!   => str or nil
- *  
- *  Processes <i>str</i> as for <code>String#chop</code>, returning <i>str</i>,
- *  or <code>nil</code> if <i>str</i> is the empty string.  See also
- *  <code>String#chomp!</code>.
- */
-
-static VALUE
-rb_str_chop_bang(VALUE str, SEL sel)
-{
-    long n;
-    const char *p;
-    CFRange r;
-
-    n = CFStringGetLength((CFStringRef)str);
-    if (n == 0)
+    if (SPECIAL_CONST_P(str1) || SPECIAL_CONST_P(str2)) {
 	return Qnil;
-    rb_str_modify(str);
-    p = RSTRING_PTR(str);
-    r = CFRangeMake(n - 1, 1);
-    if (n >= 2 && p[n - 1] == '\n' && p[n - 2] == '\r') {
-	/* We need this to pass the tests, but this is most probably 
-	 * unnecessary.
-	 */
-	r.location--;
-	r.length++;
     }
-    CFStringDelete((CFMutableStringRef)str, r);
-    return str;
-}
-
-
-/*
- *  call-seq:
- *     str.chop   => new_str
- *  
- *  Returns a new <code>String</code> with the last character removed.  If the
- *  string ends with <code>\r\n</code>, both characters are removed. Applying
- *  <code>chop</code> to an empty string returns an empty
- *  string. <code>String#chomp</code> is often a safer alternative, as it leaves
- *  the string unchanged if it doesn't end in a record separator.
- *     
- *     "string\r\n".chop   #=> "string"
- *     "string\n\r".chop   #=> "string\n"
- *     "string\n".chop     #=> "string"
- *     "string".chop       #=> "strin"
- *     "x".chop.chop       #=> ""
- */
-
-static VALUE
-rb_str_chop(VALUE str, SEL sel)
-{
-    VALUE str2 = rb_str_new3(str);
-    rb_str_chop_bang(str2, 0);
-    return str2;
-}
-
-/*
- *  call-seq:
- *     str.chomp!(separator=$/)   => str or nil
- *  
- *  Modifies <i>str</i> in place as described for <code>String#chomp</code>,
- *  returning <i>str</i>, or <code>nil</code> if no modifications were made.
- */
-
-static VALUE
-rb_str_chomp_bang(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE rs;
-    long len, rslen;
-    CFRange range_result;
-
-    if (rb_scan_args(argc, argv, "01", &rs) == 0) {
-	rs = rb_rs;
-    }
-    rb_str_modify(str);
-    if (rs == Qnil) {
+    assert(OBJC_CLASS(str1) == rb_cMRString); // TODO
+    assert(OBJC_CLASS(str2) == rb_cMRString); // TODO
+    encoding_t *encoding = str_compatible_encoding(STR(str1), STR(str2));
+    if (encoding == NULL) {
 	return Qnil;
     }
-    len = CFStringGetLength((CFStringRef)str);
-    if (len == 0) {
-	return Qnil;
-    }
-    StringValue(rs);
-    rslen = CFStringGetLength((CFStringRef)rs);
-    range_result = CFRangeMake(len, 0);
-    if (rs == rb_default_rs
-	|| rslen == 0
-	|| (rslen == 1 
-	    && CFStringGetCharacterAtIndex((CFStringRef)rs, 0) == '\n')) {
-	UniChar c;
-	c = CFStringGetCharacterAtIndex((CFStringRef)str, 
-		range_result.location - 1);
-	if (c == '\n') {
-	    range_result.location--;
-	    range_result.length++;
-	    c = CFStringGetCharacterAtIndex((CFStringRef)str, 
-		    range_result.location - 1);
-	}
-	if (c == '\r' && (rslen > 0 || range_result.location != len)) {
-	    /* MS is the devil */
-	    range_result.location--;
-	    range_result.length++;
-	}
-    }
     else {
-	StringValue(rs);
-	CFStringFindWithOptions((CFStringRef)str, (CFStringRef)rs,
-		CFRangeMake(len - rslen, rslen), 0, &range_result);
+	return (VALUE)encoding;
     }
-    if (range_result.length == 0 
-	|| range_result.location + range_result.length > len) {
-	return Qnil;
-    }
-    CFStringDelete((CFMutableStringRef)str, range_result);
-    return str;
 }
 
 
-/*
- *  call-seq:
- *     str.chomp(separator=$/)   => new_str
- *  
- *  Returns a new <code>String</code> with the given record separator removed
- *  from the end of <i>str</i> (if present). If <code>$/</code> has not been
- *  changed from the default Ruby record separator, then <code>chomp</code> also
- *  removes carriage return characters (that is it will remove <code>\n</code>,
- *  <code>\r</code>, and <code>\r\n</code>).
- *     
- *     "hello".chomp            #=> "hello"
- *     "hello\n".chomp          #=> "hello"
- *     "hello\r\n".chomp        #=> "hello"
- *     "hello\n\r".chomp        #=> "hello\n"
- *     "hello\r".chomp          #=> "hello"
- *     "hello \n there".chomp   #=> "hello \n there"
- *     "hello".chomp("llo")     #=> "he"
- */
-
 static VALUE
-rb_str_chomp(VALUE str, SEL sel, int argc, VALUE *argv)
+mr_str_s_alloc(VALUE klass)
 {
-    str = rb_str_new3(str);
-    rb_str_chomp_bang(str, 0, argc, argv);
-    return str;
+    return (VALUE)str_alloc();
 }
 
-/*
- *  call-seq:
- *     str.lstrip!   => self or nil
- *  
- *  Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
- *  change was made. See also <code>String#rstrip!</code> and
- *  <code>String#strip!</code>.
- *     
- *     "  hello  ".lstrip   #=> "hello  "
- *     "hello".lstrip!      #=> nil
- */
 
 static VALUE
-rb_str_strip_bang2(VALUE str, int direction)
+mr_str_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
 {
-    long i, n, orig_n;
-    CFStringInlineBuffer buf;
-    CFCharacterSetRef charset;
-    bool changed;
-
-    rb_str_modify(str);
-    n = orig_n = CFStringGetLength((CFStringRef)str);
-    if (n == 0)
-	return Qnil;
-    CFStringInitInlineBuffer((CFStringRef)str, &buf, CFRangeMake(0, n));
-    charset = CFCharacterSetGetPredefined(kCFCharacterSetWhitespaceAndNewline);
-    changed = false;
-
-    if (direction >= 0) {
-	for (i = n - 1; i >= 0; i--) {
-	    UniChar c = CFStringGetCharacterFromInlineBuffer(&buf, i);
-	    if (!CFCharacterSetIsCharacterMember(charset, c))
-		break;
-	}
-	if (i < n - 1) {
-	    CFRange range = CFRangeMake(i + 1, n - i - 1);
-	    CFStringDelete((CFMutableStringRef)str, range);
-	    n -= range.length;	    
-	}
+    if (argc > 0) {
+	assert(argc == 1);
+	str_replace(STR(self), argv[0]);
     }
-
-    if (direction <= 0) {
-	for (i = 0; i < n; i++) {
-	    UniChar c = CFStringGetCharacterFromInlineBuffer(&buf, i);
-	    if (!CFCharacterSetIsCharacterMember(charset, c))
-		break;
-	}
-	if (i > 0) {
-	    CFRange range = CFRangeMake(0, i);
-	    CFStringDelete((CFMutableStringRef)str, range);
-	}
-    }
-
-    return orig_n != n ? str : Qnil;
+    return self;
 }
 
 static VALUE
-rb_str_lstrip_bang(VALUE str, SEL sel)
+mr_str_replace(VALUE self, SEL sel, VALUE arg)
 {
-    return rb_str_strip_bang2(str, -1);
+    str_replace(STR(self), arg);
+    return self;
 }
 
-
-/*
- *  call-seq:
- *     str.lstrip   => new_str
- *  
- *  Returns a copy of <i>str</i> with leading whitespace removed. See also
- *  <code>String#rstrip</code> and <code>String#strip</code>.
- *     
- *     "  hello  ".lstrip   #=> "hello  "
- *     "hello".lstrip       #=> "hello"
- */
-
 static VALUE
-rb_str_lstrip(VALUE str)
+mr_str_clear(VALUE self, SEL sel)
 {
-    str = rb_str_dup(str);
-    rb_str_lstrip_bang(str, 0);
-    return str;
+    str_clear(STR(self));
+    return self;
 }
 
-
-/*
- *  call-seq:
- *     str.rstrip!   => self or nil
- *  
- *  Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if
- *  no change was made. See also <code>String#lstrip!</code> and
- *  <code>String#strip!</code>.
- *     
- *     "  hello  ".rstrip   #=> "  hello"
- *     "hello".rstrip!      #=> nil
- */
-
 static VALUE
-rb_str_rstrip_bang(VALUE str, SEL sel)
+mr_str_chars_count(VALUE self, SEL sel)
 {
-    return rb_str_strip_bang2(str, 1);
+    return INT2NUM(str_length(STR(self), false));
 }
 
-
-/*
- *  call-seq:
- *     str.rstrip   => new_str
- *  
- *  Returns a copy of <i>str</i> with trailing whitespace removed. See also
- *  <code>String#lstrip</code> and <code>String#strip</code>.
- *     
- *     "  hello  ".rstrip   #=> "  hello"
- *     "hello".rstrip       #=> "hello"
- */
-
 static VALUE
-rb_str_rstrip(VALUE str)
+mr_str_length(VALUE self, SEL sel)
 {
-    str = rb_str_dup(str);
-    rb_str_rstrip_bang(str, 0);
-    return str;
+    return INT2NUM(str_length(STR(self), true));
 }
 
-
-/*
- *  call-seq:
- *     str.strip!   => str or nil
- *  
- *  Removes leading and trailing whitespace from <i>str</i>. Returns
- *  <code>nil</code> if <i>str</i> was not altered.
- */
-
 static VALUE
-rb_str_strip_bang(VALUE str, SEL sel)
+mr_str_bytesize(VALUE self, SEL sel)
 {
-    return rb_str_strip_bang2(str, 0);
+    return INT2NUM(str_bytesize(STR(self)));
 }
 
-
-/*
- *  call-seq:
- *     str.strip   => new_str
- *  
- *  Returns a copy of <i>str</i> with leading and trailing whitespace removed.
- *     
- *     "    hello    ".strip   #=> "hello"
- *     "\tgoodbye\r\n".strip   #=> "goodbye"
- */
-
 static VALUE
-rb_str_strip(VALUE str, SEL sel)
+mr_str_encoding(VALUE self, SEL sel)
 {
-    str = rb_str_dup(str);
-    rb_str_strip_bang(str, 0);
-    return str;
+    return (VALUE)STR(self)->encoding;
 }
 
 static VALUE
-scan_once(VALUE str, VALUE pat, long *start, long strlen, bool pat_is_string)
+mr_str_getbyte(VALUE self, SEL sel, VALUE index)
 {
-    VALUE result, match;
-    struct re_registers *regs;
-    long i;
-
-    if (pat_is_string) {
-	/* XXX this is sometimes slower than the regexp search, especially for
-	 * long pattern strings 
-	 */
-	CFRange result_range;
-	if (CFStringFindWithOptions((CFStringRef)str, 
-	    (CFStringRef)pat,
-	    CFRangeMake(*start, strlen - *start),
-	    0,
-	    &result_range)) {
-	    CFStringRef substr = CFStringCreateWithSubstring(NULL, 
-		(CFStringRef)str, result_range);
-	    *start = result_range.location + result_range.length + 1;
-	    result = (VALUE)CFStringCreateMutableCopy(NULL, 0, substr);
-	    CFRelease(substr);
-	    CFMakeCollectable((CFTypeRef)result);
-	}
-	else {
-	    result = Qnil;
-	}
-	return result;
+    unsigned char c;
+    if (str_getbyte(STR(self), NUM2LONG(index), &c)) {
+	return INT2NUM(c);
     }
-
-    if (rb_reg_search2(pat, str, *start, 0, false) >= 0) {
-	match = rb_backref_get();
-	GC_WB(&RMATCH(match)->str, str);
-	regs = RMATCH_REGS(match);
-	if (BEG(0) == END(0)) {
-	    /*
-	     * Always consume at least one character of the input string
-	     */
-	    *start = END(0)+1;
-	}
-	else {
-	    *start = END(0);
-	}
-	if (regs->num_regs == 1) {
-	    return rb_reg_nth_match(0, match);
-	}
-	result = rb_ary_new2(regs->num_regs);
-	for (i=1; i < regs->num_regs; i++) {
-	    rb_ary_push(result, rb_reg_nth_match(i, match));
-	}
-
-	return result;
+    else {
+	return Qnil;
     }
-    return Qnil;
 }
 
-
-/*
- *  call-seq:
- *     str.scan(pattern)                         => array
- *     str.scan(pattern) {|match, ...| block }   => str
- *  
- *  Both forms iterate through <i>str</i>, matching the pattern (which may be a
- *  <code>Regexp</code> or a <code>String</code>). For each match, a result is
- *  generated and either added to the result array or passed to the block. If
- *  the pattern contains no groups, each individual result consists of the
- *  matched string, <code>$&</code>.  If the pattern contains groups, each
- *  individual result is itself an array containing one entry per group.
- *     
- *     a = "cruel world"
- *     a.scan(/\w+/)        #=> ["cruel", "world"]
- *     a.scan(/.../)        #=> ["cru", "el ", "wor"]
- *     a.scan(/(...)/)      #=> [["cru"], ["el "], ["wor"]]
- *     a.scan(/(..)(..)/)   #=> [["cr", "ue"], ["l ", "wo"]]
- *     
- *  And the block form:
- *     
- *     a.scan(/\w+/) {|w| print "<<#{w}>> " }
- *     print "\n"
- *     a.scan(/(.)(.)/) {|x,y| print y, x }
- *     print "\n"
- *     
- *  <em>produces:</em>
- *     
- *     <<cruel>> <<world>>
- *     rceu lowlr
- */
-
 static VALUE
-rb_str_scan(VALUE str, SEL sel, VALUE pat)
+mr_str_setbyte(VALUE self, SEL sel, VALUE index, VALUE value)
 {
-    VALUE result;
-    long start = 0;
-    VALUE match = Qnil;
-    long len = CFStringGetLength((CFStringRef)str);
-    bool pat_is_string = TYPE(pat) == T_STRING;
-    
-    if (!pat_is_string) {
-	pat = get_pat(pat, 1);
-    }
-    if (!rb_block_given_p()) {
-	VALUE ary = rb_ary_new();
-
-	while (!NIL_P(result = scan_once(str, pat, &start, len, 
-					 pat_is_string))) {
-	    rb_ary_push(ary, result);
-	}
-	return ary;
-    }
-
-    while (!NIL_P(result = scan_once(str, pat, &start, len, pat_is_string))) {
-	match = rb_backref_get();
-	rb_match_busy(match);
-	rb_yield(result);
-	RETURN_IF_BROKEN();
-	rb_backref_set(match);	/* restore $~ value */
-    }
-    rb_backref_set(match);
-    return str;
+    str_setbyte(STR(self), NUM2LONG(index), 0xFF & (unsigned long)NUM2LONG(value));
+    return value;
 }
 
-
-/*
- *  call-seq:
- *     str.hex   => integer
- *  
- *  Treats leading characters from <i>str</i> as a string of hexadecimal digits
- *  (with an optional sign and an optional <code>0x</code>) and returns the
- *  corresponding number. Zero is returned on error.
- *     
- *     "0x0a".hex     #=> 10
- *     "-1234".hex    #=> -4660
- *     "0".hex        #=> 0
- *     "wombat".hex   #=> 0
- */
-
 static VALUE
-rb_str_hex(VALUE str, SEL sel)
+mr_str_force_encoding(VALUE self, SEL sel, VALUE encoding)
 {
-    rb_encoding *enc = rb_enc_get(str);
-
-    if (!rb_enc_asciicompat(enc)) {
-	rb_raise(rb_eArgError, "ASCII incompatible encoding: %s", rb_enc_name(enc));
+    encoding_t *enc;
+    if (SPECIAL_CONST_P(encoding) || (OBJC_CLASS(encoding) != rb_cMREncoding)) {
+	abort(); // TODO
     }
-    return rb_str_to_inum(str, 16, Qfalse);
+    enc = (encoding_t *)encoding;
+    str_force_encoding(STR(self), enc);
+    return self;
 }
 
-
-/*
- *  call-seq:
- *     str.oct   => integer
- *  
- *  Treats leading characters of <i>str</i> as a string of octal digits (with an
- *  optional sign) and returns the corresponding number.  Returns 0 if the
- *  conversion fails.
- *     
- *     "123".oct       #=> 83
- *     "-377".oct      #=> -255
- *     "bad".oct       #=> 0
- *     "0377bad".oct   #=> 255
- */
-
 static VALUE
-rb_str_oct(VALUE str, SEL sel)
+mr_str_is_valid_encoding(VALUE self, SEL sel)
 {
-    rb_encoding *enc = rb_enc_get(str);
-
-    if (!rb_enc_asciicompat(enc)) {
-	rb_raise(rb_eArgError, "ASCII incompatible encoding: %s", rb_enc_name(enc));
-    }
-    return rb_str_to_inum(str, -8, Qfalse);
+    return str_is_valid_encoding(STR(self)) ? Qtrue : Qfalse;
 }
 
-
-/*
- *  call-seq:
- *     str.crypt(other_str)   => new_str
- *  
- *  Applies a one-way cryptographic hash to <i>str</i> by invoking the standard
- *  library function <code>crypt</code>. The argument is the salt string, which
- *  should be two characters long, each character drawn from
- *  <code>[a-zA-Z0-9./]</code>.
- */
-
-extern char *crypt(const char *, const char *);
-
 static VALUE
-rb_str_crypt(VALUE str, SEL sel, VALUE salt)
+mr_str_is_ascii_only(VALUE self, SEL sel)
 {
-    StringValue(salt);
-    if (RSTRING_LEN(salt) < 2) {
-	rb_raise(rb_eArgError, "salt too short (need >=2 bytes)");
-    }
-
-    size_t str_len = RSTRING_LEN(str);
-    char *s = alloca(str_len + 1);
-    strncpy(s, RSTRING_PTR(str), str_len + 1);
-
-    VALUE crypted = rb_str_new2(crypt(s, RSTRING_PTR(salt)));
-    if (OBJ_TAINTED(str) || OBJ_TAINTED(salt)) {
-	OBJ_TAINT(crypted);
-    }
-    return crypted;
+    return str_is_ruby_ascii_only(STR(self)) ? Qtrue : Qfalse;
 }
 
-
-/*
- *  call-seq:
- *     str.intern   => symbol
- *     str.to_sym   => symbol
- *  
- *  Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the
- *  symbol if it did not previously exist. See <code>Symbol#id2name</code>.
- *     
- *     "Koala".intern         #=> :Koala
- *     s = 'cat'.to_sym       #=> :cat
- *     s == :cat              #=> true
- *     s = '@cat'.to_sym      #=> :@cat
- *     s == :@cat             #=> true
- *
- *  This can also be used to create symbols that cannot be represented using the
- *  <code>:xxx</code> notation.
- *     
- *     'cat and dog'.to_sym   #=> :"cat and dog"
- */
-
-VALUE
-rb_str_intern_fast(VALUE s)
-{
-    char *cptr = (char *)CFStringGetCStringPtr((CFStringRef)s, 0);
-    if (cptr != NULL) {
-	return ID2SYM(rb_intern(cptr));
-    }
-
-    char buf[200];
-    if (CFStringGetLength((CFStringRef)s) > sizeof(buf)) {
-	return ID2SYM(rb_intern(RSTRING_PTR(s)));
-    }
-
-    if (!CFStringGetCString((CFStringRef)s, buf, sizeof buf,
-		kCFStringEncodingUTF8)) {
-	// Probably an UTF16 string...
-	rb_raise(rb_eRuntimeError, "can't intern string `%p'", (void *)s);
-    }
-    return ID2SYM(rb_intern(buf));
-}
-
 static VALUE
-rb_str_intern(VALUE str, SEL sel)
+mr_str_aref(VALUE self, SEL sel, int argc, VALUE *argv)
 {
-    if (OBJ_TAINTED(str) && rb_safe_level() >= 1) {
-	rb_raise(rb_eSecurityError, "Insecure: can't intern tainted string");
-    }
-    return rb_str_intern_fast(str);
-}
+    string_t *ret;
+    if (argc == 1) {
+	VALUE index = argv[0];
+	switch (TYPE(index)) {
+	    case T_FIXNUM:
+		{
+		    ret = str_get_character_at(STR(self), FIX2LONG(index), true);
+		}
+		break;
 
-/*
- *  call-seq:
- *     str.ord   => integer
- *  
- *  Return the <code>Integer</code> ordinal of a one-character string.
- *     
- *     "a".ord         #=> 97
- */
+	    case T_REGEXP:
+		abort(); // TODO
 
-static VALUE
-rb_str_ord(VALUE s, SEL sel)
-{
-    if (CFStringGetLength((CFStringRef)s) == 0) {
-	rb_raise(rb_eArgError, "empty string");
-    }
-    return INT2NUM(CFStringGetCharacterAtIndex((CFStringRef)s, 0));
-}
+	    case T_STRING:
+		{
+		    if (OBJC_CLASS(index) == rb_cMRString) {
+			string_t *searched = STR(index);
+			if (str_include_string(STR(self), searched)) {
+			    return (VALUE)str_new_from_string(searched);
+			}
+		    }
+		    else {
+			string_t *searched = str_new_from_cfstring((CFStringRef)index);
+			if (str_include_string(STR(self), searched)) {
+			    // no need to duplicate the string as we just created it
+			    return (VALUE)searched;
+			}
+		    }
+		    return Qnil;
+		}
 
-/*
- *  call-seq:
- *     str.sum(n=16)   => integer
- *  
- *  Returns a basic <em>n</em>-bit checksum of the characters in <i>str</i>,
- *  where <em>n</em> is the optional <code>Fixnum</code> parameter, defaulting
- *  to 16. The result is simply the sum of the binary value of each character in
- *  <i>str</i> modulo <code>2n - 1</code>. This is not a particularly good
- *  checksum.
- */
-
-static VALUE
-rb_str_sum(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    VALUE vbits;
-    int bits;
-    const char *ptr, *p, *pend;
-    long len;
-
-    if (argc == 0) {
-	bits = 16;
+	    default:
+		{
+		    VALUE rb_start = 0, rb_end = 0;
+		    int exclude_end = false;
+		    if (rb_range_values(index, &rb_start, &rb_end, &exclude_end)) {
+			long start = NUM2LONG(rb_start);
+			long end = NUM2LONG(rb_end);
+			if (exclude_end) {
+			    --end;
+			}
+			ret = str_get_characters(STR(self), start, end, true);
+		    }
+		    else {
+			ret = str_get_character_at(STR(self), NUM2LONG(index), true);
+		    }
+		}
+		break;
+	}
     }
-    else {
-	rb_scan_args(argc, argv, "01", &vbits);
-	bits = NUM2INT(vbits);
-    }
-    ptr = p = RSTRING_PTR(str);
-    len = RSTRING_LEN(str);
-    pend = p + len;
-    if (bits >= sizeof(long)*CHAR_BIT) {
-	VALUE sum = INT2FIX(0);
-
-	while (p < pend) {
-	    str_mod_check(str, ptr, len);
-	    sum = rb_funcall(sum, '+', 1, INT2FIX((unsigned char)*p));
-	    p++;
+    else if (argc == 2) {
+	long length = NUM2LONG(argv[1]);
+	long start = NUM2LONG(argv[0]);
+	if (length < 0) {
+	    return Qnil;
 	}
-	if (bits != 0) {
-	    VALUE mod;
-
-	    mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits));
-	    mod = rb_funcall(mod, '-', 1, INT2FIX(1));
-	    sum = rb_funcall(sum, '&', 1, mod);
+	long end = start + length - 1;
+	if ((start < 0) && (end >= 0)) {
+	    end = -1;
 	}
-	return sum;
+	ret = str_get_characters(STR(self), start, end, true);
     }
     else {
-       unsigned long sum = 0;
-
-	while (p < pend) {
-	    str_mod_check(str, ptr, len);
-	    sum += (unsigned char)*p;
-	    p++;
-	}
-	if (bits != 0) {
-           sum &= (((unsigned long)1)<<bits)-1;
-	}
-	return rb_int2inum(sum);
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
     }
-}
 
-static inline void
-rb_str_justify0(VALUE str, VALUE pad, long width, long padwidth, long index)
-{
-    do {
-	if (padwidth > width) {
-	    pad = (VALUE)CFStringCreateWithSubstring(
-		    NULL,
-		    (CFStringRef)pad,
-		    CFRangeMake(0, width));
-	    CFMakeCollectable((CFTypeRef)pad);
-	}
-	CFStringInsert((CFMutableStringRef)str, index, (CFStringRef)pad);
-	width -= padwidth;
-	index += padwidth;
+    if (ret == NULL) {
+	return Qnil;
     }
-    while (width > 0);
+    else {
+	return (VALUE)ret;
+    }
 }
 
 static VALUE
-rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag)
+mr_str_index(VALUE self, SEL sel, int argc, VALUE *argv)
 {
-    VALUE w, pad;
-    long n, width, padwidth;
-
-    rb_scan_args(argc, argv, "11", &w, &pad);
-    width = NUM2LONG(w);
-
-    if (NIL_P(pad)) {
-	pad = rb_str_new(" ", 1);
-	padwidth = 1;
+    if ((argc < 1) || (argc > 2)) {
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
     }
-    else {
-	StringValue(pad);
-	padwidth = CFStringGetLength((CFStringRef)pad);
-    }
 
-    if (padwidth == 0) {
-	rb_raise(rb_eArgError, "zero width padding");
+    VALUE rb_searched = argv[0];
+    if (TYPE(rb_searched) == T_REGEXP) {
+	abort(); // TODO
     }
 
-    n = CFStringGetLength((CFStringRef)str);
-   
-    str = rb_str_new3(str);
-    if (width < 0 || width <= n) {
-	return str;
+    long start_index = 0;
+    if (argc == 2) {
+	start_index = NUM2LONG(argv[1]);
     }
-    width -= n;
+    string_t *searched = str_need_string(rb_searched);
 
-    if (jflag == 'c') {
-	rb_str_justify0(str, pad, ceil(width / 2.0), padwidth, n);
-	rb_str_justify0(str, pad, floor(width / 2.0), padwidth, 0);
+    long index = str_index_for_string(STR(self), searched, start_index, true);
+    if (index == -1) {
+	return Qnil;
     }
-    else if (jflag == 'l') {
-	rb_str_justify0(str, pad, width, padwidth, n);
-    }
-    else if (jflag == 'r') {
-	rb_str_justify0(str, pad, width, padwidth, 0);
-    }
     else {
-	rb_bug("invalid jflag");
+	return INT2NUM(index);
     }
-
-    if (OBJ_TAINTED(pad)) {
-	OBJ_TAINT(str);
-    }
-
-    return str;
 }
 
 
-/*
- *  call-seq:
- *     str.ljust(integer, padstr=' ')   => new_str
- *  
- *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new
- *  <code>String</code> of length <i>integer</i> with <i>str</i> left justified
- *  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
- *     
- *     "hello".ljust(4)            #=> "hello"
- *     "hello".ljust(20)           #=> "hello               "
- *     "hello".ljust(20, '1234')   #=> "hello123412341234123"
- */
-
 static VALUE
-rb_str_ljust(VALUE str, SEL sel, int argc, VALUE *argv)
+mr_str_getchar(VALUE self, SEL sel, VALUE index)
 {
-    return rb_str_justify(argc, argv, str, 'l');
-}
-
-
-/*
- *  call-seq:
- *     str.rjust(integer, padstr=' ')   => new_str
- *  
- *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new
- *  <code>String</code> of length <i>integer</i> with <i>str</i> right justified
- *  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
- *     
- *     "hello".rjust(4)            #=> "hello"
- *     "hello".rjust(20)           #=> "               hello"
- *     "hello".rjust(20, '1234')   #=> "123412341234123hello"
- */
-
-static VALUE
-rb_str_rjust(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    return rb_str_justify(argc, argv, str, 'r');
-}
-
-
-/*
- *  call-seq:
- *     str.center(integer, padstr)   => new_str
- *  
- *  If <i>integer</i> is greater than the length of <i>str</i>, returns a new
- *  <code>String</code> of length <i>integer</i> with <i>str</i> centered and
- *  padded with <i>padstr</i>; otherwise, returns <i>str</i>.
- *     
- *     "hello".center(4)         #=> "hello"
- *     "hello".center(20)        #=> "       hello        "
- *     "hello".center(20, '123') #=> "1231231hello12312312"
- */
-
-static VALUE
-rb_str_center(VALUE str, SEL sel, int argc, VALUE *argv)
-{
-    return rb_str_justify(argc, argv, str, 'c');
-}
-
-/*
- *  call-seq:
- *     str.partition(sep)              => [head, sep, tail]
- *  
- *  Searches the string for <i>sep</i> and returns the part before
- *  it, the <i>sep</i>, and the part after it.  If <i>sep</i> is not found,
- *  returns <i>str</i> and two empty strings.
- *     
- *     "hello".partition("l")         #=> ["he", "l", "lo"]
- *     "hello".partition("x")         #=> ["hello", "", ""]
- */
-
-static VALUE
-rb_str_partition(VALUE str, SEL sel, VALUE sep)
-{
-    long pos;
-    int regex = Qfalse;
-    long strlen, seplen = 0;
-
-    if (TYPE(sep) == T_REGEXP) {
-	pos = rb_reg_search(sep, str, 0, 0);
-	regex = Qtrue;
+    string_t *ret = str_get_character_at(STR(self), FIX2LONG(index), false);
+    if (ret == NULL) {
+	return Qnil;
     }
     else {
-	StringValue(sep);
-	pos = rb_str_index(str, sep, 0);
-	seplen = CFStringGetLength((CFStringRef)sep);
+	return (VALUE)ret;
     }
-    if (pos < 0) {
-      failed:
-	return rb_ary_new3(3, str, rb_str_new(0,0),rb_str_new(0,0));
-    }
-    if (regex) {
-	sep = rb_str_subpat(str, sep, 0);
-	seplen = CFStringGetLength((CFStringRef)sep);
-	if (pos == 0 && seplen == 0) goto failed;
-    }
-    strlen = CFStringGetLength((CFStringRef)str);
-    return rb_ary_new3(3, rb_str_subseq(str, 0, pos),
-		          sep,
-		          rb_str_subseq(str, pos+seplen,
-					     strlen-pos-seplen));
 }
 
-/*
- *  call-seq:
- *     str.rpartition(sep)            => [head, sep, tail]
- *  
- *  Searches <i>sep</i> in the string from the end of the string, and
- *  returns the part before it, the <i>sep</i>, and the part after it.
- *  If <i>sep</i> is not found, returns two empty strings and
- *  <i>str</i>.
- *     
- *     "hello".rpartition("l")         #=> ["hel", "l", "o"]
- *     "hello".rpartition("x")         #=> ["", "", "hello"]
- */
-
 static VALUE
-rb_str_rpartition(VALUE str, SEL sel, VALUE sep)
+mr_str_plus(VALUE self, SEL sel, VALUE to_add)
 {
-    long pos = RSTRING_LEN(str);
-    int regex = Qfalse;
-    long seplen;
-
-    if (TYPE(sep) == T_REGEXP) {
-	pos = rb_reg_search(sep, str, pos, 1);
-	regex = Qtrue;
-    }
-    else {
-	VALUE tmp;
-
-	tmp = rb_check_string_type(sep);
-	if (NIL_P(tmp)) {
-	    rb_raise(rb_eTypeError, "type mismatch: %s given",
-		     rb_obj_classname(sep));
-	}
-	pos = rb_str_sublen(str, pos);
-	pos = rb_str_rindex(str, sep, pos);
-    }
-    if (pos < 0) {
-	return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str);
-    }
-    if (regex) {
-	sep = rb_reg_nth_match(0, rb_backref_get());
-	if (sep == Qnil)
-	    return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str);
-    }
-    seplen = RSTRING_LEN(sep);
-    return rb_ary_new3(3, rb_str_substr(str, 0, pos),
-		          sep,
-		          rb_str_substr(str, pos + seplen, seplen));
+    return (VALUE)str_plus_string(STR(self), str_need_string(to_add));
 }
 
-/*
- *  call-seq:
- *     str.start_with?([prefix]+)   => true or false
- *  
- *  Returns true if <i>str</i> starts with the prefix given.
- */
-
 static VALUE
-rb_str_start_with(VALUE str, SEL sel, int argc, VALUE *argv)
+mr_str_concat(VALUE self, SEL sel, VALUE to_concat)
 {
-    int i;
+    switch (TYPE(to_concat)) {
+	case T_FIXNUM:
+	case T_BIGNUM:
+	    abort(); // TODO
 
-    for (i = 0; i < argc; i++) {
-	VALUE tmp = rb_check_string_type(argv[i]);
-	if (NIL_P(tmp)) {
-	    continue;
-	}
-	if (CFStringHasPrefix((CFStringRef)str, (CFStringRef)tmp)) {
-	    return Qtrue;
-	}
+	default:
+	    str_concat_string(STR(self), str_need_string(to_concat));
     }
-    return Qfalse;
+    return self;
 }
 
-/*
- *  call-seq:
- *     str.end_with?([suffix]+)   => true or false
- *  
- *  Returns true if <i>str</i> ends with the suffix given.
- */
-
 static VALUE
-rb_str_end_with(VALUE str, SEL sel, int argc, VALUE *argv)
+mr_str_equal(VALUE self, SEL sel, VALUE compared_to)
 {
-    int i;
+    if (SPECIAL_CONST_P(compared_to)) {
+	return Qfalse;
+    }
 
-    for (i = 0; i < argc; i++) {
-	VALUE tmp = rb_check_string_type(argv[i]);
-	if (NIL_P(tmp)) {
-	    continue;
+    if (TYPE(compared_to) == T_STRING) {
+	string_t *str;
+	if (OBJC_CLASS(compared_to) == rb_cMRString) {
+	    str = STR(compared_to);
 	}
-	if (CFStringHasSuffix((CFStringRef)str, (CFStringRef)tmp)) {
-	    return Qtrue;
+	else {
+	    str = str_new_from_cfstring((CFStringRef)compared_to);
 	}
+	return str_is_equal_to_string(STR(self), str) ? Qtrue : Qfalse;
     }
-    return Qfalse;
-}
-
-void
-rb_str_setter(VALUE val, ID id, VALUE *var)
-{
-    if (!NIL_P(val) && TYPE(val) != T_STRING) {
-	rb_raise(rb_eTypeError, "value of %s must be String", rb_id2name(id));
-    }
-    *var = val;
-}
-
-
-/*
- *  call-seq:
- *     str.force_encoding(encoding)   => str
- *
- *  Changes the encoding to +encoding+ and returns self.
- */
-
-static VALUE
-rb_str_force_encoding(VALUE str, SEL sel, VALUE enc)
-{
-    // TODO
-    str_modifiable(str);
-    return str;
-}
-
-/*
- *  call-seq:
- *     str.valid_encoding?  => true or false
- *  
- *  Returns true for a string which encoded correctly.
- *
- *    "\xc2\xa1".force_encoding("UTF-8").valid_encoding? => true
- *    "\xc2".force_encoding("UTF-8").valid_encoding? => false
- *    "\x80".force_encoding("UTF-8").valid_encoding? => false
- */
-
-static VALUE
-rb_str_valid_encoding_p(VALUE str, SEL sel)
-{
-    return *(VALUE *)str == rb_cByteString ? Qfalse : Qtrue;
-}
-
-/*
- *  call-seq:
- *     str.ascii_only?  => true or false
- *  
- *  Returns true for a string which has only ASCII characters.
- *
- *    "abc".force_encoding("UTF-8").ascii_only? => true
- *    "abc\u{6666}".force_encoding("UTF-8").ascii_only? => false
- */
-
-static VALUE
-rb_str_is_ascii_only_p(VALUE str, SEL sel)
-{
-	CFCharacterSetRef ascii = CFCharacterSetCreateWithCharactersInRange(NULL, CFRangeMake(0, 128));
-	CFCharacterSetRef this = CFCharacterSetCreateWithCharactersInString(NULL, (CFStringRef)str);
-	Boolean b = CFCharacterSetIsSupersetOfSet(ascii, this);
-	CFRelease(ascii); CFRelease(this);
-	return (b ? Qtrue : Qfalse);
-}
-
-static VALUE
-rb_str_transform_bang(VALUE str, SEL sel, VALUE transform_name)
-{
-    CFRange range;
-
-    rb_str_modify(str);
-    StringValue(transform_name);
-    
-    range = CFRangeMake(0, RSTRING_LEN(str));
-
-    if (!CFStringTransform((CFMutableStringRef)str, 
-		&range,
-		(CFStringRef)transform_name,
-		false)) {
-	rb_raise(rb_eRuntimeError, "cannot apply transformation `%s' to `%s'",
-		RSTRING_PTR(transform_name), RSTRING_PTR(str));
-    }
-
-    return range.length == kCFNotFound ? Qnil : str;
-}
-
-static VALUE
-rb_str_transform(VALUE str, SEL sel, VALUE transform_name)
-{
-    str = rb_str_dup(str);
-    rb_str_transform_bang(str, 0, transform_name);
-    return str;
-}
-
-/**********************************************************************
- * Document-class: Symbol
- *
- *  <code>Symbol</code> objects represent names and some strings
- *  inside the Ruby
- *  interpreter. They are generated using the <code>:name</code> and
- *  <code>:"string"</code> literals
- *  syntax, and by the various <code>to_sym</code> methods. The same
- *  <code>Symbol</code> object will be created for a given name or string
- *  for the duration of a program's execution, regardless of the context
- *  or meaning of that name. Thus if <code>Fred</code> is a constant in
- *  one context, a method in another, and a class in a third, the
- *  <code>Symbol</code> <code>:Fred</code> will be the same object in
- *  all three contexts.
- *     
- *     module One
- *       class Fred
- *       end
- *       $f1 = :Fred
- *     end
- *     module Two
- *       Fred = 1
- *       $f2 = :Fred
- *     end
- *     def Fred()
- *     end
- *     $f3 = :Fred
- *     $f1.object_id   #=> 2514190
- *     $f2.object_id   #=> 2514190
- *     $f3.object_id   #=> 2514190
- *     
- */
-
-
-/*
- *  call-seq:
- *     sym == obj   => true or false
- *  
- *  Equality---If <i>sym</i> and <i>obj</i> are exactly the same
- *  symbol, returns <code>true</code>. Otherwise, compares them
- *  as strings.
- */
-
-static VALUE
-sym_equal(VALUE sym1, SEL sel, VALUE sym2)
-{
-    return sym1 == sym2 ? Qtrue : Qfalse;
-}
-
-static VALUE
-sym_cmp(VALUE sym1, SEL sel, VALUE sym2)
-{
-    int code;
-    if (CLASS_OF(sym2) != rb_cSymbol) {
-	return Qnil;
-    }
-    code = strcmp(RSYMBOL(sym1)->str, RSYMBOL(sym2)->str);
-    if (code > 0) {
-	code = 1;
-    }
-    else if (code < 0) {
-	code = -1;
-    }
-    return INT2FIX(code);
-}
-
-/*
- *  call-seq:
- *     sym.inspect    => string
- *  
- *  Returns the representation of <i>sym</i> as a symbol literal.
- *     
- *     :fred.inspect   #=> ":fred"
- */
-
-static inline bool
-sym_printable(const char *str, long len)
-{
-    // TODO multibyte symbols
-    long i;
-    for (i = 0; i < len; i++) {
-	if (!isprint(str[i])) {
-	    return false;
-	}
-    }
-    return true;
-}
-
-static VALUE
-sym_inspect(VALUE sym, SEL sel)
-{
-    const char *symstr = RSYMBOL(sym)->str;
-
-    long len = strlen(symstr);
-    if (len == 0) {
-	return rb_str_new2(":\"\"");
-    }
-
-    VALUE str = rb_str_new2(":");
-    if (!rb_symname_p(symstr) || !sym_printable(symstr, len)) {
-	rb_str_buf_cat2(str, "\"");
-	rb_str_buf_append(str, sym);
-	rb_str_buf_cat2(str, "\"");
-    }
     else {
-	rb_str_buf_append(str, sym);
+	return Qfalse;
     }
-
-    return str;
 }
 
-
-/*
- *  call-seq:
- *     sym.id2name   => string
- *     sym.to_s      => string
- *  
- *  Returns the name or string corresponding to <i>sym</i>.
- *     
- *     :fred.id2name   #=> "fred"
- */
-
-
 static VALUE
-rb_sym_to_s_imp(VALUE sym, SEL sel)
+mr_str_not_equal(VALUE self, SEL sel, VALUE compared_to)
 {
-    return rb_str_new2(RSYMBOL(sym)->str);
+    return mr_str_equal(self, sel, compared_to) == Qfalse ? Qtrue : Qfalse;
 }
 
-VALUE
-rb_sym_to_s(VALUE sym)
-{
-    return rb_sym_to_s_imp(sym, 0);
-}
-
-/*
- * call-seq:
- *   sym.to_sym   => sym
- *   sym.intern   => sym
- *
- * In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding
- * to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned
- * in this case.
- */
-
 static VALUE
-sym_to_sym(VALUE sym, SEL sel)
+mr_str_include(VALUE self, SEL sel, VALUE searched)
 {
-    return sym;
+    return str_include_string(STR(self), str_need_string(searched)) ? Qtrue : Qfalse;
 }
 
-/*
- * call-seq:
- *   sym.to_proc
- *
- * Returns a _Proc_ object which respond to the given method by _sym_.
- *
- *   (1..3).collect(&:to_s)  #=> ["1", "2", "3"]
- */
-
 static VALUE
-sym_to_proc(VALUE sym, SEL sel)
+mr_str_is_stored_in_uchars(VALUE self, SEL sel)
 {
-    SEL msel = sel_registerName(rb_id2name(SYM2ID(sym)));
-    rb_vm_block_t *b = rb_vm_create_block_calling_sel(msel);
-    return rb_proc_alloc_with_block(rb_cProc, b);
+    return str_is_stored_in_uchars(STR(self)) ? Qtrue : Qfalse;
 }
 
-ID
-rb_to_id(VALUE name)
-{
-    VALUE tmp;
-    ID id;
-
-    switch (TYPE(name)) {
-      default:
-	tmp = rb_check_string_type(name);
-	if (NIL_P(tmp)) {
-	    rb_raise(rb_eTypeError, "%s is not a symbol",
-		     RSTRING_PTR(rb_inspect(name)));
-	}
-	name = tmp;
-	/* fall through */
-      case T_STRING:
-	name = rb_str_intern(name, 0);
-	/* fall through */
-      case T_SYMBOL:
-	return SYM2ID(name);
-    }
-    return id;
-}
-
-#define PREPARE_RCV(x) \
-    Class old = *(Class *)x; \
-    *(Class *)x = (Class)rb_cCFString;
-
-#define RESTORE_RCV(x) \
-    *(Class *)x = old;
-
-bool
-rb_objc_str_is_pure(VALUE str)
-{
-    return *(Class *)str == (Class)rb_cCFString;
-}
-
-static CFIndex
-imp_rb_str_length(void *rcv, SEL sel)
-{
-    CFIndex length;
-    PREPARE_RCV(rcv);
-    length = CFStringGetLength((CFStringRef)rcv);
-    RESTORE_RCV(rcv);
-    return length;
-}
-
-static UniChar
-imp_rb_str_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
-{
-    UniChar character;
-    PREPARE_RCV(rcv);
-    character = CFStringGetCharacterAtIndex((CFStringRef)rcv, idx);
-    RESTORE_RCV(rcv);
-    return character;
-}
-
-static void
-imp_rb_str_getCharactersRange(void *rcv, SEL sel, UniChar *buffer, 
-			      CFRange range)
-{
-    PREPARE_RCV(rcv);
-    CFStringGetCharacters((CFStringRef)rcv, range, buffer);
-    RESTORE_RCV(rcv);
-}
-
-static void
-imp_rb_str_replaceCharactersInRangeWithString(void *rcv, SEL sel, 
-					      CFRange range, void *str)
-{
-    PREPARE_RCV(rcv);
-    CFStringReplace((CFMutableStringRef)rcv, range, (CFStringRef)str);
-    RESTORE_RCV(rcv);
-}
-
-static const UniChar *
-imp_rb_str_fastCharacterContents(void *rcv, SEL sel)
-{
-    const UniChar *ptr;
-    PREPARE_RCV(rcv);
-    ptr = CFStringGetCharactersPtr((CFStringRef)rcv);
-    RESTORE_RCV(rcv);
-    return ptr;
-}
-
-static const char *
-imp_rb_str_fastCStringContents(void *rcv, SEL sel, bool nullTerminaisonRequired)
-{
-    const char *cstr;
-    PREPARE_RCV(rcv);
-    cstr = CFStringGetCStringPtr((CFStringRef)rcv, 0);
-    /* XXX nullTerminaisonRequired should perhaps be honored */
-    RESTORE_RCV(rcv);
-    return cstr;
-}
-
-static CFStringEncoding
-imp_rb_str_fastestEncodingInCFStringEncoding(void *rcv, SEL sel)
-{
-    CFStringEncoding encoding;
-    PREPARE_RCV(rcv);
-    encoding =  CFStringGetFastestEncoding((CFStringRef)rcv);
-    RESTORE_RCV(rcv);
-    return encoding;
-}
-
-static bool
-imp_rb_str_isEqual(void *rcv, SEL sel, void *other)
-{
-    bool flag;
-    PREPARE_RCV(rcv);
-    flag = (other != NULL) && CFEqual((CFTypeRef)rcv, (CFTypeRef)other);    
-    RESTORE_RCV(rcv);
-    return flag;
-}
-
-static void *
-imp_rb_str_copy(void *rcv, SEL sel)
-{
-    void *dup;
-    PREPARE_RCV(rcv);
-    dup = (void *)objc_msgSend(rcv, selCopy);
-    RESTORE_RCV(rcv);
-    return dup;
-}
-
-static void *
-imp_rb_str_mutableCopy(void *rcv, SEL sel)
-{
-    void *dup;
-    PREPARE_RCV(rcv);
-    dup = (void *)objc_msgSend(rcv, selMutableCopy);
-    RESTORE_RCV(rcv);
-    return dup;
-}
-
-void
-rb_objc_install_string_primitives(Class klass)
-{
-    rb_objc_install_method2(klass, "length", (IMP)imp_rb_str_length);
-    rb_objc_install_method2(klass, "characterAtIndex:",
-	    (IMP)imp_rb_str_characterAtIndex);
-    rb_objc_install_method2(klass, "getCharacters:range:",
-	    (IMP)imp_rb_str_getCharactersRange);
-    rb_objc_install_method2(klass, "_fastCharacterContents",
-	    (IMP)imp_rb_str_fastCharacterContents);
-    rb_objc_install_method2(klass, "_fastCStringContents:",
-	    (IMP)imp_rb_str_fastCStringContents);
-    rb_objc_install_method2(klass, "_fastestEncodingInCFStringEncoding",
-	(IMP)imp_rb_str_fastestEncodingInCFStringEncoding);
-    rb_objc_install_method2(klass, "isEqual:", (IMP)imp_rb_str_isEqual);
-    rb_objc_install_method2(klass, "copy", (IMP)imp_rb_str_copy);
-    rb_objc_install_method2(klass, "mutableCopy", (IMP)imp_rb_str_mutableCopy);
-
-    const bool mutable = class_getSuperclass(klass)
-	== (Class)rb_cNSMutableString;
-
-    if (mutable) {
-	rb_objc_install_method2(klass, "replaceCharactersInRange:withString:", 
-		(IMP)imp_rb_str_replaceCharactersInRangeWithString);
-    }
-
-    rb_objc_define_method(*(VALUE *)klass, "alloc", str_alloc, 0);
-}
-
-static CFIndex
-imp_rb_symbol_length(void *rcv, SEL sel)
-{
-    return RSYMBOL(rcv)->len;
-}
-
-static UniChar
-imp_rb_symbol_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
-{
-    if (idx < 0 || idx > RSYMBOL(rcv)->len) {
-	rb_bug("[Symbol characterAtIndex:] out of bounds");
-    }
-    return RSYMBOL(rcv)->str[idx];
-}
-
-static void
-imp_rb_symbol_getCharactersRange(void *rcv, SEL sel, UniChar *buffer, 
-	CFRange range)
-{
-    if (range.location + range.length > RSYMBOL(rcv)->len) {
-	rb_bug("[Symbol getCharacters:range:] out of bounds");
-    }
-
-    for (int i = range.location; i < range.location + range.length; i++) {
-	*buffer = RSYMBOL(rcv)->str[i];
-	buffer++;
-    }
-}
-
-static bool
-imp_rb_symbol_isEqual(void *rcv, SEL sel, void *other)
-{
-    if (rcv == other) {
-	return true;
-    }
-    if (other == NULL || *(VALUE *)other != rb_cSymbol) {
-	return false;
-    }
-    if (RSYMBOL(rcv)->len != RSYMBOL(other)->len) {
-	return false;
-    }
-    return strcmp(RSYMBOL(rcv)->str, RSYMBOL(other)->str) == 0;
-}
-
-static void *
-imp_rb_symbol_mutableCopy(void *rcv, SEL sel)
-{
-    CFMutableStringRef new_str = CFStringCreateMutable(NULL, 0);
-    CFStringAppendCString(new_str, RSYMBOL(rcv)->str, kCFStringEncodingUTF8);
-    CFMakeCollectable(new_str);
-    return new_str;
-}
-
-static void
-install_symbol_primitives(void)
-{
-    Class klass = (Class)rb_cSymbol;
-
-    rb_objc_install_method2(klass, "length", (IMP)imp_rb_symbol_length);
-    rb_objc_install_method2(klass, "characterAtIndex:", (IMP)imp_rb_symbol_characterAtIndex);
-    rb_objc_install_method2(klass, "getCharacters:range:", (IMP)imp_rb_symbol_getCharactersRange);
-    rb_objc_install_method2(klass, "isEqual:", (IMP)imp_rb_symbol_isEqual);
-    rb_objc_install_method2(klass, "mutableCopy", (IMP)imp_rb_symbol_mutableCopy);
-}
-
-#undef INSTALL_METHOD
-
-CFMutableDataRef 
-rb_bytestring_wrapped_data(VALUE bstr)
-{
-    return ((rb_bstr_t *)bstr)->data;
-}
-
-void
-rb_bytestring_set_wrapped_data(VALUE bstr, CFMutableDataRef data)
-{
-    GC_WB(&((rb_bstr_t *)bstr)->data, data);
-}
-
-UInt8 *
-rb_bytestring_byte_pointer(VALUE bstr)
-{
-    return CFDataGetMutableBytePtr(rb_bytestring_wrapped_data(bstr));
-}
-
-static inline VALUE
-bytestring_alloc(void)
-{
-    NEWOBJ(bstr, rb_bstr_t);
-    bstr->basic.flags = 0;
-    bstr->basic.klass = rb_cByteString;
-    bstr->data = NULL;
-    return (VALUE)bstr;
-}
-
 static VALUE
-rb_bytestring_alloc(VALUE klass, SEL sel)
+mr_str_to_s(VALUE self, SEL sel)
 {
-    VALUE bstr = bytestring_alloc();
-
-    CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
-    rb_bytestring_set_wrapped_data(bstr, data);
-    CFMakeCollectable(data);
-
-    return bstr;
-}
-
-VALUE 
-rb_bytestring_new() 
-{
-    return rb_bytestring_alloc(0, 0);
-}
-
-VALUE
-rb_bytestring_new_with_data(const UInt8 *buf, long size)
-{
-    VALUE v = rb_bytestring_new();
-    CFDataAppendBytes(rb_bytestring_wrapped_data(v), buf, size);
-    return v;
-}
-
-VALUE
-rb_bytestring_new_with_cfdata(CFMutableDataRef data)
-{
-    VALUE v = bytestring_alloc();
-    rb_bytestring_set_wrapped_data(v, data);
-    return v;
-}
-
-static VALUE
-bytestring_from_data(VALUE klass, SEL sel, VALUE data)
-{
-    return rb_bytestring_new_with_cfdata((CFMutableDataRef)data);
-}
-
-static void inline
-rb_bytestring_copy_cfstring_content(VALUE bstr, CFStringRef str)
-{
-    if (CFStringGetLength(str) != 0) {
-        const char *cptr = RSTRING_PTR((VALUE)str);
-	assert(cptr != NULL); // TODO handle UTF-16 strings
-
-	CFDataAppendBytes(rb_bytestring_wrapped_data(bstr), (UInt8 *)cptr, 
-		CFStringGetLength(str));
+    if (OBJC_CLASS(self) != rb_cMRString) {
+	return (VALUE)str_dup(self);
     }
+    return self;
 }
 
-static VALUE
-rb_bytestring_initialize(VALUE recv, SEL sel, int argc, VALUE *argv)
-{
-    VALUE orig;
-
-    rb_scan_args(argc, argv, "01", &orig);
-
-    if (!NIL_P(orig)) {
-	StringValue(orig);
-	rb_bytestring_copy_cfstring_content(recv, (CFStringRef)orig);
-    }
-    return orig;
-}
-
-VALUE
-rb_coerce_to_bytestring(VALUE str)
-{
-    VALUE new = rb_bytestring_alloc(0, 0);
-    rb_bytestring_copy_cfstring_content(new, (CFStringRef)str);
-    return new;
-}
-
-inline long 
-rb_bytestring_length(VALUE str)
-{
-    return CFDataGetLength(rb_bytestring_wrapped_data(str));
-}
-
 void
-rb_bytestring_resize(VALUE str, long newsize)
+Init_MRString(void)
 {
-    CFDataSetLength(rb_bytestring_wrapped_data(str), newsize);
-}
+    // encodings must be loaded before strings
+    assert(rb_cMREncoding != 0);
 
-void
-rb_bytestring_append_bytes(VALUE str, const UInt8* bytes, long len)
-{
-    CFDataAppendBytes(rb_bytestring_wrapped_data(str), bytes, len);
-}
+    rb_cMRString = rb_define_class("MRString", rb_cObject);
+    rb_objc_define_method(OBJC_CLASS(rb_cMRString), "alloc", mr_str_s_alloc, 0);
 
-CFStringRef
-rb_bytestring_resolve_cfstring(VALUE str)
-{
-    CFDataRef data = rb_bytestring_wrapped_data(str);
-    CFStringRef cfstr = CFStringCreateFromExternalRepresentation(NULL,
-	data, kCFStringEncodingUTF8);
-    if (cfstr == NULL) {
-	// If UTF8 doesn't work, try ASCII.
-	cfstr = CFStringCreateFromExternalRepresentation(NULL,
-		data, kCFStringEncodingASCII);
-    }
-    if (cfstr != NULL) {
-	return CFMakeCollectable(cfstr);
-    }
-    return (CFStringRef)str;
-}
+    rb_objc_define_method(rb_cMRString, "initialize", mr_str_initialize, -1);
+    rb_objc_define_method(rb_cMRString, "initialize_copy", mr_str_replace, 1);
+    rb_objc_define_method(rb_cMRString, "replace", mr_str_replace, 1);
+    rb_objc_define_method(rb_cMRString, "clear", mr_str_clear, 0);
+    rb_objc_define_method(rb_cMRString, "encoding", mr_str_encoding, 0);
+    rb_objc_define_method(rb_cMRString, "length", mr_str_length, 0);
+    rb_objc_define_method(rb_cMRString, "size", mr_str_length, 0); // alias
+    rb_objc_define_method(rb_cMRString, "bytesize", mr_str_bytesize, 0);
+    rb_objc_define_method(rb_cMRString, "getbyte", mr_str_getbyte, 1);
+    rb_objc_define_method(rb_cMRString, "setbyte", mr_str_setbyte, 2);
+    rb_objc_define_method(rb_cMRString, "force_encoding", mr_str_force_encoding, 1);
+    rb_objc_define_method(rb_cMRString, "valid_encoding?", mr_str_is_valid_encoding, 0);
+    rb_objc_define_method(rb_cMRString, "ascii_only?", mr_str_is_ascii_only, 0);
+    rb_objc_define_method(rb_cMRString, "[]", mr_str_aref, -1);
+    rb_objc_define_method(rb_cMRString, "index", mr_str_index, -1);
+    rb_objc_define_method(rb_cMRString, "+", mr_str_plus, 1);
+    rb_objc_define_method(rb_cMRString, "<<", mr_str_concat, 1);
+    rb_objc_define_method(rb_cMRString, "concat", mr_str_concat, 1);
+    rb_objc_define_method(rb_cMRString, "==", mr_str_equal, 1);
+    rb_objc_define_method(rb_cMRString, "!=", mr_str_not_equal, 1);
+    rb_objc_define_method(rb_cMRString, "include?", mr_str_include, 1);
+    rb_objc_define_method(rb_cMRString, "to_s", mr_str_to_s, 0);
+    rb_objc_define_method(rb_cMRString, "to_str", mr_str_to_s, 0);
 
-static bool
-imp_rb_bytestring_isEqual(void *rcv, SEL sel, void *other)
-{
-    if (rcv == other) {
-	return true;
-    }
-    if (*(VALUE *)other == rb_cByteString) {
-	// Both operands are bytestrings.
-	CFDataRef rcv_data = rb_bytestring_wrapped_data((VALUE)rcv);
-	CFDataRef other_data = rb_bytestring_wrapped_data((VALUE)other);
-	if (CFDataGetLength(rcv_data) != CFDataGetLength(other_data)) {
-	    return false;
-	}
-	return CFEqual(rcv_data, other_data);
-    }
-    else {
-	// Given operand is a character string.
-	CFStringRef rcv_str = rb_bytestring_resolve_cfstring((VALUE)rcv);
-	if (rcv_str == (CFStringRef)rcv) {
-	    // Can't resolve a character string based on that data.
-	    return false;
-	}
-	return CFEqual(rcv_str, (CFTypeRef)other);
-    }
-}
+    // added for MacRuby
+    rb_objc_define_method(rb_cMRString, "chars_count", mr_str_chars_count, 0);
+    rb_objc_define_method(rb_cMRString, "getchar", mr_str_getchar, 1);
 
-static CFIndex
-imp_rb_bytestring_length(void *rcv, SEL sel) 
-{
-    return rb_bytestring_length((VALUE)rcv);
+    // this method does not exist in Ruby and is there only for debugging purpose
+    rb_objc_define_method(rb_cMRString, "stored_in_uchars?", mr_str_is_stored_in_uchars, 0);
 }
 
-static inline long
-bytestring_index(VALUE bstr, VALUE idx)
-{
-    long index = NUM2LONG(idx);
-    while (index < 0) {
-	// adjusting for negative indices
-	index += rb_bytestring_length(bstr);
-    }
-    return index;
-}
+void Init_MREncoding(void);
 
-static VALUE
-rb_bytestring_getbyte(VALUE bstr, SEL sel, VALUE idx)
-{
-    const long index = bytestring_index(bstr, idx);
-    return INT2FIX(rb_bytestring_byte_pointer(bstr)[index]);
-}
-
-static VALUE
-rb_bytestring_setbyte(VALUE bstr, SEL sel, VALUE idx, VALUE newbyte)
-{
-    const long index = bytestring_index(bstr, idx);
-    rb_bytestring_byte_pointer(bstr)[index] = FIX2UINT(newbyte);
-    return Qnil;
-}
-
-static VALUE
-rb_bytestring_bytesize(VALUE bstr, SEL sel)
-{
-    return LONG2NUM(CFDataGetLength(rb_bytestring_wrapped_data(bstr)));
-}
-
-static UniChar
-imp_rb_bytestring_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
-{
-    // XXX should be encoding aware
-    return rb_bytestring_byte_pointer((VALUE)rcv)[idx];
-}
-
-static void
-imp_rb_bytestring_replaceCharactersInRange_withString(void *rcv, SEL sel,
-	CFRange range, void *str)
-{
-    const UInt8 *bytes = (const UInt8 *)RSTRING_PTR(str);
-    const long length = RSTRING_LEN(str);
-    CFMutableDataRef data = rb_bytestring_wrapped_data((VALUE)rcv);
-
-    // No need to check if the given range fits in the data's bounds,
-    // CFDataReplaceBytes() will grow the object automatically for us.
-    CFDataReplaceBytes(data, range, bytes, length);
-}
-
-VALUE
-rb_bytestring_copy(VALUE bstr)
-{
-    VALUE new_bstr = rb_bytestring_new();
-    CFMutableDataRef rcv_data = rb_bytestring_wrapped_data(bstr);
-    CFMutableDataRef new_data = rb_bytestring_wrapped_data(new_bstr);
-    CFDataAppendBytes(new_data, (const UInt8 *)CFDataGetMutableBytePtr(rcv_data),
-	    CFDataGetLength(rcv_data));
-    return new_bstr;
-}
-
-static void *
-imp_rb_bytestring_mutableCopy(void *rcv, SEL sel)
-{
-    return (void *)rb_bytestring_copy((VALUE)rcv);
-}
-
-static void
-imp_rb_bytestring_cfAppendCString_length(void *rcv, SEL sel, const UInt8 *cstr,
-					 long len)
-{
-    CFDataAppendBytes(rb_bytestring_wrapped_data((VALUE)rcv), cstr, len);
-}
-
-static void
-imp_rb_bytestring_setString(void *rcv, SEL sel, void *new_str)
-{
-    CFMutableDataRef data = rb_bytestring_wrapped_data((VALUE)rcv);
-    CFRange data_range = CFRangeMake(0, CFDataGetLength(data));
-    const char *cstr = RSTRING_PTR(new_str);
-    const long len = RSTRING_LEN(new_str);
-    CFDataReplaceBytes(data, data_range, (const UInt8 *)cstr, len);
-} 
-
-/*
- *  A <code>String</code> object holds and manipulates an arbitrary sequence of
- *  bytes, typically representing characters. String objects may be created
- *  using <code>String::new</code> or as literals.
- *     
- *  Because of aliasing issues, users of strings should be aware of the methods
- *  that modify the contents of a <code>String</code> object.  Typically,
- *  methods with names ending in ``!'' modify their receiver, while those
- *  without a ``!'' return a new <code>String</code>.  However, there are
- *  exceptions, such as <code>String#[]=</code>.
- *     
- */
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
-# define NSCFSTRING_CNAME "NSCFString"
-#else
-# define NSCFSTRING_CNAME "__NSCFString"
-#endif
-
 void
-Init_String(void)
+Init_new_string(void)
 {
-    rb_cCFString = (VALUE)objc_getClass(NSCFSTRING_CNAME);
-    assert(rb_cCFString != 0);
-    rb_const_set(rb_cObject, rb_intern("NSCFString"), rb_cCFString);
-    rb_cString = rb_cNSString = (VALUE)objc_getClass("NSString");
-    rb_cNSMutableString = (VALUE)objc_getClass("NSMutableString");
-    rb_const_set(rb_cObject, rb_intern("String"), rb_cNSMutableString);
-    rb_set_class_path(rb_cNSMutableString, rb_cObject, "NSMutableString");
-
-    rb_include_module(rb_cString, rb_mComparable);
-
-    rb_objc_define_method(*(VALUE *)rb_cString, "try_convert", rb_str_s_try_convert, 1);
-    rb_objc_define_method(rb_cString, "initialize", rb_str_init, -1);
-    rb_objc_define_method(rb_cString, "initialize_copy", rb_str_replace_imp, 1);
-    rb_objc_define_method(rb_cString, "<=>", rb_str_cmp_m, 1);
-    rb_objc_define_method(rb_cString, "==", rb_str_equal_imp, 1);
-    rb_objc_define_method(rb_cString, "eql?", rb_str_eql, 1);
-    rb_objc_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
-    rb_objc_define_method(rb_cString, "+", rb_str_plus_imp, 1);
-    rb_objc_define_method(rb_cString, "*", rb_str_times, 1);
-    rb_objc_define_method(rb_cString, "%", rb_str_format_m, 1);
-    rb_objc_define_method(rb_cString, "[]", rb_str_aref_m, -1);
-    rb_objc_define_method(rb_cString, "[]=", rb_str_aset_m, -1);
-    rb_objc_define_method(rb_cString, "insert", rb_str_insert, 2);
-    rb_objc_define_method(rb_cString, "size", rb_str_length_imp, 0);
-    rb_objc_define_method(rb_cString, "bytesize", rb_str_bytesize, 0);
-    rb_objc_define_method(rb_cString, "empty?", rb_str_empty, 0);
-    rb_objc_define_method(rb_cString, "=~", rb_str_match, 1);
-    rb_objc_define_method(rb_cString, "match", rb_str_match_m, -1);
-    rb_objc_define_method(rb_cString, "succ", rb_str_succ, 0);
-    rb_objc_define_method(rb_cString, "succ!", rb_str_succ_bang, 0);
-    rb_objc_define_method(rb_cString, "next", rb_str_succ, 0);
-    rb_objc_define_method(rb_cString, "next!", rb_str_succ_bang, 0);
-    rb_objc_define_method(rb_cString, "upto", rb_str_upto, -1);
-    rb_objc_define_method(rb_cString, "index", rb_str_index_m, -1);
-    rb_objc_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
-    rb_objc_define_method(rb_cString, "replace", rb_str_replace_imp, 1);
-    rb_objc_define_method(rb_cString, "clear", rb_str_clear, 0);
-    rb_objc_define_method(rb_cString, "chr", rb_str_chr, 0);
-    rb_objc_define_method(rb_cString, "getbyte", rb_str_getbyte, 1);
-    rb_objc_define_method(rb_cString, "setbyte", rb_str_setbyte, 2);
-
-    rb_objc_define_method(rb_cString, "to_i", rb_str_to_i, -1);
-    rb_objc_define_method(rb_cString, "to_f", rb_str_to_f, 0);
-    rb_objc_define_method(rb_cString, "to_s", rb_str_to_s, 0);
-    rb_objc_define_method(rb_cString, "to_str", rb_str_to_s, 0);
-    rb_objc_define_method(rb_cString, "inspect", rb_str_inspect, 0);
-    rb_objc_define_method(rb_cString, "dump", rb_str_dump, 0);
-
-    rb_objc_define_method(rb_cString, "upcase", rb_str_upcase, 0);
-    rb_objc_define_method(rb_cString, "downcase", rb_str_downcase, 0);
-    rb_objc_define_method(rb_cString, "capitalize", rb_str_capitalize, 0);
-    rb_objc_define_method(rb_cString, "swapcase", rb_str_swapcase, 0);
-
-    rb_objc_define_method(rb_cString, "upcase!", rb_str_upcase_bang, 0);
-    rb_objc_define_method(rb_cString, "downcase!", rb_str_downcase_bang, 0);
-    rb_objc_define_method(rb_cString, "capitalize!", rb_str_capitalize_bang, 0);
-    rb_objc_define_method(rb_cString, "swapcase!", rb_str_swapcase_bang, 0);
-
-    rb_objc_define_method(rb_cString, "hex", rb_str_hex, 0);
-    rb_objc_define_method(rb_cString, "oct", rb_str_oct, 0);
-    rb_objc_define_method(rb_cString, "split", rb_str_split_m, -1);
-    rb_objc_define_method(rb_cString, "lines", rb_str_each_line, -1);
-    rb_objc_define_method(rb_cString, "bytes", rb_str_each_byte, 0);
-    rb_objc_define_method(rb_cString, "chars", rb_str_each_char, 0);
-    rb_objc_define_method(rb_cString, "reverse", rb_str_reverse, 0);
-    rb_objc_define_method(rb_cString, "reverse!", rb_str_reverse_bang, 0);
-    rb_objc_define_method(rb_cString, "concat", rb_str_concat_imp, 1);
-    rb_objc_define_method(rb_cString, "<<", rb_str_concat_imp, 1);
-    rb_objc_define_method(rb_cString, "crypt", rb_str_crypt, 1);
-    rb_objc_define_method(rb_cString, "intern", rb_str_intern, 0);
-    rb_objc_define_method(rb_cString, "to_sym", rb_str_intern, 0);
-    rb_objc_define_method(rb_cString, "ord", rb_str_ord, 0);
-
-    rb_objc_define_method(rb_cString, "include?", rb_str_include, 1);
-    rb_objc_define_method(rb_cString, "start_with?", rb_str_start_with, -1);
-    rb_objc_define_method(rb_cString, "end_with?", rb_str_end_with, -1);
-
-    rb_objc_define_method(rb_cString, "scan", rb_str_scan, 1);
-
-    rb_objc_define_method(rb_cString, "ljust", rb_str_ljust, -1);
-    rb_objc_define_method(rb_cString, "rjust", rb_str_rjust, -1);
-    rb_objc_define_method(rb_cString, "center", rb_str_center, -1);
-
-    rb_objc_define_method(rb_cString, "sub", rb_str_sub, -1);
-    rb_objc_define_method(rb_cString, "gsub", rb_str_gsub, -1);
-    rb_objc_define_method(rb_cString, "chop", rb_str_chop, 0);
-    rb_objc_define_method(rb_cString, "chomp", rb_str_chomp, -1);
-    rb_objc_define_method(rb_cString, "strip", rb_str_strip, 0);
-    rb_objc_define_method(rb_cString, "lstrip", rb_str_lstrip, 0);
-    rb_objc_define_method(rb_cString, "rstrip", rb_str_rstrip, 0);
-
-    rb_objc_define_method(rb_cString, "sub!", rb_str_sub_bang, -1);
-    rb_objc_define_method(rb_cString, "gsub!", rb_str_gsub_bang, -1);
-    rb_objc_define_method(rb_cString, "chop!", rb_str_chop_bang, 0);
-    rb_objc_define_method(rb_cString, "chomp!", rb_str_chomp_bang, -1);
-    rb_objc_define_method(rb_cString, "strip!", rb_str_strip_bang, 0);
-    rb_objc_define_method(rb_cString, "lstrip!", rb_str_lstrip_bang, 0);
-    rb_objc_define_method(rb_cString, "rstrip!", rb_str_rstrip_bang, 0);
-
-    rb_objc_define_method(rb_cString, "tr", rb_str_tr, 2);
-    rb_objc_define_method(rb_cString, "tr_s", rb_str_tr_s, 2);
-    rb_objc_define_method(rb_cString, "delete", rb_str_delete, -1);
-    rb_objc_define_method(rb_cString, "squeeze", rb_str_squeeze, -1);
-    rb_objc_define_method(rb_cString, "count", rb_str_count, -1);
-
-    rb_objc_define_method(rb_cString, "tr!", rb_str_tr_bang, 2);
-    rb_objc_define_method(rb_cString, "tr_s!", rb_str_tr_s_bang, 2);
-    rb_objc_define_method(rb_cString, "delete!", rb_str_delete_bang, -1);
-    rb_objc_define_method(rb_cString, "squeeze!", rb_str_squeeze_bang, -1);
-
-    rb_objc_define_method(rb_cString, "each_line", rb_str_each_line, -1);
-    rb_objc_define_method(rb_cString, "each_byte", rb_str_each_byte, 0);
-    rb_objc_define_method(rb_cString, "each_char", rb_str_each_char, 0);
-
-    rb_objc_define_method(rb_cString, "sum", rb_str_sum, -1);
-
-    rb_objc_define_method(rb_cString, "slice", rb_str_aref_m, -1);
-    rb_objc_define_method(rb_cString, "slice!", rb_str_slice_bang, -1);
-
-    rb_objc_define_method(rb_cString, "partition", rb_str_partition, 1);
-    rb_objc_define_method(rb_cString, "rpartition", rb_str_rpartition, 1);
-
-    rb_objc_define_method(rb_cString, "encoding", rb_obj_encoding, 0); /* in encoding.c */
-    rb_objc_define_method(rb_cString, "force_encoding", rb_str_force_encoding, 1);
-    rb_objc_define_method(rb_cString, "valid_encoding?", rb_str_valid_encoding_p, 0);
-    rb_objc_define_method(rb_cString, "ascii_only?", rb_str_is_ascii_only_p, 0);
-
-    rb_objc_define_method(rb_cString, "transform", rb_str_transform, 1);
-    rb_objc_define_method(rb_cString, "transform!", rb_str_transform_bang, 1);
-
-    /* to return mutable copies */
-    rb_objc_define_method(rb_cString, "dup", rb_str_dup_imp, 0);
-    rb_objc_define_method(rb_cString, "clone", rb_str_clone, 0);
-
-    id_to_s = rb_intern("to_s");
-
-    rb_fs = Qnil;
-    rb_define_variable("$;", &rb_fs);
-    rb_define_variable("$-F", &rb_fs);
-
-    /* rb_cSymbol is defined in parse.y because it's needed early */
-    rb_set_class_path(rb_cSymbol, rb_cObject, "Symbol");
-    rb_const_set(rb_cObject, rb_intern("Symbol"), rb_cSymbol);
-
-    rb_undef_alloc_func(rb_cSymbol);
-    rb_undef_method(CLASS_OF(rb_cSymbol), "new");
-    rb_objc_define_method(*(VALUE *)rb_cSymbol, "all_symbols", rb_sym_all_symbols, 0); /* in parse.y */
-
-    rb_objc_define_method(rb_cSymbol, "==", sym_equal, 1);
-    rb_objc_define_method(rb_cSymbol, "eql?", sym_equal, 1);
-    rb_objc_define_method(rb_cSymbol, "<=>", sym_cmp, 1);
-    rb_objc_define_method(rb_cSymbol, "inspect", sym_inspect, 0);
-    rb_objc_define_method(rb_cSymbol, "dup", rb_obj_dup, 0);
-    rb_objc_define_method(rb_cSymbol, "to_proc", sym_to_proc, 0);
-    rb_objc_define_method(rb_cSymbol, "to_s", rb_sym_to_s_imp, 0);
-    rb_objc_define_method(rb_cSymbol, "id2name", rb_sym_to_s_imp, 0);
-    rb_objc_define_method(rb_cSymbol, "description", rb_sym_to_s_imp, 0);
-    rb_objc_define_method(rb_cSymbol, "intern", sym_to_sym, 0);
-    rb_objc_define_method(rb_cSymbol, "to_sym", sym_to_sym, 0);
- 
-    rb_undef_method(rb_cSymbol, "to_str");
-    rb_undef_method(rb_cSymbol, "include?");
-
-    install_symbol_primitives();
-
-    rb_cByteString = rb_define_class("ByteString", rb_cNSMutableString);
-    RCLASS_SET_VERSION_FLAG(rb_cByteString, RCLASS_IS_STRING_SUBCLASS);
-
-    rb_objc_define_method(*(VALUE *)rb_cString, "__new_bytestring__",
-	    bytestring_from_data, 1);
-
-    rb_objc_install_method2((Class)rb_cByteString, "isEqual:",
-	    (IMP)imp_rb_bytestring_isEqual);
-    rb_objc_install_method2((Class)rb_cByteString, "length",
-	    (IMP)imp_rb_bytestring_length);
-    rb_objc_install_method2((Class)rb_cByteString, "characterAtIndex:",
-	    (IMP)imp_rb_bytestring_characterAtIndex);
-    rb_objc_install_method2((Class)rb_cByteString,
-	    "replaceCharactersInRange:withString:",
-	    (IMP)imp_rb_bytestring_replaceCharactersInRange_withString);
-    rb_objc_install_method2((Class)rb_cByteString, "mutableCopy",
-	    (IMP)imp_rb_bytestring_mutableCopy);
-    rb_objc_install_method2((Class)rb_cByteString, "_cfAppendCString:length:",
-	    (IMP)imp_rb_bytestring_cfAppendCString_length);
-    rb_objc_install_method2((Class)rb_cByteString, "setString:",
-	    (IMP)imp_rb_bytestring_setString);
-    rb_objc_define_method(rb_cByteString, "initialize",
-	    rb_bytestring_initialize, -1);
-    rb_objc_define_method(*(VALUE *)rb_cByteString, "alloc",
-	    rb_bytestring_alloc, 0);
-    rb_objc_define_method(rb_cByteString, "bytesize",
-	    rb_bytestring_bytesize, 0);
-    rb_objc_define_method(rb_cByteString, "getbyte", rb_bytestring_getbyte, 1);
-    rb_objc_define_method(rb_cByteString, "setbyte", rb_bytestring_setbyte, 2);
+    Init_MREncoding();
+    Init_MRString();
 }

Added: MacRuby/branches/icu/ucnv.c
===================================================================
--- MacRuby/branches/icu/ucnv.c	                        (rev 0)
+++ MacRuby/branches/icu/ucnv.c	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,410 @@
+#include "encoding.h"
+#include "unicode/ucnv.h"
+
+// do not forget to close the converter
+// before leaving the function
+#define USE_CONVERTER(cnv, str) \
+    assert(str->encoding->private_data != NULL); \
+    char cnv##_buffer[U_CNV_SAFECLONE_BUFFERSIZE]; \
+    UErrorCode cnv##_err = U_ZERO_ERROR; \
+    int32_t cnv##_buffer_size = U_CNV_SAFECLONE_BUFFERSIZE; \
+    UConverter *cnv = ucnv_safeClone( \
+	    (UConverter *)str->encoding->private_data, \
+	    cnv##_buffer, \
+	    &cnv##_buffer_size, \
+	    &cnv##_err \
+	); \
+    ucnv_reset(cnv);
+
+static void
+str_ucnv_update_flags(string_t *self)
+{
+    assert(!str_is_stored_in_uchars(self));
+
+    USE_CONVERTER(cnv, self);
+
+    bool ascii_only = true;
+    bool valid_encoding = true;
+    bool has_supplementary = false;
+
+    const char *pos = self->data.bytes;
+    const char *end = pos + self->length_in_bytes;
+    for (;;) {
+	// iterate through the string one Unicode code point at a time
+	UErrorCode err = U_ZERO_ERROR;
+	UChar32 c = ucnv_getNextUChar(cnv, &pos, end, &err);
+	if (U_FAILURE(err)) {
+	    if (err == U_INDEX_OUTOFBOUNDS_ERROR) {
+		// end of the string
+		break;
+	    }
+	    else {
+		// conversion error
+		valid_encoding = false;
+		ascii_only = false;
+	    }
+	}
+	else {
+	    if (c > 127) {
+		ascii_only = false;
+		if (U_IS_SUPPLEMENTARY(c)) {
+		    has_supplementary = true;
+		}
+	    }
+	}
+    }
+
+    ucnv_close(cnv);
+
+    str_set_has_supplementary(self, has_supplementary);
+    str_set_valid_encoding(self, valid_encoding);
+    str_set_ascii_only(self, ascii_only);
+}
+
+static void
+str_ucnv_make_data_binary(string_t *self)
+{
+    assert(str_is_stored_in_uchars(self));
+
+    USE_CONVERTER(cnv, self);
+
+    UErrorCode err = U_ZERO_ERROR;
+    long capa = UCNV_GET_MAX_BYTES_FOR_STRING(BYTES_TO_UCHARS(self->length_in_bytes), ucnv_getMaxCharSize(cnv));
+    char *buffer = xmalloc(capa);
+    const UChar *source_pos = self->data.uchars;
+    const UChar *source_end = self->data.uchars + BYTES_TO_UCHARS(self->length_in_bytes);
+    char *target_pos = buffer;
+    char *target_end = buffer + capa;
+    ucnv_fromUnicode(cnv, &target_pos, target_end, &source_pos, source_end, NULL, true, &err);
+    // there should never be any conversion error here
+    // (if there's one it means some checking has been forgotten before)
+    assert(U_SUCCESS(err));
+
+    ucnv_close(cnv);
+
+    str_set_stored_in_uchars(self, false);
+    self->capacity_in_bytes = capa;
+    self->length_in_bytes = target_pos - buffer;
+    GC_WB(&self->data.bytes, buffer);
+}
+
+static long
+utf16_bytesize_approximation(encoding_t *enc, int bytesize)
+{
+    long approximation;
+    if (UTF16_ENC(enc)) {
+	approximation = bytesize; // the bytesize in UTF-16 is the same whatever the endianness
+    }
+    else if (UTF32_ENC(enc)) {
+	// the bytesize in UTF-16 is nearly half of the bytesize in UTF-32
+	// (if there characters not in the BMP it's a bit more though)
+	approximation = bytesize / 2;
+    }
+    else {
+	// take a quite large size to not have to reallocate
+	approximation = bytesize * 2;
+    }
+
+    if (ODD_NUMBER(approximation)) {
+	// the size must be an even number
+	++approximation;
+    }
+
+    return approximation;
+}
+
+static bool
+str_ucnv_try_making_data_uchars(string_t *self)
+{
+    assert(!str_is_stored_in_uchars(self));
+
+    USE_CONVERTER(cnv, self);
+
+    long capa = utf16_bytesize_approximation(self->encoding, self->length_in_bytes);
+    const char *source_pos = self->data.bytes;
+    const char *source_end = self->data.bytes + self->length_in_bytes;
+    UChar *buffer = xmalloc(capa);
+    UChar *target_pos = buffer;
+    UErrorCode err = U_ZERO_ERROR;
+    for (;;) {
+	UChar *target_end = buffer + BYTES_TO_UCHARS(capa);
+	err = U_ZERO_ERROR;
+	ucnv_toUnicode(cnv, &target_pos, target_end, &source_pos, source_end, NULL, true, &err);
+	if (err == U_BUFFER_OVERFLOW_ERROR) {
+	    long index = target_pos - buffer;
+	    capa *= 2; // double the buffer's size
+	    buffer = xrealloc(buffer, capa);
+	    target_pos = buffer + index;
+	}
+	else {
+	    break;
+	}
+    }
+
+    ucnv_close(cnv);
+
+    if (U_SUCCESS(err)) {
+	str_set_valid_encoding(self, true);
+	str_set_stored_in_uchars(self, true);
+	self->capacity_in_bytes = capa;
+	self->length_in_bytes = UCHARS_TO_BYTES(target_pos - buffer);
+	GC_WB(&self->data.uchars, buffer);
+
+	return true;
+    }
+    else {
+	str_set_valid_encoding(self, false);
+
+	return false;
+    }
+}
+
+static long
+str_ucnv_length(string_t *self, bool ucs2_mode)
+{
+    assert(!str_is_stored_in_uchars(self));
+
+    USE_CONVERTER(cnv, self);
+
+    const char *pos = self->data.bytes;
+    const char *end = pos + self->length_in_bytes;
+    long len = 0;
+    bool valid_encoding = true;
+    for (;;) {
+	const char *character_start_pos = pos;
+	// iterate through the string one Unicode code point at a time
+	UErrorCode err = U_ZERO_ERROR;
+	UChar32 c = ucnv_getNextUChar(cnv, &pos, end, &err);
+	if (err == U_INDEX_OUTOFBOUNDS_ERROR) {
+	    // end of the string
+	    break;
+	}
+	else if (U_FAILURE(err)) {
+	    valid_encoding = false;
+	    long min_char_size = self->encoding->min_char_size;
+	    long converted_width = pos - character_start_pos;
+	    len += div_round_up(converted_width, min_char_size);
+	}
+	else {
+	    if (ucs2_mode && !U_IS_BMP(c)) {
+		len += 2;
+	    }
+	    else {
+		++len;
+	    }
+	}
+    }
+
+    ucnv_close(cnv);
+
+    str_set_valid_encoding(self, valid_encoding);
+
+    return len;
+}
+
+#define STACK_BUFFER_SIZE 1024
+static long
+str_ucnv_bytesize(string_t *self)
+{
+    assert(str_is_stored_in_uchars(self));
+
+    // for strings stored in UTF-16 for which the Ruby encoding is not UTF-16,
+    // we have to convert back the string in its original encoding to get the length in bytes
+    USE_CONVERTER(cnv, self);
+
+    UErrorCode err = U_ZERO_ERROR;
+
+    long len = 0;
+    char buffer[STACK_BUFFER_SIZE];
+    const UChar *source_pos = self->data.uchars;
+    const UChar *source_end = self->data.uchars + BYTES_TO_UCHARS(self->length_in_bytes);
+    char *target_end = buffer + STACK_BUFFER_SIZE;
+    for (;;) {
+	err = U_ZERO_ERROR;
+	char *target_pos = buffer;
+	ucnv_fromUnicode(cnv, &target_pos, target_end, &source_pos, source_end, NULL, true, &err);
+	len += target_pos - buffer;
+	if (err != U_BUFFER_OVERFLOW_ERROR) {
+	    // if the convertion failed, a check was missing somewhere
+	    assert(U_SUCCESS(err));
+	    break;
+	}
+    }
+
+    ucnv_close(cnv);
+    return len;
+}
+
+static character_boundaries_t
+str_ucnv_get_character_boundaries(string_t *self, long index, bool ucs2_mode)
+{
+    assert(!str_is_stored_in_uchars(self));
+
+    character_boundaries_t boundaries = {-1, -1};
+
+    if (index < 0) {
+	// calculating the length is slow but we don't have much choice
+	index += str_ucnv_length(self, ucs2_mode);
+	if (index < 0) {
+	    return boundaries;
+	}
+    }
+
+    // the code has many similarities with str_length
+    USE_CONVERTER(cnv, self);
+
+    const char *pos = self->data.bytes;
+    const char *end = pos + self->length_in_bytes;
+    long current_index = 0;
+    for (;;) {
+	const char *character_start_pos = pos;
+	// iterate through the string one Unicode code point at a time
+	// (we dont care what the character is or if it's valid or not)
+	UErrorCode err = U_ZERO_ERROR;
+	UChar32 c = ucnv_getNextUChar(cnv, &pos, end, &err);
+	if (err == U_INDEX_OUTOFBOUNDS_ERROR) {
+	    // end of the string
+	    break;
+	}
+	long offset_in_bytes = character_start_pos - self->data.bytes;
+	long converted_width = pos - character_start_pos;
+	if (U_FAILURE(err)) {
+	    long min_char_size = self->encoding->min_char_size;
+	    // division of converted_width by min_char_size rounded up
+	    long diff = div_round_up(converted_width, min_char_size);
+	    long length_in_bytes;
+	    if (current_index == index) {
+		if (min_char_size > converted_width) {
+		    length_in_bytes = converted_width;
+		}
+		else {
+		    length_in_bytes = min_char_size;
+		}
+		boundaries.start_offset_in_bytes = offset_in_bytes;
+		boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + length_in_bytes;
+		break;
+	    }
+	    else if (current_index + diff > index) {
+		long adjusted_offset = offset_in_bytes + (index - current_index) * min_char_size;
+		if (adjusted_offset + min_char_size > offset_in_bytes + converted_width) {
+		    length_in_bytes = offset_in_bytes + converted_width - adjusted_offset;
+		}
+		else {
+		    length_in_bytes = min_char_size;
+		}
+		boundaries.start_offset_in_bytes = adjusted_offset;
+		boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + length_in_bytes;
+		break;
+	    }
+	    current_index += diff;
+	}
+	else {
+	    if (ucs2_mode && !U_IS_BMP(c)) {
+		// you cannot cut a surrogate in an encoding that is not UTF-16
+		if (current_index == index) {
+		    boundaries.start_offset_in_bytes = offset_in_bytes;
+		    break;
+		}
+		else if (current_index+1 == index) {
+		    boundaries.end_offset_in_bytes = offset_in_bytes + converted_width;
+		    break;
+		}
+		++current_index;
+	    }
+
+	    if (current_index == index) {
+		boundaries.start_offset_in_bytes = offset_in_bytes;
+		boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + converted_width;
+		break;
+	    }
+
+	    ++current_index;
+	}
+    }
+
+    ucnv_close(cnv);
+
+    return boundaries;
+}
+
+static long
+str_ucnv_offset_in_bytes_to_index(string_t *self, long offset_in_bytes, bool ucs2_mode)
+{
+    assert(!str_is_stored_in_uchars(self));
+
+    // the code has many similarities with str_length
+    USE_CONVERTER(cnv, self);
+
+    const char *current_position = self->data.bytes;
+    const char *searched_position = current_position + offset_in_bytes;
+    const char *end = current_position + self->length_in_bytes;
+    long index = 0;
+    for (;;) {
+	const char *character_start_position = current_position;
+	// iterate through the string one Unicode code point at a time
+	UErrorCode err = U_ZERO_ERROR;
+	UChar32 c = ucnv_getNextUChar(cnv, &current_position, end, &err);
+	if (err == U_INDEX_OUTOFBOUNDS_ERROR) {
+	    // end of the string
+	    // should not happen because str_offset_in_bytes_to_index
+	    // checks before that offset_in_bytes is inferior to the length in bytes
+	    abort();
+	}
+	else if (U_FAILURE(err)) {
+	    long min_char_size = self->encoding->min_char_size;
+	    long converted_width = current_position - character_start_position;
+	    long to_add = div_round_up(converted_width, min_char_size);
+	    if (searched_position < character_start_position + to_add) {
+		long difference = searched_position - character_start_position;
+		index += (difference / min_char_size);
+		break;
+	    }
+	    index += to_add;
+	}
+	else {
+	    if (searched_position < current_position) {
+		break;
+	    }
+	    if (ucs2_mode && !U_IS_BMP(c)) {
+		index += 2;
+	    }
+	    else {
+		++index;
+	    }
+	}
+	if (searched_position == current_position) {
+	    break;
+	}
+    }
+
+    ucnv_close(cnv);
+
+    return index;
+}
+
+void
+enc_init_ucnv_encoding(encoding_t *encoding)
+{
+    // create the ICU converter
+    UErrorCode err = U_ZERO_ERROR;
+    UConverter *converter = ucnv_open(encoding->public_name, &err);
+    if (!U_SUCCESS(err) || (converter == NULL)) {
+	fprintf(stderr, "Couldn't create the encoder for %s\n", encoding->public_name);
+	abort();
+    }
+    // stop the conversion when the conversion failed
+    err = U_ZERO_ERROR;
+    ucnv_setToUCallBack(converter, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
+    err = U_ZERO_ERROR;
+    ucnv_setFromUCallBack(converter, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &err);
+
+    // fill the fields not filled yet
+    encoding->private_data = converter;
+    encoding->methods.update_flags = str_ucnv_update_flags;
+    encoding->methods.make_data_binary = str_ucnv_make_data_binary;
+    encoding->methods.try_making_data_uchars = str_ucnv_try_making_data_uchars;
+    encoding->methods.length = str_ucnv_length;
+    encoding->methods.bytesize = str_ucnv_bytesize;
+    encoding->methods.get_character_boundaries = str_ucnv_get_character_boundaries;
+    encoding->methods.offset_in_bytes_to_index = str_ucnv_offset_in_bytes_to_index;
+}

Added: MacRuby/branches/icu/unicode/brkiter.h
===================================================================
--- MacRuby/branches/icu/unicode/brkiter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/brkiter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,557 @@
+/*
+********************************************************************************
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+********************************************************************************
+*
+* File brkiter.h
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   02/18/97    aliu        Added typedef for TextCount.  Made DONE const.
+*   05/07/97    aliu        Fixed DLL declaration.
+*   07/09/97    jfitz       Renamed BreakIterator and interface synced with JDK
+*   08/11/98    helena      Sync-up JDK1.2.
+*   01/13/2000  helena      Added UErrorCode parameter to createXXXInstance methods.
+********************************************************************************
+*/
+
+#ifndef BRKITER_H
+#define BRKITER_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file
+ * \brief C++ API: Break Iterator.
+ */
+ 
+#if UCONFIG_NO_BREAK_ITERATION
+
+U_NAMESPACE_BEGIN
+
+/*
+ * Allow the declaration of APIs with pointers to BreakIterator
+ * even when break iteration is removed from the build.
+ */
+class BreakIterator;
+
+U_NAMESPACE_END
+
+#else
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+#include "unicode/chariter.h"
+#include "unicode/locid.h"
+#include "unicode/ubrk.h"
+#include "unicode/strenum.h"
+#include "unicode/utext.h"
+#include "unicode/umisc.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * The BreakIterator class implements methods for finding the location
+ * of boundaries in text. BreakIterator is an abstract base class.
+ * Instances of BreakIterator maintain a current position and scan over
+ * text returning the index of characters where boundaries occur.
+ * <p>
+ * Line boundary analysis determines where a text string can be broken
+ * when line-wrapping. The mechanism correctly handles punctuation and
+ * hyphenated words.
+ * <p>
+ * Sentence boundary analysis allows selection with correct
+ * interpretation of periods within numbers and abbreviations, and
+ * trailing punctuation marks such as quotation marks and parentheses.
+ * <p>
+ * Word boundary analysis is used by search and replace functions, as
+ * well as within text editing applications that allow the user to
+ * select words with a double click. Word selection provides correct
+ * interpretation of punctuation marks within and following
+ * words. Characters that are not part of a word, such as symbols or
+ * punctuation marks, have word-breaks on both sides.
+ * <p>
+ * Character boundary analysis allows users to interact with
+ * characters as they expect to, for example, when moving the cursor
+ * through a text string. Character boundary analysis provides correct
+ * navigation of through character strings, regardless of how the
+ * character is stored.  For example, an accented character might be
+ * stored as a base character and a diacritical mark. What users
+ * consider to be a character can differ between languages.
+ * <p>
+ * The text boundary positions are found according to the rules
+ * described in Unicode Standard Annex #29, Text Boundaries, and
+ * Unicode Standard Annex #14, Line Breaking Properties.  These
+ * are available at http://www.unicode.org/reports/tr14/ and
+ * http://www.unicode.org/reports/tr29/.
+ * <p>
+ * In addition to the C++ API defined in this header file, a
+ * plain C API with equivalent functionality is defined in the
+ * file ubrk.h
+ * <p>
+ * Code snippits illustrating the use of the Break Iterator APIs
+ * are available in the ICU User Guide, 
+ * http://icu.sourceforge.net/userguide/boundaryAnalysis.html
+ * and in the sample program icu/source/samples/break/break.cpp"
+ *
+ */
+class U_COMMON_API BreakIterator : public UObject {
+public:
+    /**
+     *  destructor
+     *  @stable ICU 2.0
+     */
+    virtual ~BreakIterator();
+
+    /**
+     * Return true if another object is semantically equal to this
+     * one. The other object should be an instance of the same subclass of
+     * BreakIterator. Objects of different subclasses are considered
+     * unequal.
+     * <P>
+     * Return true if this BreakIterator is at the same position in the
+     * same text, and is the same class and type (word, line, etc.) of
+     * BreakIterator, as the argument.  Text is considered the same if
+     * it contains the same characters, it need not be the same
+     * object, and styles are not considered.
+     * @stable ICU 2.0
+     */
+    virtual UBool operator==(const BreakIterator&) const = 0;
+
+    /**
+     * Returns the complement of the result of operator==
+     * @param rhs The BreakIterator to be compared for inequality
+     * @return the complement of the result of operator==
+     * @stable ICU 2.0
+     */
+    UBool operator!=(const BreakIterator& rhs) const { return !operator==(rhs); }
+
+    /**
+     * Return a polymorphic copy of this object.  This is an abstract
+     * method which subclasses implement.
+     * @stable ICU 2.0
+     */
+    virtual BreakIterator* clone(void) const = 0;
+
+    /**
+     * Return a polymorphic class ID for this object. Different subclasses
+     * will return distinct unequal values.
+     * @stable ICU 2.0
+     */
+    virtual UClassID getDynamicClassID(void) const = 0;
+
+    /**
+     * Return a CharacterIterator over the text being analyzed.
+     * @stable ICU 2.0
+     */
+    virtual CharacterIterator& getText(void) const = 0;
+
+
+    /**
+      *  Get a UText for the text being analyzed.
+      *  The returned UText is a shallow clone of the UText used internally
+      *  by the break iterator implementation.  It can safely be used to
+      *  access the text without impacting any break iterator operations,
+      *  but the underlying text itself must not be altered.
+      *
+      * @param fillIn A UText to be filled in.  If NULL, a new UText will be
+      *           allocated to hold the result.
+      * @param status receives any error codes.
+      * @return   The current UText for this break iterator.  If an input
+      *           UText was provided, it will always be returned.
+      * @draft ICU 3.4
+      */
+     virtual UText *getUText(UText *fillIn, UErrorCode &status) const = 0;
+
+    /**
+     * Change the text over which this operates. The text boundary is
+     * reset to the start.
+     * @param text The UnicodeString used to change the text.
+     * @stable ICU 2.0
+     */
+    virtual void  setText(const UnicodeString &text) = 0;
+
+    /**
+     * Reset the break iterator to operate over the text represented by 
+     * the UText.  The iterator position is reset to the start.
+     *
+     * This function makes a shallow clone of the supplied UText.  This means
+     * that the caller is free to immediately close or otherwise reuse the
+     * Utext that was passed as a parameter, but that the underlying text itself
+     * must not be altered while being referenced by the break iterator.
+     *
+     * @param text The UText used to change the text.
+     * @param status receives any error codes.
+     * @draft ICU 3.4
+     */
+    virtual void  setText(UText *text, UErrorCode &status) = 0;
+
+    /**
+     * Change the text over which this operates. The text boundary is
+     * reset to the start.
+     * Note that setText(UText *) provides similar functionality to this function,
+     * and is more efficient.
+     * @param it The CharacterIterator used to change the text.
+     * @stable ICU 2.0
+     */
+    virtual void  adoptText(CharacterIterator* it) = 0;
+
+    enum {
+        /**
+         * DONE is returned by previous() and next() after all valid
+         * boundaries have been returned.
+         * @stable ICU 2.0
+         */
+        DONE = (int32_t)-1
+    };
+
+    /**
+     * Return the index of the first character in the text being scanned.
+     * @stable ICU 2.0
+     */
+    virtual int32_t first(void) = 0;
+
+    /**
+     * Return the index immediately BEYOND the last character in the text being scanned.
+     * @stable ICU 2.0
+     */
+    virtual int32_t last(void) = 0;
+
+    /**
+     * Return the boundary preceding the current boundary.
+     * @return The character index of the previous text boundary or DONE if all
+     * boundaries have been returned.
+     * @stable ICU 2.0
+     */
+    virtual int32_t previous(void) = 0;
+
+    /**
+     * Return the boundary following the current boundary.
+     * @return The character index of the next text boundary or DONE if all
+     * boundaries have been returned.
+     * @stable ICU 2.0
+     */
+    virtual int32_t next(void) = 0;
+
+    /**
+     * Return character index of the current interator position within the text.
+     * @return The boundary most recently returned.
+     * @stable ICU 2.0
+     */
+    virtual int32_t current(void) const = 0;
+
+    /**
+     * Return the first boundary following the specified offset.
+     * The value returned is always greater than the offset or
+     * the value BreakIterator.DONE
+     * @param offset the offset to begin scanning.
+     * @return The first boundary after the specified offset.
+     * @stable ICU 2.0
+     */
+    virtual int32_t following(int32_t offset) = 0;
+
+    /**
+     * Return the first boundary preceding the specified offset.
+     * The value returned is always smaller than the offset or
+     * the value BreakIterator.DONE
+     * @param offset the offset to begin scanning.
+     * @return The first boundary before the specified offset.
+     * @stable ICU 2.0
+     */
+    virtual int32_t preceding(int32_t offset) = 0;
+
+    /**
+     * Return true if the specfied position is a boundary position.
+     * As a side effect, the current position of the iterator is set
+     * to the first boundary position at or following the specified offset.
+     * @param offset the offset to check.
+     * @return True if "offset" is a boundary position.
+     * @stable ICU 2.0
+     */
+    virtual UBool isBoundary(int32_t offset) = 0;
+
+    /**
+     * Return the nth boundary from the current boundary
+     * @param n which boundary to return.  A value of 0
+     * does nothing.  Negative values move to previous boundaries
+     * and positive values move to later boundaries.
+     * @return The index of the nth boundary from the current position, or
+     * DONE if there are fewer than |n| boundaries in the specfied direction.
+     * @stable ICU 2.0
+     */
+    virtual int32_t next(int32_t n) = 0;
+
+    /**
+     * Create BreakIterator for word-breaks using the given locale.
+     * Returns an instance of a BreakIterator implementing word breaks.
+     * WordBreak is useful for word selection (ex. double click)
+     * @param where the locale.
+     * @param status the error code
+     * @return A BreakIterator for word-breaks.  The UErrorCode& status
+     * parameter is used to return status information to the user.
+     * To check whether the construction succeeded or not, you should check
+     * the value of U_SUCCESS(err).  If you wish more detailed information, you
+     * can check for informational error results which still indicate success.
+     * U_USING_FALLBACK_WARNING indicates that a fall back locale was used.  For
+     * example, 'de_CH' was requested, but nothing was found there, so 'de' was
+     * used.  U_USING_DEFAULT_WARNING indicates that the default locale data was
+     * used; neither the requested locale nor any of its fall back locales
+     * could be found.
+     * The caller owns the returned object and is responsible for deleting it.
+     * @stable ICU 2.0
+     */
+    static BreakIterator* U_EXPORT2
+    createWordInstance(const Locale& where, UErrorCode& status);
+
+    /**
+     * Create BreakIterator for line-breaks using specified locale.
+     * Returns an instance of a BreakIterator implementing line breaks. Line
+     * breaks are logically possible line breaks, actual line breaks are
+     * usually determined based on display width.
+     * LineBreak is useful for word wrapping text.
+     * @param where the locale.
+     * @param status The error code.
+     * @return A BreakIterator for line-breaks.  The UErrorCode& status
+     * parameter is used to return status information to the user.
+     * To check whether the construction succeeded or not, you should check
+     * the value of U_SUCCESS(err).  If you wish more detailed information, you
+     * can check for informational error results which still indicate success.
+     * U_USING_FALLBACK_WARNING indicates that a fall back locale was used.  For
+     * example, 'de_CH' was requested, but nothing was found there, so 'de' was
+     * used.  U_USING_DEFAULT_WARNING indicates that the default locale data was
+     * used; neither the requested locale nor any of its fall back locales
+     * could be found.
+     * The caller owns the returned object and is responsible for deleting it.
+     * @stable ICU 2.0
+     */
+    static BreakIterator* U_EXPORT2
+    createLineInstance(const Locale& where, UErrorCode& status);
+
+    /**
+     * Create BreakIterator for character-breaks using specified locale
+     * Returns an instance of a BreakIterator implementing character breaks.
+     * Character breaks are boundaries of combining character sequences.
+     * @param where the locale.
+     * @param status The error code.
+     * @return A BreakIterator for character-breaks.  The UErrorCode& status
+     * parameter is used to return status information to the user.
+     * To check whether the construction succeeded or not, you should check
+     * the value of U_SUCCESS(err).  If you wish more detailed information, you
+     * can check for informational error results which still indicate success.
+     * U_USING_FALLBACK_WARNING indicates that a fall back locale was used.  For
+     * example, 'de_CH' was requested, but nothing was found there, so 'de' was
+     * used.  U_USING_DEFAULT_WARNING indicates that the default locale data was
+     * used; neither the requested locale nor any of its fall back locales
+     * could be found.
+     * The caller owns the returned object and is responsible for deleting it.
+     * @stable ICU 2.0
+     */
+    static BreakIterator* U_EXPORT2
+    createCharacterInstance(const Locale& where, UErrorCode& status);
+
+    /**
+     * Create BreakIterator for sentence-breaks using specified locale
+     * Returns an instance of a BreakIterator implementing sentence breaks.
+     * @param where the locale.
+     * @param status The error code.
+     * @return A BreakIterator for sentence-breaks.  The UErrorCode& status
+     * parameter is used to return status information to the user.
+     * To check whether the construction succeeded or not, you should check
+     * the value of U_SUCCESS(err).  If you wish more detailed information, you
+     * can check for informational error results which still indicate success.
+     * U_USING_FALLBACK_WARNING indicates that a fall back locale was used.  For
+     * example, 'de_CH' was requested, but nothing was found there, so 'de' was
+     * used.  U_USING_DEFAULT_WARNING indicates that the default locale data was
+     * used; neither the requested locale nor any of its fall back locales
+     * could be found.
+     * The caller owns the returned object and is responsible for deleting it.
+     * @stable ICU 2.0
+     */
+    static BreakIterator* U_EXPORT2
+    createSentenceInstance(const Locale& where, UErrorCode& status);
+
+    /**
+     * Create BreakIterator for title-casing breaks using the specified locale
+     * Returns an instance of a BreakIterator implementing title breaks.
+     * The iterator returned locates title boundaries as described for
+     * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
+     * please use Word Boundary iterator.{@link #createWordInstance }
+     *
+     * @param where the locale.
+     * @param status The error code.
+     * @return A BreakIterator for title-breaks.  The UErrorCode& status
+     * parameter is used to return status information to the user.
+     * To check whether the construction succeeded or not, you should check
+     * the value of U_SUCCESS(err).  If you wish more detailed information, you
+     * can check for informational error results which still indicate success.
+     * U_USING_FALLBACK_WARNING indicates that a fall back locale was used.  For
+     * example, 'de_CH' was requested, but nothing was found there, so 'de' was
+     * used.  U_USING_DEFAULT_WARNING indicates that the default locale data was
+     * used; neither the requested locale nor any of its fall back locales
+     * could be found.
+     * The caller owns the returned object and is responsible for deleting it.
+     * @stable ICU 2.1
+     */
+    static BreakIterator* U_EXPORT2
+    createTitleInstance(const Locale& where, UErrorCode& status);
+
+    /**
+     * Get the set of Locales for which TextBoundaries are installed.
+     * <p><b>Note:</b> this will not return locales added through the register
+     * call. To see the registered locales too, use the getAvailableLocales
+     * function that returns a StringEnumeration object </p>
+     * @param count the output parameter of number of elements in the locale list
+     * @return available locales
+     * @stable ICU 2.0
+     */
+    static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count);
+
+    /**
+     * Get name of the object for the desired Locale, in the desired langauge.
+     * @param objectLocale must be from getAvailableLocales.
+     * @param displayLocale specifies the desired locale for output.
+     * @param name the fill-in parameter of the return value
+     * Uses best match.
+     * @return user-displayable name
+     * @stable ICU 2.0
+     */
+    static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale,
+                                         const Locale& displayLocale,
+                                         UnicodeString& name);
+
+    /**
+     * Get name of the object for the desired Locale, in the langauge of the
+     * default locale.
+     * @param objectLocale must be from getMatchingLocales
+     * @param name the fill-in parameter of the return value
+     * @return user-displayable name
+     * @stable ICU 2.0
+     */
+    static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale,
+                                         UnicodeString& name);
+
+    /**
+     * Thread safe client-buffer-based cloning operation
+     *    Do NOT call delete on a safeclone, since 'new' is not used to create it.
+     * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated.
+     * If buffer is not large enough, new memory will be allocated.
+     * @param BufferSize reference to size of allocated space.
+     * If BufferSize == 0, a sufficient size for use in cloning will
+     * be returned ('pre-flighting')
+     * If BufferSize is not enough for a stack-based safe clone,
+     * new memory will be allocated.
+     * @param status to indicate whether the operation went on smoothly or there were errors
+     *  An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were
+     *  necessary.
+     * @return pointer to the new clone
+     *
+     * @stable ICU 2.0
+     */
+    virtual BreakIterator *  createBufferClone(void *stackBuffer,
+                                               int32_t &BufferSize,
+                                               UErrorCode &status) = 0;
+
+    /**
+     *   Determine whether the BreakIterator was created in user memory by
+     *   createBufferClone(), and thus should not be deleted.  Such objects
+     *   must be closed by an explicit call to the destructor (not delete).
+     *  @stable ICU 2.0
+     */
+    inline UBool isBufferClone(void);
+
+#if !UCONFIG_NO_SERVICE
+    /**
+     * Register a new break iterator of the indicated kind, to use in the given locale.
+     * The break iterator will be adopted.  Clones of the iterator will be returned
+     * if a request for a break iterator of the given kind matches or falls back to
+     * this locale.
+     * @param toAdopt the BreakIterator instance to be adopted
+     * @param locale the Locale for which this instance is to be registered
+     * @param kind the type of iterator for which this instance is to be registered
+     * @param status the in/out status code, no special meanings are assigned
+     * @return a registry key that can be used to unregister this instance
+     * @stable ICU 2.4
+     */
+    static URegistryKey U_EXPORT2 registerInstance(BreakIterator* toAdopt,
+                                        const Locale& locale,
+                                        UBreakIteratorType kind,
+                                        UErrorCode& status);
+
+    /**
+     * Unregister a previously-registered BreakIterator using the key returned from the
+     * register call.  Key becomes invalid after a successful call and should not be used again.
+     * The BreakIterator corresponding to the key will be deleted.
+     * @param key the registry key returned by a previous call to registerInstance
+     * @param status the in/out status code, no special meanings are assigned
+     * @return TRUE if the iterator for the key was successfully unregistered
+     * @stable ICU 2.4
+     */
+    static UBool U_EXPORT2 unregister(URegistryKey key, UErrorCode& status);
+
+    /**
+     * Return a StringEnumeration over the locales available at the time of the call,
+     * including registered locales.
+     * @return a StringEnumeration over the locales available at the time of the call
+     * @stable ICU 2.4
+     */
+    static StringEnumeration* U_EXPORT2 getAvailableLocales(void);
+#endif
+
+    /**
+     * Returns the locale for this break iterator. Two flavors are available: valid and
+     * actual locale.
+     * @stable ICU 2.8
+     */
+    Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
+
+    /** Get the locale for this break iterator object. You can choose between valid and actual locale.
+     *  @param type type of the locale we're looking for (valid or actual)
+     *  @param status error code for the operation
+     *  @return the locale
+     *  @internal
+     */
+    const char *getLocaleID(ULocDataLocaleType type, UErrorCode& status) const;
+
+ private:
+    static BreakIterator* buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode& status);
+    static BreakIterator* createInstance(const Locale& loc, int32_t kind, UErrorCode& status);
+    static BreakIterator* makeInstance(const Locale& loc, int32_t kind, UErrorCode& status);
+
+    friend class ICUBreakIteratorFactory;
+    friend class ICUBreakIteratorService;
+
+protected:
+    /** @internal */
+    BreakIterator();
+    /** @internal */
+    UBool fBufferClone;
+    /** @internal */
+    BreakIterator (const BreakIterator &other) : UObject(other), fBufferClone(FALSE) {}
+
+private:
+
+    /** @internal */
+    char actualLocale[ULOC_FULLNAME_CAPACITY];
+    char validLocale[ULOC_FULLNAME_CAPACITY];
+
+    /**
+     * The assignment operator has no real implementation.
+     * It's provided to make the compiler happy. Do not call.
+     */
+    BreakIterator& operator=(const BreakIterator&);
+};
+
+inline UBool BreakIterator::isBufferClone()
+{
+    return fBufferClone;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
+#endif // _BRKITER
+//eof
+

Added: MacRuby/branches/icu/unicode/caniter.h
===================================================================
--- MacRuby/branches/icu/unicode/caniter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/caniter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,201 @@
+/*
+ *******************************************************************************
+ * Copyright (C) 1996-2006, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+#ifndef CANITER_H
+#define CANITER_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+
+/**
+ * \file
+ * \brief C++ API: Canonical Iterator
+ */
+ 
+/** Should permutation skip characters with combining class zero
+ *  Should be either TRUE or FALSE. This is a compile time option
+ *  @stable ICU 2.4
+ */
+#ifndef CANITER_SKIP_ZEROES
+#define CANITER_SKIP_ZEROES TRUE
+#endif
+
+U_NAMESPACE_BEGIN
+
+class Hashtable;
+
+/**
+ * This class allows one to iterate through all the strings that are canonically equivalent to a given
+ * string. For example, here are some sample results:
+Results for: {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+1: \\u0041\\u030A\\u0064\\u0307\\u0327
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+2: \\u0041\\u030A\\u0064\\u0327\\u0307
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+3: \\u0041\\u030A\\u1E0B\\u0327
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+4: \\u0041\\u030A\\u1E11\\u0307
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+5: \\u00C5\\u0064\\u0307\\u0327
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+6: \\u00C5\\u0064\\u0327\\u0307
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+7: \\u00C5\\u1E0B\\u0327
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+8: \\u00C5\\u1E11\\u0307
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+9: \\u212B\\u0064\\u0307\\u0327
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+10: \\u212B\\u0064\\u0327\\u0307
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+11: \\u212B\\u1E0B\\u0327
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+12: \\u212B\\u1E11\\u0307
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+ *<br>Note: the code is intended for use with small strings, and is not suitable for larger ones,
+ * since it has not been optimized for that situation.
+ * Note, CanonicalIterator is not intended to be subclassed.
+ * @author M. Davis
+ * @author C++ port by V. Weinstein
+ * @stable ICU 2.4
+ */
+class U_COMMON_API CanonicalIterator : public UObject {
+public:
+    /**
+     * Construct a CanonicalIterator object
+     * @param source    string to get results for
+     * @param status    Fill-in parameter which receives the status of this operation.
+     * @stable ICU 2.4
+     */
+    CanonicalIterator(const UnicodeString &source, UErrorCode &status);
+
+    /** Destructor
+     *  Cleans pieces
+     * @stable ICU 2.4
+     */
+    virtual ~CanonicalIterator();
+
+    /**
+     * Gets the NFD form of the current source we are iterating over.
+     * @return gets the source: NOTE: it is the NFD form of source
+     * @stable ICU 2.4
+     */
+    UnicodeString getSource();
+
+    /**
+     * Resets the iterator so that one can start again from the beginning.
+     * @stable ICU 2.4
+     */
+    void reset();
+
+    /**
+     * Get the next canonically equivalent string.
+     * <br><b>Warning: The strings are not guaranteed to be in any particular order.</b>
+     * @return the next string that is canonically equivalent. A bogus string is returned when
+     * the iteration is done.
+     * @stable ICU 2.4
+     */
+    UnicodeString next();
+
+    /**
+     * Set a new source for this iterator. Allows object reuse.
+     * @param newSource     the source string to iterate against. This allows the same iterator to be used
+     *                     while changing the source string, saving object creation.
+     * @param status        Fill-in parameter which receives the status of this operation.
+     * @stable ICU 2.4
+     */
+    void setSource(const UnicodeString &newSource, UErrorCode &status);
+
+    /**
+     * Dumb recursive implementation of permutation.
+     * TODO: optimize
+     * @param source     the string to find permutations for
+     * @param skipZeros  determine if skip zeros
+     * @param result     the results in a set.
+     * @param status       Fill-in parameter which receives the status of this operation.
+     * @internal
+     */
+    static void U_EXPORT2 permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status);
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.2
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.2
+     */
+    virtual UClassID getDynamicClassID() const;
+
+private:
+    // ===================== PRIVATES ==============================
+    // private default constructor
+    CanonicalIterator();
+
+
+    /**
+     * Copy constructor. Private for now.
+     * @internal
+     */
+    CanonicalIterator(const CanonicalIterator& other);
+
+    /**
+     * Assignment operator. Private for now.
+     * @internal
+     */
+    CanonicalIterator& operator=(const CanonicalIterator& other);
+
+    // fields
+    UnicodeString source;
+    UBool done;
+
+    // 2 dimensional array holds the pieces of the string with
+    // their different canonically equivalent representations
+    UnicodeString **pieces;
+    int32_t pieces_length;
+    int32_t *pieces_lengths;
+
+    // current is used in iterating to combine pieces
+    int32_t *current;
+    int32_t current_length;
+
+    // transient fields
+    UnicodeString buffer;
+
+    // we have a segment, in NFD. Find all the strings that are canonically equivalent to it.
+    UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment)
+
+    //Set getEquivalents2(String segment);
+    Hashtable *getEquivalents2(Hashtable *fillinResult, const UChar *segment, int32_t segLen, UErrorCode &status);
+    //Hashtable *getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status);
+
+    /**
+     * See if the decomposition of cp2 is at segment starting at segmentPos
+     * (with canonical rearrangment!)
+     * If so, take the remainder, and return the equivalents
+     */
+    //Set extract(int comp, String segment, int segmentPos, StringBuffer buffer);
+    Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const UChar *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status);
+    //Hashtable *extract(UChar32 comp, const UnicodeString &segment, int32_t segLen, int32_t segmentPos, UErrorCode &status);
+
+    void cleanPieces();
+
+};
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_NORMALIZATION */
+
+#endif

Added: MacRuby/branches/icu/unicode/chariter.h
===================================================================
--- MacRuby/branches/icu/unicode/chariter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/chariter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,716 @@
+/*
+********************************************************************
+*
+*   Copyright (C) 1997-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+********************************************************************
+*/
+
+#ifndef CHARITER_H
+#define CHARITER_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+/**
+ * \file
+ * \brief C++ API: Character Iterator
+ */
+ 
+U_NAMESPACE_BEGIN
+/**
+ * Abstract class that defines an API for forward-only iteration
+ * on text objects.
+ * This is a minimal interface for iteration without random access
+ * or backwards iteration. It is especially useful for wrapping
+ * streams with converters into an object for collation or
+ * normalization.
+ *
+ * <p>Characters can be accessed in two ways: as code units or as
+ * code points.
+ * Unicode code points are 21-bit integers and are the scalar values
+ * of Unicode characters. ICU uses the type UChar32 for them.
+ * Unicode code units are the storage units of a given
+ * Unicode/UCS Transformation Format (a character encoding scheme).
+ * With UTF-16, all code points can be represented with either one
+ * or two code units ("surrogates").
+ * String storage is typically based on code units, while properties
+ * of characters are typically determined using code point values.
+ * Some processes may be designed to work with sequences of code units,
+ * or it may be known that all characters that are important to an
+ * algorithm can be represented with single code units.
+ * Other processes will need to use the code point access functions.</p>
+ *
+ * <p>ForwardCharacterIterator provides nextPostInc() to access
+ * a code unit and advance an internal position into the text object,
+ * similar to a <code>return text[position++]</code>.<br>
+ * It provides next32PostInc() to access a code point and advance an internal
+ * position.</p>
+ *
+ * <p>next32PostInc() assumes that the current position is that of
+ * the beginning of a code point, i.e., of its first code unit.
+ * After next32PostInc(), this will be true again.
+ * In general, access to code units and code points in the same
+ * iteration loop should not be mixed. In UTF-16, if the current position
+ * is on a second code unit (Low Surrogate), then only that code unit
+ * is returned even by next32PostInc().</p>
+ *
+ * <p>For iteration with either function, there are two ways to
+ * check for the end of the iteration. When there are no more
+ * characters in the text object:
+ * <ul>
+ * <li>The hasNext() function returns FALSE.</li>
+ * <li>nextPostInc() and next32PostInc() return DONE
+ *     when one attempts to read beyond the end of the text object.</li>
+ * </ul>
+ *
+ * Example:
+ * \code 
+ * void function1(ForwardCharacterIterator &it) {
+ *     UChar32 c;
+ *     while(it.hasNext()) {
+ *         c=it.next32PostInc();
+ *         // use c
+ *     }
+ * }
+ *
+ * void function1(ForwardCharacterIterator &it) {
+ *     UChar c;
+ *     while((c=it.nextPostInc())!=ForwardCharacterIterator::DONE) {
+ *         // use c
+ *      }
+ *  }
+ * \endcode
+ * </p>
+ *
+ * @stable ICU 2.0
+ */
+class U_COMMON_API ForwardCharacterIterator : public UObject {
+public:
+    /**
+     * Value returned by most of ForwardCharacterIterator's functions
+     * when the iterator has reached the limits of its iteration.
+     * @stable ICU 2.0
+     */
+    enum { DONE = 0xffff };
+    
+    /**
+     * Destructor.  
+     * @stable ICU 2.0
+     */
+    virtual ~ForwardCharacterIterator();
+    
+    /**
+     * Returns true when both iterators refer to the same
+     * character in the same character-storage object.  
+     * @param that The ForwardCharacterIterator to be compared for equality
+     * @return true when both iterators refer to the same
+     * character in the same character-storage object
+     * @stable ICU 2.0
+     */
+    virtual UBool operator==(const ForwardCharacterIterator& that) const = 0;
+    
+    /**
+     * Returns true when the iterators refer to different
+     * text-storage objects, or to different characters in the
+     * same text-storage object.  
+     * @param that The ForwardCharacterIterator to be compared for inequality
+     * @return true when the iterators refer to different
+     * text-storage objects, or to different characters in the
+     * same text-storage object
+     * @stable ICU 2.0
+     */
+    inline UBool operator!=(const ForwardCharacterIterator& that) const;
+    
+    /**
+     * Generates a hash code for this iterator.  
+     * @return the hash code.
+     * @stable ICU 2.0
+     */
+    virtual int32_t hashCode(void) const = 0;
+    
+    /**
+     * Returns a UClassID for this ForwardCharacterIterator ("poor man's
+     * RTTI").<P> Despite the fact that this function is public,
+     * DO NOT CONSIDER IT PART OF CHARACTERITERATOR'S API! 
+     * @return a UClassID for this ForwardCharacterIterator 
+     * @stable ICU 2.0
+     */
+    virtual UClassID getDynamicClassID(void) const = 0;
+    
+    /**
+     * Gets the current code unit for returning and advances to the next code unit
+     * in the iteration range
+     * (toward endIndex()).  If there are
+     * no more code units to return, returns DONE.
+     * @return the current code unit.
+     * @stable ICU 2.0
+     */
+    virtual UChar         nextPostInc(void) = 0;
+    
+    /**
+     * Gets the current code point for returning and advances to the next code point
+     * in the iteration range
+     * (toward endIndex()).  If there are
+     * no more code points to return, returns DONE.
+     * @return the current code point.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       next32PostInc(void) = 0;
+    
+    /**
+     * Returns FALSE if there are no more code units or code points
+     * at or after the current position in the iteration range.
+     * This is used with nextPostInc() or next32PostInc() in forward
+     * iteration.
+     * @returns FALSE if there are no more code units or code points
+     * at or after the current position in the iteration range.
+     * @stable ICU 2.0
+     */
+    virtual UBool        hasNext() = 0;
+    
+protected:
+    /** Default constructor to be overridden in the implementing class. @stable ICU 2.0*/
+    ForwardCharacterIterator();
+    
+    /** Copy constructor to be overridden in the implementing class. @stable ICU 2.0*/
+    ForwardCharacterIterator(const ForwardCharacterIterator &other);
+    
+    /**
+     * Assignment operator to be overridden in the implementing class.
+     * @stable ICU 2.0
+     */
+    ForwardCharacterIterator &operator=(const ForwardCharacterIterator&) { return *this; }
+};
+
+/**
+ * Abstract class that defines an API for iteration
+ * on text objects.
+ * This is an interface for forward and backward iteration
+ * and random access into a text object.
+ *
+ * <p>The API provides backward compatibility to the Java and older ICU
+ * CharacterIterator classes but extends them significantly:
+ * <ol>
+ * <li>CharacterIterator is now a subclass of ForwardCharacterIterator.</li>
+ * <li>While the old API functions provided forward iteration with
+ *     "pre-increment" semantics, the new one also provides functions
+ *     with "post-increment" semantics. They are more efficient and should
+ *     be the preferred iterator functions for new implementations.
+ *     The backward iteration always had "pre-decrement" semantics, which
+ *     are efficient.</li>
+ * <li>Just like ForwardCharacterIterator, it provides access to
+ *     both code units and code points. Code point access versions are available
+ *     for the old and the new iteration semantics.</li>
+ * <li>There are new functions for setting and moving the current position
+ *     without returning a character, for efficiency.</li>
+ * </ol>
+ *
+ * See ForwardCharacterIterator for examples for using the new forward iteration
+ * functions. For backward iteration, there is also a hasPrevious() function
+ * that can be used analogously to hasNext().
+ * The old functions work as before and are shown below.</p>
+ *
+ * <p>Examples for some of the new functions:</p>
+ *
+ * Forward iteration with hasNext():
+ * \code
+ * void forward1(CharacterIterator &it) {
+ *     UChar32 c;
+ *     for(it.setToStart(); it.hasNext();) {
+ *         c=it.next32PostInc();
+ *         // use c
+ *     }
+ *  }
+ * \endcode
+ * Forward iteration more similar to loops with the old forward iteration,
+ * showing a way to convert simple for() loops:
+ * \code
+ * void forward2(CharacterIterator &it) {
+ *     UChar c;
+ *     for(c=it.firstPostInc(); c!=CharacterIterator::DONE; c=it.nextPostInc()) {
+ *          // use c
+ *      }
+ * }
+ * \endcode
+ * Backward iteration with setToEnd() and hasPrevious():
+ * \code
+ *  void backward1(CharacterIterator &it) {
+ *      UChar32 c;
+ *      for(it.setToEnd(); it.hasPrevious();) {
+ *         c=it.previous32();
+ *          // use c
+ *      }
+ *  }
+ * \endcode
+ * Backward iteration with a more traditional for() loop:
+ * \code
+ * void backward2(CharacterIterator &it) {
+ *     UChar c;
+ *     for(c=it.last(); c!=CharacterIterator::DONE; c=it.previous()) {
+ *         // use c
+ *      }
+ *  }
+ * \endcode
+ *
+ * Example for random access:
+ * \code
+ *  void random(CharacterIterator &it) {
+ *      // set to the third code point from the beginning
+ *      it.move32(3, CharacterIterator::kStart);
+ *      // get a code point from here without moving the position
+ *      UChar32 c=it.current32();
+ *      // get the position
+ *      int32_t pos=it.getIndex();
+ *      // get the previous code unit
+ *      UChar u=it.previous();
+ *      // move back one more code unit
+ *      it.move(-1, CharacterIterator::kCurrent);
+ *      // set the position back to where it was
+ *      // and read the same code point c and move beyond it
+ *      it.setIndex(pos);
+ *      if(c!=it.next32PostInc()) {
+ *          exit(1); // CharacterIterator inconsistent
+ *      }
+ *  }
+ * \endcode
+ *
+ * <p>Examples, especially for the old API:</p>
+ *
+ * Function processing characters, in this example simple output
+ * <pre>
+ * \code
+ *  void processChar( UChar c )
+ *  {
+ *      cout << " " << c;
+ *  }
+ * \endcode
+ * </pre>
+ * Traverse the text from start to finish
+ * <pre> 
+ * \code
+ *  void traverseForward(CharacterIterator& iter)
+ *  {
+ *      for(UChar c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
+ *          processChar(c);
+ *      }
+ *  }
+ * \endcode
+ * </pre>
+ * Traverse the text backwards, from end to start
+ * <pre>
+ * \code
+ *  void traverseBackward(CharacterIterator& iter)
+ *  {
+ *      for(UChar c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) {
+ *          processChar(c);
+ *      }
+ *  }
+ * \endcode
+ * </pre>
+ * Traverse both forward and backward from a given position in the text. 
+ * Calls to notBoundary() in this example represents some additional stopping criteria.
+ * <pre>
+ * \code
+ * void traverseOut(CharacterIterator& iter, int32_t pos)
+ * {
+ *      UChar c;
+ *      for (c = iter.setIndex(pos);
+ *      c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c));
+ *          c = iter.next()) {}
+ *      int32_t end = iter.getIndex();
+ *      for (c = iter.setIndex(pos);
+ *          c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c));
+ *          c = iter.previous()) {}
+ *      int32_t start = iter.getIndex() + 1;
+ *  
+ *      cout << "start: " << start << " end: " << end << endl;
+ *      for (c = iter.setIndex(start); iter.getIndex() < end; c = iter.next() ) {
+ *          processChar(c);
+ *     }
+ *  }
+ * \endcode
+ * </pre>
+ * Creating a StringCharacterIterator and calling the test functions
+ * <pre>
+ * \code
+ *  void CharacterIterator_Example( void )
+ *   {
+ *       cout << endl << "===== CharacterIterator_Example: =====" << endl;
+ *       UnicodeString text("Ein kleiner Satz.");
+ *       StringCharacterIterator iterator(text);
+ *       cout << "----- traverseForward: -----------" << endl;
+ *       traverseForward( iterator );
+ *       cout << endl << endl << "----- traverseBackward: ----------" << endl;
+ *       traverseBackward( iterator );
+ *       cout << endl << endl << "----- traverseOut: ---------------" << endl;
+ *       traverseOut( iterator, 7 );
+ *       cout << endl << endl << "-----" << endl;
+ *   }
+ * \endcode
+ * </pre>
+ *
+ * @stable ICU 2.0
+ */
+class U_COMMON_API CharacterIterator : public ForwardCharacterIterator {
+public:
+    /**
+     * Origin enumeration for the move() and move32() functions.
+     * @stable ICU 2.0
+     */
+    enum EOrigin { kStart, kCurrent, kEnd };
+
+    /**
+     * Returns a pointer to a new CharacterIterator of the same
+     * concrete class as this one, and referring to the same
+     * character in the same text-storage object as this one.  The
+     * caller is responsible for deleting the new clone.  
+     * @return a pointer to a new CharacterIterator
+     * @stable ICU 2.0
+     */
+    virtual CharacterIterator* clone(void) const = 0;
+
+    /**
+     * Sets the iterator to refer to the first code unit in its
+     * iteration range, and returns that code unit.
+     * This can be used to begin an iteration with next().
+     * @return the first code unit in its iteration range.
+     * @stable ICU 2.0
+     */
+    virtual UChar         first(void) = 0;
+
+    /**
+     * Sets the iterator to refer to the first code unit in its
+     * iteration range, returns that code unit, and moves the position
+     * to the second code unit. This is an alternative to setToStart()
+     * for forward iteration with nextPostInc().
+     * @return the first code unit in its iteration range.
+     * @stable ICU 2.0
+     */
+    virtual UChar         firstPostInc(void);
+
+    /**
+     * Sets the iterator to refer to the first code point in its
+     * iteration range, and returns that code unit,
+     * This can be used to begin an iteration with next32().
+     * Note that an iteration with next32PostInc(), beginning with,
+     * e.g., setToStart() or firstPostInc(), is more efficient.
+     * @return the first code point in its iteration range.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       first32(void) = 0;
+
+    /**
+     * Sets the iterator to refer to the first code point in its
+     * iteration range, returns that code point, and moves the position
+     * to the second code point. This is an alternative to setToStart()
+     * for forward iteration with next32PostInc().
+     * @return the first code point in its iteration range.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       first32PostInc(void);
+
+    /**
+     * Sets the iterator to refer to the first code unit or code point in its
+     * iteration range. This can be used to begin a forward
+     * iteration with nextPostInc() or next32PostInc().
+     * @return the start position of the iteration range
+     * @stable ICU 2.0
+     */
+    inline int32_t    setToStart();
+
+    /**
+     * Sets the iterator to refer to the last code unit in its
+     * iteration range, and returns that code unit.
+     * This can be used to begin an iteration with previous().
+     * @return the last code unit.
+     * @stable ICU 2.0
+     */
+    virtual UChar         last(void) = 0;
+        
+    /**
+     * Sets the iterator to refer to the last code point in its
+     * iteration range, and returns that code unit.
+     * This can be used to begin an iteration with previous32().
+     * @return the last code point.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       last32(void) = 0;
+
+    /**
+     * Sets the iterator to the end of its iteration range, just behind
+     * the last code unit or code point. This can be used to begin a backward
+     * iteration with previous() or previous32().
+     * @return the end position of the iteration range
+     * @stable ICU 2.0
+     */
+    inline int32_t    setToEnd();
+
+    /**
+     * Sets the iterator to refer to the "position"-th code unit
+     * in the text-storage object the iterator refers to, and
+     * returns that code unit.  
+     * @param position the "position"-th code unit in the text-storage object
+     * @return the "position"-th code unit.
+     * @stable ICU 2.0
+     */
+    virtual UChar         setIndex(int32_t position) = 0;
+
+    /**
+     * Sets the iterator to refer to the beginning of the code point
+     * that contains the "position"-th code unit
+     * in the text-storage object the iterator refers to, and
+     * returns that code point.
+     * The current position is adjusted to the beginning of the code point
+     * (its first code unit).
+     * @param position the "position"-th code unit in the text-storage object
+     * @return the "position"-th code point.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       setIndex32(int32_t position) = 0;
+
+    /**
+     * Returns the code unit the iterator currently refers to. 
+     * @return the current code unit. 
+     * @stable ICU 2.0
+     */
+    virtual UChar         current(void) const = 0;
+        
+    /**
+     * Returns the code point the iterator currently refers to.  
+     * @return the current code point.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       current32(void) const = 0;
+        
+    /**
+     * Advances to the next code unit in the iteration range
+     * (toward endIndex()), and returns that code unit.  If there are
+     * no more code units to return, returns DONE.
+     * @return the next code unit.
+     * @stable ICU 2.0
+     */
+    virtual UChar         next(void) = 0;
+        
+    /**
+     * Advances to the next code point in the iteration range
+     * (toward endIndex()), and returns that code point.  If there are
+     * no more code points to return, returns DONE.
+     * Note that iteration with "pre-increment" semantics is less
+     * efficient than iteration with "post-increment" semantics
+     * that is provided by next32PostInc().
+     * @return the next code point.
+     * @stable ICU 2.0
+     */
+    virtual UChar32       next32(void) = 0;
+        
+    /**
+     * Advances to the previous code unit in the iteration range
+     * (toward startIndex()), and returns that code unit.  If there are
+     * no more code units to return, returns DONE.  
+     * @return the previous code unit.
+     * @stable ICU 2.0
+     */
+    virtual UChar         previous(void) = 0;
+
+    /**
+     * Advances to the previous code point in the iteration range
+     * (toward startIndex()), and returns that code point.  If there are
+     * no more code points to return, returns DONE. 
+     * @return the previous code point. 
+     * @stable ICU 2.0
+     */
+    virtual UChar32       previous32(void) = 0;
+
+    /**
+     * Returns FALSE if there are no more code units or code points
+     * before the current position in the iteration range.
+     * This is used with previous() or previous32() in backward
+     * iteration.
+     * @return FALSE if there are no more code units or code points
+     * before the current position in the iteration range, return TRUE otherwise.
+     * @stable ICU 2.0
+     */
+    virtual UBool        hasPrevious() = 0;
+
+    /**
+     * Returns the numeric index in the underlying text-storage
+     * object of the character returned by first().  Since it's
+     * possible to create an iterator that iterates across only
+     * part of a text-storage object, this number isn't
+     * necessarily 0.  
+     * @returns the numeric index in the underlying text-storage
+     * object of the character returned by first().
+     * @stable ICU 2.0
+     */
+    inline int32_t       startIndex(void) const;
+        
+    /**
+     * Returns the numeric index in the underlying text-storage
+     * object of the position immediately BEYOND the character
+     * returned by last().  
+     * @return the numeric index in the underlying text-storage
+     * object of the position immediately BEYOND the character
+     * returned by last().
+     * @stable ICU 2.0
+     */
+    inline int32_t       endIndex(void) const;
+        
+    /**
+     * Returns the numeric index in the underlying text-storage
+     * object of the character the iterator currently refers to
+     * (i.e., the character returned by current()).  
+     * @return the numberic index in the text-storage object of 
+     * the character the iterator currently refers to
+     * @stable ICU 2.0
+     */
+    inline int32_t       getIndex(void) const;
+
+    /**
+     * Returns the length of the entire text in the underlying
+     * text-storage object.
+     * @return the length of the entire text in the text-storage object
+     * @stable ICU 2.0
+     */
+    inline int32_t           getLength() const;
+
+    /**
+     * Moves the current position relative to the start or end of the
+     * iteration range, or relative to the current position itself.
+     * The movement is expressed in numbers of code units forward
+     * or backward by specifying a positive or negative delta.
+     * @param delta the position relative to origin. A positive delta means forward;
+     * a negative delta means backward.
+     * @param origin Origin enumeration {kStart, kCurrent, kEnd}
+     * @return the new position
+     * @stable ICU 2.0
+     */
+    virtual int32_t      move(int32_t delta, EOrigin origin) = 0;
+
+    /**
+     * Moves the current position relative to the start or end of the
+     * iteration range, or relative to the current position itself.
+     * The movement is expressed in numbers of code points forward
+     * or backward by specifying a positive or negative delta.
+     * @param delta the position relative to origin. A positive delta means forward;
+     * a negative delta means backward.
+     * @param origin Origin enumeration {kStart, kCurrent, kEnd}
+     * @return the new position
+     * @stable ICU 2.0
+     */
+    virtual int32_t      move32(int32_t delta, EOrigin origin) = 0;
+
+    /**
+     * Copies the text under iteration into the UnicodeString
+     * referred to by "result".  
+     * @param result Receives a copy of the text under iteration.  
+     * @stable ICU 2.0
+     */
+    virtual void            getText(UnicodeString&  result) = 0;
+
+protected:
+    /**
+     * Empty constructor.
+     * @stable ICU 2.0
+     */
+    CharacterIterator();
+
+    /**
+     * Constructor, just setting the length field in this base class.
+     * @stable ICU 2.0
+     */
+    CharacterIterator(int32_t length);
+
+    /**
+     * Constructor, just setting the length and position fields in this base class.
+     * @stable ICU 2.0
+     */
+    CharacterIterator(int32_t length, int32_t position);
+
+    /**
+     * Constructor, just setting the length, start, end, and position fields in this base class.
+     * @stable ICU 2.0
+     */
+    CharacterIterator(int32_t length, int32_t textBegin, int32_t textEnd, int32_t position);
+  
+    /**
+     * Copy constructor.
+     *
+     * @param that The CharacterIterator to be copied
+     * @stable ICU 2.0
+     */
+    CharacterIterator(const CharacterIterator &that);
+
+    /**
+     * Assignment operator.  Sets this CharacterIterator to have the same behavior,
+     * as the one passed in.
+     * @param that The CharacterIterator passed in.
+     * @return the newly set CharacterIterator.
+     * @stable ICU 2.0
+     */
+    CharacterIterator &operator=(const CharacterIterator &that);
+
+    /**
+     * Base class text length field.
+     * Necessary this for correct getText() and hashCode().
+     * @stable ICU 2.0
+     */
+    int32_t textLength;
+
+    /**
+     * Base class field for the current position.
+     * @stable ICU 2.0
+     */
+    int32_t  pos;
+
+    /**
+     * Base class field for the start of the iteration range.
+     * @stable ICU 2.0
+     */
+    int32_t  begin;
+
+    /**
+     * Base class field for the end of the iteration range.
+     * @stable ICU 2.0
+     */
+    int32_t  end;
+};
+
+inline UBool
+ForwardCharacterIterator::operator!=(const ForwardCharacterIterator& that) const {
+    return !operator==(that);
+}
+
+inline int32_t
+CharacterIterator::setToStart() {
+    return move(0, kStart);
+}
+
+inline int32_t
+CharacterIterator::setToEnd() {
+    return move(0, kEnd);
+}
+
+inline int32_t
+CharacterIterator::startIndex(void) const {
+    return begin;
+}
+
+inline int32_t
+CharacterIterator::endIndex(void) const {
+    return end;
+}
+
+inline int32_t
+CharacterIterator::getIndex(void) const {
+    return pos;
+}
+
+inline int32_t
+CharacterIterator::getLength(void) const {
+    return textLength;
+}
+
+U_NAMESPACE_END
+#endif

Added: MacRuby/branches/icu/unicode/dbbi.h
===================================================================
--- MacRuby/branches/icu/unicode/dbbi.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/dbbi.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,41 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2006 IBM Corp. All rights reserved.
+**********************************************************************
+*   Date        Name        Description
+*   12/1/99    rgillam     Complete port from Java.
+*   01/13/2000 helena      Added UErrorCode to ctors.
+**********************************************************************
+*/
+
+#ifndef DBBI_H
+#define DBBI_H
+
+#include "unicode/rbbi.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+/**
+ * \file
+ * \brief C++ API: Dictionary Based Break Iterator
+ */
+ 
+U_NAMESPACE_BEGIN
+
+/**
+ * An obsolete subclass of RuleBasedBreakIterator. Handling of dictionary-
+ * based break iteration has been folded into the base class. This class
+ * is deprecated as of ICU 3.6.
+ */
+ 
+#ifndef U_HIDE_DEPRECATED_API
+
+typedef RuleBasedBreakIterator DictionaryBasedBreakIterator;
+
+#endif
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
+#endif

Added: MacRuby/branches/icu/unicode/docmain.h
===================================================================
--- MacRuby/branches/icu/unicode/docmain.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/docmain.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,202 @@
+/********************************************************************
+ * COPYRIGHT: 
+ * Copyright (c) 1997-2005, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ *
+ *  FILE NAME: DOCMAIN.h
+ *
+ *   Date          Name        Description
+ *   12/11/2000    Ram        Creation.
+ */
+
+/* This file contains documentation for Doxygen and doesnot have
+ * any significance with respect to C or C++ API
+ */
+
+/*! \mainpage
+ *
+ * \section API API Reference Usage
+ * 
+ * <h3>C++ Programmers:</h3>
+ * <p>Use <a href="hierarchy.html">Class Hierarchy</a> or <a href="classes.html"> Alphabetical List </a>
+ * or <a href="annotated.html"> Compound List</a>
+ * to find the class you are interested in. For example, to find BreakIterator,
+ * you can go to the <a href="classes.html"> Alphabetical List</a>, then click on
+ * "BreakIterator". Once you are at the class, you will find an inheritance
+ * chart, a list of the public members, a detailed description of the class,
+ * then detailed member descriptions.</p>
+ * 
+ * <h3>C Programmers:</h3>
+ * <p>Use <a href="#Module">Module List</a> or <a href="globals.html">File Members</a>
+ * to find a list of all the functions and constants.
+ * For example, to find BreakIterator functions you would click on
+ * <a href="files.html"> File List</a>,
+ * then find "ubrk.h" and click on it. You will find descriptions of Defines,
+ * Typedefs, Enumerations, and Functions, with detailed descriptions below.
+ * If you want to find a specific function, such as ubrk_next(), then click
+ * first on <a href="globals.html"> File Members</a>, then use your browser
+ * Find dialog to search for "ubrk_next()".</p>
+ *
+ *
+ * <h3>API References for Previous Releases</h3>
+ * <p>The API References for each release of ICU are also available as
+ * a zip file from the ICU 
+ * <a href="http://www.ibm.com/software/globalization/icu/downloads.jsp">download page</a>.</p>
+ *
+ * <hr>
+ *
+ * <h2>Architecture (User's Guide)</h2>
+ * <ul>
+ *   <li><a href="http://icu.sourceforge.net/userguide/">Introduction</a></li>
+ *   <li><a href="http://icu.sourceforge.net/userguide/i18n.html">Internationalization</a></li>
+ *   <li><a href="http://icu.sourceforge.net/userguide/design.html">Locale Model</a></li>
+ *   <li><a href="http://icu.sourceforge.net/userguide/design.html">Multithreading</a></li>
+ *   <li><a href="http://icu.sourceforge.net/userguide/conversion.html">Conversion</a></li>
+ *   <li><a href="http://icu.sourceforge.net/userguide/design.html">Error Handling</a></li>
+ * </ul>
+ *
+ * <hr>
+ *\htmlonly <h2><a NAME="Module">Module List</a></h2> \endhtmlonly
+ * <table border="1" cols="3" align="center">
+ *   <tr>
+ *     <td><strong>Module Name</strong></td>
+ *     <td><strong>C</strong></td>
+ *     <td><strong>C++</strong></td>
+ *   </tr>
+ *   <tr>
+ *     <td>Basic Types and Constants</td>
+ *     <td>utypes.h</td>
+ *     <td>utypes.h</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Strings and Character Iteration</td>
+ *     <td>ustring.h, utf.h</td>
+ *     <td>UnicodeString, CharacterIterator</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Unicode Character<br>Properties and Names</td>
+ *     <td>uchar.h</td>
+ *     <td>uchar.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Codepage Conversion</td>
+ *     <td>ucnv.h</td>
+ *     <td>ucnv.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Unicode Text Compression</td>
+ *     <td>ucnv.h <br> (encoding name "SCSU" or "BOCU-1")</td>
+ *     <td>ucnv.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Locales </td>
+ *     <td>uloc.h</a></td>
+ *     <td>Locale</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Resource Bundles</td>
+ *     <td>ures.h</td>
+ *     <td>ResourceBundle</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Normalization</td>
+ *     <td>unorm.h</td>
+ *     <td>Normalizer</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Calendars</td>
+ *     <td>ucal.h</td>
+ *     <td>Calendar</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Date and Time Formatting</td>
+ *     <td>udat.h</td>
+ *     <td>DateFormat</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Message Formatting</td>
+ *     <td>umsg.h</td>
+ *     <td>MessageFormat</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Number Formatting</td>
+ *     <td>unum.h</td>
+ *     <td>NumberFormat</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Number Spellout <br> (Rule Based Number Formatting)</td>
+ *     <td>unum.h <br> (use UNUM_SPELLOUT)</td>
+ *     <td>RuleBasedNumberFormat</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Text Transformation <br> (Transliteration)</td>
+ *     <td>utrans.h</td>
+ *     <td>Transliterator</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Bidirectional Algorithm</td>
+ *     <td>ubidi.h</td>
+ *     <td>ubidi.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Arabic Shaping</td>
+ *     <td>ushape.h</td>
+ *     <td>ushape.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Collation</td>
+ *     <td>ucol.h</td>
+ *     <td>Collator</td>
+ *   </tr>
+ *   <tr>
+ *     <td>String Searching</td>
+ *     <td>usearch.h</td>
+ *     <td>StringSearch</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Text Boundary Analysis <br> (Break Iteration)</td>
+ *     <td>ubrk.h</td>
+ *     <td>BreakIterator</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Unicode Set</td>
+ *     <td>uset.h</td>
+ *     <td>UnicodeSet</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Regular Expressions</td>
+ *     <td>uregex.h</td>
+ *     <td>RegexPattern, RegexMatcher</td>
+ *   </tr>
+ *   <tr>
+ *     <td>StringPrep</td>
+ *     <td>usprep.h</td>
+ *     <td>usprep.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>International Domain Names in Applications</td>
+ *     <td>uidna.h</td>
+ *     <td>uidna.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Universal Time Scale</td>
+ *     <td>utmscale.h</td>
+ *     <td>utmscale.h C API</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Basic Layout Engine Types and Constants</td>
+ *     <td>(no C API)</td>
+ *     <td>LETypes.h</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Complex Text Layout</td>
+ *     <td>(no C API)</td>
+ *     <td>LayoutEngine, ParagraphLayout</td>
+ *   </tr>
+ *   <tr>
+ *     <td>ICU I/O</td>
+ *     <td>ustdio.h</td>
+ *     <td>ustream.h</td>
+ *   </tr>
+ * </table>
+ */

Added: MacRuby/branches/icu/unicode/locid.h
===================================================================
--- MacRuby/branches/icu/unicode/locid.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/locid.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,765 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1996-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File locid.h
+*
+* Created by: Helena Shih
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   02/11/97    aliu        Changed gLocPath to fgLocPath and added methods to
+*                           get and set it.
+*   04/02/97    aliu        Made operator!= inline; fixed return value of getName().
+*   04/15/97    aliu        Cleanup for AIX/Win32.
+*   04/24/97    aliu        Numerous changes per code review.
+*   08/18/98    stephen     Added tokenizeString(),changed getDisplayName()
+*   09/08/98    stephen     Moved definition of kEmptyString for Mac Port
+*   11/09/99    weiv        Added const char * getName() const;
+*   04/12/00    srl         removing unicodestring api's and cached hash code
+*   08/10/01    grhoten     Change the static Locales to accessor functions
+******************************************************************************
+*/
+
+#ifndef LOCID_H
+#define LOCID_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+#include "unicode/putil.h"
+#include "unicode/uloc.h"
+#include "unicode/strenum.h"
+
+/**
+ * \file
+ * \brief C++ API: Locale ID object.
+ */
+
+/**
+ * A <code>Locale</code> object represents a specific geographical, political,
+ * or cultural region. An operation that requires a <code>Locale</code> to perform
+ * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
+ * to tailor information for the user. For example, displaying a number
+ * is a locale-sensitive operation--the number should be formatted
+ * according to the customs/conventions of the user's native country,
+ * region, or culture.
+ *
+ * The Locale class is not suitable for subclassing.
+ *
+ * <P>
+ * You can create a <code>Locale</code> object using the constructor in
+ * this class:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ *       Locale( const   char*  language,
+ *               const   char*  country,
+ *               const   char*  variant);
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * The first argument to the constructors is a valid <STRONG>ISO
+ * Language Code.</STRONG> These codes are the lower-case two-letter
+ * codes as defined by ISO-639.
+ * You can find a full list of these codes at:
+ * <BR><a href ="http://www.loc.gov/standards/iso639-2/">
+ * http://www.loc.gov/standards/iso639-2/</a>
+ *
+ * <P>
+ * The second argument to the constructors is a valid <STRONG>ISO Country
+ * Code.</STRONG> These codes are the upper-case two-letter codes
+ * as defined by ISO-3166.
+ * You can find a full list of these codes at a number of sites, such as:
+ * <BR><a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
+ * http://www.iso.org/iso/en/prods-services/iso3166ma/index.html</a>
+ *
+ * <P>
+ * The third constructor requires a third argument--the <STRONG>Variant.</STRONG>
+ * The Variant codes are vendor and browser-specific.
+ * For example, use REVISED for a langauge's revised script orthography, and POSIX for POSIX.
+ * Where there are two variants, separate them with an underscore, and
+ * put the most important one first. For
+ * example, a Traditional Spanish collation might be referenced, with
+ * "ES", "ES", "Traditional_POSIX".
+ *
+ * <P>
+ * Because a <code>Locale</code> object is just an identifier for a region,
+ * no validity check is performed when you construct a <code>Locale</code>.
+ * If you want to see whether particular resources are available for the
+ * <code>Locale</code> you construct, you must query those resources. For
+ * example, ask the <code>NumberFormat</code> for the locales it supports
+ * using its <code>getAvailableLocales</code> method.
+ * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular
+ * locale, you get back the best available match, not necessarily
+ * precisely what you asked for. For more information, look at
+ * <code>ResourceBundle</code>.
+ *
+ * <P>
+ * The <code>Locale</code> class provides a number of convenient constants
+ * that you can use to create <code>Locale</code> objects for commonly used
+ * locales. For example, the following refers to a <code>Locale</code> object
+ * for the United States:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ *       Locale::getUS()
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ *
+ * <P>
+ * Once you've created a <code>Locale</code> you can query it for information about
+ * itself. Use <code>getCountry</code> to get the ISO Country Code and
+ * <code>getLanguage</code> to get the ISO Language Code. You can
+ * use <code>getDisplayCountry</code> to get the
+ * name of the country suitable for displaying to the user. Similarly,
+ * you can use <code>getDisplayLanguage</code> to get the name of
+ * the language suitable for displaying to the user. Interestingly,
+ * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
+ * and have two versions: one that uses the default locale and one
+ * that takes a locale as an argument and displays the name or country in
+ * a language appropriate to that locale.
+ *
+ * <P>
+ * ICU provides a number of classes that perform locale-sensitive
+ * operations. For example, the <code>NumberFormat</code> class formats
+ * numbers, currency, or percentages in a locale-sensitive manner. Classes
+ * such as <code>NumberFormat</code> have a number of convenience methods
+ * for creating a default object of that type. For example, the
+ * <code>NumberFormat</code> class provides these three convenience methods
+ * for creating a default <code>NumberFormat</code> object:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ *     UErrorCode success = U_ZERO_ERROR;
+ *     Locale myLocale;
+ *     NumberFormat *nf;
+ *
+ *     nf = NumberFormat::createInstance( success );          delete nf;
+ *     nf = NumberFormat::createCurrencyInstance( success );  delete nf;
+ *     nf = NumberFormat::createPercentInstance( success );   delete nf;
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * Each of these methods has two variants; one with an explicit locale
+ * and one without; the latter using the default locale.
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ *     nf = NumberFormat::createInstance( myLocale, success );          delete nf;
+ *     nf = NumberFormat::createCurrencyInstance( myLocale, success );  delete nf;
+ *     nf = NumberFormat::createPercentInstance( myLocale, success );   delete nf;
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * A <code>Locale</code> is the mechanism for identifying the kind of object
+ * (<code>NumberFormat</code>) that you would like to get. The locale is
+ * <STRONG>just</STRONG> a mechanism for identifying objects,
+ * <STRONG>not</STRONG> a container for the objects themselves.
+ *
+ * <P>
+ * Each class that performs locale-sensitive operations allows you
+ * to get all the available objects of that type. You can sift
+ * through these objects by language, country, or variant,
+ * and use the display names to present a menu to the user.
+ * For example, you can create a menu of all the collation objects
+ * suitable for a given language. Such classes implement these
+ * three class methods:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ *       static Locale* getAvailableLocales(int32_t& numLocales)
+ *       static UnicodeString& getDisplayName(const Locale&  objectLocale,
+ *                                            const Locale&  displayLocale,
+ *                                            UnicodeString& displayName)
+ *       static UnicodeString& getDisplayName(const Locale&  objectLocale,
+ *                                            UnicodeString& displayName)
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ *
+ * @stable ICU 2.0
+ * @see ResourceBundle
+ */
+U_NAMESPACE_BEGIN
+class U_COMMON_API Locale : public UObject {
+public:
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getEnglish(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getFrench(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getGerman(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getItalian(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getJapanese(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getKorean(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getChinese(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getSimplifiedChinese(void);
+    /** Useful constant for this language. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getTraditionalChinese(void);
+
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getFrance(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getGermany(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getItaly(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getJapan(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getKorea(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getChina(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getPRC(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getTaiwan(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getUK(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getUS(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getCanada(void);
+    /** Useful constant for this country/region. @stable ICU 2.0 */
+    static const Locale &U_EXPORT2 getCanadaFrench(void);
+
+
+    /**
+     * Construct a default locale object, a Locale for the default locale ID.
+     *
+     * @see getDefault
+     * @see uloc_getDefault
+     * @stable ICU 2.0
+     */
+    Locale();
+
+    /**
+     * Construct a locale from language, country, variant.
+     * If an error occurs, then the constructed object will be "bogus"
+     * (isBogus() will return TRUE).
+     *
+     * @param language Lowercase two-letter or three-letter ISO-639 code.
+     *  This parameter can instead be an ICU style C locale (e.g. "en_US"),
+     *  but the other parameters must not be used.
+     *  This parameter can be NULL; if so,
+     *  the locale is initialized to match the current default locale.
+     *  (This is the same as using the default constructor.)
+     *  Please note: The Java Locale class does NOT accept the form
+     *  'new Locale("en_US")' but only 'new Locale("en","US")'
+     *
+     * @param country  Uppercase two-letter ISO-3166 code. (optional)
+     * @param variant  Uppercase vendor and browser specific code. See class
+     *                 description. (optional)
+     * @param keywordsAndValues A string consisting of keyword/values pairs, such as
+     *                 "collation=phonebook;currency=euro"
+     *
+     * @see getDefault
+     * @see uloc_getDefault
+     * @stable ICU 2.0
+     */
+    Locale( const   char * language,
+            const   char * country  = 0,
+            const   char * variant  = 0,
+            const   char * keywordsAndValues = 0);
+
+    /**
+     * Initializes a Locale object from another Locale object.
+     *
+     * @param other The Locale object being copied in.
+     * @stable ICU 2.0
+     */
+    Locale(const    Locale& other);
+
+
+    /**
+     * Destructor
+     * @stable ICU 2.0
+     */
+    virtual ~Locale() ;
+
+    /**
+     * Replaces the entire contents of *this with the specified value.
+     *
+     * @param other The Locale object being copied in.
+     * @return      *this
+     * @stable ICU 2.0
+     */
+    Locale& operator=(const Locale& other);
+
+    /**
+     * Checks if two locale keys are the same.
+     *
+     * @param other The locale key object to be compared with this.
+     * @return      True if the two locale keys are the same, false otherwise.
+     * @stable ICU 2.0
+     */
+    UBool   operator==(const    Locale&     other) const;
+
+    /**
+     * Checks if two locale keys are not the same.
+     *
+     * @param other The locale key object to be compared with this.
+     * @return      True if the two locale keys are not the same, false
+     *              otherwise.
+     * @stable ICU 2.0
+     */
+    UBool   operator!=(const    Locale&     other) const;
+
+    /**
+     * Clone this object.
+     * Clones can be used concurrently in multiple threads.
+     * If an error occurs, then NULL is returned.
+     * The caller must delete the clone.
+     *
+     * @return a clone of this object
+     *
+     * @see getDynamicClassID
+     * @stable ICU 2.8
+     */
+    Locale *clone() const;
+
+    /**
+     * Common methods of getting the current default Locale. Used for the
+     * presentation: menus, dialogs, etc. Generally set once when your applet or
+     * application is initialized, then never reset. (If you do reset the
+     * default locale, you probably want to reload your GUI, so that the change
+     * is reflected in your interface.)
+     *
+     * More advanced programs will allow users to use different locales for
+     * different fields, e.g. in a spreadsheet.
+     *
+     * Note that the initial setting will match the host system.
+     * @return a reference to the Locale object for the default locale ID
+     * @system
+     * @stable ICU 2.0
+     */
+    static const Locale& U_EXPORT2 getDefault(void);
+
+    /**
+     * Sets the default. Normally set once at the beginning of a process,
+     * then never reset.
+     * setDefault() only changes ICU's default locale ID, <strong>not</strong>
+     * the default locale ID of the runtime environment.
+     *
+     * @param newLocale Locale to set to.  If NULL, set to the value obtained
+     *                  from the runtime environement.
+     * @param success The error code.
+     * @system
+     * @stable ICU 2.0
+     */
+    static void U_EXPORT2 setDefault(const Locale& newLocale,
+                                     UErrorCode&   success);
+
+    /**
+     * Creates a locale which has had minimal canonicalization
+     * as per uloc_getName().
+     * @param name The name to create from.  If name is null,
+     *  the default Locale is used.
+     * @return new locale object
+     * @stable ICU 2.0
+     * @see uloc_getName
+     */
+    static Locale U_EXPORT2 createFromName(const char *name);
+
+    /**
+     * Creates a locale from the given string after canonicalizing
+     * the string by calling uloc_canonicalize().
+     * @param name the locale ID to create from.  Must not be NULL.
+     * @return a new locale object corresponding to the given name
+     * @stable ICU 3.0
+     * @see uloc_canonicalize
+     */
+    static Locale U_EXPORT2 createCanonical(const char* name);
+
+    /**
+     * Returns the locale's ISO-639 language code.
+     * @return      An alias to the code
+     * @stable ICU 2.0
+     */
+    inline const char *  getLanguage( ) const;
+
+    /**
+     * Returns the locale's ISO-15924 abbreviation script code.
+     * @return      An alias to the code
+     * @see uscript_getShortName
+     * @see uscript_getCode
+     * @stable ICU 2.8
+     */
+    inline const char *  getScript( ) const;
+
+    /**
+     * Returns the locale's ISO-3166 country code.
+     * @return      An alias to the code
+     * @stable ICU 2.0
+     */
+    inline const char *  getCountry( ) const;
+
+    /**
+     * Returns the locale's variant code.
+     * @return      An alias to the code
+     * @stable ICU 2.0
+     */
+    inline const char *  getVariant( ) const;
+
+    /**
+     * Returns the programmatic name of the entire locale, with the language,
+     * country and variant separated by underbars. If a field is missing, up
+     * to two leading underbars will occur. Example: "en", "de_DE", "en_US_WIN",
+     * "de__POSIX", "fr__MAC", "__MAC", "_MT", "_FR_EURO"
+     * @return      A pointer to "name".
+     * @stable ICU 2.0
+     */
+    inline const char * getName() const;
+
+    /**
+     * Returns the programmatic name of the entire locale as getName would return,
+     * but without keywords.
+     * @return      A pointer to "name".
+     * @see getName
+     * @stable ICU 2.8
+     */
+    const char * getBaseName() const;
+
+
+    /**
+     * Gets the list of keywords for the specified locale.
+     *
+     * @return pointer to StringEnumeration class. Client must dispose of it by calling delete.
+     * @param status Returns any error information while performing this operation.
+     * @stable ICU 2.8
+     */
+    StringEnumeration * createKeywords(UErrorCode &status) const;
+
+    /**
+     * Get the value for a keyword.
+     *
+     * @param keywordName name of the keyword for which we want the value. Case insensitive.
+     * @param status Returns any error information while performing this operation.
+     * @param buffer The buffer to receive the keyword value.
+     * @param bufferCapacity The capacity of receiving buffer
+     * @return the length of keyword value
+     *
+     * @stable ICU 2.8
+     */
+    int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufferCapacity, UErrorCode &status) const;
+
+    /**
+     * returns the locale's three-letter language code, as specified
+     * in ISO draft standard ISO-639-2.
+     * @return      An alias to the code, or NULL
+     * @stable ICU 2.0
+     */
+    const char * getISO3Language() const;
+
+    /**
+     * Fills in "name" with the locale's three-letter ISO-3166 country code.
+     * @return      An alias to the code, or NULL
+     * @stable ICU 2.0
+     */
+    const char * getISO3Country() const;
+
+    /**
+     * Returns the Windows LCID value corresponding to this locale.
+     * This value is stored in the resource data for the locale as a one-to-four-digit
+     * hexadecimal number.  If the resource is missing, in the wrong format, or
+     * there is no Windows LCID value that corresponds to this locale, returns 0.
+     * @stable ICU 2.0
+     */
+    uint32_t        getLCID(void) const;
+
+    /**
+     * Fills in "dispLang" with the name of this locale's language in a format suitable for
+     * user display in the default locale.  For example, if the locale's language code is
+     * "fr" and the default locale's language code is "en", this function would set
+     * dispLang to "French".
+     * @param dispLang  Receives the language's display name.
+     * @return          A reference to "dispLang".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayLanguage(UnicodeString&   dispLang) const;
+
+    /**
+     * Fills in "dispLang" with the name of this locale's language in a format suitable for
+     * user display in the locale specified by "displayLocale".  For example, if the locale's
+     * language code is "en" and displayLocale's language code is "fr", this function would set
+     * dispLang to "Anglais".
+     * @param displayLocale  Specifies the locale to be used to display the name.  In other words,
+     *                  if the locale's language code is "en", passing Locale::getFrench() for
+     *                  displayLocale would result in "Anglais", while passing Locale::getGerman()
+     *                  for displayLocale would result in "Englisch".
+     * @param dispLang  Receives the language's display name.
+     * @return          A reference to "dispLang".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayLanguage( const   Locale&         displayLocale,
+                                                UnicodeString&  dispLang) const;
+
+    /**
+     * Fills in "dispScript" with the name of this locale's script in a format suitable
+     * for user display in the default locale.  For example, if the locale's script code
+     * is "LATN" and the default locale's language code is "en", this function would set
+     * dispScript to "Latin".
+     * @param dispScript    Receives the scripts's display name.
+     * @return              A reference to "dispScript".
+     * @stable ICU 2.8
+     */
+    UnicodeString&  getDisplayScript(          UnicodeString& dispScript) const;
+
+    /**
+     * Fills in "dispScript" with the name of this locale's country in a format suitable
+     * for user display in the locale specified by "displayLocale".  For example, if the locale's
+     * script code is "LATN" and displayLocale's language code is "en", this function would set
+     * dispScript to "Latin".
+     * @param displayLocale      Specifies the locale to be used to display the name.  In other
+     *                      words, if the locale's script code is "LATN", passing
+     *                      Locale::getFrench() for displayLocale would result in "", while
+     *                      passing Locale::getGerman() for displayLocale would result in
+     *                      "".
+     * @param dispScript    Receives the scripts's display name.
+     * @return              A reference to "dispScript".
+     * @stable ICU 2.8
+     */
+    UnicodeString&  getDisplayScript(  const   Locale&         displayLocale,
+                                               UnicodeString&  dispScript) const;
+
+    /**
+     * Fills in "dispCountry" with the name of this locale's country in a format suitable
+     * for user display in the default locale.  For example, if the locale's country code
+     * is "FR" and the default locale's language code is "en", this function would set
+     * dispCountry to "France".
+     * @param dispCountry   Receives the country's display name.
+     * @return              A reference to "dispCountry".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayCountry(          UnicodeString& dispCountry) const;
+
+    /**
+     * Fills in "dispCountry" with the name of this locale's country in a format suitable
+     * for user display in the locale specified by "displayLocale".  For example, if the locale's
+     * country code is "US" and displayLocale's language code is "fr", this function would set
+     * dispCountry to "&Eacute;tats-Unis".
+     * @param displayLocale      Specifies the locale to be used to display the name.  In other
+     *                      words, if the locale's country code is "US", passing
+     *                      Locale::getFrench() for displayLocale would result in "&Eacute;tats-Unis", while
+     *                      passing Locale::getGerman() for displayLocale would result in
+     *                      "Vereinigte Staaten".
+     * @param dispCountry   Receives the country's display name.
+     * @return              A reference to "dispCountry".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayCountry(  const   Locale&         displayLocale,
+                                                UnicodeString&  dispCountry) const;
+
+    /**
+     * Fills in "dispVar" with the name of this locale's variant code in a format suitable
+     * for user display in the default locale.
+     * @param dispVar   Receives the variant's name.
+     * @return          A reference to "dispVar".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayVariant(      UnicodeString& dispVar) const;
+
+    /**
+     * Fills in "dispVar" with the name of this locale's variant code in a format
+     * suitable for user display in the locale specified by "displayLocale".
+     * @param displayLocale  Specifies the locale to be used to display the name.
+     * @param dispVar   Receives the variant's display name.
+     * @return          A reference to "dispVar".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayVariant(  const   Locale&         displayLocale,
+                                                UnicodeString&  dispVar) const;
+
+    /**
+     * Fills in "name" with the name of this locale in a format suitable for user display
+     * in the default locale.  This function uses getDisplayLanguage(), getDisplayCountry(),
+     * and getDisplayVariant() to do its work, and outputs the display name in the format
+     * "language (country[,variant])".  For example, if the default locale is en_US, then
+     * fr_FR's display name would be "French (France)", and es_MX_Traditional's display name
+     * would be "Spanish (Mexico,Traditional)".
+     * @param name  Receives the locale's display name.
+     * @return      A reference to "name".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayName(         UnicodeString&  name) const;
+
+    /**
+     * Fills in "name" with the name of this locale in a format suitable for user display
+     * in the locale specfied by "displayLocale".  This function uses getDisplayLanguage(),
+     * getDisplayCountry(), and getDisplayVariant() to do its work, and outputs the display
+     * name in the format "language (country[,variant])".  For example, if displayLocale is
+     * fr_FR, then en_US's display name would be "Anglais (&Eacute;tats-Unis)", and no_NO_NY's
+     * display name would be "norv&eacute;gien (Norv&egrave;ge,NY)".
+     * @param displayLocale  Specifies the locale to be used to display the name.
+     * @param name      Receives the locale's display name.
+     * @return          A reference to "name".
+     * @stable ICU 2.0
+     */
+    UnicodeString&  getDisplayName( const   Locale&         displayLocale,
+                                            UnicodeString&  name) const;
+
+    /**
+     * Generates a hash code for the locale.
+     * @stable ICU 2.0
+     */
+    int32_t         hashCode(void) const;
+
+    /**
+     * Sets the locale to bogus
+     * A bogus locale represents a non-existing locale associated
+     * with services that can be instantiated from non-locale data
+     * in addition to locale (for example, collation can be
+     * instantiated from a locale and from a rule set).
+     * @stable ICU 2.1
+     */
+    void setToBogus();
+
+    /**
+     * Gets the bogus state. Locale object can be bogus if it doesn't exist
+     * @return FALSE if it is a real locale, TRUE if it is a bogus locale
+     * @stable ICU 2.1
+     */
+    UBool isBogus(void) const;
+
+    /**
+     * Returns a list of all installed locales.
+     * @param count Receives the number of locales in the list.
+     * @return      A pointer to an array of Locale objects.  This array is the list
+     *              of all locales with installed resource files.  The called does NOT
+     *              get ownership of this list, and must NOT delete it.
+     * @stable ICU 2.0
+     */
+    static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count);
+
+    /**
+     * Gets a list of all available 2-letter country codes defined in ISO 639.  This is a
+     * pointer to an array of pointers to arrays of char.  All of these pointers are
+     * owned by ICU-- do not delete them, and do not write through them.  The array is
+     * terminated with a null pointer.
+     * @return a list of all available country codes
+     * @stable ICU 2.0
+     */
+    static const char* const* U_EXPORT2 getISOCountries();
+
+    /**
+     * Gets a list of all available language codes defined in ISO 639.  This is a pointer
+     * to an array of pointers to arrays of char.  All of these pointers are owned
+     * by ICU-- do not delete them, and do not write through them.  The array is
+     * terminated with a null pointer.
+     * @return a list of all available language codes
+     * @stable ICU 2.0
+     */
+    static const char* const* U_EXPORT2 getISOLanguages();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.2
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.2
+     */
+    virtual UClassID getDynamicClassID() const;
+
+protected: /* only protected for testing purposes. DO NOT USE. */
+    /**
+     * Set this from a single POSIX style locale string.
+     * @internal
+     */
+    void setFromPOSIXID(const char *posixID);
+
+private:
+    /**
+     * Initialize the locale object with a new name.
+     * Was deprecated - used in implementation - moved internal
+     *
+     * @param cLocaleID The new locale name.
+     */
+    Locale& init(const char* cLocaleID, UBool canonicalize);
+
+    /*
+     * Internal constructor to allow construction of a locale object with
+     *   NO side effects.   (Default constructor tries to get
+     *   the default locale.)
+     */
+    enum ELocaleType {
+        eBOGUS
+    };
+    Locale(ELocaleType);
+
+    /**
+     * Initialize the locale cache for commonly used locales
+     */
+    static Locale *getLocaleCache(void);
+
+    char language[ULOC_LANG_CAPACITY];
+    char script[ULOC_SCRIPT_CAPACITY];
+    char country[ULOC_COUNTRY_CAPACITY];
+    int32_t variantBegin;
+    char* fullName;
+    char fullNameBuffer[ULOC_FULLNAME_CAPACITY];
+    // name without keywords
+    char* baseName;
+    char baseNameBuffer[ULOC_FULLNAME_CAPACITY];
+
+    UBool fIsBogus;
+
+    static const Locale &getLocale(int locid);
+
+    /**
+     * A friend to allow the default locale to be set by either the C or C++ API.
+     * @internal
+     */
+    friend void locale_set_default_internal(const char *);
+};
+
+inline UBool
+Locale::operator!=(const    Locale&     other) const
+{
+    return !operator==(other);
+}
+
+inline const char *
+Locale::getCountry() const
+{
+    return country;
+}
+
+inline const char *
+Locale::getLanguage() const
+{
+    return language;
+}
+
+inline const char *
+Locale::getScript() const
+{
+    return script;
+}
+
+inline const char *
+Locale::getVariant() const
+{
+    return &fullName[variantBegin];
+}
+
+inline const char *
+Locale::getName() const
+{
+    return fullName;
+}
+
+inline UBool
+Locale::isBogus(void) const {
+    return fIsBogus;
+}
+
+U_NAMESPACE_END
+
+#endif
+

Added: MacRuby/branches/icu/unicode/normlzr.h
===================================================================
--- MacRuby/branches/icu/unicode/normlzr.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/normlzr.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,823 @@
+/*
+ ********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 1996-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************
+ */
+
+#ifndef NORMLZR_H
+#define NORMLZR_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file 
+ * \brief C++ API: Unicode Normalization
+ */
+ 
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+#include "unicode/chariter.h"
+#include "unicode/unorm.h"
+
+
+struct UCharIterator;
+typedef struct UCharIterator UCharIterator; /**< C typedef for struct UCharIterator. @stable ICU 2.1 */
+
+U_NAMESPACE_BEGIN
+/**
+ * The Normalizer class supports the standard normalization forms described in
+ * <a href="http://www.unicode.org/unicode/reports/tr15/" target="unicode">
+ * Unicode Standard Annex #15: Unicode Normalization Forms</a>.
+ *
+ * The Normalizer class consists of two parts:
+ * - static functions that normalize strings or test if strings are normalized
+ * - a Normalizer object is an iterator that takes any kind of text and
+ *   provides iteration over its normalized form
+ *
+ * The Normalizer class is not suitable for subclassing.
+ *
+ * The static functions are basically wrappers around the C implementation,
+ * using UnicodeString instead of UChar*.
+ * For basic information about normalization forms and details about the C API
+ * please see the documentation in unorm.h.
+ *
+ * The iterator API with the Normalizer constructors and the non-static functions
+ * uses a CharacterIterator as input. It is possible to pass a string which
+ * is then internally wrapped in a CharacterIterator.
+ * The input text is not normalized all at once, but incrementally where needed
+ * (providing efficient random access).
+ * This allows to pass in a large text but spend only a small amount of time
+ * normalizing a small part of that text.
+ * However, if the entire text is normalized, then the iterator will be
+ * slower than normalizing the entire text at once and iterating over the result.
+ * A possible use of the Normalizer iterator is also to report an index into the
+ * original text that is close to where the normalized characters come from.
+ *
+ * <em>Important:</em> The iterator API was cleaned up significantly for ICU 2.0.
+ * The earlier implementation reported the getIndex() inconsistently,
+ * and previous() could not be used after setIndex(), next(), first(), and current().
+ *
+ * Normalizer allows to start normalizing from anywhere in the input text by
+ * calling setIndexOnly(), first(), or last().
+ * Without calling any of these, the iterator will start at the beginning of the text.
+ *
+ * At any time, next() returns the next normalized code point (UChar32),
+ * with post-increment semantics (like CharacterIterator::next32PostInc()).
+ * previous() returns the previous normalized code point (UChar32),
+ * with pre-decrement semantics (like CharacterIterator::previous32()).
+ *
+ * current() returns the current code point
+ * (respectively the one at the newly set index) without moving
+ * the getIndex(). Note that if the text at the current position
+ * needs to be normalized, then these functions will do that.
+ * (This is why current() is not const.)
+ * It is more efficient to call setIndexOnly() instead, which does not
+ * normalize.
+ *
+ * getIndex() always refers to the position in the input text where the normalized
+ * code points are returned from. It does not always change with each returned
+ * code point.
+ * The code point that is returned from any of the functions
+ * corresponds to text at or after getIndex(), according to the
+ * function's iteration semantics (post-increment or pre-decrement).
+ *
+ * next() returns a code point from at or after the getIndex()
+ * from before the next() call. After the next() call, the getIndex()
+ * might have moved to where the next code point will be returned from
+ * (from a next() or current() call).
+ * This is semantically equivalent to array access with array[index++]
+ * (post-increment semantics).
+ *
+ * previous() returns a code point from at or after the getIndex()
+ * from after the previous() call.
+ * This is semantically equivalent to array access with array[--index]
+ * (pre-decrement semantics).
+ *
+ * Internally, the Normalizer iterator normalizes a small piece of text
+ * starting at the getIndex() and ending at a following "safe" index.
+ * The normalized results is stored in an internal string buffer, and
+ * the code points are iterated from there.
+ * With multiple iteration calls, this is repeated until the next piece
+ * of text needs to be normalized, and the getIndex() needs to be moved.
+ *
+ * The following "safe" index, the internal buffer, and the secondary
+ * iteration index into that buffer are not exposed on the API.
+ * This also means that it is currently not practical to return to
+ * a particular, arbitrary position in the text because one would need to
+ * know, and be able to set, in addition to the getIndex(), at least also the
+ * current index into the internal buffer.
+ * It is currently only possible to observe when getIndex() changes
+ * (with careful consideration of the iteration semantics),
+ * at which time the internal index will be 0.
+ * For example, if getIndex() is different after next() than before it,
+ * then the internal index is 0 and one can return to this getIndex()
+ * later with setIndexOnly().
+ *
+ * @author Laura Werner, Mark Davis, Markus Scherer
+ * @stable ICU 2.0
+ */
+class U_COMMON_API Normalizer : public UObject {
+public:
+  /**
+   * If DONE is returned from an iteration function that returns a code point,
+   * then there are no more normalization results available.
+   * @stable ICU 2.0
+   */
+  enum {
+      DONE=0xffff
+  };
+
+  // Constructors
+
+  /**
+   * Creates a new <code>Normalizer</code> object for iterating over the
+   * normalized form of a given string.
+   * <p>
+   * @param str   The string to be normalized.  The normalization
+   *              will start at the beginning of the string.
+   *
+   * @param mode  The normalization mode.
+   * @stable ICU 2.0
+   */
+  Normalizer(const UnicodeString& str, UNormalizationMode mode);
+
+  /**
+   * Creates a new <code>Normalizer</code> object for iterating over the
+   * normalized form of a given string.
+   * <p>
+   * @param str   The string to be normalized.  The normalization
+   *              will start at the beginning of the string.
+   *
+   * @param length Length of the string, or -1 if NUL-terminated.
+   * @param mode  The normalization mode.
+   * @stable ICU 2.0
+   */
+  Normalizer(const UChar* str, int32_t length, UNormalizationMode mode);
+
+  /**
+   * Creates a new <code>Normalizer</code> object for iterating over the
+   * normalized form of the given text.
+   * <p>
+   * @param iter  The input text to be normalized.  The normalization
+   *              will start at the beginning of the string.
+   *
+   * @param mode  The normalization mode.
+   * @stable ICU 2.0
+   */
+  Normalizer(const CharacterIterator& iter, UNormalizationMode mode);
+
+  /**
+   * Copy constructor.
+   * @param copy The object to be copied.
+   * @stable ICU 2.0
+   */
+  Normalizer(const Normalizer& copy);
+
+  /**
+   * Destructor
+   * @stable ICU 2.0
+   */
+  virtual ~Normalizer();
+
+
+  //-------------------------------------------------------------------------
+  // Static utility methods
+  //-------------------------------------------------------------------------
+
+  /**
+   * Normalizes a <code>UnicodeString</code> according to the specified normalization mode.
+   * This is a wrapper for unorm_normalize(), using UnicodeString's.
+   *
+   * The <code>options</code> parameter specifies which optional
+   * <code>Normalizer</code> features are to be enabled for this operation.
+   *
+   * @param source    the input string to be normalized.
+   * @param mode      the normalization mode
+   * @param options   the optional features to be enabled (0 for no options)
+   * @param result    The normalized string (on output).
+   * @param status    The error code.
+   * @stable ICU 2.0
+   */
+  static void U_EXPORT2 normalize(const UnicodeString& source,
+                        UNormalizationMode mode, int32_t options,
+                        UnicodeString& result,
+                        UErrorCode &status);
+
+  /**
+   * Compose a <code>UnicodeString</code>.
+   * This is equivalent to normalize() with mode UNORM_NFC or UNORM_NFKC.
+   * This is a wrapper for unorm_normalize(), using UnicodeString's.
+   *
+   * The <code>options</code> parameter specifies which optional
+   * <code>Normalizer</code> features are to be enabled for this operation.
+   *
+   * @param source    the string to be composed.
+   * @param compat    Perform compatibility decomposition before composition.
+   *                  If this argument is <code>FALSE</code>, only canonical
+   *                  decomposition will be performed.
+   * @param options   the optional features to be enabled (0 for no options)
+   * @param result    The composed string (on output).
+   * @param status    The error code.
+   * @stable ICU 2.0
+   */
+  static void U_EXPORT2 compose(const UnicodeString& source,
+                      UBool compat, int32_t options,
+                      UnicodeString& result,
+                      UErrorCode &status);
+
+  /**
+   * Static method to decompose a <code>UnicodeString</code>.
+   * This is equivalent to normalize() with mode UNORM_NFD or UNORM_NFKD.
+   * This is a wrapper for unorm_normalize(), using UnicodeString's.
+   *
+   * The <code>options</code> parameter specifies which optional
+   * <code>Normalizer</code> features are to be enabled for this operation.
+   *
+   * @param source    the string to be decomposed.
+   * @param compat    Perform compatibility decomposition.
+   *                  If this argument is <code>FALSE</code>, only canonical
+   *                  decomposition will be performed.
+   * @param options   the optional features to be enabled (0 for no options)
+   * @param result    The decomposed string (on output).
+   * @param status    The error code.
+   * @stable ICU 2.0
+   */
+  static void U_EXPORT2 decompose(const UnicodeString& source,
+                        UBool compat, int32_t options,
+                        UnicodeString& result,
+                        UErrorCode &status);
+
+  /**
+   * Performing quick check on a string, to quickly determine if the string is
+   * in a particular normalization format.
+   * This is a wrapper for unorm_quickCheck(), using a UnicodeString.
+   *
+   * Three types of result can be returned UNORM_YES, UNORM_NO or
+   * UNORM_MAYBE. Result UNORM_YES indicates that the argument
+   * string is in the desired normalized format, UNORM_NO determines that
+   * argument string is not in the desired normalized format. A
+   * UNORM_MAYBE result indicates that a more thorough check is required,
+   * the user may have to put the string in its normalized form and compare the
+   * results.
+   * @param source       string for determining if it is in a normalized format
+   * @param mode         normalization format
+   * @param status A reference to a UErrorCode to receive any errors
+   * @return UNORM_YES, UNORM_NO or UNORM_MAYBE
+   *
+   * @see isNormalized
+   * @stable ICU 2.0
+   */
+  static inline UNormalizationCheckResult
+  quickCheck(const UnicodeString &source, UNormalizationMode mode, UErrorCode &status);
+
+  /**
+   * Performing quick check on a string; same as the other version of quickCheck
+   * but takes an extra options parameter like most normalization functions.
+   *
+   * @param source       string for determining if it is in a normalized format
+   * @param mode         normalization format
+   * @param options      the optional features to be enabled (0 for no options)
+   * @param status A reference to a UErrorCode to receive any errors
+   * @return UNORM_YES, UNORM_NO or UNORM_MAYBE
+   *
+   * @see isNormalized
+   * @stable ICU 2.6
+   */
+  static inline UNormalizationCheckResult
+  quickCheck(const UnicodeString &source, UNormalizationMode mode, int32_t options, UErrorCode &status);
+
+  /**
+   * Test if a string is in a given normalization form.
+   * This is semantically equivalent to source.equals(normalize(source, mode)) .
+   *
+   * Unlike unorm_quickCheck(), this function returns a definitive result,
+   * never a "maybe".
+   * For NFD, NFKD, and FCD, both functions work exactly the same.
+   * For NFC and NFKC where quickCheck may return "maybe", this function will
+   * perform further tests to arrive at a TRUE/FALSE result.
+   *
+   * @param src        String that is to be tested if it is in a normalization format.
+   * @param mode       Which normalization form to test for.
+   * @param errorCode  ICU error code in/out parameter.
+   *                   Must fulfill U_SUCCESS before the function call.
+   * @return Boolean value indicating whether the source string is in the
+   *         "mode" normalization form.
+   *
+   * @see quickCheck
+   * @stable ICU 2.2
+   */
+  static inline UBool
+  isNormalized(const UnicodeString &src, UNormalizationMode mode, UErrorCode &errorCode);
+
+  /**
+   * Test if a string is in a given normalization form; same as the other version of isNormalized
+   * but takes an extra options parameter like most normalization functions.
+   *
+   * @param src        String that is to be tested if it is in a normalization format.
+   * @param mode       Which normalization form to test for.
+   * @param options      the optional features to be enabled (0 for no options)
+   * @param errorCode  ICU error code in/out parameter.
+   *                   Must fulfill U_SUCCESS before the function call.
+   * @return Boolean value indicating whether the source string is in the
+   *         "mode" normalization form.
+   *
+   * @see quickCheck
+   * @stable ICU 2.6
+   */
+  static inline UBool
+  isNormalized(const UnicodeString &src, UNormalizationMode mode, int32_t options, UErrorCode &errorCode);
+
+  /**
+   * Concatenate normalized strings, making sure that the result is normalized as well.
+   *
+   * If both the left and the right strings are in
+   * the normalization form according to "mode/options",
+   * then the result will be
+   *
+   * \code
+   *     dest=normalize(left+right, mode, options)
+   * \endcode
+   *
+   * For details see unorm_concatenate in unorm.h.
+   *
+   * @param left Left source string.
+   * @param right Right source string.
+   * @param result The output string.
+   * @param mode The normalization mode.
+   * @param options A bit set of normalization options.
+   * @param errorCode ICU error code in/out parameter.
+   *                   Must fulfill U_SUCCESS before the function call.
+   * @return result
+   *
+   * @see unorm_concatenate
+   * @see normalize
+   * @see unorm_next
+   * @see unorm_previous
+   *
+   * @stable ICU 2.1
+   */
+  static UnicodeString &
+  U_EXPORT2 concatenate(UnicodeString &left, UnicodeString &right,
+              UnicodeString &result,
+              UNormalizationMode mode, int32_t options,
+              UErrorCode &errorCode);
+
+  /**
+   * Compare two strings for canonical equivalence.
+   * Further options include case-insensitive comparison and
+   * code point order (as opposed to code unit order).
+   *
+   * Canonical equivalence between two strings is defined as their normalized
+   * forms (NFD or NFC) being identical.
+   * This function compares strings incrementally instead of normalizing
+   * (and optionally case-folding) both strings entirely,
+   * improving performance significantly.
+   *
+   * Bulk normalization is only necessary if the strings do not fulfill the FCD
+   * conditions. Only in this case, and only if the strings are relatively long,
+   * is memory allocated temporarily.
+   * For FCD strings and short non-FCD strings there is no memory allocation.
+   *
+   * Semantically, this is equivalent to
+   *   strcmp[CodePointOrder](NFD(foldCase(s1)), NFD(foldCase(s2)))
+   * where code point order and foldCase are all optional.
+   *
+   * UAX 21 2.5 Caseless Matching specifies that for a canonical caseless match
+   * the case folding must be performed first, then the normalization.
+   *
+   * @param s1 First source string.
+   * @param s2 Second source string.
+   *
+   * @param options A bit set of options:
+   *   - U_FOLD_CASE_DEFAULT or 0 is used for default options:
+   *     Case-sensitive comparison in code unit order, and the input strings
+   *     are quick-checked for FCD.
+   *
+   *   - UNORM_INPUT_IS_FCD
+   *     Set if the caller knows that both s1 and s2 fulfill the FCD conditions.
+   *     If not set, the function will quickCheck for FCD
+   *     and normalize if necessary.
+   *
+   *   - U_COMPARE_CODE_POINT_ORDER
+   *     Set to choose code point order instead of code unit order
+   *     (see u_strCompare for details).
+   *
+   *   - U_COMPARE_IGNORE_CASE
+   *     Set to compare strings case-insensitively using case folding,
+   *     instead of case-sensitively.
+   *     If set, then the following case folding options are used.
+   *
+   *   - Options as used with case-insensitive comparisons, currently:
+   *
+   *   - U_FOLD_CASE_EXCLUDE_SPECIAL_I
+   *    (see u_strCaseCompare for details)
+   *
+   *   - regular normalization options shifted left by UNORM_COMPARE_NORM_OPTIONS_SHIFT
+   *
+   * @param errorCode ICU error code in/out parameter.
+   *                  Must fulfill U_SUCCESS before the function call.
+   * @return <0 or 0 or >0 as usual for string comparisons
+   *
+   * @see unorm_compare
+   * @see normalize
+   * @see UNORM_FCD
+   * @see u_strCompare
+   * @see u_strCaseCompare
+   *
+   * @stable ICU 2.2
+   */
+  static inline int32_t
+  compare(const UnicodeString &s1, const UnicodeString &s2,
+          uint32_t options,
+          UErrorCode &errorCode);
+
+  //-------------------------------------------------------------------------
+  // Iteration API
+  //-------------------------------------------------------------------------
+
+  /**
+   * Return the current character in the normalized text.
+   * current() may need to normalize some text at getIndex().
+   * The getIndex() is not changed.
+   *
+   * @return the current normalized code point
+   * @stable ICU 2.0
+   */
+  UChar32              current(void);
+
+  /**
+   * Return the first character in the normalized text.
+   * This is equivalent to setIndexOnly(startIndex()) followed by next().
+   * (Post-increment semantics.)
+   *
+   * @return the first normalized code point
+   * @stable ICU 2.0
+   */
+  UChar32              first(void);
+
+  /**
+   * Return the last character in the normalized text.
+   * This is equivalent to setIndexOnly(endIndex()) followed by previous().
+   * (Pre-decrement semantics.)
+   *
+   * @return the last normalized code point
+   * @stable ICU 2.0
+   */
+  UChar32              last(void);
+
+  /**
+   * Return the next character in the normalized text.
+   * (Post-increment semantics.)
+   * If the end of the text has already been reached, DONE is returned.
+   * The DONE value could be confused with a U+FFFF non-character code point
+   * in the text. If this is possible, you can test getIndex()<endIndex()
+   * before calling next(), or (getIndex()<endIndex() || last()!=DONE)
+   * after calling next(). (Calling last() will change the iterator state!)
+   *
+   * The C API unorm_next() is more efficient and does not have this ambiguity.
+   *
+   * @return the next normalized code point
+   * @stable ICU 2.0
+   */
+  UChar32              next(void);
+
+  /**
+   * Return the previous character in the normalized text and decrement.
+   * (Pre-decrement semantics.)
+   * If the beginning of the text has already been reached, DONE is returned.
+   * The DONE value could be confused with a U+FFFF non-character code point
+   * in the text. If this is possible, you can test
+   * (getIndex()>startIndex() || first()!=DONE). (Calling first() will change
+   * the iterator state!)
+   *
+   * The C API unorm_previous() is more efficient and does not have this ambiguity.
+   *
+   * @return the previous normalized code point
+   * @stable ICU 2.0
+   */
+  UChar32              previous(void);
+
+  /**
+   * Set the iteration position in the input text that is being normalized,
+   * without any immediate normalization.
+   * After setIndexOnly(), getIndex() will return the same index that is
+   * specified here.
+   *
+   * @param index the desired index in the input text.
+   * @stable ICU 2.0
+   */
+  void                 setIndexOnly(int32_t index);
+
+  /**
+   * Reset the index to the beginning of the text.
+   * This is equivalent to setIndexOnly(startIndex)).
+   * @stable ICU 2.0
+   */
+  void                reset(void);
+
+  /**
+   * Retrieve the current iteration position in the input text that is
+   * being normalized.
+   *
+   * A following call to next() will return a normalized code point from
+   * the input text at or after this index.
+   *
+   * After a call to previous(), getIndex() will point at or before the
+   * position in the input text where the normalized code point
+   * was returned from with previous().
+   *
+   * @return the current index in the input text
+   * @stable ICU 2.0
+   */
+  int32_t            getIndex(void) const;
+
+  /**
+   * Retrieve the index of the start of the input text. This is the begin index
+   * of the <code>CharacterIterator</code> or the start (i.e. index 0) of the string
+   * over which this <code>Normalizer</code> is iterating.
+   *
+   * @return the smallest index in the input text where the Normalizer operates
+   * @stable ICU 2.0
+   */
+  int32_t            startIndex(void) const;
+
+  /**
+   * Retrieve the index of the end of the input text. This is the end index
+   * of the <code>CharacterIterator</code> or the length of the string
+   * over which this <code>Normalizer</code> is iterating.
+   * This end index is exclusive, i.e., the Normalizer operates only on characters
+   * before this index.
+   *
+   * @return the first index in the input text where the Normalizer does not operate
+   * @stable ICU 2.0
+   */
+  int32_t            endIndex(void) const;
+
+  /**
+   * Returns TRUE when both iterators refer to the same character in the same
+   * input text.
+   *
+   * @param that a Normalizer object to compare this one to
+   * @return comparison result
+   * @stable ICU 2.0
+   */
+  UBool        operator==(const Normalizer& that) const;
+
+  /**
+   * Returns FALSE when both iterators refer to the same character in the same
+   * input text.
+   *
+   * @param that a Normalizer object to compare this one to
+   * @return comparison result
+   * @stable ICU 2.0
+   */
+  inline UBool        operator!=(const Normalizer& that) const;
+
+  /**
+   * Returns a pointer to a new Normalizer that is a clone of this one.
+   * The caller is responsible for deleting the new clone.
+   * @return a pointer to a new Normalizer
+   * @stable ICU 2.0
+   */
+  Normalizer*        clone(void) const;
+
+  /**
+   * Generates a hash code for this iterator.
+   *
+   * @return the hash code
+   * @stable ICU 2.0
+   */
+  int32_t                hashCode(void) const;
+
+  //-------------------------------------------------------------------------
+  // Property access methods
+  //-------------------------------------------------------------------------
+
+  /**
+   * Set the normalization mode for this object.
+   * <p>
+   * <b>Note:</b>If the normalization mode is changed while iterating
+   * over a string, calls to {@link #next() } and {@link #previous() } may
+   * return previously buffers characters in the old normalization mode
+   * until the iteration is able to re-sync at the next base character.
+   * It is safest to call {@link #setIndexOnly }, {@link #reset() },
+   * {@link #setText }, {@link #first() },
+   * {@link #last() }, etc. after calling <code>setMode</code>.
+   * <p>
+   * @param newMode the new mode for this <code>Normalizer</code>.
+   * @see #getUMode
+   * @stable ICU 2.0
+   */
+  void setMode(UNormalizationMode newMode);
+
+  /**
+   * Return the normalization mode for this object.
+   *
+   * This is an unusual name because there used to be a getMode() that
+   * returned a different type.
+   *
+   * @return the mode for this <code>Normalizer</code>
+   * @see #setMode
+   * @stable ICU 2.0
+   */
+  UNormalizationMode getUMode(void) const;
+
+  /**
+   * Set options that affect this <code>Normalizer</code>'s operation.
+   * Options do not change the basic composition or decomposition operation
+   * that is being performed, but they control whether
+   * certain optional portions of the operation are done.
+   * Currently the only available option is obsolete.
+   *
+   * It is possible to specify multiple options that are all turned on or off.
+   *
+   * @param   option  the option(s) whose value is/are to be set.
+   * @param   value   the new setting for the option.  Use <code>TRUE</code> to
+   *                  turn the option(s) on and <code>FALSE</code> to turn it/them off.
+   *
+   * @see #getOption
+   * @stable ICU 2.0
+   */
+  void setOption(int32_t option,
+         UBool value);
+
+  /**
+   * Determine whether an option is turned on or off.
+   * If multiple options are specified, then the result is TRUE if any
+   * of them are set.
+   * <p>
+   * @param option the option(s) that are to be checked
+   * @return TRUE if any of the option(s) are set
+   * @see #setOption
+   * @stable ICU 2.0
+   */
+  UBool getOption(int32_t option) const;
+
+  /**
+   * Set the input text over which this <code>Normalizer</code> will iterate.
+   * The iteration position is set to the beginning.
+   *
+   * @param newText a string that replaces the current input text
+   * @param status a UErrorCode
+   * @stable ICU 2.0
+   */
+  void setText(const UnicodeString& newText,
+           UErrorCode &status);
+
+  /**
+   * Set the input text over which this <code>Normalizer</code> will iterate.
+   * The iteration position is set to the beginning.
+   *
+   * @param newText a CharacterIterator object that replaces the current input text
+   * @param status a UErrorCode
+   * @stable ICU 2.0
+   */
+  void setText(const CharacterIterator& newText,
+           UErrorCode &status);
+
+  /**
+   * Set the input text over which this <code>Normalizer</code> will iterate.
+   * The iteration position is set to the beginning.
+   *
+   * @param newText a string that replaces the current input text
+   * @param length the length of the string, or -1 if NUL-terminated
+   * @param status a UErrorCode
+   * @stable ICU 2.0
+   */
+  void setText(const UChar* newText,
+                    int32_t length,
+            UErrorCode &status);
+  /**
+   * Copies the input text into the UnicodeString argument.
+   *
+   * @param result Receives a copy of the text under iteration.
+   * @stable ICU 2.0
+   */
+  void            getText(UnicodeString&  result);
+
+  /**
+   * ICU "poor man's RTTI", returns a UClassID for this class.
+   * @returns a UClassID for this class.
+   * @stable ICU 2.2
+   */
+  static UClassID U_EXPORT2 getStaticClassID();
+
+  /**
+   * ICU "poor man's RTTI", returns a UClassID for the actual class.
+   * @return a UClassID for the actual class.
+   * @stable ICU 2.2
+   */
+  virtual UClassID getDynamicClassID() const;
+
+private:
+  //-------------------------------------------------------------------------
+  // Private functions
+  //-------------------------------------------------------------------------
+
+  Normalizer(); // default constructor not implemented
+  Normalizer &operator=(const Normalizer &that); // assignment operator not implemented
+
+  // Private utility methods for iteration
+  // For documentation, see the source code
+  UBool nextNormalize();
+  UBool previousNormalize();
+
+  void    init(CharacterIterator *iter);
+  void    clearBuffer(void);
+
+  //-------------------------------------------------------------------------
+  // Private data
+  //-------------------------------------------------------------------------
+
+  UNormalizationMode  fUMode;
+  int32_t             fOptions;
+
+  // The input text and our position in it
+  UCharIterator       *text;
+
+  // The normalization buffer is the result of normalization
+  // of the source in [currentIndex..nextIndex[ .
+  int32_t         currentIndex, nextIndex;
+
+  // A buffer for holding intermediate results
+  UnicodeString       buffer;
+  int32_t         bufferPos;
+
+};
+
+//-------------------------------------------------------------------------
+// Inline implementations
+//-------------------------------------------------------------------------
+
+inline UBool
+Normalizer::operator!= (const Normalizer& other) const
+{ return ! operator==(other); }
+
+inline UNormalizationCheckResult
+Normalizer::quickCheck(const UnicodeString& source,
+                       UNormalizationMode mode,
+                       UErrorCode &status) {
+    if(U_FAILURE(status)) {
+        return UNORM_MAYBE;
+    }
+
+    return unorm_quickCheck(source.getBuffer(), source.length(),
+                            mode, &status);
+}
+
+inline UNormalizationCheckResult
+Normalizer::quickCheck(const UnicodeString& source,
+                       UNormalizationMode mode, int32_t options,
+                       UErrorCode &status) {
+    if(U_FAILURE(status)) {
+        return UNORM_MAYBE;
+    }
+
+    return unorm_quickCheckWithOptions(source.getBuffer(), source.length(),
+                                       mode, options, &status);
+}
+
+inline UBool
+Normalizer::isNormalized(const UnicodeString& source,
+                         UNormalizationMode mode,
+                         UErrorCode &status) {
+    if(U_FAILURE(status)) {
+        return FALSE;
+    }
+
+    return unorm_isNormalized(source.getBuffer(), source.length(),
+                              mode, &status);
+}
+
+inline UBool
+Normalizer::isNormalized(const UnicodeString& source,
+                         UNormalizationMode mode, int32_t options,
+                         UErrorCode &status) {
+    if(U_FAILURE(status)) {
+        return FALSE;
+    }
+
+    return unorm_isNormalizedWithOptions(source.getBuffer(), source.length(),
+                                         mode, options, &status);
+}
+
+inline int32_t
+Normalizer::compare(const UnicodeString &s1, const UnicodeString &s2,
+                    uint32_t options,
+                    UErrorCode &errorCode) {
+  // all argument checking is done in unorm_compare
+  return unorm_compare(s1.getBuffer(), s1.length(),
+                       s2.getBuffer(), s2.length(),
+                       options,
+                       &errorCode);
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_NORMALIZATION */
+
+#endif // NORMLZR_H

Added: MacRuby/branches/icu/unicode/parseerr.h
===================================================================
--- MacRuby/branches/icu/unicode/parseerr.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/parseerr.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,92 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   03/14/00    aliu        Creation.
+*   06/27/00    aliu        Change from C++ class to C struct
+**********************************************************************
+*/
+#ifndef PARSEERR_H
+#define PARSEERR_H
+
+#include "unicode/utypes.h"
+
+
+/**
+ * \file
+ * \brief C API: Parse Error Information
+ */
+/**
+ * The capacity of the context strings in UParseError.
+ * @stable ICU 2.0
+ */ 
+enum { U_PARSE_CONTEXT_LEN = 16 };
+
+/**
+ * A UParseError struct is used to returned detailed information about
+ * parsing errors.  It is used by ICU parsing engines that parse long
+ * rules, patterns, or programs, where the text being parsed is long
+ * enough that more information than a UErrorCode is needed to
+ * localize the error.
+ *
+ * <p>The line, offset, and context fields are optional; parsing
+ * engines may choose not to use to use them.
+ *
+ * <p>The preContext and postContext strings include some part of the
+ * context surrounding the error.  If the source text is "let for=7"
+ * and "for" is the error (e.g., because it is a reserved word), then
+ * some examples of what a parser might produce are the following:
+ *
+ * <pre>
+ * preContext   postContext
+ * ""           ""            The parser does not support context
+ * "let "       "=7"          Pre- and post-context only
+ * "let "       "for=7"       Pre- and post-context and error text
+ * ""           "for"         Error text only
+ * </pre>
+ *
+ * <p>Examples of engines which use UParseError (or may use it in the
+ * future) are Transliterator, RuleBasedBreakIterator, and
+ * RegexPattern.
+ * 
+ * @stable ICU 2.0
+ */
+typedef struct UParseError {
+
+    /**
+     * The line on which the error occured.  If the parser uses this
+     * field, it sets it to the line number of the source text line on
+     * which the error appears, which will be be a value >= 1.  If the
+     * parse does not support line numbers, the value will be <= 0.
+     * @stable ICU 2.0
+     */
+    int32_t        line;
+
+    /**
+     * The character offset to the error.  If the line field is >= 1,
+     * then this is the offset from the start of the line.  Otherwise,
+     * this is the offset from the start of the text.  If the parser
+     * does not support this field, it will have a value < 0.
+     * @stable ICU 2.0
+     */
+    int32_t        offset;
+
+    /**
+     * Textual context before the error.  Null-terminated.  The empty
+     * string if not supported by parser.
+     * @stable ICU 2.0   
+     */
+    UChar          preContext[U_PARSE_CONTEXT_LEN];
+
+    /**
+     * The error itself and/or textual context after the error.
+     * Null-terminated.  The empty string if not supported by parser.
+     * @stable ICU 2.0   
+     */
+    UChar          postContext[U_PARSE_CONTEXT_LEN];
+
+} UParseError;
+
+#endif

Added: MacRuby/branches/icu/unicode/parsepos.h
===================================================================
--- MacRuby/branches/icu/unicode/parsepos.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/parsepos.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,230 @@
+/*
+* Copyright (C) 1997-2005, International Business Machines Corporation and others. All Rights Reserved.
+*******************************************************************************
+*
+* File PARSEPOS.H
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   07/09/97    helena      Converted from java.
+*   07/17/98    stephen     Added errorIndex support.
+*   05/11/99    stephen     Cleaned up.
+*******************************************************************************
+*/
+
+#ifndef PARSEPOS_H
+#define PARSEPOS_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+
+ 
+U_NAMESPACE_BEGIN
+
+/**
+ * \file
+ * \brief C++ API: Canonical Iterator
+ */
+/** 
+ * <code>ParsePosition</code> is a simple class used by <code>Format</code>
+ * and its subclasses to keep track of the current position during parsing.
+ * The <code>parseObject</code> method in the various <code>Format</code>
+ * classes requires a <code>ParsePosition</code> object as an argument.
+ *
+ * <p>
+ * By design, as you parse through a string with different formats,
+ * you can use the same <code>ParsePosition</code>, since the index parameter
+ * records the current position.
+ *
+ * The ParsePosition class is not suitable for subclassing.
+ *
+ * @version     1.3 10/30/97
+ * @author      Mark Davis, Helena Shih
+ * @see         java.text.Format
+ */
+
+class U_COMMON_API ParsePosition : public UObject {
+public:
+    /**
+     * Default constructor, the index starts with 0 as default.
+     * @stable ICU 2.0
+     */
+    ParsePosition()
+        : UObject(),
+        index(0),
+        errorIndex(-1)
+      {}
+
+    /**
+     * Create a new ParsePosition with the given initial index.
+     * @param newIndex the new text offset.
+     * @stable ICU 2.0
+     */
+    ParsePosition(int32_t newIndex)
+        : UObject(),
+        index(newIndex),
+        errorIndex(-1)
+      {}
+
+    /**
+     * Copy constructor
+     * @param copy the object to be copied from.
+     * @stable ICU 2.0
+     */
+    ParsePosition(const ParsePosition& copy)
+        : UObject(copy),
+        index(copy.index),
+        errorIndex(copy.errorIndex)
+      {}
+
+    /**
+     * Destructor
+     * @stable ICU 2.0
+     */
+    virtual ~ParsePosition();
+
+    /**
+     * Assignment operator
+     * @stable ICU 2.0
+     */
+    ParsePosition&      operator=(const ParsePosition& copy);
+
+    /**
+     * Equality operator.
+     * @return TRUE if the two parse positions are equal, FALSE otherwise.
+     * @stable ICU 2.0
+     */
+    UBool              operator==(const ParsePosition& that) const;
+
+    /**
+     * Equality operator.
+     * @return TRUE if the two parse positions are not equal, FALSE otherwise.
+     * @stable ICU 2.0
+     */
+    UBool              operator!=(const ParsePosition& that) const;
+
+    /**
+     * Clone this object.
+     * Clones can be used concurrently in multiple threads.
+     * If an error occurs, then NULL is returned.
+     * The caller must delete the clone.
+     *
+     * @return a clone of this object
+     *
+     * @see getDynamicClassID
+     * @stable ICU 2.8
+     */
+    ParsePosition *clone() const;
+
+    /**
+     * Retrieve the current parse position.  On input to a parse method, this
+     * is the index of the character at which parsing will begin; on output, it
+     * is the index of the character following the last character parsed.
+     * @return the current index.
+     * @stable ICU 2.0
+     */
+    int32_t getIndex(void) const;
+
+    /**
+     * Set the current parse position.
+     * @param index the new index.
+     * @stable ICU 2.0
+     */
+    void setIndex(int32_t index);
+
+    /**
+     * Set the index at which a parse error occurred.  Formatters
+     * should set this before returning an error code from their
+     * parseObject method.  The default value is -1 if this is not
+     * set.
+     * @stable ICU 2.0
+     */
+    void setErrorIndex(int32_t ei);
+
+    /**
+     * Retrieve the index at which an error occurred, or -1 if the
+     * error index has not been set.
+     * @stable ICU 2.0
+     */
+    int32_t getErrorIndex(void) const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.2
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.2
+     */
+    virtual UClassID getDynamicClassID() const;
+
+private:
+    /**
+     * Input: the place you start parsing.
+     * <br>Output: position where the parse stopped.
+     * This is designed to be used serially,
+     * with each call setting index up for the next one.
+     */
+    int32_t index;
+
+    /**
+     * The index at which a parse error occurred.
+     */
+    int32_t errorIndex;
+
+};
+
+inline ParsePosition&
+ParsePosition::operator=(const ParsePosition& copy)
+{
+  index = copy.index;
+  errorIndex = copy.errorIndex;
+  return *this;
+}
+
+inline UBool
+ParsePosition::operator==(const ParsePosition& copy) const
+{
+  if(index != copy.index || errorIndex != copy.errorIndex)
+  return FALSE;
+  else
+  return TRUE;
+}
+
+inline UBool
+ParsePosition::operator!=(const ParsePosition& copy) const
+{
+  return !operator==(copy);
+}
+
+inline int32_t
+ParsePosition::getIndex() const
+{
+  return index;
+}
+
+inline void
+ParsePosition::setIndex(int32_t offset)
+{
+  this->index = offset;
+}
+
+inline int32_t
+ParsePosition::getErrorIndex() const
+{
+  return errorIndex;
+}
+
+inline void
+ParsePosition::setErrorIndex(int32_t ei)
+{
+  this->errorIndex = ei;
+}
+U_NAMESPACE_END
+
+#endif

Added: MacRuby/branches/icu/unicode/platform.h
===================================================================
--- MacRuby/branches/icu/unicode/platform.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/platform.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,290 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : platform.h
+*
+*   Date        Name        Description
+*   05/13/98    nos         Creation (content moved here from ptypes.h).
+*   03/02/99    stephen     Added AS400 support.
+*   03/30/99    stephen     Added Linux support.
+*   04/13/99    stephen     Reworked for autoconf.
+******************************************************************************
+*/
+
+/**
+ * \file 
+ * \brief Basic types for the platform 
+ */
+
+/* Define the platform we're on. */
+#ifndef U_DARWIN
+#define U_DARWIN
+#endif
+
+/* Define whether inttypes.h is available */
+#ifndef U_HAVE_INTTYPES_H
+#define U_HAVE_INTTYPES_H 1
+#endif
+
+/*
+ * Define what support for C++ streams is available.
+ *     If U_IOSTREAM_SOURCE is set to 199711, then <iostream> is available
+ * (1997711 is the date the ISO/IEC C++ FDIS was published), and then
+ * one should qualify streams using the std namespace in ICU header
+ * files.
+ *     If U_IOSTREAM_SOURCE is set to 198506, then <iostream.h> is
+ * available instead (198506 is the date when Stroustrup published
+ * "An Extensible I/O Facility for C++" at the summer USENIX conference).
+ *     If U_IOSTREAM_SOURCE is 0, then C++ streams are not available and
+ * support for them will be silently suppressed in ICU.
+ *
+ */
+
+#ifndef U_IOSTREAM_SOURCE
+#define U_IOSTREAM_SOURCE 199711
+#endif
+
+/* Determines whether specific types are available */
+#ifndef U_HAVE_INT8_T
+#define U_HAVE_INT8_T 1
+#endif
+
+#ifndef U_HAVE_UINT8_T
+#define U_HAVE_UINT8_T 1
+#endif
+
+#ifndef U_HAVE_INT16_T
+#define U_HAVE_INT16_T 1
+#endif
+
+#ifndef U_HAVE_UINT16_T
+#define U_HAVE_UINT16_T 1
+#endif
+
+#ifndef U_HAVE_INT32_T
+#define U_HAVE_INT32_T 1
+#endif
+
+#ifndef U_HAVE_UINT32_T
+#define U_HAVE_UINT32_T 1
+#endif
+
+#ifndef U_HAVE_INT64_T
+#define U_HAVE_INT64_T 1
+#endif
+
+#ifndef U_HAVE_UINT64_T
+#define U_HAVE_UINT64_T 1
+#endif
+
+/*===========================================================================*/
+/* Generic data types                                                        */
+/*===========================================================================*/
+
+#include <sys/types.h>
+
+/* If your platform does not have the <inttypes.h> header, you may
+   need to edit the typedefs below. */
+#if U_HAVE_INTTYPES_H
+
+/* autoconf 2.13 sometimes can't properly find the data types in <inttypes.h> */
+/* os/390 needs <inttypes.h>, but it doesn't have int8_t, and it sometimes */
+/* doesn't have uint8_t depending on the OS version. */
+/* So we have this work around. */
+#ifdef OS390
+/* The features header is needed to get (u)int64_t sometimes. */
+#include <features.h>
+#if ! U_HAVE_INT8_T
+typedef signed char int8_t;
+#endif
+#if !defined(__uint8_t)
+#define __uint8_t 1
+typedef unsigned char uint8_t;
+#endif
+#endif /* OS390 */
+
+#include <inttypes.h>
+
+#else /* U_HAVE_INTTYPES_H */
+
+#if ! U_HAVE_INT8_T
+typedef signed char int8_t;
+#endif
+
+#if ! U_HAVE_UINT8_T
+typedef unsigned char uint8_t;
+#endif
+
+#if ! U_HAVE_INT16_T
+typedef signed short int16_t;
+#endif
+
+#if ! U_HAVE_UINT16_T
+typedef unsigned short uint16_t;
+#endif
+
+#if ! U_HAVE_INT32_T
+typedef signed int int32_t;
+#endif
+
+#if ! U_HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+
+#if ! U_HAVE_INT64_T
+    typedef signed long long int64_t;
+/* else we may not have a 64-bit type */
+#endif
+
+#if ! U_HAVE_UINT64_T
+    typedef unsigned long long uint64_t;
+/* else we may not have a 64-bit type */
+#endif
+
+#endif
+
+/*===========================================================================*/
+/* Compiler and environment features                                         */
+/*===========================================================================*/
+
+/* Define whether namespace is supported */
+#ifndef U_HAVE_NAMESPACE
+#define U_HAVE_NAMESPACE 1
+#endif
+
+/* Determines the endianness of the platform
+   It's done this way in case multiple architectures are being built at once.
+   For example, Darwin supports fat binaries, which can be both PPC and x86 based. */
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
+#define U_IS_BIG_ENDIAN (BYTE_ORDER == BIG_ENDIAN)
+#else
+#define U_IS_BIG_ENDIAN 0
+#endif
+
+/* 1 or 0 to enable or disable threads.  If undefined, default is: enable threads. */
+#define ICU_USE_THREADS 1
+
+#ifndef U_DEBUG
+#define U_DEBUG 0
+#endif
+
+#ifndef U_RELEASE
+#define U_RELEASE 1
+#endif
+
+/* Determine whether to disable renaming or not. This overrides the
+   setting in umachine.h which is for all platforms. */
+#ifndef U_DISABLE_RENAMING
+#define U_DISABLE_RENAMING 1
+#endif
+
+/* Determine whether to override new and delete. */
+#ifndef U_OVERRIDE_CXX_ALLOCATION
+#define U_OVERRIDE_CXX_ALLOCATION 1
+#endif
+/* Determine whether to override placement new and delete for STL. */
+#ifndef U_HAVE_PLACEMENT_NEW
+#define U_HAVE_PLACEMENT_NEW 1
+#endif
+
+/* Determine whether to enable tracing. */
+#ifndef U_ENABLE_TRACING
+#define U_ENABLE_TRACING 1
+#endif
+
+/* Do we allow ICU users to use the draft APIs by default? */
+#ifndef U_DEFAULT_SHOW_DRAFT
+#define U_DEFAULT_SHOW_DRAFT 0
+#endif
+
+/* Define the library suffix in a C syntax. */
+#define U_HAVE_LIB_SUFFIX 0
+#define U_LIB_SUFFIX_C_NAME 
+#define U_LIB_SUFFIX_C_NAME_STRING ""
+
+/*===========================================================================*/
+/* Character data types                                                      */
+/*===========================================================================*/
+
+#if ((defined(OS390) && (!defined(__CHARSET_LIB) || !__CHARSET_LIB))) || defined(OS400)
+#   define U_CHARSET_FAMILY 1
+#endif
+
+/*===========================================================================*/
+/* Information about wchar support                                           */
+/*===========================================================================*/
+
+#define U_HAVE_WCHAR_H      1
+#define U_SIZEOF_WCHAR_T    4
+
+#define U_HAVE_WCSCPY       1
+
+/*===========================================================================*/
+/* Information about POSIX support                                           */
+/*===========================================================================*/
+
+#define U_HAVE_NL_LANGINFO          1
+#define U_HAVE_NL_LANGINFO_CODESET  1
+#define U_NL_LANGINFO_CODESET       CODESET
+
+#if 1
+#define U_TZSET         tzset
+#endif
+#if 1
+#define U_TIMEZONE      timezone
+#endif
+#if 1
+#define U_TZNAME        tzname
+#endif
+
+#define U_HAVE_MMAP     1
+#define U_HAVE_POPEN    1
+
+/*===========================================================================*/
+/* Symbol import-export control                                              */
+/*===========================================================================*/
+
+#if defined(U_DARWIN) && defined(__GNUC__) && (__GNUC__ >= 4)
+#define USE_GCC_VISIBILITY_ATTRIBUTE 1
+#endif
+
+#ifdef USE_GCC_VISIBILITY_ATTRIBUTE
+#define U_EXPORT __attribute__((visibility("default")))
+#else
+#define U_EXPORT
+#endif
+
+/* U_CALLCONV is releated to U_EXPORT2 */
+#define U_EXPORT2
+
+/* cygwin needs to export/import data */
+#ifdef U_CYGWIN
+#define U_IMPORT __declspec(dllimport)
+#else
+#define U_IMPORT 
+#endif
+
+/*===========================================================================*/
+/* Code alignment and C function inlining                                    */
+/*===========================================================================*/
+
+#ifndef U_INLINE
+#   ifdef __cplusplus
+#       define U_INLINE inline
+#   else
+#       define U_INLINE inline
+#   endif
+#endif
+
+#define U_ALIGN_CODE(n) 
+
+/*===========================================================================*/
+/* Programs used by ICU code                                                 */
+/*===========================================================================*/
+
+#define U_MAKE  "/usr/bin/gnumake"

Added: MacRuby/branches/icu/unicode/ppalmos.h
===================================================================
--- MacRuby/branches/icu/unicode/ppalmos.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ppalmos.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,273 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : ppalmos.h
+*
+*   Date        Name        Description
+*   05/10/04    Ken Krugler Creation (copied from pwin32.h & modified).
+******************************************************************************
+*/
+
+#ifndef U_PPALMOS_H
+#define U_PPALMOS_H
+
+ /**
+  * \file
+  * \brief Configuration constants for the Palm OS platform
+  */
+  
+/* Define the platform we're on. */
+#ifndef U_PALMOS
+#define U_PALMOS
+#endif
+
+/* _MSC_VER is used to detect the Microsoft compiler. */
+#if defined(_MSC_VER)
+#define U_INT64_IS_LONG_LONG 0
+#else
+#define U_INT64_IS_LONG_LONG 1
+#endif
+
+/* Define whether inttypes.h is available */
+#ifndef U_HAVE_INTTYPES_H
+#define U_HAVE_INTTYPES_H 1
+#endif
+
+/*
+ * Define what support for C++ streams is available.
+ *     If U_IOSTREAM_SOURCE is set to 199711, then <iostream> is available
+ * (1997711 is the date the ISO/IEC C++ FDIS was published), and then
+ * one should qualify streams using the std namespace in ICU header
+ * files.
+ *     If U_IOSTREAM_SOURCE is set to 198506, then <iostream.h> is
+ * available instead (198506 is the date when Stroustrup published
+ * "An Extensible I/O Facility for C++" at the summer USENIX conference).
+ *     If U_IOSTREAM_SOURCE is 0, then C++ streams are not available and
+ * support for them will be silently suppressed in ICU.
+ *
+ */
+
+#ifndef U_IOSTREAM_SOURCE
+#define U_IOSTREAM_SOURCE 199711
+#endif
+
+/* Determines whether specific types are available */
+#ifndef U_HAVE_INT8_T
+#define U_HAVE_INT8_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT8_T
+#define U_HAVE_UINT8_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT16_T
+#define U_HAVE_INT16_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT16_T
+#define U_HAVE_UINT16_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT32_T
+#define U_HAVE_INT32_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT32_T
+#define U_HAVE_UINT32_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT64_T
+#define U_HAVE_INT64_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT64_T
+#define U_HAVE_UINT64_T U_HAVE_INTTYPES_H
+#endif
+
+
+/*===========================================================================*/
+/* Generic data types                                                        */
+/*===========================================================================*/
+
+/* If your platform does not have the <inttypes.h> header, you may
+   need to edit the typedefs below. */
+#if U_HAVE_INTTYPES_H
+#include <inttypes.h>
+#else /* U_HAVE_INTTYPES_H */
+
+#if ! U_HAVE_INT8_T
+typedef signed char int8_t;
+#endif
+
+#if ! U_HAVE_UINT8_T
+typedef unsigned char uint8_t;
+#endif
+
+#if ! U_HAVE_INT16_T
+typedef signed short int16_t;
+#endif
+
+#if ! U_HAVE_UINT16_T
+typedef unsigned short uint16_t;
+#endif
+
+#if ! U_HAVE_INT32_T
+typedef signed int int32_t;
+#endif
+
+#if ! U_HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+
+#if ! U_HAVE_INT64_T
+#if U_INT64_IS_LONG_LONG
+    typedef signed long long int64_t;
+#else
+    typedef signed __int64 int64_t;
+#endif
+#endif
+
+#if ! U_HAVE_UINT64_T
+#if U_INT64_IS_LONG_LONG
+    typedef unsigned long long uint64_t;
+#else
+    typedef unsigned __int64 uint64_t;
+#endif
+#endif
+#endif
+
+/*===========================================================================*/
+/* Compiler and environment features                                         */
+/*===========================================================================*/
+
+/* Define whether namespace is supported */
+#ifndef U_HAVE_NAMESPACE
+#define U_HAVE_NAMESPACE 1
+#endif
+
+/* Determines the endianness of the platform */
+#define U_IS_BIG_ENDIAN 0
+
+/* 1 or 0 to enable or disable threads.  If undefined, default is: enable threads. */
+#define ICU_USE_THREADS 1
+
+#ifndef U_DEBUG
+#ifdef _DEBUG
+#define U_DEBUG 1
+#else
+#define U_DEBUG 0
+#endif
+#endif
+
+#ifndef U_RELEASE
+#ifdef NDEBUG
+#define U_RELEASE 1
+#else
+#define U_RELEASE 0
+#endif
+#endif
+
+/* Determine whether to disable renaming or not. This overrides the
+   setting in umachine.h which is for all platforms. */
+#ifndef U_DISABLE_RENAMING
+#define U_DISABLE_RENAMING 0
+#endif
+
+/* Determine whether to override new and delete. */
+#ifndef U_OVERRIDE_CXX_ALLOCATION
+#define U_OVERRIDE_CXX_ALLOCATION 1
+#endif
+/* Determine whether to override placement new and delete for STL. */
+#ifndef U_HAVE_PLACEMENT_NEW
+#define U_HAVE_PLACEMENT_NEW 0
+#endif
+/* Determine whether to override new and delete for MFC. */
+#if !defined(U_HAVE_DEBUG_LOCATION_NEW) && defined(_MSC_VER)
+#define U_HAVE_DEBUG_LOCATION_NEW 0
+#endif
+
+/* Determine whether to enable tracing. */
+#ifndef U_ENABLE_TRACING
+#define U_ENABLE_TRACING 1
+#endif
+
+/* Do we allow ICU users to use the draft APIs by default? */
+#ifndef U_DEFAULT_SHOW_DRAFT
+#define U_DEFAULT_SHOW_DRAFT 1
+#endif
+
+/* Define the library suffix in a C syntax. */
+#define U_HAVE_LIB_SUFFIX 0
+#define U_LIB_SUFFIX_C_NAME 
+#define U_LIB_SUFFIX_C_NAME_STRING ""
+
+/*===========================================================================*/
+/* Information about wchar support                                           */
+/*===========================================================================*/
+
+#define U_HAVE_WCHAR_H 1
+#define U_SIZEOF_WCHAR_T 2
+
+#define U_HAVE_WCSCPY    0
+
+/*===========================================================================*/
+/* Information about POSIX support                                           */
+/*===========================================================================*/
+
+
+/* TODO: Fix Palm OS's determination of a timezone */
+#if 0
+#define U_TZSET         _tzset
+#endif
+#if 0
+#define U_TIMEZONE      _timezone
+#endif
+#if 0
+#define U_TZNAME        _tzname
+#endif
+
+#define U_HAVE_MMAP 0
+#define U_HAVE_POPEN 0
+
+/*===========================================================================*/
+/* Symbol import-export control                                              */
+/*===========================================================================*/
+
+#define U_EXPORT
+#define U_EXPORT2
+#define U_IMPORT
+
+/*===========================================================================*/
+/* Code alignment and C function inlining                                    */
+/*===========================================================================*/
+
+#ifndef U_INLINE
+#   ifdef __cplusplus
+#       define U_INLINE inline
+#   else
+#       define U_INLINE __inline
+#   endif
+#endif
+
+#if defined(_MSC_VER) && defined(_M_IX86)
+#define U_ALIGN_CODE(val)    __asm      align val
+#else
+#define U_ALIGN_CODE(val)
+#endif
+
+
+/*===========================================================================*/
+/* Programs used by ICU code                                                 */
+/*===========================================================================*/
+
+#ifndef U_MAKE
+#define U_MAKE  "nmake"
+#define U_MAKE_IS_NMAKE 1
+#endif
+
+#endif

Added: MacRuby/branches/icu/unicode/putil.h
===================================================================
--- MacRuby/branches/icu/unicode/putil.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/putil.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,184 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : putil.h
+*
+*   Date        Name        Description
+*   05/14/98    nos         Creation (content moved here from utypes.h).
+*   06/17/99    erm         Added IEEE_754
+*   07/22/98    stephen     Added IEEEremainder, max, min, trunc
+*   08/13/98    stephen     Added isNegativeInfinity, isPositiveInfinity
+*   08/24/98    stephen     Added longBitsFromDouble
+*   03/02/99    stephen     Removed openFile().  Added AS400 support.
+*   04/15/99    stephen     Converted to C
+*   11/15/99    helena      Integrated S/390 changes for IEEE support.
+*   01/11/00    helena      Added u_getVersion.
+******************************************************************************
+*/
+
+#ifndef PUTIL_H
+#define PUTIL_H
+
+#include "unicode/utypes.h"
+ /**
+  * \file
+  * \brief C API: Platform Utilities
+  */
+  
+/* Define this to 1 if your platform supports IEEE 754 floating point,
+   to 0 if it does not. */
+#ifndef IEEE_754
+#   define IEEE_754 1
+#endif
+
+/*==========================================================================*/
+/* Platform utilities                                                       */
+/*==========================================================================*/
+
+/**
+ * Platform utilities isolates the platform dependencies of the
+ * libarary.  For each platform which this code is ported to, these
+ * functions may have to be re-implemented.
+ */
+
+/**
+ * Return the ICU data directory. 
+ * The data directory is where common format ICU data files (.dat files)
+ *   are loaded from.  Note that normal use of the built-in ICU
+ *   facilities does not require loading of an external data file;
+ *   unless you are adding custom data to ICU, the data directory
+ *   does not need to be set.
+ *
+ * The data directory is determined as follows:
+ *    If u_setDataDirectory() has been called, that is it, otherwise
+ *    if the ICU_DATA environment variable is set, use that, otherwise
+ *    If a data directory was specifed at ICU build time
+ *      (#define ICU_DATA_DIR "path"), use that,
+ *    otherwise no data directory is available.
+ *
+ * @return the data directory, or an empty string ("") if no data directory has
+ *         been specified.
+ *   
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2 u_getDataDirectory(void);
+
+/** 
+ * Set the ICU data directory. 
+ * The data directory is where common format ICU data files (.dat files)
+ *   are loaded from.  Note that normal use of the built-in ICU
+ *   facilities does not require loading of an external data file;
+ *   unless you are adding custom data to ICU, the data directory
+ *   does not need to be set.
+ *
+ * This function should be called at most once in a process, before the
+ * first ICU operation (e.g., u_init()) that will require the loading of an
+ * ICU data file.
+ * This function is not thread-safe. Use it before calling ICU APIs from
+ * multiple threads.
+ *
+ * @param directory The directory to be set.
+ *
+ * @see u_init
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 u_setDataDirectory(const char *directory);
+
+/**
+ * Please use ucnv_getDefaultName() instead.
+ * Return the default codepage for this platform and locale.
+ * This function can call setlocale() on Unix platforms. Please read the
+ * platform documentation on setlocale() before calling this function.
+ * @return the default codepage for this platform 
+ * @internal
+ */
+U_INTERNAL const char*  U_EXPORT2 uprv_getDefaultCodepage(void);
+
+/**
+ * Please use uloc_getDefault() instead.
+ * Return the default locale ID string by querying ths system, or
+ *     zero if one cannot be found. 
+ * This function can call setlocale() on Unix platforms. Please read the
+ * platform documentation on setlocale() before calling this function.
+ * @return the default locale ID string
+ * @internal
+ */
+U_INTERNAL const char*  U_EXPORT2 uprv_getDefaultLocaleID(void);
+
+/**
+ * Filesystem file and path separator characters.
+ * Example: '/' and ':' on Unix, '\\' and ';' on Windows.
+ * @stable ICU 2.0
+ */
+#ifdef XP_MAC
+#   define U_FILE_SEP_CHAR ':'
+#   define U_FILE_ALT_SEP_CHAR ':'
+#   define U_PATH_SEP_CHAR ';'
+#   define U_FILE_SEP_STRING ":"
+#   define U_FILE_ALT_SEP_STRING ":"
+#   define U_PATH_SEP_STRING ";"
+#elif defined(U_WINDOWS)
+#   define U_FILE_SEP_CHAR '\\'
+#   define U_FILE_ALT_SEP_CHAR '/'
+#   define U_PATH_SEP_CHAR ';'
+#   define U_FILE_SEP_STRING "\\"
+#   define U_FILE_ALT_SEP_STRING "/"
+#   define U_PATH_SEP_STRING ";"
+#else
+#   define U_FILE_SEP_CHAR '/'
+#   define U_FILE_ALT_SEP_CHAR '/'
+#   define U_PATH_SEP_CHAR ':'
+#   define U_FILE_SEP_STRING "/"
+#   define U_FILE_ALT_SEP_STRING "/"
+#   define U_PATH_SEP_STRING ":"
+#endif
+
+/**
+ * Convert char characters to UChar characters.
+ * This utility function is useful only for "invariant characters"
+ * that are encoded in the platform default encoding.
+ * They are a small, constant subset of the encoding and include
+ * just the latin letters, digits, and some punctuation.
+ * For details, see U_CHARSET_FAMILY.
+ *
+ * @param cs Input string, points to <code>length</code>
+ *           character bytes from a subset of the platform encoding.
+ * @param us Output string, points to memory for <code>length</code>
+ *           Unicode characters.
+ * @param length The number of characters to convert; this may
+ *               include the terminating <code>NUL</code>.
+ *
+ * @see U_CHARSET_FAMILY
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+u_charsToUChars(const char *cs, UChar *us, int32_t length);
+
+/**
+ * Convert UChar characters to char characters.
+ * This utility function is useful only for "invariant characters"
+ * that can be encoded in the platform default encoding.
+ * They are a small, constant subset of the encoding and include
+ * just the latin letters, digits, and some punctuation.
+ * For details, see U_CHARSET_FAMILY.
+ *
+ * @param us Input string, points to <code>length</code>
+ *           Unicode characters that can be encoded with the
+ *           codepage-invariant subset of the platform encoding.
+ * @param cs Output string, points to memory for <code>length</code>
+ *           character bytes.
+ * @param length The number of characters to convert; this may
+ *               include the terminating <code>NUL</code>.
+ *
+ * @see U_CHARSET_FAMILY
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+u_UCharsToChars(const UChar *us, char *cs, int32_t length);
+
+#endif

Added: MacRuby/branches/icu/unicode/pwin32.h
===================================================================
--- MacRuby/branches/icu/unicode/pwin32.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/pwin32.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,298 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : platform.h
+*
+*   Date        Name        Description
+*   05/13/98    nos         Creation (content moved here from ptypes.h).
+*   03/02/99    stephen     Added AS400 support.
+*   03/30/99    stephen     Added Linux support.
+*   04/13/99    stephen     Reworked for autoconf.
+******************************************************************************
+*/
+
+ /**
+  * \file
+  * \brief Configuration constants for the Windows platform
+  */
+  
+/* Define the platform we're on. */
+#ifndef U_WINDOWS
+#define U_WINDOWS
+#endif
+
+#if defined(__BORLANDC__)
+#define U_HAVE_PLACEMENT_NEW 0
+#define U_HAVE_INTTYPES_H 1
+#define __STDC_CONSTANT_MACROS
+#endif
+
+/* _MSC_VER is used to detect the Microsoft compiler. */
+#if defined(_MSC_VER)
+#define U_INT64_IS_LONG_LONG 0
+#else
+#define U_INT64_IS_LONG_LONG 1
+#endif
+
+/* Define whether inttypes.h is available */
+#ifndef U_HAVE_INTTYPES_H
+#define U_HAVE_INTTYPES_H 0
+#endif
+
+/*
+ * Define what support for C++ streams is available.
+ *     If U_IOSTREAM_SOURCE is set to 199711, then <iostream> is available
+ * (1997711 is the date the ISO/IEC C++ FDIS was published), and then
+ * one should qualify streams using the std namespace in ICU header
+ * files.
+ *     If U_IOSTREAM_SOURCE is set to 198506, then <iostream.h> is
+ * available instead (198506 is the date when Stroustrup published
+ * "An Extensible I/O Facility for C++" at the summer USENIX conference).
+ *     If U_IOSTREAM_SOURCE is 0, then C++ streams are not available and
+ * support for them will be silently suppressed in ICU.
+ *
+ */
+
+#ifndef U_IOSTREAM_SOURCE
+#define U_IOSTREAM_SOURCE 199711
+#endif
+
+/* Determines whether specific types are available */
+#ifndef U_HAVE_INT8_T
+#define U_HAVE_INT8_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT8_T
+#define U_HAVE_UINT8_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT16_T
+#define U_HAVE_INT16_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT16_T
+#define U_HAVE_UINT16_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT32_T
+#define U_HAVE_INT32_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT32_T
+#define U_HAVE_UINT32_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_INT64_T
+#define U_HAVE_INT64_T U_HAVE_INTTYPES_H
+#endif
+
+#ifndef U_HAVE_UINT64_T
+#define U_HAVE_UINT64_T U_HAVE_INTTYPES_H
+#endif
+
+/* Define 64 bit limits */
+#if !U_INT64_IS_LONG_LONG
+# ifndef INT64_C
+#  define INT64_C(x) ((int64_t)x)
+# endif
+# ifndef UINT64_C
+#  define UINT64_C(x) ((uint64_t)x)
+# endif
+/* else use the umachine.h definition */
+#endif
+
+/*===========================================================================*/
+/* Generic data types                                                        */
+/*===========================================================================*/
+
+/* If your platform does not have the <inttypes.h> header, you may
+   need to edit the typedefs below. */
+#if U_HAVE_INTTYPES_H
+#include <inttypes.h>
+#else /* U_HAVE_INTTYPES_H */
+
+#if ! U_HAVE_INT8_T
+typedef signed char int8_t;
+#endif
+
+#if ! U_HAVE_UINT8_T
+typedef unsigned char uint8_t;
+#endif
+
+#if ! U_HAVE_INT16_T
+typedef signed short int16_t;
+#endif
+
+#if ! U_HAVE_UINT16_T
+typedef unsigned short uint16_t;
+#endif
+
+#if ! U_HAVE_INT32_T
+typedef signed int int32_t;
+#endif
+
+#if ! U_HAVE_UINT32_T
+typedef unsigned int uint32_t;
+#endif
+
+#if ! U_HAVE_INT64_T
+#if U_INT64_IS_LONG_LONG
+    typedef signed long long int64_t;
+#else
+    typedef signed __int64 int64_t;
+#endif
+#endif
+
+#if ! U_HAVE_UINT64_T
+#if U_INT64_IS_LONG_LONG
+    typedef unsigned long long uint64_t;
+#else
+    typedef unsigned __int64 uint64_t;
+#endif
+#endif
+#endif
+
+/*===========================================================================*/
+/* Compiler and environment features                                         */
+/*===========================================================================*/
+
+/* Define whether namespace is supported */
+#ifndef U_HAVE_NAMESPACE
+#define U_HAVE_NAMESPACE 1
+#endif
+
+/* Determines the endianness of the platform */
+#define U_IS_BIG_ENDIAN 0
+
+/* 1 or 0 to enable or disable threads.  If undefined, default is: enable threads. */
+#define ICU_USE_THREADS 1
+
+/* On strong memory model CPUs (e.g. x86 CPUs), we use a safe & quick double check mutex lock. */
+/*
+Microsoft can define _M_IX86, _M_AMD64 (before Visual Studio 8) or _M_X64 (starting in Visual Studio 8). 
+Intel can define _M_IX86 or _M_X64
+*/
+#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
+#define UMTX_STRONG_MEMORY_MODEL 1
+#endif
+
+#ifndef U_DEBUG
+#ifdef _DEBUG
+#define U_DEBUG 1
+#else
+#define U_DEBUG 0
+#endif
+#endif
+
+#ifndef U_RELEASE
+#ifdef NDEBUG
+#define U_RELEASE 1
+#else
+#define U_RELEASE 0
+#endif
+#endif
+
+/* Determine whether to disable renaming or not. This overrides the
+   setting in umachine.h which is for all platforms. */
+#ifndef U_DISABLE_RENAMING
+#define U_DISABLE_RENAMING 0
+#endif
+
+/* Determine whether to override new and delete. */
+#ifndef U_OVERRIDE_CXX_ALLOCATION
+#define U_OVERRIDE_CXX_ALLOCATION 1
+#endif
+/* Determine whether to override placement new and delete for STL. */
+#ifndef U_HAVE_PLACEMENT_NEW
+#define U_HAVE_PLACEMENT_NEW 1
+#endif
+/* Determine whether to override new and delete for MFC. */
+#if !defined(U_HAVE_DEBUG_LOCATION_NEW) && defined(_MSC_VER)
+#define U_HAVE_DEBUG_LOCATION_NEW 1
+#endif
+
+/* Determine whether to enable tracing. */
+#ifndef U_ENABLE_TRACING
+#define U_ENABLE_TRACING 1
+#endif
+
+/* Do we allow ICU users to use the draft APIs by default? */
+#ifndef U_DEFAULT_SHOW_DRAFT
+#define U_DEFAULT_SHOW_DRAFT 1
+#endif
+
+/* Define the library suffix in a C syntax. */
+#define U_HAVE_LIB_SUFFIX 0
+#define U_LIB_SUFFIX_C_NAME 
+#define U_LIB_SUFFIX_C_NAME_STRING ""
+
+/*===========================================================================*/
+/* Information about wchar support                                           */
+/*===========================================================================*/
+
+#define U_HAVE_WCHAR_H 1
+#define U_SIZEOF_WCHAR_T 2
+
+#define U_HAVE_WCSCPY 1
+
+/*===========================================================================*/
+/* Information about POSIX support                                           */
+/*===========================================================================*/
+
+#if 1
+#define U_TZSET         _tzset
+#endif
+#if 1
+#define U_TIMEZONE      _timezone
+#endif
+#if 1
+#define U_TZNAME        _tzname
+#endif
+
+#define U_HAVE_MMAP 0
+#define U_HAVE_POPEN 0
+
+/*===========================================================================*/
+/* Symbol import-export control                                              */
+/*===========================================================================*/
+
+#ifdef U_STATIC_IMPLEMENTATION
+#define U_EXPORT
+#else
+#define U_EXPORT __declspec(dllexport)
+#endif
+#define U_EXPORT2 __cdecl
+#define U_IMPORT __declspec(dllimport)
+
+/*===========================================================================*/
+/* Code alignment and C function inlining                                    */
+/*===========================================================================*/
+
+#ifndef U_INLINE
+#   ifdef __cplusplus
+#       define U_INLINE inline
+#   else
+#       define U_INLINE __inline
+#   endif
+#endif
+
+#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_MANAGED)
+#define U_ALIGN_CODE(val)    __asm      align val
+#else
+#define U_ALIGN_CODE(val)
+#endif
+
+
+/*===========================================================================*/
+/* Programs used by ICU code                                                 */
+/*===========================================================================*/
+
+#ifndef U_MAKE
+#define U_MAKE  "nmake"
+#define U_MAKE_IS_NMAKE 1
+#endif

Added: MacRuby/branches/icu/unicode/rbbi.h
===================================================================
--- MacRuby/branches/icu/unicode/rbbi.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/rbbi.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,700 @@
+/*
+***************************************************************************
+*   Copyright (C) 1999-2006 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+
+**********************************************************************
+*   Date        Name        Description
+*   10/22/99    alan        Creation.
+*   11/11/99    rgillam     Complete port from Java.
+**********************************************************************
+*/
+
+#ifndef RBBI_H
+#define RBBI_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file
+ * \brief C++ API: Rule Based Break Iterator
+ */
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/brkiter.h"
+#include "unicode/udata.h"
+#include "unicode/parseerr.h"
+#include "unicode/schriter.h"
+#include "unicode/uchriter.h"
+
+
+struct UTrie;
+
+U_NAMESPACE_BEGIN
+
+/** @internal */
+struct RBBIDataHeader;
+class  RuleBasedBreakIteratorTables;
+class  BreakIterator;
+class  RBBIDataWrapper;
+class  UStack;
+class  LanguageBreakEngine;
+class  UnhandledEngine;
+struct RBBIStateTable;
+
+
+
+
+/**
+ *
+ * A subclass of BreakIterator whose behavior is specified using a list of rules.
+ * <p>Instances of this class are most commonly created by the factory methods of
+ *  BreakIterator::createWordInstance(), BreakIterator::createLineInstance(), etc.,
+ *  and then used via the abstract API in class BreakIterator</p>
+ *
+ * <p>See the ICU User Guide for information on Break Iterator Rules.</p>
+ *
+ * <p>This class is not intended to be subclassed.  (Class DictionaryBasedBreakIterator
+ *    is a subclass, but that relationship is effectively internal to the ICU
+ *    implementation.  The subclassing interface to RulesBasedBreakIterator is
+ *    not part of the ICU API, and may not remain stable.</p>
+ *
+ */
+class U_COMMON_API RuleBasedBreakIterator : public BreakIterator {
+
+protected:
+    /**
+     * The UText through which this BreakIterator accesses the text
+     * @internal
+     */
+    UText  *fText;
+
+    /**
+     *   A character iterator that refers to the same text as the UText, above.
+     *   Only included for compatibility with old API, which was based on CharacterIterators.
+     *   Value may be adopted from outside, or one of fSCharIter or fDCharIter, below.
+     */
+    CharacterIterator  *fCharIter;
+
+    /**
+     *   When the input text is provided by a UnicodeString, this will point to
+     *    a characterIterator that wraps that data.  Needed only for the
+     *    implementation of getText(), a backwards compatibility issue.
+     */
+    StringCharacterIterator *fSCharIter;
+
+    /**
+     *  When the input text is provided by a UText, this
+     *    dummy CharacterIterator over an empty string will
+     *    be returned from getText()
+     */
+    UCharCharacterIterator *fDCharIter;
+
+    /**
+     * The rule data for this BreakIterator instance
+     * @internal
+     */
+    RBBIDataWrapper    *fData;
+
+    /** Index of the Rule {tag} values for the most recent match.
+     *  @internal
+    */
+    int32_t             fLastRuleStatusIndex;
+
+    /**
+     * Rule tag value valid flag.
+     * Some iterator operations don't intrinsically set the correct tag value.
+     * This flag lets us lazily compute the value if we are ever asked for it.
+     * @internal
+     */
+    UBool               fLastStatusIndexValid;
+
+    /**
+     * Counter for the number of characters encountered with the "dictionary"
+     *   flag set.
+     * @internal
+     */
+    uint32_t            fDictionaryCharCount;
+
+    /**
+     * When a range of characters is divided up using the dictionary, the break
+     * positions that are discovered are stored here, preventing us from having
+     * to use either the dictionary or the state table again until the iterator
+     * leaves this range of text. Has the most impact for line breaking.
+     * @internal
+     */
+    int32_t*            fCachedBreakPositions;
+
+    /**
+     * The number of elements in fCachedBreakPositions
+     * @internal
+     */
+    int32_t             fNumCachedBreakPositions;
+
+    /**
+     * if fCachedBreakPositions is not null, this indicates which item in the
+     * cache the current iteration position refers to
+     * @internal
+     */
+    int32_t             fPositionInCache;
+    
+    /**
+     *
+     * If present, UStack of LanguageBreakEngine objects that might handle
+     * dictionary characters. Searched from top to bottom to find an object to
+     * handle a given character.
+     * @internal
+     */
+    UStack              *fLanguageBreakEngines;
+    
+    /**
+     *
+     * If present, the special LanguageBreakEngine used for handling
+     * characters that are in the dictionary set, but not handled by any
+     * LangugageBreakEngine.
+     * @internal
+     */
+    UnhandledEngine     *fUnhandledBreakEngine;
+    
+    /**
+     *
+     * The type of the break iterator, or -1 if it has not been set.
+     * @internal
+     */
+    int32_t             fBreakType;
+    
+protected:
+    //=======================================================================
+    // constructors
+    //=======================================================================
+
+    /**
+     * Constructor from a flattened set of RBBI data in malloced memory.
+     *             RulesBasedBreakIterators built from a custom set of rules
+     *             are created via this constructor; the rules are compiled
+     *             into memory, then the break iterator is constructed here.
+     *
+     *             The break iterator adopts the memory, and will
+     *             free it when done.
+     * @internal
+     */
+    RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status);
+
+
+    friend class RBBIRuleBuilder;
+    /** @internal */
+    friend class BreakIterator;
+
+
+
+public:
+
+    /** Default constructor.  Creates an empty shell of an iterator, with no
+     *  rules or text to iterate over.   Object can subsequently be assigned to.
+     *  @stable ICU 2.2
+     */
+    RuleBasedBreakIterator();
+
+    /**
+     * Copy constructor.  Will produce a break iterator with the same behavior,
+     * and which iterates over the same text, as the one passed in.
+     * @param that The RuleBasedBreakIterator passed to be copied
+     * @stable ICU 2.0
+     */
+    RuleBasedBreakIterator(const RuleBasedBreakIterator& that);
+
+    /**
+     * Construct a RuleBasedBreakIterator from a set of rules supplied as a string.
+     * @param rules The break rules to be used.
+     * @param parseError  In the event of a syntax error in the rules, provides the location
+     *                    within the rules of the problem.
+     * @param status Information on any errors encountered.
+     * @stable ICU 2.2
+     */
+    RuleBasedBreakIterator( const UnicodeString    &rules,
+                             UParseError           &parseError,
+                             UErrorCode            &status);
+
+
+    /**
+     * This constructor uses the udata interface to create a BreakIterator
+     * whose internal tables live in a memory-mapped file.  "image" is an
+     * ICU UDataMemory handle for the pre-compiled break iterator tables.
+     * @param image handle to the memory image for the break iterator data.
+     *        Ownership of the UDataMemory handle passes to the Break Iterator,
+     *        which will be responsible for closing it when it is no longer needed.
+     * @param status Information on any errors encountered.
+     * @see udata_open
+     * @see #getBinaryRules
+     * @stable ICU 2.8
+     */
+    RuleBasedBreakIterator(UDataMemory* image, UErrorCode &status);
+
+    /**
+     * Destructor
+     *  @stable ICU 2.0
+     */
+    virtual ~RuleBasedBreakIterator();
+
+    /**
+     * Assignment operator.  Sets this iterator to have the same behavior,
+     * and iterate over the same text, as the one passed in.
+     * @param that The RuleBasedBreakItertor passed in
+     * @return the newly created RuleBasedBreakIterator
+     *  @stable ICU 2.0
+     */
+    RuleBasedBreakIterator& operator=(const RuleBasedBreakIterator& that);
+
+    /**
+     * Equality operator.  Returns TRUE if both BreakIterators are of the
+     * same class, have the same behavior, and iterate over the same text.
+     * @param that The BreakIterator to be compared for equality
+     * @return TRUE if both BreakIterators are of the
+     * same class, have the same behavior, and iterate over the same text.
+     *  @stable ICU 2.0
+     */
+    virtual UBool operator==(const BreakIterator& that) const;
+
+    /**
+     * Not-equal operator.  If operator== returns TRUE, this returns FALSE,
+     * and vice versa.
+     * @param that The BreakIterator to be compared for inequality
+     * @return TRUE if both BreakIterators are not same.
+     *  @stable ICU 2.0
+     */
+    UBool operator!=(const BreakIterator& that) const;
+
+    /**
+     * Returns a newly-constructed RuleBasedBreakIterator with the same
+     * behavior, and iterating over the same text, as this one.
+     * Differs from the copy constructor in that it is polymorphic, and
+     * will correctly clone (copy) a derived class.
+     * clone() is thread safe.  Multiple threads may simultaeneously
+     * clone the same source break iterator.
+     * @return a newly-constructed RuleBasedBreakIterator
+     * @stable ICU 2.0
+     */
+    virtual BreakIterator* clone() const;
+
+    /**
+     * Compute a hash code for this BreakIterator
+     * @return A hash code
+     *  @stable ICU 2.0
+     */
+    virtual int32_t hashCode(void) const;
+
+    /**
+     * Returns the description used to create this iterator
+     * @return the description used to create this iterator
+     *  @stable ICU 2.0
+     */
+    virtual const UnicodeString& getRules(void) const;
+
+    //=======================================================================
+    // BreakIterator overrides
+    //=======================================================================
+
+    /**
+     * <p>
+     * Return a CharacterIterator over the text being analyzed.
+     * The returned character iterator is owned by the break iterator, and must
+     * not be deleted by the caller.  Repeated calls to this function may
+     * return the same CharacterIterator.
+     * </p>
+     * <p>
+     * The returned character iterator must not be used concurrently with
+     * the break iterator.  If concurrent operation is needed, clone the
+     * returned character iterator first and operate on the clone.
+     * </p>
+     * <p>
+     * When the break iterator is operating on text supplied via a UText,
+     * this function will fail.  Lacking any way to signal failures, it
+     * returns an CharacterIterator containing no text.
+     * The function getUText() provides similar functionality,
+     * is reliable, and is more efficient.
+     * </p>
+     *
+     * TODO:  deprecate this function?
+     *
+     * @return An iterator over the text being analyzed.
+     * @stable ICU 2.0
+     */
+    virtual  CharacterIterator& getText(void) const;
+
+
+    /**
+      *  Get a UText for the text being analyzed.
+      *  The returned UText is a shallow clone of the UText used internally
+      *  by the break iterator implementation.  It can safely be used to
+      *  access the text without impacting any break iterator operations,
+      *  but the underlying text itself must not be altered.
+      *
+      * @param fillIn A UText to be filled in.  If NULL, a new UText will be
+      *           allocated to hold the result.
+      * @param status receives any error codes.
+      * @return   The current UText for this break iterator.  If an input
+      *           UText was provided, it will always be returned.
+      * @draft ICU 3.4
+      */
+     virtual UText *getUText(UText *fillIn, UErrorCode &status) const;
+
+    /**
+     * Set the iterator to analyze a new piece of text.  This function resets
+     * the current iteration position to the beginning of the text.
+     * @param newText An iterator over the text to analyze.  The BreakIterator
+     * takes ownership of the character iterator.  The caller MUST NOT delete it!
+     *  @stable ICU 2.0
+     */
+    virtual void adoptText(CharacterIterator* newText);
+
+    /**
+     * Set the iterator to analyze a new piece of text.  This function resets
+     * the current iteration position to the beginning of the text.
+     * @param newText The text to analyze.
+     *  @stable ICU 2.0
+     */
+    virtual void setText(const UnicodeString& newText);
+
+    /**
+     * Reset the break iterator to operate over the text represented by
+     * the UText.  The iterator position is reset to the start.
+     *
+     * This function makes a shallow clone of the supplied UText.  This means
+     * that the caller is free to immediately close or otherwise reuse the
+     * Utext that was passed as a parameter, but that the underlying text itself
+     * must not be altered while being referenced by the break iterator.
+     *
+     * @param text    The UText used to change the text.
+     * @param status  Receives any error codes.
+     * @draft ICU 3.4
+     */
+    virtual void  setText(UText *text, UErrorCode &status);
+
+    /**
+     * Sets the current iteration position to the beginning of the text.
+     * @return The offset of the beginning of the text.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t first(void);
+
+    /**
+     * Sets the current iteration position to the end of the text.
+     * @return The text's past-the-end offset.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t last(void);
+
+    /**
+     * Advances the iterator either forward or backward the specified number of steps.
+     * Negative values move backward, and positive values move forward.  This is
+     * equivalent to repeatedly calling next() or previous().
+     * @param n The number of steps to move.  The sign indicates the direction
+     * (negative is backwards, and positive is forwards).
+     * @return The character offset of the boundary position n boundaries away from
+     * the current one.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t next(int32_t n);
+
+    /**
+     * Advances the iterator to the next boundary position.
+     * @return The position of the first boundary after this one.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t next(void);
+
+    /**
+     * Moves the iterator backwards, to the last boundary preceding this one.
+     * @return The position of the last boundary position preceding this one.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t previous(void);
+
+    /**
+     * Sets the iterator to refer to the first boundary position following
+     * the specified position.
+     * @param offset The position from which to begin searching for a break position.
+     * @return The position of the first break after the current position.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t following(int32_t offset);
+
+    /**
+     * Sets the iterator to refer to the last boundary position before the
+     * specified position.
+     * @param offset The position to begin searching for a break from.
+     * @return The position of the last boundary before the starting position.
+     *  @stable ICU 2.0
+     */
+    virtual int32_t preceding(int32_t offset);
+
+    /**
+     * Returns true if the specfied position is a boundary position.  As a side
+     * effect, leaves the iterator pointing to the first boundary position at
+     * or after "offset".
+     * @param offset the offset to check.
+     * @return True if "offset" is a boundary position.
+     *  @stable ICU 2.0
+     */
+    virtual UBool isBoundary(int32_t offset);
+
+    /**
+     * Returns the current iteration position.
+     * @return The current iteration position.
+     * @stable ICU 2.0
+     */
+    virtual int32_t current(void) const;
+
+
+    /**
+     * Return the status tag from the break rule that determined the most recently
+     * returned break position.  For break rules that do not specify a
+     * status, a default value of 0 is returned.  If more than one break rule
+     * would cause a boundary to be located at some position in the text,
+     * the numerically largest of the applicable status values is returned.
+     * <p>
+     * Of the standard types of ICU break iterators, only word break and
+     * line break provide status values.  The values are defined in
+     * the header file ubrk.h.  For Word breaks, the status allows distinguishing between words
+     * that contain alphabetic letters, "words" that appear to be numbers,
+     * punctuation and spaces, words containing ideographic characters, and
+     * more.  For Line Break, the status distinguishes between hard (mandatory) breaks
+     * and soft (potential) break positions.
+     * <p>
+     * <code>getRuleStatus()</code> can be called after obtaining a boundary
+     * position from <code>next()</code>, <code>previous()</code>, or
+     * any other break iterator functions that returns a boundary position.
+     * <p>
+     * When creating custom break rules, one is free to define whatever
+     * status values may be convenient for the application.
+     * <p>
+     * Note: this function is not thread safe.  It should not have been
+     *       declared const, and the const remains only for compatibility
+     *       reasons.  (The function is logically const, but not bit-wise const).
+     * <p>
+     * @return the status from the break rule that determined the most recently
+     * returned break position.
+     *
+     * @see UWordBreak
+     * @stable ICU 2.2
+     */
+    virtual int32_t getRuleStatus() const;
+
+   /**
+    * Get the status (tag) values from the break rule(s) that determined the most
+    * recently returned break position.
+    * <p>
+    * The returned status value(s) are stored into an array provided by the caller.
+    * The values are stored in sorted (ascending) order.
+    * If the capacity of the output array is insufficient to hold the data,
+    *  the output will be truncated to the available length, and a
+    *  U_BUFFER_OVERFLOW_ERROR will be signaled.
+    *
+    * @param fillInVec an array to be filled in with the status values.
+    * @param capacity  the length of the supplied vector.  A length of zero causes
+    *                  the function to return the number of status values, in the
+    *                  normal way, without attemtping to store any values.
+    * @param status    receives error codes.
+    * @return          The number of rule status values from rules that determined
+    *                  the most recent boundary returned by the break iterator.
+    *                  In the event of a U_BUFFER_OVERFLOW_ERROR, the return value
+    *                  is the total number of status values that were available,
+    *                  not the reduced number that were actually returned.
+    * @see getRuleStatus
+    * @stable ICU 3.0
+    */
+    virtual int32_t getRuleStatusVec(int32_t *fillInVec, int32_t capacity, UErrorCode &status);
+
+    /**
+     * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
+     * This method is to implement a simple version of RTTI, since not all
+     * C++ compilers support genuine RTTI.  Polymorphic operator==() and
+     * clone() methods call this method.
+     *
+     * @return          The class ID for this object. All objects of a
+     *                  given class have the same class ID.  Objects of
+     *                  other classes have different class IDs.
+     * @stable ICU 2.0
+     */
+    virtual UClassID getDynamicClassID(void) const;
+
+    /**
+     * Returns the class ID for this class.  This is useful only for
+     * comparing to a return value from getDynamicClassID().  For example:
+     *
+     *      Base* polymorphic_pointer = createPolymorphicObject();
+     *      if (polymorphic_pointer->getDynamicClassID() ==
+     *          Derived::getStaticClassID()) ...
+     *
+     * @return          The class ID for all objects of this class.
+     * @stable ICU 2.0
+     */
+    static UClassID U_EXPORT2 getStaticClassID(void);
+
+    /*
+     * Create a clone (copy) of this break iterator in memory provided
+     *  by the caller.  The idea is to increase performance by avoiding
+     *  a storage allocation.  Use of this functoin is NOT RECOMMENDED.
+     *  Performance gains are minimal, and correct buffer management is
+     *  tricky.  Use clone() instead.
+     *
+     * @param stackBuffer  The pointer to the memory into which the cloned object
+     *                     should be placed.  If NULL,  allocate heap memory
+     *                     for the cloned object.
+     * @param BufferSize   The size of the buffer.  If zero, return the required
+     *                     buffer size, but do not clone the object.  If the
+     *                     size was too small (but not zero), allocate heap
+     *                     storage for the cloned object.
+     *
+     * @param status       Error status.  U_SAFECLONE_ALLOCATED_WARNING will be
+     *                     returned if the the provided buffer was too small, and
+     *                     the clone was therefore put on the heap.
+     *
+     * @return  Pointer to the clone object.  This may differ from the stackBuffer
+     *          address if the byte alignment of the stack buffer was not suitable
+     *          or if the stackBuffer was too small to hold the clone.
+     * @stable ICU 2.0
+     */
+    virtual BreakIterator *  createBufferClone(void *stackBuffer,
+                                               int32_t &BufferSize,
+                                               UErrorCode &status);
+
+
+    /**
+     * Return the binary form of compiled break rules,
+     * which can then be used to create a new break iterator at some
+     * time in the future.  Creating a break iterator from pre-compiled rules
+     * is much faster than building one from the source form of the
+     * break rules.
+     *
+     * The binary data can only be used with the same version of ICU
+     *  and on the same platform type (processor endian-ness)
+     *
+     * @param length Returns the length of the binary data.  (Out paramter.)
+     *
+     * @return   A pointer to the binary (compiled) rule data.  The storage
+     *           belongs to the RulesBasedBreakIterator object, not the
+     *           caller, and must not be modified or deleted.
+     * @internal
+     */
+    virtual const uint8_t *getBinaryRules(uint32_t &length);
+
+
+protected:
+    //=======================================================================
+    // implementation
+    //=======================================================================
+    /**
+     * Dumps caches and performs other actions associated with a complete change
+     * in text or iteration position.
+     * @internal
+     */
+    virtual void reset(void);
+
+#if 0
+    /**
+      * Return true if the category lookup for this char
+      * indicates that it is in the set of dictionary lookup chars.
+      * This function is intended for use by dictionary based break iterators.
+      * @return true if the category lookup for this char
+      * indicates that it is in the set of dictionary lookup chars.
+      * @internal
+      */
+    virtual UBool isDictionaryChar(UChar32);
+
+    /**
+      * Get the type of the break iterator.
+      * @internal
+      */
+    virtual int32_t getBreakType() const;
+#endif
+
+    /**
+      * Set the type of the break iterator.
+      * @internal
+      */
+    virtual void setBreakType(int32_t type);
+
+    /**
+      * Common initialization function, used by constructors and bufferClone.
+      *   (Also used by DictionaryBasedBreakIterator::createBufferClone().)
+      * @internal
+      */
+    void init();
+
+private:
+
+    /**
+     * This method backs the iterator back up to a "safe position" in the text.
+     * This is a position that we know, without any context, must be a break position.
+     * The various calling methods then iterate forward from this safe position to
+     * the appropriate position to return.  (For more information, see the description
+     * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
+     * @param statetable state table used of moving backwards
+     * @internal
+     */
+    int32_t handlePrevious(const RBBIStateTable *statetable);
+
+    /**
+     * This method is the actual implementation of the next() method.  All iteration
+     * vectors through here.  This method initializes the state machine to state 1
+     * and advances through the text character by character until we reach the end
+     * of the text or the state machine transitions to state 0.  We update our return
+     * value every time the state machine passes through a possible end state.
+     * @param statetable state table used of moving forwards
+     * @internal
+     */
+    int32_t handleNext(const RBBIStateTable *statetable);
+
+protected:
+
+    /**
+     * This is the function that actually implements dictionary-based
+     * breaking.  Covering at least the range from startPos to endPos,
+     * it checks for dictionary characters, and if it finds them determines
+     * the appropriate object to deal with them. It may cache found breaks in
+     * fCachedBreakPositions as it goes. It may well also look at text outside
+     * the range startPos to endPos.
+     * If going forward, endPos is the normal Unicode break result, and
+     * if goind in reverse, startPos is the normal Unicode break result
+     * @param startPos  The start position of a range of text
+     * @param endPos    The end position of a range of text
+     * @param reverse   The call is for the reverse direction
+     * @internal
+     */
+    int32_t checkDictionary(int32_t startPos, int32_t endPos, UBool reverse);
+
+private:
+
+    /**
+     * This function returns the appropriate LanguageBreakEngine for a
+     * given character c.
+     * @param c         A character in the dictionary set
+     * @internal
+     */
+    const LanguageBreakEngine *getLanguageBreakEngine(UChar32 c);
+
+    /**
+     *  @internal
+     */
+    void makeRuleStatusValid();
+
+};
+
+//------------------------------------------------------------------------------
+//
+//   Inline Functions Definitions ...
+//
+//------------------------------------------------------------------------------
+
+inline UBool RuleBasedBreakIterator::operator!=(const BreakIterator& that) const {
+    return !operator==(that);
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
+#endif

Added: MacRuby/branches/icu/unicode/rep.h
===================================================================
--- MacRuby/branches/icu/unicode/rep.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/rep.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,259 @@
+/*
+**************************************************************************
+* Copyright (C) 1999-2005, International Business Machines Corporation and
+* others. All Rights Reserved.
+**************************************************************************
+*   Date        Name        Description
+*   11/17/99    aliu        Creation.  Ported from java.  Modified to
+*                           match current UnicodeString API.  Forced
+*                           to use name "handleReplaceBetween" because
+*                           of existing methods in UnicodeString.
+**************************************************************************
+*/
+
+#ifndef REP_H
+#define REP_H
+
+#include "unicode/uobject.h"
+
+/**
+ * \file 
+ * \brief C++ API: Replaceable String
+ */
+ 
+U_NAMESPACE_BEGIN
+
+class UnicodeString;
+
+/**
+ * <code>Replaceable</code> is an abstract base class representing a
+ * string of characters that supports the replacement of a range of
+ * itself with a new string of characters.  It is used by APIs that
+ * change a piece of text while retaining metadata.  Metadata is data
+ * other than the Unicode characters returned by char32At().  One
+ * example of metadata is style attributes; another is an edit
+ * history, marking each character with an author and revision number.
+ *
+ * <p>An implicit aspect of the <code>Replaceable</code> API is that
+ * during a replace operation, new characters take on the metadata of
+ * the old characters.  For example, if the string "the <b>bold</b>
+ * font" has range (4, 8) replaced with "strong", then it becomes "the
+ * <b>strong</b> font".
+ *
+ * <p><code>Replaceable</code> specifies ranges using a start
+ * offset and a limit offset.  The range of characters thus specified
+ * includes the characters at offset start..limit-1.  That is, the
+ * start offset is inclusive, and the limit offset is exclusive.
+ *
+ * <p><code>Replaceable</code> also includes API to access characters
+ * in the string: <code>length()</code>, <code>charAt()</code>,
+ * <code>char32At()</code>, and <code>extractBetween()</code>.
+ *
+ * <p>For a subclass to support metadata, typical behavior of
+ * <code>replace()</code> is the following:
+ * <ul>
+ *   <li>Set the metadata of the new text to the metadata of the first
+ *   character replaced</li>
+ *   <li>If no characters are replaced, use the metadata of the
+ *   previous character</li>
+ *   <li>If there is no previous character (i.e. start == 0), use the
+ *   following character</li>
+ *   <li>If there is no following character (i.e. the replaceable was
+ *   empty), use default metadata.<br>
+ *   <li>If the code point U+FFFF is seen, it should be interpreted as
+ *   a special marker having no metadata<li>
+ *   </li>
+ * </ul>
+ * If this is not the behavior, the subclass should document any differences.
+ * @author Alan Liu
+ * @stable ICU 2.0
+ */
+class U_COMMON_API Replaceable : public UObject {
+
+public:
+    /**
+     * Destructor.
+     * @stable ICU 2.0
+     */
+    virtual ~Replaceable();
+
+    /**
+     * Returns the number of 16-bit code units in the text.
+     * @return number of 16-bit code units in text
+     * @stable ICU 1.8
+     */ 
+    inline int32_t length() const;
+
+    /**
+     * Returns the 16-bit code unit at the given offset into the text.
+     * @param offset an integer between 0 and <code>length()</code>-1
+     * inclusive
+     * @return 16-bit code unit of text at given offset
+     * @stable ICU 1.8
+     */
+    inline UChar charAt(int32_t offset) const;
+
+    /**
+     * Returns the 32-bit code point at the given 16-bit offset into
+     * the text.  This assumes the text is stored as 16-bit code units
+     * with surrogate pairs intermixed.  If the offset of a leading or
+     * trailing code unit of a surrogate pair is given, return the
+     * code point of the surrogate pair.
+     *
+     * @param offset an integer between 0 and <code>length()</code>-1
+     * inclusive
+     * @return 32-bit code point of text at given offset
+     * @stable ICU 1.8
+     */
+    inline UChar32 char32At(int32_t offset) const;
+
+    /**
+     * Copies characters in the range [<tt>start</tt>, <tt>limit</tt>) 
+     * into the UnicodeString <tt>target</tt>.
+     * @param start offset of first character which will be copied
+     * @param limit offset immediately following the last character to
+     * be copied
+     * @param target UnicodeString into which to copy characters.
+     * @return A reference to <TT>target</TT>
+     * @stable ICU 2.1
+     */
+    virtual void extractBetween(int32_t start,
+                                int32_t limit,
+                                UnicodeString& target) const = 0;
+
+    /**
+     * Replaces a substring of this object with the given text.  If the
+     * characters being replaced have metadata, the new characters
+     * that replace them should be given the same metadata.
+     *
+     * <p>Subclasses must ensure that if the text between start and
+     * limit is equal to the replacement text, that replace has no
+     * effect. That is, any metadata
+     * should be unaffected. In addition, subclasses are encouraged to
+     * check for initial and trailing identical characters, and make a
+     * smaller replacement if possible. This will preserve as much
+     * metadata as possible.
+     * @param start the beginning index, inclusive; <code>0 <= start
+     * <= limit</code>.
+     * @param limit the ending index, exclusive; <code>start <= limit
+     * <= length()</code>.
+     * @param text the text to replace characters <code>start</code>
+     * to <code>limit - 1</code> 
+     * @stable ICU 2.0
+     */
+    virtual void handleReplaceBetween(int32_t start,
+                                      int32_t limit,
+                                      const UnicodeString& text) = 0;
+    // Note: All other methods in this class take the names of
+    // existing UnicodeString methods.  This method is the exception.
+    // It is named differently because all replace methods of
+    // UnicodeString return a UnicodeString&.  The 'between' is
+    // required in order to conform to the UnicodeString naming
+    // convention; API taking start/length are named <operation>, and
+    // those taking start/limit are named <operationBetween>.  The
+    // 'handle' is added because 'replaceBetween' and
+    // 'doReplaceBetween' are already taken.
+
+    /**
+     * Copies a substring of this object, retaining metadata.
+     * This method is used to duplicate or reorder substrings.
+     * The destination index must not overlap the source range.
+     * 
+     * @param start the beginning index, inclusive; <code>0 <= start <=
+     * limit</code>.
+     * @param limit the ending index, exclusive; <code>start <= limit <=
+     * length()</code>.
+     * @param dest the destination index.  The characters from
+     * <code>start..limit-1</code> will be copied to <code>dest</code>.
+     * Implementations of this method may assume that <code>dest <= start ||
+     * dest >= limit</code>.
+     * @stable ICU 2.0
+     */
+    virtual void copy(int32_t start, int32_t limit, int32_t dest) = 0;
+
+    /**
+     * Returns true if this object contains metadata.  If a
+     * Replaceable object has metadata, calls to the Replaceable API
+     * must be made so as to preserve metadata.  If it does not, calls
+     * to the Replaceable API may be optimized to improve performance.
+     * The default implementation returns true.
+     * @return true if this object contains metadata
+     * @stable ICU 2.2
+     */
+    virtual UBool hasMetaData() const;
+
+    /**
+     * Clone this object, an instance of a subclass of Replaceable.
+     * Clones can be used concurrently in multiple threads.
+     * If a subclass does not implement clone(), or if an error occurs,
+     * then NULL is returned.
+     * The clone functions in all subclasses return a pointer to a Replaceable
+     * because some compilers do not support covariant (same-as-this)
+     * return types; cast to the appropriate subclass if necessary.
+     * The caller must delete the clone.
+     *
+     * @return a clone of this object
+     *
+     * @see getDynamicClassID
+     * @stable ICU 2.6
+     */
+    virtual Replaceable *clone() const;
+
+protected:
+
+    /**
+     * Default constructor.
+     * @stable ICU 2.4
+     */
+    Replaceable();
+
+    /*
+     * Assignment operator not declared. The compiler will provide one
+     * which does nothing since this class does not contain any data members.
+     * API/code coverage may show the assignment operator as present and
+     * untested - ignore.
+     * Subclasses need this assignment operator if they use compiler-provided
+     * assignment operators of their own. An alternative to not declaring one
+     * here would be to declare and empty-implement a protected or public one.
+    Replaceable &Replaceable::operator=(const Replaceable &);
+     */
+
+    /**
+     * Virtual version of length().
+     * @stable ICU 2.4
+     */ 
+    virtual int32_t getLength() const = 0;
+
+    /**
+     * Virtual version of charAt().
+     * @stable ICU 2.4
+     */
+    virtual UChar getCharAt(int32_t offset) const = 0;
+
+    /**
+     * Virtual version of char32At().
+     * @stable ICU 2.4
+     */
+    virtual UChar32 getChar32At(int32_t offset) const = 0;
+};
+
+inline int32_t
+Replaceable::length() const {
+    return getLength();
+}
+
+inline UChar
+Replaceable::charAt(int32_t offset) const {
+    return getCharAt(offset);
+}
+
+inline UChar32
+Replaceable::char32At(int32_t offset) const {
+    return getChar32At(offset);
+}
+
+// There is no rep.cpp, see unistr.cpp for Replaceable function implementations.
+
+U_NAMESPACE_END
+
+#endif

Added: MacRuby/branches/icu/unicode/resbund.h
===================================================================
--- MacRuby/branches/icu/unicode/resbund.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/resbund.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,485 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1996-2005, International Business Machines Corporation
+*   and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File resbund.h
+*
+*   CREATED BY
+*       Richard Gillam
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   2/5/97      aliu        Added scanForLocaleInFile.  Added
+*                           constructor which attempts to read resource bundle
+*                           from a specific file, without searching other files.
+*   2/11/97     aliu        Added UErrorCode return values to constructors.  Fixed
+*                           infinite loops in scanForFile and scanForLocale.
+*                           Modified getRawResourceData to not delete storage
+*                           in localeData and resourceData which it doesn't own.
+*                           Added Mac compatibility #ifdefs for tellp() and
+*                           ios::nocreate.
+*   2/18/97     helena      Updated with 100% documentation coverage.
+*   3/13/97     aliu        Rewrote to load in entire resource bundle and store
+*                           it as a Hashtable of ResourceBundleData objects.
+*                           Added state table to govern parsing of files.
+*                           Modified to load locale index out of new file
+*                           distinct from default.txt.
+*   3/25/97     aliu        Modified to support 2-d arrays, needed for timezone
+*                           data. Added support for custom file suffixes.  Again,
+*                           needed to support timezone data.
+*   4/7/97      aliu        Cleaned up.
+* 03/02/99      stephen     Removed dependency on FILE*.
+* 03/29/99      helena      Merged Bertrand and Stephen's changes.
+* 06/11/99      stephen     Removed parsing of .txt files.
+*                           Reworked to use new binary format.
+*                           Cleaned up.
+* 06/14/99      stephen     Removed methods taking a filename suffix.
+* 11/09/99      weiv        Added getLocale(), fRealLocale, removed fRealLocaleID
+******************************************************************************
+*/
+
+#ifndef RESBUND_H
+#define RESBUND_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/ures.h"
+#include "unicode/unistr.h"
+#include "unicode/locid.h"
+
+/**
+ * \file 
+ * \brief C++ API: Resource Bundle
+ */
+ 
+U_NAMESPACE_BEGIN
+
+/**
+ * A class representing a collection of resource information pertaining to a given
+ * locale. A resource bundle provides a way of accessing locale- specfic information in
+ * a data file. You create a resource bundle that manages the resources for a given
+ * locale and then ask it for individual resources.
+ * <P>
+ * Resource bundles in ICU4C are currently defined using text files which conform to the following
+ * <a href="http://dev.icu-project.org/cgi-bin/viewcvs.cgi/~checkout~/icuhtml/design/bnf_rb.txt">BNF definition</a>.
+ * More on resource bundle concepts and syntax can be found in the
+ * <a href="http://icu.sourceforge.net/userguide/ResourceManagement.html">Users Guide</a>.
+ * <P>
+ *
+ * The ResourceBundle class is not suitable for subclassing.
+ *
+ * @stable ICU 2.0
+ */
+class U_COMMON_API ResourceBundle : public UObject {
+public:
+    /**
+     * Constructor
+     *
+     * @param packageName   The packageName and locale together point to an ICU udata object, 
+     *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+     *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
+     *                      a package registered with udata_setAppData(). Using a full file or directory
+     *                      pathname for packageName is deprecated.
+     * @param locale  This is the locale this resource bundle is for. To get resources
+     *                for the French locale, for example, you would create a
+     *                ResourceBundle passing Locale::FRENCH for the "locale" parameter,
+     *                and all subsequent calls to that resource bundle will return
+     *                resources that pertain to the French locale. If the caller doesn't
+     *                pass a locale parameter, the default locale for the system (as
+     *                returned by Locale::getDefault()) will be used.
+     * @param err     The Error Code.
+     * The UErrorCode& err parameter is used to return status information to the user. To
+     * check whether the construction succeeded or not, you should check the value of
+     * U_SUCCESS(err). If you wish more detailed information, you can check for
+     * informational error results which still indicate success. U_USING_FALLBACK_WARNING
+     * indicates that a fall back locale was used. For example, 'de_CH' was requested,
+     * but nothing was found there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that
+     * the default locale data was used; neither the requested locale nor any of its
+     * fall back locales could be found.
+     * @stable ICU 2.0
+     */
+    ResourceBundle(const UnicodeString&    packageName,
+                   const Locale&           locale,
+                   UErrorCode&              err);
+
+    /**
+     * Construct a resource bundle for the default bundle in the specified package.
+     *
+     * @param packageName   The packageName and locale together point to an ICU udata object, 
+     *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+     *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
+     *                      a package registered with udata_setAppData(). Using a full file or directory
+     *                      pathname for packageName is deprecated.
+     * @param err A UErrorCode value
+     * @stable ICU 2.0
+     */
+    ResourceBundle(const UnicodeString&    packageName,
+                   UErrorCode&              err);
+
+    /**
+     * Construct a resource bundle for the ICU default bundle.
+     *
+     * @param err A UErrorCode value
+     * @stable ICU 2.0
+     */
+    ResourceBundle(UErrorCode &err);
+
+    /**
+     * Standard constructor, onstructs a resource bundle for the locale-specific
+     * bundle in the specified package.
+     *
+     * @param packageName   The packageName and locale together point to an ICU udata object, 
+     *                      as defined by <code> udata_open( packageName, "res", locale, err) </code> 
+     *                      or equivalent.  Typically, packageName will refer to a (.dat) file, or to
+     *                      a package registered with udata_setAppData(). Using a full file or directory
+     *                      pathname for packageName is deprecated.
+     *                      NULL is used to refer to ICU data.
+     * @param locale The locale for which to open a resource bundle.
+     * @param err A UErrorCode value
+     * @stable ICU 2.0
+     */
+    ResourceBundle(const char* packageName,
+                   const Locale& locale,
+                   UErrorCode& err);
+
+    /**
+     * Copy constructor.
+     *
+     * @param original The resource bundle to copy.
+     * @stable ICU 2.0
+     */
+    ResourceBundle(const ResourceBundle &original);
+
+    /**
+     * Constructor from a C UResourceBundle. The resource bundle is
+     * copied and not adopted. ures_close will still need to be used on the
+     * original resource bundle.
+     *
+     * @param res A pointer to the C resource bundle.
+     * @param status A UErrorCode value.
+     * @stable ICU 2.0
+     */
+    ResourceBundle(UResourceBundle *res,
+                   UErrorCode &status);
+
+    /**
+     * Assignment operator.
+     *
+     * @param other The resource bundle to copy.
+     * @stable ICU 2.0
+     */
+    ResourceBundle&
+      operator=(const ResourceBundle& other);
+
+    /** Destructor.
+     * @stable ICU 2.0
+     */
+    virtual ~ResourceBundle();
+
+    /**
+     * Clone this object.
+     * Clones can be used concurrently in multiple threads.
+     * If an error occurs, then NULL is returned.
+     * The caller must delete the clone.
+     *
+     * @return a clone of this object
+     *
+     * @see getDynamicClassID
+     * @stable ICU 2.8
+     */
+    ResourceBundle *clone() const;
+
+    /**
+     * Returns the size of a resource. Size for scalar types is always 1, and for vector/table types is
+     * the number of child resources.
+     * @warning Integer array is treated as a scalar type. There are no
+     *          APIs to access individual members of an integer array. It
+     *          is always returned as a whole.
+     *
+     * @return number of resources in a given resource.
+     * @stable ICU 2.0
+     */
+    int32_t
+      getSize(void) const;
+
+    /**
+     * returns a string from a string resource type
+     *
+     * @param status  fills in the outgoing error code
+     *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
+     *                could be a warning
+     *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
+     * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file.
+     * @stable ICU 2.0
+     */
+    UnicodeString
+      getString(UErrorCode& status) const;
+
+    /**
+     * returns a binary data from a resource. Can be used at most primitive resource types (binaries,
+     * strings, ints)
+     *
+     * @param len     fills in the length of resulting byte chunk
+     * @param status  fills in the outgoing error code
+     *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
+     *                could be a warning
+     *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
+     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.
+     * @stable ICU 2.0
+     */
+    const uint8_t*
+      getBinary(int32_t& len, UErrorCode& status) const;
+
+
+    /**
+     * returns an integer vector from a resource.
+     *
+     * @param len     fills in the length of resulting integer vector
+     * @param status  fills in the outgoing error code
+     *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
+     *                could be a warning
+     *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
+     * @return a pointer to a vector of integers that lives in a memory mapped/DLL file.
+     * @stable ICU 2.0
+     */
+    const int32_t*
+      getIntVector(int32_t& len, UErrorCode& status) const;
+
+    /**
+     * returns an unsigned integer from a resource.
+     * This integer is originally 28 bits.
+     *
+     * @param status  fills in the outgoing error code
+     *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
+     *                could be a warning
+     *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
+     * @return an unsigned integer value
+     * @stable ICU 2.0
+     */
+    uint32_t
+      getUInt(UErrorCode& status) const;
+
+    /**
+     * returns a signed integer from a resource.
+     * This integer is originally 28 bit and the sign gets propagated.
+     *
+     * @param status  fills in the outgoing error code
+     *                could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found
+     *                could be a warning
+     *                e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT>
+     * @return a signed integer value
+     * @stable ICU 2.0
+     */
+    int32_t
+      getInt(UErrorCode& status) const;
+
+    /**
+     * Checks whether the resource has another element to iterate over.
+     *
+     * @return TRUE if there are more elements, FALSE if there is no more elements
+     * @stable ICU 2.0
+     */
+    UBool
+      hasNext(void) const;
+
+    /**
+     * Resets the internal context of a resource so that iteration starts from the first element.
+     *
+     * @stable ICU 2.0
+     */
+    void
+      resetIterator(void);
+
+    /**
+     * Returns the key associated with this resource. Not all the resources have a key - only
+     * those that are members of a table.
+     *
+     * @return a key associated to this resource, or NULL if it doesn't have a key
+     * @stable ICU 2.0
+     */
+    const char*
+      getKey(void) const;
+
+    /**
+     * Gets the locale ID of the resource bundle as a string.
+     * Same as getLocale().getName() .
+     *
+     * @return the locale ID of the resource bundle as a string
+     * @stable ICU 2.0
+     */
+    const char*
+      getName(void) const;
+
+
+    /**
+     * Returns the type of a resource. Available types are defined in enum UResType
+     *
+     * @return type of the given resource.
+     * @stable ICU 2.0
+     */
+    UResType
+      getType(void) const;
+
+    /**
+     * Returns the next resource in a given resource or NULL if there are no more resources
+     *
+     * @param status            fills in the outgoing error code
+     * @return                  ResourceBundle object.
+     * @stable ICU 2.0
+     */
+    ResourceBundle
+      getNext(UErrorCode& status);
+
+    /**
+     * Returns the next string in a resource or NULL if there are no more resources
+     * to iterate over.
+     *
+     * @param status            fills in the outgoing error code
+     * @return an UnicodeString object.
+     * @stable ICU 2.0
+     */
+    UnicodeString
+      getNextString(UErrorCode& status);
+
+    /**
+     * Returns the next string in a resource or NULL if there are no more resources
+     * to iterate over.
+     *
+     * @param key               fill in for key associated with this string
+     * @param status            fills in the outgoing error code
+     * @return an UnicodeString object.
+     * @stable ICU 2.0
+     */
+    UnicodeString
+      getNextString(const char ** key,
+                    UErrorCode& status);
+
+    /**
+     * Returns the resource in a resource at the specified index.
+     *
+     * @param index             an index to the wanted resource.
+     * @param status            fills in the outgoing error code
+     * @return                  ResourceBundle object. If there is an error, resource is invalid.
+     * @stable ICU 2.0
+     */
+    ResourceBundle
+      get(int32_t index,
+          UErrorCode& status) const;
+
+    /**
+     * Returns the string in a given resource at the specified index.
+     *
+     * @param index             an index to the wanted string.
+     * @param status            fills in the outgoing error code
+     * @return                  an UnicodeString object. If there is an error, string is bogus
+     * @stable ICU 2.0
+     */
+    UnicodeString
+      getStringEx(int32_t index,
+                  UErrorCode& status) const;
+
+    /**
+     * Returns a resource in a resource that has a given key. This procedure works only with table
+     * resources.
+     *
+     * @param key               a key associated with the wanted resource
+     * @param status            fills in the outgoing error code.
+     * @return                  ResourceBundle object. If there is an error, resource is invalid.
+     * @stable ICU 2.0
+     */
+    ResourceBundle
+      get(const char* key,
+          UErrorCode& status) const;
+
+    /**
+     * Returns a string in a resource that has a given key. This procedure works only with table
+     * resources.
+     *
+     * @param key               a key associated with the wanted string
+     * @param status            fills in the outgoing error code
+     * @return                  an UnicodeString object. If there is an error, string is bogus
+     * @stable ICU 2.0
+     */
+    UnicodeString
+      getStringEx(const char* key,
+                  UErrorCode& status) const;
+
+    /**
+     * Return the version number associated with this ResourceBundle as a string. Please
+     * use getVersion, as this method is going to be deprecated.
+     *
+     * @return  A version number string as specified in the resource bundle or its parent.
+     *          The caller does not own this string.
+     * @see getVersion
+     * @deprecated ICU 2.8 Use getVersion instead.
+     */
+    const char*
+      getVersionNumber(void) const;
+
+    /**
+     * Return the version number associated with this ResourceBundle as a UVersionInfo array.
+     *
+     * @param versionInfo A UVersionInfo array that is filled with the version number
+     *                    as specified in the resource bundle or its parent.
+     * @stable ICU 2.0
+     */
+    void
+      getVersion(UVersionInfo versionInfo) const;
+
+    /**
+     * Return the Locale associated with this ResourceBundle.
+     *
+     * @return a Locale object
+     * @deprecated ICU 2.8 Use getLocale(ULocDataLocaleType type, UErrorCode &status) overload instead.
+     */
+    const Locale&
+      getLocale(void) const;
+
+    /**
+     * Return the Locale associated with this ResourceBundle.
+     * @param type You can choose between requested, valid and actual
+     *             locale. For description see the definition of
+     *             ULocDataLocaleType in uloc.h
+     * @param status just for catching illegal arguments
+     *
+     * @return a Locale object
+     * @stable ICU 2.8
+     */
+    const Locale
+      getLocale(ULocDataLocaleType type, UErrorCode &status) const;
+    /**
+     * This API implements multilevel fallback
+     * @internal
+     */
+    ResourceBundle
+        getWithFallback(const char* key, UErrorCode& status);
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.2
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.2
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+private:
+    ResourceBundle(); // default constructor not implemented
+
+    UResourceBundle *fResource;
+    void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error);
+    Locale *fLocale;
+
+};
+
+U_NAMESPACE_END
+#endif

Added: MacRuby/branches/icu/unicode/schriter.h
===================================================================
--- MacRuby/branches/icu/unicode/schriter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/schriter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,187 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1998-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File schriter.h
+*
+* Modification History:
+*
+*   Date        Name        Description
+*  05/05/99     stephen     Cleaned up.
+******************************************************************************
+*/
+
+#ifndef SCHRITER_H
+#define SCHRITER_H
+
+#include "unicode/utypes.h"
+#include "unicode/chariter.h"
+#include "unicode/uchriter.h"
+
+/**
+ * \file 
+ * \brief C++ API: String Character Iterator
+ */
+ 
+U_NAMESPACE_BEGIN
+/**
+ * A concrete subclass of CharacterIterator that iterates over the
+ * characters (code units or code points) in a UnicodeString.
+ * It's possible not only to create an
+ * iterator that iterates over an entire UnicodeString, but also to
+ * create one that iterates over only a subrange of a UnicodeString
+ * (iterators over different subranges of the same UnicodeString don't
+ * compare equal).
+ * @see CharacterIterator
+ * @see ForwardCharacterIterator
+ * @stable ICU 2.0
+ */
+class U_COMMON_API StringCharacterIterator : public UCharCharacterIterator {
+public:
+  /**
+   * Create an iterator over the UnicodeString referred to by "textStr".
+   * The UnicodeString object is copied.
+   * The iteration range is the whole string, and the starting position is 0.
+   * @param textStr The unicode string used to create an iterator
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator(const UnicodeString& textStr);
+
+  /**
+   * Create an iterator over the UnicodeString referred to by "textStr".
+   * The iteration range is the whole string, and the starting
+   * position is specified by "textPos".  If "textPos" is outside the valid
+   * iteration range, the behavior of this object is undefined.
+   * @param textStr The unicode string used to create an iterator
+   * @param textPos The starting position of the iteration
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator(const UnicodeString&    textStr,
+              int32_t              textPos);
+
+  /**
+   * Create an iterator over the UnicodeString referred to by "textStr".
+   * The UnicodeString object is copied.
+   * The iteration range begins with the code unit specified by
+   * "textBegin" and ends with the code unit BEFORE the code unit specfied
+   * by "textEnd".  The starting position is specified by "textPos".  If
+   * "textBegin" and "textEnd" don't form a valid range on "text" (i.e.,
+   * textBegin >= textEnd or either is negative or greater than text.size()),
+   * or "textPos" is outside the range defined by "textBegin" and "textEnd",
+   * the behavior of this iterator is undefined.
+   * @param textStr    The unicode string used to create the StringCharacterIterator
+   * @param textBegin  The begin position of the iteration range
+   * @param textEnd    The end position of the iteration range
+   * @param textPos    The starting position of the iteration
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator(const UnicodeString&    textStr,
+              int32_t              textBegin,
+              int32_t              textEnd,
+              int32_t              textPos);
+
+  /**
+   * Copy constructor.  The new iterator iterates over the same range
+   * of the same string as "that", and its initial position is the
+   * same as "that"'s current position.
+   * The UnicodeString object in "that" is copied.
+   * @param that The StringCharacterIterator to be copied
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator(const StringCharacterIterator&  that);
+
+  /**
+   * Destructor.
+   * @stable ICU 2.0
+   */
+  virtual ~StringCharacterIterator();
+
+  /**
+   * Assignment operator.  *this is altered to iterate over the same
+   * range of the same string as "that", and refers to the same
+   * character within that string as "that" does.
+   * @param that The object to be copied.
+   * @return the newly created object.
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator&
+  operator=(const StringCharacterIterator&    that);
+
+  /**
+   * Returns true if the iterators iterate over the same range of the
+   * same string and are pointing at the same character.
+   * @param that The ForwardCharacterIterator to be compared for equality
+   * @return true if the iterators iterate over the same range of the
+   * same string and are pointing at the same character.
+   * @stable ICU 2.0
+   */
+  virtual UBool          operator==(const ForwardCharacterIterator& that) const;
+
+  /**
+   * Returns a new StringCharacterIterator referring to the same
+   * character in the same range of the same string as this one.  The
+   * caller must delete the new iterator.
+   * @return the newly cloned object.
+   * @stable ICU 2.0
+   */
+  virtual CharacterIterator* clone(void) const;
+
+  /**
+   * Sets the iterator to iterate over the provided string.
+   * @param newText The string to be iterated over
+   * @stable ICU 2.0
+   */
+  void setText(const UnicodeString& newText);
+
+  /**
+   * Copies the UnicodeString under iteration into the UnicodeString
+   * referred to by "result".  Even if this iterator iterates across
+   * only a part of this string, the whole string is copied.
+   * @param result Receives a copy of the text under iteration.
+   * @stable ICU 2.0
+   */
+  virtual void            getText(UnicodeString& result);
+
+  /**
+   * Return a class ID for this object (not really public)
+   * @return a class ID for this object.
+   * @stable ICU 2.0
+   */
+  virtual UClassID         getDynamicClassID(void) const;
+
+  /**
+   * Return a class ID for this class (not really public)
+   * @return a class ID for this class
+   * @stable ICU 2.0
+   */
+  static UClassID   U_EXPORT2 getStaticClassID(void);
+
+protected:
+  /**
+   * Default constructor, iteration over empty string.
+   * @stable ICU 2.0
+   */
+  StringCharacterIterator();
+
+  /**
+   * Sets the iterator to iterate over the provided string.
+   * @param newText The string to be iterated over
+   * @param newTextLength The length of the String
+   * @stable ICU 2.0
+   */
+  void setText(const UChar* newText, int32_t newTextLength);
+
+  /**
+   * Copy of the iterated string object.
+   * @stable ICU 2.0
+   */
+  UnicodeString            text;
+
+};
+
+U_NAMESPACE_END
+#endif

Added: MacRuby/branches/icu/unicode/strenum.h
===================================================================
--- MacRuby/branches/icu/unicode/strenum.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/strenum.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,271 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*/
+
+#ifndef STRENUM_H
+#define STRENUM_H
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+
+/**
+ * \file 
+ * \brief C++ API: String Enumeration
+ */
+ 
+U_NAMESPACE_BEGIN
+
+/**
+ * Base class for 'pure' C++ implementations of uenum api.  Adds a
+ * method that returns the next UnicodeString since in C++ this can
+ * be a common storage format for strings.
+ *
+ * <p>The model is that the enumeration is over strings maintained by
+ * a 'service.'  At any point, the service might change, invalidating
+ * the enumerator (though this is expected to be rare).  The iterator
+ * returns an error if this has occurred.  Lack of the error is no
+ * guarantee that the service didn't change immediately after the
+ * call, so the returned string still might not be 'valid' on
+ * subsequent use.</p>
+ *
+ * <p>Strings may take the form of const char*, const UChar*, or const
+ * UnicodeString*.  The type you get is determine by the variant of
+ * 'next' that you call.  In general the StringEnumeration is
+ * optimized for one of these types, but all StringEnumerations can
+ * return all types.  Returned strings are each terminated with a NUL.
+ * Depending on the service data, they might also include embedded NUL
+ * characters, so API is provided to optionally return the true
+ * length, counting the embedded NULs but not counting the terminating
+ * NUL.</p>
+ *
+ * <p>The pointers returned by next, unext, and snext become invalid
+ * upon any subsequent call to the enumeration's destructor, next,
+ * unext, snext, or reset.</p>
+ *
+ * ICU 2.8 adds some default implementations and helper functions
+ * for subclasses.
+ *
+ * @stable ICU 2.4 
+ */
+class U_COMMON_API StringEnumeration : public UObject { 
+public:
+    /**
+     * Destructor.
+     * @stable ICU 2.4
+     */
+    virtual ~StringEnumeration();
+
+    /**
+     * Clone this object, an instance of a subclass of StringEnumeration.
+     * Clones can be used concurrently in multiple threads.
+     * If a subclass does not implement clone(), or if an error occurs,
+     * then NULL is returned.
+     * The clone functions in all subclasses return a base class pointer
+     * because some compilers do not support covariant (same-as-this)
+     * return types; cast to the appropriate subclass if necessary.
+     * The caller must delete the clone.
+     *
+     * @return a clone of this object
+     *
+     * @see getDynamicClassID
+     * @stable ICU 2.8
+     */
+    virtual StringEnumeration *clone() const;
+
+    /**
+     * <p>Return the number of elements that the iterator traverses.  If
+     * the iterator is out of sync with its service, status is set to
+     * U_ENUM_OUT_OF_SYNC_ERROR, and the return value is zero.</p>
+     *
+     * <p>The return value will not change except possibly as a result of
+     * a subsequent call to reset, or if the iterator becomes out of sync.</p>
+     *
+     * <p>This is a convenience function. It can end up being very
+     * expensive as all the items might have to be pre-fetched
+     * (depending on the storage format of the data being
+     * traversed).</p>
+     *
+     * @param status the error code.
+     * @return number of elements in the iterator.
+     *
+     * @stable ICU 2.4 */
+    virtual int32_t count(UErrorCode& status) const = 0;
+
+    /**
+     * <p>Returns the next element as a NUL-terminated char*.  If there
+     * are no more elements, returns NULL.  If the resultLength pointer
+     * is not NULL, the length of the string (not counting the
+     * terminating NUL) is returned at that address.  If an error
+     * status is returned, the value at resultLength is undefined.</p>
+     *
+     * <p>The returned pointer is owned by this iterator and must not be
+     * deleted by the caller.  The pointer is valid until the next call
+     * to next, unext, snext, reset, or the enumerator's destructor.</p>
+     *
+     * <p>If the iterator is out of sync with its service, status is set
+     * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
+     *
+     * <p>If the native service string is a UChar* string, it is
+     * converted to char* with the invariant converter.  If the
+     * conversion fails (because a character cannot be converted) then
+     * status is set to U_INVARIANT_CONVERSION_ERROR and the return
+     * value is undefined (though not NULL).</p>
+     *
+     * Starting with ICU 2.8, the default implementation calls snext()
+     * and handles the conversion.
+     *
+     * @param status the error code.
+     * @param resultLength a pointer to receive the length, can be NULL.
+     * @return a pointer to the string, or NULL.
+     *
+     * @stable ICU 2.4 
+     */
+    virtual const char* next(int32_t *resultLength, UErrorCode& status);
+
+    /**
+     * <p>Returns the next element as a NUL-terminated UChar*.  If there
+     * are no more elements, returns NULL.  If the resultLength pointer
+     * is not NULL, the length of the string (not counting the
+     * terminating NUL) is returned at that address.  If an error
+     * status is returned, the value at resultLength is undefined.</p>
+     *
+     * <p>The returned pointer is owned by this iterator and must not be
+     * deleted by the caller.  The pointer is valid until the next call
+     * to next, unext, snext, reset, or the enumerator's destructor.</p>
+     *
+     * <p>If the iterator is out of sync with its service, status is set
+     * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
+     *
+     * Starting with ICU 2.8, the default implementation calls snext()
+     * and handles the conversion.
+     *
+     * @param status the error code.
+     * @param resultLength a ponter to receive the length, can be NULL.
+     * @return a pointer to the string, or NULL.
+     *
+     * @stable ICU 2.4 
+     */
+    virtual const UChar* unext(int32_t *resultLength, UErrorCode& status);
+
+    /**
+     * <p>Returns the next element a UnicodeString*.  If there are no
+     * more elements, returns NULL.</p>
+     *
+     * <p>The returned pointer is owned by this iterator and must not be
+     * deleted by the caller.  The pointer is valid until the next call
+     * to next, unext, snext, reset, or the enumerator's destructor.</p>
+     *
+     * <p>If the iterator is out of sync with its service, status is set
+     * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p>
+     *
+     * @param status the error code.
+     * @return a pointer to the string, or NULL.
+     *
+     * @stable ICU 2.4 
+     */
+    virtual const UnicodeString* snext(UErrorCode& status) = 0;
+
+    /**
+     * <p>Resets the iterator.  This re-establishes sync with the
+     * service and rewinds the iterator to start at the first
+     * element.</p>
+     *
+     * <p>Previous pointers returned by next, unext, or snext become
+     * invalid, and the value returned by count might change.</p>
+     *
+     * @param status the error code.
+     *
+     * @stable ICU 2.4 
+     */
+    virtual void reset(UErrorCode& status) = 0;
+
+    /**
+     * Compares this enumeration to other to check if both are equal
+     *
+     * @param that The other string enumeration to compare this object to
+     * @return TRUE if the enumerations are equal. FALSE if not.
+     * @draft ICU 3.6 
+     */
+    virtual UBool operator==(const StringEnumeration& that)const;
+    /**
+     * Compares this enumeration to other to check if both are not equal
+     *
+     * @param that The other string enumeration to compare this object to
+     * @return TRUE if the enumerations are equal. FALSE if not.
+     * @draft ICU 3.6 
+     */
+    virtual UBool operator!=(const StringEnumeration& that)const;
+
+protected:
+    /**
+     * UnicodeString field for use with default implementations and subclasses.
+     * @stable ICU 2.8
+     */
+    UnicodeString unistr;
+    /**
+     * char * default buffer for use with default implementations and subclasses.
+     * @stable ICU 2.8
+     */
+    char charsBuffer[32];
+    /**
+     * char * buffer for use with default implementations and subclasses.
+     * Allocated in constructor and in ensureCharsCapacity().
+     * @stable ICU 2.8
+     */
+    char *chars;
+    /**
+     * Capacity of chars, for use with default implementations and subclasses.
+     * @stable ICU 2.8
+     */
+    int32_t charsCapacity;
+
+    /**
+     * Default constructor for use with default implementations and subclasses.
+     * @stable ICU 2.8
+     */
+    StringEnumeration();
+
+    /**
+     * Ensures that chars is at least as large as the requested capacity.
+     * For use with default implementations and subclasses.
+     *
+     * @param capacity Requested capacity.
+     * @param status ICU in/out error code.
+     * @stable ICU 2.8
+     */
+    void ensureCharsCapacity(int32_t capacity, UErrorCode &status);
+
+    /**
+     * Converts s to Unicode and sets unistr to the result.
+     * For use with default implementations and subclasses,
+     * especially for implementations of snext() in terms of next().
+     * This is provided with a helper function instead of a default implementation
+     * of snext() to avoid potential infinite loops between next() and snext().
+     *
+     * For example:
+     * \code
+     * const UnicodeString* snext(UErrorCode& status) {
+     *   int32_t resultLength=0;
+     *   const char *s=next(&resultLength, status);
+     *   return setChars(s, resultLength, status);
+     * }
+     * \endcode
+     *
+     * @param s String to be converted to Unicode.
+     * @param length Length of the string.
+     * @param status ICU in/out error code.
+     * @return A pointer to unistr.
+     * @stable ICU 2.8
+     */
+    UnicodeString *setChars(const char *s, int32_t length, UErrorCode &status);
+};
+
+U_NAMESPACE_END
+
+/* STRENUM_H */
+#endif

Added: MacRuby/branches/icu/unicode/symtable.h
===================================================================
--- MacRuby/branches/icu/unicode/symtable.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/symtable.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,112 @@
+/*
+**********************************************************************
+*   Copyright (c) 2000-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   02/04/00    aliu        Creation.
+**********************************************************************
+*/
+#ifndef SYMTABLE_H
+#define SYMTABLE_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file 
+ * \brief C++ API: An interface that defines both lookup protocol and parsing of
+ * symbolic names.
+ */
+ 
+U_NAMESPACE_BEGIN
+
+class ParsePosition;
+class UnicodeFunctor;
+class UnicodeSet;
+class UnicodeString;
+
+/**
+ * An interface that defines both lookup protocol and parsing of
+ * symbolic names.
+ *
+ * <p>A symbol table maintains two kinds of mappings.  The first is
+ * between symbolic names and their values.  For example, if the
+ * variable with the name "start" is set to the value "alpha"
+ * (perhaps, though not necessarily, through an expression such as
+ * "$start=alpha"), then the call lookup("start") will return the
+ * char[] array ['a', 'l', 'p', 'h', 'a'].
+ *
+ * <p>The second kind of mapping is between character values and
+ * UnicodeMatcher objects.  This is used by RuleBasedTransliterator,
+ * which uses characters in the private use area to represent objects
+ * such as UnicodeSets.  If U+E015 is mapped to the UnicodeSet [a-z],
+ * then lookupMatcher(0xE015) will return the UnicodeSet [a-z].
+ *
+ * <p>Finally, a symbol table defines parsing behavior for symbolic
+ * names.  All symbolic names start with the SYMBOL_REF character.
+ * When a parser encounters this character, it calls parseReference()
+ * with the position immediately following the SYMBOL_REF.  The symbol
+ * table parses the name, if there is one, and returns it.
+ *
+ * @stable ICU 2.8
+ */
+class U_COMMON_API SymbolTable /* not : public UObject because this is an interface/mixin class */ {
+public:
+
+    /**
+     * The character preceding a symbol reference name.
+     * @stable ICU 2.8
+     */
+    enum { SYMBOL_REF = 0x0024 /*$*/ };
+
+    /**
+     * Destructor.
+     * @stable ICU 2.8
+     */
+    virtual ~SymbolTable();
+
+    /**
+     * Lookup the characters associated with this string and return it.
+     * Return <tt>NULL</tt> if no such name exists.  The resultant
+     * string may have length zero.
+     * @param s the symbolic name to lookup
+     * @return a string containing the name's value, or <tt>NULL</tt> if
+     * there is no mapping for s.
+     * @stable ICU 2.8
+     */
+    virtual const UnicodeString* lookup(const UnicodeString& s) const = 0;
+
+    /**
+     * Lookup the UnicodeMatcher associated with the given character, and
+     * return it.  Return <tt>NULL</tt> if not found.
+     * @param ch a 32-bit code point from 0 to 0x10FFFF inclusive.
+     * @return the UnicodeMatcher object represented by the given
+     * character, or NULL if there is no mapping for ch.
+     * @stable ICU 2.8
+     */
+    virtual const UnicodeFunctor* lookupMatcher(UChar32 ch) const = 0;
+
+    /**
+     * Parse a symbol reference name from the given string, starting
+     * at the given position.  If no valid symbol reference name is
+     * found, return the empty string and leave pos unchanged.  That is, if the
+     * character at pos cannot start a name, or if pos is at or after
+     * text.length(), then return an empty string.  This indicates an
+     * isolated SYMBOL_REF character.
+     * @param text the text to parse for the name
+     * @param pos on entry, the index of the first character to parse.
+     * This is the character following the SYMBOL_REF character.  On
+     * exit, the index after the last parsed character.  If the parse
+     * failed, pos is unchanged on exit.
+     * @param limit the index after the last character to be parsed.
+     * @return the parsed name, or an empty string if there is no
+     * valid symbolic name at the given position.
+     * @stable ICU 2.8
+     */
+    virtual UnicodeString parseReference(const UnicodeString& text,
+                                         ParsePosition& pos, int32_t limit) const = 0;
+};
+U_NAMESPACE_END
+
+#endif

Added: MacRuby/branches/icu/unicode/ubidi.h
===================================================================
--- MacRuby/branches/icu/unicode/ubidi.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ubidi.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,1917 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  ubidi.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999jul27
+*   created by: Markus W. Scherer
+*/
+
+#ifndef UBIDI_H
+#define UBIDI_H
+
+#include "unicode/utypes.h"
+#include "unicode/uchar.h"
+
+/**
+ *\file
+ * \brief C API: BIDI algorithm
+ *
+ * <h2>BIDI algorithm for ICU</h2>
+ *
+ * This is an implementation of the Unicode Bidirectional algorithm.
+ * The algorithm is defined in the
+ * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
+ * version 13, also described in The Unicode Standard, Version 4.0 .<p>
+ *
+ * Note: Libraries that perform a bidirectional algorithm and
+ * reorder strings accordingly are sometimes called "Storage Layout Engines".
+ * ICU's BiDi and shaping (u_shapeArabic()) APIs can be used at the core of such
+ * "Storage Layout Engines".
+ *
+ * <h3>General remarks about the API:</h3>
+ *
+ * In functions with an error code parameter,
+ * the <code>pErrorCode</code> pointer must be valid
+ * and the value that it points to must not indicate a failure before
+ * the function call. Otherwise, the function returns immediately.
+ * After the function call, the value indicates success or failure.<p>
+ *
+ * The &quot;limit&quot; of a sequence of characters is the position just after their
+ * last character, i.e., one more than that position.<p>
+ *
+ * Some of the API functions provide access to &quot;runs&quot;.
+ * Such a &quot;run&quot; is defined as a sequence of characters
+ * that are at the same embedding level
+ * after performing the BIDI algorithm.<p>
+ *
+ * @author Markus W. Scherer
+ * @version 1.0
+ *
+ *
+ * <h4> Sample code for the ICU BIDI API </h4>
+ *
+ * <h5>Rendering a paragraph with the ICU BiDi API</h5>
+ *
+ * This is (hypothetical) sample code that illustrates
+ * how the ICU BiDi API could be used to render a paragraph of text.
+ * Rendering code depends highly on the graphics system,
+ * therefore this sample code must make a lot of assumptions,
+ * which may or may not match any existing graphics system's properties.
+ *
+ * <p>The basic assumptions are:</p>
+ * <ul>
+ * <li>Rendering is done from left to right on a horizontal line.</li>
+ * <li>A run of single-style, unidirectional text can be rendered at once.</li>
+ * <li>Such a run of text is passed to the graphics system with
+ *     characters (code units) in logical order.</li>
+ * <li>The line-breaking algorithm is very complicated
+ *     and Locale-dependent -
+ *     and therefore its implementation omitted from this sample code.</li>
+ * </ul>
+ *
+ * <pre>
+ * \code
+ *#include "unicode/ubidi.h"
+ *
+ *typedef enum {
+ *     styleNormal=0, styleSelected=1,
+ *     styleBold=2, styleItalics=4,
+ *     styleSuper=8, styleSub=16
+ *} Style;
+ *
+ *typedef struct { int32_t limit; Style style; } StyleRun;
+ *
+ *int getTextWidth(const UChar *text, int32_t start, int32_t limit,
+ *                  const StyleRun *styleRuns, int styleRunCount);
+ *
+ * // set *pLimit and *pStyleRunLimit for a line
+ * // from text[start] and from styleRuns[styleRunStart]
+ * // using ubidi_getLogicalRun(para, ...)
+ *void getLineBreak(const UChar *text, int32_t start, int32_t *pLimit,
+ *                  UBiDi *para,
+ *                  const StyleRun *styleRuns, int styleRunStart, int *pStyleRunLimit,
+ *                  int *pLineWidth);
+ *
+ * // render runs on a line sequentially, always from left to right
+ *
+ * // prepare rendering a new line
+ * void startLine(UBiDiDirection textDirection, int lineWidth);
+ *
+ * // render a run of text and advance to the right by the run width
+ * // the text[start..limit-1] is always in logical order
+ * void renderRun(const UChar *text, int32_t start, int32_t limit,
+ *               UBiDiDirection textDirection, Style style);
+ *
+ * // We could compute a cross-product
+ * // from the style runs with the directional runs
+ * // and then reorder it.
+ * // Instead, here we iterate over each run type
+ * // and render the intersections -
+ * // with shortcuts in simple (and common) cases.
+ * // renderParagraph() is the main function.
+ *
+ * // render a directional run with
+ * // (possibly) multiple style runs intersecting with it
+ * void renderDirectionalRun(const UChar *text,
+ *                           int32_t start, int32_t limit,
+ *                           UBiDiDirection direction,
+ *                           const StyleRun *styleRuns, int styleRunCount) {
+ *     int i;
+ *
+ *     // iterate over style runs
+ *     if(direction==UBIDI_LTR) {
+ *         int styleLimit;
+ *
+ *         for(i=0; i<styleRunCount; ++i) {
+ *             styleLimit=styleRun[i].limit;
+ *             if(start<styleLimit) {
+ *                 if(styleLimit>limit) { styleLimit=limit; }
+ *                 renderRun(text, start, styleLimit,
+ *                           direction, styleRun[i].style);
+ *                 if(styleLimit==limit) { break; }
+ *                 start=styleLimit;
+ *             }
+ *         }
+ *     } else {
+ *         int styleStart;
+ *
+ *         for(i=styleRunCount-1; i>=0; --i) {
+ *             if(i>0) {
+ *                 styleStart=styleRun[i-1].limit;
+ *             } else {
+ *                 styleStart=0;
+ *             }
+ *             if(limit>=styleStart) {
+ *                 if(styleStart<start) { styleStart=start; }
+ *                 renderRun(text, styleStart, limit,
+ *                           direction, styleRun[i].style);
+ *                 if(styleStart==start) { break; }
+ *                 limit=styleStart;
+ *             }
+ *         }
+ *     }
+ * }
+ *
+ * // the line object represents text[start..limit-1]
+ * void renderLine(UBiDi *line, const UChar *text,
+ *                 int32_t start, int32_t limit,
+ *                 const StyleRun *styleRuns, int styleRunCount) {
+ *     UBiDiDirection direction=ubidi_getDirection(line);
+ *     if(direction!=UBIDI_MIXED) {
+ *         // unidirectional
+ *         if(styleRunCount<=1) {
+ *             renderRun(text, start, limit, direction, styleRuns[0].style);
+ *         } else {
+ *             renderDirectionalRun(text, start, limit,
+ *                                  direction, styleRuns, styleRunCount);
+ *         }
+ *     } else {
+ *         // mixed-directional
+ *         int32_t count, i, length;
+ *         UBiDiLevel level;
+ *
+ *         count=ubidi_countRuns(para, pErrorCode);
+ *         if(U_SUCCESS(*pErrorCode)) {
+ *             if(styleRunCount<=1) {
+ *                 Style style=styleRuns[0].style;
+ *
+ *                 // iterate over directional runs
+ *                for(i=0; i<count; ++i) {
+ *                    direction=ubidi_getVisualRun(para, i, &start, &length);
+ *                     renderRun(text, start, start+length, direction, style);
+ *                }
+ *             } else {
+ *                 int32_t j;
+ *
+ *                 // iterate over both directional and style runs
+ *                 for(i=0; i<count; ++i) {
+ *                     direction=ubidi_getVisualRun(line, i, &start, &length);
+ *                     renderDirectionalRun(text, start, start+length,
+ *                                          direction, styleRuns, styleRunCount);
+ *                 }
+ *             }
+ *         }
+ *     }
+ * }
+ *
+ *void renderParagraph(const UChar *text, int32_t length,
+ *                     UBiDiDirection textDirection,
+ *                      const StyleRun *styleRuns, int styleRunCount,
+ *                      int lineWidth,
+ *                      UErrorCode *pErrorCode) {
+ *     UBiDi *para;
+ *
+ *     if(pErrorCode==NULL || U_FAILURE(*pErrorCode) || length<=0) {
+ *         return;
+ *     }
+ *
+ *     para=ubidi_openSized(length, 0, pErrorCode);
+ *     if(para==NULL) { return; }
+ *
+ *     ubidi_setPara(para, text, length,
+ *                   textDirection ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,
+ *                   NULL, pErrorCode);
+ *     if(U_SUCCESS(*pErrorCode)) {
+ *         UBiDiLevel paraLevel=1&ubidi_getParaLevel(para);
+ *         StyleRun styleRun={ length, styleNormal };
+ *         int width;
+ *
+ *         if(styleRuns==NULL || styleRunCount<=0) {
+ *            styleRunCount=1;
+ *             styleRuns=&styleRun;
+ *         }
+ *
+ *        // assume styleRuns[styleRunCount-1].limit>=length
+ *
+ *         width=getTextWidth(text, 0, length, styleRuns, styleRunCount);
+ *         if(width<=lineWidth) {
+ *             // everything fits onto one line
+ *
+ *            // prepare rendering a new line from either left or right
+ *             startLine(paraLevel, width);
+ *
+ *             renderLine(para, text, 0, length,
+ *                        styleRuns, styleRunCount);
+ *         } else {
+ *             UBiDi *line;
+ *
+ *             // we need to render several lines
+ *             line=ubidi_openSized(length, 0, pErrorCode);
+ *             if(line!=NULL) {
+ *                 int32_t start=0, limit;
+ *                 int styleRunStart=0, styleRunLimit;
+ *
+ *                 for(;;) {
+ *                     limit=length;
+ *                     styleRunLimit=styleRunCount;
+ *                     getLineBreak(text, start, &limit, para,
+ *                                  styleRuns, styleRunStart, &styleRunLimit,
+ *                                 &width);
+ *                     ubidi_setLine(para, start, limit, line, pErrorCode);
+ *                     if(U_SUCCESS(*pErrorCode)) {
+ *                         // prepare rendering a new line
+ *                         // from either left or right
+ *                         startLine(paraLevel, width);
+ *
+ *                         renderLine(line, text, start, limit,
+ *                                    styleRuns+styleRunStart,
+ *                                    styleRunLimit-styleRunStart);
+ *                     }
+ *                     if(limit==length) { break; }
+ *                     start=limit;
+ *                     styleRunStart=styleRunLimit-1;
+ *                     if(start>=styleRuns[styleRunStart].limit) {
+ *                         ++styleRunStart;
+ *                     }
+ *                 }
+ *
+ *                 ubidi_close(line);
+ *             }
+ *        }
+ *    }
+ *
+ *     ubidi_close(para);
+ *}
+ *\endcode
+ * </pre>
+ */
+
+/*DOCXX_TAG*/
+/*@{*/
+
+/**
+ * UBiDiLevel is the type of the level values in this
+ * BiDi implementation.
+ * It holds an embedding level and indicates the visual direction
+ * by its bit&nbsp;0 (even/odd value).<p>
+ *
+ * It can also hold non-level values for the
+ * <code>paraLevel</code> and <code>embeddingLevels</code>
+ * arguments of <code>ubidi_setPara()</code>; there:
+ * <ul>
+ * <li>bit&nbsp;7 of an <code>embeddingLevels[]</code>
+ * value indicates whether the using application is
+ * specifying the level of a character to <i>override</i> whatever the
+ * BiDi implementation would resolve it to.</li>
+ * <li><code>paraLevel</code> can be set to the
+ * pseudo-level values <code>UBIDI_DEFAULT_LTR</code>
+ * and <code>UBIDI_DEFAULT_RTL</code>.</li>
+ * </ul>
+ *
+ * @see ubidi_setPara
+ *
+ * <p>The related constants are not real, valid level values.
+ * <code>UBIDI_DEFAULT_XXX</code> can be used to specify
+ * a default for the paragraph level for
+ * when the <code>ubidi_setPara()</code> function
+ * shall determine it but there is no
+ * strongly typed character in the input.<p>
+ *
+ * Note that the value for <code>UBIDI_DEFAULT_LTR</code> is even
+ * and the one for <code>UBIDI_DEFAULT_RTL</code> is odd,
+ * just like with normal LTR and RTL level values -
+ * these special values are designed that way. Also, the implementation
+ * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
+ *
+ * @see UBIDI_DEFAULT_LTR
+ * @see UBIDI_DEFAULT_RTL
+ * @see UBIDI_LEVEL_OVERRIDE
+ * @see UBIDI_MAX_EXPLICIT_LEVEL
+ * @stable ICU 2.0
+ */
+typedef uint8_t UBiDiLevel;
+
+/** Paragraph level setting.
+ *  If there is no strong character, then set the paragraph level to 0 (left-to-right).
+ * @stable ICU 2.0
+ */
+#define UBIDI_DEFAULT_LTR 0xfe
+
+/** Paragraph level setting.
+ *  If there is no strong character, then set the paragraph level to 1 (right-to-left).
+ * @stable ICU 2.0
+ */
+#define UBIDI_DEFAULT_RTL 0xff
+
+/**
+ * Maximum explicit embedding level.
+ * (The maximum resolved level can be up to <code>UBIDI_MAX_EXPLICIT_LEVEL+1</code>).
+ * @stable ICU 2.0
+ */
+#define UBIDI_MAX_EXPLICIT_LEVEL 61
+
+/** Bit flag for level input.
+ *  Overrides directional properties.
+ * @stable ICU 2.0
+ */
+#define UBIDI_LEVEL_OVERRIDE 0x80
+
+/**
+ * Special value which can be returned by the mapping functions when a logical
+ * index has no corresponding visual index or vice-versa. This may happen
+ * for the logical-to-visual mapping of a BiDi control when option
+ * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> is specified. This can also happen
+ * for the visual-to-logical mapping of a BiDi mark (LRM or RLM) inserted
+ * by option <code>#UBIDI_OPTION_INSERT_MARKS</code>.
+ * @see ubidi_getVisualIndex
+ * @see ubidi_getVisualMap
+ * @see ubidi_getLogicalIndex
+ * @see ubidi_getLogicalMap
+ * @draft ICU 3.6
+ */
+#define UBIDI_MAP_NOWHERE   (-1)
+
+/**
+ * <code>UBiDiDirection</code> values indicate the text direction.
+ * @stable ICU 2.0
+ */
+enum UBiDiDirection {
+    /** All left-to-right text. This is a 0 value. @stable ICU 2.0 */
+    UBIDI_LTR,
+    /** All right-to-left text. This is a 1 value. @stable ICU 2.0 */
+    UBIDI_RTL,
+    /** Mixed-directional text. @stable ICU 2.0 */
+    UBIDI_MIXED
+};
+
+/** @stable ICU 2.0 */
+typedef enum UBiDiDirection UBiDiDirection;
+
+/**
+ * Forward declaration of the <code>UBiDi</code> structure for the declaration of
+ * the API functions. Its fields are implementation-specific.<p>
+ * This structure holds information about a paragraph (or multiple paragraphs)
+ * of text with BiDi-algorithm-related details, or about one line of
+ * such a paragraph.<p>
+ * Reordering can be done on a line, or on one or more paragraphs which are
+ * then interpreted each as one single line.
+ * @stable ICU 2.0
+ */
+struct UBiDi;
+
+/** @stable ICU 2.0 */
+typedef struct UBiDi UBiDi;
+
+/**
+ * Allocate a <code>UBiDi</code> structure.
+ * Such an object is initially empty. It is assigned
+ * the BiDi properties of a piece of text containing one or more paragraphs
+ * by <code>ubidi_setPara()</code>
+ * or the BiDi properties of a line within a paragraph by
+ * <code>ubidi_setLine()</code>.<p>
+ * This object can be reused for as long as it is not deallocated
+ * by calling <code>ubidi_close()</code>.<p>
+ * <code>ubidi_setPara()</code> and <code>ubidi_setLine()</code> will allocate
+ * additional memory for internal structures as necessary.
+ *
+ * @return An empty <code>UBiDi</code> object.
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDi * U_EXPORT2
+ubidi_open(void);
+
+/**
+ * Allocate a <code>UBiDi</code> structure with preallocated memory
+ * for internal structures.
+ * This function provides a <code>UBiDi</code> object like <code>ubidi_open()</code>
+ * with no arguments, but it also preallocates memory for internal structures
+ * according to the sizings supplied by the caller.<p>
+ * Subsequent functions will not allocate any more memory, and are thus
+ * guaranteed not to fail because of lack of memory.<p>
+ * The preallocation can be limited to some of the internal memory
+ * by setting some values to 0 here. That means that if, e.g.,
+ * <code>maxRunCount</code> cannot be reasonably predetermined and should not
+ * be set to <code>maxLength</code> (the only failproof value) to avoid
+ * wasting memory, then <code>maxRunCount</code> could be set to 0 here
+ * and the internal structures that are associated with it will be allocated
+ * on demand, just like with <code>ubidi_open()</code>.
+ *
+ * @param maxLength is the maximum text or line length that internal memory
+ *        will be preallocated for. An attempt to associate this object with a
+ *        longer text will fail, unless this value is 0, which leaves the allocation
+ *        up to the implementation.
+ *
+ * @param maxRunCount is the maximum anticipated number of same-level runs
+ *        that internal memory will be preallocated for. An attempt to access
+ *        visual runs on an object that was not preallocated for as many runs
+ *        as the text was actually resolved to will fail,
+ *        unless this value is 0, which leaves the allocation up to the implementation.<br><br>
+ *        The number of runs depends on the actual text and maybe anywhere between
+ *        1 and <code>maxLength</code>. It is typically small.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return An empty <code>UBiDi</code> object with preallocated memory.
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDi * U_EXPORT2
+ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode);
+
+/**
+ * <code>ubidi_close()</code> must be called to free the memory
+ * associated with a UBiDi object.<p>
+ *
+ * <strong>Important: </strong>
+ * A parent <code>UBiDi</code> object must not be destroyed or reused if
+ * it still has children.
+ * If a <code>UBiDi</code> object has become the <i>child</i>
+ * of another one (its <i>parent</i>) by calling
+ * <code>ubidi_setLine()</code>, then the child object must
+ * be destroyed (closed) or reused (by calling
+ * <code>ubidi_setPara()</code> or <code>ubidi_setLine()</code>)
+ * before the parent object.
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ *
+ * @see ubidi_setPara
+ * @see ubidi_setLine
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_close(UBiDi *pBiDi);
+
+/**
+ * Modify the operation of the BiDi algorithm such that it
+ * approximates an "inverse BiDi" algorithm. This function
+ * must be called before <code>ubidi_setPara()</code>.
+ *
+ * <p>The normal operation of the BiDi algorithm as described
+ * in the Unicode Technical Report is to take text stored in logical
+ * (keyboard, typing) order and to determine the reordering of it for visual
+ * rendering.
+ * Some legacy systems store text in visual order, and for operations
+ * with standard, Unicode-based algorithms, the text needs to be transformed
+ * to logical order. This is effectively the inverse algorithm of the
+ * described BiDi algorithm. Note that there is no standard algorithm for
+ * this "inverse BiDi" and that the current implementation provides only an
+ * approximation of "inverse BiDi".</p>
+ *
+ * <p>With <code>isInverse</code> set to <code>TRUE</code>,
+ * this function changes the behavior of some of the subsequent functions
+ * in a way that they can be used for the inverse BiDi algorithm.
+ * Specifically, runs of text with numeric characters will be treated in a
+ * special way and may need to be surrounded with LRM characters when they are
+ * written in reordered sequence.</p>
+ *
+ * <p>Output runs should be retrieved using <code>ubidi_getVisualRun()</code>.
+ * Since the actual input for "inverse BiDi" is visually ordered text and
+ * <code>ubidi_getVisualRun()</code> gets the reordered runs, these are actually
+ * the runs of the logically ordered output.</p>
+ *
+ * <p>Calling this function with argument <code>isInverse</code> set to
+ * <code>TRUE</code> is equivalent to calling
+ * <code>ubidi_setReorderingMode</code> with argument
+ * <code>reorderingMode</code>
+ * set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.<br>
+ * Calling this function with argument <code>isInverse</code> set to
+ * <code>FALSE</code> is equivalent to calling
+ * <code>ubidi_setReorderingMode</code> with argument
+ * <code>reorderingMode</code>
+ * set to <code>#UBIDI_REORDER_DEFAULT</code>.
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ *
+ * @param isInverse specifies "forward" or "inverse" BiDi operation.
+ *
+ * @see ubidi_setPara
+ * @see ubidi_writeReordered
+ * @see ubidi_setReorderingMode
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_setInverse(UBiDi *pBiDi, UBool isInverse);
+
+/**
+ * Is this BiDi object set to perform the inverse BiDi algorithm?
+ * <p>Note: calling this function after setting the reordering mode with
+ * <code>ubidi_setReorderingMode</code> will return <code>TRUE</code> if the
+ * reordering mode was set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>,
+ * <code>FALSE</code> for all other values.</p>
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @return TRUE if the BiDi object is set to perform the inverse BiDi algorithm
+ * by handling numbers as L.
+ *
+ * @see ubidi_setInverse
+ * @see ubidi_setReorderingMode
+ * @stable ICU 2.0
+ */
+
+U_STABLE UBool U_EXPORT2
+ubidi_isInverse(UBiDi *pBiDi);
+
+/**
+ * Specify whether block separators must be allocated level zero,
+ * so that successive paragraphs will progress from left to right.
+ * This function must be called before <code>ubidi_setPara()</code>.
+ * Paragraph separators (B) may appear in the text.  Setting them to level zero
+ * means that all paragraph separators (including one possibly appearing
+ * in the last text position) are kept in the reordered text after the text
+ * that they follow in the source text.
+ * When this feature is not enabled, a paragraph separator at the last
+ * position of the text before reordering will go to the first position
+ * of the reordered text when the paragraph level is odd.
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ *
+ * @param orderParagraphsLTR specifies whether paragraph separators (B) must
+ * receive level 0, so that successive paragraphs progress from left to right.
+ *
+ * @see ubidi_setPara
+ * @stable ICU 3.4
+ */
+U_STABLE void U_EXPORT2
+ubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR);
+
+/**
+ * Is this BiDi object set to allocate level 0 to block separators so that
+ * successive paragraphs progress from left to right?
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @return TRUE if the BiDi object is set to allocate level 0 to block
+ *         separators.
+ *
+ * @see ubidi_orderParagraphsLTR
+ * @stable ICU 3.4
+ */
+U_STABLE UBool U_EXPORT2
+ubidi_isOrderParagraphsLTR(UBiDi *pBiDi);
+
+/**
+ * <code>UBiDiReorderingMode</code> values indicate which variant of the BiDi
+ * algorithm to use.
+ *
+ * @see ubidi_setReorderingMode
+ * @draft ICU 3.6
+ */
+typedef enum UBiDiReorderingMode {
+    /** Regular Logical to Visual BiDi algorithm according to Unicode.
+      * This is a 0 value. @draft ICU 3.6 */
+    UBIDI_REORDER_DEFAULT = 0,
+    /** Logical to Visual algorithm which handles numbers in a way which
+      * mimicks the behavior of Windows XP.
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_NUMBERS_SPECIAL,
+    /** Logical to Visual algorithm grouping numbers with adjacent R characters
+      * (reversible algorithm).
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_GROUP_NUMBERS_WITH_R,
+    /** Reorder runs only to transform a Logical LTR string to the Logical RTL
+      * string with the same display, or vice-versa.<br>
+      * If this mode is set together with option
+      * <code>#UBIDI_OPTION_INSERT_MARKS</code>, some BiDi controls in the source
+      * text may be removed and other controls may be added to produce the
+      * minimum combination which has the required display.
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_RUNS_ONLY,
+    /** Visual to Logical algorithm which handles numbers like L
+      * (same algorithm as selected by <code>ubidi_setInverse(TRUE)</code>.
+      * @see ubidi_setInverse
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_INVERSE_NUMBERS_AS_L,
+    /** Visual to Logical algorithm equivalent to the regular Logical to Visual
+      * algorithm. @draft ICU 3.6 */
+    UBIDI_REORDER_INVERSE_LIKE_DIRECT,
+    /** Inverse BiDi (Visual to Logical) algorithm for the
+      * <code>UBIDI_REORDER_NUMBERS_SPECIAL</code> BiDi algorithm.
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL,
+    /** Number of values for reordering mode.
+      * @draft ICU 3.6 */
+    UBIDI_REORDER_COUNT
+} UBiDiReorderingMode;
+
+/**
+ * Modify the operation of the BiDi algorithm such that it implements some
+ * variant to the basic BiDi algorithm or approximates an "inverse BiDi"
+ * algorithm, depending on different values of the "reordering mode".
+ * This function must be called before <code>ubidi_setPara()</code>, and stays
+ * in effect until called again with a different argument.
+ *
+ * <p>The normal operation of the BiDi algorithm as described
+ * in the Unicode Standard Annex #9 is to take text stored in logical
+ * (keyboard, typing) order and to determine how to reorder it for visual
+ * rendering.</p>
+ *
+ * <p>With the reordering mode set to a value other than
+ * <code>#UBIDI_REORDER_DEFAULT</code>, this function changes the behavior of
+ * some of the subsequent functions in a way such that they implement an
+ * inverse BiDi algorithm or some other algorithm variants.</p>
+ *
+ * <p>Some legacy systems store text in visual order, and for operations
+ * with standard, Unicode-based algorithms, the text needs to be transformed
+ * into logical order. This is effectively the inverse algorithm of the
+ * described BiDi algorithm. Note that there is no standard algorithm for
+ * this "inverse BiDi", so a number of variants are implemented here.</p>
+ *
+ * <p>In other cases, it may be desirable to emulate some variant of the
+ * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a
+ * Logical to Logical transformation.</p>
+ *
+ * <ul>
+ * <li>When the reordering mode is set to <code>#UBIDI_REORDER_DEFAULT</code>,
+ * the standard BiDi Logical to Visual algorithm is applied.</li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_NUMBERS_SPECIAL</code>,
+ * the algorithm used to perform BiDi transformations when calling
+ * <code>ubidi_setPara</code> should approximate the algorithm used in
+ * Microsoft Windows XP rather than strictly conform to the Unicode BiDi
+ * algorithm.
+ * <br>
+ * The differences between the basic algorithm and the algorithm addressed
+ * by this option are as follows:
+ * <ul>
+ *   <li>Within text at an even embedding level, the sequence "123AB"
+ *   (where AB represent R or AL letters) is transformed to "123BA" by the
+ *   Unicode algorithm and to "BA123" by the Windows algorithm.</li>
+ *   <li>Arabic-Indic numbers (AN) are handled by the Windows algorithm just
+ *   like regular numbers (EN).</li>
+ * </ul></li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_GROUP_NUMBERS_WITH_R</code>,
+ * numbers located between LTR text and RTL text are associated with the RTL
+ * text. For instance, an LTR paragraph with content "abc 123 DEF" (where
+ * upper case letters represent RTL characters) will be transformed to
+ * "abc FED 123" (and not "abc 123 FED"), "DEF 123 abc" will be transformed
+ * to "123 FED abc" and "123 FED abc" will be transformed to "DEF 123 abc".
+ * This makes the algorithm reversible and makes it useful when round trip
+ * (from visual to logical and back to visual) must be achieved without
+ * adding LRM characters. However, this is a variation from the standard
+ * Unicode Bidi algorithm.<br>
+ * The source text should not contain BiDi control characters other than LRM
+ * or RLM.</li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_RUNS_ONLY</code>,
+ * a "Logical to Logical" transformation must be performed:
+ * <ul>
+ * <li>If the default text level of the source text (argument <code>paraLevel</code>
+ * in <code>ubidi_setPara</code>) is even, the source text will be handled as
+ * LTR logical text and will be transformed to the RTL logical text which has
+ * the same LTR visual display.</li>
+ * <li>If the default level of the source text is odd, the source text
+ * will be handled as RTL logical text and will be transformed to the
+ * LTR logical text which has the same LTR visual display.</li>
+ * </ul>
+ * This mode may be needed when logical text which is basically Arabic or
+ * Hebrew, with possible included numbers or phrases in English, has to be
+ * displayed as if it had an even embedding level (this can happen if the
+ * displaying application treats all text as if it was basically LTR.
+ * <br>
+ * This mode may also be needed in the reverse case, when logical text which is
+ * basically English, with possible included phrases in Arabic or Hebrew, has to
+ * be displayed as if it had an odd embedding level.
+ * <br>
+ * Both cases could be handled by adding LRE or RLE at the head of the text,
+ * if the display subsystem supports these formatting controls. If it does not,
+ * the problem may be handled by transforming the source text in this mode
+ * before displaying it, so that it will be displayed properly.<br>
+ * The source text should not contain BiDi control characters other than LRM
+ * or RLM.</li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>, an "inverse BiDi" algorithm
+ * is applied.
+ * Runs of text with numeric characters will be treated like LTR letters and
+ * may need to be surrounded with LRM characters when they are written in
+ * reordered sequence (the option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> can
+ * be used with function <code>ubidi_writeReordered</code> to this end. This
+ * mode is equivalent to calling <code>ubidi_setInverse()</code> with
+ * argument <code>isInverse</code> set to <code>TRUE</code>.</li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_INVERSE_LIKE_DIRECT</code>, the "direct" Logical to Visual
+ * BiDi algorithm is used as an approximation of an "inverse BiDi" algorithm.
+ * This mode is similar to mode <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>
+ * but is closer to the regular BiDi algorithm.
+ * <br>
+ * For example, an LTR paragraph with the content "FED 123 456 CBA" (where
+ * upper case represents RTL characters) will be transformed to
+ * "ABC 456 123 DEF", as opposed to "DEF 123 456 ABC"
+ * with mode <code>UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.<br>
+ * When used in conjunction with option
+ * <code>#UBIDI_OPTION_INSERT_MARKS</code>, this mode generally
+ * adds BiDi marks to the output significantly more sparingly than mode
+ * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> with option
+ * <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls to
+ * <code>ubidi_writeReordered</code>.</li>
+ *
+ * <li>When the reordering mode is set to
+ * <code>#UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the Logical to Visual
+ * BiDi algorithm used in Windows XP is used as an approximation of an
+ * "inverse BiDi" algorithm.
+ * <br>
+ * For example, an LTR paragraph with the content "abc FED123" (where
+ * upper case represents RTL characters) will be transformed to
+ * "abc 123DEF.</li>
+ * </ul>
+ *
+ * <p>In all the reordering modes specifying an "inverse BiDi" algorithm
+ * (i.e. those with a name starting with <code>UBIDI_REORDER_INVERSE</code>),
+ * output runs should be retrieved using
+ * <code>ubidi_getVisualRun()</code>, and the output text with
+ * <code>ubidi_writeReordered()</code>. The caller should keep in mind that in
+ * "inverse BiDi" modes the input is actually visually ordered text and
+ * reordered output returned by <code>ubidi_getVisualRun()</code> or
+ * <code>ubidi_writeReordered()</code> are actually runs or character string
+ * of logically ordered output.<br>
+ * For all the "inverse BiDi" modes, the source text should not contain
+ * BiDi control characters other than LRM or RLM.</p>
+ *
+ * <p>Note that option <code>#UBIDI_OUTPUT_REVERSE</code> of
+ * <code>ubidi_writeReordered</code> has no useful meaning and should not be
+ * used in conjunction with any value of the reordering mode specifying
+ * "inverse BiDi" or with value <code>UBIDI_REORDER_RUNS_ONLY</code>.
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @param reorderingMode specifies the required variant of the BiDi algorithm.
+ *
+ * @see UBiDiReorderingMode
+ * @see ubidi_setInverse
+ * @see ubidi_setPara
+ * @see ubidi_writeReordered
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode);
+
+/**
+ * What is the requested reordering mode for a given BiDi object?
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @return the current reordering mode of the BiDi object
+ * @see ubidi_setReorderingMode
+ * @draft ICU 3.6
+ */
+U_DRAFT UBiDiReorderingMode U_EXPORT2
+ubidi_getReorderingMode(UBiDi *pBiDi);
+
+/**
+ * <code>UBiDiReorderingOption</code> values indicate which options are
+ * specified to affect the BiDi algorithm.
+ *
+ * @see ubidi_setReorderingOptions
+ * @draft ICU 3.6
+ */
+typedef enum UBiDiReorderingOption {
+    /**
+     * option value for <code>ubidi_setReorderingOptions</code>:
+     * disable all the options which can be set with this function
+     * @see ubidi_setReorderingOptions
+     * @draft ICU 3.6
+     */
+    UBIDI_OPTION_DEFAULT = 0,
+
+    /**
+     * option bit for <code>ubidi_setReorderingOptions</code>:
+     * insert BiDi marks (LRM or RLM) when needed to ensure correct result of
+     * a reordering to a Logical order
+     *
+     * <p>This option must be set or reset before calling
+     * <code>ubidi_setPara</code>.</p>
+     *
+     * <p>This option is significant only with reordering modes which generate
+     * a result with Logical order, specifically:</p>
+     * <ul>
+     *   <li><code>#UBIDI_REORDER_RUNS_ONLY</code></li>
+     *   <li><code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code></li>
+     *   <li><code>#UBIDI_REORDER_INVERSE_LIKE_DIRECT</code></li>
+     *   <li><code>#UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code></li>
+     * </ul>
+     *
+     * <p>If this option is set in conjunction with reordering mode
+     * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> or with calling
+     * <code>ubidi_setInverse(TRUE)</code>, it implies
+     * option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code>
+     * in calls to function <code>ubidi_writeReordered()</code>.</p>
+     *
+     * <p>For other reordering modes, a minimum number of LRM or RLM characters
+     * will be added to the source text after reordering it so as to ensure
+     * round trip, i.e. when applying the inverse reordering mode on the
+     * resulting logical text with removal of BiDi marks
+     * (option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> set before calling
+     * <code>ubidi_setPara()</code> or option <code>#UBIDI_REMOVE_BIDI_CONTROLS</code>
+     * in <code>ubidi_writeReordered</code>), the result will be identical to the
+     * source text in the first transformation.
+     *
+     * <p>This option will be ignored if specified together with option
+     * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>. It inhibits option
+     * <code>UBIDI_REMOVE_BIDI_CONTROLS</code> in calls to function
+     * <code>ubidi_writeReordered()</code> and it implies option
+     * <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls to function
+     * <code>ubidi_writeReordered()</code> if the reordering mode is
+     * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.</p>
+     *
+     * @see ubidi_setReorderingMode
+     * @see ubidi_setReorderingOptions
+     * @draft ICU 3.6
+     */
+    UBIDI_OPTION_INSERT_MARKS = 1,
+
+    /**
+     * option bit for <code>ubidi_setReorderingOptions</code>:
+     * remove BiDi control characters
+     *
+     * <p>This option must be set or reset before calling
+     * <code>ubidi_setPara</code>.</p>
+     *
+     * <p>This option nullifies option <code>#UBIDI_OPTION_INSERT_MARKS</code>.
+     * It inhibits option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls
+     * to function <code>ubidi_writeReordered()</code> and it implies option
+     * <code>#UBIDI_REMOVE_BIDI_CONTROLS</code> in calls to that function.</p>
+     *
+     * @see ubidi_setReorderingMode
+     * @see ubidi_setReorderingOptions
+     * @draft ICU 3.6
+     */
+    UBIDI_OPTION_REMOVE_CONTROLS = 2,
+
+    /**
+     * option bit for <code>ubidi_setReorderingOptions</code>:
+     * process the output as part of a stream to be continued
+     *
+     * <p>This option must be set or reset before calling
+     * <code>ubidi_setPara</code>.</p>
+     *
+     * <p>This option specifies that the caller is interested in processing large
+     * text object in parts.
+     * The results of the successive calls are expected to be concatenated by the
+     * caller. Only the call for the last part will have this option bit off.</p>
+     *
+     * <p>When this option bit is on, <code>ubidi_setPara()</code> may process
+     * less than the full source text in order to truncate the text at a meaningful
+     * boundary. The caller should call <code>ubidi_getProcessedLength()</code>
+     * immediately after calling <code>ubidi_setPara()</code> in order to
+     * determine how much of the source text has been processed.
+     * Source text beyond that length should be resubmitted in following calls to
+     * <code>ubidi_setPara</code>. The processed length may be less than
+     * the length of the source text if a character preceding the last character of
+     * the source text constitutes a reasonable boundary (like a block separator)
+     * for text to be continued.<br>
+     * If the last character of the source text constitutes a reasonable
+     * boundary, the whole text will be processed at once.<br>
+     * If nowhere in the source text there exists
+     * such a reasonable boundary, the processed length will be zero.<br>
+     * The caller should check for such an occurrence and do one of the following:
+     * <ul><li>submit a larger amount of text with a better chance to include
+     *         a reasonable boundary.</li>
+     *     <li>resubmit the same text after turning off option
+     *         <code>UBIDI_OPTION_STREAMING</code>.</li></ul>
+     * In all cases, this option should be turned off before processing the last
+     * part of the text.</p>
+     *
+     * <p>When the <code>UBIDI_OPTION_STREAMING</code> option is used,
+     * it is recommended to call <code>ubidi_orderParagraphsLTR()</code> with
+     * argument <code>orderParagraphsLTR</code> set to <code>TRUE</code> before
+     * calling <code>ubidi_setPara</code> so that later paragraphs may be
+     * concatenated to previous paragraphs on the right.</p>
+     *
+     * @see ubidi_setReorderingMode
+     * @see ubidi_setReorderingOptions
+     * @see ubidi_getProcessedLength
+     * @see ubidi_orderParagraphsLTR
+     * @draft ICU 3.6
+     */
+    UBIDI_OPTION_STREAMING = 4
+} UBiDiReorderingOption;
+
+/**
+ * Specify which of the reordering options
+ * should be applied during BiDi transformations.
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @param reorderingOptions is a combination of zero or more of the following
+ * options:
+ * <code>#UBIDI_OPTION_DEFAULT</code>, <code>#UBIDI_OPTION_INSERT_MARKS</code>,
+ * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>, <code>#UBIDI_OPTION_STREAMING</code>.
+ *
+ * @see ubidi_getReorderingOptions
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions);
+
+/**
+ * What are the reordering options applied to a given BiDi object?
+ *
+ * @param pBiDi is a <code>UBiDi</code> object.
+ * @return the current reordering options of the BiDi object
+ * @see ubidi_setReorderingOptions
+ * @draft ICU 3.6
+ */
+U_DRAFT uint32_t U_EXPORT2
+ubidi_getReorderingOptions(UBiDi *pBiDi);
+
+/**
+ * Perform the Unicode BiDi algorithm. It is defined in the
+ * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Anned #9</a>,
+ * version 13,
+ * also described in The Unicode Standard, Version 4.0 .<p>
+ *
+ * This function takes a piece of plain text containing one or more paragraphs,
+ * with or without externally specified embedding levels from <i>styled</i>
+ * text and computes the left-right-directionality of each character.<p>
+ *
+ * If the entire text is all of the same directionality, then
+ * the function may not perform all the steps described by the algorithm,
+ * i.e., some levels may not be the same as if all steps were performed.
+ * This is not relevant for unidirectional text.<br>
+ * For example, in pure LTR text with numbers the numbers would get
+ * a resolved level of 2 higher than the surrounding text according to
+ * the algorithm. This implementation may set all resolved levels to
+ * the same value in such a case.<p>
+ *
+ * The text can be composed of multiple paragraphs. Occurrence of a block
+ * separator in the text terminates a paragraph, and whatever comes next starts
+ * a new paragraph. The exception to this rule is when a Carriage Return (CR)
+ * is followed by a Line Feed (LF). Both CR and LF are block separators, but
+ * in that case, the pair of characters is considered as terminating the
+ * preceding paragraph, and a new paragraph will be started by a character
+ * coming after the LF.
+ *
+ * @param pBiDi A <code>UBiDi</code> object allocated with <code>ubidi_open()</code>
+ *        which will be set to contain the reordering information,
+ *        especially the resolved levels for all the characters in <code>text</code>.
+ *
+ * @param text is a pointer to the text that the BiDi algorithm will be performed on.
+ *        This pointer is stored in the UBiDi object and can be retrieved
+ *        with <code>ubidi_getText()</code>.<br>
+ *        <strong>Note:</strong> the text must be (at least) <code>length</code> long.
+ *
+ * @param length is the length of the text; if <code>length==-1</code> then
+ *        the text must be zero-terminated.
+ *
+ * @param paraLevel specifies the default level for the text;
+ *        it is typically 0 (LTR) or 1 (RTL).
+ *        If the function shall determine the paragraph level from the text,
+ *        then <code>paraLevel</code> can be set to
+ *        either <code>#UBIDI_DEFAULT_LTR</code>
+ *        or <code>#UBIDI_DEFAULT_RTL</code>; if the text contains multiple
+ *        paragraphs, the paragraph level shall be determined separately for
+ *        each paragraph; if a paragraph does not include any strongly typed
+ *        character, then the desired default is used (0 for LTR or 1 for RTL).
+ *        Any other value between 0 and <code>#UBIDI_MAX_EXPLICIT_LEVEL</code>
+ *        is also valid, with odd levels indicating RTL.
+ *
+ * @param embeddingLevels (in) may be used to preset the embedding and override levels,
+ *        ignoring characters like LRE and PDF in the text.
+ *        A level overrides the directional property of its corresponding
+ *        (same index) character if the level has the
+ *        <code>#UBIDI_LEVEL_OVERRIDE</code> bit set.<br><br>
+ *        Except for that bit, it must be
+ *        <code>paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL</code>,
+ *        with one exception: a level of zero may be specified for a paragraph
+ *        separator even if <code>paraLevel>0</code> when multiple paragraphs
+ *        are submitted in the same call to <code>ubidi_setPara()</code>.<br><br>
+ *        <strong>Caution: </strong>A copy of this pointer, not of the levels,
+ *        will be stored in the <code>UBiDi</code> object;
+ *        the <code>embeddingLevels</code> array must not be
+ *        deallocated before the <code>UBiDi</code> structure is destroyed or reused,
+ *        and the <code>embeddingLevels</code>
+ *        should not be modified to avoid unexpected results on subsequent BiDi operations.
+ *        However, the <code>ubidi_setPara()</code> and
+ *        <code>ubidi_setLine()</code> functions may modify some or all of the levels.<br><br>
+ *        After the <code>UBiDi</code> object is reused or destroyed, the caller
+ *        must take care of the deallocation of the <code>embeddingLevels</code> array.<br><br>
+ *        <strong>Note:</strong> the <code>embeddingLevels</code> array must be
+ *        at least <code>length</code> long.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length,
+              UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
+              UErrorCode *pErrorCode);
+
+/**
+ * <code>ubidi_setLine()</code> sets a <code>UBiDi</code> to
+ * contain the reordering information, especially the resolved levels,
+ * for all the characters in a line of text. This line of text is
+ * specified by referring to a <code>UBiDi</code> object representing
+ * this information for a piece of text containing one or more paragraphs,
+ * and by specifying a range of indexes in this text.<p>
+ * In the new line object, the indexes will range from 0 to <code>limit-start-1</code>.<p>
+ *
+ * This is used after calling <code>ubidi_setPara()</code>
+ * for a piece of text, and after line-breaking on that text.
+ * It is not necessary if each paragraph is treated as a single line.<p>
+ *
+ * After line-breaking, rules (L1) and (L2) for the treatment of
+ * trailing WS and for reordering are performed on
+ * a <code>UBiDi</code> object that represents a line.<p>
+ *
+ * <strong>Important: </strong><code>pLineBiDi</code> shares data with
+ * <code>pParaBiDi</code>.
+ * You must destroy or reuse <code>pLineBiDi</code> before <code>pParaBiDi</code>.
+ * In other words, you must destroy or reuse the <code>UBiDi</code> object for a line
+ * before the object for its parent paragraph.<p>
+ *
+ * The text pointer that was stored in <code>pParaBiDi</code> is also copied,
+ * and <code>start</code> is added to it so that it points to the beginning of the
+ * line for this object.
+ *
+ * @param pParaBiDi is the parent paragraph object. It must have been set
+ * by a successful call to ubidi_setPara.
+ *
+ * @param start is the line's first index into the text.
+ *
+ * @param limit is just behind the line's last index into the text
+ *        (its last index +1).<br>
+ *        It must be <code>0<=start<=limit<=</code>containing paragraph limit.
+ *        If the specified line crosses a paragraph boundary, the function
+ *        will terminate with error code U_ILLEGAL_ARGUMENT_ERROR.
+ *
+ * @param pLineBiDi is the object that will now represent a line of the text.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @see ubidi_setPara
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_setLine(const UBiDi *pParaBiDi,
+              int32_t start, int32_t limit,
+              UBiDi *pLineBiDi,
+              UErrorCode *pErrorCode);
+
+/**
+ * Get the directionality of the text.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @return A <code>UBIDI_XXX</code> value that indicates if the entire text
+ *         represented by this object is unidirectional,
+ *         and which direction, or if it is mixed-directional.
+ *
+ * @see UBiDiDirection
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDiDirection U_EXPORT2
+ubidi_getDirection(const UBiDi *pBiDi);
+
+/**
+ * Get the pointer to the text.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @return The pointer to the text that the UBiDi object was created for.
+ *
+ * @see ubidi_setPara
+ * @see ubidi_setLine
+ * @stable ICU 2.0
+ */
+U_STABLE const UChar * U_EXPORT2
+ubidi_getText(const UBiDi *pBiDi);
+
+/**
+ * Get the length of the text.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @return The length of the text that the UBiDi object was created for.
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_getLength(const UBiDi *pBiDi);
+
+/**
+ * Get the paragraph level of the text.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @return The paragraph level. If there are multiple paragraphs, their
+ *         level may vary if the required paraLevel is UBIDI_DEFAULT_LTR or
+ *         UBIDI_DEFAULT_RTL.  In that case, the level of the first paragraph
+ *         is returned.
+ *
+ * @see UBiDiLevel
+ * @see ubidi_getParagraph
+ * @see ubidi_getParagraphByIndex
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDiLevel U_EXPORT2
+ubidi_getParaLevel(const UBiDi *pBiDi);
+
+/**
+ * Get the number of paragraphs.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @return The number of paragraphs.
+ * @stable ICU 3.4
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_countParagraphs(UBiDi *pBiDi);
+
+/**
+ * Get a paragraph, given a position within the text.
+ * This function returns information about a paragraph.<p>
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param charIndex is the index of a character within the text, in the
+ *        range <code>[0..ubidi_getProcessedLength(pBiDi)-1]</code>.
+ *
+ * @param pParaStart will receive the index of the first character of the
+ *        paragraph in the text.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pParaLimit will receive the limit of the paragraph.
+ *        The l-value that you point to here may be the
+ *        same expression (variable) as the one for
+ *        <code>charIndex</code>.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pParaLevel will receive the level of the paragraph.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The index of the paragraph containing the specified position.
+ *
+ * @see ubidi_getProcessedLength
+ * @stable ICU 3.4
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex, int32_t *pParaStart,
+                   int32_t *pParaLimit, UBiDiLevel *pParaLevel,
+                   UErrorCode *pErrorCode);
+
+/**
+ * Get a paragraph, given the index of this paragraph.
+ *
+ * This function returns information about a paragraph.<p>
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @param paraIndex is the number of the paragraph, in the
+ *        range <code>[0..ubidi_countParagraphs(pBiDi)-1]</code>.
+ *
+ * @param pParaStart will receive the index of the first character of the
+ *        paragraph in the text.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pParaLimit will receive the limit of the paragraph.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pParaLevel will receive the level of the paragraph.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @stable ICU 3.4
+ */
+U_STABLE void U_EXPORT2
+ubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex,
+                          int32_t *pParaStart, int32_t *pParaLimit,
+                          UBiDiLevel *pParaLevel, UErrorCode *pErrorCode);
+
+/**
+ * Get the level for one character.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param charIndex the index of a character.
+ *
+ * @return The level for the character at charIndex.
+ *
+ * @see UBiDiLevel
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDiLevel U_EXPORT2
+ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex);
+
+/**
+ * Get an array of levels for each character.<p>
+ *
+ * Note that this function may allocate memory under some
+ * circumstances, unlike <code>ubidi_getLevelAt()</code>.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object, whose
+ *        text length must be strictly positive.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The levels array for the text,
+ *         or <code>NULL</code> if an error occurs.
+ *
+ * @see UBiDiLevel
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE const UBiDiLevel * U_EXPORT2
+ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode);
+
+/**
+ * Get a logical run.
+ * This function returns information about a run and is used
+ * to retrieve runs in logical order.<p>
+ * This is especially useful for line-breaking on a paragraph.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param logicalStart is the first character of the run.
+ *
+ * @param pLogicalLimit will receive the limit of the run.
+ *        The l-value that you point to here may be the
+ *        same expression (variable) as the one for
+ *        <code>logicalStart</code>.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @param pLevel will receive the level of the run.
+ *        This pointer can be <code>NULL</code> if this
+ *        value is not necessary.
+ *
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalStart,
+                    int32_t *pLogicalLimit, UBiDiLevel *pLevel);
+
+/**
+ * Get the number of runs.
+ * This function may invoke the actual reordering on the
+ * <code>UBiDi</code> object, after <code>ubidi_setPara()</code>
+ * may have resolved only the levels of the text. Therefore,
+ * <code>ubidi_countRuns()</code> may have to allocate memory,
+ * and may fail doing so.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The number of runs.
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
+
+/**
+ * Get one run's logical start, length, and directionality,
+ * which can be 0 for LTR or 1 for RTL.
+ * In an RTL run, the character at the logical start is
+ * visually on the right of the displayed run.
+ * The length is the number of characters in the run.<p>
+ * <code>ubidi_countRuns()</code> should be called
+ * before the runs are retrieved.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param runIndex is the number of the run in visual order, in the
+ *        range <code>[0..ubidi_countRuns(pBiDi)-1]</code>.
+ *
+ * @param pLogicalStart is the first logical character index in the text.
+ *        The pointer may be <code>NULL</code> if this index is not needed.
+ *
+ * @param pLength is the number of characters (at least one) in the run.
+ *        The pointer may be <code>NULL</code> if this is not needed.
+ *
+ * @return the directionality of the run,
+ *         <code>UBIDI_LTR==0</code> or <code>UBIDI_RTL==1</code>,
+ *         never <code>UBIDI_MIXED</code>.
+ *
+ * @see ubidi_countRuns
+ *
+ * Example:
+ * <pre>
+ * \code
+ * int32_t i, count=ubidi_countRuns(pBiDi),
+ *         logicalStart, visualIndex=0, length;
+ * for(i=0; i<count; ++i) {
+ *    if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &length)) {
+ *         do { // LTR
+ *             show_char(text[logicalStart++], visualIndex++);
+ *         } while(--length>0);
+ *     } else {
+ *         logicalStart+=length;  // logicalLimit
+ *         do { // RTL
+ *             show_char(text[--logicalStart], visualIndex++);
+ *         } while(--length>0);
+ *     }
+ * }
+ *\endcode
+ * </pre>
+ *
+ * Note that in right-to-left runs, code like this places
+ * modifier letters before base characters and second surrogates
+ * before first ones.
+ * @stable ICU 2.0
+ */
+U_STABLE UBiDiDirection U_EXPORT2
+ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
+                   int32_t *pLogicalStart, int32_t *pLength);
+
+/**
+ * Get the visual position from a logical text position.
+ * If such a mapping is used many times on the same
+ * <code>UBiDi</code> object, then calling
+ * <code>ubidi_getLogicalMap()</code> is more efficient.<p>
+ *
+ * The value returned may be <code>#UBIDI_MAP_NOWHERE</code> if there is no
+ * visual position because the corresponding text character is a BiDi control
+ * removed from output by the option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>.
+ * <p>
+ * Note that in right-to-left runs, this mapping places
+ * modifier letters before base characters and second surrogates
+ * before first ones.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param logicalIndex is the index of a character in the text.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The visual position of this character.
+ *
+ * @see ubidi_getLogicalMap
+ * @see ubidi_getLogicalIndex
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode);
+
+/**
+ * Get the logical text position from a visual position.
+ * If such a mapping is used many times on the same
+ * <code>UBiDi</code> object, then calling
+ * <code>ubidi_getVisualMap()</code> is more efficient.<p>
+ *
+ * The value returned may be <code>#UBIDI_MAP_NOWHERE</code> if there is no
+ * logical position because the corresponding text character is a BiDi mark
+ * inserted in the output by option <code>#UBIDI_OPTION_INSERT_MARKS</code>.
+ * <p>
+ * This is the inverse function to <code>ubidi_getVisualIndex()</code>.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param visualIndex is the visual position of a character.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The index of this character in the text.
+ *
+ * @see ubidi_getVisualMap
+ * @see ubidi_getVisualIndex
+ * @see ubidi_getResultLength
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode);
+
+/**
+ * Get a logical-to-visual index map (array) for the characters in the UBiDi
+ * (paragraph or line) object.
+ * <p>
+ * Some values in the map may be <code>#UBIDI_MAP_NOWHERE</code> if the
+ * corresponding text characters are BiDi controls removed from the visual
+ * output by the option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param indexMap is a pointer to an array of <code>ubidi_getProcessedLength()</code>
+ *        indexes which will reflect the reordering of the characters.
+ *        If option <code>#UBIDI_OPTION_INSERT_MARKS</code> is set, the number
+ *        of elements allocated in <code>indexMap</code> must be no less than
+ *        <code>ubidi_getResultLength()</code>.
+ *        The array does not need to be initialized.<br><br>
+ *        The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @see ubidi_getVisualMap
+ * @see ubidi_getVisualIndex
+ * @see ubidi_getProcessedLength
+ * @see ubidi_getResultLength
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
+
+/**
+ * Get a visual-to-logical index map (array) for the characters in the UBiDi
+ * (paragraph or line) object.
+ * <p>
+ * Some values in the map may be <code>#UBIDI_MAP_NOWHERE</code> if the
+ * corresponding text characters are BiDi marks inserted in the visual output
+ * by the option <code>#UBIDI_OPTION_INSERT_MARKS</code>.
+ *
+ * @param pBiDi is the paragraph or line <code>UBiDi</code> object.
+ *
+ * @param indexMap is a pointer to an array of <code>ubidi_getResultLength()</code>
+ *        indexes which will reflect the reordering of the characters.
+ *        If option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> is set, the number
+ *        of elements allocated in <code>indexMap</code> must be no less than
+ *        <code>ubidi_getProcessedLength()</code>.
+ *        The array does not need to be initialized.<br><br>
+ *        The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @see ubidi_getLogicalMap
+ * @see ubidi_getLogicalIndex
+ * @see ubidi_getProcessedLength
+ * @see ubidi_getResultLength
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode);
+
+/**
+ * This is a convenience function that does not use a UBiDi object.
+ * It is intended to be used for when an application has determined the levels
+ * of objects (character sequences) and just needs to have them reordered (L2).
+ * This is equivalent to using <code>ubidi_getLogicalMap()</code> on a
+ * <code>UBiDi</code> object.
+ *
+ * @param levels is an array with <code>length</code> levels that have been determined by
+ *        the application.
+ *
+ * @param length is the number of levels in the array, or, semantically,
+ *        the number of objects to be reordered.
+ *        It must be <code>length>0</code>.
+ *
+ * @param indexMap is a pointer to an array of <code>length</code>
+ *        indexes which will reflect the reordering of the characters.
+ *        The array does not need to be initialized.<p>
+ *        The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
+
+/**
+ * This is a convenience function that does not use a UBiDi object.
+ * It is intended to be used for when an application has determined the levels
+ * of objects (character sequences) and just needs to have them reordered (L2).
+ * This is equivalent to using <code>ubidi_getVisualMap()</code> on a
+ * <code>UBiDi</code> object.
+ *
+ * @param levels is an array with <code>length</code> levels that have been determined by
+ *        the application.
+ *
+ * @param length is the number of levels in the array, or, semantically,
+ *        the number of objects to be reordered.
+ *        It must be <code>length>0</code>.
+ *
+ * @param indexMap is a pointer to an array of <code>length</code>
+ *        indexes which will reflect the reordering of the characters.
+ *        The array does not need to be initialized.<p>
+ *        The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap);
+
+/**
+ * Invert an index map.
+ * The index mapping of the first map is inverted and written to
+ * the second one.
+ *
+ * @param srcMap is an array with <code>length</code> indexes
+ *        which defines the original mapping from a source array containing
+ *        <code>length</code> elements to a destination array.
+ *        All indexes must be >=0 or equal to <code>UBIDI_MAP_NOWHERE</code>.
+ *        This special value means that the corresponding elements in the source
+ *        array have no matching element in the destination array.
+ *        Some indexes may have a value >= <code>length</code>, if the
+ *        destination array has more elements than the source array.
+ *        There must be no duplicate indexes (two or more indexes with the
+ *        same value except <code>UBIDI_MAP_NOWHERE</code>).
+ *
+ * @param destMap is an array with a number of indexes equal to 1 + the highest
+ *        value in <code>srcMap</code>.
+ *        <code>destMap</code> will be filled with the inverse mapping.
+ *        Elements of <code>destMap</code> which have no matching elements in
+ *        <code>srcMap</code> will receive an index equal to
+ *        <code>UBIDI_MAP_NOWHERE</code>
+ *
+ * @param length is the length of each array.
+ * @See UBIDI_MAP_NOWHERE
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length);
+
+/** option flags for ubidi_writeReordered() */
+
+/**
+ * option bit for ubidi_writeReordered():
+ * keep combining characters after their base characters in RTL runs
+ *
+ * @see ubidi_writeReordered
+ * @stable ICU 2.0
+ */
+#define UBIDI_KEEP_BASE_COMBINING       1
+
+/**
+ * option bit for ubidi_writeReordered():
+ * replace characters with the "mirrored" property in RTL runs
+ * by their mirror-image mappings
+ *
+ * @see ubidi_writeReordered
+ * @stable ICU 2.0
+ */
+#define UBIDI_DO_MIRRORING              2
+
+/**
+ * option bit for ubidi_writeReordered():
+ * surround the run with LRMs if necessary;
+ * this is part of the approximate "inverse BiDi" algorithm
+ *
+ * <p>This option does not imply corresponding adjustment of the index
+ * mappings.</p>
+ *
+ * @see ubidi_setInverse
+ * @see ubidi_writeReordered
+ * @stable ICU 2.0
+ */
+#define UBIDI_INSERT_LRM_FOR_NUMERIC    4
+
+/**
+ * option bit for ubidi_writeReordered():
+ * remove BiDi control characters
+ * (this does not affect #UBIDI_INSERT_LRM_FOR_NUMERIC)
+ *
+ * <p>This option does not imply corresponding adjustment of the index
+ * mappings.</p>
+ *
+ * @see ubidi_writeReordered
+ * @stable ICU 2.0
+ */
+#define UBIDI_REMOVE_BIDI_CONTROLS      8
+
+/**
+ * option bit for ubidi_writeReordered():
+ * write the output in reverse order
+ *
+ * <p>This has the same effect as calling <code>ubidi_writeReordered()</code>
+ * first without this option, and then calling
+ * <code>ubidi_writeReverse()</code> without mirroring.
+ * Doing this in the same step is faster and avoids a temporary buffer.
+ * An example for using this option is output to a character terminal that
+ * is designed for RTL scripts and stores text in reverse order.</p>
+ *
+ * @see ubidi_writeReordered
+ * @stable ICU 2.0
+ */
+#define UBIDI_OUTPUT_REVERSE            16
+
+/**
+ * Get the length of the source text processed by the last call to
+ * <code>ubidi_setPara()</code>. This length may be different from the length
+ * of the source text if option <code>#UBIDI_OPTION_STREAMING</code>
+ * has been set.
+ * <br>
+ * Note that whenever the length of the text affects the execution or the
+ * result of a function, it is the processed length which must be considered,
+ * except for <code>ubidi_setPara</code> (which receives unprocessed source
+ * text) and <code>ubidi_getLength</code> (which returns the original length
+ * of the source text).<br>
+ * In particular, the processed length is the one to consider in the following
+ * cases:
+ * <ul>
+ * <li>maximum value of the <code>limit</code> argument of
+ * <code>ubidi_setLine</code></li>
+ * <li>maximum value of the <code>charIndex</code> argument of
+ * <code>ubidi_getParagraph</code></li>
+ * <li>maximum value of the <code>charIndex</code> argument of
+ * <code>ubidi_getLevelAt</code></li>
+ * <li>number of elements in the array returned by <code>ubidi_getLevels</code></li>
+ * <li>maximum value of the <code>logicalStart</code> argument of
+ * <code>ubidi_getLogicalRun</code></li>
+ * <li>maximum value of the <code>logicalIndex</code> argument of
+ * <code>ubidi_getVisualIndex</code></li>
+ * <li>number of elements filled in the <code>*indexMap</code> argument of
+ * <code>ubidi_getLogicalMap</code></li>
+ * <li>length of text processed by <code>ubidi_writeReordered</code></li>
+ * </ul>
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @return The length of the part of the source text processed by
+ *         the last call to <code>ubidi_setPara</code>.
+ * @see ubidi_setPara
+ * @see UBIDI_OPTION_STREAMING
+ * @draft ICU 3.6
+ */
+U_DRAFT int32_t U_EXPORT2
+ubidi_getProcessedLength(const UBiDi *pBiDi);
+
+/**
+ * Get the length of the reordered text resulting from the last call to
+ * <code>ubidi_setPara()</code>. This length may be different from the length
+ * of the source text if option <code>#UBIDI_OPTION_INSERT_MARKS</code>
+ * or option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> has been set.
+ * <br>
+ * This resulting length is the one to consider in the following cases:
+ * <ul>
+ * <li>maximum value of the <code>visualIndex</code> argument of
+ * <code>ubidi_getLogicalIndex</code></li>
+ * <li>number of elements of the <code>*indexMap</code> argument of
+ * <code>ubidi_getVisualMap</code></li>
+ * </ul>
+ * Note that this length stays identical to the source text length if
+ * BiDi marks are inserted or removed using option bits of
+ * <code>ubidi_writeReordered</code>, or if option
+ * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> has been set.
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @return The length of the reordered text resulting from
+ *         the last call to <code>ubidi_setPara</code>.
+ * @see ubidi_setPara
+ * @see UBIDI_OPTION_INSERT_MARKS
+ * @see UBIDI_OPTION_REMOVE_CONTROLS
+ * @draft ICU 3.6
+ */
+U_DRAFT int32_t U_EXPORT2
+ubidi_getResultLength(const UBiDi *pBiDi);
+
+U_CDECL_BEGIN
+/**
+ * value returned by <code>UBiDiClassCallback</code> callbacks when
+ * there is no need to override the standard BiDi class for a given code point.
+ * @see UBiDiClassCallback
+ * @draft ICU 3.6
+ */
+#define U_BIDI_CLASS_DEFAULT  U_CHAR_DIRECTION_COUNT
+
+/**
+ * Callback type declaration for overriding default BiDi class values with
+ * custom ones.
+ * <p>Usually, the function pointer will be propagated to a <code>UBiDi</code>
+ * object by calling the <code>ubidi_setClassCallback()</code> function;
+ * then the callback will be invoked by the UBA implementation any time the
+ * class of a character is to be determined.</p>
+ *
+ * @param context is a pointer to the callback private data.
+ *
+ * @param c       is the code point to get a BiDi class for.
+ *
+ * @return The directional property / BiDi class for the given code point
+ *         <code>c</code> if the default class has been overridden, or
+ *         <code>#U_BIDI_CLASS_DEFAULT</code> if the standard BiDi class value
+ *         for <code>c</code> is to be used.
+ * @see ubidi_setClassCallback
+ * @see ubidi_getClassCallback
+ * @draft ICU 3.6
+ */
+typedef UCharDirection U_CALLCONV
+UBiDiClassCallback(const void *context, UChar32 c);
+
+U_CDECL_END
+
+/**
+ * Retrieve the BiDi class for a given code point.
+ * <p>If a <code>#UBiDiClassCallback</code> callback is defined and returns a
+ * value other than <code>#U_BIDI_CLASS_DEFAULT</code>, that value is used;
+ * otherwise the default class determination mechanism is invoked.</p>
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @param c     is the code point whose BiDi class must be retrieved.
+ *
+ * @return The BiDi class for character <code>c</code> based
+ *         on the given <code>pBiDi</code> instance.
+ * @see UBiDiClassCallback
+ * @draft ICU 3.6
+ */
+U_DRAFT UCharDirection U_EXPORT2
+ubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c);
+
+/**
+ * Set the callback function and callback data used by the UBA
+ * implementation for BiDi class determination.
+ * <p>This may be useful for assigning BiDi classes to PUA characters, or
+ * for special application needs. For instance, an application may want to
+ * handle all spaces like L or R characters (according to the base direction)
+ * when creating the visual ordering of logical lines which are part of a report
+ * organized in columns: there should not be interaction between adjacent
+ * cells.<p>
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @param newFn is the new callback function pointer.
+ *
+ * @param newContext is the new callback context pointer. This can be NULL.
+ *
+ * @param oldFn fillin: Returns the old callback function pointer. This can be
+ *                      NULL.
+ *
+ * @param oldContext fillin: Returns the old callback's context. This can be
+ *                           NULL.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @see ubidi_getClassCallback
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn,
+                       const void *newContext, UBiDiClassCallback **oldFn,
+                       const void **oldContext, UErrorCode *pErrorCode);
+
+/**
+ * Get the current callback function used for BiDi class determination.
+ *
+ * @param pBiDi is the paragraph <code>UBiDi</code> object.
+ *
+ * @param fn fillin: Returns the callback function pointer.
+ *
+ * @param context fillin: Returns the callback's private context.
+ *
+ * @see ubidi_setClassCallback
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context);
+
+/**
+ * Take a <code>UBiDi</code> object containing the reordering
+ * information for a piece of text (one or more paragraphs) set by
+ * <code>ubidi_setPara()</code> or for a line of text set by
+ * <code>ubidi_setLine()</code> and write a reordered string to the
+ * destination buffer.
+ *
+ * This function preserves the integrity of characters with multiple
+ * code units and (optionally) modifier letters.
+ * Characters in RTL runs can be replaced by mirror-image characters
+ * in the destination buffer. Note that "real" mirroring has
+ * to be done in a rendering engine by glyph selection
+ * and that for many "mirrored" characters there are no
+ * Unicode characters as mirror-image equivalents.
+ * There are also options to insert or remove BiDi control
+ * characters; see the description of the <code>destSize</code>
+ * and <code>options</code> parameters and of the option bit flags.
+ *
+ * @param pBiDi A pointer to a <code>UBiDi</code> object that
+ *              is set by <code>ubidi_setPara()</code> or
+ *              <code>ubidi_setLine()</code> and contains the reordering
+ *              information for the text that it was defined for,
+ *              as well as a pointer to that text.<br><br>
+ *              The text was aliased (only the pointer was stored
+ *              without copying the contents) and must not have been modified
+ *              since the <code>ubidi_setPara()</code> call.
+ *
+ * @param dest A pointer to where the reordered text is to be copied.
+ *             The source text and <code>dest[destSize]</code>
+ *             must not overlap.
+ *
+ * @param destSize The size of the <code>dest</code> buffer,
+ *                 in number of UChars.
+ *                 If the <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code>
+ *                 option is set, then the destination length could be
+ *                 as large as
+ *                 <code>ubidi_getLength(pBiDi)+2*ubidi_countRuns(pBiDi)</code>.
+ *                 If the <code>UBIDI_REMOVE_BIDI_CONTROLS</code> option
+ *                 is set, then the destination length may be less than
+ *                 <code>ubidi_getLength(pBiDi)</code>.
+ *                 If none of these options is set, then the destination length
+ *                 will be exactly <code>ubidi_getLength(pBiDi)</code>.
+ *
+ * @param options A bit set of options for the reordering that control
+ *                how the reordered text is written.
+ *                The options include mirroring the characters on a code
+ *                point basis and inserting LRM characters, which is used
+ *                especially for transforming visually stored text
+ *                to logically stored text (although this is still an
+ *                imperfect implementation of an "inverse BiDi" algorithm
+ *                because it uses the "forward BiDi" algorithm at its core).
+ *                The available options are:
+ *                <code>#UBIDI_DO_MIRRORING</code>,
+ *                <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code>,
+ *                <code>#UBIDI_KEEP_BASE_COMBINING</code>,
+ *                <code>#UBIDI_OUTPUT_REVERSE</code>,
+ *                <code>#UBIDI_REMOVE_BIDI_CONTROLS</code>
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The length of the output string.
+ *
+ * @see ubidi_getProcessedLength
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_writeReordered(UBiDi *pBiDi,
+                     UChar *dest, int32_t destSize,
+                     uint16_t options,
+                     UErrorCode *pErrorCode);
+
+/**
+ * Reverse a Right-To-Left run of Unicode text.
+ *
+ * This function preserves the integrity of characters with multiple
+ * code units and (optionally) modifier letters.
+ * Characters can be replaced by mirror-image characters
+ * in the destination buffer. Note that "real" mirroring has
+ * to be done in a rendering engine by glyph selection
+ * and that for many "mirrored" characters there are no
+ * Unicode characters as mirror-image equivalents.
+ * There are also options to insert or remove BiDi control
+ * characters.
+ *
+ * This function is the implementation for reversing RTL runs as part
+ * of <code>ubidi_writeReordered()</code>. For detailed descriptions
+ * of the parameters, see there.
+ * Since no BiDi controls are inserted here, the output string length
+ * will never exceed <code>srcLength</code>.
+ *
+ * @see ubidi_writeReordered
+ *
+ * @param src A pointer to the RTL run text.
+ *
+ * @param srcLength The length of the RTL run.
+ *
+ * @param dest A pointer to where the reordered text is to be copied.
+ *             <code>src[srcLength]</code> and <code>dest[destSize]</code>
+ *             must not overlap.
+ *
+ * @param destSize The size of the <code>dest</code> buffer,
+ *                 in number of UChars.
+ *                 If the <code>UBIDI_REMOVE_BIDI_CONTROLS</code> option
+ *                 is set, then the destination length may be less than
+ *                 <code>srcLength</code>.
+ *                 If this option is not set, then the destination length
+ *                 will be exactly <code>srcLength</code>.
+ *
+ * @param options A bit set of options for the reordering that control
+ *                how the reordered text is written.
+ *                See the <code>options</code> parameter in <code>ubidi_writeReordered()</code>.
+ *
+ * @param pErrorCode must be a valid pointer to an error code value.
+ *
+ * @return The length of the output string.
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubidi_writeReverse(const UChar *src, int32_t srcLength,
+                   UChar *dest, int32_t destSize,
+                   uint16_t options,
+                   UErrorCode *pErrorCode);
+
+/*#define BIDI_SAMPLE_CODE*/
+/*@}*/
+
+#endif

Added: MacRuby/branches/icu/unicode/ubrk.h
===================================================================
--- MacRuby/branches/icu/unicode/ubrk.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ubrk.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,478 @@
+/*
+******************************************************************************
+* Copyright (C) 1996-2006, International Business Machines Corporation and others.
+* All Rights Reserved.
+******************************************************************************
+*/
+
+#ifndef UBRK_H
+#define UBRK_H
+
+#include "unicode/utypes.h"
+#include "unicode/uloc.h"
+#include "unicode/utext.h"
+
+/**
+ * A text-break iterator.
+ *  For usage in C programs.
+ */
+#ifndef UBRK_TYPEDEF_UBREAK_ITERATOR
+#   define UBRK_TYPEDEF_UBREAK_ITERATOR
+    /**
+     *  Opaque type representing an ICU Break iterator object.
+     *  @stable ICU 2.0
+     */
+    typedef void UBreakIterator;
+#endif
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/parseerr.h"
+
+/**
+ * \file
+ * \brief C API: BreakIterator
+ *
+ * <h2> BreakIterator C API </h2>
+ *
+ * The BreakIterator C API defines  methods for finding the location
+ * of boundaries in text. Pointer to a UBreakIterator maintain a
+ * current position and scan over text returning the index of characters
+ * where boundaries occur.
+ * <p>
+ * Line boundary analysis determines where a text string can be broken
+ * when line-wrapping. The mechanism correctly handles punctuation and
+ * hyphenated words.
+ * <p>
+ * Sentence boundary analysis allows selection with correct
+ * interpretation of periods within numbers and abbreviations, and
+ * trailing punctuation marks such as quotation marks and parentheses.
+ * <p>
+ * Word boundary analysis is used by search and replace functions, as
+ * well as within text editing applications that allow the user to
+ * select words with a double click. Word selection provides correct
+ * interpretation of punctuation marks within and following
+ * words. Characters that are not part of a word, such as symbols or
+ * punctuation marks, have word-breaks on both sides.
+ * <p>
+ * Character boundary analysis allows users to interact with
+ * characters as they expect to, for example, when moving the cursor
+ * through a text string. Character boundary analysis provides correct
+ * navigation of through character strings, regardless of how the
+ * character is stored.  For example, an accented character might be
+ * stored as a base character and a diacritical mark. What users
+ * consider to be a character can differ between languages.
+ * <p>
+ * Title boundary analysis locates all positions,
+ * typically starts of words, that should be set to Title Case
+ * when title casing the text.
+ * <p>
+ * The text boundary positions are found according to the rules
+ * described in Unicode Standard Annex #29, Text Boundaries, and
+ * Unicode Standard Annex #14, Line Breaking Properties.  These
+ * are available at http://www.unicode.org/reports/tr14/ and
+ * http://www.unicode.org/reports/tr29/.
+ * <p>
+ * In addition to the plain C API defined in this header file, an
+ * object oriented C++ API with equivalent functionality is defined in the
+ * file brkiter.h.
+ * <p>
+ * Code snippits illustrating the use of the Break Iterator APIs
+ * are available in the ICU User Guide, 
+ * http://icu.sourceforge.net/userguide/boundaryAnalysis.html
+ * and in the sample program icu/source/samples/break/break.cpp"
+ */
+
+/** The possible types of text boundaries.  @stable ICU 2.0 */
+typedef enum UBreakIteratorType {
+  /** Character breaks  @stable ICU 2.0 */
+  UBRK_CHARACTER = 0,
+  /** Word breaks @stable ICU 2.0 */
+  UBRK_WORD = 1,
+  /** Line breaks @stable ICU 2.0 */
+  UBRK_LINE = 2,
+  /** Sentence breaks @stable ICU 2.0 */
+  UBRK_SENTENCE = 3,
+
+#ifndef U_HIDE_DEPRECATED_API
+  /** 
+   * Title Case breaks 
+   * The iterator created using this type locates title boundaries as described for 
+   * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
+   * please use Word Boundary iterator.
+   *
+   * @deprecated ICU 2.8 Use the word break iterator for titlecasing for Unicode 4 and later.
+   */
+  UBRK_TITLE = 4,
+#endif /* U_HIDE_DEPRECATED_API */
+  UBRK_COUNT = 5
+} UBreakIteratorType;
+
+/** Value indicating all text boundaries have been returned.
+ *  @stable ICU 2.0 
+ */
+#define UBRK_DONE ((int32_t) -1)
+
+
+/**
+ *  Enum constants for the word break tags returned by
+ *  getRuleStatus().  A range of values is defined for each category of
+ *  word, to allow for further subdivisions of a category in future releases.
+ *  Applications should check for tag values falling within the range, rather
+ *  than for single individual values.
+ *  @stable ICU 2.2
+*/
+typedef enum UWordBreak {
+    /** Tag value for "words" that do not fit into any of other categories. 
+     *  Includes spaces and most punctuation. */
+    UBRK_WORD_NONE           = 0,
+    /** Upper bound for tags for uncategorized words. */
+    UBRK_WORD_NONE_LIMIT     = 100,
+    /** Tag value for words that appear to be numbers, lower limit.    */
+    UBRK_WORD_NUMBER         = 100,
+    /** Tag value for words that appear to be numbers, upper limit.    */
+    UBRK_WORD_NUMBER_LIMIT   = 200,
+    /** Tag value for words that contain letters, excluding
+     *  hiragana, katakana or ideographic characters, lower limit.    */
+    UBRK_WORD_LETTER         = 200,
+    /** Tag value for words containing letters, upper limit  */
+    UBRK_WORD_LETTER_LIMIT   = 300,
+    /** Tag value for words containing kana characters, lower limit */
+    UBRK_WORD_KANA           = 300,
+    /** Tag value for words containing kana characters, upper limit */
+    UBRK_WORD_KANA_LIMIT     = 400,
+    /** Tag value for words containing ideographic characters, lower limit */
+    UBRK_WORD_IDEO           = 400,
+    /** Tag value for words containing ideographic characters, upper limit */
+    UBRK_WORD_IDEO_LIMIT     = 500
+} UWordBreak;
+
+/**
+ *  Enum constants for the line break tags returned by getRuleStatus().
+ *  A range of values is defined for each category of
+ *  word, to allow for further subdivisions of a category in future releases.
+ *  Applications should check for tag values falling within the range, rather
+ *  than for single individual values.
+ *  @stable ICU 2.8
+*/
+typedef enum ULineBreakTag {
+    /** Tag value for soft line breaks, positions at which a line break
+      *  is acceptable but not required                */
+    UBRK_LINE_SOFT            = 0,
+    /** Upper bound for soft line breaks.              */
+    UBRK_LINE_SOFT_LIMIT      = 100,
+    /** Tag value for a hard, or mandatory line break  */
+    UBRK_LINE_HARD            = 100,
+    /** Upper bound for hard line breaks.              */
+    UBRK_LINE_HARD_LIMIT      = 200
+} ULineBreakTag;
+
+
+
+/**
+ *  Enum constants for the sentence break tags returned by getRuleStatus().
+ *  A range of values is defined for each category of
+ *  sentence, to allow for further subdivisions of a category in future releases.
+ *  Applications should check for tag values falling within the range, rather
+ *  than for single individual values.
+ *  @stable ICU 2.8
+*/
+typedef enum USentenceBreakTag {
+    /** Tag value for for sentences  ending with a sentence terminator
+      * ('.', '?', '!', etc.) character, possibly followed by a
+      * hard separator (CR, LF, PS, etc.)
+      */
+    UBRK_SENTENCE_TERM       = 0,
+    /** Upper bound for tags for sentences ended by sentence terminators.    */
+    UBRK_SENTENCE_TERM_LIMIT = 100,
+    /** Tag value for for sentences that do not contain an ending
+      * sentence terminator ('.', '?', '!', etc.) character, but 
+      * are ended only by a hard separator (CR, LF, PS, etc.) or end of input.
+      */
+    UBRK_SENTENCE_SEP        = 100,
+    /** Upper bound for tags for sentences ended by a separator.              */
+    UBRK_SENTENCE_SEP_LIMIT  = 200
+    /** Tag value for a hard, or mandatory line break  */
+} USentenceBreakTag;
+
+
+/**
+ * Open a new UBreakIterator for locating text boundaries for a specified locale.
+ * A UBreakIterator may be used for detecting character, line, word,
+ * and sentence breaks in text.
+ * @param type The type of UBreakIterator to open: one of UBRK_CHARACTER, UBRK_WORD,
+ * UBRK_LINE, UBRK_SENTENCE
+ * @param locale The locale specifying the text-breaking conventions.
+ * @param text The text to be iterated over.
+ * @param textLength The number of characters in text, or -1 if null-terminated.
+ * @param status A UErrorCode to receive any errors.
+ * @return A UBreakIterator for the specified locale.
+ * @see ubrk_openRules
+ * @stable ICU 2.0
+ */
+U_STABLE UBreakIterator* U_EXPORT2
+ubrk_open(UBreakIteratorType type,
+      const char *locale,
+      const UChar *text,
+      int32_t textLength,
+      UErrorCode *status);
+
+/**
+ * Open a new UBreakIterator for locating text boundaries using specified breaking rules.
+ * The rule syntax is ... (TBD)
+ * @param rules A set of rules specifying the text breaking conventions.
+ * @param rulesLength The number of characters in rules, or -1 if null-terminated.
+ * @param text The text to be iterated over.  May be null, in which case ubrk_setText() is
+ *        used to specify the text to be iterated.
+ * @param textLength The number of characters in text, or -1 if null-terminated.
+ * @param parseErr   Receives position and context information for any syntax errors
+ *                   detected while parsing the rules.
+ * @param status A UErrorCode to receive any errors.
+ * @return A UBreakIterator for the specified rules.
+ * @see ubrk_open
+ * @stable ICU 2.2
+ */
+U_STABLE UBreakIterator* U_EXPORT2
+ubrk_openRules(const UChar     *rules,
+               int32_t         rulesLength,
+               const UChar     *text,
+               int32_t          textLength,
+               UParseError     *parseErr,
+               UErrorCode      *status);
+
+/**
+ * Thread safe cloning operation
+ * @param bi iterator to be cloned
+ * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated.
+ *  If buffer is not large enough, new memory will be allocated.
+ *  Clients can use the U_BRK_SAFECLONE_BUFFERSIZE. This will probably be enough to avoid memory allocations.
+ * @param pBufferSize pointer to size of allocated space.
+ *  If *pBufferSize == 0, a sufficient size for use in cloning will
+ *  be returned ('pre-flighting')
+ *  If *pBufferSize is not enough for a stack-based safe clone,
+ *  new memory will be allocated.
+ * @param status to indicate whether the operation went on smoothly or there were errors
+ *  An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were necessary.
+ * @return pointer to the new clone
+ * @stable ICU 2.0
+ */
+U_STABLE UBreakIterator * U_EXPORT2
+ubrk_safeClone(
+          const UBreakIterator *bi,
+          void *stackBuffer,
+          int32_t *pBufferSize,
+          UErrorCode *status);
+
+/**
+  * A recommended size (in bytes) for the memory buffer to be passed to ubrk_saveClone().
+  * @stable ICU 2.0
+  */
+#define U_BRK_SAFECLONE_BUFFERSIZE 512
+
+/**
+* Close a UBreakIterator.
+* Once closed, a UBreakIterator may no longer be used.
+* @param bi The break iterator to close.
+ * @stable ICU 2.0
+*/
+U_STABLE void U_EXPORT2
+ubrk_close(UBreakIterator *bi);
+
+/**
+ * Sets an existing iterator to point to a new piece of text
+ * @param bi The iterator to use
+ * @param text The text to be set
+ * @param textLength The length of the text
+ * @param status The error code
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ubrk_setText(UBreakIterator* bi,
+             const UChar*    text,
+             int32_t         textLength,
+             UErrorCode*     status);
+
+
+/**
+ * Sets an existing iterator to point to a new piece of text
+ * @param bi The iterator to use
+ * @param text The text to be set
+ * @param status The error code
+ * @draft ICU 3.4
+ */
+U_DRAFT void U_EXPORT2
+ubrk_setUText(UBreakIterator* bi,
+             UText*          text,
+             UErrorCode*     status);
+
+
+
+/**
+ * Determine the most recently-returned text boundary.
+ *
+ * @param bi The break iterator to use.
+ * @return The character index most recently returned by \ref ubrk_next, \ref ubrk_previous,
+ * \ref ubrk_first, or \ref ubrk_last.
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_current(const UBreakIterator *bi);
+
+/**
+ * Determine the text boundary following the current text boundary.
+ *
+ * @param bi The break iterator to use.
+ * @return The character index of the next text boundary, or UBRK_DONE
+ * if all text boundaries have been returned.
+ * @see ubrk_previous
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_next(UBreakIterator *bi);
+
+/**
+ * Determine the text boundary preceding the current text boundary.
+ *
+ * @param bi The break iterator to use.
+ * @return The character index of the preceding text boundary, or UBRK_DONE
+ * if all text boundaries have been returned.
+ * @see ubrk_next
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_previous(UBreakIterator *bi);
+
+/**
+ * Determine the index of the first character in the text being scanned.
+ * This is not always the same as index 0 of the text.
+ * @param bi The break iterator to use.
+ * @return The character index of the first character in the text being scanned.
+ * @see ubrk_last
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_first(UBreakIterator *bi);
+
+/**
+ * Determine the index immediately <EM>beyond</EM> the last character in the text being
+ * scanned.
+ * This is not the same as the last character.
+ * @param bi The break iterator to use.
+ * @return The character offset immediately <EM>beyond</EM> the last character in the
+ * text being scanned.
+ * @see ubrk_first
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_last(UBreakIterator *bi);
+
+/**
+ * Determine the text boundary preceding the specified offset.
+ * The value returned is always smaller than offset, or UBRK_DONE.
+ * @param bi The break iterator to use.
+ * @param offset The offset to begin scanning.
+ * @return The text boundary preceding offset, or UBRK_DONE.
+ * @see ubrk_following
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_preceding(UBreakIterator *bi,
+           int32_t offset);
+
+/**
+ * Determine the text boundary following the specified offset.
+ * The value returned is always greater than offset, or UBRK_DONE.
+ * @param bi The break iterator to use.
+ * @param offset The offset to begin scanning.
+ * @return The text boundary following offset, or UBRK_DONE.
+ * @see ubrk_preceding
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ubrk_following(UBreakIterator *bi,
+           int32_t offset);
+
+/**
+* Get a locale for which text breaking information is available.
+* A UBreakIterator in a locale returned by this function will perform the correct
+* text breaking for the locale.
+* @param index The index of the desired locale.
+* @return A locale for which number text breaking information is available, or 0 if none.
+* @see ubrk_countAvailable
+* @stable ICU 2.0
+*/
+U_STABLE const char* U_EXPORT2
+ubrk_getAvailable(int32_t index);
+
+/**
+* Determine how many locales have text breaking information available.
+* This function is most useful as determining the loop ending condition for
+* calls to \ref ubrk_getAvailable.
+* @return The number of locales for which text breaking information is available.
+* @see ubrk_getAvailable
+* @stable ICU 2.0
+*/
+U_STABLE int32_t U_EXPORT2
+ubrk_countAvailable(void);
+
+
+/**
+* Returns true if the specfied position is a boundary position.  As a side
+* effect, leaves the iterator pointing to the first boundary position at
+* or after "offset".
+* @param bi The break iterator to use.
+* @param offset the offset to check.
+* @return True if "offset" is a boundary position.
+* @stable ICU 2.0
+*/
+U_STABLE  UBool U_EXPORT2
+ubrk_isBoundary(UBreakIterator *bi, int32_t offset);
+
+/**
+ * Return the status from the break rule that determined the most recently
+ * returned break position.  The values appear in the rule source
+ * within brackets, {123}, for example.  For rules that do not specify a
+ * status, a default value of 0 is returned.
+ * <p>
+ * For word break iterators, the possible values are defined in enum UWordBreak.
+ * @stable ICU 2.2
+ */
+U_STABLE  int32_t U_EXPORT2
+ubrk_getRuleStatus(UBreakIterator *bi);
+
+/**
+ * Get the statuses from the break rules that determined the most recently
+ * returned break position.  The values appear in the rule source
+ * within brackets, {123}, for example.  The default status value for rules
+ * that do not explicitly provide one is zero.
+ * <p>
+ * For word break iterators, the possible values are defined in enum UWordBreak.
+ * @param bi        The break iterator to use
+ * @param fillInVec an array to be filled in with the status values.  
+ * @param capacity  the length of the supplied vector.  A length of zero causes
+ *                  the function to return the number of status values, in the
+ *                  normal way, without attemtping to store any values.
+ * @param status    receives error codes.  
+ * @return          The number of rule status values from rules that determined 
+ *                  the most recent boundary returned by the break iterator.
+ * @stable ICU 3.0
+ */
+U_STABLE  int32_t U_EXPORT2
+ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status);
+
+/**
+ * Return the locale of the break iterator. You can choose between the valid and
+ * the actual locale.
+ * @param bi break iterator
+ * @param type locale type (valid or actual)
+ * @param status error code
+ * @return locale string
+ * @stable ICU 2.8
+ */
+U_STABLE const char* U_EXPORT2
+ubrk_getLocaleByType(const UBreakIterator *bi, ULocDataLocaleType type, UErrorCode* status);
+
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
+#endif

Added: MacRuby/branches/icu/unicode/ucasemap.h
===================================================================
--- MacRuby/branches/icu/unicode/ucasemap.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ucasemap.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,180 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ucasemap.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2005may06
+*   created by: Markus W. Scherer
+*
+*   Case mapping service object and functions using it.
+*/
+
+#ifndef __UCASEMAP_H__
+#define __UCASEMAP_H__
+
+#include "unicode/utypes.h"
+#include "unicode/ustring.h"
+
+/**
+ * \file
+ * \brief C API: Unicode case mapping functions using a UCaseMap service object.
+ *
+ * The service object takes care of memory allocations, data loading, and setup
+ * for the attributes, as usual.
+ *
+ * Currently, the functionality provided here does not overlap with uchar.h
+ * and ustring.h.
+ *
+ * ucasemap_utf8ToLower() and ucasemap_utf8ToUpper() operate directly on
+ * UTF-8 strings.
+ */
+
+/**
+ * UCaseMap is an opaque service object for newer ICU case mapping functions.
+ * Older functions did not use a service object.
+ * @draft ICU 3.4
+ */
+struct UCaseMap;
+typedef struct UCaseMap UCaseMap; /**< C typedef for struct UCaseMap. @draft ICU 3.4 */
+
+/**
+ * Open a UCaseMap service object for a locale and a set of options.
+ * The locale ID and options are preprocessed so that functions using the
+ * service object need not process them in each call.
+ *
+ * @param locale ICU locale ID, used for language-dependent
+ *               upper-/lower-/title-casing according to the Unicode standard.
+ *               Usual semantics: ""=root, NULL=default locale, etc.
+ * @param options Options bit set, used for case folding and string comparisons.
+ *                Same flags as for u_foldCase(), u_strFoldCase(),
+ *                u_strCaseCompare(), etc.
+ *                Use 0 or U_FOLD_CASE_DEFAULT for default behavior.
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                   which must not indicate a failure before the function call.
+ * @return Pointer to a UCaseMap service object, if successful.
+ *
+ * @draft ICU 3.4
+ */
+U_DRAFT UCaseMap * U_EXPORT2
+ucasemap_open(const char *locale, uint32_t options, UErrorCode *pErrorCode);
+
+/**
+ * Close a UCaseMap service object.
+ * @param csm Object to be closed.
+ * @draft ICU 3.4
+ */
+U_DRAFT void U_EXPORT2
+ucasemap_close(UCaseMap *csm);
+
+/**
+ * Get the locale ID that is used for language-dependent case mappings.
+ * @param csm UCaseMap service object.
+ * @return locale ID
+ * @draft ICU 3.4
+ */
+U_DRAFT const char * U_EXPORT2
+ucasemap_getLocale(const UCaseMap *csm);
+
+/**
+ * Get the options bit set that is used for case folding and string comparisons.
+ * @param csm UCaseMap service object.
+ * @return options bit set
+ * @draft ICU 3.4
+ */
+U_DRAFT uint32_t U_EXPORT2
+ucasemap_getOptions(const UCaseMap *csm);
+
+/**
+ * Set the locale ID that is used for language-dependent case mappings.
+ *
+ * @param csm UCaseMap service object.
+ * @param locale Locale ID, see ucasemap_open().
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                   which must not indicate a failure before the function call.
+ *
+ * @see ucasemap_open
+ * @draft ICU 3.4
+ */
+U_DRAFT void U_EXPORT2
+ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode);
+
+/**
+ * Set the options bit set that is used for case folding and string comparisons.
+ *
+ * @param csm UCaseMap service object.
+ * @param options Options bit set, see ucasemap_open().
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                   which must not indicate a failure before the function call.
+ *
+ * @see ucasemap_open
+ * @draft ICU 3.4
+ */
+U_DRAFT void U_EXPORT2
+ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode);
+
+/**
+ * Lowercase the characters in a UTF-8 string.
+ * Casing is locale-dependent and context-sensitive.
+ * The result may be longer or shorter than the original.
+ * The source string and the destination buffer must not overlap.
+ *
+ * @param csm       UCaseMap service object.
+ * @param dest      A buffer for the result string. The result will be NUL-terminated if
+ *                  the buffer is large enough.
+ *                  The contents is undefined in case of failure.
+ * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+ *                  dest may be NULL and the function will only return the length of the result
+ *                  without writing any of the result string.
+ * @param src       The original string
+ * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                  which must not indicate a failure before the function call.
+ * @return The length of the result string, if successful - or in case of a buffer overflow,
+ *         in which case it will be greater than destCapacity.
+ *
+ * @see u_strToLower
+ * @draft ICU 3.4
+ */
+U_DRAFT int32_t U_EXPORT2
+ucasemap_utf8ToLower(const UCaseMap *csm,
+                     char *dest, int32_t destCapacity,
+                     const char *src, int32_t srcLength,
+                     UErrorCode *pErrorCode);
+
+/**
+ * Uppercase the characters in a UTF-8 string.
+ * Casing is locale-dependent and context-sensitive.
+ * The result may be longer or shorter than the original.
+ * The source string and the destination buffer must not overlap.
+ *
+ * @param csm       UCaseMap service object.
+ * @param dest      A buffer for the result string. The result will be NUL-terminated if
+ *                  the buffer is large enough.
+ *                  The contents is undefined in case of failure.
+ * @param destCapacity The size of the buffer (number of bytes). If it is 0, then
+ *                  dest may be NULL and the function will only return the length of the result
+ *                  without writing any of the result string.
+ * @param src       The original string
+ * @param srcLength The length of the original string. If -1, then src must be NUL-terminated.
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                  which must not indicate a failure before the function call.
+ * @return The length of the result string, if successful - or in case of a buffer overflow,
+ *         in which case it will be greater than destCapacity.
+ *
+ * @see u_strToUpper
+ * @draft ICU 3.4
+ */
+U_DRAFT int32_t U_EXPORT2
+ucasemap_utf8ToUpper(const UCaseMap *csm,
+                     char *dest, int32_t destCapacity,
+                     const char *src, int32_t srcLength,
+                     UErrorCode *pErrorCode);
+
+#endif

Added: MacRuby/branches/icu/unicode/ucat.h
===================================================================
--- MacRuby/branches/icu/unicode/ucat.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ucat.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,158 @@
+/*
+**********************************************************************
+* Copyright (c) 2003-2004, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: March 19 2003
+* Since: ICU 2.6
+**********************************************************************
+*/
+#ifndef UCAT_H
+#define UCAT_H
+
+#include "unicode/utypes.h"
+#include "unicode/ures.h"
+
+/**
+ * \file
+ * \brief C API: Message Catalog Wrappers
+ *
+ * This C API provides look-alike functions that deliberately resemble
+ * the POSIX catopen, catclose, and catgets functions.  The underlying
+ * implementation is in terms of ICU resource bundles, rather than
+ * POSIX message catalogs.
+ *
+ * The ICU resource bundles obey standard ICU inheritance policies.
+ * To facilitate this, sets and messages are flattened into one tier.
+ * This is done by creating resource bundle keys of the form
+ * &lt;set_num&gt;%&lt;msg_num&gt; where set_num is the set number and msg_num is
+ * the message number, formatted as decimal strings.
+ *
+ * Example:  Consider a message catalog containing two sets:
+ *
+ * Set 1: Message 4  = "Good morning."
+ *        Message 5  = "Good afternoon."
+ *        Message 7  = "Good evening."
+ *        Message 8  = "Good night."
+ * Set 4: Message 14 = "Please "
+ *        Message 19 = "Thank you."
+ *        Message 20 = "Sincerely,"
+ *
+ * The ICU resource bundle source file would, assuming it is named
+ * "greet.txt", would look like this:
+ *
+ * greet
+ * {
+ *     1%4  { "Good morning." }
+ *     1%5  { "Good afternoon." }
+ *     1%7  { "Good evening." }
+ *     1%8  { "Good night." }
+ * 
+ *     4%14 { "Please " }
+ *     4%19 { "Thank you." }
+ *     4%20 { "Sincerely," }
+ * }
+ *
+ * The catgets function is commonly used in combination with functions
+ * like printf and strftime.  ICU components like message format can
+ * be used instead, although they use a different format syntax.
+ * There is an ICU package, icuio, that provides some of
+ * the POSIX-style formatting API.
+ */
+
+U_CDECL_BEGIN
+
+/**
+ * An ICU message catalog descriptor, analogous to nl_catd.
+ * 
+ * @stable ICU 2.6
+ */
+typedef UResourceBundle* u_nl_catd;
+
+/**
+ * Open and return an ICU message catalog descriptor. The descriptor
+ * may be passed to u_catgets() to retrieve localized strings.
+ *
+ * @param name string containing the full path pointing to the
+ * directory where the resources reside followed by the package name
+ * e.g. "/usr/resource/my_app/resources/guimessages" on a Unix system.
+ * If NULL, ICU default data files will be used.
+ *
+ * Unlike POSIX, environment variables are not interpolated within the
+ * name.
+ *
+ * @param locale the locale for which we want to open the resource. If
+ * NULL, the default ICU locale will be used (see uloc_getDefault). If
+ * strlen(locale) == 0, the root locale will be used.
+ *
+ * @param ec input/output error code. Upon output,
+ * U_USING_FALLBACK_WARNING indicates that a fallback locale was
+ * used. For example, 'de_CH' was requested, but nothing was found
+ * there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that the
+ * default locale data or root locale data was used; neither the
+ * requested locale nor any of its fallback locales were found.
+ *
+ * @return a message catalog descriptor that may be passed to
+ * u_catgets(). If the ec parameter indicates success, then the caller
+ * is responsible for calling u_catclose() to close the message
+ * catalog. If the ec parameter indicates failure, then NULL will be
+ * returned.
+ * 
+ * @stable ICU 2.6
+ */
+U_STABLE u_nl_catd U_EXPORT2
+u_catopen(const char* name, const char* locale, UErrorCode* ec);
+
+/**
+ * Close an ICU message catalog, given its descriptor.
+ *
+ * @param catd a message catalog descriptor to be closed. May be NULL,
+ * in which case no action is taken.
+ * 
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+u_catclose(u_nl_catd catd);
+
+/**
+ * Retrieve a localized string from an ICU message catalog.
+ *
+ * @param catd a message catalog descriptor returned by u_catopen.
+ *
+ * @param set_num the message catalog set number. Sets need not be
+ * numbered consecutively.
+ *
+ * @param msg_num the message catalog message number within the
+ * set. Messages need not be numbered consecutively.
+ *
+ * @param s the default string. This is returned if the string
+ * specified by the set_num and msg_num is not found. It must be
+ * zero-terminated.
+ *
+ * @param len fill-in parameter to receive the length of the result.
+ * May be NULL, in which case it is ignored.
+ *
+ * @param ec input/output error code. May be U_USING_FALLBACK_WARNING
+ * or U_USING_DEFAULT_WARNING. U_MISSING_RESOURCE_ERROR indicates that
+ * the set_num/msg_num tuple does not specify a valid message string
+ * in this catalog.
+ *
+ * @return a pointer to a zero-terminated UChar array which lives in
+ * an internal buffer area, typically a memory mapped/DLL file. The
+ * caller must NOT delete this pointer. If the call is unsuccessful
+ * for any reason, then s is returned.  This includes the situation in
+ * which ec indicates a failing error code upon entry to this
+ * function.
+ * 
+ * @stable ICU 2.6
+ */
+U_STABLE const UChar* U_EXPORT2
+u_catgets(u_nl_catd catd, int32_t set_num, int32_t msg_num,
+          const UChar* s,
+          int32_t* len, UErrorCode* ec);
+
+U_CDECL_END
+
+#endif /*UCAT_H*/
+/*eof*/

Added: MacRuby/branches/icu/unicode/uchar.h
===================================================================
--- MacRuby/branches/icu/unicode/uchar.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uchar.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,3026 @@
+/*
+**********************************************************************
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*
+* File UCHAR.H
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   04/02/97    aliu        Creation.
+*   03/29/99    helena      Updated for C APIs.
+*   4/15/99     Madhu       Updated for C Implementation and Javadoc
+*   5/20/99     Madhu       Added the function u_getVersion()
+*   8/19/1999   srl         Upgraded scripts to Unicode 3.0
+*   8/27/1999   schererm    UCharDirection constants: U_...
+*   11/11/1999  weiv        added u_isalnum(), cleaned comments
+*   01/11/2000  helena      Renamed u_getVersion to u_getUnicodeVersion().
+******************************************************************************
+*/
+
+#ifndef UCHAR_H
+#define UCHAR_H
+
+#include "unicode/utypes.h"
+
+U_CDECL_BEGIN
+
+/*==========================================================================*/
+/* Unicode version number                                                   */
+/*==========================================================================*/
+/**
+ * Unicode version number, default for the current ICU version.
+ * The actual Unicode Character Database (UCD) data is stored in uprops.dat
+ * and may be generated from UCD files from a different Unicode version.
+ * Call u_getUnicodeVersion to get the actual Unicode version of the data.
+ *
+ * @see u_getUnicodeVersion
+ * @stable ICU 2.0
+ */
+#define U_UNICODE_VERSION "5.0"
+
+/**
+ * \file
+ * \brief C API: Unicode Properties
+ *
+ * This C API provides low-level access to the Unicode Character Database.
+ * In addition to raw property values, some convenience functions calculate
+ * derived properties, for example for Java-style programming.
+ *
+ * Unicode assigns each code point (not just assigned character) values for
+ * many properties.
+ * Most of them are simple boolean flags, or constants from a small enumerated list.
+ * For some properties, values are strings or other relatively more complex types.
+ *
+ * For more information see
+ * "About the Unicode Character Database" (http://www.unicode.org/ucd/)
+ * and the ICU User Guide chapter on Properties (http://icu.sourceforge.net/userguide/properties.html).
+ *
+ * Many functions are designed to match java.lang.Character functions.
+ * See the individual function documentation,
+ * and see the JDK 1.4 java.lang.Character documentation
+ * at http://java.sun.com/j2se/1.4/docs/api/java/lang/Character.html
+ *
+ * There are also functions that provide easy migration from C/POSIX functions
+ * like isblank(). Their use is generally discouraged because the C/POSIX
+ * standards do not define their semantics beyond the ASCII range, which means
+ * that different implementations exhibit very different behavior.
+ * Instead, Unicode properties should be used directly.
+ *
+ * There are also only a few, broad C/POSIX character classes, and they tend
+ * to be used for conflicting purposes. For example, the "isalpha()" class
+ * is sometimes used to determine word boundaries, while a more sophisticated
+ * approach would at least distinguish initial letters from continuation
+ * characters (the latter including combining marks).
+ * (In ICU, BreakIterator is the most sophisticated API for word boundaries.)
+ * Another example: There is no "istitle()" class for titlecase characters.
+ *
+ * ICU 3.4 and later provides API access for all twelve C/POSIX character classes.
+ * ICU implements them according to the Standard Recommendations in
+ * Annex C: Compatibility Properties of UTS #18 Unicode Regular Expressions
+ * (http://www.unicode.org/reports/tr18/#Compatibility_Properties).
+ *
+ * API access for C/POSIX character classes is as follows:
+ * - alpha:     u_isUAlphabetic(c) or u_hasBinaryProperty(c, UCHAR_ALPHABETIC)
+ * - lower:     u_isULowercase(c) or u_hasBinaryProperty(c, UCHAR_LOWERCASE)
+ * - upper:     u_isUUppercase(c) or u_hasBinaryProperty(c, UCHAR_UPPERCASE)
+ * - punct:     u_ispunct(c)
+ * - digit:     u_isdigit(c) or u_charType(c)==U_DECIMAL_DIGIT_NUMBER
+ * - xdigit:    u_isxdigit(c) or u_hasBinaryProperty(c, UCHAR_POSIX_XDIGIT)
+ * - alnum:     u_hasBinaryProperty(c, UCHAR_POSIX_ALNUM)
+ * - space:     u_isUWhiteSpace(c) or u_hasBinaryProperty(c, UCHAR_WHITE_SPACE)
+ * - blank:     u_isblank(c) or u_hasBinaryProperty(c, UCHAR_POSIX_BLANK)
+ * - cntrl:     u_charType(c)==U_CONTROL_CHAR
+ * - graph:     u_hasBinaryProperty(c, UCHAR_POSIX_GRAPH)
+ * - print:     u_hasBinaryProperty(c, UCHAR_POSIX_PRINT)
+ *
+ * Note: Some of the u_isxyz() functions in uchar.h predate, and do not match,
+ * the Standard Recommendations in UTS #18. Instead, they match Java
+ * functions according to their API documentation.
+ *
+ * \htmlonly
+ * The C/POSIX character classes are also available in UnicodeSet patterns,
+ * using patterns like [:graph:] or \p{graph}.
+ * \endhtmlonly
+ *
+ * Note: There are several ICU whitespace functions.
+ * Comparison:
+ * - u_isUWhiteSpace=UCHAR_WHITE_SPACE: Unicode White_Space property;
+ *       most of general categories "Z" (separators) + most whitespace ISO controls
+ *       (including no-break spaces, but excluding IS1..IS4 and ZWSP)
+ * - u_isWhitespace: Java isWhitespace; Z + whitespace ISO controls but excluding no-break spaces
+ * - u_isJavaSpaceChar: Java isSpaceChar; just Z (including no-break spaces)
+ * - u_isspace: Z + whitespace ISO controls (including no-break spaces)
+ * - u_isblank: "horizontal spaces" = TAB + Zs - ZWSP
+ */
+
+/**
+ * Constants.
+ */
+
+/** The lowest Unicode code point value. Code points are non-negative. @stable ICU 2.0 */
+#define UCHAR_MIN_VALUE 0
+
+/**
+ * The highest Unicode code point value (scalar value) according to
+ * The Unicode Standard. This is a 21-bit value (20.1 bits, rounded up).
+ * For a single character, UChar32 is a simple type that can hold any code point value.
+ *
+ * @see UChar32
+ * @stable ICU 2.0
+ */
+#define UCHAR_MAX_VALUE 0x10ffff
+
+/**
+ * Get a single-bit bit set (a flag) from a bit number 0..31.
+ * @stable ICU 2.1
+ */
+#define U_MASK(x) ((uint32_t)1<<(x))
+
+/*
+ * !! Note: Several comments in this file are machine-read by the
+ * genpname tool.  These comments describe the correspondence between
+ * icu enum constants and UCD entities.  Do not delete them.  Update
+ * these comments as needed.
+ *
+ * Any comment of the form "/ *[name]* /" (spaces added) is such
+ * a comment.
+ *
+ * The U_JG_* and U_GC_*_MASK constants are matched by their symbolic
+ * name, which must match PropertyValueAliases.txt.
+ */
+
+/**
+ * Selection constants for Unicode properties.
+ * These constants are used in functions like u_hasBinaryProperty to select
+ * one of the Unicode properties.
+ *
+ * The properties APIs are intended to reflect Unicode properties as defined
+ * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR).
+ * For details about the properties see http://www.unicode.org/ucd/ .
+ * For names of Unicode properties see the UCD file PropertyAliases.txt.
+ *
+ * Important: If ICU is built with UCD files from Unicode versions below, e.g., 3.2,
+ * then properties marked with "new in Unicode 3.2" are not or not fully available.
+ * Check u_getUnicodeVersion to be sure.
+ *
+ * @see u_hasBinaryProperty
+ * @see u_getIntPropertyValue
+ * @see u_getUnicodeVersion
+ * @stable ICU 2.1
+ */
+typedef enum UProperty {
+    /*  See note !!.  Comments of the form "Binary property Dash",
+        "Enumerated property Script", "Double property Numeric_Value",
+        and "String property Age" are read by genpname. */
+
+    /*  Note: Place UCHAR_ALPHABETIC before UCHAR_BINARY_START so that
+    debuggers display UCHAR_ALPHABETIC as the symbolic name for 0,
+    rather than UCHAR_BINARY_START.  Likewise for other *_START
+    identifiers. */
+
+    /** Binary property Alphabetic. Same as u_isUAlphabetic, different from u_isalpha.
+        Lu+Ll+Lt+Lm+Lo+Nl+Other_Alphabetic @stable ICU 2.1 */
+    UCHAR_ALPHABETIC=0,
+    /** First constant for binary Unicode properties. @stable ICU 2.1 */
+    UCHAR_BINARY_START=UCHAR_ALPHABETIC,
+    /** Binary property ASCII_Hex_Digit. 0-9 A-F a-f @stable ICU 2.1 */
+    UCHAR_ASCII_HEX_DIGIT=1,
+    /** Binary property Bidi_Control.
+        Format controls which have specific functions
+        in the Bidi Algorithm. @stable ICU 2.1 */
+    UCHAR_BIDI_CONTROL=2,
+    /** Binary property Bidi_Mirrored.
+        Characters that may change display in RTL text.
+        Same as u_isMirrored.
+        See Bidi Algorithm, UTR 9. @stable ICU 2.1 */
+    UCHAR_BIDI_MIRRORED=3,
+    /** Binary property Dash. Variations of dashes. @stable ICU 2.1 */
+    UCHAR_DASH=4,
+    /** Binary property Default_Ignorable_Code_Point (new in Unicode 3.2).
+        Ignorable in most processing.
+        <2060..206F, FFF0..FFFB, E0000..E0FFF>+Other_Default_Ignorable_Code_Point+(Cf+Cc+Cs-White_Space) @stable ICU 2.1 */
+    UCHAR_DEFAULT_IGNORABLE_CODE_POINT=5,
+    /** Binary property Deprecated (new in Unicode 3.2).
+        The usage of deprecated characters is strongly discouraged. @stable ICU 2.1 */
+    UCHAR_DEPRECATED=6,
+    /** Binary property Diacritic. Characters that linguistically modify
+        the meaning of another character to which they apply. @stable ICU 2.1 */
+    UCHAR_DIACRITIC=7,
+    /** Binary property Extender.
+        Extend the value or shape of a preceding alphabetic character,
+        e.g., length and iteration marks. @stable ICU 2.1 */
+    UCHAR_EXTENDER=8,
+    /** Binary property Full_Composition_Exclusion.
+        CompositionExclusions.txt+Singleton Decompositions+
+        Non-Starter Decompositions. @stable ICU 2.1 */
+    UCHAR_FULL_COMPOSITION_EXCLUSION=9,
+    /** Binary property Grapheme_Base (new in Unicode 3.2).
+        For programmatic determination of grapheme cluster boundaries.
+        [0..10FFFF]-Cc-Cf-Cs-Co-Cn-Zl-Zp-Grapheme_Link-Grapheme_Extend-CGJ @stable ICU 2.1 */
+    UCHAR_GRAPHEME_BASE=10,
+    /** Binary property Grapheme_Extend (new in Unicode 3.2).
+        For programmatic determination of grapheme cluster boundaries.
+        Me+Mn+Mc+Other_Grapheme_Extend-Grapheme_Link-CGJ @stable ICU 2.1 */
+    UCHAR_GRAPHEME_EXTEND=11,
+    /** Binary property Grapheme_Link (new in Unicode 3.2).
+        For programmatic determination of grapheme cluster boundaries. @stable ICU 2.1 */
+    UCHAR_GRAPHEME_LINK=12,
+    /** Binary property Hex_Digit.
+        Characters commonly used for hexadecimal numbers. @stable ICU 2.1 */
+    UCHAR_HEX_DIGIT=13,
+    /** Binary property Hyphen. Dashes used to mark connections
+        between pieces of words, plus the Katakana middle dot. @stable ICU 2.1 */
+    UCHAR_HYPHEN=14,
+    /** Binary property ID_Continue.
+        Characters that can continue an identifier.
+        DerivedCoreProperties.txt also says "NOTE: Cf characters should be filtered out."
+        ID_Start+Mn+Mc+Nd+Pc @stable ICU 2.1 */
+    UCHAR_ID_CONTINUE=15,
+    /** Binary property ID_Start.
+        Characters that can start an identifier.
+        Lu+Ll+Lt+Lm+Lo+Nl @stable ICU 2.1 */
+    UCHAR_ID_START=16,
+    /** Binary property Ideographic.
+        CJKV ideographs. @stable ICU 2.1 */
+    UCHAR_IDEOGRAPHIC=17,
+    /** Binary property IDS_Binary_Operator (new in Unicode 3.2).
+        For programmatic determination of
+        Ideographic Description Sequences. @stable ICU 2.1 */
+    UCHAR_IDS_BINARY_OPERATOR=18,
+    /** Binary property IDS_Trinary_Operator (new in Unicode 3.2).
+        For programmatic determination of
+        Ideographic Description Sequences. @stable ICU 2.1 */
+    UCHAR_IDS_TRINARY_OPERATOR=19,
+    /** Binary property Join_Control.
+        Format controls for cursive joining and ligation. @stable ICU 2.1 */
+    UCHAR_JOIN_CONTROL=20,
+    /** Binary property Logical_Order_Exception (new in Unicode 3.2).
+        Characters that do not use logical order and
+        require special handling in most processing. @stable ICU 2.1 */
+    UCHAR_LOGICAL_ORDER_EXCEPTION=21,
+    /** Binary property Lowercase. Same as u_isULowercase, different from u_islower.
+        Ll+Other_Lowercase @stable ICU 2.1 */
+    UCHAR_LOWERCASE=22,
+    /** Binary property Math. Sm+Other_Math @stable ICU 2.1 */
+    UCHAR_MATH=23,
+    /** Binary property Noncharacter_Code_Point.
+        Code points that are explicitly defined as illegal
+        for the encoding of characters. @stable ICU 2.1 */
+    UCHAR_NONCHARACTER_CODE_POINT=24,
+    /** Binary property Quotation_Mark. @stable ICU 2.1 */
+    UCHAR_QUOTATION_MARK=25,
+    /** Binary property Radical (new in Unicode 3.2).
+        For programmatic determination of
+        Ideographic Description Sequences. @stable ICU 2.1 */
+    UCHAR_RADICAL=26,
+    /** Binary property Soft_Dotted (new in Unicode 3.2).
+        Characters with a "soft dot", like i or j.
+        An accent placed on these characters causes
+        the dot to disappear. @stable ICU 2.1 */
+    UCHAR_SOFT_DOTTED=27,
+    /** Binary property Terminal_Punctuation.
+        Punctuation characters that generally mark
+        the end of textual units. @stable ICU 2.1 */
+    UCHAR_TERMINAL_PUNCTUATION=28,
+    /** Binary property Unified_Ideograph (new in Unicode 3.2).
+        For programmatic determination of
+        Ideographic Description Sequences. @stable ICU 2.1 */
+    UCHAR_UNIFIED_IDEOGRAPH=29,
+    /** Binary property Uppercase. Same as u_isUUppercase, different from u_isupper.
+        Lu+Other_Uppercase @stable ICU 2.1 */
+    UCHAR_UPPERCASE=30,
+    /** Binary property White_Space.
+        Same as u_isUWhiteSpace, different from u_isspace and u_isWhitespace.
+        Space characters+TAB+CR+LF-ZWSP-ZWNBSP @stable ICU 2.1 */
+    UCHAR_WHITE_SPACE=31,
+    /** Binary property XID_Continue.
+        ID_Continue modified to allow closure under
+        normalization forms NFKC and NFKD. @stable ICU 2.1 */
+    UCHAR_XID_CONTINUE=32,
+    /** Binary property XID_Start. ID_Start modified to allow
+        closure under normalization forms NFKC and NFKD. @stable ICU 2.1 */
+    UCHAR_XID_START=33,
+    /** Binary property Case_Sensitive. Either the source of a case
+        mapping or _in_ the target of a case mapping. Not the same as
+        the general category Cased_Letter. @stable ICU 2.6 */
+   UCHAR_CASE_SENSITIVE=34,
+    /** Binary property STerm (new in Unicode 4.0.1).
+        Sentence Terminal. Used in UAX #29: Text Boundaries
+        (http://www.unicode.org/reports/tr29/)
+        @stable ICU 3.0 */
+    UCHAR_S_TERM=35,
+    /** Binary property Variation_Selector (new in Unicode 4.0.1).
+        Indicates all those characters that qualify as Variation Selectors.
+        For details on the behavior of these characters,
+        see StandardizedVariants.html and 15.6 Variation Selectors.
+        @stable ICU 3.0 */
+    UCHAR_VARIATION_SELECTOR=36,
+    /** Binary property NFD_Inert.
+        ICU-specific property for characters that are inert under NFD,
+        i.e., they do not interact with adjacent characters.
+        Used for example in normalizing transforms in incremental mode
+        to find the boundary of safely normalizable text despite possible
+        text additions.
+
+        There is one such property per normalization form.
+        These properties are computed as follows - an inert character is:
+        a) unassigned, or ALL of the following:
+        b) of combining class 0.
+        c) not decomposed by this normalization form.
+        AND if NFC or NFKC,
+        d) can never compose with a previous character.
+        e) can never compose with a following character.
+        f) can never change if another character is added.
+           Example: a-breve might satisfy all but f, but if you
+           add an ogonek it changes to a-ogonek + breve
+
+        See also com.ibm.text.UCD.NFSkippable in the ICU4J repository,
+        and icu/source/common/unormimp.h .
+        @stable ICU 3.0 */
+    UCHAR_NFD_INERT=37,
+    /** Binary property NFKD_Inert.
+        ICU-specific property for characters that are inert under NFKD,
+        i.e., they do not interact with adjacent characters.
+        Used for example in normalizing transforms in incremental mode
+        to find the boundary of safely normalizable text despite possible
+        text additions.
+        @see UCHAR_NFD_INERT
+        @stable ICU 3.0 */
+    UCHAR_NFKD_INERT=38,
+    /** Binary property NFC_Inert.
+        ICU-specific property for characters that are inert under NFC,
+        i.e., they do not interact with adjacent characters.
+        Used for example in normalizing transforms in incremental mode
+        to find the boundary of safely normalizable text despite possible
+        text additions.
+        @see UCHAR_NFD_INERT
+        @stable ICU 3.0 */
+    UCHAR_NFC_INERT=39,
+    /** Binary property NFKC_Inert.
+        ICU-specific property for characters that are inert under NFKC,
+        i.e., they do not interact with adjacent characters.
+        Used for example in normalizing transforms in incremental mode
+        to find the boundary of safely normalizable text despite possible
+        text additions.
+        @see UCHAR_NFD_INERT
+        @stable ICU 3.0 */
+    UCHAR_NFKC_INERT=40,
+    /** Binary Property Segment_Starter.
+        ICU-specific property for characters that are starters in terms of
+        Unicode normalization and combining character sequences.
+        They have ccc=0 and do not occur in non-initial position of the
+        canonical decomposition of any character
+        (like " in NFD(a-umlaut) and a Jamo T in an NFD(Hangul LVT)).
+        ICU uses this property for segmenting a string for generating a set of
+        canonically equivalent strings, e.g. for canonical closure while
+        processing collation tailoring rules.
+        @stable ICU 3.0 */
+    UCHAR_SEGMENT_STARTER=41,
+#ifndef U_HIDE_DRAFT_API
+    /** Binary property Pattern_Syntax (new in Unicode 4.1).
+        See UAX #31 Identifier and Pattern Syntax
+        (http://www.unicode.org/reports/tr31/)
+        @draft ICU 3.4 */
+    UCHAR_PATTERN_SYNTAX=42,
+    /** Binary property Pattern_White_Space (new in Unicode 4.1).
+        See UAX #31 Identifier and Pattern Syntax
+        (http://www.unicode.org/reports/tr31/)
+        @draft ICU 3.4 */
+    UCHAR_PATTERN_WHITE_SPACE=43,
+    /** Binary property alnum (a C/POSIX character class).
+        Implemented according to the UTS #18 Annex C Standard Recommendation.
+        See the uchar.h file documentation.
+        @draft ICU 3.4 */
+    UCHAR_POSIX_ALNUM=44,
+    /** Binary property blank (a C/POSIX character class).
+        Implemented according to the UTS #18 Annex C Standard Recommendation.
+        See the uchar.h file documentation.
+        @draft ICU 3.4 */
+    UCHAR_POSIX_BLANK=45,
+    /** Binary property graph (a C/POSIX character class).
+        Implemented according to the UTS #18 Annex C Standard Recommendation.
+        See the uchar.h file documentation.
+        @draft ICU 3.4 */
+    UCHAR_POSIX_GRAPH=46,
+    /** Binary property print (a C/POSIX character class).
+        Implemented according to the UTS #18 Annex C Standard Recommendation.
+        See the uchar.h file documentation.
+        @draft ICU 3.4 */
+    UCHAR_POSIX_PRINT=47,
+    /** Binary property xdigit (a C/POSIX character class).
+        Implemented according to the UTS #18 Annex C Standard Recommendation.
+        See the uchar.h file documentation.
+        @draft ICU 3.4 */
+    UCHAR_POSIX_XDIGIT=48,
+#endif /* U_HIDE_DRAFT_API */
+    /** One more than the last constant for binary Unicode properties. @stable ICU 2.1 */
+    UCHAR_BINARY_LIMIT=49,
+
+    /** Enumerated property Bidi_Class.
+        Same as u_charDirection, returns UCharDirection values. @stable ICU 2.2 */
+    UCHAR_BIDI_CLASS=0x1000,
+    /** First constant for enumerated/integer Unicode properties. @stable ICU 2.2 */
+    UCHAR_INT_START=UCHAR_BIDI_CLASS,
+    /** Enumerated property Block.
+        Same as ublock_getCode, returns UBlockCode values. @stable ICU 2.2 */
+    UCHAR_BLOCK=0x1001,
+    /** Enumerated property Canonical_Combining_Class.
+        Same as u_getCombiningClass, returns 8-bit numeric values. @stable ICU 2.2 */
+    UCHAR_CANONICAL_COMBINING_CLASS=0x1002,
+    /** Enumerated property Decomposition_Type.
+        Returns UDecompositionType values. @stable ICU 2.2 */
+    UCHAR_DECOMPOSITION_TYPE=0x1003,
+    /** Enumerated property East_Asian_Width.
+        See http://www.unicode.org/reports/tr11/
+        Returns UEastAsianWidth values. @stable ICU 2.2 */
+    UCHAR_EAST_ASIAN_WIDTH=0x1004,
+    /** Enumerated property General_Category.
+        Same as u_charType, returns UCharCategory values. @stable ICU 2.2 */
+    UCHAR_GENERAL_CATEGORY=0x1005,
+    /** Enumerated property Joining_Group.
+        Returns UJoiningGroup values. @stable ICU 2.2 */
+    UCHAR_JOINING_GROUP=0x1006,
+    /** Enumerated property Joining_Type.
+        Returns UJoiningType values. @stable ICU 2.2 */
+    UCHAR_JOINING_TYPE=0x1007,
+    /** Enumerated property Line_Break.
+        Returns ULineBreak values. @stable ICU 2.2 */
+    UCHAR_LINE_BREAK=0x1008,
+    /** Enumerated property Numeric_Type.
+        Returns UNumericType values. @stable ICU 2.2 */
+    UCHAR_NUMERIC_TYPE=0x1009,
+    /** Enumerated property Script.
+        Same as uscript_getScript, returns UScriptCode values. @stable ICU 2.2 */
+    UCHAR_SCRIPT=0x100A,
+    /** Enumerated property Hangul_Syllable_Type, new in Unicode 4.
+        Returns UHangulSyllableType values. @stable ICU 2.6 */
+    UCHAR_HANGUL_SYLLABLE_TYPE=0x100B,
+    /** Enumerated property NFD_Quick_Check.
+        Returns UNormalizationCheckResult values. @stable ICU 3.0 */
+    UCHAR_NFD_QUICK_CHECK=0x100C,
+    /** Enumerated property NFKD_Quick_Check.
+        Returns UNormalizationCheckResult values. @stable ICU 3.0 */
+    UCHAR_NFKD_QUICK_CHECK=0x100D,
+    /** Enumerated property NFC_Quick_Check.
+        Returns UNormalizationCheckResult values. @stable ICU 3.0 */
+    UCHAR_NFC_QUICK_CHECK=0x100E,
+    /** Enumerated property NFKC_Quick_Check.
+        Returns UNormalizationCheckResult values. @stable ICU 3.0 */
+    UCHAR_NFKC_QUICK_CHECK=0x100F,
+    /** Enumerated property Lead_Canonical_Combining_Class.
+        ICU-specific property for the ccc of the first code point
+        of the decomposition, or lccc(c)=ccc(NFD(c)[0]).
+        Useful for checking for canonically ordered text;
+        see UNORM_FCD and http://www.unicode.org/notes/tn5/#FCD .
+        Returns 8-bit numeric values like UCHAR_CANONICAL_COMBINING_CLASS. @stable ICU 3.0 */
+    UCHAR_LEAD_CANONICAL_COMBINING_CLASS=0x1010,
+    /** Enumerated property Trail_Canonical_Combining_Class.
+        ICU-specific property for the ccc of the last code point
+        of the decomposition, or tccc(c)=ccc(NFD(c)[last]).
+        Useful for checking for canonically ordered text;
+        see UNORM_FCD and http://www.unicode.org/notes/tn5/#FCD .
+        Returns 8-bit numeric values like UCHAR_CANONICAL_COMBINING_CLASS. @stable ICU 3.0 */
+    UCHAR_TRAIL_CANONICAL_COMBINING_CLASS=0x1011,
+#ifndef U_HIDE_DRAFT_API
+    /** Enumerated property Grapheme_Cluster_Break (new in Unicode 4.1).
+        Used in UAX #29: Text Boundaries
+        (http://www.unicode.org/reports/tr29/)
+        Returns UGraphemeClusterBreak values. @draft ICU 3.4 */
+    UCHAR_GRAPHEME_CLUSTER_BREAK=0x1012,
+    /** Enumerated property Sentence_Break (new in Unicode 4.1).
+        Used in UAX #29: Text Boundaries
+        (http://www.unicode.org/reports/tr29/)
+        Returns USentenceBreak values. @draft ICU 3.4 */
+    UCHAR_SENTENCE_BREAK=0x1013,
+    /** Enumerated property Word_Break (new in Unicode 4.1).
+        Used in UAX #29: Text Boundaries
+        (http://www.unicode.org/reports/tr29/)
+        Returns UWordBreakValues values. @draft ICU 3.4 */
+    UCHAR_WORD_BREAK=0x1014,
+#endif /*U_HIDE_DRAFT_API*/
+    /** One more than the last constant for enumerated/integer Unicode properties. @stable ICU 2.2 */
+    UCHAR_INT_LIMIT=0x1015,
+
+    /** Bitmask property General_Category_Mask.
+        This is the General_Category property returned as a bit mask.
+        When used in u_getIntPropertyValue(c), same as U_MASK(u_charType(c)),
+        returns bit masks for UCharCategory values where exactly one bit is set.
+        When used with u_getPropertyValueName() and u_getPropertyValueEnum(),
+        a multi-bit mask is used for sets of categories like "Letters".
+        Mask values should be cast to uint32_t.
+        @stable ICU 2.4 */
+    UCHAR_GENERAL_CATEGORY_MASK=0x2000,
+    /** First constant for bit-mask Unicode properties. @stable ICU 2.4 */
+    UCHAR_MASK_START=UCHAR_GENERAL_CATEGORY_MASK,
+    /** One more than the last constant for bit-mask Unicode properties. @stable ICU 2.4 */
+    UCHAR_MASK_LIMIT=0x2001,
+
+    /** Double property Numeric_Value.
+        Corresponds to u_getNumericValue. @stable ICU 2.4 */
+    UCHAR_NUMERIC_VALUE=0x3000,
+    /** First constant for double Unicode properties. @stable ICU 2.4 */
+    UCHAR_DOUBLE_START=UCHAR_NUMERIC_VALUE,
+    /** One more than the last constant for double Unicode properties. @stable ICU 2.4 */
+    UCHAR_DOUBLE_LIMIT=0x3001,
+
+    /** String property Age.
+        Corresponds to u_charAge. @stable ICU 2.4 */
+    UCHAR_AGE=0x4000,
+    /** First constant for string Unicode properties. @stable ICU 2.4 */
+    UCHAR_STRING_START=UCHAR_AGE,
+    /** String property Bidi_Mirroring_Glyph.
+        Corresponds to u_charMirror. @stable ICU 2.4 */
+    UCHAR_BIDI_MIRRORING_GLYPH=0x4001,
+    /** String property Case_Folding.
+        Corresponds to u_strFoldCase in ustring.h. @stable ICU 2.4 */
+    UCHAR_CASE_FOLDING=0x4002,
+    /** String property ISO_Comment.
+        Corresponds to u_getISOComment. @stable ICU 2.4 */
+    UCHAR_ISO_COMMENT=0x4003,
+    /** String property Lowercase_Mapping.
+        Corresponds to u_strToLower in ustring.h. @stable ICU 2.4 */
+    UCHAR_LOWERCASE_MAPPING=0x4004,
+    /** String property Name.
+        Corresponds to u_charName. @stable ICU 2.4 */
+    UCHAR_NAME=0x4005,
+    /** String property Simple_Case_Folding.
+        Corresponds to u_foldCase. @stable ICU 2.4 */
+    UCHAR_SIMPLE_CASE_FOLDING=0x4006,
+    /** String property Simple_Lowercase_Mapping.
+        Corresponds to u_tolower. @stable ICU 2.4 */
+    UCHAR_SIMPLE_LOWERCASE_MAPPING=0x4007,
+    /** String property Simple_Titlecase_Mapping.
+        Corresponds to u_totitle. @stable ICU 2.4 */
+    UCHAR_SIMPLE_TITLECASE_MAPPING=0x4008,
+    /** String property Simple_Uppercase_Mapping.
+        Corresponds to u_toupper. @stable ICU 2.4 */
+    UCHAR_SIMPLE_UPPERCASE_MAPPING=0x4009,
+    /** String property Titlecase_Mapping.
+        Corresponds to u_strToTitle in ustring.h. @stable ICU 2.4 */
+    UCHAR_TITLECASE_MAPPING=0x400A,
+    /** String property Unicode_1_Name.
+        Corresponds to u_charName. @stable ICU 2.4 */
+    UCHAR_UNICODE_1_NAME=0x400B,
+    /** String property Uppercase_Mapping.
+        Corresponds to u_strToUpper in ustring.h. @stable ICU 2.4 */
+    UCHAR_UPPERCASE_MAPPING=0x400C,
+    /** One more than the last constant for string Unicode properties. @stable ICU 2.4 */
+    UCHAR_STRING_LIMIT=0x400D,
+
+    /** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */
+    UCHAR_INVALID_CODE = -1
+} UProperty;
+
+/**
+ * Data for enumerated Unicode general category types.
+ * See http://www.unicode.org/Public/UNIDATA/UnicodeData.html .
+ * @stable ICU 2.0
+ */
+typedef enum UCharCategory
+{
+    /** See note !!.  Comments of the form "Cn" are read by genpname. */
+
+    /** Non-category for unassigned and non-character code points. @stable ICU 2.0 */
+    U_UNASSIGNED              = 0,
+    /** Cn "Other, Not Assigned (no characters in [UnicodeData.txt] have this property)" (same as U_UNASSIGNED!) @stable ICU 2.0 */
+    U_GENERAL_OTHER_TYPES     = 0,
+    /** Lu @stable ICU 2.0 */
+    U_UPPERCASE_LETTER        = 1,
+    /** Ll @stable ICU 2.0 */
+    U_LOWERCASE_LETTER        = 2,
+    /** Lt @stable ICU 2.0 */
+    U_TITLECASE_LETTER        = 3,
+    /** Lm @stable ICU 2.0 */
+    U_MODIFIER_LETTER         = 4,
+    /** Lo @stable ICU 2.0 */
+    U_OTHER_LETTER            = 5,
+    /** Mn @stable ICU 2.0 */
+    U_NON_SPACING_MARK        = 6,
+    /** Me @stable ICU 2.0 */
+    U_ENCLOSING_MARK          = 7,
+    /** Mc @stable ICU 2.0 */
+    U_COMBINING_SPACING_MARK  = 8,
+    /** Nd @stable ICU 2.0 */
+    U_DECIMAL_DIGIT_NUMBER    = 9,
+    /** Nl @stable ICU 2.0 */
+    U_LETTER_NUMBER           = 10,
+    /** No @stable ICU 2.0 */
+    U_OTHER_NUMBER            = 11,
+    /** Zs @stable ICU 2.0 */
+    U_SPACE_SEPARATOR         = 12,
+    /** Zl @stable ICU 2.0 */
+    U_LINE_SEPARATOR          = 13,
+    /** Zp @stable ICU 2.0 */
+    U_PARAGRAPH_SEPARATOR     = 14,
+    /** Cc @stable ICU 2.0 */
+    U_CONTROL_CHAR            = 15,
+    /** Cf @stable ICU 2.0 */
+    U_FORMAT_CHAR             = 16,
+    /** Co @stable ICU 2.0 */
+    U_PRIVATE_USE_CHAR        = 17,
+    /** Cs @stable ICU 2.0 */
+    U_SURROGATE               = 18,
+    /** Pd @stable ICU 2.0 */
+    U_DASH_PUNCTUATION        = 19,
+    /** Ps @stable ICU 2.0 */
+    U_START_PUNCTUATION       = 20,
+    /** Pe @stable ICU 2.0 */
+    U_END_PUNCTUATION         = 21,
+    /** Pc @stable ICU 2.0 */
+    U_CONNECTOR_PUNCTUATION   = 22,
+    /** Po @stable ICU 2.0 */
+    U_OTHER_PUNCTUATION       = 23,
+    /** Sm @stable ICU 2.0 */
+    U_MATH_SYMBOL             = 24,
+    /** Sc @stable ICU 2.0 */
+    U_CURRENCY_SYMBOL         = 25,
+    /** Sk @stable ICU 2.0 */
+    U_MODIFIER_SYMBOL         = 26,
+    /** So @stable ICU 2.0 */
+    U_OTHER_SYMBOL            = 27,
+    /** Pi @stable ICU 2.0 */
+    U_INITIAL_PUNCTUATION     = 28,
+    /** Pf @stable ICU 2.0 */
+    U_FINAL_PUNCTUATION       = 29,
+    /** One higher than the last enum UCharCategory constant. @stable ICU 2.0 */
+    U_CHAR_CATEGORY_COUNT
+} UCharCategory;
+
+/**
+ * U_GC_XX_MASK constants are bit flags corresponding to Unicode
+ * general category values.
+ * For each category, the nth bit is set if the numeric value of the
+ * corresponding UCharCategory constant is n.
+ *
+ * There are also some U_GC_Y_MASK constants for groups of general categories
+ * like L for all letter categories.
+ *
+ * @see u_charType
+ * @see U_GET_GC_MASK
+ * @see UCharCategory
+ * @stable ICU 2.1
+ */
+#define U_GC_CN_MASK    U_MASK(U_GENERAL_OTHER_TYPES)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_LU_MASK    U_MASK(U_UPPERCASE_LETTER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_LL_MASK    U_MASK(U_LOWERCASE_LETTER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_LT_MASK    U_MASK(U_TITLECASE_LETTER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_LM_MASK    U_MASK(U_MODIFIER_LETTER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_LO_MASK    U_MASK(U_OTHER_LETTER)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_MN_MASK    U_MASK(U_NON_SPACING_MARK)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_ME_MASK    U_MASK(U_ENCLOSING_MARK)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_MC_MASK    U_MASK(U_COMBINING_SPACING_MARK)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_ND_MASK    U_MASK(U_DECIMAL_DIGIT_NUMBER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_NL_MASK    U_MASK(U_LETTER_NUMBER)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_NO_MASK    U_MASK(U_OTHER_NUMBER)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_ZS_MASK    U_MASK(U_SPACE_SEPARATOR)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_ZL_MASK    U_MASK(U_LINE_SEPARATOR)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_ZP_MASK    U_MASK(U_PARAGRAPH_SEPARATOR)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_CC_MASK    U_MASK(U_CONTROL_CHAR)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_CF_MASK    U_MASK(U_FORMAT_CHAR)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_CO_MASK    U_MASK(U_PRIVATE_USE_CHAR)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_CS_MASK    U_MASK(U_SURROGATE)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PD_MASK    U_MASK(U_DASH_PUNCTUATION)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PS_MASK    U_MASK(U_START_PUNCTUATION)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PE_MASK    U_MASK(U_END_PUNCTUATION)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PC_MASK    U_MASK(U_CONNECTOR_PUNCTUATION)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PO_MASK    U_MASK(U_OTHER_PUNCTUATION)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_SM_MASK    U_MASK(U_MATH_SYMBOL)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_SC_MASK    U_MASK(U_CURRENCY_SYMBOL)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_SK_MASK    U_MASK(U_MODIFIER_SYMBOL)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_SO_MASK    U_MASK(U_OTHER_SYMBOL)
+
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PI_MASK    U_MASK(U_INITIAL_PUNCTUATION)
+/** Mask constant for a UCharCategory. @stable ICU 2.1 */
+#define U_GC_PF_MASK    U_MASK(U_FINAL_PUNCTUATION)
+
+
+/** Mask constant for multiple UCharCategory bits (L Letters). @stable ICU 2.1 */
+#define U_GC_L_MASK \
+            (U_GC_LU_MASK|U_GC_LL_MASK|U_GC_LT_MASK|U_GC_LM_MASK|U_GC_LO_MASK)
+
+/** Mask constant for multiple UCharCategory bits (LC Cased Letters). @stable ICU 2.1 */
+#define U_GC_LC_MASK \
+            (U_GC_LU_MASK|U_GC_LL_MASK|U_GC_LT_MASK)
+
+/** Mask constant for multiple UCharCategory bits (M Marks). @stable ICU 2.1 */
+#define U_GC_M_MASK (U_GC_MN_MASK|U_GC_ME_MASK|U_GC_MC_MASK)
+
+/** Mask constant for multiple UCharCategory bits (N Numbers). @stable ICU 2.1 */
+#define U_GC_N_MASK (U_GC_ND_MASK|U_GC_NL_MASK|U_GC_NO_MASK)
+
+/** Mask constant for multiple UCharCategory bits (Z Separators). @stable ICU 2.1 */
+#define U_GC_Z_MASK (U_GC_ZS_MASK|U_GC_ZL_MASK|U_GC_ZP_MASK)
+
+/** Mask constant for multiple UCharCategory bits (C Others). @stable ICU 2.1 */
+#define U_GC_C_MASK \
+            (U_GC_CN_MASK|U_GC_CC_MASK|U_GC_CF_MASK|U_GC_CO_MASK|U_GC_CS_MASK)
+
+/** Mask constant for multiple UCharCategory bits (P Punctuation). @stable ICU 2.1 */
+#define U_GC_P_MASK \
+            (U_GC_PD_MASK|U_GC_PS_MASK|U_GC_PE_MASK|U_GC_PC_MASK|U_GC_PO_MASK| \
+             U_GC_PI_MASK|U_GC_PF_MASK)
+
+/** Mask constant for multiple UCharCategory bits (S Symbols). @stable ICU 2.1 */
+#define U_GC_S_MASK (U_GC_SM_MASK|U_GC_SC_MASK|U_GC_SK_MASK|U_GC_SO_MASK)
+
+/**
+ * This specifies the language directional property of a character set.
+ * @stable ICU 2.0
+ */
+typedef enum UCharDirection {
+    /** See note !!.  Comments of the form "EN" are read by genpname. */
+
+    /** L @stable ICU 2.0 */
+    U_LEFT_TO_RIGHT               = 0,
+    /** R @stable ICU 2.0 */
+    U_RIGHT_TO_LEFT               = 1,
+    /** EN @stable ICU 2.0 */
+    U_EUROPEAN_NUMBER             = 2,
+    /** ES @stable ICU 2.0 */
+    U_EUROPEAN_NUMBER_SEPARATOR   = 3,
+    /** ET @stable ICU 2.0 */
+    U_EUROPEAN_NUMBER_TERMINATOR  = 4,
+    /** AN @stable ICU 2.0 */
+    U_ARABIC_NUMBER               = 5,
+    /** CS @stable ICU 2.0 */
+    U_COMMON_NUMBER_SEPARATOR     = 6,
+    /** B @stable ICU 2.0 */
+    U_BLOCK_SEPARATOR             = 7,
+    /** S @stable ICU 2.0 */
+    U_SEGMENT_SEPARATOR           = 8,
+    /** WS @stable ICU 2.0 */
+    U_WHITE_SPACE_NEUTRAL         = 9,
+    /** ON @stable ICU 2.0 */
+    U_OTHER_NEUTRAL               = 10,
+    /** LRE @stable ICU 2.0 */
+    U_LEFT_TO_RIGHT_EMBEDDING     = 11,
+    /** LRO @stable ICU 2.0 */
+    U_LEFT_TO_RIGHT_OVERRIDE      = 12,
+    /** AL @stable ICU 2.0 */
+    U_RIGHT_TO_LEFT_ARABIC        = 13,
+    /** RLE @stable ICU 2.0 */
+    U_RIGHT_TO_LEFT_EMBEDDING     = 14,
+    /** RLO @stable ICU 2.0 */
+    U_RIGHT_TO_LEFT_OVERRIDE      = 15,
+    /** PDF @stable ICU 2.0 */
+    U_POP_DIRECTIONAL_FORMAT      = 16,
+    /** NSM @stable ICU 2.0 */
+    U_DIR_NON_SPACING_MARK        = 17,
+    /** BN @stable ICU 2.0 */
+    U_BOUNDARY_NEUTRAL            = 18,
+    /** @stable ICU 2.0 */
+    U_CHAR_DIRECTION_COUNT
+} UCharDirection;
+
+/**
+ * Constants for Unicode blocks, see the Unicode Data file Blocks.txt
+ * @stable ICU 2.0
+ */
+enum UBlockCode {
+
+    /** New No_Block value in Unicode 4. @stable ICU 2.6 */
+    UBLOCK_NO_BLOCK = 0, /*[none]*/ /* Special range indicating No_Block */
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BASIC_LATIN = 1, /*[0000]*/ /*See note !!*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LATIN_1_SUPPLEMENT=2, /*[0080]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LATIN_EXTENDED_A =3, /*[0100]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LATIN_EXTENDED_B =4, /*[0180]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_IPA_EXTENSIONS =5, /*[0250]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SPACING_MODIFIER_LETTERS =6, /*[02B0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_COMBINING_DIACRITICAL_MARKS =7, /*[0300]*/
+
+    /**
+     * Unicode 3.2 renames this block to "Greek and Coptic".
+     * @stable ICU 2.0
+     */
+    UBLOCK_GREEK =8, /*[0370]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CYRILLIC =9, /*[0400]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ARMENIAN =10, /*[0530]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HEBREW =11, /*[0590]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ARABIC =12, /*[0600]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SYRIAC =13, /*[0700]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_THAANA =14, /*[0780]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_DEVANAGARI =15, /*[0900]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BENGALI =16, /*[0980]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GURMUKHI =17, /*[0A00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GUJARATI =18, /*[0A80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ORIYA =19, /*[0B00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_TAMIL =20, /*[0B80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_TELUGU =21, /*[0C00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_KANNADA =22, /*[0C80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MALAYALAM =23, /*[0D00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SINHALA =24, /*[0D80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_THAI =25, /*[0E00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LAO =26, /*[0E80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_TIBETAN =27, /*[0F00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MYANMAR =28, /*[1000]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GEORGIAN =29, /*[10A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HANGUL_JAMO =30, /*[1100]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ETHIOPIC =31, /*[1200]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CHEROKEE =32, /*[13A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS =33, /*[1400]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_OGHAM =34, /*[1680]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_RUNIC =35, /*[16A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_KHMER =36, /*[1780]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MONGOLIAN =37, /*[1800]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LATIN_EXTENDED_ADDITIONAL =38, /*[1E00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GREEK_EXTENDED =39, /*[1F00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GENERAL_PUNCTUATION =40, /*[2000]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SUPERSCRIPTS_AND_SUBSCRIPTS =41, /*[2070]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CURRENCY_SYMBOLS =42, /*[20A0]*/
+
+    /**
+     * Unicode 3.2 renames this block to "Combining Diacritical Marks for Symbols".
+     * @stable ICU 2.0
+     */
+    UBLOCK_COMBINING_MARKS_FOR_SYMBOLS =43, /*[20D0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LETTERLIKE_SYMBOLS =44, /*[2100]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_NUMBER_FORMS =45, /*[2150]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ARROWS =46, /*[2190]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MATHEMATICAL_OPERATORS =47, /*[2200]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MISCELLANEOUS_TECHNICAL =48, /*[2300]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CONTROL_PICTURES =49, /*[2400]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_OPTICAL_CHARACTER_RECOGNITION =50, /*[2440]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ENCLOSED_ALPHANUMERICS =51, /*[2460]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BOX_DRAWING =52, /*[2500]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BLOCK_ELEMENTS =53, /*[2580]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_GEOMETRIC_SHAPES =54, /*[25A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_MISCELLANEOUS_SYMBOLS =55, /*[2600]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_DINGBATS =56, /*[2700]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BRAILLE_PATTERNS =57, /*[2800]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_RADICALS_SUPPLEMENT =58, /*[2E80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_KANGXI_RADICALS =59, /*[2F00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS =60, /*[2FF0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION =61, /*[3000]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HIRAGANA =62, /*[3040]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_KATAKANA =63, /*[30A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BOPOMOFO =64, /*[3100]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HANGUL_COMPATIBILITY_JAMO =65, /*[3130]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_KANBUN =66, /*[3190]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_BOPOMOFO_EXTENDED =67, /*[31A0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS =68, /*[3200]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_COMPATIBILITY =69, /*[3300]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A =70, /*[3400]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_UNIFIED_IDEOGRAPHS =71, /*[4E00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_YI_SYLLABLES =72, /*[A000]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_YI_RADICALS =73, /*[A490]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HANGUL_SYLLABLES =74, /*[AC00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HIGH_SURROGATES =75, /*[D800]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HIGH_PRIVATE_USE_SURROGATES =76, /*[DB80]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_LOW_SURROGATES =77, /*[DC00]*/
+
+    /**
+     * Same as UBLOCK_PRIVATE_USE_AREA.
+     * Until Unicode 3.1.1, the corresponding block name was "Private Use",
+     * and multiple code point ranges had this block.
+     * Unicode 3.2 renames the block for the BMP PUA to "Private Use Area" and
+     * adds separate blocks for the supplementary PUAs.
+     *
+     * @stable ICU 2.0
+     */
+    UBLOCK_PRIVATE_USE = 78,
+    /**
+     * Same as UBLOCK_PRIVATE_USE.
+     * Until Unicode 3.1.1, the corresponding block name was "Private Use",
+     * and multiple code point ranges had this block.
+     * Unicode 3.2 renames the block for the BMP PUA to "Private Use Area" and
+     * adds separate blocks for the supplementary PUAs.
+     *
+     * @stable ICU 2.0
+     */
+    UBLOCK_PRIVATE_USE_AREA =UBLOCK_PRIVATE_USE, /*[E000]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS =79, /*[F900]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ALPHABETIC_PRESENTATION_FORMS =80, /*[FB00]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ARABIC_PRESENTATION_FORMS_A =81, /*[FB50]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_COMBINING_HALF_MARKS =82, /*[FE20]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_COMPATIBILITY_FORMS =83, /*[FE30]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SMALL_FORM_VARIANTS =84, /*[FE50]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_ARABIC_PRESENTATION_FORMS_B =85, /*[FE70]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_SPECIALS =86, /*[FFF0]*/
+
+    /** @stable ICU 2.0 */
+    UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS =87, /*[FF00]*/
+
+    /* New blocks in Unicode 3.1 */
+
+    /** @stable ICU 2.0 */
+    UBLOCK_OLD_ITALIC = 88  , /*[10300]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_GOTHIC = 89 , /*[10330]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_DESERET = 90 , /*[10400]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_BYZANTINE_MUSICAL_SYMBOLS = 91 , /*[1D000]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_MUSICAL_SYMBOLS = 92 , /*[1D100]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS = 93  , /*[1D400]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B  = 94 , /*[20000]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = 95 , /*[2F800]*/
+    /** @stable ICU 2.0 */
+    UBLOCK_TAGS = 96, /*[E0000]*/
+
+    /* New blocks in Unicode 3.2 */
+
+    /**
+     * Unicode 4.0.1 renames the "Cyrillic Supplementary" block to "Cyrillic Supplement".
+     * @stable ICU 2.2
+     */
+    UBLOCK_CYRILLIC_SUPPLEMENTARY = 97, 
+    /** @stable ICU 3.0  */
+    UBLOCK_CYRILLIC_SUPPLEMENT = UBLOCK_CYRILLIC_SUPPLEMENTARY, /*[0500]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_TAGALOG = 98, /*[1700]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_HANUNOO = 99, /*[1720]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_BUHID = 100, /*[1740]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_TAGBANWA = 101, /*[1760]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = 102, /*[27C0]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_SUPPLEMENTAL_ARROWS_A = 103, /*[27F0]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_SUPPLEMENTAL_ARROWS_B = 104, /*[2900]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = 105, /*[2980]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS = 106, /*[2A00]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_KATAKANA_PHONETIC_EXTENSIONS = 107, /*[31F0]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_VARIATION_SELECTORS = 108, /*[FE00]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_A = 109, /*[F0000]*/
+    /** @stable ICU 2.2 */
+    UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_B = 110, /*[100000]*/
+
+    /* New blocks in Unicode 4 */
+
+    /** @stable ICU 2.6 */
+    UBLOCK_LIMBU = 111, /*[1900]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_TAI_LE = 112, /*[1950]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_KHMER_SYMBOLS = 113, /*[19E0]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_PHONETIC_EXTENSIONS = 114, /*[1D00]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS = 115, /*[2B00]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_YIJING_HEXAGRAM_SYMBOLS = 116, /*[4DC0]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_LINEAR_B_SYLLABARY = 117, /*[10000]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_LINEAR_B_IDEOGRAMS = 118, /*[10080]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_AEGEAN_NUMBERS = 119, /*[10100]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_UGARITIC = 120, /*[10380]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_SHAVIAN = 121, /*[10450]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_OSMANYA = 122, /*[10480]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_CYPRIOT_SYLLABARY = 123, /*[10800]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_TAI_XUAN_JING_SYMBOLS = 124, /*[1D300]*/
+    /** @stable ICU 2.6 */
+    UBLOCK_VARIATION_SELECTORS_SUPPLEMENT = 125, /*[E0100]*/
+
+#ifndef U_HIDE_DRAFT_API
+    /* New blocks in Unicode 4.1 */
+
+    /** @draft ICU 3.4 */
+    UBLOCK_ANCIENT_GREEK_MUSICAL_NOTATION = 126, /*[1D200]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_ANCIENT_GREEK_NUMBERS = 127, /*[10140]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_ARABIC_SUPPLEMENT = 128, /*[0750]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_BUGINESE = 129, /*[1A00]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_CJK_STROKES = 130, /*[31C0]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = 131, /*[1DC0]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_COPTIC = 132, /*[2C80]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_ETHIOPIC_EXTENDED = 133, /*[2D80]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_ETHIOPIC_SUPPLEMENT = 134, /*[1380]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_GEORGIAN_SUPPLEMENT = 135, /*[2D00]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_GLAGOLITIC = 136, /*[2C00]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_KHAROSHTHI = 137, /*[10A00]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_MODIFIER_TONE_LETTERS = 138, /*[A700]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_NEW_TAI_LUE = 139, /*[1980]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_OLD_PERSIAN = 140, /*[103A0]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_PHONETIC_EXTENSIONS_SUPPLEMENT = 141, /*[1D80]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_SUPPLEMENTAL_PUNCTUATION = 142, /*[2E00]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_SYLOTI_NAGRI = 143, /*[A800]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_TIFINAGH = 144, /*[2D30]*/
+    /** @draft ICU 3.4 */
+    UBLOCK_VERTICAL_FORMS = 145, /*[FE10]*/
+
+    /* New blocks in Unicode 5.0 */
+
+    /** @draft ICU 3.6 */
+    UBLOCK_NKO = 146, /*[07C0]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_BALINESE = 147, /*[1B00]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_LATIN_EXTENDED_C = 148, /*[2C60]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_LATIN_EXTENDED_D = 149, /*[A720]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_PHAGS_PA = 150, /*[A840]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_PHOENICIAN = 151, /*[10900]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_CUNEIFORM = 152, /*[12000]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_CUNEIFORM_NUMBERS_AND_PUNCTUATION = 153, /*[12400]*/
+    /** @draft ICU 3.6 */
+    UBLOCK_COUNTING_ROD_NUMERALS = 154, /*[1D360]*/
+
+#endif /*U_HIDE_DRAFT_API*/
+    
+    /** @stable ICU 2.0 */
+    UBLOCK_COUNT = 155,
+
+    /** @stable ICU 2.0 */
+    UBLOCK_INVALID_CODE=-1
+};
+
+/** @stable ICU 2.0 */
+typedef enum UBlockCode UBlockCode;
+
+/**
+ * East Asian Width constants.
+ *
+ * @see UCHAR_EAST_ASIAN_WIDTH
+ * @see u_getIntPropertyValue
+ * @stable ICU 2.2
+ */
+typedef enum UEastAsianWidth {
+    U_EA_NEUTRAL,   /*[N]*/ /*See note !!*/
+    U_EA_AMBIGUOUS, /*[A]*/
+    U_EA_HALFWIDTH, /*[H]*/
+    U_EA_FULLWIDTH, /*[F]*/
+    U_EA_NARROW,    /*[Na]*/
+    U_EA_WIDE,      /*[W]*/
+    U_EA_COUNT
+} UEastAsianWidth;
+/*
+ * Implementation note:
+ * Keep UEastAsianWidth constant values in sync with names list in genprops/props2.c.
+ */
+
+/**
+ * Selector constants for u_charName().
+ * u_charName() returns the "modern" name of a
+ * Unicode character; or the name that was defined in
+ * Unicode version 1.0, before the Unicode standard merged
+ * with ISO-10646; or an "extended" name that gives each
+ * Unicode code point a unique name.
+ *
+ * @see u_charName
+ * @stable ICU 2.0
+ */
+typedef enum UCharNameChoice {
+    U_UNICODE_CHAR_NAME,
+    U_UNICODE_10_CHAR_NAME,
+    U_EXTENDED_CHAR_NAME,
+    U_CHAR_NAME_CHOICE_COUNT
+} UCharNameChoice;
+
+/**
+ * Selector constants for u_getPropertyName() and
+ * u_getPropertyValueName().  These selectors are used to choose which
+ * name is returned for a given property or value.  All properties and
+ * values have a long name.  Most have a short name, but some do not.
+ * Unicode allows for additional names, beyond the long and short
+ * name, which would be indicated by U_LONG_PROPERTY_NAME + i, where
+ * i=1, 2,...
+ *
+ * @see u_getPropertyName()
+ * @see u_getPropertyValueName()
+ * @stable ICU 2.4
+ */
+typedef enum UPropertyNameChoice {
+    U_SHORT_PROPERTY_NAME,
+    U_LONG_PROPERTY_NAME,
+    U_PROPERTY_NAME_CHOICE_COUNT
+} UPropertyNameChoice;
+
+/**
+ * Decomposition Type constants.
+ *
+ * @see UCHAR_DECOMPOSITION_TYPE
+ * @stable ICU 2.2
+ */
+typedef enum UDecompositionType {
+    U_DT_NONE,              /*[none]*/ /*See note !!*/
+    U_DT_CANONICAL,         /*[can]*/
+    U_DT_COMPAT,            /*[com]*/
+    U_DT_CIRCLE,            /*[enc]*/
+    U_DT_FINAL,             /*[fin]*/
+    U_DT_FONT,              /*[font]*/
+    U_DT_FRACTION,          /*[fra]*/
+    U_DT_INITIAL,           /*[init]*/
+    U_DT_ISOLATED,          /*[iso]*/
+    U_DT_MEDIAL,            /*[med]*/
+    U_DT_NARROW,            /*[nar]*/
+    U_DT_NOBREAK,           /*[nb]*/
+    U_DT_SMALL,             /*[sml]*/
+    U_DT_SQUARE,            /*[sqr]*/
+    U_DT_SUB,               /*[sub]*/
+    U_DT_SUPER,             /*[sup]*/
+    U_DT_VERTICAL,          /*[vert]*/
+    U_DT_WIDE,              /*[wide]*/
+    U_DT_COUNT /* 18 */
+} UDecompositionType;
+
+/**
+ * Joining Type constants.
+ *
+ * @see UCHAR_JOINING_TYPE
+ * @stable ICU 2.2
+ */
+typedef enum UJoiningType {
+    U_JT_NON_JOINING,       /*[U]*/ /*See note !!*/
+    U_JT_JOIN_CAUSING,      /*[C]*/
+    U_JT_DUAL_JOINING,      /*[D]*/
+    U_JT_LEFT_JOINING,      /*[L]*/
+    U_JT_RIGHT_JOINING,     /*[R]*/
+    U_JT_TRANSPARENT,       /*[T]*/
+    U_JT_COUNT /* 6 */
+} UJoiningType;
+
+/**
+ * Joining Group constants.
+ *
+ * @see UCHAR_JOINING_GROUP
+ * @stable ICU 2.2
+ */
+typedef enum UJoiningGroup {
+    U_JG_NO_JOINING_GROUP,
+    U_JG_AIN,
+    U_JG_ALAPH,
+    U_JG_ALEF,
+    U_JG_BEH,
+    U_JG_BETH,
+    U_JG_DAL,
+    U_JG_DALATH_RISH,
+    U_JG_E,
+    U_JG_FEH,
+    U_JG_FINAL_SEMKATH,
+    U_JG_GAF,
+    U_JG_GAMAL,
+    U_JG_HAH,
+    U_JG_HAMZA_ON_HEH_GOAL,
+    U_JG_HE,
+    U_JG_HEH,
+    U_JG_HEH_GOAL,
+    U_JG_HETH,
+    U_JG_KAF,
+    U_JG_KAPH,
+    U_JG_KNOTTED_HEH,
+    U_JG_LAM,
+    U_JG_LAMADH,
+    U_JG_MEEM,
+    U_JG_MIM,
+    U_JG_NOON,
+    U_JG_NUN,
+    U_JG_PE,
+    U_JG_QAF,
+    U_JG_QAPH,
+    U_JG_REH,
+    U_JG_REVERSED_PE,
+    U_JG_SAD,
+    U_JG_SADHE,
+    U_JG_SEEN,
+    U_JG_SEMKATH,
+    U_JG_SHIN,
+    U_JG_SWASH_KAF,
+    U_JG_SYRIAC_WAW,
+    U_JG_TAH,
+    U_JG_TAW,
+    U_JG_TEH_MARBUTA,
+    U_JG_TETH,
+    U_JG_WAW,
+    U_JG_YEH,
+    U_JG_YEH_BARREE,
+    U_JG_YEH_WITH_TAIL,
+    U_JG_YUDH,
+    U_JG_YUDH_HE,
+    U_JG_ZAIN,
+    U_JG_FE,        /**< @stable ICU 2.6 */
+    U_JG_KHAPH,     /**< @stable ICU 2.6 */
+    U_JG_ZHAIN,     /**< @stable ICU 2.6 */
+    U_JG_COUNT
+} UJoiningGroup;
+
+/**
+ * Grapheme Cluster Break constants.
+ *
+ * @see UCHAR_GRAPHEME_CLUSTER_BREAK
+ * @draft ICU 3.4
+ */
+typedef enum UGraphemeClusterBreak {
+#ifndef U_HIDE_DRAFT_API
+    U_GCB_OTHER = 0,            /*[XX]*/ /*See note !!*/
+    U_GCB_CONTROL = 1,          /*[CN]*/
+    U_GCB_CR = 2,               /*[CR]*/
+    U_GCB_EXTEND = 3,           /*[EX]*/
+    U_GCB_L = 4,                /*[L]*/
+    U_GCB_LF = 5,               /*[LF]*/
+    U_GCB_LV = 6,               /*[LV]*/
+    U_GCB_LVT = 7,              /*[LVT]*/
+    U_GCB_T = 8,                /*[T]*/
+    U_GCB_V = 9,                /*[V]*/
+#endif /*U_HIDE_DRAFT_API*/
+    U_GCB_COUNT = 10
+} UGraphemeClusterBreak;
+
+/**
+ * Word Break constants.
+ * (UWordBreak is a pre-existing enum type in ubrk.h for word break status tags.)
+ *
+ * @see UCHAR_WORD_BREAK
+ * @draft ICU 3.4
+ */
+typedef enum UWordBreakValues {
+#ifndef U_HIDE_DRAFT_API
+    U_WB_OTHER = 0,             /*[XX]*/ /*See note !!*/
+    U_WB_ALETTER = 1,           /*[LE]*/
+    U_WB_FORMAT = 2,            /*[FO]*/
+    U_WB_KATAKANA = 3,          /*[KA]*/
+    U_WB_MIDLETTER = 4,         /*[ML]*/
+    U_WB_MIDNUM = 5,            /*[MN]*/
+    U_WB_NUMERIC = 6,           /*[NU]*/
+    U_WB_EXTENDNUMLET = 7,      /*[EX]*/
+#endif /*U_HIDE_DRAFT_API*/
+    U_WB_COUNT = 8
+} UWordBreakValues;
+
+/**
+ * Sentence Break constants.
+ *
+ * @see UCHAR_SENTENCE_BREAK
+ * @draft ICU 3.4
+ */
+typedef enum USentenceBreak {
+#ifndef U_HIDE_DRAFT_API
+    U_SB_OTHER = 0,             /*[XX]*/ /*See note !!*/
+    U_SB_ATERM = 1,             /*[AT]*/
+    U_SB_CLOSE = 2,             /*[CL]*/
+    U_SB_FORMAT = 3,            /*[FO]*/
+    U_SB_LOWER = 4,             /*[LO]*/
+    U_SB_NUMERIC = 5,           /*[NU]*/
+    U_SB_OLETTER = 6,           /*[LE]*/
+    U_SB_SEP = 7,               /*[SE]*/
+    U_SB_SP = 8,                /*[SP]*/
+    U_SB_STERM = 9,             /*[ST]*/
+    U_SB_UPPER = 10,             /*[UP]*/
+#endif /*U_HIDE_DRAFT_API*/
+    U_SB_COUNT = 11
+} USentenceBreak;
+
+/**
+ * Line Break constants.
+ *
+ * @see UCHAR_LINE_BREAK
+ * @stable ICU 2.2
+ */
+typedef enum ULineBreak {
+    U_LB_UNKNOWN = 0,           /*[XX]*/ /*See note !!*/
+    U_LB_AMBIGUOUS = 1,         /*[AI]*/
+    U_LB_ALPHABETIC = 2,        /*[AL]*/
+    U_LB_BREAK_BOTH = 3,        /*[B2]*/
+    U_LB_BREAK_AFTER = 4,       /*[BA]*/
+    U_LB_BREAK_BEFORE = 5,      /*[BB]*/
+    U_LB_MANDATORY_BREAK = 6,   /*[BK]*/
+    U_LB_CONTINGENT_BREAK = 7,  /*[CB]*/
+    U_LB_CLOSE_PUNCTUATION = 8, /*[CL]*/
+    U_LB_COMBINING_MARK = 9,    /*[CM]*/
+    U_LB_CARRIAGE_RETURN = 10,   /*[CR]*/
+    U_LB_EXCLAMATION = 11,       /*[EX]*/
+    U_LB_GLUE = 12,              /*[GL]*/
+    U_LB_HYPHEN = 13,            /*[HY]*/
+    U_LB_IDEOGRAPHIC = 14,       /*[ID]*/
+    U_LB_INSEPERABLE = 15,
+    /** Renamed from the misspelled "inseperable" in Unicode 4.0.1/ICU 3.0 @stable ICU 3.0 */
+    U_LB_INSEPARABLE=U_LB_INSEPERABLE,/*[IN]*/
+    U_LB_INFIX_NUMERIC = 16,     /*[IS]*/
+    U_LB_LINE_FEED = 17,         /*[LF]*/
+    U_LB_NONSTARTER = 18,        /*[NS]*/
+    U_LB_NUMERIC = 19,           /*[NU]*/
+    U_LB_OPEN_PUNCTUATION = 20,  /*[OP]*/
+    U_LB_POSTFIX_NUMERIC = 21,   /*[PO]*/
+    U_LB_PREFIX_NUMERIC = 22,    /*[PR]*/
+    U_LB_QUOTATION = 23,         /*[QU]*/
+    U_LB_COMPLEX_CONTEXT = 24,   /*[SA]*/
+    U_LB_SURROGATE = 25,         /*[SG]*/
+    U_LB_SPACE = 26,             /*[SP]*/
+    U_LB_BREAK_SYMBOLS = 27,     /*[SY]*/
+    U_LB_ZWSPACE = 28,           /*[ZW]*/
+    U_LB_NEXT_LINE = 29,         /*[NL]*/ /* from here on: new in Unicode 4/ICU 2.6 */
+    U_LB_WORD_JOINER = 30,       /*[WJ]*/
+    U_LB_H2 = 31,                /*[H2]*/ /* from here on: new in Unicode 4.1/ICU 3.4 */
+    U_LB_H3 = 32,                /*[H3]*/
+    U_LB_JL = 33,                /*[JL]*/
+    U_LB_JT = 34,                /*[JT]*/
+    U_LB_JV = 35,                /*[JV]*/
+    U_LB_COUNT = 36
+} ULineBreak;
+
+/**
+ * Numeric Type constants.
+ *
+ * @see UCHAR_NUMERIC_TYPE
+ * @stable ICU 2.2
+ */
+typedef enum UNumericType {
+    U_NT_NONE,              /*[None]*/ /*See note !!*/
+    U_NT_DECIMAL,           /*[de]*/
+    U_NT_DIGIT,             /*[di]*/
+    U_NT_NUMERIC,           /*[nu]*/
+    U_NT_COUNT
+} UNumericType;
+
+/**
+ * Hangul Syllable Type constants.
+ *
+ * @see UCHAR_HANGUL_SYLLABLE_TYPE
+ * @stable ICU 2.6
+ */
+typedef enum UHangulSyllableType {
+    U_HST_NOT_APPLICABLE,   /*[NA]*/ /*See note !!*/
+    U_HST_LEADING_JAMO,     /*[L]*/
+    U_HST_VOWEL_JAMO,       /*[V]*/
+    U_HST_TRAILING_JAMO,    /*[T]*/
+    U_HST_LV_SYLLABLE,      /*[LV]*/
+    U_HST_LVT_SYLLABLE,     /*[LVT]*/
+    U_HST_COUNT
+} UHangulSyllableType;
+
+/**
+ * Check a binary Unicode property for a code point.
+ *
+ * Unicode, especially in version 3.2, defines many more properties than the
+ * original set in UnicodeData.txt.
+ *
+ * The properties APIs are intended to reflect Unicode properties as defined
+ * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR).
+ * For details about the properties see http://www.unicode.org/ucd/ .
+ * For names of Unicode properties see the UCD file PropertyAliases.txt.
+ *
+ * Important: If ICU is built with UCD files from Unicode versions below 3.2,
+ * then properties marked with "new in Unicode 3.2" are not or not fully available.
+ *
+ * @param c Code point to test.
+ * @param which UProperty selector constant, identifies which binary property to check.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT.
+ * @return TRUE or FALSE according to the binary Unicode property value for c.
+ *         Also FALSE if 'which' is out of bounds or if the Unicode version
+ *         does not have data for the property at all, or not for this code point.
+ *
+ * @see UProperty
+ * @see u_getIntPropertyValue
+ * @see u_getUnicodeVersion
+ * @stable ICU 2.1
+ */
+U_STABLE UBool U_EXPORT2
+u_hasBinaryProperty(UChar32 c, UProperty which);
+
+/**
+ * Check if a code point has the Alphabetic Unicode property.
+ * Same as u_hasBinaryProperty(c, UCHAR_ALPHABETIC).
+ * This is different from u_isalpha!
+ * @param c Code point to test
+ * @return true if the code point has the Alphabetic Unicode property, false otherwise
+ *
+ * @see UCHAR_ALPHABETIC
+ * @see u_isalpha
+ * @see u_hasBinaryProperty
+ * @stable ICU 2.1
+ */
+U_STABLE UBool U_EXPORT2
+u_isUAlphabetic(UChar32 c);
+
+/**
+ * Check if a code point has the Lowercase Unicode property.
+ * Same as u_hasBinaryProperty(c, UCHAR_LOWERCASE).
+ * This is different from u_islower!
+ * @param c Code point to test
+ * @return true if the code point has the Lowercase Unicode property, false otherwise
+ *
+ * @see UCHAR_LOWERCASE
+ * @see u_islower
+ * @see u_hasBinaryProperty
+ * @stable ICU 2.1
+ */
+U_STABLE UBool U_EXPORT2
+u_isULowercase(UChar32 c);
+
+/**
+ * Check if a code point has the Uppercase Unicode property.
+ * Same as u_hasBinaryProperty(c, UCHAR_UPPERCASE).
+ * This is different from u_isupper!
+ * @param c Code point to test
+ * @return true if the code point has the Uppercase Unicode property, false otherwise
+ *
+ * @see UCHAR_UPPERCASE
+ * @see u_isupper
+ * @see u_hasBinaryProperty
+ * @stable ICU 2.1
+ */
+U_STABLE UBool U_EXPORT2
+u_isUUppercase(UChar32 c);
+
+/**
+ * Check if a code point has the White_Space Unicode property.
+ * Same as u_hasBinaryProperty(c, UCHAR_WHITE_SPACE).
+ * This is different from both u_isspace and u_isWhitespace!
+ *
+ * Note: There are several ICU whitespace functions; please see the uchar.h
+ * file documentation for a detailed comparison.
+ *
+ * @param c Code point to test
+ * @return true if the code point has the White_Space Unicode property, false otherwise.
+ *
+ * @see UCHAR_WHITE_SPACE
+ * @see u_isWhitespace
+ * @see u_isspace
+ * @see u_isJavaSpaceChar
+ * @see u_hasBinaryProperty
+ * @stable ICU 2.1
+ */
+U_STABLE UBool U_EXPORT2
+u_isUWhiteSpace(UChar32 c);
+
+/**
+ * Get the property value for an enumerated or integer Unicode property for a code point.
+ * Also returns binary and mask property values.
+ *
+ * Unicode, especially in version 3.2, defines many more properties than the
+ * original set in UnicodeData.txt.
+ *
+ * The properties APIs are intended to reflect Unicode properties as defined
+ * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR).
+ * For details about the properties see http://www.unicode.org/ .
+ * For names of Unicode properties see the UCD file PropertyAliases.txt.
+ *
+ * Sample usage:
+ * UEastAsianWidth ea=(UEastAsianWidth)u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
+ * UBool b=(UBool)u_getIntPropertyValue(c, UCHAR_IDEOGRAPHIC);
+ *
+ * @param c Code point to test.
+ * @param which UProperty selector constant, identifies which property to check.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT
+ *        or UCHAR_INT_START<=which<UCHAR_INT_LIMIT
+ *        or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT.
+ * @return Numeric value that is directly the property value or,
+ *         for enumerated properties, corresponds to the numeric value of the enumerated
+ *         constant of the respective property value enumeration type
+ *         (cast to enum type if necessary).
+ *         Returns 0 or 1 (for FALSE/TRUE) for binary Unicode properties.
+ *         Returns a bit-mask for mask properties.
+ *         Returns 0 if 'which' is out of bounds or if the Unicode version
+ *         does not have data for the property at all, or not for this code point.
+ *
+ * @see UProperty
+ * @see u_hasBinaryProperty
+ * @see u_getIntPropertyMinValue
+ * @see u_getIntPropertyMaxValue
+ * @see u_getUnicodeVersion
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+u_getIntPropertyValue(UChar32 c, UProperty which);
+
+/**
+ * Get the minimum value for an enumerated/integer/binary Unicode property.
+ * Can be used together with u_getIntPropertyMaxValue
+ * to allocate arrays of UnicodeSet or similar.
+ *
+ * @param which UProperty selector constant, identifies which binary property to check.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT
+ *        or UCHAR_INT_START<=which<UCHAR_INT_LIMIT.
+ * @return Minimum value returned by u_getIntPropertyValue for a Unicode property.
+ *         0 if the property selector is out of range.
+ *
+ * @see UProperty
+ * @see u_hasBinaryProperty
+ * @see u_getUnicodeVersion
+ * @see u_getIntPropertyMaxValue
+ * @see u_getIntPropertyValue
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+u_getIntPropertyMinValue(UProperty which);
+
+/**
+ * Get the maximum value for an enumerated/integer/binary Unicode property.
+ * Can be used together with u_getIntPropertyMinValue
+ * to allocate arrays of UnicodeSet or similar.
+ *
+ * Examples for min/max values (for Unicode 3.2):
+ *
+ * - UCHAR_BIDI_CLASS:    0/18 (U_LEFT_TO_RIGHT/U_BOUNDARY_NEUTRAL)
+ * - UCHAR_SCRIPT:        0/45 (USCRIPT_COMMON/USCRIPT_TAGBANWA)
+ * - UCHAR_IDEOGRAPHIC:   0/1  (FALSE/TRUE)
+ *
+ * For undefined UProperty constant values, min/max values will be 0/-1.
+ *
+ * @param which UProperty selector constant, identifies which binary property to check.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT
+ *        or UCHAR_INT_START<=which<UCHAR_INT_LIMIT.
+ * @return Maximum value returned by u_getIntPropertyValue for a Unicode property.
+ *         <=0 if the property selector is out of range.
+ *
+ * @see UProperty
+ * @see u_hasBinaryProperty
+ * @see u_getUnicodeVersion
+ * @see u_getIntPropertyMaxValue
+ * @see u_getIntPropertyValue
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+u_getIntPropertyMaxValue(UProperty which);
+
+/**
+ * Get the numeric value for a Unicode code point as defined in the
+ * Unicode Character Database.
+ *
+ * A "double" return type is necessary because
+ * some numeric values are fractions, negative, or too large for int32_t.
+ *
+ * For characters without any numeric values in the Unicode Character Database,
+ * this function will return U_NO_NUMERIC_VALUE.
+ *
+ * Similar to java.lang.Character.getNumericValue(), but u_getNumericValue()
+ * also supports negative values, large values, and fractions,
+ * while Java's getNumericValue() returns values 10..35 for ASCII letters.
+ *
+ * @param c Code point to get the numeric value for.
+ * @return Numeric value of c, or U_NO_NUMERIC_VALUE if none is defined.
+ *
+ * @see U_NO_NUMERIC_VALUE
+ * @stable ICU 2.2
+ */
+U_STABLE double U_EXPORT2
+u_getNumericValue(UChar32 c);
+
+/**
+ * Special value that is returned by u_getNumericValue when
+ * no numeric value is defined for a code point.
+ *
+ * @see u_getNumericValue
+ * @stable ICU 2.2
+ */
+#define U_NO_NUMERIC_VALUE ((double)-123456789.)
+
+/**
+ * Determines whether the specified code point has the general category "Ll"
+ * (lowercase letter).
+ *
+ * Same as java.lang.Character.isLowerCase().
+ *
+ * This misses some characters that are also lowercase but
+ * have a different general category value.
+ * In order to include those, use UCHAR_LOWERCASE.
+ *
+ * In addition to being equivalent to a Java function, this also serves
+ * as a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is an Ll lowercase letter
+ *
+ * @see UCHAR_LOWERCASE
+ * @see u_isupper
+ * @see u_istitle
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_islower(UChar32 c);
+
+/**
+ * Determines whether the specified code point has the general category "Lu"
+ * (uppercase letter).
+ *
+ * Same as java.lang.Character.isUpperCase().
+ *
+ * This misses some characters that are also uppercase but
+ * have a different general category value.
+ * In order to include those, use UCHAR_UPPERCASE.
+ *
+ * In addition to being equivalent to a Java function, this also serves
+ * as a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is an Lu uppercase letter
+ *
+ * @see UCHAR_UPPERCASE
+ * @see u_islower
+ * @see u_istitle
+ * @see u_tolower
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isupper(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a titlecase letter.
+ * True for general category "Lt" (titlecase letter).
+ *
+ * Same as java.lang.Character.isTitleCase().
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is an Lt titlecase letter
+ *
+ * @see u_isupper
+ * @see u_islower
+ * @see u_totitle
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_istitle(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a digit character according to Java.
+ * True for characters with general category "Nd" (decimal digit numbers).
+ * Beginning with Unicode 4, this is the same as
+ * testing for the Numeric_Type of Decimal.
+ *
+ * Same as java.lang.Character.isDigit().
+ *
+ * In addition to being equivalent to a Java function, this also serves
+ * as a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a digit character according to Character.isDigit()
+ *
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isdigit(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a letter character.
+ * True for general categories "L" (letters).
+ *
+ * Same as java.lang.Character.isLetter().
+ *
+ * In addition to being equivalent to a Java function, this also serves
+ * as a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a letter character
+ *
+ * @see u_isdigit
+ * @see u_isalnum
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isalpha(UChar32 c);
+
+/**
+ * Determines whether the specified code point is an alphanumeric character
+ * (letter or digit) according to Java.
+ * True for characters with general categories
+ * "L" (letters) and "Nd" (decimal digit numbers).
+ *
+ * Same as java.lang.Character.isLetterOrDigit().
+ *
+ * In addition to being equivalent to a Java function, this also serves
+ * as a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is an alphanumeric character according to Character.isLetterOrDigit()
+ *
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isalnum(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a hexadecimal digit.
+ * This is equivalent to u_digit(c, 16)>=0.
+ * True for characters with general category "Nd" (decimal digit numbers)
+ * as well as Latin letters a-f and A-F in both ASCII and Fullwidth ASCII.
+ * (That is, for letters with code points
+ * 0041..0046, 0061..0066, FF21..FF26, FF41..FF46.)
+ *
+ * In order to narrow the definition of hexadecimal digits to only ASCII
+ * characters, use (c<=0x7f && u_isxdigit(c)).
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a hexadecimal digit
+ *
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_isxdigit(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a punctuation character.
+ * True for characters with general categories "P" (punctuation).
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a punctuation character
+ *
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_ispunct(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a "graphic" character
+ * (printable, excluding spaces).
+ * TRUE for all characters except those with general categories
+ * "Cc" (control codes), "Cf" (format controls), "Cs" (surrogates),
+ * "Cn" (unassigned), and "Z" (separators).
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a "graphic" character
+ *
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_isgraph(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a "blank" or "horizontal space",
+ * a character that visibly separates words on a line.
+ * The following are equivalent definitions:
+ *
+ * TRUE for Unicode White_Space characters except for "vertical space controls"
+ * where "vertical space controls" are the following characters:
+ * U+000A (LF) U+000B (VT) U+000C (FF) U+000D (CR) U+0085 (NEL) U+2028 (LS) U+2029 (PS)
+ *
+ * same as
+ *
+ * TRUE for U+0009 (TAB) and characters with general category "Zs" (space separators)
+ * except Zero Width Space (ZWSP, U+200B).
+ *
+ * Note: There are several ICU whitespace functions; please see the uchar.h
+ * file documentation for a detailed comparison.
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a "blank"
+ *
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_isblank(UChar32 c);
+
+/**
+ * Determines whether the specified code point is "defined",
+ * which usually means that it is assigned a character.
+ * True for general categories other than "Cn" (other, not assigned),
+ * i.e., true for all code points mentioned in UnicodeData.txt.
+ *
+ * Note that non-character code points (e.g., U+FDD0) are not "defined"
+ * (they are Cn), but surrogate code points are "defined" (Cs).
+ *
+ * Same as java.lang.Character.isDefined().
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is assigned a character
+ *
+ * @see u_isdigit
+ * @see u_isalpha
+ * @see u_isalnum
+ * @see u_isupper
+ * @see u_islower
+ * @see u_istitle
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isdefined(UChar32 c);
+
+/**
+ * Determines if the specified character is a space character or not.
+ *
+ * Note: There are several ICU whitespace functions; please see the uchar.h
+ * file documentation for a detailed comparison.
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c    the character to be tested
+ * @return  true if the character is a space character; false otherwise.
+ *
+ * @see u_isJavaSpaceChar
+ * @see u_isWhitespace
+ * @see u_isUWhiteSpace
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isspace(UChar32 c);
+
+/**
+ * Determine if the specified code point is a space character according to Java.
+ * True for characters with general categories "Z" (separators),
+ * which does not include control codes (e.g., TAB or Line Feed).
+ *
+ * Same as java.lang.Character.isSpaceChar().
+ *
+ * Note: There are several ICU whitespace functions; please see the uchar.h
+ * file documentation for a detailed comparison.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a space character according to Character.isSpaceChar()
+ *
+ * @see u_isspace
+ * @see u_isWhitespace
+ * @see u_isUWhiteSpace
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_isJavaSpaceChar(UChar32 c);
+
+/**
+ * Determines if the specified code point is a whitespace character according to Java/ICU.
+ * A character is considered to be a Java whitespace character if and only
+ * if it satisfies one of the following criteria:
+ *
+ * - It is a Unicode separator (categories "Z"), but is not
+ *      a no-break space (U+00A0 NBSP or U+2007 Figure Space or U+202F Narrow NBSP).
+ * - It is U+0009 HORIZONTAL TABULATION.
+ * - It is U+000A LINE FEED.
+ * - It is U+000B VERTICAL TABULATION.
+ * - It is U+000C FORM FEED.
+ * - It is U+000D CARRIAGE RETURN.
+ * - It is U+001C FILE SEPARATOR.
+ * - It is U+001D GROUP SEPARATOR.
+ * - It is U+001E RECORD SEPARATOR.
+ * - It is U+001F UNIT SEPARATOR.
+ * - It is U+0085 NEXT LINE.
+ *
+ * Same as java.lang.Character.isWhitespace() except that Java omits U+0085.
+ *
+ * Note: There are several ICU whitespace functions; please see the uchar.h
+ * file documentation for a detailed comparison.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a whitespace character according to Java/ICU
+ *
+ * @see u_isspace
+ * @see u_isJavaSpaceChar
+ * @see u_isUWhiteSpace
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isWhitespace(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a control character
+ * (as defined by this function).
+ * A control character is one of the following:
+ * - ISO 8-bit control character (U+0000..U+001f and U+007f..U+009f)
+ * - U_CONTROL_CHAR (Cc)
+ * - U_FORMAT_CHAR (Cf)
+ * - U_LINE_SEPARATOR (Zl)
+ * - U_PARAGRAPH_SEPARATOR (Zp)
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a control character
+ *
+ * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
+ * @see u_isprint
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_iscntrl(UChar32 c);
+
+/**
+ * Determines whether the specified code point is an ISO control code.
+ * True for U+0000..U+001f and U+007f..U+009f (general category "Cc").
+ *
+ * Same as java.lang.Character.isISOControl().
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is an ISO control code
+ *
+ * @see u_iscntrl
+ * @stable ICU 2.6
+ */
+U_STABLE UBool U_EXPORT2
+u_isISOControl(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a printable character.
+ * True for general categories <em>other</em> than "C" (controls).
+ *
+ * This is a C/POSIX migration function.
+ * See the comments about C/POSIX character classification functions in the
+ * documentation at the top of this header file.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a printable character
+ *
+ * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
+ * @see u_iscntrl
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isprint(UChar32 c);
+
+/**
+ * Determines whether the specified code point is a base character.
+ * True for general categories "L" (letters), "N" (numbers),
+ * "Mc" (spacing combining marks), and "Me" (enclosing marks).
+ *
+ * Note that this is different from the Unicode definition in
+ * chapter 3.5, conformance clause D13,
+ * which defines base characters to be all characters (not Cn)
+ * that do not graphically combine with preceding characters (M)
+ * and that are neither control (Cc) or format (Cf) characters.
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is a base character according to this function
+ *
+ * @see u_isalpha
+ * @see u_isdigit
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isbase(UChar32 c);
+
+/**
+ * Returns the bidirectional category value for the code point,
+ * which is used in the Unicode bidirectional algorithm
+ * (UAX #9 http://www.unicode.org/reports/tr9/).
+ * Note that some <em>unassigned</em> code points have bidi values
+ * of R or AL because they are in blocks that are reserved
+ * for Right-To-Left scripts.
+ *
+ * Same as java.lang.Character.getDirectionality()
+ *
+ * @param c the code point to be tested
+ * @return the bidirectional category (UCharDirection) value
+ *
+ * @see UCharDirection
+ * @stable ICU 2.0
+ */
+U_STABLE UCharDirection U_EXPORT2
+u_charDirection(UChar32 c);
+
+/**
+ * Determines whether the code point has the Bidi_Mirrored property.
+ * This property is set for characters that are commonly used in
+ * Right-To-Left contexts and need to be displayed with a "mirrored"
+ * glyph.
+ *
+ * Same as java.lang.Character.isMirrored().
+ * Same as UCHAR_BIDI_MIRRORED
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the character has the Bidi_Mirrored property
+ *
+ * @see UCHAR_BIDI_MIRRORED
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isMirrored(UChar32 c);
+
+/**
+ * Maps the specified character to a "mirror-image" character.
+ * For characters with the Bidi_Mirrored property, implementations
+ * sometimes need a "poor man's" mapping to another Unicode
+ * character (code point) such that the default glyph may serve
+ * as the mirror-image of the default glyph of the specified
+ * character. This is useful for text conversion to and from
+ * codepages with visual order, and for displays without glyph
+ * selecetion capabilities.
+ *
+ * @param c the code point to be mapped
+ * @return another Unicode code point that may serve as a mirror-image
+ *         substitute, or c itself if there is no such mapping or c
+ *         does not have the Bidi_Mirrored property
+ *
+ * @see UCHAR_BIDI_MIRRORED
+ * @see u_isMirrored
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_charMirror(UChar32 c);
+
+/**
+ * Returns the general category value for the code point.
+ *
+ * Same as java.lang.Character.getType().
+ *
+ * @param c the code point to be tested
+ * @return the general category (UCharCategory) value
+ *
+ * @see UCharCategory
+ * @stable ICU 2.0
+ */
+U_STABLE int8_t U_EXPORT2
+u_charType(UChar32 c);
+
+/**
+ * Get a single-bit bit set for the general category of a character.
+ * This bit set can be compared bitwise with U_GC_SM_MASK, U_GC_L_MASK, etc.
+ * Same as U_MASK(u_charType(c)).
+ *
+ * @param c the code point to be tested
+ * @return a single-bit mask corresponding to the general category (UCharCategory) value
+ *
+ * @see u_charType
+ * @see UCharCategory
+ * @see U_GC_CN_MASK
+ * @stable ICU 2.1
+ */
+#define U_GET_GC_MASK(c) U_MASK(u_charType(c))
+
+/**
+ * Callback from u_enumCharTypes(), is called for each contiguous range
+ * of code points c (where start<=c<limit)
+ * with the same Unicode general category ("character type").
+ *
+ * The callback function can stop the enumeration by returning FALSE.
+ *
+ * @param context an opaque pointer, as passed into utrie_enum()
+ * @param start the first code point in a contiguous range with value
+ * @param limit one past the last code point in a contiguous range with value
+ * @param type the general category for all code points in [start..limit[
+ * @return FALSE to stop the enumeration
+ *
+ * @stable ICU 2.1
+ * @see UCharCategory
+ * @see u_enumCharTypes
+ */
+typedef UBool U_CALLCONV
+UCharEnumTypeRange(const void *context, UChar32 start, UChar32 limit, UCharCategory type);
+
+/**
+ * Enumerate efficiently all code points with their Unicode general categories.
+ *
+ * This is useful for building data structures (e.g., UnicodeSet's),
+ * for enumerating all assigned code points (type!=U_UNASSIGNED), etc.
+ *
+ * For each contiguous range of code points with a given general category ("character type"),
+ * the UCharEnumTypeRange function is called.
+ * Adjacent ranges have different types.
+ * The Unicode Standard guarantees that the numeric value of the type is 0..31.
+ *
+ * @param enumRange a pointer to a function that is called for each contiguous range
+ *                  of code points with the same general category
+ * @param context an opaque pointer that is passed on to the callback function
+ *
+ * @stable ICU 2.1
+ * @see UCharCategory
+ * @see UCharEnumTypeRange
+ */
+U_STABLE void U_EXPORT2
+u_enumCharTypes(UCharEnumTypeRange *enumRange, const void *context);
+
+#if !UCONFIG_NO_NORMALIZATION
+
+/**
+ * Returns the combining class of the code point as specified in UnicodeData.txt.
+ *
+ * @param c the code point of the character
+ * @return the combining class of the character
+ * @stable ICU 2.0
+ */
+U_STABLE uint8_t U_EXPORT2
+u_getCombiningClass(UChar32 c);
+
+#endif
+
+/**
+ * Returns the decimal digit value of a decimal digit character.
+ * Such characters have the general category "Nd" (decimal digit numbers)
+ * and a Numeric_Type of Decimal.
+ *
+ * Unlike ICU releases before 2.6, no digit values are returned for any
+ * Han characters because Han number characters are often used with a special
+ * Chinese-style number format (with characters for powers of 10 in between)
+ * instead of in decimal-positional notation.
+ * Unicode 4 explicitly assigns Han number characters the Numeric_Type
+ * Numeric instead of Decimal.
+ * See Jitterbug 1483 for more details.
+ *
+ * Use u_getIntPropertyValue(c, UCHAR_NUMERIC_TYPE) and u_getNumericValue()
+ * for complete numeric Unicode properties.
+ *
+ * @param c the code point for which to get the decimal digit value
+ * @return the decimal digit value of c,
+ *         or -1 if c is not a decimal digit character
+ *
+ * @see u_getNumericValue
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+u_charDigitValue(UChar32 c);
+
+/**
+ * Returns the Unicode allocation block that contains the character.
+ *
+ * @param c the code point to be tested
+ * @return the block value (UBlockCode) for c
+ *
+ * @see UBlockCode
+ * @stable ICU 2.0
+ */
+U_STABLE UBlockCode U_EXPORT2
+ublock_getCode(UChar32 c);
+
+/**
+ * Retrieve the name of a Unicode character.
+ * Depending on <code>nameChoice</code>, the character name written
+ * into the buffer is the "modern" name or the name that was defined
+ * in Unicode version 1.0.
+ * The name contains only "invariant" characters
+ * like A-Z, 0-9, space, and '-'.
+ * Unicode 1.0 names are only retrieved if they are different from the modern
+ * names and if the data file contains the data for them. gennames may or may
+ * not be called with a command line option to include 1.0 names in unames.dat.
+ *
+ * @param code The character (code point) for which to get the name.
+ *             It must be <code>0<=code<=0x10ffff</code>.
+ * @param nameChoice Selector for which name to get.
+ * @param buffer Destination address for copying the name.
+ *               The name will always be zero-terminated.
+ *               If there is no name, then the buffer will be set to the empty string.
+ * @param bufferLength <code>==sizeof(buffer)</code>
+ * @param pErrorCode Pointer to a UErrorCode variable;
+ *        check for <code>U_SUCCESS()</code> after <code>u_charName()</code>
+ *        returns.
+ * @return The length of the name, or 0 if there is no name for this character.
+ *         If the bufferLength is less than or equal to the length, then the buffer
+ *         contains the truncated name and the returned length indicates the full
+ *         length of the name.
+ *         The length does not include the zero-termination.
+ *
+ * @see UCharNameChoice
+ * @see u_charFromName
+ * @see u_enumCharNames
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+u_charName(UChar32 code, UCharNameChoice nameChoice,
+           char *buffer, int32_t bufferLength,
+           UErrorCode *pErrorCode);
+
+/**
+ * Get the ISO 10646 comment for a character.
+ * The ISO 10646 comment is an informative field in the Unicode Character
+ * Database (UnicodeData.txt field 11) and is from the ISO 10646 names list.
+ *
+ * @param c The character (code point) for which to get the ISO comment.
+ *             It must be <code>0<=c<=0x10ffff</code>.
+ * @param dest Destination address for copying the comment.
+ *             The comment will be zero-terminated if possible.
+ *             If there is no comment, then the buffer will be set to the empty string.
+ * @param destCapacity <code>==sizeof(dest)</code>
+ * @param pErrorCode Pointer to a UErrorCode variable;
+ *        check for <code>U_SUCCESS()</code> after <code>u_getISOComment()</code>
+ *        returns.
+ * @return The length of the comment, or 0 if there is no comment for this character.
+ *         If the destCapacity is less than or equal to the length, then the buffer
+ *         contains the truncated name and the returned length indicates the full
+ *         length of the name.
+ *         The length does not include the zero-termination.
+ *
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+u_getISOComment(UChar32 c,
+                char *dest, int32_t destCapacity,
+                UErrorCode *pErrorCode);
+
+/**
+ * Find a Unicode character by its name and return its code point value.
+ * The name is matched exactly and completely.
+ * If the name does not correspond to a code point, <i>pErrorCode</i>
+ * is set to <code>U_INVALID_CHAR_FOUND</code>.
+ * A Unicode 1.0 name is matched only if it differs from the modern name.
+ * Unicode names are all uppercase. Extended names are lowercase followed
+ * by an uppercase hexadecimal number, and within angle brackets.
+ *
+ * @param nameChoice Selector for which name to match.
+ * @param name The name to match.
+ * @param pErrorCode Pointer to a UErrorCode variable
+ * @return The Unicode value of the code point with the given name,
+ *         or an undefined value if there is no such code point.
+ *
+ * @see UCharNameChoice
+ * @see u_charName
+ * @see u_enumCharNames
+ * @stable ICU 1.7
+ */
+U_STABLE UChar32 U_EXPORT2
+u_charFromName(UCharNameChoice nameChoice,
+               const char *name,
+               UErrorCode *pErrorCode);
+
+/**
+ * Type of a callback function for u_enumCharNames() that gets called
+ * for each Unicode character with the code point value and
+ * the character name.
+ * If such a function returns FALSE, then the enumeration is stopped.
+ *
+ * @param context The context pointer that was passed to u_enumCharNames().
+ * @param code The Unicode code point for the character with this name.
+ * @param nameChoice Selector for which kind of names is enumerated.
+ * @param name The character's name, zero-terminated.
+ * @param length The length of the name.
+ * @return TRUE if the enumeration should continue, FALSE to stop it.
+ *
+ * @see UCharNameChoice
+ * @see u_enumCharNames
+ * @stable ICU 1.7
+ */
+typedef UBool U_CALLCONV UEnumCharNamesFn(void *context,
+                               UChar32 code,
+                               UCharNameChoice nameChoice,
+                               const char *name,
+                               int32_t length);
+
+/**
+ * Enumerate all assigned Unicode characters between the start and limit
+ * code points (start inclusive, limit exclusive) and call a function
+ * for each, passing the code point value and the character name.
+ * For Unicode 1.0 names, only those are enumerated that differ from the
+ * modern names.
+ *
+ * @param start The first code point in the enumeration range.
+ * @param limit One more than the last code point in the enumeration range
+ *              (the first one after the range).
+ * @param fn The function that is to be called for each character name.
+ * @param context An arbitrary pointer that is passed to the function.
+ * @param nameChoice Selector for which kind of names to enumerate.
+ * @param pErrorCode Pointer to a UErrorCode variable
+ *
+ * @see UCharNameChoice
+ * @see UEnumCharNamesFn
+ * @see u_charName
+ * @see u_charFromName
+ * @stable ICU 1.7
+ */
+U_STABLE void U_EXPORT2
+u_enumCharNames(UChar32 start, UChar32 limit,
+                UEnumCharNamesFn *fn,
+                void *context,
+                UCharNameChoice nameChoice,
+                UErrorCode *pErrorCode);
+
+/**
+ * Return the Unicode name for a given property, as given in the
+ * Unicode database file PropertyAliases.txt.
+ *
+ * In addition, this function maps the property
+ * UCHAR_GENERAL_CATEGORY_MASK to the synthetic names "gcm" /
+ * "General_Category_Mask".  These names are not in
+ * PropertyAliases.txt.
+ *
+ * @param property UProperty selector other than UCHAR_INVALID_CODE.
+ *         If out of range, NULL is returned.
+ *
+ * @param nameChoice selector for which name to get.  If out of range,
+ *         NULL is returned.  All properties have a long name.  Most
+ *         have a short name, but some do not.  Unicode allows for
+ *         additional names; if present these will be returned by
+ *         U_LONG_PROPERTY_NAME + i, where i=1, 2,...
+ *
+ * @return a pointer to the name, or NULL if either the
+ *         property or the nameChoice is out of range.  If a given
+ *         nameChoice returns NULL, then all larger values of
+ *         nameChoice will return NULL, with one exception: if NULL is
+ *         returned for U_SHORT_PROPERTY_NAME, then
+ *         U_LONG_PROPERTY_NAME (and higher) may still return a
+ *         non-NULL value.  The returned pointer is valid until
+ *         u_cleanup() is called.
+ *
+ * @see UProperty
+ * @see UPropertyNameChoice
+ * @stable ICU 2.4
+ */
+U_STABLE const char* U_EXPORT2
+u_getPropertyName(UProperty property,
+                  UPropertyNameChoice nameChoice);
+
+/**
+ * Return the UProperty enum for a given property name, as specified
+ * in the Unicode database file PropertyAliases.txt.  Short, long, and
+ * any other variants are recognized.
+ *
+ * In addition, this function maps the synthetic names "gcm" /
+ * "General_Category_Mask" to the property
+ * UCHAR_GENERAL_CATEGORY_MASK.  These names are not in
+ * PropertyAliases.txt.
+ *
+ * @param alias the property name to be matched.  The name is compared
+ *         using "loose matching" as described in PropertyAliases.txt.
+ *
+ * @return a UProperty enum, or UCHAR_INVALID_CODE if the given name
+ *         does not match any property.
+ *
+ * @see UProperty
+ * @stable ICU 2.4
+ */
+U_STABLE UProperty U_EXPORT2
+u_getPropertyEnum(const char* alias);
+
+/**
+ * Return the Unicode name for a given property value, as given in the
+ * Unicode database file PropertyValueAliases.txt.
+ *
+ * Note: Some of the names in PropertyValueAliases.txt can only be
+ * retrieved using UCHAR_GENERAL_CATEGORY_MASK, not
+ * UCHAR_GENERAL_CATEGORY.  These include: "C" / "Other", "L" /
+ * "Letter", "LC" / "Cased_Letter", "M" / "Mark", "N" / "Number", "P"
+ * / "Punctuation", "S" / "Symbol", and "Z" / "Separator".
+ *
+ * @param property UProperty selector constant.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT
+ *        or UCHAR_INT_START<=which<UCHAR_INT_LIMIT
+ *        or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT.
+ *        If out of range, NULL is returned.
+ *
+ * @param value selector for a value for the given property.  If out
+ *         of range, NULL is returned.  In general, valid values range
+ *         from 0 up to some maximum.  There are a few exceptions:
+ *         (1.) UCHAR_BLOCK values begin at the non-zero value
+ *         UBLOCK_BASIC_LATIN.  (2.)  UCHAR_CANONICAL_COMBINING_CLASS
+ *         values are not contiguous and range from 0..240.  (3.)
+ *         UCHAR_GENERAL_CATEGORY_MASK values are not values of
+ *         UCharCategory, but rather mask values produced by
+ *         U_GET_GC_MASK().  This allows grouped categories such as
+ *         [:L:] to be represented.  Mask values range
+ *         non-contiguously from 1..U_GC_P_MASK.
+ *
+ * @param nameChoice selector for which name to get.  If out of range,
+ *         NULL is returned.  All values have a long name.  Most have
+ *         a short name, but some do not.  Unicode allows for
+ *         additional names; if present these will be returned by
+ *         U_LONG_PROPERTY_NAME + i, where i=1, 2,...
+
+ * @return a pointer to the name, or NULL if either the
+ *         property or the nameChoice is out of range.  If a given
+ *         nameChoice returns NULL, then all larger values of
+ *         nameChoice will return NULL, with one exception: if NULL is
+ *         returned for U_SHORT_PROPERTY_NAME, then
+ *         U_LONG_PROPERTY_NAME (and higher) may still return a
+ *         non-NULL value.  The returned pointer is valid until
+ *         u_cleanup() is called.
+ *
+ * @see UProperty
+ * @see UPropertyNameChoice
+ * @stable ICU 2.4
+ */
+U_STABLE const char* U_EXPORT2
+u_getPropertyValueName(UProperty property,
+                       int32_t value,
+                       UPropertyNameChoice nameChoice);
+
+/**
+ * Return the property value integer for a given value name, as
+ * specified in the Unicode database file PropertyValueAliases.txt.
+ * Short, long, and any other variants are recognized.
+ *
+ * Note: Some of the names in PropertyValueAliases.txt will only be
+ * recognized with UCHAR_GENERAL_CATEGORY_MASK, not
+ * UCHAR_GENERAL_CATEGORY.  These include: "C" / "Other", "L" /
+ * "Letter", "LC" / "Cased_Letter", "M" / "Mark", "N" / "Number", "P"
+ * / "Punctuation", "S" / "Symbol", and "Z" / "Separator".
+ *
+ * @param property UProperty selector constant.
+ *        Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT
+ *        or UCHAR_INT_START<=which<UCHAR_INT_LIMIT
+ *        or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT.
+ *        If out of range, UCHAR_INVALID_CODE is returned.
+ *
+ * @param alias the value name to be matched.  The name is compared
+ *         using "loose matching" as described in
+ *         PropertyValueAliases.txt.
+ *
+ * @return a value integer or UCHAR_INVALID_CODE if the given name
+ *         does not match any value of the given property, or if the
+ *         property is invalid.  Note: U CHAR_GENERAL_CATEGORY values
+ *         are not values of UCharCategory, but rather mask values
+ *         produced by U_GET_GC_MASK().  This allows grouped
+ *         categories such as [:L:] to be represented.
+ *
+ * @see UProperty
+ * @stable ICU 2.4
+ */
+U_STABLE int32_t U_EXPORT2
+u_getPropertyValueEnum(UProperty property,
+                       const char* alias);
+
+/**
+ * Determines if the specified character is permissible as the
+ * first character in an identifier according to Unicode
+ * (The Unicode Standard, Version 3.0, chapter 5.16 Identifiers).
+ * True for characters with general categories "L" (letters) and "Nl" (letter numbers).
+ *
+ * Same as java.lang.Character.isUnicodeIdentifierStart().
+ * Same as UCHAR_ID_START
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point may start an identifier
+ *
+ * @see UCHAR_ID_START
+ * @see u_isalpha
+ * @see u_isIDPart
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isIDStart(UChar32 c);
+
+/**
+ * Determines if the specified character is permissible
+ * in an identifier according to Java.
+ * True for characters with general categories "L" (letters),
+ * "Nl" (letter numbers), "Nd" (decimal digits),
+ * "Mc" and "Mn" (combining marks), "Pc" (connecting punctuation), and
+ * u_isIDIgnorable(c).
+ *
+ * Same as java.lang.Character.isUnicodeIdentifierPart().
+ * Almost the same as Unicode's ID_Continue (UCHAR_ID_CONTINUE)
+ * except that Unicode recommends to ignore Cf which is less than
+ * u_isIDIgnorable(c).
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point may occur in an identifier according to Java
+ *
+ * @see UCHAR_ID_CONTINUE
+ * @see u_isIDStart
+ * @see u_isIDIgnorable
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isIDPart(UChar32 c);
+
+/**
+ * Determines if the specified character should be regarded
+ * as an ignorable character in an identifier,
+ * according to Java.
+ * True for characters with general category "Cf" (format controls) as well as
+ * non-whitespace ISO controls
+ * (U+0000..U+0008, U+000E..U+001B, U+007F..U+0084, U+0086..U+009F).
+ *
+ * Same as java.lang.Character.isIdentifierIgnorable()
+ * except that Java also returns TRUE for U+0085 Next Line
+ * (it omits U+0085 from whitespace ISO controls).
+ *
+ * Note that Unicode just recommends to ignore Cf (format controls).
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point is ignorable in identifiers according to Java
+ *
+ * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT
+ * @see u_isIDStart
+ * @see u_isIDPart
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isIDIgnorable(UChar32 c);
+
+/**
+ * Determines if the specified character is permissible as the
+ * first character in a Java identifier.
+ * In addition to u_isIDStart(c), true for characters with
+ * general categories "Sc" (currency symbols) and "Pc" (connecting punctuation).
+ *
+ * Same as java.lang.Character.isJavaIdentifierStart().
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point may start a Java identifier
+ *
+ * @see     u_isJavaIDPart
+ * @see     u_isalpha
+ * @see     u_isIDStart
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isJavaIDStart(UChar32 c);
+
+/**
+ * Determines if the specified character is permissible
+ * in a Java identifier.
+ * In addition to u_isIDPart(c), true for characters with
+ * general category "Sc" (currency symbols).
+ *
+ * Same as java.lang.Character.isJavaIdentifierPart().
+ *
+ * @param c the code point to be tested
+ * @return TRUE if the code point may occur in a Java identifier
+ *
+ * @see     u_isIDIgnorable
+ * @see     u_isJavaIDStart
+ * @see     u_isalpha
+ * @see     u_isdigit
+ * @see     u_isIDPart
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+u_isJavaIDPart(UChar32 c);
+
+/**
+ * The given character is mapped to its lowercase equivalent according to
+ * UnicodeData.txt; if the character has no lowercase equivalent, the character
+ * itself is returned.
+ *
+ * Same as java.lang.Character.toLowerCase().
+ *
+ * This function only returns the simple, single-code point case mapping.
+ * Full case mappings should be used whenever possible because they produce
+ * better results by working on whole strings.
+ * They take into account the string context and the language and can map
+ * to a result string with a different length as appropriate.
+ * Full case mappings are applied by the string case mapping functions,
+ * see ustring.h and the UnicodeString class.
+ * See also the User Guide chapter on C/POSIX migration:
+ * http://icu.sourceforge.net/userguide/posix.html#case_mappings
+ *
+ * @param c the code point to be mapped
+ * @return the Simple_Lowercase_Mapping of the code point, if any;
+ *         otherwise the code point itself.
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_tolower(UChar32 c);
+
+/**
+ * The given character is mapped to its uppercase equivalent according to UnicodeData.txt;
+ * if the character has no uppercase equivalent, the character itself is
+ * returned.
+ *
+ * Same as java.lang.Character.toUpperCase().
+ *
+ * This function only returns the simple, single-code point case mapping.
+ * Full case mappings should be used whenever possible because they produce
+ * better results by working on whole strings.
+ * They take into account the string context and the language and can map
+ * to a result string with a different length as appropriate.
+ * Full case mappings are applied by the string case mapping functions,
+ * see ustring.h and the UnicodeString class.
+ * See also the User Guide chapter on C/POSIX migration:
+ * http://icu.sourceforge.net/userguide/posix.html#case_mappings
+ *
+ * @param c the code point to be mapped
+ * @return the Simple_Uppercase_Mapping of the code point, if any;
+ *         otherwise the code point itself.
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_toupper(UChar32 c);
+
+/**
+ * The given character is mapped to its titlecase equivalent
+ * according to UnicodeData.txt;
+ * if none is defined, the character itself is returned.
+ *
+ * Same as java.lang.Character.toTitleCase().
+ *
+ * This function only returns the simple, single-code point case mapping.
+ * Full case mappings should be used whenever possible because they produce
+ * better results by working on whole strings.
+ * They take into account the string context and the language and can map
+ * to a result string with a different length as appropriate.
+ * Full case mappings are applied by the string case mapping functions,
+ * see ustring.h and the UnicodeString class.
+ * See also the User Guide chapter on C/POSIX migration:
+ * http://icu.sourceforge.net/userguide/posix.html#case_mappings
+ *
+ * @param c the code point to be mapped
+ * @return the Simple_Titlecase_Mapping of the code point, if any;
+ *         otherwise the code point itself.
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_totitle(UChar32 c);
+
+/** Option value for case folding: use default mappings defined in CaseFolding.txt. @stable ICU 2.0 */
+#define U_FOLD_CASE_DEFAULT 0
+
+/**
+ * Option value for case folding:
+ *
+ * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I
+ * and dotless i appropriately for Turkic languages (tr, az).
+ *
+ * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that
+ * are to be included for default mappings and
+ * excluded for the Turkic-specific mappings.
+ *
+ * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that
+ * are to be excluded for default mappings and
+ * included for the Turkic-specific mappings.
+ *
+ * @stable ICU 2.0
+ */
+#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1
+
+/**
+ * The given character is mapped to its case folding equivalent according to
+ * UnicodeData.txt and CaseFolding.txt;
+ * if the character has no case folding equivalent, the character
+ * itself is returned.
+ *
+ * This function only returns the simple, single-code point case mapping.
+ * Full case mappings should be used whenever possible because they produce
+ * better results by working on whole strings.
+ * They take into account the string context and the language and can map
+ * to a result string with a different length as appropriate.
+ * Full case mappings are applied by the string case mapping functions,
+ * see ustring.h and the UnicodeString class.
+ * See also the User Guide chapter on C/POSIX migration:
+ * http://icu.sourceforge.net/userguide/posix.html#case_mappings
+ *
+ * @param c the code point to be mapped
+ * @param options Either U_FOLD_CASE_DEFAULT or U_FOLD_CASE_EXCLUDE_SPECIAL_I
+ * @return the Simple_Case_Folding of the code point, if any;
+ *         otherwise the code point itself.
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_foldCase(UChar32 c, uint32_t options);
+
+/**
+ * Returns the decimal digit value of the code point in the
+ * specified radix.
+ *
+ * If the radix is not in the range <code>2<=radix<=36</code> or if the
+ * value of <code>c</code> is not a valid digit in the specified
+ * radix, <code>-1</code> is returned. A character is a valid digit
+ * if at least one of the following is true:
+ * <ul>
+ * <li>The character has a decimal digit value.
+ *     Such characters have the general category "Nd" (decimal digit numbers)
+ *     and a Numeric_Type of Decimal.
+ *     In this case the value is the character's decimal digit value.</li>
+ * <li>The character is one of the uppercase Latin letters
+ *     <code>'A'</code> through <code>'Z'</code>.
+ *     In this case the value is <code>c-'A'+10</code>.</li>
+ * <li>The character is one of the lowercase Latin letters
+ *     <code>'a'</code> through <code>'z'</code>.
+ *     In this case the value is <code>ch-'a'+10</code>.</li>
+ * <li>Latin letters from both the ASCII range (0061..007A, 0041..005A)
+ *     as well as from the Fullwidth ASCII range (FF41..FF5A, FF21..FF3A)
+ *     are recognized.</li>
+ * </ul>
+ *
+ * Same as java.lang.Character.digit().
+ *
+ * @param   ch      the code point to be tested.
+ * @param   radix   the radix.
+ * @return  the numeric value represented by the character in the
+ *          specified radix,
+ *          or -1 if there is no value or if the value exceeds the radix.
+ *
+ * @see     UCHAR_NUMERIC_TYPE
+ * @see     u_forDigit
+ * @see     u_charDigitValue
+ * @see     u_isdigit
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+u_digit(UChar32 ch, int8_t radix);
+
+/**
+ * Determines the character representation for a specific digit in
+ * the specified radix. If the value of <code>radix</code> is not a
+ * valid radix, or the value of <code>digit</code> is not a valid
+ * digit in the specified radix, the null character
+ * (<code>U+0000</code>) is returned.
+ * <p>
+ * The <code>radix</code> argument is valid if it is greater than or
+ * equal to 2 and less than or equal to 36.
+ * The <code>digit</code> argument is valid if
+ * <code>0 <= digit < radix</code>.
+ * <p>
+ * If the digit is less than 10, then
+ * <code>'0' + digit</code> is returned. Otherwise, the value
+ * <code>'a' + digit - 10</code> is returned.
+ *
+ * Same as java.lang.Character.forDigit().
+ *
+ * @param   digit   the number to convert to a character.
+ * @param   radix   the radix.
+ * @return  the <code>char</code> representation of the specified digit
+ *          in the specified radix.
+ *
+ * @see     u_digit
+ * @see     u_charDigitValue
+ * @see     u_isdigit
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+u_forDigit(int32_t digit, int8_t radix);
+
+/**
+ * Get the "age" of the code point.
+ * The "age" is the Unicode version when the code point was first
+ * designated (as a non-character or for Private Use)
+ * or assigned a character.
+ * This can be useful to avoid emitting code points to receiving
+ * processes that do not accept newer characters.
+ * The data is from the UCD file DerivedAge.txt.
+ *
+ * @param c The code point.
+ * @param versionArray The Unicode version number array, to be filled in.
+ *
+ * @stable ICU 2.1
+ */
+U_STABLE void U_EXPORT2
+u_charAge(UChar32 c, UVersionInfo versionArray);
+
+/**
+ * Gets the Unicode version information.
+ * The version array is filled in with the version information
+ * for the Unicode standard that is currently used by ICU.
+ * For example, Unicode version 3.1.1 is represented as an array with
+ * the values { 3, 1, 1, 0 }.
+ *
+ * @param versionArray an output array that will be filled in with
+ *                     the Unicode version number
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+u_getUnicodeVersion(UVersionInfo versionArray);
+
+/**
+ * Get the FC_NFKC_Closure property string for a character.
+ * See Unicode Standard Annex #15 for details, search for "FC_NFKC_Closure"
+ * or for "FNC": http://www.unicode.org/reports/tr15/
+ *
+ * @param c The character (code point) for which to get the FC_NFKC_Closure string.
+ *             It must be <code>0<=c<=0x10ffff</code>.
+ * @param dest Destination address for copying the string.
+ *             The string will be zero-terminated if possible.
+ *             If there is no FC_NFKC_Closure string,
+ *             then the buffer will be set to the empty string.
+ * @param destCapacity <code>==sizeof(dest)</code>
+ * @param pErrorCode Pointer to a UErrorCode variable.
+ * @return The length of the string, or 0 if there is no FC_NFKC_Closure string for this character.
+ *         If the destCapacity is less than or equal to the length, then the buffer
+ *         contains the truncated name and the returned length indicates the full
+ *         length of the name.
+ *         The length does not include the zero-termination.
+ *
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+u_getFC_NFKC_Closure(UChar32 c, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode);
+
+U_CDECL_END
+
+#endif /*_UCHAR*/
+/*eof*/

Added: MacRuby/branches/icu/unicode/uchriter.h
===================================================================
--- MacRuby/branches/icu/unicode/uchriter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uchriter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,381 @@
+/*
+**********************************************************************
+*   Copyright (C) 1998-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#ifndef UCHRITER_H
+#define UCHRITER_H
+
+#include "unicode/utypes.h"
+#include "unicode/chariter.h"
+
+/**
+ * \file 
+ * \brief C++ API: UChar Character Iterator
+ */
+ 
+U_NAMESPACE_BEGIN
+
+/**
+ * A concrete subclass of CharacterIterator that iterates over the
+ * characters (code units or code points) in a UChar array.
+ * It's possible not only to create an
+ * iterator that iterates over an entire UChar array, but also to
+ * create one that iterates over only a subrange of a UChar array
+ * (iterators over different subranges of the same UChar array don't
+ * compare equal).
+ * @see CharacterIterator
+ * @see ForwardCharacterIterator
+ * @stable ICU 2.0
+ */
+class U_COMMON_API UCharCharacterIterator : public CharacterIterator {
+public:
+  /**
+   * Create an iterator over the UChar array referred to by "textPtr".
+   * The iteration range is 0 to <code>length-1</code>.
+   * text is only aliased, not adopted (the
+   * destructor will not delete it).
+   * @param textPtr The UChar array to be iterated over
+   * @param length The length of the UChar array
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator(const UChar* textPtr, int32_t length);
+
+  /**
+   * Create an iterator over the UChar array referred to by "textPtr".
+   * The iteration range is 0 to <code>length-1</code>.
+   * text is only aliased, not adopted (the
+   * destructor will not delete it).
+   * The starting
+   * position is specified by "position". If "position" is outside the valid
+   * iteration range, the behavior of this object is undefined.
+   * @param textPtr The UChar array to be iteratd over
+   * @param length The length of the UChar array
+   * @param position The starting position of the iteration
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator(const UChar* textPtr, int32_t length,
+                         int32_t position);
+
+  /**
+   * Create an iterator over the UChar array referred to by "textPtr".
+   * The iteration range is 0 to <code>end-1</code>.
+   * text is only aliased, not adopted (the
+   * destructor will not delete it).
+   * The starting
+   * position is specified by "position". If begin and end do not
+   * form a valid iteration range or "position" is outside the valid
+   * iteration range, the behavior of this object is undefined.
+   * @param textPtr The UChar array to be iterated over
+   * @param length The length of the UChar array
+   * @param textBegin  The begin position of the iteration range
+   * @param textEnd    The end position of the iteration range
+   * @param position    The starting position of the iteration
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator(const UChar* textPtr, int32_t length,
+                         int32_t textBegin,
+                         int32_t textEnd,
+                         int32_t position);
+
+  /**
+   * Copy constructor.  The new iterator iterates over the same range
+   * of the same string as "that", and its initial position is the
+   * same as "that"'s current position.
+   * @param that The UCharCharacterIterator to be copied
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator(const UCharCharacterIterator&  that);
+
+  /**
+   * Destructor.
+   * @stable ICU 2.0
+   */
+  virtual ~UCharCharacterIterator();
+
+  /**
+   * Assignment operator.  *this is altered to iterate over the sane
+   * range of the same string as "that", and refers to the same
+   * character within that string as "that" does.
+   * @param that The object to be copied
+   * @return the newly created object
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator&
+  operator=(const UCharCharacterIterator&    that);
+
+  /**
+   * Returns true if the iterators iterate over the same range of the
+   * same string and are pointing at the same character.
+   * @param that The ForwardCharacterIterator used to be compared for equality
+   * @return true if the iterators iterate over the same range of the
+   * same string and are pointing at the same character.
+   * @stable ICU 2.0
+   */
+  virtual UBool          operator==(const ForwardCharacterIterator& that) const;
+
+  /**
+   * Generates a hash code for this iterator.
+   * @return the hash code.
+   * @stable ICU 2.0
+   */
+  virtual int32_t         hashCode(void) const;
+
+  /**
+   * Returns a new UCharCharacterIterator referring to the same
+   * character in the same range of the same string as this one.  The
+   * caller must delete the new iterator.
+   * @return the CharacterIterator newly created
+   * @stable ICU 2.0
+   */
+  virtual CharacterIterator* clone(void) const;
+
+  /**
+   * Sets the iterator to refer to the first code unit in its
+   * iteration range, and returns that code unit.
+   * This can be used to begin an iteration with next().
+   * @return the first code unit in its iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar         first(void);
+
+  /**
+   * Sets the iterator to refer to the first code unit in its
+   * iteration range, returns that code unit, and moves the position
+   * to the second code unit. This is an alternative to setToStart()
+   * for forward iteration with nextPostInc().
+   * @return the first code unit in its iteration range
+   * @stable ICU 2.0
+   */
+  virtual UChar         firstPostInc(void);
+
+  /**
+   * Sets the iterator to refer to the first code point in its
+   * iteration range, and returns that code unit,
+   * This can be used to begin an iteration with next32().
+   * Note that an iteration with next32PostInc(), beginning with,
+   * e.g., setToStart() or firstPostInc(), is more efficient.
+   * @return the first code point in its iteration range
+   * @stable ICU 2.0
+   */
+  virtual UChar32       first32(void);
+
+  /**
+   * Sets the iterator to refer to the first code point in its
+   * iteration range, returns that code point, and moves the position
+   * to the second code point. This is an alternative to setToStart()
+   * for forward iteration with next32PostInc().
+   * @return the first code point in its iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       first32PostInc(void);
+
+  /**
+   * Sets the iterator to refer to the last code unit in its
+   * iteration range, and returns that code unit.
+   * This can be used to begin an iteration with previous().
+   * @return the last code unit in its iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar         last(void);
+
+  /**
+   * Sets the iterator to refer to the last code point in its
+   * iteration range, and returns that code unit.
+   * This can be used to begin an iteration with previous32().
+   * @return the last code point in its iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       last32(void);
+
+  /**
+   * Sets the iterator to refer to the "position"-th code unit
+   * in the text-storage object the iterator refers to, and
+   * returns that code unit.
+   * @param position the position within the text-storage object
+   * @return the code unit
+   * @stable ICU 2.0
+   */
+  virtual UChar         setIndex(int32_t position);
+
+  /**
+   * Sets the iterator to refer to the beginning of the code point
+   * that contains the "position"-th code unit
+   * in the text-storage object the iterator refers to, and
+   * returns that code point.
+   * The current position is adjusted to the beginning of the code point
+   * (its first code unit).
+   * @param position the position within the text-storage object
+   * @return the code unit
+   * @stable ICU 2.0
+   */
+  virtual UChar32       setIndex32(int32_t position);
+
+  /**
+   * Returns the code unit the iterator currently refers to.
+   * @return the code unit the iterator currently refers to.
+   * @stable ICU 2.0
+   */
+  virtual UChar         current(void) const;
+
+  /**
+   * Returns the code point the iterator currently refers to.
+   * @return the code point the iterator currently refers to.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       current32(void) const;
+
+  /**
+   * Advances to the next code unit in the iteration range (toward
+   * endIndex()), and returns that code unit.  If there are no more
+   * code units to return, returns DONE.
+   * @return the next code unit in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar         next(void);
+
+  /**
+   * Gets the current code unit for returning and advances to the next code unit
+   * in the iteration range
+   * (toward endIndex()).  If there are
+   * no more code units to return, returns DONE.
+   * @return the current code unit.
+   * @stable ICU 2.0
+   */
+  virtual UChar         nextPostInc(void);
+
+  /**
+   * Advances to the next code point in the iteration range (toward
+   * endIndex()), and returns that code point.  If there are no more
+   * code points to return, returns DONE.
+   * Note that iteration with "pre-increment" semantics is less
+   * efficient than iteration with "post-increment" semantics
+   * that is provided by next32PostInc().
+   * @return the next code point in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       next32(void);
+
+  /**
+   * Gets the current code point for returning and advances to the next code point
+   * in the iteration range
+   * (toward endIndex()).  If there are
+   * no more code points to return, returns DONE.
+   * @return the current point.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       next32PostInc(void);
+
+  /**
+   * Returns FALSE if there are no more code units or code points
+   * at or after the current position in the iteration range.
+   * This is used with nextPostInc() or next32PostInc() in forward
+   * iteration.
+   * @return FALSE if there are no more code units or code points
+   * at or after the current position in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UBool        hasNext();
+
+  /**
+   * Advances to the previous code unit in the iteration range (toward
+   * startIndex()), and returns that code unit.  If there are no more
+   * code units to return, returns DONE.
+   * @return the previous code unit in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar         previous(void);
+
+  /**
+   * Advances to the previous code point in the iteration range (toward
+   * startIndex()), and returns that code point.  If there are no more
+   * code points to return, returns DONE.
+   * @return the previous code point in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UChar32       previous32(void);
+
+  /**
+   * Returns FALSE if there are no more code units or code points
+   * before the current position in the iteration range.
+   * This is used with previous() or previous32() in backward
+   * iteration.
+   * @return FALSE if there are no more code units or code points
+   * before the current position in the iteration range.
+   * @stable ICU 2.0
+   */
+  virtual UBool        hasPrevious();
+
+  /**
+   * Moves the current position relative to the start or end of the
+   * iteration range, or relative to the current position itself.
+   * The movement is expressed in numbers of code units forward
+   * or backward by specifying a positive or negative delta.
+   * @param delta the position relative to origin. A positive delta means forward;
+   * a negative delta means backward.
+   * @param origin Origin enumeration {kStart, kCurrent, kEnd}
+   * @return the new position
+   * @stable ICU 2.0
+   */
+  virtual int32_t      move(int32_t delta, EOrigin origin);
+
+  /**
+   * Moves the current position relative to the start or end of the
+   * iteration range, or relative to the current position itself.
+   * The movement is expressed in numbers of code points forward
+   * or backward by specifying a positive or negative delta.
+   * @param delta the position relative to origin. A positive delta means forward;
+   * a negative delta means backward.
+   * @param origin Origin enumeration {kStart, kCurrent, kEnd}
+   * @return the new position
+   * @stable ICU 2.0
+   */
+  virtual int32_t      move32(int32_t delta, EOrigin origin);
+
+  /**
+   * Sets the iterator to iterate over a new range of text
+   * @stable ICU 2.0
+   */
+  void setText(const UChar* newText, int32_t newTextLength);
+
+  /**
+   * Copies the UChar array under iteration into the UnicodeString
+   * referred to by "result".  Even if this iterator iterates across
+   * only a part of this string, the whole string is copied.
+   * @param result Receives a copy of the text under iteration.
+   * @stable ICU 2.0
+   */
+  virtual void            getText(UnicodeString& result);
+
+  /**
+   * Return a class ID for this class (not really public)
+   * @return a class ID for this class
+   * @stable ICU 2.0
+   */
+  static UClassID         U_EXPORT2 getStaticClassID(void);
+
+  /**
+   * Return a class ID for this object (not really public)
+   * @return a class ID for this object.
+   * @stable ICU 2.0
+   */
+  virtual UClassID        getDynamicClassID(void) const;
+
+protected:
+  /**
+   * Protected constructor
+   * @stable ICU 2.0
+   */
+  UCharCharacterIterator();
+  /**
+   * Protected member text
+   * @stable ICU 2.0
+   */
+  const UChar*            text;
+
+};
+
+U_NAMESPACE_END
+#endif

Added: MacRuby/branches/icu/unicode/uclean.h
===================================================================
--- MacRuby/branches/icu/unicode/uclean.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uclean.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,267 @@
+/*
+******************************************************************************
+*                                                                            *
+* Copyright (C) 2001-2005, International Business Machines                   *
+*                Corporation and others. All Rights Reserved.                *
+*                                                                            *
+******************************************************************************
+*   file name:  uclean.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001July05
+*   created by: George Rhoten
+*/
+
+#ifndef __UCLEAN_H__
+#define __UCLEAN_H__
+
+#include "unicode/utypes.h"
+/**
+ * \file
+ * \brief C API: Initialize and clean up ICU
+ */
+ 
+/**
+ *  Initialize ICU. The description further below applies to ICU 2.6 to ICU 3.4.
+ *  Starting with ICU 3.4, u_init() needs not be called any more for
+ *  ensuring thread safety, but it can give an indication for whether ICU
+ *  can load its data. In ICU 3.4, it will try to load the converter alias table
+ *  (cnvalias.icu) and give an error code if that fails.
+ *  This may change in the future.
+ *  <p>
+ *  For ensuring the availability of necessary data, an application should
+ *  open the service objects (converters, collators, etc.) that it will use
+ *  and check for error codes there.
+ *  <p>
+ *  Documentation for ICU 2.6 to ICU 3.4:
+ *  <p>
+ *  This function loads and initializes data items
+ *  that are required internally by various ICU functions.  Use of this explicit
+ *  initialization is required in multi-threaded applications; in 
+ *  single threaded apps, use is optional, but incurs little additional
+ *  cost, and is thus recommended.
+ *  <p>
+ *  In multi-threaded applications, u_init() should be called  in the
+ *  main thread before starting additional threads, or, alternatively
+ *  it can be called in each individual thread once, before other ICU
+ *  functions are called in that thread.  In this second scenario, the
+ *  application must guarantee that the first call to u_init() happen
+ *  without contention, in a single thread only.
+ *  <p>
+ *  If <code>u_setMemoryFunctions()</code> or 
+ *  <code>u_setMutexFunctions</code> are needed (uncommon), they must be
+ *  called _before_ <code>u_init()</code>.
+ *  <p>
+ *  Extra, repeated, or otherwise unneeded calls to u_init() do no harm,
+ *  other than taking a small amount of time.
+ *
+ * @param status An ICU UErrorCode parameter. It must not be <code>NULL</code>.
+ *    An Error will be returned if some required part of ICU data can not
+ *    be loaded or initialized.
+ *    The function returns immediately if the input error code indicates a
+ *    failure, as usual.
+ *
+ * @stable ICU 2.6
+ */  
+U_STABLE void U_EXPORT2 
+u_init(UErrorCode *status);
+
+/**
+ * Clean up the system resources, such as allocated memory or open files,
+ * used in all ICU libraries. This will free/delete all memory owned by the
+ * ICU libraries, and return them to their original load state. All open ICU
+ * items (collators, resource bundles, converters, etc.) must be closed before
+ * calling this function, otherwise ICU may not free its allocated memory
+ * (e.g. close your converters and resource bundles before calling this
+ * function). Generally, this function should be called once just before
+ * an application exits. For applications that dynamically load and unload
+ * the ICU libraries (relatively uncommon), u_cleanup() should be called
+ * just before the library unload.
+ * <p>
+ * u_cleanup() also clears any ICU heap functions, mutex functions or
+ * trace functions that may have been set for the process.  
+ * This has the effect of restoring ICU to its initial condition, before
+ * any of these override functions were installed.  Refer to
+ * u_setMemoryFunctions(), u_setMutexFunctions and 
+ * utrace_setFunctions().  If ICU is to be reinitialized after after
+ * calling u_cleanup(), these runtime override functions will need to
+ * be set up again if they are still required.
+ * <p>
+ * u_cleanup() is not thread safe.  All other threads should stop using ICU
+ * before calling this function.
+ * <p>
+ * Any open ICU items will be left in an undefined state by u_cleanup(),
+ * and any subsequent attempt to use such an item will give unpredictable
+ * results.
+ * <p>
+ * After calling u_cleanup(), an application may continue to use ICU by
+ * calling u_init().  An application must invoke u_init() first from one single
+ * thread before allowing other threads call u_init().  All threads existing
+ * at the time of the first thread's call to u_init() must also call
+ * u_init() themselves before continuing with other ICU operations.  
+ * <p>
+ * The use of u_cleanup() just before an application terminates is optional,
+ * but it should be called only once for performance reasons. The primary
+ * benefit is to eliminate reports of memory or resource leaks originating
+ * in ICU code from the results generated by heap analysis tools.
+ * <p>
+ * <strong>Use this function with great care!</strong>
+ * </p>
+ *
+ * @stable ICU 2.0
+ * @system
+ */
+U_STABLE void U_EXPORT2 
+u_cleanup(void);
+
+
+
+
+/**
+  * An opaque pointer type that represents an ICU mutex.
+  * For user-implemented mutexes, the value will typically point to a
+  *  struct or object that implements the mutex.
+  * @stable ICU 2.8
+  * @system
+  */
+typedef void *UMTX;
+
+/**
+  *  Function Pointer type for a user supplied mutex initialization function.
+  *  The user-supplied function will be called by ICU whenever ICU needs to create a
+  *  new mutex.  The function implementation should create a mutex, and store a pointer
+  *  to something that uniquely identifies the mutex into the UMTX that is supplied
+  *  as a paramter.
+  *  @param context user supplied value, obtained from from u_setMutexFunctions().
+  *  @param mutex   Receives a pointer that identifies the new mutex.
+  *                 The mutex init function must set the UMTX to a non-null value.   
+  *                 Subsequent calls by ICU to lock, unlock, or destroy a mutex will 
+  *                 identify the mutex by the UMTX value.
+  *  @param status  Error status.  Report errors back to ICU by setting this variable
+  *                 with an error code.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX  *mutex, UErrorCode* status);
+
+
+/**
+  *  Function Pointer type for a user supplied mutex functions.
+  *  One of the  user-supplied functions with this signature will be called by ICU
+  *  whenever ICU needs to lock, unlock, or destroy a mutex.
+  *  @param context user supplied value, obtained from from u_setMutexFunctions().
+  *  @param mutex   specify the mutex on which to operate.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void U_CALLCONV UMtxFn   (const void *context, UMTX  *mutex);
+
+
+/**
+  *  Set the functions that ICU will use for mutex operations
+  *  Use of this function is optional; by default (without this function), ICU will
+  *  directly access system functions for mutex operations
+  *  This function can only be used when ICU is in an initial, unused state, before
+  *  u_init() has been called.
+  *  This function may be used even when ICU has been built without multi-threaded
+  *  support  (see ICU_USE_THREADS pre-processor variable, umutex.h)
+  *  @param context This pointer value will be saved, and then (later) passed as
+  *                 a parameter to the user-supplied mutex functions each time they
+  *                 are called. 
+  *  @param init    Pointer to a mutex initialization function.  Must be non-null.
+  *  @param destroy Pointer to the mutex destroy function.  Must be non-null.
+  *  @param lock    pointer to the mutex lock function.  Must be non-null.
+  *  @param unlock  Pointer to the mutex unlock function.  Must be non-null.
+  *  @param status  Receives error values.
+  *  @stable ICU 2.8
+  *  @system
+  */  
+U_STABLE void U_EXPORT2 
+u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
+                    UErrorCode *status);
+
+
+/**
+  *  Pointer type for a user supplied atomic increment or decrement function.
+  *  @param context user supplied value, obtained from from u_setAtomicIncDecFunctions().
+  *  @param p   Pointer to a 32 bit int to be incremented or decremented
+  *  @return    The value of the variable after the inc or dec operation.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
+
+/**
+ *  Set the functions that ICU will use for atomic increment and decrement of int32_t values.
+ *  Use of this function is optional; by default (without this function), ICU will
+ *  use its own internal implementation of atomic increment/decrement.
+ *  This function can only be used when ICU is in an initial, unused state, before
+ *  u_init() has been called.
+ *  @param context This pointer value will be saved, and then (later) passed as
+ *                 a parameter to the increment and decrement functions each time they
+ *                 are called.  This function can only be called 
+ *  @param inc     Pointer to a function to do an atomic increment operation.  Must be non-null.
+ *  @param dec     Pointer to a function to do an atomic decrement operation.  Must be non-null.
+ *  @param status  Receives error values.
+ *  @stable ICU 2.8
+ *  @system
+ */  
+U_STABLE void U_EXPORT2 
+u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec,
+                    UErrorCode *status);
+
+
+
+/**
+  *  Pointer type for a user supplied memory allocation function.
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param size    The number of bytes to be allocated
+  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size);
+/**
+  *  Pointer type for a user supplied memory re-allocation function.
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param size    The number of bytes to be allocated
+  *  @return        Pointer to the newly allocated memory, or NULL if the allocation failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void *U_CALLCONV UMemReallocFn(const void *context, void *mem, size_t size);
+/**
+  *  Pointer type for a user supplied memory free  function.  Behavior should be
+  *  similar the standard C library free().
+  *  @param context user supplied value, obtained from from u_setMemoryFunctions().
+  *  @param mem     Pointer to the memory block to be resized
+  *  @param size    The new size for the block
+  *  @return        Pointer to the resized memory block, or NULL if the resizing failed.
+  *  @stable ICU 2.8
+  *  @system
+  */
+typedef void  U_CALLCONV UMemFreeFn (const void *context, void *mem);
+
+/**
+ *  Set the functions that ICU will use for memory allocation.
+ *  Use of this function is optional; by default (without this function), ICU will
+ *  use the standard C library malloc() and free() functions.
+ *  This function can only be used when ICU is in an initial, unused state, before
+ *  u_init() has been called.
+ *  @param context This pointer value will be saved, and then (later) passed as
+ *                 a parameter to the memory functions each time they
+ *                 are called.
+ *  @param a       Pointer to a user-supplied malloc function.
+ *  @param r       Pointer to a user-supplied realloc function.
+ *  @param f       Pointer to a user-supplied free function.
+ *  @param status  Receives error values.
+ *  @stable ICU 2.8
+ *  @system
+ */  
+U_STABLE void U_EXPORT2 
+u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, 
+                    UErrorCode *status);
+
+#endif

Added: MacRuby/branches/icu/unicode/ucnv.h
===================================================================
--- MacRuby/branches/icu/unicode/ucnv.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ucnv.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,1938 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+ *  ucnv.h:
+ *  External APIs for the ICU's codeset conversion library
+ *  Bertrand A. Damiba
+ *
+ * Modification History:
+ *
+ *   Date        Name        Description
+ *   04/04/99    helena      Fixed internal header inclusion.
+ *   05/11/00    helena      Added setFallback and usesFallback APIs.
+ *   06/29/2000  helena      Major rewrite of the callback APIs.
+ *   12/07/2000  srl         Update of documentation
+ */
+
+/**
+ * \file
+ * \brief C API: Character conversion 
+ *
+ * <h2>Character Conversion C API</h2>
+ *
+ * <p>This API is used to convert codepage or character encoded data to and
+ * from UTF-16. You can open a converter with {@link ucnv_open() }. With that
+ * converter, you can get its properties, set options, convert your data and
+ * close the converter.</p>
+ *
+ * <p>Since many software programs recogize different converter names for
+ * different types of converters, there are other functions in this API to
+ * iterate over the converter aliases. The functions {@link ucnv_getAvailableName() },
+ * {@link ucnv_getAlias() } and {@link ucnv_getStandardName() } are some of the
+ * more frequently used alias functions to get this information.</p>
+ *
+ * <p>When a converter encounters an illegal, irregular, invalid or unmappable character
+ * its default behavior is to use a substitution character to replace the
+ * bad byte sequence. This behavior can be changed by using {@link ucnv_setFromUCallBack() }
+ * or {@link ucnv_setToUCallBack() } on the converter. The header ucnv_err.h defines
+ * many other callback actions that can be used instead of a character substitution.</p>
+ *
+ * <p>More information about this API can be found in our 
+ * <a href="http://icu.sourceforge.net/userguide/conversion.html">User's
+ * Guide</a>.</p>
+ */
+
+#ifndef UCNV_H
+#define UCNV_H
+
+#include "unicode/ucnv_err.h"
+#include "unicode/uenum.h"
+
+#ifndef __USET_H__
+
+/**
+ * USet is the C API type for Unicode sets.
+ * It is forward-declared here to avoid including the header file if related
+ * conversion APIs are not used.
+ * See unicode/uset.h
+ *
+ * @see ucnv_getUnicodeSet
+ * @stable ICU 2.6
+ */
+struct USet;
+/** @stable ICU 2.6 */
+typedef struct USet USet;
+
+#endif
+
+#if !UCONFIG_NO_CONVERSION
+
+U_CDECL_BEGIN
+
+/** Maximum length of a converter name including the terminating NULL @stable ICU 2.0 */
+#define UCNV_MAX_CONVERTER_NAME_LENGTH 60
+/** Maximum length of a converter name including path and terminating NULL @stable ICU 2.0 */
+#define UCNV_MAX_FULL_FILE_NAME_LENGTH (600+UCNV_MAX_CONVERTER_NAME_LENGTH)
+
+/** Shift in for EBDCDIC_STATEFUL and iso2022 states @stable ICU 2.0 */
+#define  UCNV_SI 0x0F
+/** Shift out for EBDCDIC_STATEFUL and iso2022 states @stable ICU 2.0 */
+#define  UCNV_SO 0x0E
+
+/**
+ * Enum for specifying basic types of converters
+ * @see ucnv_getType
+ * @stable ICU 2.0
+ */
+typedef enum {
+    UCNV_UNSUPPORTED_CONVERTER = -1,
+    UCNV_SBCS = 0,
+    UCNV_DBCS = 1,
+    UCNV_MBCS = 2,
+    UCNV_LATIN_1 = 3,
+    UCNV_UTF8 = 4,
+    UCNV_UTF16_BigEndian = 5,
+    UCNV_UTF16_LittleEndian = 6,
+    UCNV_UTF32_BigEndian = 7,
+    UCNV_UTF32_LittleEndian = 8,
+    UCNV_EBCDIC_STATEFUL = 9,
+    UCNV_ISO_2022 = 10,
+
+    UCNV_LMBCS_1 = 11,
+    UCNV_LMBCS_2, 
+    UCNV_LMBCS_3,
+    UCNV_LMBCS_4,
+    UCNV_LMBCS_5,
+    UCNV_LMBCS_6,
+    UCNV_LMBCS_8,
+    UCNV_LMBCS_11,
+    UCNV_LMBCS_16,
+    UCNV_LMBCS_17,
+    UCNV_LMBCS_18,
+    UCNV_LMBCS_19,
+    UCNV_LMBCS_LAST = UCNV_LMBCS_19,
+    UCNV_HZ,
+    UCNV_SCSU,
+    UCNV_ISCII,
+    UCNV_US_ASCII,
+    UCNV_UTF7,
+    UCNV_BOCU1,
+    UCNV_UTF16,
+    UCNV_UTF32,
+    UCNV_CESU8,
+    UCNV_IMAP_MAILBOX,
+
+    /* Number of converter types for which we have conversion routines. */
+    UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES
+
+} UConverterType;
+
+/**
+ * Enum for specifying which platform a converter ID refers to.
+ * The use of platform/CCSID is not recommended. See ucnv_openCCSID().
+ *
+ * @see ucnv_getPlatform
+ * @see ucnv_openCCSID
+ * @see ucnv_getCCSID
+ * @stable ICU 2.0
+ */
+typedef enum {
+    UCNV_UNKNOWN = -1,
+    UCNV_IBM = 0
+} UConverterPlatform;
+
+/**
+ * Function pointer for error callback in the codepage to unicode direction.
+ * Called when an error has occured in conversion to unicode, or on open/close of the callback (see reason).
+ * @param context Pointer to the callback's private data
+ * @param args Information about the conversion in progress
+ * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param reason Defines the reason the callback was invoked
+ * @param pErrorCode    ICU error code in/out parameter.
+ *                      For converter callback functions, set to a conversion error
+ *                      before the call, and the callback may reset it to U_ZERO_ERROR.
+ * @see ucnv_setToUCallBack
+ * @see UConverterToUnicodeArgs
+ * @stable ICU 2.0
+ */
+typedef void (U_EXPORT2 *UConverterToUCallback) (
+                  const void* context,
+                  UConverterToUnicodeArgs *args,
+                  const char *codeUnits,
+                  int32_t length,
+                  UConverterCallbackReason reason,
+                  UErrorCode *pErrorCode);
+
+/**
+ * Function pointer for error callback in the unicode to codepage direction.
+ * Called when an error has occured in conversion from unicode, or on open/close of the callback (see reason).
+ * @param context Pointer to the callback's private data
+ * @param args Information about the conversion in progress
+ * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint.
+ * @param reason Defines the reason the callback was invoked
+ * @param pErrorCode    ICU error code in/out parameter.
+ *                      For converter callback functions, set to a conversion error
+ *                      before the call, and the callback may reset it to U_ZERO_ERROR.
+ * @see ucnv_setFromUCallBack
+ * @stable ICU 2.0
+ */
+typedef void (U_EXPORT2 *UConverterFromUCallback) (
+                    const void* context,
+                    UConverterFromUnicodeArgs *args,
+                    const UChar* codeUnits,
+                    int32_t length,
+                    UChar32 codePoint,
+                    UConverterCallbackReason reason,
+                    UErrorCode *pErrorCode);
+
+U_CDECL_END
+
+/**
+ * Character that separates converter names from options and options from each other.
+ * @see ucnv_open
+ * @stable ICU 2.0
+ */
+#define UCNV_OPTION_SEP_CHAR ','
+
+/**
+ * String version of UCNV_OPTION_SEP_CHAR. 
+ * @see ucnv_open
+ * @stable ICU 2.0
+ */
+#define UCNV_OPTION_SEP_STRING ","
+
+/**
+ * Character that separates a converter option from its value.
+ * @see ucnv_open
+ * @stable ICU 2.0
+ */
+#define UCNV_VALUE_SEP_CHAR '='
+
+/**
+ * String version of UCNV_VALUE_SEP_CHAR. 
+ * @see ucnv_open
+ * @stable ICU 2.0
+ */
+#define UCNV_VALUE_SEP_STRING "="
+
+/**
+ * Converter option for specifying a locale.
+ * For example, ucnv_open("SCSU,locale=ja", &errorCode);
+ * See convrtrs.txt.
+ *
+ * @see ucnv_open
+ * @stable ICU 2.0
+ */
+#define UCNV_LOCALE_OPTION_STRING ",locale="
+
+/**
+ * Converter option for specifying a version selector (0..9) for some converters.
+ * For example, ucnv_open("UTF-7,version=1", &errorCode);
+ * See convrtrs.txt.
+ *
+ * @see ucnv_open
+ * @stable ICU 2.4
+ */
+#define UCNV_VERSION_OPTION_STRING ",version="
+
+/**
+ * Converter option for EBCDIC SBCS or mixed-SBCS/DBCS (stateful) codepages.
+ * Swaps Unicode mappings for EBCDIC LF and NL codes, as used on
+ * S/390 (z/OS) Unix System Services (Open Edition).
+ * For example, ucnv_open("ibm-1047,swaplfnl", &errorCode);
+ * See convrtrs.txt.
+ *
+ * @see ucnv_open
+ * @stable ICU 2.4
+ */
+#define UCNV_SWAP_LFNL_OPTION_STRING ",swaplfnl"
+
+/**
+ * Do a fuzzy compare of two converter/alias names.
+ * The comparison is case-insensitive, ignores leading zeroes if they are not
+ * followed by further digits, and ignores all but letters and digits.
+ * Thus the strings "UTF-8", "utf_8", "u*T at f08" and "Utf 8" are exactly equivalent.
+ * See section 1.4, Charset Alias Matching in Unicode Technical Standard #22
+ * at http://www.unicode.org/reports/tr22/
+ *
+ * @param name1 a converter name or alias, zero-terminated
+ * @param name2 a converter name or alias, zero-terminated
+ * @return 0 if the names match, or a negative value if the name1
+ * lexically precedes name2, or a positive value if the name1
+ * lexically follows name2.
+ * @stable ICU 2.0
+ */
+U_STABLE int U_EXPORT2
+ucnv_compareNames(const char *name1, const char *name2);
+
+
+/**
+ * Creates a UConverter object with the name of a coded character set specified as a C string.
+ * The actual name will be resolved with the alias file
+ * using a case-insensitive string comparison that ignores
+ * leading zeroes and all non-alphanumeric characters.
+ * E.g., the names "UTF8", "utf-8", "u*T at f08" and "Utf 8" are all equivalent.
+ * (See also ucnv_compareNames().)
+ * If <code>NULL</code> is passed for the converter name, it will create one with the
+ * getDefaultName return value.
+ *
+ * <p>A converter name for ICU 1.5 and above may contain options
+ * like a locale specification to control the specific behavior of
+ * the newly instantiated converter.
+ * The meaning of the options depends on the particular converter.
+ * If an option is not defined for or recognized by a given converter, then it is ignored.</p>
+ *
+ * <p>Options are appended to the converter name string, with a
+ * <code>UCNV_OPTION_SEP_CHAR</code> between the name and the first option and
+ * also between adjacent options.</p>
+ *
+ * <p>If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.</p>
+ *
+ * <p>The conversion behavior and names can vary between platforms. ICU may
+ * convert some characters differently from other platforms. Details on this topic
+ * are in the <a href="http://icu.sourceforge.net/userguide/conversion.html">User's
+ * Guide</a>. Aliases starting with a "cp" prefix have no specific meaning
+ * other than its an alias starting with the letters "cp". Please do not
+ * associate any meaning to these aliases.</p>
+ *
+ * @param converterName Name of the coded character set table.
+ *          This may have options appended to the string.
+ *          IANA alias character set names, IBM CCSIDs starting with "ibm-",
+ *          Windows codepage numbers starting with "windows-" are frequently
+ *          used for this parameter. See ucnv_getAvailableName and
+ *          ucnv_getAlias for a complete list that is available.
+ *          If this parameter is NULL, the default converter will be used.
+ * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured
+ * @see ucnv_openU
+ * @see ucnv_openCCSID
+ * @see ucnv_getAvailableName
+ * @see ucnv_getAlias
+ * @see ucnv_getDefaultName
+ * @see ucnv_close
+ * @ee ucnv_compareNames
+ * @stable ICU 2.0
+ */
+U_STABLE UConverter* U_EXPORT2 
+ucnv_open(const char *converterName, UErrorCode *err);
+
+
+/**
+ * Creates a Unicode converter with the names specified as unicode string. 
+ * The name should be limited to the ASCII-7 alphanumerics range.
+ * The actual name will be resolved with the alias file
+ * using a case-insensitive string comparison that ignores
+ * leading zeroes and all non-alphanumeric characters.
+ * E.g., the names "UTF8", "utf-8", "u*T at f08" and "Utf 8" are all equivalent.
+ * (See also ucnv_compareNames().)
+ * If <TT>NULL</TT> is passed for the converter name, it will create 
+ * one with the ucnv_getDefaultName() return value.
+ * If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.
+ *
+ * <p>See ucnv_open for the complete details</p>
+ * @param name Name of the UConverter table in a zero terminated 
+ *        Unicode string
+ * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, 
+ *        U_FILE_ACCESS_ERROR</TT>
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an 
+ *        error occured
+ * @see ucnv_open
+ * @see ucnv_openCCSID
+ * @see ucnv_close
+ * @ee ucnv_compareNames
+ * @stable ICU 2.0
+ */
+U_STABLE UConverter* U_EXPORT2 
+ucnv_openU(const UChar *name,
+           UErrorCode *err);
+
+/**
+ * Creates a UConverter object from a CCSID number and platform pair.
+ * Note that the usefulness of this function is limited to platforms with numeric
+ * encoding IDs. Only IBM and Microsoft platforms use numeric (16-bit) identifiers for
+ * encodings.
+ *
+ * In addition, IBM CCSIDs and Unicode conversion tables are not 1:1 related.
+ * For many IBM CCSIDs there are multiple (up to six) Unicode conversion tables, and
+ * for some Unicode conversion tables there are multiple CCSIDs.
+ * Some "alternate" Unicode conversion tables are provided by the
+ * IBM CDRA conversion table registry.
+ * The most prominent example of a systematic modification of conversion tables that is
+ * not provided in the form of conversion table files in the repository is
+ * that S/390 Unix System Services swaps the codes for Line Feed and New Line in all
+ * EBCDIC codepages, which requires such a swap in the Unicode conversion tables as well.
+ *
+ * Only IBM default conversion tables are accessible with ucnv_openCCSID().
+ * ucnv_getCCSID() will return the same CCSID for all conversion tables that are associated
+ * with that CCSID.
+ *
+ * Currently, the only "platform" supported in the ICU converter API is UCNV_IBM.
+ *
+ * In summary, the use of CCSIDs and the associated API functions is not recommended.
+ *
+ * In order to open a converter with the default IBM CDRA Unicode conversion table,
+ * you can use this function or use the prefix "ibm-":
+ * \code
+ *     char name[20];
+ *     sprintf(name, "ibm-%hu", ccsid);
+ *     cnv=ucnv_open(name, &errorCode);
+ * \endcode
+ *
+ * In order to open a converter with the IBM S/390 Unix System Services variant
+ * of a Unicode/EBCDIC conversion table,
+ * you can use the prefix "ibm-" together with the option string UCNV_SWAP_LFNL_OPTION_STRING:
+ * \code
+ *     char name[20];
+ *     sprintf(name, "ibm-%hu" UCNV_SWAP_LFNL_OPTION_STRING, ccsid);
+ *     cnv=ucnv_open(name, &errorCode);
+ * \endcode
+ *
+ * In order to open a converter from a Microsoft codepage number, use the prefix "cp":
+ * \code
+ *     char name[20];
+ *     sprintf(name, "cp%hu", codepageID);
+ *     cnv=ucnv_open(name, &errorCode);
+ * \endcode
+ *
+ * If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.
+ *
+ * @param codepage codepage number to create
+ * @param platform the platform in which the codepage number exists
+ * @param err error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an error
+ *   occured.
+ * @see ucnv_open
+ * @see ucnv_openU
+ * @see ucnv_close
+ * @see ucnv_getCCSID
+ * @see ucnv_getPlatform
+ * @see UConverterPlatform
+ * @stable ICU 2.0
+ */
+U_STABLE UConverter* U_EXPORT2
+ucnv_openCCSID(int32_t codepage,
+               UConverterPlatform platform,
+               UErrorCode * err);
+
+/**
+ * <p>Creates a UConverter object specified from a packageName and a converterName.</p>
+ * 
+ * <p>The packageName and converterName must point to an ICU udata object, as defined by
+ *   <code> udata_open( packageName, "cnv", converterName, err) </code> or equivalent.
+ * Typically, packageName will refer to a (.dat) file, or to a package registered with
+ * udata_setAppData(). Using a full file or directory pathname for packageName is deprecated.</p>
+ * 
+ * <p>The name will NOT be looked up in the alias mechanism, nor will the converter be
+ * stored in the converter cache or the alias table. The only way to open further converters
+ * is call this function multiple times, or use the ucnv_safeClone() function to clone a 
+ * 'master' converter.</p>
+ *
+ * <p>A future version of ICU may add alias table lookups and/or caching
+ * to this function.</p>
+ * 
+ * <p>Example Use:
+ *      <code>cnv = ucnv_openPackage("myapp", "myconverter", &err);</code>
+ * </p>
+ *
+ * @param packageName name of the package (equivalent to 'path' in udata_open() call)
+ * @param converterName name of the data item to be used, without suffix.
+ * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT>
+ * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured
+ * @see udata_open
+ * @see ucnv_open
+ * @see ucnv_safeClone
+ * @see ucnv_close
+ * @stable ICU 2.2
+ */
+U_STABLE UConverter* U_EXPORT2 
+ucnv_openPackage(const char *packageName, const char *converterName, UErrorCode *err);
+
+/**
+ * Thread safe converter cloning operation.
+ * For most efficient operation, pass in a stackBuffer (and a *pBufferSize)
+ * with at least U_CNV_SAFECLONE_BUFFERSIZE bytes of space.
+ * If the buffer size is sufficient, then the clone will use the stack buffer;
+ * otherwise, it will be allocated, and *pBufferSize will indicate
+ * the actual size. (This should not occur with U_CNV_SAFECLONE_BUFFERSIZE.)
+ *
+ * You must ucnv_close() the clone in any case.
+ *
+ * If *pBufferSize==0, (regardless of whether stackBuffer==NULL or not)
+ * then *pBufferSize will be changed to a sufficient size
+ * for cloning this converter,
+ * without actually cloning the converter ("pure pre-flighting").
+ *
+ * If *pBufferSize is greater than zero but not large enough for a stack-based
+ * clone, then the converter is cloned using newly allocated memory
+ * and *pBufferSize is changed to the necessary size.
+ *
+ * If the converter clone fits into the stack buffer but the stack buffer is not
+ * sufficiently aligned for the clone, then the clone will use an
+ * adjusted pointer and use an accordingly smaller buffer size.
+ *
+ * @param cnv converter to be cloned
+ * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated. 
+ *  If buffer is not large enough, new memory will be allocated.
+ *  Clients can use the U_CNV_SAFECLONE_BUFFERSIZE. This will probably be enough to avoid memory allocations.
+ * @param pBufferSize pointer to size of allocated space. pBufferSize must not be NULL.
+ * @param status to indicate whether the operation went on smoothly or there were errors
+ *  An informational status value, U_SAFECLONE_ALLOCATED_WARNING,
+ *  is used if any allocations were necessary.
+ *  However, it is better to check if *pBufferSize grew for checking for
+ *  allocations because warning codes can be overridden by subsequent
+ *  function calls.
+ * @return pointer to the new clone
+ * @stable ICU 2.0
+ */
+U_STABLE UConverter * U_EXPORT2 
+ucnv_safeClone(const UConverter *cnv, 
+               void             *stackBuffer,
+               int32_t          *pBufferSize, 
+               UErrorCode       *status);
+
+/**
+ * \def U_CNV_SAFECLONE_BUFFERSIZE
+ * Definition of a buffer size that is designed to be large enough for
+ * converters to be cloned with ucnv_safeClone().
+ * @stable ICU 2.0
+ */
+#define U_CNV_SAFECLONE_BUFFERSIZE  1024
+
+/**
+ * Deletes the unicode converter and releases resources associated
+ * with just this instance.
+ * Does not free up shared converter tables.
+ *
+ * @param converter the converter object to be deleted
+ * @see ucnv_open
+ * @see ucnv_openU
+ * @see ucnv_openCCSID
+ * @stable ICU 2.0
+ */
+U_STABLE void  U_EXPORT2
+ucnv_close(UConverter * converter);
+
+/**
+ * Fills in the output parameter, subChars, with the substitution characters
+ * as multiple bytes.
+ * If ucnv_setSubstString() set a Unicode string because the converter is
+ * stateful, then subChars will be an empty string.
+ *
+ * @param converter the Unicode converter
+ * @param subChars the subsitution characters
+ * @param len on input the capacity of subChars, on output the number 
+ * of bytes copied to it
+ * @param  err the outgoing error status code.
+ * If the substitution character array is too small, an
+ * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned.
+ * @see ucnv_setSubstString
+ * @see ucnv_setSubstChars
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getSubstChars(const UConverter *converter,
+                   char *subChars,
+                   int8_t *len,
+                   UErrorCode *err);
+
+/**
+ * Sets the substitution chars when converting from unicode to a codepage. The
+ * substitution is specified as a string of 1-4 bytes, and may contain
+ * <TT>NULL</TT> bytes.
+ * The subChars must represent a single character. The caller needs to know the
+ * byte sequence of a valid character in the converter's charset.
+ * For some converters, for example some ISO 2022 variants, only single-byte
+ * substitution characters may be supported.
+ * The newer ucnv_setSubstString() function relaxes these limitations.
+ *
+ * @param converter the Unicode converter
+ * @param subChars the substitution character byte sequence we want set
+ * @param len the number of bytes in subChars
+ * @param err the error status code.  <TT>U_INDEX_OUTOFBOUNDS_ERROR </TT> if
+ * len is bigger than the maximum number of bytes allowed in subchars
+ * @see ucnv_setSubstString
+ * @see ucnv_getSubstChars
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_setSubstChars(UConverter *converter,
+                   const char *subChars,
+                   int8_t len,
+                   UErrorCode *err);
+
+/**
+ * Set a substitution string for converting from Unicode to a charset.
+ * The caller need not know the charset byte sequence for each charset.
+ *
+ * Unlike ucnv_setSubstChars() which is designed to set a charset byte sequence
+ * for a single character, this function takes a Unicode string with
+ * zero, one or more characters, and immediately verifies that the string can be
+ * converted to the charset.
+ * If not, or if the result is too long (more than 32 bytes as of ICU 3.6),
+ * then the function returns with an error accordingly.
+ *
+ * Also unlike ucnv_setSubstChars(), this function works for stateful charsets
+ * by converting on the fly at the point of substitution rather than setting
+ * a fixed byte sequence.
+ *
+ * @param cnv The UConverter object.
+ * @param s The Unicode string.
+ * @param length The number of UChars in s, or -1 for a NUL-terminated string.
+ * @param err Pointer to a standard ICU error code. Its input value must
+ *            pass the U_SUCCESS() test, or else the function returns
+ *            immediately. Check for U_FAILURE() on output or use with
+ *            function chaining. (See User Guide for details.)
+ *
+ * @see ucnv_setSubstChars
+ * @see ucnv_getSubstChars
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ucnv_setSubstString(UConverter *cnv,
+                    const UChar *s,
+                    int32_t length,
+                    UErrorCode *err);
+
+/**
+ * Fills in the output parameter, errBytes, with the error characters from the
+ * last failing conversion.
+ *
+ * @param converter the Unicode converter
+ * @param errBytes the codepage bytes which were in error
+ * @param len on input the capacity of errBytes, on output the number of
+ *  bytes which were copied to it
+ * @param err the error status code.
+ * If the substitution character array is too small, an
+ * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getInvalidChars(const UConverter *converter,
+                     char *errBytes,
+                     int8_t *len,
+                     UErrorCode *err);
+
+/**
+ * Fills in the output parameter, errChars, with the error characters from the
+ * last failing conversion.
+ *
+ * @param converter the Unicode converter
+ * @param errUChars the UChars which were in error
+ * @param len on input the capacity of errUChars, on output the number of 
+ *  UChars which were copied to it
+ * @param err the error status code.
+ * If the substitution character array is too small, an
+ * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getInvalidUChars(const UConverter *converter,
+                      UChar *errUChars,
+                      int8_t *len,
+                      UErrorCode *err);
+
+/**
+ * Resets the state of a converter to the default state. This is used
+ * in the case of an error, to restart a conversion from a known default state.
+ * It will also empty the internal output buffers.
+ * @param converter the Unicode converter
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_reset(UConverter *converter);
+
+/**
+ * Resets the to-Unicode part of a converter state to the default state.
+ * This is used in the case of an error to restart a conversion to
+ * Unicode to a known default state. It will also empty the internal
+ * output buffers used for the conversion to Unicode codepoints.
+ * @param converter the Unicode converter
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_resetToUnicode(UConverter *converter);
+
+/**
+ * Resets the from-Unicode part of a converter state to the default state.
+ * This is used in the case of an error to restart a conversion from
+ * Unicode to a known default state. It will also empty the internal output
+ * buffers used for the conversion from Unicode codepoints.
+ * @param converter the Unicode converter
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_resetFromUnicode(UConverter *converter);
+
+/**
+ * Returns the maximum number of bytes that are output per UChar in conversion
+ * from Unicode using this converter.
+ * The returned number can be used with UCNV_GET_MAX_BYTES_FOR_STRING
+ * to calculate the size of a target buffer for conversion from Unicode.
+ *
+ * Note: Before ICU 2.8, this function did not return reliable numbers for
+ * some stateful converters (EBCDIC_STATEFUL, ISO-2022) and LMBCS.
+ *
+ * This number may not be the same as the maximum number of bytes per
+ * "conversion unit". In other words, it may not be the intuitively expected
+ * number of bytes per character that would be published for a charset,
+ * and may not fulfill any other purpose than the allocation of an output
+ * buffer of guaranteed sufficient size for a given input length and converter.
+ *
+ * Examples for special cases that are taken into account:
+ * - Supplementary code points may convert to more bytes than BMP code points.
+ *   This function returns bytes per UChar (UTF-16 code unit), not per
+ *   Unicode code point, for efficient buffer allocation.
+ * - State-shifting output (SI/SO, escapes, etc.) from stateful converters.
+ * - When m input UChars are converted to n output bytes, then the maximum m/n
+ *   is taken into account.
+ *
+ * The number returned here does not take into account
+ * (see UCNV_GET_MAX_BYTES_FOR_STRING):
+ * - callbacks which output more than one charset character sequence per call,
+ *   like escape callbacks
+ * - initial and final non-character bytes that are output by some converters
+ *   (automatic BOMs, initial escape sequence, final SI, etc.)
+ *
+ * Examples for returned values:
+ * - SBCS charsets: 1
+ * - Shift-JIS: 2
+ * - UTF-16: 2 (2 per BMP, 4 per surrogate _pair_, BOM not counted)
+ * - UTF-8: 3 (3 per BMP, 4 per surrogate _pair_)
+ * - EBCDIC_STATEFUL (EBCDIC mixed SBCS/DBCS): 3 (SO + DBCS)
+ * - ISO-2022: 3 (always outputs UTF-8)
+ * - ISO-2022-JP: 6 (4-byte escape sequences + DBCS)
+ * - ISO-2022-CN: 8 (4-byte designator sequences + 2-byte SS2/SS3 + DBCS)
+ *
+ * @param converter The Unicode converter.
+ * @return The maximum number of bytes per UChar that are output by ucnv_fromUnicode(),
+ *         to be used together with UCNV_GET_MAX_BYTES_FOR_STRING for buffer allocation.
+ *
+ * @see UCNV_GET_MAX_BYTES_FOR_STRING
+ * @see ucnv_getMinCharSize
+ * @stable ICU 2.0
+ */
+U_STABLE int8_t U_EXPORT2
+ucnv_getMaxCharSize(const UConverter *converter);
+
+/**
+ * Calculates the size of a buffer for conversion from Unicode to a charset.
+ * The calculated size is guaranteed to be sufficient for this conversion.
+ *
+ * It takes into account initial and final non-character bytes that are output
+ * by some converters.
+ * It does not take into account callbacks which output more than one charset
+ * character sequence per call, like escape callbacks.
+ * The default (substitution) callback only outputs one charset character sequence.
+ *
+ * @param length Number of UChars to be converted.
+ * @param maxCharSize Return value from ucnv_getMaxCharSize() for the converter
+ *                    that will be used.
+ * @return Size of a buffer that will be large enough to hold the output bytes of
+ *         converting length UChars with the converter that returned the maxCharSize.
+ *
+ * @see ucnv_getMaxCharSize
+ * @stable ICU 2.8
+ */
+#define UCNV_GET_MAX_BYTES_FOR_STRING(length, maxCharSize) \
+     (((int32_t)(length)+10)*(int32_t)(maxCharSize))
+
+/**
+ * Returns the minimum byte length for characters in this codepage. 
+ * This is usually either 1 or 2.
+ * @param converter the Unicode converter
+ * @return the minimum number of bytes allowed by this particular converter
+ * @see ucnv_getMaxCharSize
+ * @stable ICU 2.0
+ */
+U_STABLE int8_t U_EXPORT2
+ucnv_getMinCharSize(const UConverter *converter);
+
+/**
+ * Returns the display name of the converter passed in based on the Locale 
+ * passed in. If the locale contains no display name, the internal ASCII
+ * name will be filled in.
+ *
+ * @param converter the Unicode converter.
+ * @param displayLocale is the specific Locale we want to localised for
+ * @param displayName user provided buffer to be filled in
+ * @param displayNameCapacity size of displayName Buffer
+ * @param err error status code
+ * @return displayNameLength number of UChar needed in displayName
+ * @see ucnv_getName
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_getDisplayName(const UConverter *converter,
+                    const char *displayLocale,
+                    UChar *displayName,
+                    int32_t displayNameCapacity,
+                    UErrorCode *err);
+
+/**
+ * Gets the internal, canonical name of the converter (zero-terminated).
+ * The lifetime of the returned string will be that of the converter 
+ * passed to this function.
+ * @param converter the Unicode converter
+ * @param err UErrorCode status
+ * @return the internal name of the converter
+ * @see ucnv_getDisplayName
+ * @stable ICU 2.0
+ */
+U_STABLE const char * U_EXPORT2 
+ucnv_getName(const UConverter *converter, UErrorCode *err);
+
+/**
+ * Gets a codepage number associated with the converter. This is not guaranteed
+ * to be the one used to create the converter. Some converters do not represent
+ * platform registered codepages and return zero for the codepage number.
+ * The error code fill-in parameter indicates if the codepage number
+ * is available.
+ * Does not check if the converter is <TT>NULL</TT> or if converter's data
+ * table is <TT>NULL</TT>.
+ *
+ * Important: The use of CCSIDs is not recommended because it is limited
+ * to only two platforms in principle and only one (UCNV_IBM) in the current
+ * ICU converter API.
+ * Also, CCSIDs are insufficient to identify IBM Unicode conversion tables precisely.
+ * For more details see ucnv_openCCSID().
+ *
+ * @param converter the Unicode converter
+ * @param err the error status code.
+ * @return If any error occurrs, -1 will be returned otherwise, the codepage number
+ * will be returned
+ * @see ucnv_openCCSID
+ * @see ucnv_getPlatform
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_getCCSID(const UConverter *converter,
+              UErrorCode *err);
+
+/**
+ * Gets a codepage platform associated with the converter. Currently, 
+ * only <TT>UCNV_IBM</TT> will be returned.
+ * Does not test if the converter is <TT>NULL</TT> or if converter's data 
+ * table is <TT>NULL</TT>. 
+ * @param converter the Unicode converter
+ * @param err the error status code.
+ * @return The codepage platform
+ * @stable ICU 2.0
+ */
+U_STABLE UConverterPlatform U_EXPORT2
+ucnv_getPlatform(const UConverter *converter,
+                 UErrorCode *err);
+
+/**
+ * Gets the type of the converter
+ * e.g. SBCS, MBCS, DBCS, UTF8, UTF16_BE, UTF16_LE, ISO_2022, 
+ * EBCDIC_STATEFUL, LATIN_1
+ * @param converter a valid, opened converter
+ * @return the type of the converter
+ * @stable ICU 2.0
+ */
+U_STABLE UConverterType U_EXPORT2
+ucnv_getType(const UConverter * converter);
+
+/**
+ * Gets the "starter" (lead) bytes for converters of type MBCS.
+ * Will fill in an <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> if converter passed in
+ * is not MBCS. Fills in an array of type UBool, with the value of the byte 
+ * as offset to the array. For example, if (starters[0x20] == TRUE) at return,
+ * it means that the byte 0x20 is a starter byte in this converter.
+ * Context pointers are always owned by the caller.
+ * 
+ * @param converter a valid, opened converter of type MBCS
+ * @param starters an array of size 256 to be filled in
+ * @param err error status, <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> if the 
+ * converter is not a type which can return starters.
+ * @see ucnv_getType
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getStarters(const UConverter* converter, 
+                 UBool starters[256],
+                 UErrorCode* err);
+
+
+/**
+ * Selectors for Unicode sets that can be returned by ucnv_getUnicodeSet().
+ * @see ucnv_getUnicodeSet
+ * @stable ICU 2.6
+ */
+typedef enum UConverterUnicodeSet {
+    /** Select the set of roundtrippable Unicode code points. @stable ICU 2.6 */
+    UCNV_ROUNDTRIP_SET,
+    /** Number of UConverterUnicodeSet selectors. @stable ICU 2.6 */
+    UCNV_SET_COUNT
+} UConverterUnicodeSet;
+
+
+/**
+ * Returns the set of Unicode code points that can be converted by an ICU converter.
+ *
+ * The current implementation returns only one kind of set (UCNV_ROUNDTRIP_SET):
+ * The set of all Unicode code points that can be roundtrip-converted
+ * (converted without any data loss) with the converter.
+ * This set will not include code points that have fallback mappings
+ * or are only the result of reverse fallback mappings.
+ * See UTR #22 "Character Mapping Markup Language"
+ * at http://www.unicode.org/reports/tr22/
+ *
+ * This is useful for example for
+ * - checking that a string or document can be roundtrip-converted with a converter,
+ *   without/before actually performing the conversion
+ * - testing if a converter can be used for text for typical text for a certain locale,
+ *   by comparing its roundtrip set with the set of ExemplarCharacters from
+ *   ICU's locale data or other sources
+ *
+ * In the future, there may be more UConverterUnicodeSet choices to select
+ * sets with different properties.
+ *
+ * @param cnv The converter for which a set is requested.
+ * @param setFillIn A valid USet *. It will be cleared by this function before
+ *            the converter's specific set is filled into the USet.
+ * @param whichSet A UConverterUnicodeSet selector;
+ *              currently UCNV_ROUNDTRIP_SET is the only supported value.
+ * @param pErrorCode ICU error code in/out parameter.
+ *                   Must fulfill U_SUCCESS before the function call.
+ *
+ * @see UConverterUnicodeSet
+ * @see uset_open
+ * @see uset_close
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+ucnv_getUnicodeSet(const UConverter *cnv,
+                   USet *setFillIn,
+                   UConverterUnicodeSet whichSet,
+                   UErrorCode *pErrorCode);
+
+/**
+ * Gets the current calback function used by the converter when an illegal
+ *  or invalid codepage sequence is found. 
+ * Context pointers are always owned by the caller.
+ *
+ * @param converter the unicode converter
+ * @param action fillin: returns the callback function pointer
+ * @param context fillin: returns the callback's private void* context
+ * @see ucnv_setToUCallBack
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getToUCallBack (const UConverter * converter,
+                     UConverterToUCallback *action,
+                     const void **context);
+
+/**
+ * Gets the current callback function used by the converter when illegal 
+ * or invalid Unicode sequence is found.
+ * Context pointers are always owned by the caller.
+ *
+ * @param converter the unicode converter
+ * @param action fillin: returns the callback function pointer
+ * @param context fillin: returns the callback's private void* context
+ * @see ucnv_setFromUCallBack
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_getFromUCallBack (const UConverter * converter,
+                       UConverterFromUCallback *action,
+                       const void **context);
+
+/**
+ * Changes the callback function used by the converter when
+ * an illegal or invalid sequence is found.
+ * Context pointers are always owned by the caller.
+ * Predefined actions and contexts can be found in the ucnv_err.h header.
+ *
+ * @param converter the unicode converter
+ * @param newAction the new callback function
+ * @param newContext the new toUnicode callback context pointer. This can be NULL.
+ * @param oldAction fillin: returns the old callback function pointer. This can be NULL.
+ * @param oldContext fillin: returns the old callback's private void* context. This can be NULL.
+ * @param err The error code status
+ * @see ucnv_getToUCallBack
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_setToUCallBack (UConverter * converter,
+                     UConverterToUCallback newAction,
+                     const void* newContext,
+                     UConverterToUCallback *oldAction,
+                     const void** oldContext,
+                     UErrorCode * err);
+
+/**
+ * Changes the current callback function used by the converter when
+ * an illegal or invalid sequence is found.
+ * Context pointers are always owned by the caller.
+ * Predefined actions and contexts can be found in the ucnv_err.h header.
+ *
+ * @param converter the unicode converter
+ * @param newAction the new callback function
+ * @param newContext the new fromUnicode callback context pointer. This can be NULL.
+ * @param oldAction fillin: returns the old callback function pointer. This can be NULL.
+ * @param oldContext fillin: returns the old callback's private void* context. This can be NULL.
+ * @param err The error code status
+ * @see ucnv_getFromUCallBack
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_setFromUCallBack (UConverter * converter,
+                       UConverterFromUCallback newAction,
+                       const void *newContext,
+                       UConverterFromUCallback *oldAction,
+                       const void **oldContext,
+                       UErrorCode * err);
+
+/**
+ * Converts an array of unicode characters to an array of codepage
+ * characters. This function is optimized for converting a continuous
+ * stream of data in buffer-sized chunks, where the entire source and
+ * target does not fit in available buffers.
+ * 
+ * The source pointer is an in/out parameter. It starts out pointing where the 
+ * conversion is to begin, and ends up pointing after the last UChar consumed. 
+ * 
+ * Target similarly starts out pointer at the first available byte in the output
+ * buffer, and ends up pointing after the last byte written to the output.
+ * 
+ * The converter always attempts to consume the entire source buffer, unless 
+ * (1.) the target buffer is full, or (2.) a failing error is returned from the
+ * current callback function.  When a successful error status has been
+ * returned, it means that all of the source buffer has been
+ *  consumed. At that point, the caller should reset the source and
+ *  sourceLimit pointers to point to the next chunk.
+ * 
+ * At the end of the stream (flush==TRUE), the input is completely consumed
+ * when *source==sourceLimit and no error code is set.
+ * The converter object is then automatically reset by this function.
+ * (This means that a converter need not be reset explicitly between data
+ * streams if it finishes the previous stream without errors.)
+ * 
+ * This is a <I>stateful</I> conversion. Additionally, even when all source data has
+ * been consumed, some data may be in the converters' internal state.
+ * Call this function repeatedly, updating the target pointers with
+ * the next empty chunk of target in case of a
+ * <TT>U_BUFFER_OVERFLOW_ERROR</TT>, and updating the source  pointers
+ *  with the next chunk of source when a successful error status is
+ * returned, until there are no more chunks of source data.
+ * @param converter the Unicode converter
+ * @param target I/O parameter. Input : Points to the beginning of the buffer to copy
+ *  codepage characters to. Output : points to after the last codepage character copied
+ *  to <TT>target</TT>.
+ * @param targetLimit the pointer just after last of the <TT>target</TT> buffer
+ * @param source I/O parameter, pointer to pointer to the source Unicode character buffer. 
+ * @param sourceLimit the pointer just after the last of the source buffer
+ * @param offsets if NULL is passed, nothing will happen to it, otherwise it needs to have the same number
+ * of allocated cells as <TT>target</TT>. Will fill in offsets from target to source pointer
+ * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT>
+ * For output data carried across calls, and other data without a specific source character
+ * (such as from escape sequences or callbacks)  -1 will be placed for offsets. 
+ * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available
+ * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned,
+ * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until
+ * the source buffer is consumed.
+ * @param err the error status.  <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the
+ * converter is <TT>NULL</TT>.
+ * <code>U_BUFFER_OVERFLOW_ERROR</code> will be set if the target is full and there is 
+ * still data to be written to the target.
+ * @see ucnv_fromUChars
+ * @see ucnv_convert
+ * @see ucnv_getMinCharSize
+ * @see ucnv_setToUCallBack
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_fromUnicode (UConverter * converter,
+                  char **target,
+                  const char *targetLimit,
+                  const UChar ** source,
+                  const UChar * sourceLimit,
+                  int32_t* offsets,
+                  UBool flush,
+                  UErrorCode * err);
+
+/**
+ * Converts a buffer of codepage bytes into an array of unicode UChars
+ * characters. This function is optimized for converting a continuous
+ * stream of data in buffer-sized chunks, where the entire source and
+ * target does not fit in available buffers.
+ * 
+ * The source pointer is an in/out parameter. It starts out pointing where the 
+ * conversion is to begin, and ends up pointing after the last byte of source consumed. 
+ * 
+ * Target similarly starts out pointer at the first available UChar in the output
+ * buffer, and ends up pointing after the last UChar written to the output. 
+ * It does NOT necessarily keep UChar sequences together.
+ * 
+ * The converter always attempts to consume the entire source buffer, unless 
+ * (1.) the target buffer is full, or (2.) a failing error is returned from the
+ * current callback function.  When a successful error status has been
+ * returned, it means that all of the source buffer has been
+ *  consumed. At that point, the caller should reset the source and
+ *  sourceLimit pointers to point to the next chunk.
+ *
+ * At the end of the stream (flush==TRUE), the input is completely consumed
+ * when *source==sourceLimit and no error code is set
+ * The converter object is then automatically reset by this function.
+ * (This means that a converter need not be reset explicitly between data
+ * streams if it finishes the previous stream without errors.)
+ * 
+ * This is a <I>stateful</I> conversion. Additionally, even when all source data has
+ * been consumed, some data may be in the converters' internal state.
+ * Call this function repeatedly, updating the target pointers with
+ * the next empty chunk of target in case of a
+ * <TT>U_BUFFER_OVERFLOW_ERROR</TT>, and updating the source  pointers
+ *  with the next chunk of source when a successful error status is
+ * returned, until there are no more chunks of source data.
+ * @param converter the Unicode converter
+ * @param target I/O parameter. Input : Points to the beginning of the buffer to copy
+ *  UChars into. Output : points to after the last UChar copied.
+ * @param targetLimit the pointer just after the end of the <TT>target</TT> buffer
+ * @param source I/O parameter, pointer to pointer to the source codepage buffer. 
+ * @param sourceLimit the pointer to the byte after the end of the source buffer
+ * @param offsets if NULL is passed, nothing will happen to it, otherwise it needs to have the same number
+ * of allocated cells as <TT>target</TT>. Will fill in offsets from target to source pointer
+ * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT>
+ * For output data carried across calls, and other data without a specific source character
+ * (such as from escape sequences or callbacks)  -1 will be placed for offsets. 
+ * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available
+ * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned,
+ * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until
+ * the source buffer is consumed.
+ * @param err the error status.  <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the
+ * converter is <TT>NULL</TT>.
+ * <code>U_BUFFER_OVERFLOW_ERROR</code> will be set if the target is full and there is 
+ * still data to be written to the target. 
+ * @see ucnv_fromUChars
+ * @see ucnv_convert
+ * @see ucnv_getMinCharSize
+ * @see ucnv_setFromUCallBack
+ * @see ucnv_getNextUChar
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_toUnicode(UConverter *converter,
+               UChar **target,
+               const UChar *targetLimit,
+               const char **source,
+               const char *sourceLimit,
+               int32_t *offsets,
+               UBool flush,
+               UErrorCode *err);
+
+/**
+ * Convert the Unicode string into a codepage string using an existing UConverter.
+ * The output string is NUL-terminated if possible.
+ *
+ * This function is a more convenient but less powerful version of ucnv_fromUnicode().
+ * It is only useful for whole strings, not for streaming conversion.
+ *
+ * The maximum output buffer capacity required (barring output from callbacks) will be
+ * UCNV_GET_MAX_BYTES_FOR_STRING(srcLength, ucnv_getMaxCharSize(cnv)).
+ *
+ * @param cnv the converter object to be used (ucnv_resetFromUnicode() will be called)
+ * @param src the input Unicode string
+ * @param srcLength the input string length, or -1 if NUL-terminated
+ * @param dest destination string buffer, can be NULL if destCapacity==0
+ * @param destCapacity the number of chars available at dest
+ * @param pErrorCode normal ICU error code;
+ *                  common error codes that may be set by this function include
+ *                  U_BUFFER_OVERFLOW_ERROR, U_STRING_NOT_TERMINATED_WARNING,
+ *                  U_ILLEGAL_ARGUMENT_ERROR, and conversion errors
+ * @return the length of the output string, not counting the terminating NUL;
+ *         if the length is greater than destCapacity, then the string will not fit
+ *         and a buffer of the indicated length would need to be passed in
+ * @see ucnv_fromUnicode
+ * @see ucnv_convert
+ * @see UCNV_GET_MAX_BYTES_FOR_STRING
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_fromUChars(UConverter *cnv,
+                char *dest, int32_t destCapacity,
+                const UChar *src, int32_t srcLength,
+                UErrorCode *pErrorCode);
+
+/**
+ * Convert the codepage string into a Unicode string using an existing UConverter.
+ * The output string is NUL-terminated if possible.
+ *
+ * This function is a more convenient but less powerful version of ucnv_toUnicode().
+ * It is only useful for whole strings, not for streaming conversion.
+ *
+ * The maximum output buffer capacity required (barring output from callbacks) will be
+ * 2*srcLength (each char may be converted into a surrogate pair).
+ *
+ * @param cnv the converter object to be used (ucnv_resetToUnicode() will be called)
+ * @param src the input codepage string
+ * @param srcLength the input string length, or -1 if NUL-terminated
+ * @param dest destination string buffer, can be NULL if destCapacity==0
+ * @param destCapacity the number of UChars available at dest
+ * @param pErrorCode normal ICU error code;
+ *                  common error codes that may be set by this function include
+ *                  U_BUFFER_OVERFLOW_ERROR, U_STRING_NOT_TERMINATED_WARNING,
+ *                  U_ILLEGAL_ARGUMENT_ERROR, and conversion errors
+ * @return the length of the output string, not counting the terminating NUL;
+ *         if the length is greater than destCapacity, then the string will not fit
+ *         and a buffer of the indicated length would need to be passed in
+ * @see ucnv_toUnicode
+ * @see ucnv_convert
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_toUChars(UConverter *cnv,
+              UChar *dest, int32_t destCapacity,
+              const char *src, int32_t srcLength,
+              UErrorCode *pErrorCode);
+
+/**
+ * Convert a codepage buffer into Unicode one character at a time.
+ * The input is completely consumed when the U_INDEX_OUTOFBOUNDS_ERROR is set.
+ *
+ * Advantage compared to ucnv_toUnicode() or ucnv_toUChars():
+ * - Faster for small amounts of data, for most converters, e.g.,
+ *   US-ASCII, ISO-8859-1, UTF-8/16/32, and most "normal" charsets.
+ *   (For complex converters, e.g., SCSU, UTF-7 and ISO 2022 variants,
+ *    it uses ucnv_toUnicode() internally.)
+ * - Convenient.
+ *
+ * Limitations compared to ucnv_toUnicode():
+ * - Always assumes flush=TRUE.
+ *   This makes ucnv_getNextUChar() unsuitable for "streaming" conversion,
+ *   that is, for where the input is supplied in multiple buffers,
+ *   because ucnv_getNextUChar() will assume the end of the input at the end
+ *   of the first buffer.
+ * - Does not provide offset output.
+ *
+ * It is possible to "mix" ucnv_getNextUChar() and ucnv_toUnicode() because
+ * ucnv_getNextUChar() uses the current state of the converter
+ * (unlike ucnv_toUChars() which always resets first).
+ * However, if ucnv_getNextUChar() is called after ucnv_toUnicode()
+ * stopped in the middle of a character sequence (with flush=FALSE),
+ * then ucnv_getNextUChar() will always use the slower ucnv_toUnicode()
+ * internally until the next character boundary.
+ * (This is new in ICU 2.6. In earlier releases, ucnv_getNextUChar() had to
+ * start at a character boundary.)
+ *
+ * Instead of using ucnv_getNextUChar(), it is recommended
+ * to convert using ucnv_toUnicode() or ucnv_toUChars()
+ * and then iterate over the text using U16_NEXT() or a UCharIterator (uiter.h)
+ * or a C++ CharacterIterator or similar.
+ * This allows streaming conversion and offset output, for example.
+ *
+ * <p>Handling of surrogate pairs and supplementary-plane code points:<br>
+ * There are two different kinds of codepages that provide mappings for surrogate characters:
+ * <ul>
+ *   <li>Codepages like UTF-8, UTF-32, and GB 18030 provide direct representations for Unicode
+ *       code points U+10000-U+10ffff as well as for single surrogates U+d800-U+dfff.
+ *       Each valid sequence will result in exactly one returned code point.
+ *       If a sequence results in a single surrogate, then that will be returned
+ *       by itself, even if a neighboring sequence encodes the matching surrogate.</li>
+ *   <li>Codepages like SCSU and LMBCS (and UTF-16) provide direct representations only for BMP code points
+ *       including surrogates. Code points in supplementary planes are represented with
+ *       two sequences, each encoding a surrogate.
+ *       For these codepages, matching pairs of surrogates will be combined into single
+ *       code points for returning from this function.
+ *       (Note that SCSU is actually a mix of these codepage types.)</li>
+ * </ul></p>
+ *
+ * @param converter an open UConverter
+ * @param source the address of a pointer to the codepage buffer, will be
+ *  updated to point after the bytes consumed in the conversion call.
+ * @param sourceLimit points to the end of the input buffer
+ * @param err fills in error status (see ucnv_toUnicode)
+ * <code>U_INDEX_OUTOFBOUNDS_ERROR</code> will be set if the input 
+ * is empty or does not convert to any output (e.g.: pure state-change 
+ * codes SI/SO, escape sequences for ISO 2022,
+ * or if the callback did not output anything, ...).
+ * This function will not set a <code>U_BUFFER_OVERFLOW_ERROR</code> because
+ *  the "buffer" is the return code. However, there might be subsequent output
+ *  stored in the converter object
+ * that will be returned in following calls to this function.
+ * @return a UChar32 resulting from the partial conversion of source
+ * @see ucnv_toUnicode
+ * @see ucnv_toUChars
+ * @see ucnv_convert
+ * @stable ICU 2.0
+ */
+U_STABLE UChar32 U_EXPORT2
+ucnv_getNextUChar(UConverter * converter,
+                  const char **source,
+                  const char * sourceLimit,
+                  UErrorCode * err);
+
+/**
+ * Convert from one external charset to another using two existing UConverters.
+ * Internally, two conversions - ucnv_toUnicode() and ucnv_fromUnicode() -
+ * are used, "pivoting" through 16-bit Unicode.
+ *
+ * Important: For streaming conversion (multiple function calls for successive
+ * parts of a text stream), the caller must provide a pivot buffer explicitly,
+ * and must preserve the pivot buffer and associated pointers from one
+ * call to another. (The buffer may be moved if its contents and the relative
+ * pointer positions are preserved.)
+ *
+ * There is a similar function, ucnv_convert(),
+ * which has the following limitations:
+ * - it takes charset names, not converter objects, so that
+ *   - two converters are opened for each call
+ *   - only single-string conversion is possible, not streaming operation
+ * - it does not provide enough information to find out,
+ *   in case of failure, whether the toUnicode or
+ *   the fromUnicode conversion failed
+ *
+ * By contrast, ucnv_convertEx()
+ * - takes UConverter parameters instead of charset names
+ * - fully exposes the pivot buffer for streaming conversion and complete error handling
+ *
+ * ucnv_convertEx() also provides further convenience:
+ * - an option to reset the converters at the beginning
+ *   (if reset==TRUE, see parameters;
+ *    also sets *pivotTarget=*pivotSource=pivotStart)
+ * - allow NUL-terminated input
+ *   (only a single NUL byte, will not work for charsets with multi-byte NULs)
+ *   (if sourceLimit==NULL, see parameters)
+ * - terminate with a NUL on output
+ *   (only a single NUL byte, not useful for charsets with multi-byte NULs),
+ *   or set U_STRING_NOT_TERMINATED_WARNING if the output exactly fills
+ *   the target buffer
+ * - the pivot buffer can be provided internally;
+ *   possible only for whole-string conversion, not streaming conversion;
+ *   in this case, the caller will not be able to get details about where an
+ *   error occurred
+ *   (if pivotStart==NULL, see below)
+ *
+ * The function returns when one of the following is true:
+ * - the entire source text has been converted successfully to the target buffer
+ * - a target buffer overflow occurred (U_BUFFER_OVERFLOW_ERROR)
+ * - a conversion error occurred
+ *   (other U_FAILURE(), see description of pErrorCode)
+ *
+ * Limitation compared to the direct use of
+ * ucnv_fromUnicode() and ucnv_toUnicode():
+ * ucnv_convertEx() does not provide offset information.
+ *
+ * Limitation compared to ucnv_fromUChars() and ucnv_toUChars():
+ * ucnv_convertEx() does not support preflighting directly.
+ *
+ * Sample code for converting a single string from
+ * one external charset to UTF-8, ignoring the location of errors:
+ *
+ * \code
+ * int32_t
+ * myToUTF8(UConverter *cnv,
+ *          const char *s, int32_t length,
+ *          char *u8, int32_t capacity,
+ *          UErrorCode *pErrorCode) {
+ *     UConverter *utf8Cnv;
+ *     char *target;
+ *
+ *     if(U_FAILURE(*pErrorCode)) {
+ *         return 0;
+ *     }
+ *
+ *     utf8Cnv=myGetCachedUTF8Converter(pErrorCode);
+ *     if(U_FAILURE(*pErrorCode)) {
+ *         return 0;
+ *     }
+ *
+ *     target=u8;
+ *     ucnv_convertEx(cnv, utf8Cnv,
+ *                    &target, u8+capacity,
+ *                    &s, length>=0 ? s+length : NULL,
+ *                    NULL, NULL, NULL, NULL,
+ *                    TRUE, TRUE,
+ *                    pErrorCode);
+ * 
+ *     myReleaseCachedUTF8Converter(utf8Cnv);
+ *
+ *     // return the output string length, but without preflighting
+ *     return (int32_t)(target-u8);
+ * }
+ * \endcode
+ *
+ * @param targetCnv     Output converter, used to convert from the UTF-16 pivot
+ *                      to the target using ucnv_fromUnicode().
+ * @param sourceCnv     Input converter, used to convert from the source to
+ *                      the UTF-16 pivot using ucnv_toUnicode().
+ * @param target        I/O parameter, same as for ucnv_fromUChars().
+ *                      Input: *target points to the beginning of the target buffer.
+ *                      Output: *target points to the first unit after the last char written.
+ * @param targetLimit   Pointer to the first unit after the target buffer.
+ * @param source        I/O parameter, same as for ucnv_toUChars().
+ *                      Input: *source points to the beginning of the source buffer.
+ *                      Output: *source points to the first unit after the last char read.
+ * @param sourceLimit   Pointer to the first unit after the source buffer.
+ * @param pivotStart    Pointer to the UTF-16 pivot buffer. If pivotStart==NULL,
+ *                      then an internal buffer is used and the other pivot
+ *                      arguments are ignored and can be NULL as well.
+ * @param pivotSource   I/O parameter, same as source in ucnv_fromUChars() for
+ *                      conversion from the pivot buffer to the target buffer.
+ * @param pivotTarget   I/O parameter, same as target in ucnv_toUChars() for
+ *                      conversion from the source buffer to the pivot buffer.
+ *                      It must be pivotStart<=*pivotSource<=*pivotTarget<=pivotLimit
+ *                      and pivotStart<pivotLimit (unless pivotStart==NULL).
+ * @param pivotLimit    Pointer to the first unit after the pivot buffer.
+ * @param reset         If TRUE, then ucnv_resetToUnicode(sourceCnv) and
+ *                      ucnv_resetFromUnicode(targetCnv) are called, and the
+ *                      pivot pointers are reset (*pivotTarget=*pivotSource=pivotStart).
+ * @param flush         If true, indicates the end of the input.
+ *                      Passed directly to ucnv_toUnicode(), and carried over to
+ *                      ucnv_fromUnicode() when the source is empty as well.
+ * @param pErrorCode    ICU error code in/out parameter.
+ *                      Must fulfill U_SUCCESS before the function call.
+ *                      U_BUFFER_OVERFLOW_ERROR always refers to the target buffer
+ *                      because overflows into the pivot buffer are handled internally.
+ *                      Other conversion errors are from the source-to-pivot
+ *                      conversion if *pivotSource==pivotStart, otherwise from
+ *                      the pivot-to-target conversion.
+ *
+ * @see ucnv_convert
+ * @see ucnv_fromAlgorithmic
+ * @see ucnv_toAlgorithmic
+ * @see ucnv_fromUnicode
+ * @see ucnv_toUnicode
+ * @see ucnv_fromUChars
+ * @see ucnv_toUChars
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+ucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv,
+               char **target, const char *targetLimit,
+               const char **source, const char *sourceLimit,
+               UChar *pivotStart, UChar **pivotSource,
+               UChar **pivotTarget, const UChar *pivotLimit,
+               UBool reset, UBool flush,
+               UErrorCode *pErrorCode);
+
+/**
+ * Convert from one external charset to another.
+ * Internally, two converters are opened according to the name arguments,
+ * then the text is converted to and from the 16-bit Unicode "pivot"
+ * using ucnv_convertEx(), then the converters are closed again.
+ *
+ * This is a convenience function, not an efficient way to convert a lot of text:
+ * ucnv_convert()
+ * - takes charset names, not converter objects, so that
+ *   - two converters are opened for each call
+ *   - only single-string conversion is possible, not streaming operation
+ * - does not provide enough information to find out,
+ *   in case of failure, whether the toUnicode or
+ *   the fromUnicode conversion failed
+ * - allows NUL-terminated input
+ *   (only a single NUL byte, will not work for charsets with multi-byte NULs)
+ *   (if sourceLength==-1, see parameters)
+ * - terminate with a NUL on output
+ *   (only a single NUL byte, not useful for charsets with multi-byte NULs),
+ *   or set U_STRING_NOT_TERMINATED_WARNING if the output exactly fills
+ *   the target buffer
+ * - a pivot buffer is provided internally
+ *
+ * The function returns when one of the following is true:
+ * - the entire source text has been converted successfully to the target buffer
+ *   and either the target buffer is terminated with a single NUL byte
+ *   or the error code is set to U_STRING_NOT_TERMINATED_WARNING
+ * - a target buffer overflow occurred (U_BUFFER_OVERFLOW_ERROR)
+ *   and the full output string length is returned ("preflighting")
+ * - a conversion error occurred
+ *   (other U_FAILURE(), see description of pErrorCode)
+ *
+ * @param toConverterName   The name of the converter that is used to convert
+ *                          from the UTF-16 pivot buffer to the target.
+ * @param fromConverterName The name of the converter that is used to convert
+ *                          from the source to the UTF-16 pivot buffer.
+ * @param target            Pointer to the output buffer.
+ * @param targetCapacity    Capacity of the target, in bytes.
+ * @param source            Pointer to the input buffer.
+ * @param sourceLength      Length of the input text, in bytes, or -1 for NUL-terminated input.
+ * @param pErrorCode        ICU error code in/out parameter.
+ *                          Must fulfill U_SUCCESS before the function call.
+ * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity
+ *         and a U_BUFFER_OVERFLOW_ERROR is set.
+ *
+ * @see ucnv_convertEx
+ * @see ucnv_fromAlgorithmic
+ * @see ucnv_toAlgorithmic
+ * @see ucnv_fromUnicode
+ * @see ucnv_toUnicode
+ * @see ucnv_fromUChars
+ * @see ucnv_toUChars
+ * @see ucnv_getNextUChar
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_convert(const char *toConverterName,
+             const char *fromConverterName,
+             char *target,
+             int32_t targetCapacity,
+             const char *source,
+             int32_t sourceLength,
+             UErrorCode *pErrorCode);
+
+/**
+ * Convert from one external charset to another.
+ * Internally, the text is converted to and from the 16-bit Unicode "pivot"
+ * using ucnv_convertEx(). ucnv_toAlgorithmic() works exactly like ucnv_convert()
+ * except that the two converters need not be looked up and opened completely.
+ *
+ * The source-to-pivot conversion uses the cnv converter parameter.
+ * The pivot-to-target conversion uses a purely algorithmic converter
+ * according to the specified type, e.g., UCNV_UTF8 for a UTF-8 converter.
+ *
+ * Internally, the algorithmic converter is opened and closed for each
+ * function call, which is more efficient than using the public ucnv_open()
+ * but somewhat less efficient than only resetting an existing converter
+ * and using ucnv_convertEx().
+ *
+ * This function is more convenient than ucnv_convertEx() for single-string
+ * conversions, especially when "preflighting" is desired (returning the length
+ * of the complete output even if it does not fit into the target buffer;
+ * see the User Guide Strings chapter). See ucnv_convert() for details.
+ *
+ * @param algorithmicType   UConverterType constant identifying the desired target
+ *                          charset as a purely algorithmic converter.
+ *                          Those are converters for Unicode charsets like
+ *                          UTF-8, BOCU-1, SCSU, UTF-7, IMAP-mailbox-name, etc.,
+ *                          as well as US-ASCII and ISO-8859-1.
+ * @param cnv               The converter that is used to convert
+ *                          from the source to the UTF-16 pivot buffer.
+ * @param target            Pointer to the output buffer.
+ * @param targetCapacity    Capacity of the target, in bytes.
+ * @param source            Pointer to the input buffer.
+ * @param sourceLength      Length of the input text, in bytes
+ * @param pErrorCode        ICU error code in/out parameter.
+ *                          Must fulfill U_SUCCESS before the function call.
+ * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity
+ *         and a U_BUFFER_OVERFLOW_ERROR is set.
+ *
+ * @see ucnv_fromAlgorithmic
+ * @see ucnv_convert
+ * @see ucnv_convertEx
+ * @see ucnv_fromUnicode
+ * @see ucnv_toUnicode
+ * @see ucnv_fromUChars
+ * @see ucnv_toUChars
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_toAlgorithmic(UConverterType algorithmicType,
+                   UConverter *cnv,
+                   char *target, int32_t targetCapacity,
+                   const char *source, int32_t sourceLength,
+                   UErrorCode *pErrorCode);
+
+/**
+ * Convert from one external charset to another.
+ * Internally, the text is converted to and from the 16-bit Unicode "pivot"
+ * using ucnv_convertEx(). ucnv_fromAlgorithmic() works exactly like ucnv_convert()
+ * except that the two converters need not be looked up and opened completely.
+ *
+ * The source-to-pivot conversion uses a purely algorithmic converter
+ * according to the specified type, e.g., UCNV_UTF8 for a UTF-8 converter.
+ * The pivot-to-target conversion uses the cnv converter parameter.
+ *
+ * Internally, the algorithmic converter is opened and closed for each
+ * function call, which is more efficient than using the public ucnv_open()
+ * but somewhat less efficient than only resetting an existing converter
+ * and using ucnv_convertEx().
+ *
+ * This function is more convenient than ucnv_convertEx() for single-string
+ * conversions, especially when "preflighting" is desired (returning the length
+ * of the complete output even if it does not fit into the target buffer;
+ * see the User Guide Strings chapter). See ucnv_convert() for details.
+ *
+ * @param cnv               The converter that is used to convert
+ *                          from the UTF-16 pivot buffer to the target.
+ * @param algorithmicType   UConverterType constant identifying the desired source
+ *                          charset as a purely algorithmic converter.
+ *                          Those are converters for Unicode charsets like
+ *                          UTF-8, BOCU-1, SCSU, UTF-7, IMAP-mailbox-name, etc.,
+ *                          as well as US-ASCII and ISO-8859-1.
+ * @param target            Pointer to the output buffer.
+ * @param targetCapacity    Capacity of the target, in bytes.
+ * @param source            Pointer to the input buffer.
+ * @param sourceLength      Length of the input text, in bytes
+ * @param pErrorCode        ICU error code in/out parameter.
+ *                          Must fulfill U_SUCCESS before the function call.
+ * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity
+ *         and a U_BUFFER_OVERFLOW_ERROR is set.
+ *
+ * @see ucnv_fromAlgorithmic
+ * @see ucnv_convert
+ * @see ucnv_convertEx
+ * @see ucnv_fromUnicode
+ * @see ucnv_toUnicode
+ * @see ucnv_fromUChars
+ * @see ucnv_toUChars
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_fromAlgorithmic(UConverter *cnv,
+                     UConverterType algorithmicType,
+                     char *target, int32_t targetCapacity,
+                     const char *source, int32_t sourceLength,
+                     UErrorCode *pErrorCode);
+
+/**
+ * Frees up memory occupied by unused, cached converter shared data.
+ *
+ * @return the number of cached converters successfully deleted
+ * @see ucnv_close
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_flushCache(void);
+
+/**
+ * Returns the number of available converters, as per the alias file.
+ *
+ * @return the number of available converters
+ * @see ucnv_getAvailableName
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+ucnv_countAvailable(void);
+
+/**
+ * Gets the canonical converter name of the specified converter from a list of
+ * all available converters contaied in the alias file. All converters
+ * in this list can be opened.
+ *
+ * @param n the index to a converter available on the system (in the range <TT>[0..ucnv_countAvaiable()]</TT>)
+ * @return a pointer a string (library owned), or <TT>NULL</TT> if the index is out of bounds.
+ * @see ucnv_countAvailable
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2
+ucnv_getAvailableName(int32_t n);
+
+/**
+ * Returns a UEnumeration to enumerate all of the canonical converter
+ * names, as per the alias file, regardless of the ability to open each
+ * converter.
+ *
+ * @return A UEnumeration object for getting all the recognized canonical
+ *   converter names.
+ * @see ucnv_getAvailableName
+ * @see uenum_close
+ * @see uenum_next
+ * @stable ICU 2.4
+ */
+U_STABLE UEnumeration * U_EXPORT2
+ucnv_openAllNames(UErrorCode *pErrorCode);
+
+/**
+ * Gives the number of aliases for a given converter or alias name.
+ * If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.
+ * This method only enumerates the listed entries in the alias file.
+ * @param alias alias name
+ * @param pErrorCode error status
+ * @return number of names on alias list for given alias
+ * @stable ICU 2.0
+ */
+U_STABLE uint16_t U_EXPORT2 
+ucnv_countAliases(const char *alias, UErrorCode *pErrorCode);
+
+/**
+ * Gives the name of the alias at given index of alias list.
+ * This method only enumerates the listed entries in the alias file.
+ * If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.
+ * @param alias alias name
+ * @param n index in alias list
+ * @param pErrorCode result of operation
+ * @return returns the name of the alias at given index
+ * @see ucnv_countAliases
+ * @stable ICU 2.0
+ */
+U_STABLE const char * U_EXPORT2 
+ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode);
+
+/**
+ * Fill-up the list of alias names for the given alias.
+ * This method only enumerates the listed entries in the alias file.
+ * If the alias is ambiguous, then the preferred converter is used
+ * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.
+ * @param alias alias name
+ * @param aliases fill-in list, aliases is a pointer to an array of
+ *        <code>ucnv_countAliases()</code> string-pointers
+ *        (<code>const char *</code>) that will be filled in.
+ *        The strings themselves are owned by the library.
+ * @param pErrorCode result of operation
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode);
+
+/**
+ * Return a new UEnumeration object for enumerating all the
+ * alias names for a given converter that are recognized by a standard.
+ * This method only enumerates the listed entries in the alias file.
+ * The convrtrs.txt file can be modified to change the results of
+ * this function.
+ * The first result in this list is the same result given by
+ * <code>ucnv_getStandardName</code>, which is the default alias for
+ * the specified standard name. The returned object must be closed with
+ * <code>uenum_close</code> when you are done with the object.
+ *
+ * @param convName original converter name
+ * @param standard name of the standard governing the names; MIME and IANA
+ *      are such standards
+ * @param pErrorCode The error code
+ * @return A UEnumeration object for getting all aliases that are recognized
+ *      by a standard. If any of the parameters are invalid, NULL
+ *      is returned.
+ * @see ucnv_getStandardName
+ * @see uenum_close
+ * @see uenum_next
+ * @stable ICU 2.2
+ */
+U_STABLE UEnumeration * U_EXPORT2
+ucnv_openStandardNames(const char *convName,
+                       const char *standard,
+                       UErrorCode *pErrorCode);
+
+/**
+ * Gives the number of standards associated to converter names.
+ * @return number of standards
+ * @stable ICU 2.0
+ */
+U_STABLE uint16_t U_EXPORT2
+ucnv_countStandards(void);
+
+/**
+ * Gives the name of the standard at given index of standard list.
+ * @param n index in standard list
+ * @param pErrorCode result of operation
+ * @return returns the name of the standard at given index. Owned by the library.
+ * @stable ICU 2.0
+ */
+U_STABLE const char * U_EXPORT2
+ucnv_getStandard(uint16_t n, UErrorCode *pErrorCode);
+
+/**
+ * Returns a standard name for a given converter name.
+ * <p>
+ * Example alias table:<br>
+ * conv alias1 { STANDARD1 } alias2 { STANDARD1* }
+ * <p>
+ * Result of ucnv_getStandardName("conv", "STANDARD1") from example
+ * alias table:<br>
+ * <b>"alias2"</b>
+ *
+ * @param name original converter name
+ * @param standard name of the standard governing the names; MIME and IANA
+ *        are such standards
+ * @param pErrorCode result of operation
+ * @return returns the standard converter name;
+ *         if a standard converter name cannot be determined,
+ *         then <code>NULL</code> is returned. Owned by the library.
+ * @stable ICU 2.0
+ */
+U_STABLE const char * U_EXPORT2
+ucnv_getStandardName(const char *name, const char *standard, UErrorCode *pErrorCode);
+
+/**
+ * This function will return the internal canonical converter name of the
+ * tagged alias. This is the opposite of ucnv_openStandardNames, which
+ * returns the tagged alias given the canonical name.
+ * <p>
+ * Example alias table:<br>
+ * conv alias1 { STANDARD1 } alias2 { STANDARD1* }
+ * <p>
+ * Result of ucnv_getStandardName("alias1", "STANDARD1") from example
+ * alias table:<br>
+ * <b>"conv"</b>
+ *
+ * @return returns the canonical converter name;
+ *         if a standard or alias name cannot be determined,
+ *         then <code>NULL</code> is returned. The returned string is
+ *         owned by the library.
+ * @see ucnv_getStandardName
+ * @stable ICU 2.4
+ */
+U_STABLE const char * U_EXPORT2
+ucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode);
+
+/**
+ * returns the current default converter name.
+ *
+ * @return returns the current default converter name;
+ *         if a default converter name cannot be determined,
+ *         then <code>NULL</code> is returned.
+ *         Storage owned by the library
+ * @see ucnv_setDefaultName
+ * @stable ICU 2.0
+ */
+U_STABLE const char * U_EXPORT2
+ucnv_getDefaultName(void);
+
+/**
+ * This function sets the current default converter name.
+ * DO NOT call this function from multiple threads! This function is not
+ * thread safe. If this function needs to be called, it should be called
+ * during application initialization. Most of the time, the results from
+ * ucnv_getDefaultName() is sufficient for your application.
+ * @param name the converter name to be the default (must exist).
+ * @see ucnv_getDefaultName
+ * @system
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_setDefaultName(const char *name);
+
+/**
+ * Fixes the backslash character mismapping.  For example, in SJIS, the backslash 
+ * character in the ASCII portion is also used to represent the yen currency sign.  
+ * When mapping from Unicode character 0x005C, it's unclear whether to map the 
+ * character back to yen or backslash in SJIS.  This function will take the input
+ * buffer and replace all the yen sign characters with backslash.  This is necessary
+ * when the user tries to open a file with the input buffer on Windows.
+ * This function will test the converter to see whether such mapping is
+ * required.  You can sometimes avoid using this function by using the correct version
+ * of Shift-JIS.
+ *
+ * @param cnv The converter representing the target codepage.
+ * @param source the input buffer to be fixed
+ * @param sourceLen the length of the input buffer
+ * @see ucnv_isAmbiguous
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_fixFileSeparator(const UConverter *cnv, UChar *source, int32_t sourceLen);
+
+/**
+ * Determines if the converter contains ambiguous mappings of the same
+ * character or not.
+ * @param cnv the converter to be tested
+ * @return TRUE if the converter contains ambiguous mapping of the same 
+ * character, FALSE otherwise.
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2
+ucnv_isAmbiguous(const UConverter *cnv);
+
+/**
+ * Sets the converter to use fallback mapping or not.
+ * @param cnv The converter to set the fallback mapping usage on.
+ * @param usesFallback TRUE if the user wants the converter to take advantage of the fallback 
+ * mapping, FALSE otherwise.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_setFallback(UConverter *cnv, UBool usesFallback);
+
+/**
+ * Determines if the converter uses fallback mappings or not.
+ * @param cnv The converter to be tested
+ * @return TRUE if the converter uses fallback, FALSE otherwise.
+ * @stable ICU 2.0
+ */
+U_STABLE UBool U_EXPORT2 
+ucnv_usesFallback(const UConverter *cnv);
+
+/**
+ * Detects Unicode signature byte sequences at the start of the byte stream
+ * and returns the charset name of the indicated Unicode charset.
+ * NULL is returned when no Unicode signature is recognized.
+ * The number of bytes in the signature is output as well.
+ *
+ * The caller can ucnv_open() a converter using the charset name.
+ * The first code unit (UChar) from the start of the stream will be U+FEFF
+ * (the Unicode BOM/signature character) and can usually be ignored.
+ *
+ * For most Unicode charsets it is also possible to ignore the indicated
+ * number of initial stream bytes and start converting after them.
+ * However, there are stateful Unicode charsets (UTF-7 and BOCU-1) for which
+ * this will not work. Therefore, it is best to ignore the first output UChar
+ * instead of the input signature bytes.
+ * <p>
+ * Usage:
+ * @code     
+ *      UErrorCode err = U_ZERO_ERROR;
+ *      char input[] = { '\xEF','\xBB', '\xBF','\x41','\x42','\x43' };
+ *      int32_t signatureLength = 0;
+ *      char *encoding = ucnv_detectUnicodeSignature(input,sizeof(input),&signatureLength,&err);
+ *      UConverter *conv = NULL;
+ *      UChar output[100];
+ *      UChar *target = output, *out;
+ *      char *source = input;
+ *      if(encoding!=NULL && U_SUCCESS(err)){
+ *          // should signature be discarded ?
+ *          conv = ucnv_open(encoding, &err);
+ *          // do the conversion
+ *          ucnv_toUnicode(conv,
+ *                         target, output + sizeof(output)/U_SIZEOF_UCHAR,
+ *                         source, input + sizeof(input),
+ *                         NULL, TRUE, &err);
+ *          out = output;
+ *          if (discardSignature){
+ *              ++out; // ignore initial U+FEFF
+ *          }
+ *          while(out != target) {
+ *              printf("%04x ", *out++);
+ *          }
+ *          puts("");
+ *      }
+ *     
+ * @endcode
+ *
+ * @param source            The source string in which the signature should be detected.
+ * @param sourceLength      Length of the input string, or -1 if terminated with a NUL byte.
+ * @param signatureLength   A pointer to int32_t to receive the number of bytes that make up the signature 
+ *                          of the detected UTF. 0 if not detected.
+ *                          Can be a NULL pointer.
+ * @param pErrorCode        ICU error code in/out parameter.
+ *                          Must fulfill U_SUCCESS before the function call.
+ * @return The name of the encoding detected. NULL if encoding is not detected. 
+ * @stable ICU 2.4
+ */
+U_STABLE const char* U_EXPORT2
+ucnv_detectUnicodeSignature(const char* source,
+                            int32_t sourceLength,
+                            int32_t *signatureLength,
+                            UErrorCode *pErrorCode);
+
+/**
+ * Returns the number of UChars held in the converter's internal state 
+ * because more input is needed for completing the conversion. This function is 
+ * useful for mapping semantics of ICU's converter interface to those of iconv,
+ * and this information is not needed for normal conversion.
+ * @param cnv       The converter in which the input is held
+ * @param status    ICU error code in/out parameter.
+ *                  Must fulfill U_SUCCESS before the function call.
+ * @return The number of UChars in the state. -1 if an error is encountered.
+ * @draft ICU 3.4
+ */
+U_DRAFT int32_t U_EXPORT2
+ucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status);
+
+/**
+ * Returns the number of chars held in the converter's internal state
+ * because more input is needed for completing the conversion. This function is 
+ * useful for mapping semantics of ICU's converter interface to those of iconv,
+ * and this information is not needed for normal conversion.
+ * @param cnv       The converter in which the input is held as internal state
+ * @param status    ICU error code in/out parameter.
+ *                  Must fulfill U_SUCCESS before the function call.
+ * @return The number of chars in the state. -1 if an error is encountered.
+ * @draft ICU 3.4
+ */
+U_DRAFT int32_t U_EXPORT2
+ucnv_toUCountPending(const UConverter* cnv, UErrorCode* status);
+
+#endif
+
+#endif
+/*_UCNV*/

Added: MacRuby/branches/icu/unicode/ucnv_cb.h
===================================================================
--- MacRuby/branches/icu/unicode/ucnv_cb.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ucnv_cb.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,162 @@
+/*
+**********************************************************************
+*   Copyright (C) 2000-2004, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+ *  ucnv_cb.h:
+ *  External APIs for the ICU's codeset conversion library
+ *  Helena Shih
+ * 
+ * Modification History:
+ *
+ *   Date        Name        Description
+ */
+
+/**
+ * \file 
+ * \brief C UConverter functions to aid the writers of callbacks
+ *
+ * <h2> Callback API for UConverter </h2>
+ * 
+ * These functions are provided here for the convenience of the callback
+ * writer. If you are just looking for callback functions to use, please
+ * see ucnv_err.h.  DO NOT call these functions directly when you are 
+ * working with converters, unless your code has been called as a callback
+ * via ucnv_setFromUCallback or ucnv_setToUCallback !!
+ * 
+ * A note about error codes and overflow.  Unlike other ICU functions,
+ * these functions do not expect the error status to be U_ZERO_ERROR.
+ * Callbacks must be much more careful about their error codes.
+ * The error codes used here are in/out parameters, which should be passed
+ * back in the callback's error parameter.
+ * 
+ * For example, if you call ucnv_cbfromUWriteBytes to write data out 
+ * to the output codepage, it may return U_BUFFER_OVERFLOW_ERROR if 
+ * the data did not fit in the target. But this isn't a failing error, 
+ * in fact, ucnv_cbfromUWriteBytes may be called AGAIN with the error
+ * status still U_BUFFER_OVERFLOW_ERROR to attempt to write further bytes,
+ * which will also go into the internal overflow buffers.
+ * 
+ * Concerning offsets, the 'offset' parameters here are relative to the start
+ * of SOURCE.  For example, Suppose the string "ABCD" was being converted 
+ * from Unicode into a codepage which doesn't have a mapping for 'B'.
+ * 'A' will be written out correctly, but
+ * The FromU Callback will be called on an unassigned character for 'B'.
+ * At this point, this is the state of the world:
+ *    Target:    A [..]     [points after A]
+ *    Source:  A B [C] D    [points to C - B has been consumed]
+ *             0 1  2  3 
+ *    codePoint = "B"       [the unassigned codepoint] 
+ * 
+ * Now, suppose a callback wants to write the substitution character '?' to
+ * the target. It calls ucnv_cbFromUWriteBytes() to write the ?. 
+ * It should pass ZERO as the offset, because the offset as far as the 
+ * callback is concerned is relative to the SOURCE pointer [which points 
+ * before 'C'.]  If the callback goes into the args and consumes 'C' also,
+ * it would call FromUWriteBytes with an offset of 1 (and advance the source
+ * pointer).
+ *
+ */
+
+#ifndef UCNV_CB_H
+#define UCNV_CB_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION
+
+#include "unicode/ucnv.h"
+#include "unicode/ucnv_err.h"
+
+/**
+ * ONLY used by FromU callback functions.
+ * Writes out the specified byte output bytes to the target byte buffer or to converter internal buffers.
+ *
+ * @param args callback fromUnicode arguments
+ * @param source source bytes to write
+ * @param length length of bytes to write
+ * @param offsetIndex the relative offset index from callback.
+ * @param err error status. If <TT>U_BUFFER_OVERFLOW</TT> is returned, then U_BUFFER_OVERFLOW <STRONG>must</STRONG> 
+ * be returned to the user, because it means that not all data could be written into the target buffer, and some is 
+ * in the converter error buffer.
+ * @see ucnv_cbFromUWriteSub
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args,
+                        const char* source,
+                        int32_t length,
+                        int32_t offsetIndex,
+                        UErrorCode * err);
+
+/**
+ * ONLY used by FromU callback functions.  
+ * This function will write out the correct substitution character sequence 
+ * to the target.
+ *
+ * @param args callback fromUnicode arguments
+ * @param offsetIndex the relative offset index from the current source pointer to be used
+ * @param err error status. If <TT>U_BUFFER_OVERFLOW</TT> is returned, then U_BUFFER_OVERFLOW <STRONG>must</STRONG> 
+ * be returned to the user, because it means that not all data could be written into the target buffer, and some is 
+ * in the converter error buffer.
+ * @see ucnv_cbFromUWriteBytes
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 
+ucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args,
+                      int32_t offsetIndex,
+                      UErrorCode * err);
+
+/**
+ * ONLY used by fromU callback functions.  
+ * This function will write out the error character(s) to the target UChar buffer.
+ *
+ * @param args callback fromUnicode arguments
+ * @param source pointer to pointer to first UChar to write [on exit: 1 after last UChar processed]
+ * @param sourceLimit pointer after last UChar to write
+ * @param offsetIndex the relative offset index from callback which will be set
+ * @param err error status <TT>U_BUFFER_OVERFLOW</TT>
+ * @see ucnv_cbToUWriteSub
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 ucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args,
+                             const UChar** source,
+                             const UChar*  sourceLimit,
+                             int32_t offsetIndex,
+                             UErrorCode * err);
+
+/**
+ * ONLY used by ToU callback functions.
+ *  This function will write out the specified characters to the target 
+ * UChar buffer.
+ *
+ * @param args callback toUnicode arguments
+ * @param source source string to write
+ * @param length the length of source string
+ * @param offsetIndex the relative offset index which will be written.
+ * @param err error status <TT>U_BUFFER_OVERFLOW</TT>
+ * @see ucnv_cbToUWriteSub
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 ucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args,
+                                             const UChar* source,
+                                             int32_t length,
+                                             int32_t offsetIndex,
+                                             UErrorCode * err);
+
+/**
+ * ONLY used by ToU  callback functions.  
+ * This function will write out the Unicode substitution character (U+FFFD).
+ *
+ * @param args callback fromUnicode arguments
+ * @param offsetIndex the relative offset index from callback.
+ * @param err error status <TT>U_BUFFER_OVERFLOW</TT>
+ * @see ucnv_cbToUWriteUChars
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 ucnv_cbToUWriteSub (UConverterToUnicodeArgs *args,
+                       int32_t offsetIndex,
+                       UErrorCode * err);
+#endif
+
+#endif

Added: MacRuby/branches/icu/unicode/ucnv_err.h
===================================================================
--- MacRuby/branches/icu/unicode/ucnv_err.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/ucnv_err.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,456 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+ *
+ *
+ *   ucnv_err.h:
+ */
+
+/**
+ * \file
+ * \brief C UConverter predefined error callbacks
+ *
+ *  <h2>Error Behaviour Functions</h2>
+ *  Defines some error behaviour functions called by ucnv_{from,to}Unicode
+ *  These are provided as part of ICU and many are stable, but they
+ *  can also be considered only as an example of what can be done with
+ *  callbacks.  You may of course write your own.
+ *
+ *  If you want to write your own, you may also find the functions from
+ *  ucnv_cb.h useful when writing your own callbacks.
+ *
+ *  These functions, although public, should NEVER be called directly.
+ *  They should be used as parameters to the ucnv_setFromUCallback
+ *  and ucnv_setToUCallback functions, to set the behaviour of a converter
+ *  when it encounters ILLEGAL/UNMAPPED/INVALID sequences.
+ *
+ *  usage example:  'STOP' doesn't need any context, but newContext
+ *    could be set to something other than 'NULL' if needed. The available
+ *    contexts in this header can modify the default behavior of the callback.
+ *
+ *  \code
+ *  UErrorCode err = U_ZERO_ERROR;
+ *  UConverter *myConverter = ucnv_open("ibm-949", &err);
+ *  const void *oldContext;
+ *  UConverterFromUCallback oldAction;
+ *
+ *
+ *  if (U_SUCCESS(err))
+ *  {
+ *      ucnv_setFromUCallBack(myConverter,
+ *                       UCNV_FROM_U_CALLBACK_STOP,
+ *                       NULL,
+ *                       &oldAction,
+ *                       &oldContext,
+ *                       &status);
+ *  }
+ *  \endcode
+ *
+ *  The code above tells "myConverter" to stop when it encounters an
+ *  ILLEGAL/TRUNCATED/INVALID sequences when it is used to convert from
+ *  Unicode -> Codepage. The behavior from Codepage to Unicode is not changed,
+ *  and ucnv_setToUCallBack would need to be called in order to change
+ *  that behavior too.
+ *
+ *  Here is an example with a context:
+ *
+ *  \code
+ *  UErrorCode err = U_ZERO_ERROR;
+ *  UConverter *myConverter = ucnv_open("ibm-949", &err);
+ *  const void *oldContext;
+ *  UConverterFromUCallback oldAction;
+ *
+ *
+ *  if (U_SUCCESS(err))
+ *  {
+ *      ucnv_setToUCallBack(myConverter,
+ *                       UCNV_TO_U_CALLBACK_SUBSTITUTE,
+ *                       UCNV_SUB_STOP_ON_ILLEGAL,
+ *                       &oldAction,
+ *                       &oldContext,
+ *                       &status);
+ *  }
+ *  \endcode
+ *
+ *  The code above tells "myConverter" to stop when it encounters an
+ *  ILLEGAL/TRUNCATED/INVALID sequences when it is used to convert from
+ *  Codepage -> Unicode. Any unmapped and legal characters will be
+ *  substituted to be the default substitution character.
+ */
+
+#ifndef UCNV_ERR_H
+#define UCNV_ERR_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION
+
+/** Forward declaring the UConverter structure. @stable ICU 2.0 */
+struct UConverter;
+
+/** @stable ICU 2.0 */
+typedef struct UConverter UConverter;
+
+/**
+ * FROM_U, TO_U context options for sub callback
+ * @stable ICU 2.0
+ */
+#define UCNV_SUB_STOP_ON_ILLEGAL "i"
+
+/**
+ * FROM_U, TO_U context options for skip callback
+ * @stable ICU 2.0
+ */
+#define UCNV_SKIP_STOP_ON_ILLEGAL "i"
+
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to ICU (%UXXXX) 
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_ICU       NULL
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to JAVA (\\uXXXX)
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_JAVA      "J"
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX)
+ * TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX)
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_C         "C"
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&amp;#DDDD;)\endhtmlonly
+ * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&amp;#DDDD;)\endhtmlonly
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_XML_DEC   "D"
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&amp;#xXXXX;)\endhtmlonly
+ * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Hex escape \htmlonly(&amp;#xXXXX;)\endhtmlonly
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_XML_HEX   "X"
+/**
+ * FROM_U_CALLBACK_ESCAPE context option to escape teh code unit according to Unicode (U+XXXXX)
+ * @stable ICU 2.0
+ */
+#define UCNV_ESCAPE_UNICODE   "U"
+
+/** 
+ * The process condition code to be used with the callbacks.  
+ * Codes which are greater than UCNV_IRREGULAR should be 
+ * passed on to any chained callbacks.
+ * @stable ICU 2.0
+ */
+typedef enum {
+    UCNV_UNASSIGNED = 0,  /**< The code point is unassigned.
+                             The error code U_INVALID_CHAR_FOUND will be set. */
+    UCNV_ILLEGAL = 1,     /**< The code point is illegal. For example, 
+                             \\x81\\x2E is illegal in SJIS because \\x2E
+                             is not a valid trail byte for the \\x81 
+                             lead byte.
+                             Also, starting with Unicode 3.0.1, non-shortest byte sequences
+                             in UTF-8 (like \\xC1\\xA1 instead of \\x61 for U+0061)
+                             are also illegal, not just irregular.
+                             The error code U_ILLEGAL_CHAR_FOUND will be set. */
+    UCNV_IRREGULAR = 2,   /**< The codepoint is not a regular sequence in 
+                             the encoding. For example, \\xED\\xA0\\x80..\\xED\\xBF\\xBF
+                             are irregular UTF-8 byte sequences for single surrogate
+                             code points.
+                             The error code U_INVALID_CHAR_FOUND will be set. */
+    UCNV_RESET = 3,       /**< The callback is called with this reason when a
+                             'reset' has occured. Callback should reset all
+                             state. */
+    UCNV_CLOSE = 4,        /**< Called when the converter is closed. The
+                             callback should release any allocated memory.*/
+    UCNV_CLONE = 5         /**< Called when ucnv_safeClone() is called on the
+                              converter. the pointer available as the
+                              'context' is an alias to the original converters'
+                              context pointer. If the context must be owned
+                              by the new converter, the callback must clone 
+                              the data and call ucnv_setFromUCallback 
+                              (or setToUCallback) with the correct pointer.
+                              @stable ICU 2.2
+                           */
+} UConverterCallbackReason;
+
+
+/**
+ * The structure for the fromUnicode callback function parameter.
+ * @stable ICU 2.0
+ */
+typedef struct {
+    uint16_t size;              /**< The size of this struct. @stable ICU 2.0 */
+    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0    */
+    UConverter *converter;      /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0  */
+    const UChar *source;        /**< Pointer to the source source buffer. @stable ICU 2.0    */
+    const UChar *sourceLimit;   /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0    */
+    char *target;               /**< Pointer to the target buffer. @stable ICU 2.0    */
+    const char *targetLimit;    /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0     */
+    int32_t *offsets;           /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
+} UConverterFromUnicodeArgs;
+
+
+/**
+ * The structure for the toUnicode callback function parameter.
+ * @stable ICU 2.0
+ */
+typedef struct {
+    uint16_t size;              /**< The size of this struct   @stable ICU 2.0 */
+    UBool flush;                /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0   */
+    UConverter *converter;      /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0 */
+    const char *source;         /**< Pointer to the source source buffer. @stable ICU 2.0    */
+    const char *sourceLimit;    /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0    */
+    UChar *target;              /**< Pointer to the target buffer. @stable ICU 2.0    */
+    const UChar *targetLimit;   /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0     */
+    int32_t *offsets;           /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0  */
+} UConverterToUnicodeArgs;
+
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This From Unicode callback STOPS at the ILLEGAL_SEQUENCE,
+ * returning the error code back to the caller immediately.
+ *
+ * @param context Pointer to the callback's private data
+ * @param fromUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint.
+ * @param reason Defines the reason the callback was invoked
+ * @param err This should always be set to a failure status prior to calling.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_STOP (
+                  const void *context,
+                  UConverterFromUnicodeArgs *fromUArgs,
+                  const UChar* codeUnits,
+                  int32_t length,
+                  UChar32 codePoint,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This To Unicode callback STOPS at the ILLEGAL_SEQUENCE,
+ * returning the error code back to the caller immediately.
+ *
+ * @param context Pointer to the callback's private data
+ * @param toUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param reason Defines the reason the callback was invoked
+ * @param err This should always be set to a failure status prior to calling.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_STOP (
+                  const void *context,
+                  UConverterToUnicodeArgs *toUArgs,
+                  const char* codeUnits,
+                  int32_t length,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This From Unicode callback skips any ILLEGAL_SEQUENCE, or
+ * skips only UNASSINGED_SEQUENCE depending on the context parameter
+ * simply ignoring those characters. 
+ *
+ * @param context  The function currently recognizes the callback options:
+ *                 UCNV_SKIP_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE,
+ *                      returning the error code back to the caller immediately.
+ *                 NULL: Skips any ILLEGAL_SEQUENCE
+ * @param fromUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint.
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SKIP (
+                  const void *context,
+                  UConverterFromUnicodeArgs *fromUArgs,
+                  const UChar* codeUnits,
+                  int32_t length,
+                  UChar32 codePoint,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This From Unicode callback will Substitute the ILLEGAL SEQUENCE, or 
+ * UNASSIGNED_SEQUENCE depending on context parameter, with the
+ * current substitution string for the converter. This is the default
+ * callback.
+ *
+ * @param context The function currently recognizes the callback options:
+ *                 UCNV_SUB_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE,
+ *                      returning the error code back to the caller immediately.
+ *                 NULL: Substitutes any ILLEGAL_SEQUENCE
+ * @param fromUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint.
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @see ucnv_setSubstChars
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SUBSTITUTE (
+                  const void *context,
+                  UConverterFromUnicodeArgs *fromUArgs,
+                  const UChar* codeUnits,
+                  int32_t length,
+                  UChar32 codePoint,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This From Unicode callback will Substitute the ILLEGAL SEQUENCE with the
+ * hexadecimal representation of the illegal codepoints
+ *
+ * @param context The function currently recognizes the callback options:
+ *        <ul>
+ *        <li>UCNV_ESCAPE_ICU: Substitues the  ILLEGAL SEQUENCE with the hexadecimal 
+ *          representation in the format  %UXXXX, e.g. "%uFFFE%u00AC%uC8FE"). 
+ *          In the Event the converter doesn't support the characters {%,U}[A-F][0-9], 
+ *          it will  substitute  the illegal sequence with the substitution characters.
+ *          Note that  codeUnit(32bit int eg: unit of a surrogate pair) is represented as
+ *          %UD84D%UDC56</li>
+ *        <li>UCNV_ESCAPE_JAVA: Substitues the  ILLEGAL SEQUENCE with the hexadecimal 
+ *          representation in the format  \\uXXXX, e.g. "\\uFFFE\\u00AC\\uC8FE"). 
+ *          In the Event the converter doesn't support the characters {\,u}[A-F][0-9], 
+ *          it will  substitute  the illegal sequence with the substitution characters.
+ *          Note that  codeUnit(32bit int eg: unit of a surrogate pair) is represented as
+ *          \\uD84D\\uDC56</li>
+ *        <li>UCNV_ESCAPE_C: Substitues the  ILLEGAL SEQUENCE with the hexadecimal 
+ *          representation in the format  \\uXXXX, e.g. "\\uFFFE\\u00AC\\uC8FE"). 
+ *          In the Event the converter doesn't support the characters {\,u,U}[A-F][0-9], 
+ *          it will  substitute  the illegal sequence with the substitution characters.
+ *          Note that  codeUnit(32bit int eg: unit of a surrogate pair) is represented as
+ *          \\U00023456</li>
+ *        <li>UCNV_ESCAPE_XML_DEC: Substitues the  ILLEGAL SEQUENCE with the decimal 
+ *          representation in the format \htmlonly&amp;#DDDDDDDD;, e.g. "&amp;#65534;&amp;#172;&amp;#51454;")\endhtmlonly. 
+ *          In the Event the converter doesn't support the characters {&amp;,#}[0-9], 
+ *          it will  substitute  the illegal sequence with the substitution characters.
+ *          Note that  codeUnit(32bit int eg: unit of a surrogate pair) is represented as
+ *          &amp;#144470; and Zero padding is ignored.</li>
+ *        <li>UCNV_ESCAPE_XML_HEX:Substitues the  ILLEGAL SEQUENCE with the decimal 
+ *          representation in the format \htmlonly&amp;#xXXXX; e.g. "&amp;#xFFFE;&amp;#x00AC;&amp;#xC8FE;")\endhtmlonly. 
+ *          In the Event the converter doesn't support the characters {&,#,x}[0-9], 
+ *          it will  substitute  the illegal sequence with the substitution characters.
+ *          Note that  codeUnit(32bit int eg: unit of a surrogate pair) is represented as
+ *          \htmlonly&amp;#x23456;\endhtmlonly</li>
+ *        </ul>
+ * @param fromUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint.
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_ESCAPE (
+                  const void *context,
+                  UConverterFromUnicodeArgs *fromUArgs,
+                  const UChar* codeUnits,
+                  int32_t length,
+                  UChar32 codePoint,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This To Unicode callback skips any ILLEGAL_SEQUENCE, or
+ * skips only UNASSINGED_SEQUENCE depending on the context parameter
+ * simply ignoring those characters. 
+ *
+ * @param context  The function currently recognizes the callback options:
+ *                 UCNV_SKIP_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE,
+ *                      returning the error code back to the caller immediately.
+ *                 NULL: Skips any ILLEGAL_SEQUENCE
+ * @param toUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SKIP (
+                  const void *context,
+                  UConverterToUnicodeArgs *toUArgs,
+                  const char* codeUnits,
+                  int32_t length,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This To Unicode callback will Substitute the ILLEGAL SEQUENCE,or 
+ * UNASSIGNED_SEQUENCE depending on context parameter,  with the
+ * Unicode substitution character, U+FFFD.
+ *
+ * @param context  The function currently recognizes the callback options:
+ *                 UCNV_SUB_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE,
+ *                      returning the error code back to the caller immediately.
+ *                 NULL: Substitutes any ILLEGAL_SEQUENCE
+ * @param toUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SUBSTITUTE (
+                  const void *context,
+                  UConverterToUnicodeArgs *toUArgs,
+                  const char* codeUnits,
+                  int32_t length,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+/**
+ * DO NOT CALL THIS FUNCTION DIRECTLY!
+ * This To Unicode callback will Substitute the ILLEGAL SEQUENCE with the
+ * hexadecimal representation of the illegal bytes
+ *  (in the format  %XNN, e.g. "%XFF%X0A%XC8%X03").
+ *
+ * @param context This function currently recognizes the callback options:
+ *      UCNV_ESCAPE_ICU, UCNV_ESCAPE_JAVA, UCNV_ESCAPE_C, UCNV_ESCAPE_XML_DEC,
+ *      UCNV_ESCAPE_XML_HEX and UCNV_ESCAPE_UNICODE.
+ * @param toUArgs Information about the conversion in progress
+ * @param codeUnits Points to 'length' bytes of the concerned codepage sequence
+ * @param length Size (in bytes) of the concerned codepage sequence
+ * @param reason Defines the reason the callback was invoked
+ * @param err Return value will be set to success if the callback was handled,
+ *      otherwise this value will be set to a failure status.
+ * @stable ICU 2.0
+ */
+
+U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_ESCAPE (
+                  const void *context,
+                  UConverterToUnicodeArgs *toUArgs,
+                  const char* codeUnits,
+                  int32_t length,
+                  UConverterCallbackReason reason,
+                  UErrorCode * err);
+
+#endif
+
+#endif
+
+/*UCNV_ERR_H*/ 

Added: MacRuby/branches/icu/unicode/uconfig.h
===================================================================
--- MacRuby/branches/icu/unicode/uconfig.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uconfig.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,215 @@
+/*  
+**********************************************************************
+*   Copyright (C) 2002-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   file name:  uconfig.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002sep19
+*   created by: Markus W. Scherer
+*/
+
+#ifndef __UCONFIG_H__
+#define __UCONFIG_H__
+
+/*!
+ * \file
+ * \brief Switches for excluding parts of ICU library code modules.
+ *
+ * Allows to build partial, smaller libraries for special purposes.
+ * By default, all modules are built.
+ * The switches are fairly coarse, controlling large modules.
+ * Basic services cannot be turned off.
+ *
+ * Building with any of these options does not guarantee that the
+ * ICU build process will completely work. It is recommended that
+ * the ICU libraries and data be built using the normal build.
+ * At that time you should remove the data used by those services.
+ * After building the ICU data library, you should rebuild the ICU
+ * libraries with these switches customized to your needs.
+ *
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def UCONFIG_ONLY_COLLATION
+ * This switch turns off modules that are not needed for collation.
+ *
+ * It does not turn off legacy conversion because that is necessary
+ * for ICU to work on EBCDIC platforms (for the default converter).
+ * If you want "only collation" and do not build for EBCDIC,
+ * then you can define UCONFIG_NO_LEGACY_CONVERSION 1 as well.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_ONLY_COLLATION
+#   define UCONFIG_ONLY_COLLATION 0
+#endif
+
+#if UCONFIG_ONLY_COLLATION
+    /* common library */
+#   define UCONFIG_NO_BREAK_ITERATION 1
+#   define UCONFIG_NO_IDNA 1
+
+    /* i18n library */
+#   if UCONFIG_NO_COLLATION
+#       error Contradictory collation switches in uconfig.h.
+#   endif
+#   define UCONFIG_NO_FORMATTING 1
+#   define UCONFIG_NO_TRANSLITERATION 1
+#   define UCONFIG_NO_REGULAR_EXPRESSIONS 1
+#endif
+
+/* common library switches -------------------------------------------------- */
+
+/**
+ * \def UCONFIG_NO_FILE_IO
+ * This switch turns off all file access in the common library
+ * where file access is only used for data loading.
+ * ICU data must then be provided in the form of a data DLL (or with an
+ * equivalent way to link to the data residing in an executable,
+ * as in building a combined library with both the common library's code and
+ * the data), or via udata_setCommonData().
+ * Application data must be provided via udata_setAppData() or by using
+ * "open" functions that take pointers to data, for example ucol_openBinary().
+ *
+ * File access is not used at all in the i18n library.
+ *
+ * File access cannot be turned off for the icuio library or for the ICU
+ * test suites and ICU tools.
+ *
+ * @draft ICU 3.6
+ */
+#ifndef UCONFIG_NO_FILE_IO
+#   define UCONFIG_NO_FILE_IO 0
+#endif
+
+/**
+ * \def UCONFIG_NO_CONVERSION
+ * ICU will not completely build with this switch turned on.
+ * This switch turns off all converters.
+ *
+ * @stable ICU 3.2
+ */
+#ifndef UCONFIG_NO_CONVERSION
+#   define UCONFIG_NO_CONVERSION 0
+#endif
+
+#if UCONFIG_NO_CONVERSION
+#   define UCONFIG_NO_LEGACY_CONVERSION 1
+#endif
+
+/**
+ * \def UCONFIG_NO_LEGACY_CONVERSION
+ * This switch turns off all converters except for
+ * - Unicode charsets (UTF-7/8/16/32, CESU-8, SCSU, BOCU-1)
+ * - US-ASCII
+ * - ISO-8859-1
+ *
+ * Turning off legacy conversion is not possible on EBCDIC platforms
+ * because they need ibm-37 or ibm-1047 default converters.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_LEGACY_CONVERSION
+#   define UCONFIG_NO_LEGACY_CONVERSION 0
+#endif
+
+/**
+ * \def UCONFIG_NO_NORMALIZATION
+ * This switch turns off normalization.
+ * It implies turning off several other services as well, for example
+ * collation and IDNA.
+ *
+ * @stable ICU 2.6
+ */
+#ifndef UCONFIG_NO_NORMALIZATION
+#   define UCONFIG_NO_NORMALIZATION 0
+#elif UCONFIG_NO_NORMALIZATION
+    /* common library */
+#   define UCONFIG_NO_IDNA 1
+
+    /* i18n library */
+#   if UCONFIG_ONLY_COLLATION
+#       error Contradictory collation switches in uconfig.h.
+#   endif
+#   define UCONFIG_NO_COLLATION 1
+#   define UCONFIG_NO_TRANSLITERATION 1
+#endif
+
+/**
+ * \def UCONFIG_NO_BREAK_ITERATION
+ * This switch turns off break iteration.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_BREAK_ITERATION
+#   define UCONFIG_NO_BREAK_ITERATION 0
+#endif
+
+/**
+ * \def UCONFIG_NO_IDNA
+ * This switch turns off IDNA.
+ *
+ * @stable ICU 2.6
+ */
+#ifndef UCONFIG_NO_IDNA
+#   define UCONFIG_NO_IDNA 0
+#endif
+
+/* i18n library switches ---------------------------------------------------- */
+
+/**
+ * \def UCONFIG_NO_COLLATION
+ * This switch turns off collation and collation-based string search.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_COLLATION
+#   define UCONFIG_NO_COLLATION 0
+#endif
+
+/**
+ * \def UCONFIG_NO_FORMATTING
+ * This switch turns off formatting and calendar/timezone services.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_FORMATTING
+#   define UCONFIG_NO_FORMATTING 0
+#endif
+
+/**
+ * \def UCONFIG_NO_TRANSLITERATION
+ * This switch turns off transliteration.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_TRANSLITERATION
+#   define UCONFIG_NO_TRANSLITERATION 0
+#endif
+
+/**
+ * \def UCONFIG_NO_REGULAR_EXPRESSIONS
+ * This switch turns off regular expressions.
+ *
+ * @stable ICU 2.4
+ */
+#ifndef UCONFIG_NO_REGULAR_EXPRESSIONS
+#   define UCONFIG_NO_REGULAR_EXPRESSIONS 0
+#endif
+
+/**
+ * \def UCONFIG_NO_SERVICE
+ * This switch turns off service registration.
+ *
+ * @stable ICU 3.2
+ */
+#ifndef UCONFIG_NO_SERVICE
+#   define UCONFIG_NO_SERVICE 0
+#endif
+
+#endif

Added: MacRuby/branches/icu/unicode/udata.h
===================================================================
--- MacRuby/branches/icu/unicode/udata.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/udata.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,389 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  udata.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999oct25
+*   created by: Markus W. Scherer
+*/
+
+#ifndef __UDATA_H__
+#define __UDATA_H__
+
+#include "unicode/utypes.h"
+
+U_CDECL_BEGIN
+
+/**
+ * \file
+ * \brief C API: Data loading interface
+ *
+ * <h2>Information about data loading interface</h2>
+ *
+ * This API is used to find and efficiently load data for ICU and applications
+ * using ICU. It provides an abstract interface that specifies a data type and
+ * name to find and load the data. Normally this API is used by other ICU APIs
+ * to load required data out of the ICU data library, but it can be used to
+ * load data out of other places.
+ *
+ * See the User Guide Data Management chapter.
+ */
+ 
+#ifndef U_HIDE_INTERNAL_API
+/**
+ * Character used to separate package names from tree names 
+ * @internal ICU 3.0
+ */
+#define U_TREE_SEPARATOR '-'
+
+/**
+ * String used to separate package names from tree names 
+ * @internal ICU 3.0
+ */
+#define U_TREE_SEPARATOR_STRING "-"
+
+/**
+ * Character used to separate parts of entry names
+ * @internal ICU 3.0
+ */
+#define U_TREE_ENTRY_SEP_CHAR '/'
+
+/**
+ * String used to separate parts of entry names
+ * @internal ICU 3.0
+ */
+#define U_TREE_ENTRY_SEP_STRING "/"
+
+/**
+ * Alias for standard ICU data 
+ * @internal ICU 3.0
+ */
+#define U_ICUDATA_ALIAS "ICUDATA"
+
+#endif /* U_HIDE_INTERNAL_API */
+
+/**
+ * UDataInfo contains the properties about the requested data.
+ * This is meta data.
+ *
+ * <p>This structure may grow in the future, indicated by the
+ * <code>size</code> field.</p>
+ *
+ * <p>The platform data property fields help determine if a data
+ * file can be efficiently used on a given machine.
+ * The particular fields are of importance only if the data
+ * is affected by the properties - if there is integer data
+ * with word sizes > 1 byte, char* text, or UChar* text.</p>
+ *
+ * <p>The implementation for the <code>udata_open[Choice]()</code>
+ * functions may reject data based on the value in <code>isBigEndian</code>.
+ * No other field is used by the <code>udata</code> API implementation.</p>
+ *
+ * <p>The <code>dataFormat</code> may be used to identify
+ * the kind of data, e.g. a converter table.</p>
+ *
+ * <p>The <code>formatVersion</code> field should be used to
+ * make sure that the format can be interpreted.
+ * I may be a good idea to check only for the one or two highest
+ * of the version elements to allow the data memory to
+ * get more or somewhat rearranged contents, for as long
+ * as the using code can still interpret the older contents.</p>
+ *
+ * <p>The <code>dataVersion</code> field is intended to be a
+ * common place to store the source version of the data;
+ * for data from the Unicode character database, this could
+ * reflect the Unicode version.</p>
+ * @stable ICU 2.0
+ */
+typedef struct {
+    /** sizeof(UDataInfo)
+     *  @stable ICU 2.0 */
+    uint16_t size;
+
+    /** unused, set to 0 
+     *  @stable ICU 2.0*/
+    uint16_t reservedWord;
+
+    /* platform data properties */
+    /** 0 for little-endian machine, 1 for big-endian
+     *  @stable ICU 2.0 */
+    uint8_t isBigEndian;
+
+    /** see U_CHARSET_FAMILY values in utypes.h 
+     *  @stable ICU 2.0*/
+    uint8_t charsetFamily;
+
+    /** sizeof(UChar), one of { 1, 2, 4 } 
+     *  @stable ICU 2.0*/
+    uint8_t sizeofUChar;
+
+    /** unused, set to 0 
+     *  @stable ICU 2.0*/
+    uint8_t reservedByte;
+
+    /** data format identifier 
+     *  @stable ICU 2.0*/
+    uint8_t dataFormat[4];
+
+    /** versions: [0] major [1] minor [2] milli [3] micro 
+     *  @stable ICU 2.0*/
+    uint8_t formatVersion[4];
+
+    /** versions: [0] major [1] minor [2] milli [3] micro 
+     *  @stable ICU 2.0*/
+    uint8_t dataVersion[4];
+} UDataInfo;
+
+/* API for reading data -----------------------------------------------------*/
+
+/**
+ * Forward declaration of the data memory type.
+ * @stable ICU 2.0
+ */
+typedef struct UDataMemory UDataMemory;
+
+/**
+ * Callback function for udata_openChoice().
+ * @param context parameter passed into <code>udata_openChoice()</code>.
+ * @param type The type of the data as passed into <code>udata_openChoice()</code>.
+ *             It may be <code>NULL</code>.
+ * @param name The name of the data as passed into <code>udata_openChoice()</code>.
+ * @param pInfo A pointer to the <code>UDataInfo</code> structure
+ *              of data that has been loaded and will be returned
+ *              by <code>udata_openChoice()</code> if this function
+ *              returns <code>TRUE</code>.
+ * @return TRUE if the current data memory is acceptable
+ * @stable ICU 2.0
+ */
+typedef UBool U_CALLCONV
+UDataMemoryIsAcceptable(void *context,
+                        const char *type, const char *name,
+                        const UDataInfo *pInfo);
+
+
+/**
+ * Convenience function.
+ * This function works the same as <code>udata_openChoice</code>
+ * except that any data that matches the type and name
+ * is assumed to be acceptable.
+ * @param path Specifies an absolute path and/or a basename for the
+ *             finding of the data in the file system.
+ *             <code>NULL</code> for ICU data.
+ * @param type A string that specifies the type of data to be loaded.
+ *             For example, resource bundles are loaded with type "res",
+ *             conversion tables with type "cnv".
+ *             This may be <code>NULL</code> or empty.
+ * @param name A string that specifies the name of the data.
+ * @param pErrorCode An ICU UErrorCode parameter. It must not be <code>NULL</code>.
+ * @return A pointer (handle) to a data memory object, or <code>NULL</code>
+ *         if an error occurs. Call <code>udata_getMemory()</code>
+ *         to get a pointer to the actual data.
+ *
+ * @see udata_openChoice
+ * @stable ICU 2.0
+ */
+U_STABLE UDataMemory * U_EXPORT2
+udata_open(const char *path, const char *type, const char *name,
+           UErrorCode *pErrorCode);
+
+/**
+ * Data loading function.
+ * This function is used to find and load efficiently data for
+ * ICU and applications using ICU.
+ * It provides an abstract interface that allows to specify a data
+ * type and name to find and load the data.
+ *
+ * <p>The implementation depends on platform properties and user preferences
+ * and may involve loading shared libraries (DLLs), mapping
+ * files into memory, or fopen()/fread() files.
+ * It may also involve using static memory or database queries etc.
+ * Several or all data items may be combined into one entity
+ * (DLL, memory-mappable file).</p>
+ *
+ * <p>The data is always preceded by a header that includes
+ * a <code>UDataInfo</code> structure.
+ * The caller's <code>isAcceptable()</code> function is called to make
+ * sure that the data is useful. It may be called several times if it
+ * rejects the data and there is more than one location with data
+ * matching the type and name.</p>
+ *
+ * <p>If <code>path==NULL</code>, then ICU data is loaded.
+ * Otherwise, it is separated into a basename and a basename-less directory string.
+ * The basename is used as the data package name, and the directory is
+ * logically prepended to the ICU data directory string.</p>
+ *
+ * <p>For details about ICU data loading see the User Guide
+ * Data Management chapter. (http://icu.sourceforge.net/userguide/icudata.html)</p>
+ *
+ * @param path Specifies an absolute path and/or a basename for the
+ *             finding of the data in the file system.
+ *             <code>NULL</code> for ICU data.
+ * @param type A string that specifies the type of data to be loaded.
+ *             For example, resource bundles are loaded with type "res",
+ *             conversion tables with type "cnv".
+ *             This may be <code>NULL</code> or empty.
+ * @param name A string that specifies the name of the data.
+ * @param isAcceptable This function is called to verify that loaded data
+ *                     is useful for the client code. If it returns FALSE
+ *                     for all data items, then <code>udata_openChoice()</code>
+ *                     will return with an error.
+ * @param context Arbitrary parameter to be passed into isAcceptable.
+ * @param pErrorCode An ICU UErrorCode parameter. It must not be <code>NULL</code>.
+ * @return A pointer (handle) to a data memory object, or <code>NULL</code>
+ *         if an error occurs. Call <code>udata_getMemory()</code>
+ *         to get a pointer to the actual data.
+ * @stable ICU 2.0
+ */
+U_STABLE UDataMemory * U_EXPORT2
+udata_openChoice(const char *path, const char *type, const char *name,
+                 UDataMemoryIsAcceptable *isAcceptable, void *context,
+                 UErrorCode *pErrorCode);
+
+/**
+ * Close the data memory.
+ * This function must be called to allow the system to
+ * release resources associated with this data memory.
+ * @param pData The pointer to data memory object
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+udata_close(UDataMemory *pData);
+
+/**
+ * Get the pointer to the actual data inside the data memory.
+ * The data is read-only.
+ * @param pData The pointer to data memory object
+ * @stable ICU 2.0
+ */
+U_STABLE const void * U_EXPORT2
+udata_getMemory(UDataMemory *pData);
+
+/**
+ * Get the information from the data memory header.
+ * This allows to get access to the header containing
+ * platform data properties etc. which is not part of
+ * the data itself and can therefore not be accessed
+ * via the pointer that <code>udata_getMemory()</code> returns.
+ *
+ * @param pData pointer to the data memory object
+ * @param pInfo pointer to a UDataInfo object;
+ *              its <code>size</code> field must be set correctly,
+ *              typically to <code>sizeof(UDataInfo)</code>.
+ *
+ * <code>*pInfo</code> will be filled with the UDataInfo structure
+ * in the data memory object. If this structure is smaller than
+ * <code>pInfo->size</code>, then the <code>size</code> will be
+ * adjusted and only part of the structure will be filled.
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+udata_getInfo(UDataMemory *pData, UDataInfo *pInfo);
+
+/**
+ * This function bypasses the normal ICU data loading process and
+ * allows you to force ICU's system data to come out of a user-specified
+ * area in memory.
+ *
+ * The format of this data is that of the icu common data file, as is
+ * generated by the pkgdata tool with mode=common or mode=dll.
+ * You can read in a whole common mode file and pass the address to the start of the
+ * data, or (with the appropriate link options) pass in the pointer to
+ * the data that has been loaded from a dll by the operating system,
+ * as shown in this code:
+ *
+ *       extern const  char U_IMPORT U_ICUDATA_ENTRY_POINT []; 
+ *        // U_ICUDATA_ENTRY_POINT is same as entry point specified to pkgdata tool
+ *       UErrorCode  status = U_ZERO_ERROR;
+ *
+ *       udata_setCommonData(&U_ICUDATA_ENTRY_POINT, &status);
+ *
+ * Warning: ICU must NOT have even attempted to access its data yet
+ * when this call is made, or U_USING_DEFAULT_WARNING code will
+ * be returned. Be careful of UnicodeStrings in static initialization which
+ * may attempt to load a converter (use the UNICODE_STRING(x) macro instead).
+ *
+ * Also note that it is important that the declaration be as above. The entry point
+ * must not be declared as an extern void*.
+ *
+ * This function has no effect on application (non ICU) data.  See udata_setAppData()
+ * for similar functionality for application data.
+ *
+ * @param data pointer to ICU common data
+ * @param err outgoing error status <code>U_USING_DEFAULT_WARNING, U_UNSUPPORTED_ERROR</code>
+ * @stable ICU 2.0
+ */
+
+U_STABLE void U_EXPORT2
+udata_setCommonData(const void *data, UErrorCode *err);
+
+
+/**
+ * This function bypasses the normal ICU data loading process for application-specific
+ * data and allows you to force the it to come out of a user-specified
+ * pointer.
+ *
+ * The format of this data is that of the icu common data file, like 'icudt26l.dat'
+ * or the corresponding shared library (DLL) file.
+ * The application must read in or otherwise construct an image of the data and then
+ * pass the address of it to this function.
+ *
+ *
+ * Warning:  setAppData will set a U_USING_DEFAULT_WARNING code if
+ *           data with the specifed path that has already been opened, or
+ *           if setAppData with the same path has already been called.
+ *           Any such calls to setAppData will have no effect.
+ *
+ *
+ * @param packageName the package name by which the application will refer
+ *             to (open) this data
+ * @param data pointer to the data
+ * @param err outgoing error status <code>U_USING_DEFAULT_WARNING, U_UNSUPPORTED_ERROR</code>
+ * @see udata_setCommonData
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+udata_setAppData(const char *packageName, const void *data, UErrorCode *err);
+
+/**
+ * Possible settings for udata_setFileAccess()
+ * @see udata_setFileAccess
+ * @draft ICU 3.4
+ */
+typedef enum UDataFileAccess {
+    /** ICU does not access the file system for data loading. */
+    UDATA_NO_FILES,
+    /** ICU only loads data from packages, not from single files. */
+    UDATA_ONLY_PACKAGES,
+    /** ICU loads data from packages first, and only from single files
+        if the data cannot be found in a package. */
+    UDATA_PACKAGES_FIRST,
+    /** ICU looks for data in single files first, then in packages. (default) */
+    UDATA_FILES_FIRST,
+    /** An alias for the default access mode. */
+    UDATA_DEFAULT_ACCESS = UDATA_FILES_FIRST,
+    UDATA_FILE_ACCESS_COUNT
+} UDataFileAccess;
+
+/**
+ * This function may be called to control how ICU loads data. It must be called
+ * before any ICU data is loaded, including application data loaded with ures/ResourceBundle or
+ * udata APIs. It should be called before u_init.  This function is not multithread safe.  
+ * The results of calling it while other threads are loading data are undefined.
+ * @param access The type of file access to be used
+ * @param status Error code.
+ * @see UDataFileAccess
+ * @draft ICU 3.4 
+ */
+U_DRAFT void U_EXPORT2
+udata_setFileAccess(UDataFileAccess access, UErrorCode *status);
+
+U_CDECL_END
+
+#endif

Added: MacRuby/branches/icu/unicode/udeprctd.h
===================================================================
--- MacRuby/branches/icu/unicode/udeprctd.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/udeprctd.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,50 @@
+/*
+*******************************************************************************
+*   Copyright (C) 2004-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*******************************************************************************
+*
+*   file name:  
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   Created by: genheaders.pl, a perl script written by Ram Viswanadha
+*
+*  Contains data for commenting out APIs.
+*  Gets included by umachine.h
+*
+*  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
+*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
+*/
+
+#ifndef UDEPRCTD_H
+#define UDEPRCTD_H
+
+#ifdef U_HIDE_DEPRECATED_API
+
+#    if U_DISABLE_RENAMING
+#        define ucol_getContractions ucol_getContractions_DEPRECATED_API_DO_NOT_USE
+#        define ucol_getLocale ucol_getLocale_DEPRECATED_API_DO_NOT_USE
+#        define ures_countArrayItems ures_countArrayItems_DEPRECATED_API_DO_NOT_USE
+#        define ures_getLocale ures_getLocale_DEPRECATED_API_DO_NOT_USE
+#        define ures_getVersionNumber ures_getVersionNumber_DEPRECATED_API_DO_NOT_USE
+#        define utrans_getAvailableID utrans_getAvailableID_DEPRECATED_API_DO_NOT_USE
+#        define utrans_getID utrans_getID_DEPRECATED_API_DO_NOT_USE
+#        define utrans_open utrans_open_DEPRECATED_API_DO_NOT_USE
+#        define utrans_unregister utrans_unregister_DEPRECATED_API_DO_NOT_USE
+#    else
+#        define ucol_getContractions_3_6 ucol_getContractions_DEPRECATED_API_DO_NOT_USE
+#        define ucol_getLocale_3_6 ucol_getLocale_DEPRECATED_API_DO_NOT_USE
+#        define ures_countArrayItems_3_6 ures_countArrayItems_DEPRECATED_API_DO_NOT_USE
+#        define ures_getLocale_3_6 ures_getLocale_DEPRECATED_API_DO_NOT_USE
+#        define ures_getVersionNumber_3_6 ures_getVersionNumber_DEPRECATED_API_DO_NOT_USE
+#        define utrans_getAvailableID_3_6 utrans_getAvailableID_DEPRECATED_API_DO_NOT_USE
+#        define utrans_getID_3_6 utrans_getID_DEPRECATED_API_DO_NOT_USE
+#        define utrans_open_3_6 utrans_open_DEPRECATED_API_DO_NOT_USE
+#        define utrans_unregister_3_6 utrans_unregister_DEPRECATED_API_DO_NOT_USE
+#    endif /* U_DISABLE_RENAMING */
+
+#endif /* U_HIDE_DEPRECATED_API */
+#endif /* UDEPRCTD_H */
+

Added: MacRuby/branches/icu/unicode/udraft.h
===================================================================
--- MacRuby/branches/icu/unicode/udraft.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/udraft.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,262 @@
+/*
+*******************************************************************************
+*   Copyright (C) 2004-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*******************************************************************************
+*
+*   file name:  
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   Created by: genheaders.pl, a perl script written by Ram Viswanadha
+*
+*  Contains data for commenting out APIs.
+*  Gets included by umachine.h
+*
+*  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
+*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
+*/
+
+#ifndef UDRAFT_H
+#define UDRAFT_H
+
+#ifdef U_HIDE_DRAFT_API
+
+#    if U_DISABLE_RENAMING
+#        define u_fclose u_fclose_DRAFT_API_DO_NOT_USE
+#        define u_feof u_feof_DRAFT_API_DO_NOT_USE
+#        define u_fflush u_fflush_DRAFT_API_DO_NOT_USE
+#        define u_fgetConverter u_fgetConverter_DRAFT_API_DO_NOT_USE
+#        define u_fgetc u_fgetc_DRAFT_API_DO_NOT_USE
+#        define u_fgetcodepage u_fgetcodepage_DRAFT_API_DO_NOT_USE
+#        define u_fgetcx u_fgetcx_DRAFT_API_DO_NOT_USE
+#        define u_fgetfile u_fgetfile_DRAFT_API_DO_NOT_USE
+#        define u_fgetlocale u_fgetlocale_DRAFT_API_DO_NOT_USE
+#        define u_fgets u_fgets_DRAFT_API_DO_NOT_USE
+#        define u_file_read u_file_read_DRAFT_API_DO_NOT_USE
+#        define u_file_write u_file_write_DRAFT_API_DO_NOT_USE
+#        define u_finit u_finit_DRAFT_API_DO_NOT_USE
+#        define u_fopen u_fopen_DRAFT_API_DO_NOT_USE
+#        define u_fprintf u_fprintf_DRAFT_API_DO_NOT_USE
+#        define u_fprintf_u u_fprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_fputc u_fputc_DRAFT_API_DO_NOT_USE
+#        define u_fputs u_fputs_DRAFT_API_DO_NOT_USE
+#        define u_frewind u_frewind_DRAFT_API_DO_NOT_USE
+#        define u_fscanf u_fscanf_DRAFT_API_DO_NOT_USE
+#        define u_fscanf_u u_fscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_fsetcodepage u_fsetcodepage_DRAFT_API_DO_NOT_USE
+#        define u_fsetlocale u_fsetlocale_DRAFT_API_DO_NOT_USE
+#        define u_fsettransliterator u_fsettransliterator_DRAFT_API_DO_NOT_USE
+#        define u_fstropen u_fstropen_DRAFT_API_DO_NOT_USE
+#        define u_fungetc u_fungetc_DRAFT_API_DO_NOT_USE
+#        define u_snprintf u_snprintf_DRAFT_API_DO_NOT_USE
+#        define u_snprintf_u u_snprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_sprintf u_sprintf_DRAFT_API_DO_NOT_USE
+#        define u_sprintf_u u_sprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_sscanf u_sscanf_DRAFT_API_DO_NOT_USE
+#        define u_sscanf_u u_sscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_strFromUTF8Lenient u_strFromUTF8Lenient_DRAFT_API_DO_NOT_USE
+#        define u_strFromUTF8WithSub u_strFromUTF8WithSub_DRAFT_API_DO_NOT_USE
+#        define u_strToUTF8WithSub u_strToUTF8WithSub_DRAFT_API_DO_NOT_USE
+#        define u_vfprintf u_vfprintf_DRAFT_API_DO_NOT_USE
+#        define u_vfprintf_u u_vfprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vfscanf u_vfscanf_DRAFT_API_DO_NOT_USE
+#        define u_vfscanf_u u_vfscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsnprintf u_vsnprintf_DRAFT_API_DO_NOT_USE
+#        define u_vsnprintf_u u_vsnprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsprintf u_vsprintf_DRAFT_API_DO_NOT_USE
+#        define u_vsprintf_u u_vsprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsscanf u_vsscanf_DRAFT_API_DO_NOT_USE
+#        define u_vsscanf_u u_vsscanf_u_DRAFT_API_DO_NOT_USE
+#        define ubidi_getProcessedLength ubidi_getProcessedLength_DRAFT_API_DO_NOT_USE
+#        define ubidi_getReorderingMode ubidi_getReorderingMode_DRAFT_API_DO_NOT_USE
+#        define ubidi_getReorderingOptions ubidi_getReorderingOptions_DRAFT_API_DO_NOT_USE
+#        define ubidi_getResultLength ubidi_getResultLength_DRAFT_API_DO_NOT_USE
+#        define ubidi_setReorderingMode ubidi_setReorderingMode_DRAFT_API_DO_NOT_USE
+#        define ubidi_setReorderingOptions ubidi_setReorderingOptions_DRAFT_API_DO_NOT_USE
+#        define ubrk_setUText ubrk_setUText_DRAFT_API_DO_NOT_USE
+#        define ucal_getGregorianChange ucal_getGregorianChange_DRAFT_API_DO_NOT_USE
+#        define ucal_setGregorianChange ucal_setGregorianChange_DRAFT_API_DO_NOT_USE
+#        define ucasemap_close ucasemap_close_DRAFT_API_DO_NOT_USE
+#        define ucasemap_getLocale ucasemap_getLocale_DRAFT_API_DO_NOT_USE
+#        define ucasemap_getOptions ucasemap_getOptions_DRAFT_API_DO_NOT_USE
+#        define ucasemap_open ucasemap_open_DRAFT_API_DO_NOT_USE
+#        define ucasemap_setLocale ucasemap_setLocale_DRAFT_API_DO_NOT_USE
+#        define ucasemap_setOptions ucasemap_setOptions_DRAFT_API_DO_NOT_USE
+#        define ucasemap_utf8ToLower ucasemap_utf8ToLower_DRAFT_API_DO_NOT_USE
+#        define ucasemap_utf8ToUpper ucasemap_utf8ToUpper_DRAFT_API_DO_NOT_USE
+#        define ucnv_fromUCountPending ucnv_fromUCountPending_DRAFT_API_DO_NOT_USE
+#        define ucnv_setSubstString ucnv_setSubstString_DRAFT_API_DO_NOT_USE
+#        define ucnv_toUCountPending ucnv_toUCountPending_DRAFT_API_DO_NOT_USE
+#        define ucol_getContractionsAndExpansions ucol_getContractionsAndExpansions_DRAFT_API_DO_NOT_USE
+#        define ucsdet_close ucsdet_close_DRAFT_API_DO_NOT_USE
+#        define ucsdet_detect ucsdet_detect_DRAFT_API_DO_NOT_USE
+#        define ucsdet_detectAll ucsdet_detectAll_DRAFT_API_DO_NOT_USE
+#        define ucsdet_enableInputFilter ucsdet_enableInputFilter_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getAllDetectableCharsets ucsdet_getAllDetectableCharsets_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getConfidence ucsdet_getConfidence_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getLanguage ucsdet_getLanguage_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getName ucsdet_getName_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getUChars ucsdet_getUChars_DRAFT_API_DO_NOT_USE
+#        define ucsdet_isInputFilterEnabled ucsdet_isInputFilterEnabled_DRAFT_API_DO_NOT_USE
+#        define ucsdet_open ucsdet_open_DRAFT_API_DO_NOT_USE
+#        define ucsdet_setDeclaredEncoding ucsdet_setDeclaredEncoding_DRAFT_API_DO_NOT_USE
+#        define ucsdet_setText ucsdet_setText_DRAFT_API_DO_NOT_USE
+#        define udata_setFileAccess udata_setFileAccess_DRAFT_API_DO_NOT_USE
+#        define ulocdata_close ulocdata_close_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getDelimiter ulocdata_getDelimiter_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getExemplarSet ulocdata_getExemplarSet_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getNoSubstitute ulocdata_getNoSubstitute_DRAFT_API_DO_NOT_USE
+#        define ulocdata_open ulocdata_open_DRAFT_API_DO_NOT_USE
+#        define ulocdata_setNoSubstitute ulocdata_setNoSubstitute_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8String ures_getUTF8String_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8StringByIndex ures_getUTF8StringByIndex_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8StringByKey ures_getUTF8StringByKey_DRAFT_API_DO_NOT_USE
+#        define uset_addAllCodePoints uset_addAllCodePoints_DRAFT_API_DO_NOT_USE
+#        define uset_containsAllCodePoints uset_containsAllCodePoints_DRAFT_API_DO_NOT_USE
+#        define utext_char32At utext_char32At_DRAFT_API_DO_NOT_USE
+#        define utext_clone utext_clone_DRAFT_API_DO_NOT_USE
+#        define utext_close utext_close_DRAFT_API_DO_NOT_USE
+#        define utext_copy utext_copy_DRAFT_API_DO_NOT_USE
+#        define utext_current32 utext_current32_DRAFT_API_DO_NOT_USE
+#        define utext_equals utext_equals_DRAFT_API_DO_NOT_USE
+#        define utext_extract utext_extract_DRAFT_API_DO_NOT_USE
+#        define utext_freeze utext_freeze_DRAFT_API_DO_NOT_USE
+#        define utext_getNativeIndex utext_getNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_getPreviousNativeIndex utext_getPreviousNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_hasMetaData utext_hasMetaData_DRAFT_API_DO_NOT_USE
+#        define utext_isLengthExpensive utext_isLengthExpensive_DRAFT_API_DO_NOT_USE
+#        define utext_isWritable utext_isWritable_DRAFT_API_DO_NOT_USE
+#        define utext_moveIndex32 utext_moveIndex32_DRAFT_API_DO_NOT_USE
+#        define utext_nativeLength utext_nativeLength_DRAFT_API_DO_NOT_USE
+#        define utext_next32 utext_next32_DRAFT_API_DO_NOT_USE
+#        define utext_next32From utext_next32From_DRAFT_API_DO_NOT_USE
+#        define utext_openUChars utext_openUChars_DRAFT_API_DO_NOT_USE
+#        define utext_openUTF8 utext_openUTF8_DRAFT_API_DO_NOT_USE
+#        define utext_previous32 utext_previous32_DRAFT_API_DO_NOT_USE
+#        define utext_previous32From utext_previous32From_DRAFT_API_DO_NOT_USE
+#        define utext_replace utext_replace_DRAFT_API_DO_NOT_USE
+#        define utext_setNativeIndex utext_setNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_setup utext_setup_DRAFT_API_DO_NOT_USE
+#    else
+#        define u_fclose_3_6 u_fclose_DRAFT_API_DO_NOT_USE
+#        define u_feof_3_6 u_feof_DRAFT_API_DO_NOT_USE
+#        define u_fflush_3_6 u_fflush_DRAFT_API_DO_NOT_USE
+#        define u_fgetConverter_3_6 u_fgetConverter_DRAFT_API_DO_NOT_USE
+#        define u_fgetc_3_6 u_fgetc_DRAFT_API_DO_NOT_USE
+#        define u_fgetcodepage_3_6 u_fgetcodepage_DRAFT_API_DO_NOT_USE
+#        define u_fgetcx_3_6 u_fgetcx_DRAFT_API_DO_NOT_USE
+#        define u_fgetfile_3_6 u_fgetfile_DRAFT_API_DO_NOT_USE
+#        define u_fgetlocale_3_6 u_fgetlocale_DRAFT_API_DO_NOT_USE
+#        define u_fgets_3_6 u_fgets_DRAFT_API_DO_NOT_USE
+#        define u_file_read_3_6 u_file_read_DRAFT_API_DO_NOT_USE
+#        define u_file_write_3_6 u_file_write_DRAFT_API_DO_NOT_USE
+#        define u_finit_3_6 u_finit_DRAFT_API_DO_NOT_USE
+#        define u_fopen_3_6 u_fopen_DRAFT_API_DO_NOT_USE
+#        define u_fprintf_3_6 u_fprintf_DRAFT_API_DO_NOT_USE
+#        define u_fprintf_u_3_6 u_fprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_fputc_3_6 u_fputc_DRAFT_API_DO_NOT_USE
+#        define u_fputs_3_6 u_fputs_DRAFT_API_DO_NOT_USE
+#        define u_frewind_3_6 u_frewind_DRAFT_API_DO_NOT_USE
+#        define u_fscanf_3_6 u_fscanf_DRAFT_API_DO_NOT_USE
+#        define u_fscanf_u_3_6 u_fscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_fsetcodepage_3_6 u_fsetcodepage_DRAFT_API_DO_NOT_USE
+#        define u_fsetlocale_3_6 u_fsetlocale_DRAFT_API_DO_NOT_USE
+#        define u_fsettransliterator_3_6 u_fsettransliterator_DRAFT_API_DO_NOT_USE
+#        define u_fstropen_3_6 u_fstropen_DRAFT_API_DO_NOT_USE
+#        define u_fungetc_3_6 u_fungetc_DRAFT_API_DO_NOT_USE
+#        define u_snprintf_3_6 u_snprintf_DRAFT_API_DO_NOT_USE
+#        define u_snprintf_u_3_6 u_snprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_sprintf_3_6 u_sprintf_DRAFT_API_DO_NOT_USE
+#        define u_sprintf_u_3_6 u_sprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_sscanf_3_6 u_sscanf_DRAFT_API_DO_NOT_USE
+#        define u_sscanf_u_3_6 u_sscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_strFromUTF8Lenient_3_6 u_strFromUTF8Lenient_DRAFT_API_DO_NOT_USE
+#        define u_strFromUTF8WithSub_3_6 u_strFromUTF8WithSub_DRAFT_API_DO_NOT_USE
+#        define u_strToUTF8WithSub_3_6 u_strToUTF8WithSub_DRAFT_API_DO_NOT_USE
+#        define u_vfprintf_3_6 u_vfprintf_DRAFT_API_DO_NOT_USE
+#        define u_vfprintf_u_3_6 u_vfprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vfscanf_3_6 u_vfscanf_DRAFT_API_DO_NOT_USE
+#        define u_vfscanf_u_3_6 u_vfscanf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsnprintf_3_6 u_vsnprintf_DRAFT_API_DO_NOT_USE
+#        define u_vsnprintf_u_3_6 u_vsnprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsprintf_3_6 u_vsprintf_DRAFT_API_DO_NOT_USE
+#        define u_vsprintf_u_3_6 u_vsprintf_u_DRAFT_API_DO_NOT_USE
+#        define u_vsscanf_3_6 u_vsscanf_DRAFT_API_DO_NOT_USE
+#        define u_vsscanf_u_3_6 u_vsscanf_u_DRAFT_API_DO_NOT_USE
+#        define ubidi_getProcessedLength_3_6 ubidi_getProcessedLength_DRAFT_API_DO_NOT_USE
+#        define ubidi_getReorderingMode_3_6 ubidi_getReorderingMode_DRAFT_API_DO_NOT_USE
+#        define ubidi_getReorderingOptions_3_6 ubidi_getReorderingOptions_DRAFT_API_DO_NOT_USE
+#        define ubidi_getResultLength_3_6 ubidi_getResultLength_DRAFT_API_DO_NOT_USE
+#        define ubidi_setReorderingMode_3_6 ubidi_setReorderingMode_DRAFT_API_DO_NOT_USE
+#        define ubidi_setReorderingOptions_3_6 ubidi_setReorderingOptions_DRAFT_API_DO_NOT_USE
+#        define ubrk_setUText_3_6 ubrk_setUText_DRAFT_API_DO_NOT_USE
+#        define ucal_getGregorianChange_3_6 ucal_getGregorianChange_DRAFT_API_DO_NOT_USE
+#        define ucal_setGregorianChange_3_6 ucal_setGregorianChange_DRAFT_API_DO_NOT_USE
+#        define ucasemap_close_3_6 ucasemap_close_DRAFT_API_DO_NOT_USE
+#        define ucasemap_getLocale_3_6 ucasemap_getLocale_DRAFT_API_DO_NOT_USE
+#        define ucasemap_getOptions_3_6 ucasemap_getOptions_DRAFT_API_DO_NOT_USE
+#        define ucasemap_open_3_6 ucasemap_open_DRAFT_API_DO_NOT_USE
+#        define ucasemap_setLocale_3_6 ucasemap_setLocale_DRAFT_API_DO_NOT_USE
+#        define ucasemap_setOptions_3_6 ucasemap_setOptions_DRAFT_API_DO_NOT_USE
+#        define ucasemap_utf8ToLower_3_6 ucasemap_utf8ToLower_DRAFT_API_DO_NOT_USE
+#        define ucasemap_utf8ToUpper_3_6 ucasemap_utf8ToUpper_DRAFT_API_DO_NOT_USE
+#        define ucnv_fromUCountPending_3_6 ucnv_fromUCountPending_DRAFT_API_DO_NOT_USE
+#        define ucnv_setSubstString_3_6 ucnv_setSubstString_DRAFT_API_DO_NOT_USE
+#        define ucnv_toUCountPending_3_6 ucnv_toUCountPending_DRAFT_API_DO_NOT_USE
+#        define ucol_getContractionsAndExpansions_3_6 ucol_getContractionsAndExpansions_DRAFT_API_DO_NOT_USE
+#        define ucsdet_close_3_6 ucsdet_close_DRAFT_API_DO_NOT_USE
+#        define ucsdet_detectAll_3_6 ucsdet_detectAll_DRAFT_API_DO_NOT_USE
+#        define ucsdet_detect_3_6 ucsdet_detect_DRAFT_API_DO_NOT_USE
+#        define ucsdet_enableInputFilter_3_6 ucsdet_enableInputFilter_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getAllDetectableCharsets_3_6 ucsdet_getAllDetectableCharsets_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getConfidence_3_6 ucsdet_getConfidence_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getLanguage_3_6 ucsdet_getLanguage_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getName_3_6 ucsdet_getName_DRAFT_API_DO_NOT_USE
+#        define ucsdet_getUChars_3_6 ucsdet_getUChars_DRAFT_API_DO_NOT_USE
+#        define ucsdet_isInputFilterEnabled_3_6 ucsdet_isInputFilterEnabled_DRAFT_API_DO_NOT_USE
+#        define ucsdet_open_3_6 ucsdet_open_DRAFT_API_DO_NOT_USE
+#        define ucsdet_setDeclaredEncoding_3_6 ucsdet_setDeclaredEncoding_DRAFT_API_DO_NOT_USE
+#        define ucsdet_setText_3_6 ucsdet_setText_DRAFT_API_DO_NOT_USE
+#        define udata_setFileAccess_3_6 udata_setFileAccess_DRAFT_API_DO_NOT_USE
+#        define ulocdata_close_3_6 ulocdata_close_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getDelimiter_3_6 ulocdata_getDelimiter_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getExemplarSet_3_6 ulocdata_getExemplarSet_DRAFT_API_DO_NOT_USE
+#        define ulocdata_getNoSubstitute_3_6 ulocdata_getNoSubstitute_DRAFT_API_DO_NOT_USE
+#        define ulocdata_open_3_6 ulocdata_open_DRAFT_API_DO_NOT_USE
+#        define ulocdata_setNoSubstitute_3_6 ulocdata_setNoSubstitute_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8StringByIndex_3_6 ures_getUTF8StringByIndex_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8StringByKey_3_6 ures_getUTF8StringByKey_DRAFT_API_DO_NOT_USE
+#        define ures_getUTF8String_3_6 ures_getUTF8String_DRAFT_API_DO_NOT_USE
+#        define uset_addAllCodePoints_3_6 uset_addAllCodePoints_DRAFT_API_DO_NOT_USE
+#        define uset_containsAllCodePoints_3_6 uset_containsAllCodePoints_DRAFT_API_DO_NOT_USE
+#        define utext_char32At_3_6 utext_char32At_DRAFT_API_DO_NOT_USE
+#        define utext_clone_3_6 utext_clone_DRAFT_API_DO_NOT_USE
+#        define utext_close_3_6 utext_close_DRAFT_API_DO_NOT_USE
+#        define utext_copy_3_6 utext_copy_DRAFT_API_DO_NOT_USE
+#        define utext_current32_3_6 utext_current32_DRAFT_API_DO_NOT_USE
+#        define utext_equals_3_6 utext_equals_DRAFT_API_DO_NOT_USE
+#        define utext_extract_3_6 utext_extract_DRAFT_API_DO_NOT_USE
+#        define utext_freeze_3_6 utext_freeze_DRAFT_API_DO_NOT_USE
+#        define utext_getNativeIndex_3_6 utext_getNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_getPreviousNativeIndex_3_6 utext_getPreviousNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_hasMetaData_3_6 utext_hasMetaData_DRAFT_API_DO_NOT_USE
+#        define utext_isLengthExpensive_3_6 utext_isLengthExpensive_DRAFT_API_DO_NOT_USE
+#        define utext_isWritable_3_6 utext_isWritable_DRAFT_API_DO_NOT_USE
+#        define utext_moveIndex32_3_6 utext_moveIndex32_DRAFT_API_DO_NOT_USE
+#        define utext_nativeLength_3_6 utext_nativeLength_DRAFT_API_DO_NOT_USE
+#        define utext_next32From_3_6 utext_next32From_DRAFT_API_DO_NOT_USE
+#        define utext_next32_3_6 utext_next32_DRAFT_API_DO_NOT_USE
+#        define utext_openUChars_3_6 utext_openUChars_DRAFT_API_DO_NOT_USE
+#        define utext_openUTF8_3_6 utext_openUTF8_DRAFT_API_DO_NOT_USE
+#        define utext_previous32From_3_6 utext_previous32From_DRAFT_API_DO_NOT_USE
+#        define utext_previous32_3_6 utext_previous32_DRAFT_API_DO_NOT_USE
+#        define utext_replace_3_6 utext_replace_DRAFT_API_DO_NOT_USE
+#        define utext_setNativeIndex_3_6 utext_setNativeIndex_DRAFT_API_DO_NOT_USE
+#        define utext_setup_3_6 utext_setup_DRAFT_API_DO_NOT_USE
+#    endif /* U_DISABLE_RENAMING */
+
+#endif /* U_HIDE_DRAFT_API */
+#endif /* UDRAFT_H */
+

Added: MacRuby/branches/icu/unicode/uenum.h
===================================================================
--- MacRuby/branches/icu/unicode/uenum.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uenum.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,134 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  uenum.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:2
+*
+*   created on: 2002jul08
+*   created by: Vladimir Weinstein
+*/
+
+#ifndef __UENUM_H
+#define __UENUM_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file
+ * \brief C API: String Enumeration 
+ */
+ 
+/**
+ * An enumeration object.
+ * For usage in C programs.
+ * @stable ICU 2.2
+ */
+struct UEnumeration;
+/** structure representing an enumeration object instance @stable ICU 2.2 */
+typedef struct UEnumeration UEnumeration;
+
+/**
+ * Disposes of resources in use by the iterator.  If en is NULL,
+ * does nothing.  After this call, any char* or UChar* pointer
+ * returned by uenum_unext() or uenum_next() is invalid.
+ * @param en UEnumeration structure pointer
+ * @stable ICU 2.2
+ */
+U_STABLE void U_EXPORT2
+uenum_close(UEnumeration* en);
+
+/**
+ * Returns the number of elements that the iterator traverses.  If
+ * the iterator is out-of-sync with its service, status is set to
+ * U_ENUM_OUT_OF_SYNC_ERROR.
+ * This is a convenience function. It can end up being very
+ * expensive as all the items might have to be pre-fetched (depending
+ * on the type of data being traversed). Use with caution and only 
+ * when necessary.
+ * @param en UEnumeration structure pointer
+ * @param status error code, can be U_ENUM_OUT_OF_SYNC_ERROR if the
+ *               iterator is out of sync.
+ * @return number of elements in the iterator
+ * @stable ICU 2.2
+ */
+U_STABLE int32_t U_EXPORT2
+uenum_count(UEnumeration* en, UErrorCode* status);
+
+/**
+ * Returns the next element in the iterator's list.  If there are
+ * no more elements, returns NULL.  If the iterator is out-of-sync
+ * with its service, status is set to U_ENUM_OUT_OF_SYNC_ERROR and
+ * NULL is returned.  If the native service string is a char* string,
+ * it is converted to UChar* with the invariant converter.
+ * The result is terminated by (UChar)0.
+ * @param en the iterator object
+ * @param resultLength pointer to receive the length of the result
+ *                     (not including the terminating \\0).
+ *                     If the pointer is NULL it is ignored.
+ * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if
+ *               the iterator is out of sync with its service.
+ * @return a pointer to the string.  The string will be
+ *         zero-terminated.  The return pointer is owned by this iterator
+ *         and must not be deleted by the caller.  The pointer is valid
+ *         until the next call to any uenum_... method, including
+ *         uenum_next() or uenum_unext().  When all strings have been
+ *         traversed, returns NULL.
+ * @stable ICU 2.2
+ */
+U_STABLE const UChar* U_EXPORT2
+uenum_unext(UEnumeration* en,
+            int32_t* resultLength,
+            UErrorCode* status);
+
+/**
+ * Returns the next element in the iterator's list.  If there are
+ * no more elements, returns NULL.  If the iterator is out-of-sync
+ * with its service, status is set to U_ENUM_OUT_OF_SYNC_ERROR and
+ * NULL is returned.  If the native service string is a UChar*
+ * string, it is converted to char* with the invariant converter.
+ * The result is terminated by (char)0.  If the conversion fails
+ * (because a character cannot be converted) then status is set to
+ * U_INVARIANT_CONVERSION_ERROR and the return value is undefined
+ * (but non-NULL).
+ * @param en the iterator object
+ * @param resultLength pointer to receive the length of the result
+ *                     (not including the terminating \\0).
+ *                     If the pointer is NULL it is ignored.
+ * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if
+ *               the iterator is out of sync with its service.  Set to
+ *               U_INVARIANT_CONVERSION_ERROR if the underlying native string is
+ *               UChar* and conversion to char* with the invariant converter
+ *               fails. This error pertains only to current string, so iteration
+ *               might be able to continue successfully.
+ * @return a pointer to the string.  The string will be
+ *         zero-terminated.  The return pointer is owned by this iterator
+ *         and must not be deleted by the caller.  The pointer is valid
+ *         until the next call to any uenum_... method, including
+ *         uenum_next() or uenum_unext().  When all strings have been
+ *         traversed, returns NULL.
+ * @stable ICU 2.2
+ */
+U_STABLE const char* U_EXPORT2
+uenum_next(UEnumeration* en,
+           int32_t* resultLength,
+           UErrorCode* status);
+
+/**
+ * Resets the iterator to the current list of service IDs.  This
+ * re-establishes sync with the service and rewinds the iterator
+ * to start at the first element.
+ * @param en the iterator object
+ * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if
+ *               the iterator is out of sync with its service.  
+ * @stable ICU 2.2
+ */
+U_STABLE void U_EXPORT2
+uenum_reset(UEnumeration* en, UErrorCode* status);
+
+#endif

Added: MacRuby/branches/icu/unicode/uidna.h
===================================================================
--- MacRuby/branches/icu/unicode/uidna.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uidna.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,308 @@
+/*
+ *******************************************************************************
+ *
+ *   Copyright (C) 2003-2006, International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ *
+ *******************************************************************************
+ *   file name:  uidna.h
+ *   encoding:   US-ASCII
+ *   tab size:   8 (not used)
+ *   indentation:4
+ *
+ *   created on: 2003feb1
+ *   created by: Ram Viswanadha
+ */
+
+#ifndef __UIDNA_H__
+#define __UIDNA_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_IDNA
+
+#include "unicode/parseerr.h"
+  
+/**
+ * \file
+ * \brief C API: Internationalized Domain Names in Applications Tranformation
+ *
+ * UIDNA API implements the IDNA protocol as defined in the IDNA RFC 
+ * (http://www.ietf.org/rfc/rfc3490.txt).
+ * The RFC defines 2 operations: ToASCII and ToUnicode. Domain labels 
+ * containing non-ASCII code points are required to be processed by
+ * ToASCII operation before passing it to resolver libraries. Domain names
+ * that are obtained from resolver libraries are required to be processed by
+ * ToUnicode operation before displaying the domain name to the user.
+ * IDNA requires that implementations process input strings with Nameprep
+ * (http://www.ietf.org/rfc/rfc3491.txt), 
+ * which is a profile of Stringprep (http://www.ietf.org/rfc/rfc3454.txt), 
+ * and then with Punycode (http://www.ietf.org/rfc/rfc3492.txt). 
+ * Implementations of IDNA MUST fully implement Nameprep and Punycode; 
+ * neither Nameprep nor Punycode are optional.
+ * The input and output of ToASCII and ToUnicode operations are Unicode 
+ * and are designed to be chainable, i.e., applying ToASCII or ToUnicode operations
+ * multiple times to an input string will yield the same result as applying the operation
+ * once.
+ * ToUnicode(ToUnicode(ToUnicode...(ToUnicode(string)))) == ToUnicode(string) 
+ * ToASCII(ToASCII(ToASCII...(ToASCII(string))) == ToASCII(string).
+ *
+ */
+
+/** 
+ * Option to prohibit processing of unassigned codepoints in the input and
+ * do not check if the input conforms to STD-3 ASCII rules.
+ * 
+ * @see  uidna_toASCII uidna_toUnicode
+ * @stable ICU 2.6
+ */
+#define UIDNA_DEFAULT          0x0000
+/** 
+ * Option to allow processing of unassigned codepoints in the input
+ * 
+ * @see  uidna_toASCII uidna_toUnicode
+ * @stable ICU 2.6
+ */
+#define UIDNA_ALLOW_UNASSIGNED 0x0001
+/** 
+ * Option to check if input conforms to STD-3 ASCII rules
+ * 
+ * @see  uidna_toASCII uidna_toUnicode
+ * @stable ICU 2.6
+ */
+#define UIDNA_USE_STD3_RULES   0x0002
+
+/**
+ * This function implements the ToASCII operation as defined in the IDNA RFC.
+ * This operation is done on <b>single labels</b> before sending it to something that expects
+ * ASCII names. A label is an individual part of a domain name. Labels are usually
+ * separated by dots; e.g." "www.example.com" is composed of 3 labels 
+ * "www","example", and "com".
+ *
+ *
+ * @param src               Input UChar array containing label in Unicode.
+ * @param srcLength         Number of UChars in src, or -1 if NUL-terminated.
+ * @param dest              Output UChar array with ASCII (ACE encoded) label.
+ * @param destCapacity      Size of dest.
+ * @param options           A bit set of options:
+ *
+ *  - UIDNA_DEFAULT             Use default options, i.e., do not process unassigned code points
+ *                              and do not use STD3 ASCII rules
+ *                              If unassigned code points are found the operation fails with 
+ *                              U_UNASSIGNED_ERROR error code.
+ *
+ *  - UIDNA_ALLOW_UNASSIGNED    Unassigned values can be converted to ASCII for query operations
+ *                              If this option is set, the unassigned code points are in the input 
+ *                              are treated as normal Unicode code points.
+ *                          
+ *  - UIDNA_USE_STD3_RULES      Use STD3 ASCII rules for host name syntax restrictions
+ *                              If this option is set and the input does not satisfy STD3 rules,  
+ *                              the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR
+ *
+ * @param parseError        Pointer to UParseError struct to receive information on position 
+ *                          of error if an error is encountered. Can be NULL.
+ * @param status            ICU in/out error code parameter.
+ *                          U_INVALID_CHAR_FOUND if src contains
+ *                          unmatched single surrogates.
+ *                          U_INDEX_OUTOFBOUNDS_ERROR if src contains
+ *                          too many code points.
+ *                          U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough
+ * @return                  Number of ASCII characters converted.
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+uidna_toASCII(const UChar* src, int32_t srcLength, 
+              UChar* dest, int32_t destCapacity,
+              int32_t options,
+              UParseError* parseError,
+              UErrorCode* status);
+
+
+/**
+ * This function implements the ToUnicode operation as defined in the IDNA RFC.
+ * This operation is done on <b>single labels</b> before sending it to something that expects
+ * Unicode names. A label is an individual part of a domain name. Labels are usually
+ * separated by dots; for e.g." "www.example.com" is composed of 3 labels 
+ * "www","example", and "com".
+ *
+ * @param src               Input UChar array containing ASCII (ACE encoded) label.
+ * @param srcLength         Number of UChars in src, or -1 if NUL-terminated.
+ * @param dest Output       Converted UChar array containing Unicode equivalent of label.
+ * @param destCapacity      Size of dest.
+ * @param options           A bit set of options:
+ *  
+ *  - UIDNA_DEFAULT             Use default options, i.e., do not process unassigned code points
+ *                              and do not use STD3 ASCII rules
+ *                              If unassigned code points are found the operation fails with 
+ *                              U_UNASSIGNED_ERROR error code.
+ *
+ *  - UIDNA_ALLOW_UNASSIGNED      Unassigned values can be converted to ASCII for query operations
+ *                              If this option is set, the unassigned code points are in the input 
+ *                              are treated as normal Unicode code points. <b> Note: </b> This option is 
+ *                              required on toUnicode operation because the RFC mandates 
+ *                              verification of decoded ACE input by applying toASCII and comparing
+ *                              its output with source
+ *
+ *                          
+ *                          
+ *  - UIDNA_USE_STD3_RULES      Use STD3 ASCII rules for host name syntax restrictions
+ *                              If this option is set and the input does not satisfy STD3 rules,  
+ *                              the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR
+ *
+ * @param parseError        Pointer to UParseError struct to receive information on position 
+ *                          of error if an error is encountered. Can be NULL.
+ * @param status            ICU in/out error code parameter.
+ *                          U_INVALID_CHAR_FOUND if src contains
+ *                          unmatched single surrogates.
+ *                          U_INDEX_OUTOFBOUNDS_ERROR if src contains
+ *                          too many code points.
+ *                          U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough
+ * @return                  Number of Unicode characters converted.
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+uidna_toUnicode(const UChar* src, int32_t srcLength,
+                UChar* dest, int32_t destCapacity,
+                int32_t options,
+                UParseError* parseError,
+                UErrorCode* status);
+
+
+/**
+ * Convenience function that implements the IDNToASCII operation as defined in the IDNA RFC.
+ * This operation is done on complete domain names, e.g: "www.example.com". 
+ * It is important to note that this operation can fail. If it fails, then the input 
+ * domain name cannot be used as an Internationalized Domain Name and the application
+ * should have methods defined to deal with the failure.
+ * 
+ * <b>Note:</b> IDNA RFC specifies that a conformant application should divide a domain name
+ * into separate labels, decide whether to apply allowUnassigned and useSTD3ASCIIRules on each, 
+ * and then convert. This function does not offer that level of granularity. The options once  
+ * set will apply to all labels in the domain name
+ *
+ * @param src               Input UChar array containing IDN in Unicode.
+ * @param srcLength         Number of UChars in src, or -1 if NUL-terminated.
+ * @param dest              Output UChar array with ASCII (ACE encoded) IDN.
+ * @param destCapacity      Size of dest.
+ * @param options           A bit set of options:
+ *  
+ *  - UIDNA_DEFAULT             Use default options, i.e., do not process unassigned code points
+ *                              and do not use STD3 ASCII rules
+ *                              If unassigned code points are found the operation fails with 
+ *                              U_UNASSIGNED_CODE_POINT_FOUND error code.
+ *
+ *  - UIDNA_ALLOW_UNASSIGNED    Unassigned values can be converted to ASCII for query operations
+ *                              If this option is set, the unassigned code points are in the input 
+ *                              are treated as normal Unicode code points.
+ *                          
+ *  - UIDNA_USE_STD3_RULES      Use STD3 ASCII rules for host name syntax restrictions
+ *                              If this option is set and the input does not satisfy STD3 rules,  
+ *                              the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR
+ * 
+ * @param parseError        Pointer to UParseError struct to receive information on position 
+ *                          of error if an error is encountered. Can be NULL.
+ * @param status            ICU in/out error code parameter.
+ *                          U_INVALID_CHAR_FOUND if src contains
+ *                          unmatched single surrogates.
+ *                          U_INDEX_OUTOFBOUNDS_ERROR if src contains
+ *                          too many code points.
+ *                          U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough
+ * @return                  Number of ASCII characters converted.
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+uidna_IDNToASCII(  const UChar* src, int32_t srcLength,
+                   UChar* dest, int32_t destCapacity,
+                   int32_t options,
+                   UParseError* parseError,
+                   UErrorCode* status);
+
+/**
+ * Convenience function that implements the IDNToUnicode operation as defined in the IDNA RFC.
+ * This operation is done on complete domain names, e.g: "www.example.com". 
+ *
+ * <b>Note:</b> IDNA RFC specifies that a conformant application should divide a domain name
+ * into separate labels, decide whether to apply allowUnassigned and useSTD3ASCIIRules on each, 
+ * and then convert. This function does not offer that level of granularity. The options once  
+ * set will apply to all labels in the domain name
+ *
+ * @param src               Input UChar array containing IDN in ASCII (ACE encoded) form.
+ * @param srcLength         Number of UChars in src, or -1 if NUL-terminated.
+ * @param dest Output       UChar array containing Unicode equivalent of source IDN.
+ * @param destCapacity      Size of dest.
+ * @param options           A bit set of options:
+ *  
+ *  - UIDNA_DEFAULT             Use default options, i.e., do not process unassigned code points
+ *                              and do not use STD3 ASCII rules
+ *                              If unassigned code points are found the operation fails with 
+ *                              U_UNASSIGNED_CODE_POINT_FOUND error code.
+ *
+ *  - UIDNA_ALLOW_UNASSIGNED    Unassigned values can be converted to ASCII for query operations
+ *                              If this option is set, the unassigned code points are in the input 
+ *                              are treated as normal Unicode code points.
+ *                          
+ *  - UIDNA_USE_STD3_RULES      Use STD3 ASCII rules for host name syntax restrictions
+ *                              If this option is set and the input does not satisfy STD3 rules,  
+ *                              the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR
+ *
+ * @param parseError        Pointer to UParseError struct to receive information on position 
+ *                          of error if an error is encountered. Can be NULL.
+ * @param status            ICU in/out error code parameter.
+ *                          U_INVALID_CHAR_FOUND if src contains
+ *                          unmatched single surrogates.
+ *                          U_INDEX_OUTOFBOUNDS_ERROR if src contains
+ *                          too many code points.
+ *                          U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough
+ * @return                  Number of ASCII characters converted.
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+uidna_IDNToUnicode(  const UChar* src, int32_t srcLength,
+                     UChar* dest, int32_t destCapacity,
+                     int32_t options,
+                     UParseError* parseError,
+                     UErrorCode* status);
+
+/**
+ * Compare two IDN strings for equivalence.
+ * This function splits the domain names into labels and compares them.
+ * According to IDN RFC, whenever two labels are compared, they are 
+ * considered equal if and only if their ASCII forms (obtained by 
+ * applying toASCII) match using an case-insensitive ASCII comparison.
+ * Two domain names are considered a match if and only if all labels 
+ * match regardless of whether label separators match.
+ *
+ * @param s1                First source string.
+ * @param length1           Length of first source string, or -1 if NUL-terminated.
+ *
+ * @param s2                Second source string.
+ * @param length2           Length of second source string, or -1 if NUL-terminated.
+ * @param options           A bit set of options:
+ *  
+ *  - UIDNA_DEFAULT             Use default options, i.e., do not process unassigned code points
+ *                              and do not use STD3 ASCII rules
+ *                              If unassigned code points are found the operation fails with 
+ *                              U_UNASSIGNED_CODE_POINT_FOUND error code.
+ *
+ *  - UIDNA_ALLOW_UNASSIGNED    Unassigned values can be converted to ASCII for query operations
+ *                              If this option is set, the unassigned code points are in the input 
+ *                              are treated as normal Unicode code points.
+ *                          
+ *  - UIDNA_USE_STD3_RULES      Use STD3 ASCII rules for host name syntax restrictions
+ *                              If this option is set and the input does not satisfy STD3 rules,  
+ *                              the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR
+ *
+ * @param status            ICU error code in/out parameter.
+ *                          Must fulfill U_SUCCESS before the function call.
+ * @return <0 or 0 or >0 as usual for string comparisons
+ * @stable ICU 2.6
+ */
+U_STABLE int32_t U_EXPORT2
+uidna_compare(  const UChar *s1, int32_t length1,
+                const UChar *s2, int32_t length2,
+                int32_t options,
+                UErrorCode* status);
+
+#endif /* #if !UCONFIG_NO_IDNA */
+
+#endif

Added: MacRuby/branches/icu/unicode/uintrnal.h
===================================================================
--- MacRuby/branches/icu/unicode/uintrnal.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uintrnal.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,68 @@
+/*
+*******************************************************************************
+*   Copyright (C) 2004-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*******************************************************************************
+*
+*   file name:  
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   Created by: genheaders.pl, a perl script written by Ram Viswanadha
+*
+*  Contains data for commenting out APIs.
+*  Gets included by umachine.h
+*
+*  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
+*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
+*/
+
+#ifndef UINTRNAL_H
+#define UINTRNAL_H
+
+#ifdef U_HIDE_INTERNAL_API
+
+#    if U_DISABLE_RENAMING
+#        define RegexPatternDump RegexPatternDump_INTERNAL_API_DO_NOT_USE
+#        define ucol_collatorToIdentifier ucol_collatorToIdentifier_INTERNAL_API_DO_NOT_USE
+#        define ucol_equals ucol_equals_INTERNAL_API_DO_NOT_USE
+#        define ucol_forgetUCA ucol_forgetUCA_INTERNAL_API_DO_NOT_USE
+#        define ucol_getAttributeOrDefault ucol_getAttributeOrDefault_INTERNAL_API_DO_NOT_USE
+#        define ucol_getUnsafeSet ucol_getUnsafeSet_INTERNAL_API_DO_NOT_USE
+#        define ucol_identifierToShortString ucol_identifierToShortString_INTERNAL_API_DO_NOT_USE
+#        define ucol_openFromIdentifier ucol_openFromIdentifier_INTERNAL_API_DO_NOT_USE
+#        define ucol_prepareShortStringOpen ucol_prepareShortStringOpen_INTERNAL_API_DO_NOT_USE
+#        define ucol_shortStringToIdentifier ucol_shortStringToIdentifier_INTERNAL_API_DO_NOT_USE
+#        define uprv_getDefaultCodepage uprv_getDefaultCodepage_INTERNAL_API_DO_NOT_USE
+#        define uprv_getDefaultLocaleID uprv_getDefaultLocaleID_INTERNAL_API_DO_NOT_USE
+#        define ures_openFillIn ures_openFillIn_INTERNAL_API_DO_NOT_USE
+#        define utf8_appendCharSafeBody utf8_appendCharSafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_back1SafeBody utf8_back1SafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_countTrailBytes utf8_countTrailBytes_INTERNAL_API_DO_NOT_USE
+#        define utf8_nextCharSafeBody utf8_nextCharSafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_prevCharSafeBody utf8_prevCharSafeBody_INTERNAL_API_DO_NOT_USE
+#    else
+#        define RegexPatternDump_3_6 RegexPatternDump_INTERNAL_API_DO_NOT_USE
+#        define ucol_collatorToIdentifier_3_6 ucol_collatorToIdentifier_INTERNAL_API_DO_NOT_USE
+#        define ucol_equals_3_6 ucol_equals_INTERNAL_API_DO_NOT_USE
+#        define ucol_forgetUCA_3_6 ucol_forgetUCA_INTERNAL_API_DO_NOT_USE
+#        define ucol_getAttributeOrDefault_3_6 ucol_getAttributeOrDefault_INTERNAL_API_DO_NOT_USE
+#        define ucol_getUnsafeSet_3_6 ucol_getUnsafeSet_INTERNAL_API_DO_NOT_USE
+#        define ucol_identifierToShortString_3_6 ucol_identifierToShortString_INTERNAL_API_DO_NOT_USE
+#        define ucol_openFromIdentifier_3_6 ucol_openFromIdentifier_INTERNAL_API_DO_NOT_USE
+#        define ucol_prepareShortStringOpen_3_6 ucol_prepareShortStringOpen_INTERNAL_API_DO_NOT_USE
+#        define ucol_shortStringToIdentifier_3_6 ucol_shortStringToIdentifier_INTERNAL_API_DO_NOT_USE
+#        define uprv_getDefaultCodepage_3_6 uprv_getDefaultCodepage_INTERNAL_API_DO_NOT_USE
+#        define uprv_getDefaultLocaleID_3_6 uprv_getDefaultLocaleID_INTERNAL_API_DO_NOT_USE
+#        define ures_openFillIn_3_6 ures_openFillIn_INTERNAL_API_DO_NOT_USE
+#        define utf8_appendCharSafeBody_3_6 utf8_appendCharSafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_back1SafeBody_3_6 utf8_back1SafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_countTrailBytes_3_6 utf8_countTrailBytes_INTERNAL_API_DO_NOT_USE
+#        define utf8_nextCharSafeBody_3_6 utf8_nextCharSafeBody_INTERNAL_API_DO_NOT_USE
+#        define utf8_prevCharSafeBody_3_6 utf8_prevCharSafeBody_INTERNAL_API_DO_NOT_USE
+#    endif /* U_DISABLE_RENAMING */
+
+#endif /* U_HIDE_INTERNAL_API */
+#endif /* UINTRNAL_H */
+

Added: MacRuby/branches/icu/unicode/uiter.h
===================================================================
--- MacRuby/branches/icu/unicode/uiter.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uiter.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,707 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  uiter.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002jan18
+*   created by: Markus W. Scherer
+*/
+
+#ifndef __UITER_H__
+#define __UITER_H__
+
+/**
+ * \file
+ * \brief C API: Unicode Character Iteration
+ *
+ * @see UCharIterator
+ */
+
+#include "unicode/utypes.h"
+
+#ifdef XP_CPLUSPLUS
+    U_NAMESPACE_BEGIN
+
+    class CharacterIterator;
+    class Replaceable;
+
+    U_NAMESPACE_END
+#endif
+
+U_CDECL_BEGIN
+
+struct UCharIterator;
+typedef struct UCharIterator UCharIterator; /**< C typedef for struct UCharIterator. @stable ICU 2.1 */
+
+/**
+ * Origin constants for UCharIterator.getIndex() and UCharIterator.move().
+ * @see UCharIteratorMove
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef enum UCharIteratorOrigin {
+    UITER_START, UITER_CURRENT, UITER_LIMIT, UITER_ZERO, UITER_LENGTH
+} UCharIteratorOrigin;
+
+/** Constants for UCharIterator. @stable ICU 2.6 */
+enum {
+    /**
+     * Constant value that may be returned by UCharIteratorMove
+     * indicating that the final UTF-16 index is not known, but that the move succeeded.
+     * This can occur when moving relative to limit or length, or
+     * when moving relative to the current index after a setState()
+     * when the current UTF-16 index is not known.
+     *
+     * It would be very inefficient to have to count from the beginning of the text
+     * just to get the current/limit/length index after moving relative to it.
+     * The actual index can be determined with getIndex(UITER_CURRENT)
+     * which will count the UChars if necessary.
+     *
+     * @stable ICU 2.6
+     */
+    UITER_UNKNOWN_INDEX=-2
+};
+
+
+/**
+ * Constant for UCharIterator getState() indicating an error or
+ * an unknown state.
+ * Returned by uiter_getState()/UCharIteratorGetState
+ * when an error occurs.
+ * Also, some UCharIterator implementations may not be able to return
+ * a valid state for each position. This will be clearly documented
+ * for each such iterator (none of the public ones here).
+ *
+ * @stable ICU 2.6
+ */
+#define UITER_NO_STATE ((uint32_t)0xffffffff)
+
+/**
+ * Function type declaration for UCharIterator.getIndex().
+ *
+ * Gets the current position, or the start or limit of the
+ * iteration range.
+ *
+ * This function may perform slowly for UITER_CURRENT after setState() was called,
+ * or for UITER_LENGTH, because an iterator implementation may have to count
+ * UChars if the underlying storage is not UTF-16.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @param origin get the 0, start, limit, length, or current index
+ * @return the requested index, or U_SENTINEL in an error condition
+ *
+ * @see UCharIteratorOrigin
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef int32_t U_CALLCONV
+UCharIteratorGetIndex(UCharIterator *iter, UCharIteratorOrigin origin);
+
+/**
+ * Function type declaration for UCharIterator.move().
+ *
+ * Use iter->move(iter, index, UITER_ZERO) like CharacterIterator::setIndex(index).
+ *
+ * Moves the current position relative to the start or limit of the
+ * iteration range, or relative to the current position itself.
+ * The movement is expressed in numbers of code units forward
+ * or backward by specifying a positive or negative delta.
+ * Out of bounds movement will be pinned to the start or limit.
+ *
+ * This function may perform slowly for moving relative to UITER_LENGTH
+ * because an iterator implementation may have to count the rest of the
+ * UChars if the native storage is not UTF-16.
+ *
+ * When moving relative to the limit or length, or
+ * relative to the current position after setState() was called,
+ * move() may return UITER_UNKNOWN_INDEX (-2) to avoid an inefficient
+ * determination of the actual UTF-16 index.
+ * The actual index can be determined with getIndex(UITER_CURRENT)
+ * which will count the UChars if necessary.
+ * See UITER_UNKNOWN_INDEX for details.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @param delta can be positive, zero, or negative
+ * @param origin move relative to the 0, start, limit, length, or current index
+ * @return the new index, or U_SENTINEL on an error condition,
+ *         or UITER_UNKNOWN_INDEX when the index is not known.
+ *
+ * @see UCharIteratorOrigin
+ * @see UCharIterator
+ * @see UITER_UNKNOWN_INDEX
+ * @stable ICU 2.1
+ */
+typedef int32_t U_CALLCONV
+UCharIteratorMove(UCharIterator *iter, int32_t delta, UCharIteratorOrigin origin);
+
+/**
+ * Function type declaration for UCharIterator.hasNext().
+ *
+ * Check if current() and next() can still
+ * return another code unit.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return boolean value for whether current() and next() can still return another code unit
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef UBool U_CALLCONV
+UCharIteratorHasNext(UCharIterator *iter);
+
+/**
+ * Function type declaration for UCharIterator.hasPrevious().
+ *
+ * Check if previous() can still return another code unit.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return boolean value for whether previous() can still return another code unit
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef UBool U_CALLCONV
+UCharIteratorHasPrevious(UCharIterator *iter);
+ 
+/**
+ * Function type declaration for UCharIterator.current().
+ *
+ * Return the code unit at the current position,
+ * or U_SENTINEL if there is none (index is at the limit).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the current code unit
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef UChar32 U_CALLCONV
+UCharIteratorCurrent(UCharIterator *iter);
+
+/**
+ * Function type declaration for UCharIterator.next().
+ *
+ * Return the code unit at the current index and increment
+ * the index (post-increment, like s[i++]),
+ * or return U_SENTINEL if there is none (index is at the limit).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the current code unit (and post-increment the current index)
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef UChar32 U_CALLCONV
+UCharIteratorNext(UCharIterator *iter);
+
+/**
+ * Function type declaration for UCharIterator.previous().
+ *
+ * Decrement the index and return the code unit from there
+ * (pre-decrement, like s[--i]),
+ * or return U_SENTINEL if there is none (index is at the start).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the previous code unit (after pre-decrementing the current index)
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef UChar32 U_CALLCONV
+UCharIteratorPrevious(UCharIterator *iter);
+
+/**
+ * Function type declaration for UCharIterator.reservedFn().
+ * Reserved for future use.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @param something some integer argument
+ * @return some integer
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+typedef int32_t U_CALLCONV
+UCharIteratorReserved(UCharIterator *iter, int32_t something);
+
+/**
+ * Function type declaration for UCharIterator.getState().
+ *
+ * Get the "state" of the iterator in the form of a single 32-bit word.
+ * It is recommended that the state value be calculated to be as small as
+ * is feasible. For strings with limited lengths, fewer than 32 bits may
+ * be sufficient.
+ *
+ * This is used together with setState()/UCharIteratorSetState
+ * to save and restore the iterator position more efficiently than with
+ * getIndex()/move().
+ *
+ * The iterator state is defined as a uint32_t value because it is designed
+ * for use in ucol_nextSortKeyPart() which provides 32 bits to store the state
+ * of the character iterator.
+ *
+ * With some UCharIterator implementations (e.g., UTF-8),
+ * getting and setting the UTF-16 index with existing functions
+ * (getIndex(UITER_CURRENT) followed by move(pos, UITER_ZERO)) is possible but
+ * relatively slow because the iterator has to "walk" from a known index
+ * to the requested one.
+ * This takes more time the farther it needs to go.
+ *
+ * An opaque state value allows an iterator implementation to provide
+ * an internal index (UTF-8: the source byte array index) for
+ * fast, constant-time restoration.
+ *
+ * After calling setState(), a getIndex(UITER_CURRENT) may be slow because
+ * the UTF-16 index may not be restored as well, but the iterator can deliver
+ * the correct text contents and move relative to the current position
+ * without performance degradation.
+ *
+ * Some UCharIterator implementations may not be able to return
+ * a valid state for each position, in which case they return UITER_NO_STATE instead.
+ * This will be clearly documented for each such iterator (none of the public ones here).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the state word
+ *
+ * @see UCharIterator
+ * @see UCharIteratorSetState
+ * @see UITER_NO_STATE
+ * @stable ICU 2.6
+ */
+typedef uint32_t U_CALLCONV
+UCharIteratorGetState(const UCharIterator *iter);
+
+/**
+ * Function type declaration for UCharIterator.setState().
+ *
+ * Restore the "state" of the iterator using a state word from a getState() call.
+ * The iterator object need not be the same one as for which getState() was called,
+ * but it must be of the same type (set up using the same uiter_setXYZ function)
+ * and it must iterate over the same string
+ * (binary identical regardless of memory address).
+ * For more about the state word see UCharIteratorGetState.
+ *
+ * After calling setState(), a getIndex(UITER_CURRENT) may be slow because
+ * the UTF-16 index may not be restored as well, but the iterator can deliver
+ * the correct text contents and move relative to the current position
+ * without performance degradation.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @param state the state word from a getState() call
+ *              on a same-type, same-string iterator
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                   which must not indicate a failure before the function call.
+ *
+ * @see UCharIterator
+ * @see UCharIteratorGetState
+ * @stable ICU 2.6
+ */
+typedef void U_CALLCONV
+UCharIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode);
+
+
+/**
+ * C API for code unit iteration.
+ * This can be used as a C wrapper around
+ * CharacterIterator, Replaceable, or implemented using simple strings, etc.
+ *
+ * There are two roles for using UCharIterator:
+ *
+ * A "provider" sets the necessary function pointers and controls the "protected"
+ * fields of the UCharIterator structure. A "provider" passes a UCharIterator
+ * into C APIs that need a UCharIterator as an abstract, flexible string interface.
+ *
+ * Implementations of such C APIs are "callers" of UCharIterator functions;
+ * they only use the "public" function pointers and never access the "protected"
+ * fields directly.
+ *
+ * The current() and next() functions only check the current index against the
+ * limit, and previous() only checks the current index against the start,
+ * to see if the iterator already reached the end of the iteration range.
+ *
+ * The assumption - in all iterators - is that the index is moved via the API,
+ * which means it won't go out of bounds, or the index is modified by
+ * user code that knows enough about the iterator implementation to set valid
+ * index values.
+ *
+ * UCharIterator functions return code unit values 0..0xffff,
+ * or U_SENTINEL if the iteration bounds are reached.
+ *
+ * @stable ICU 2.1
+ */
+struct UCharIterator {
+    /**
+     * (protected) Pointer to string or wrapped object or similar.
+     * Not used by caller.
+     * @stable ICU 2.1
+     */
+    const void *context;
+
+    /**
+     * (protected) Length of string or similar.
+     * Not used by caller.
+     * @stable ICU 2.1
+     */
+    int32_t length;
+
+    /**
+     * (protected) Start index or similar.
+     * Not used by caller.
+     * @stable ICU 2.1
+     */
+    int32_t start;
+
+    /**
+     * (protected) Current index or similar.
+     * Not used by caller.
+     * @stable ICU 2.1
+     */
+    int32_t index;
+
+    /**
+     * (protected) Limit index or similar.
+     * Not used by caller.
+     * @stable ICU 2.1
+     */
+    int32_t limit;
+
+    /**
+     * (protected) Used by UTF-8 iterators and possibly others.
+     * @stable ICU 2.1
+     */
+    int32_t reservedField;
+
+    /**
+     * (public) Returns the current position or the
+     * start or limit index of the iteration range.
+     *
+     * @see UCharIteratorGetIndex
+     * @stable ICU 2.1
+     */
+    UCharIteratorGetIndex *getIndex;
+
+    /**
+     * (public) Moves the current position relative to the start or limit of the
+     * iteration range, or relative to the current position itself.
+     * The movement is expressed in numbers of code units forward
+     * or backward by specifying a positive or negative delta.
+     *
+     * @see UCharIteratorMove
+     * @stable ICU 2.1
+     */
+    UCharIteratorMove *move;
+
+    /**
+     * (public) Check if current() and next() can still
+     * return another code unit.
+     *
+     * @see UCharIteratorHasNext
+     * @stable ICU 2.1
+     */
+    UCharIteratorHasNext *hasNext;
+
+    /**
+     * (public) Check if previous() can still return another code unit.
+     *
+     * @see UCharIteratorHasPrevious
+     * @stable ICU 2.1
+     */
+    UCharIteratorHasPrevious *hasPrevious;
+
+    /**
+     * (public) Return the code unit at the current position,
+     * or U_SENTINEL if there is none (index is at the limit).
+     *
+     * @see UCharIteratorCurrent
+     * @stable ICU 2.1
+     */
+    UCharIteratorCurrent *current;
+
+    /**
+     * (public) Return the code unit at the current index and increment
+     * the index (post-increment, like s[i++]),
+     * or return U_SENTINEL if there is none (index is at the limit).
+     *
+     * @see UCharIteratorNext
+     * @stable ICU 2.1
+     */
+    UCharIteratorNext *next;
+
+    /**
+     * (public) Decrement the index and return the code unit from there
+     * (pre-decrement, like s[--i]),
+     * or return U_SENTINEL if there is none (index is at the start).
+     *
+     * @see UCharIteratorPrevious
+     * @stable ICU 2.1
+     */
+    UCharIteratorPrevious *previous;
+
+    /**
+     * (public) Reserved for future use. Currently NULL.
+     *
+     * @see UCharIteratorReserved
+     * @stable ICU 2.1
+     */
+    UCharIteratorReserved *reservedFn;
+
+    /**
+     * (public) Return the state of the iterator, to be restored later with setState().
+     * This function pointer is NULL if the iterator does not implement it.
+     *
+     * @see UCharIteratorGet
+     * @stable ICU 2.6
+     */
+    UCharIteratorGetState *getState;
+
+    /**
+     * (public) Restore the iterator state from the state word from a call
+     * to getState().
+     * This function pointer is NULL if the iterator does not implement it.
+     *
+     * @see UCharIteratorSet
+     * @stable ICU 2.6
+     */
+    UCharIteratorSetState *setState;
+};
+
+/**
+ * Helper function for UCharIterator to get the code point
+ * at the current index.
+ *
+ * Return the code point that includes the code unit at the current position,
+ * or U_SENTINEL if there is none (index is at the limit).
+ * If the current code unit is a lead or trail surrogate,
+ * then the following or preceding surrogate is used to form
+ * the code point value.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the current code point
+ *
+ * @see UCharIterator
+ * @see U16_GET
+ * @see UnicodeString::char32At()
+ * @stable ICU 2.1
+ */
+U_STABLE UChar32 U_EXPORT2
+uiter_current32(UCharIterator *iter);
+
+/**
+ * Helper function for UCharIterator to get the next code point.
+ *
+ * Return the code point at the current index and increment
+ * the index (post-increment, like s[i++]),
+ * or return U_SENTINEL if there is none (index is at the limit).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the current code point (and post-increment the current index)
+ *
+ * @see UCharIterator
+ * @see U16_NEXT
+ * @stable ICU 2.1
+ */
+U_STABLE UChar32 U_EXPORT2
+uiter_next32(UCharIterator *iter);
+
+/**
+ * Helper function for UCharIterator to get the previous code point.
+ *
+ * Decrement the index and return the code point from there
+ * (pre-decrement, like s[--i]),
+ * or return U_SENTINEL if there is none (index is at the start).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the previous code point (after pre-decrementing the current index)
+ *
+ * @see UCharIterator
+ * @see U16_PREV
+ * @stable ICU 2.1
+ */
+U_STABLE UChar32 U_EXPORT2
+uiter_previous32(UCharIterator *iter);
+
+/**
+ * Get the "state" of the iterator in the form of a single 32-bit word.
+ * This is a convenience function that calls iter->getState(iter)
+ * if iter->getState is not NULL;
+ * if it is NULL or any other error occurs, then UITER_NO_STATE is returned.
+ *
+ * Some UCharIterator implementations may not be able to return
+ * a valid state for each position, in which case they return UITER_NO_STATE instead.
+ * This will be clearly documented for each such iterator (none of the public ones here).
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @return the state word
+ *
+ * @see UCharIterator
+ * @see UCharIteratorGetState
+ * @see UITER_NO_STATE
+ * @stable ICU 2.6
+ */
+U_STABLE uint32_t U_EXPORT2
+uiter_getState(const UCharIterator *iter);
+
+/**
+ * Restore the "state" of the iterator using a state word from a getState() call.
+ * This is a convenience function that calls iter->setState(iter, state, pErrorCode)
+ * if iter->setState is not NULL; if it is NULL, then U_UNSUPPORTED_ERROR is set.
+ *
+ * @param iter the UCharIterator structure ("this pointer")
+ * @param state the state word from a getState() call
+ *              on a same-type, same-string iterator
+ * @param pErrorCode Must be a valid pointer to an error code value,
+ *                   which must not indicate a failure before the function call.
+ *
+ * @see UCharIterator
+ * @see UCharIteratorSetState
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+uiter_setState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode);
+
+/**
+ * Set up a UCharIterator to iterate over a string.
+ *
+ * Sets the UCharIterator function pointers for iteration over the string s
+ * with iteration boundaries start=index=0 and length=limit=string length.
+ * The "provider" may set the start, index, and limit values at any time
+ * within the range 0..length.
+ * The length field will be ignored.
+ *
+ * The string pointer s is set into UCharIterator.context without copying
+ * or reallocating the string contents.
+ *
+ * getState() simply returns the current index.
+ * move() will always return the final index.
+ *
+ * @param iter UCharIterator structure to be set for iteration
+ * @param s String to iterate over
+ * @param length Length of s, or -1 if NUL-terminated
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+U_STABLE void U_EXPORT2
+uiter_setString(UCharIterator *iter, const UChar *s, int32_t length);
+
+/**
+ * Set up a UCharIterator to iterate over a UTF-16BE string
+ * (byte vector with a big-endian pair of bytes per UChar).
+ *
+ * Everything works just like with a normal UChar iterator (uiter_setString),
+ * except that UChars are assembled from byte pairs,
+ * and that the length argument here indicates an even number of bytes.
+ *
+ * getState() simply returns the current index.
+ * move() will always return the final index.
+ *
+ * @param iter UCharIterator structure to be set for iteration
+ * @param s UTF-16BE string to iterate over
+ * @param length Length of s as an even number of bytes, or -1 if NUL-terminated
+ *               (NUL means pair of 0 bytes at even index from s)
+ *
+ * @see UCharIterator
+ * @see uiter_setString
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+uiter_setUTF16BE(UCharIterator *iter, const char *s, int32_t length);
+
+/**
+ * Set up a UCharIterator to iterate over a UTF-8 string.
+ *
+ * Sets the UCharIterator function pointers for iteration over the UTF-8 string s
+ * with UTF-8 iteration boundaries 0 and length.
+ * The implementation counts the UTF-16 index on the fly and
+ * lazily evaluates the UTF-16 length of the text.
+ *
+ * The start field is used as the UTF-8 offset, the limit field as the UTF-8 length.
+ * When the reservedField is not 0, then it contains a supplementary code point
+ * and the UTF-16 index is between the two corresponding surrogates.
+ * At that point, the UTF-8 index is behind that code point.
+ *
+ * The UTF-8 string pointer s is set into UCharIterator.context without copying
+ * or reallocating the string contents.
+ *
+ * getState() returns a state value consisting of
+ * - the current UTF-8 source byte index (bits 31..1)
+ * - a flag (bit 0) that indicates whether the UChar position is in the middle
+ *   of a surrogate pair
+ *   (from a 4-byte UTF-8 sequence for the corresponding supplementary code point)
+ *
+ * getState() cannot also encode the UTF-16 index in the state value.
+ * move(relative to limit or length), or
+ * move(relative to current) after setState(), may return UITER_UNKNOWN_INDEX.
+ *
+ * @param iter UCharIterator structure to be set for iteration
+ * @param s UTF-8 string to iterate over
+ * @param length Length of s in bytes, or -1 if NUL-terminated
+ *
+ * @see UCharIterator
+ * @stable ICU 2.6
+ */
+U_STABLE void U_EXPORT2
+uiter_setUTF8(UCharIterator *iter, const char *s, int32_t length);
+
+#ifdef XP_CPLUSPLUS
+
+/**
+ * Set up a UCharIterator to wrap around a C++ CharacterIterator.
+ *
+ * Sets the UCharIterator function pointers for iteration using the
+ * CharacterIterator charIter.
+ *
+ * The CharacterIterator pointer charIter is set into UCharIterator.context
+ * without copying or cloning the CharacterIterator object.
+ * The other "protected" UCharIterator fields are set to 0 and will be ignored.
+ * The iteration index and boundaries are controlled by the CharacterIterator.
+ *
+ * getState() simply returns the current index.
+ * move() will always return the final index.
+ *
+ * @param iter UCharIterator structure to be set for iteration
+ * @param charIter CharacterIterator to wrap
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+U_STABLE void U_EXPORT2
+uiter_setCharacterIterator(UCharIterator *iter, CharacterIterator *charIter);
+
+/**
+ * Set up a UCharIterator to iterate over a C++ Replaceable.
+ *
+ * Sets the UCharIterator function pointers for iteration over the
+ * Replaceable rep with iteration boundaries start=index=0 and
+ * length=limit=rep->length().
+ * The "provider" may set the start, index, and limit values at any time
+ * within the range 0..length=rep->length().
+ * The length field will be ignored.
+ *
+ * The Replaceable pointer rep is set into UCharIterator.context without copying
+ * or cloning/reallocating the Replaceable object.
+ *
+ * getState() simply returns the current index.
+ * move() will always return the final index.
+ *
+ * @param iter UCharIterator structure to be set for iteration
+ * @param rep Replaceable to iterate over
+ *
+ * @see UCharIterator
+ * @stable ICU 2.1
+ */
+U_STABLE void U_EXPORT2
+uiter_setReplaceable(UCharIterator *iter, const Replaceable *rep);
+
+#endif
+
+U_CDECL_END
+
+#endif

Added: MacRuby/branches/icu/unicode/uloc.h
===================================================================
--- MacRuby/branches/icu/unicode/uloc.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/uloc.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,931 @@
+/*
+**********************************************************************
+*   Copyright (C) 1997-2007, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*
+* File ULOC.H
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   04/01/97    aliu        Creation.
+*   08/22/98    stephen     JDK 1.2 sync.
+*   12/08/98    rtg         New C API for Locale
+*   03/30/99    damiba      overhaul
+*   03/31/99    helena      Javadoc for uloc functions.
+*   04/15/99    Madhu       Updated Javadoc
+********************************************************************************
+*/
+
+#ifndef ULOC_H
+#define ULOC_H
+
+#include "unicode/utypes.h"
+#include "unicode/uenum.h"
+
+/**    
+ * \file
+ * \brief  C API: Locale 
+ *
+ * <h2> ULoc C API for Locale </h2>
+ * A <code>Locale</code> represents a specific geographical, political,
+ * or cultural region. An operation that requires a <code>Locale</code> to perform
+ * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
+ * to tailor information for the user. For example, displaying a number
+ * is a locale-sensitive operation--the number should be formatted
+ * according to the customs/conventions of the user's native country,
+ * region, or culture.  In the C APIs, a locales is simply a const char string.
+ *
+ * <P>
+ * You create a <code>Locale</code> with one of the three options listed below.
+ * Each of the component is separated by '_' in the locale string.
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ * \code
+ *       newLanguage
+ * 
+ *       newLanguage + newCountry
+ * 
+ *       newLanguage + newCountry + newVariant
+ * \endcode
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * The first option is a valid <STRONG>ISO
+ * Language Code.</STRONG> These codes are the lower-case two-letter
+ * codes as defined by ISO-639.
+ * You can find a full list of these codes at a number of sites, such as:
+ * <BR><a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
+ * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a>
+ *
+ * <P>
+ * The second option includes an additonal <STRONG>ISO Country
+ * Code.</STRONG> These codes are the upper-case two-letter codes
+ * as defined by ISO-3166.
+ * You can find a full list of these codes at a number of sites, such as:
+ * <BR><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
+ * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a>
+ *
+ * <P>
+ * The third option requires another additonal information--the 
+ * <STRONG>Variant.</STRONG>
+ * The Variant codes are vendor and browser-specific.
+ * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
+ * Where there are two variants, separate them with an underscore, and
+ * put the most important one first. For
+ * example, a Traditional Spanish collation might be referenced, with
+ * "ES", "ES", "Traditional_WIN".
+ *
+ * <P>
+ * Because a <code>Locale</code> is just an identifier for a region,
+ * no validity check is performed when you specify a <code>Locale</code>.
+ * If you want to see whether particular resources are available for the
+ * <code>Locale</code> you asked for, you must query those resources. For
+ * example, ask the <code>UNumberFormat</code> for the locales it supports
+ * using its <code>getAvailable</code> method.
+ * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular
+ * locale, you get back the best available match, not necessarily
+ * precisely what you asked for. For more information, look at
+ * <code>UResourceBundle</code>.
+ *
+ * <P>
+ * The <code>Locale</code> provides a number of convenient constants
+ * that you can use to specify the commonly used
+ * locales. For example, the following refers to a locale
+ * for the United States:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ * \code
+ *       ULOC_US
+ * \endcode
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ *
+ * <P>
+ * Once you've specified a locale you can query it for information about
+ * itself. Use <code>uloc_getCountry</code> to get the ISO Country Code and
+ * <code>uloc_getLanguage</code> to get the ISO Language Code. You can
+ * use <code>uloc_getDisplayCountry</code> to get the
+ * name of the country suitable for displaying to the user. Similarly,
+ * you can use <code>uloc_getDisplayLanguage</code> to get the name of
+ * the language suitable for displaying to the user. Interestingly,
+ * the <code>uloc_getDisplayXXX</code> methods are themselves locale-sensitive
+ * and have two versions: one that uses the default locale and one
+ * that takes a locale as an argument and displays the name or country in
+ * a language appropriate to that locale.
+ *
+ * <P>
+ * The ICU provides a number of services that perform locale-sensitive
+ * operations. For example, the <code>unum_xxx</code> functions format
+ * numbers, currency, or percentages in a locale-sensitive manner. 
+ * </P>
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ * \code
+ *     UErrorCode success = U_ZERO_ERROR;
+ *     UNumberFormat *nf;
+ *     const char* myLocale = "fr_FR";
+ * 
+ *     nf = unum_open( UNUM_DEFAULT, NULL, success );          
+ *     unum_close(nf);
+ *     nf = unum_open( UNUM_CURRENCY, NULL, success );
+ *     unum_close(nf);
+ *     nf = unum_open( UNUM_PERCENT, NULL, success );   
+ *     unum_close(nf);
+ * \endcode
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * Each of these methods has two variants; one with an explicit locale
+ * and one without; the latter using the default locale.
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ * \code 
+ * 
+ *     nf = unum_open( UNUM_DEFAULT, myLocale, success );          
+ *     unum_close(nf);
+ *     nf = unum_open( UNUM_CURRENCY, myLocale, success );
+ *     unum_close(nf);
+ *     nf = unum_open( UNUM_PERCENT, myLocale, success );   
+ *     unum_close(nf);
+ * \endcode
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * A <code>Locale</code> is the mechanism for identifying the kind of services
+ * (<code>UNumberFormat</code>) that you would like to get. The locale is
+ * <STRONG>just</STRONG> a mechanism for identifying these services.
+ *
+ * <P>
+ * Each international serivce that performs locale-sensitive operations 
+ * allows you
+ * to get all the available objects of that type. You can sift
+ * through these objects by language, country, or variant,
+ * and use the display names to present a menu to the user.
+ * For example, you can create a menu of all the collation objects
+ * suitable for a given language. Such classes implement these
+ * three class methods:
+ * \htmlonly<blockquote>\endhtmlonly
+ * <pre>
+ * \code
+ *       const char* uloc_getAvailable(int32_t index);
+ *       int32_t uloc_countAvailable();
+ *       int32_t
+ *       uloc_getDisplayName(const char* localeID,
+ *                 const char* inLocaleID, 
+ *                 UChar* result,
+ *                 int32_t maxResultSize,
+ *                  UErrorCode* err);
+ * 
+ * \endcode
+ * </pre>
+ * \htmlonly</blockquote>\endhtmlonly
+ * <P>
+ * Concerning POSIX/RFC1766 Locale IDs, 
+ *  the getLanguage/getCountry/getVariant/getName functions do understand
+ * the POSIX type form of  language_COUNTRY.ENCODING\@VARIANT
+ * and if there is not an ICU-stype variant, uloc_getVariant() for example
+ * will return the one listed after the \@at sign. As well, the hyphen
+ * "-" is recognized as a country/variant separator similarly to RFC1766.
+ * So for example, "en-us" will be interpreted as en_US.  
+ * As a result, uloc_getName() is far from a no-op, and will have the
+ * effect of converting POSIX/RFC1766 IDs into ICU form, although it does
+ * NOT map any of the actual codes (i.e. russian->ru) in any way.
+ * Applications should call uloc_getName() at the point where a locale ID
+ * is coming from an external source (user entry, OS, web browser)
+ * and pass the resulting string to other ICU functions.  For example,
+ * don't use de-de\@EURO as an argument to resourcebundle.
+ *
+ * @see UResourceBundle
+ */
+
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_CHINESE            "zh"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_ENGLISH            "en"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_FRENCH             "fr"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_GERMAN             "de"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_ITALIAN            "it"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_JAPANESE           "ja"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_KOREAN             "ko"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_SIMPLIFIED_CHINESE "zh_CN"
+/** Useful constant for this language. @stable ICU 2.0 */
+#define ULOC_TRADITIONAL_CHINESE "zh_TW"
+
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_CANADA         "en_CA"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_CANADA_FRENCH  "fr_CA"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_CHINA          "zh_CN"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_PRC            "zh_CN"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_FRANCE         "fr_FR"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_GERMANY        "de_DE"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_ITALY          "it_IT"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_JAPAN          "ja_JP"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_KOREA          "ko_KR"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_TAIWAN         "zh_TW"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_UK             "en_GB"
+/** Useful constant for this country/region. @stable ICU 2.0 */
+#define ULOC_US             "en_US"
+
+/**
+ * Useful constant for the maximum size of the language part of a locale ID.
+ * (including the terminating NULL).
+ * @stable ICU 2.0
+ */
+#define ULOC_LANG_CAPACITY 12
+
+/**
+ * Useful constant for the maximum size of the country part of a locale ID
+ * (including the terminating NULL).
+ * @stable ICU 2.0
+ */
+#define ULOC_COUNTRY_CAPACITY 4
+/**
+ * Useful constant for the maximum size of the whole locale ID
+ * (including the terminating NULL).
+ * @stable ICU 2.0
+ */
+#define ULOC_FULLNAME_CAPACITY 56
+
+/**
+ * Useful constant for the maximum size of the script part of a locale ID
+ * (including the terminating NULL).
+ * @stable ICU 2.8
+ */
+#define ULOC_SCRIPT_CAPACITY 6
+
+/**
+ * Useful constant for the maximum size of keywords in a locale
+ * @stable ICU 2.8
+ */
+#define ULOC_KEYWORDS_CAPACITY 50
+
+/**
+ * Useful constant for the maximum SIZE of keywords in a locale
+ * @stable ICU 2.8
+ */
+#define ULOC_KEYWORD_AND_VALUES_CAPACITY 100
+
+/**
+ * Character separating keywords from the locale string
+ * different for EBCDIC - TODO
+ * @stable ICU 2.8
+ */
+#define ULOC_KEYWORD_SEPARATOR '@'
+/**
+ * Character for assigning value to a keyword
+ * @stable ICU 2.8
+ */
+#define ULOC_KEYWORD_ASSIGN '='
+/**
+ * Character separating keywords
+ * @stable ICU 2.8
+ */
+#define ULOC_KEYWORD_ITEM_SEPARATOR ';'
+
+/**
+ * Constants for *_getLocale()
+ * Allow user to select whether she wants information on 
+ * requested, valid or actual locale.
+ * For example, a collator for "en_US_CALIFORNIA" was
+ * requested. In the current state of ICU (2.0), 
+ * the requested locale is "en_US_CALIFORNIA",
+ * the valid locale is "en_US" (most specific locale supported by ICU)
+ * and the actual locale is "root" (the collation data comes unmodified 
+ * from the UCA)
+ * The locale is considered supported by ICU if there is a core ICU bundle 
+ * for that locale (although it may be empty).
+ * @stable ICU 2.1
+ */
+typedef enum {
+  /** This is locale the data actually comes from 
+   * @stable ICU 2.1
+   */
+  ULOC_ACTUAL_LOCALE    = 0,
+  /** This is the most specific locale supported by ICU 
+   * @stable ICU 2.1
+   */
+  ULOC_VALID_LOCALE    = 1,
+
+#ifndef U_HIDE_DEPRECATED_API
+  /** This is the requested locale
+   *  @deprecated ICU 2.8 
+   */
+  ULOC_REQUESTED_LOCALE = 2,
+#endif /* U_HIDE_DEPRECATED_API */
+
+  ULOC_DATA_LOCALE_TYPE_LIMIT = 3
+} ULocDataLocaleType ;
+
+
+/**
+ * Gets ICU's default locale.  
+ * The returned string is a snapshot in time, and will remain valid
+ *   and unchanged even when uloc_setDefault() is called.
+ *   The returned storage is owned by ICU, and must not be altered or deleted
+ *   by the caller.
+ *  
+ * @return the ICU default locale
+ * @system
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2
+uloc_getDefault(void);
+
+/**
+ * Sets ICU's default locale.  
+ *    By default (without calling this function), ICU's default locale will be based
+ *    on information obtained from the underlying system environment.
+ *    <p>
+ *    Changes to ICU's default locale do not propagate back to the
+ *    system environment.
+ *    <p>
+ *    Changes to ICU's default locale to not affect any ICU services that
+ *    may already be open based on the previous default locale value.
+ *
+ * @param localeID the new ICU default locale. A value of NULL will try to get
+ *                 the system's default locale.
+ * @param status the error information if the setting of default locale fails
+ * @system
+ * @stable ICU 2.0
+ */
+U_STABLE void U_EXPORT2
+uloc_setDefault(const char* localeID,
+        UErrorCode*       status);
+
+/**
+ * Gets the language code for the specified locale.
+ *
+ * @param localeID the locale to get the ISO language code with
+ * @param language the language code for localeID
+ * @param languageCapacity the size of the language buffer to store the  
+ * language code with
+ * @param err error information if retrieving the language code failed
+ * @return the actual buffer size needed for the language code.  If it's greater 
+ * than languageCapacity, the returned language code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getLanguage(const char*    localeID,
+         char* language,
+         int32_t languageCapacity,
+         UErrorCode* err);
+
+/**
+ * Gets the script code for the specified locale.
+ *
+ * @param localeID the locale to get the ISO language code with
+ * @param script the language code for localeID
+ * @param scriptCapacity the size of the language buffer to store the  
+ * language code with
+ * @param err error information if retrieving the language code failed
+ * @return the actual buffer size needed for the language code.  If it's greater 
+ * than scriptCapacity, the returned language code will be truncated.  
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getScript(const char*    localeID,
+         char* script,
+         int32_t scriptCapacity,
+         UErrorCode* err);
+
+/**
+ * Gets the  country code for the specified locale.
+ *
+ * @param localeID the locale to get the country code with
+ * @param country the country code for localeID
+ * @param countryCapacity the size of the country buffer to store the  
+ * country code with
+ * @param err error information if retrieving the country code failed
+ * @return the actual buffer size needed for the country code.  If it's greater 
+ * than countryCapacity, the returned country code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getCountry(const char*    localeID,
+        char* country,
+        int32_t countryCapacity,
+        UErrorCode* err);
+
+/**
+ * Gets the variant code for the specified locale.
+ *
+ * @param localeID the locale to get the variant code with
+ * @param variant the variant code for localeID
+ * @param variantCapacity the size of the variant buffer to store the 
+ * variant code with
+ * @param err error information if retrieving the variant code failed
+ * @return the actual buffer size needed for the variant code.  If it's greater 
+ * than variantCapacity, the returned variant code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getVariant(const char*    localeID,
+        char* variant,
+        int32_t variantCapacity,
+        UErrorCode* err);
+
+
+/**
+ * Gets the full name for the specified locale.
+ * Note: This has the effect of 'canonicalizing' the ICU locale ID to
+ * a certain extent. Upper and lower case are set as needed.
+ * It does NOT map aliased names in any way.
+ * See the top of this header file.
+ * This API supports preflighting.
+ *
+ * @param localeID the locale to get the full name with
+ * @param name fill in buffer for the name without keywords.
+ * @param nameCapacity capacity of the fill in buffer.
+ * @param err error information if retrieving the full name failed
+ * @return the actual buffer size needed for the full name.  If it's greater 
+ * than nameCapacity, the returned full name will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getName(const char*    localeID,
+         char* name,
+         int32_t nameCapacity,
+         UErrorCode* err);
+
+/**
+ * Gets the full name for the specified locale.
+ * Note: This has the effect of 'canonicalizing' the string to
+ * a certain extent. Upper and lower case are set as needed,
+ * and if the components were in 'POSIX' format they are changed to
+ * ICU format.  It does NOT map aliased names in any way.
+ * See the top of this header file.
+ *
+ * @param localeID the locale to get the full name with
+ * @param name the full name for localeID
+ * @param nameCapacity the size of the name buffer to store the 
+ * full name with
+ * @param err error information if retrieving the full name failed
+ * @return the actual buffer size needed for the full name.  If it's greater 
+ * than nameCapacity, the returned full name will be truncated.  
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_canonicalize(const char*    localeID,
+         char* name,
+         int32_t nameCapacity,
+         UErrorCode* err);
+
+/**
+ * Gets the ISO language code for the specified locale.
+ *
+ * @param localeID the locale to get the ISO language code with
+ * @return language the ISO language code for localeID
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2
+uloc_getISO3Language(const char* localeID);
+
+
+/**
+ * Gets the ISO country code for the specified locale.
+ *
+ * @param localeID the locale to get the ISO country code with
+ * @return country the ISO country code for localeID
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2
+uloc_getISO3Country(const char* localeID);
+
+/**
+ * Gets the Win32 LCID value for the specified locale.
+ * If the ICU locale is not recognized by Windows, 0 will be returned.
+ *
+ * @param localeID the locale to get the Win32 LCID value with
+ * @return country the Win32 LCID for localeID
+ * @stable ICU 2.0
+ */
+U_STABLE uint32_t U_EXPORT2
+uloc_getLCID(const char* localeID);
+
+/**
+ * Gets the language name suitable for display for the specified locale.
+ *
+ * @param locale the locale to get the ISO language code with
+ * @param displayLocale Specifies the locale to be used to display the name.  In other words,
+ *                 if the locale's language code is "en", passing Locale::getFrench() for
+ *                 inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                 for inLocale would result in "Englisch".
+ * @param language the displayable language code for localeID
+ * @param languageCapacity the size of the language buffer to store the  
+ * displayable language code with
+ * @param status error information if retrieving the displayable language code failed
+ * @return the actual buffer size needed for the displayable language code.  If it's greater 
+ * than languageCapacity, the returned language code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayLanguage(const char* locale,
+            const char* displayLocale,
+            UChar* language,
+            int32_t languageCapacity,
+            UErrorCode* status);
+
+/**
+ * Gets the script name suitable for display for the specified locale.
+ *
+ * @param locale the locale to get the displayable script code with. NULL may be used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name.  In other words,
+ *                 if the locale's language code is "en", passing Locale::getFrench() for
+ *                 inLocale would result in "", while passing Locale::getGerman()
+ *                 for inLocale would result in "". NULL may be used to specify the default.
+ * @param script the displayable country code for localeID
+ * @param scriptCapacity the size of the script buffer to store the  
+ * displayable script code with
+ * @param status error information if retrieving the displayable script code failed
+ * @return the actual buffer size needed for the displayable script code.  If it's greater 
+ * than scriptCapacity, the returned displayable script code will be truncated.  
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayScript(const char* locale,
+            const char* displayLocale,
+            UChar* script,
+            int32_t scriptCapacity,
+            UErrorCode* status);
+
+/**
+ * Gets the country name suitable for display for the specified locale.
+ *
+ * @param locale the locale to get the displayable country code with. NULL may be used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name.  In other words,
+ *                 if the locale's language code is "en", passing Locale::getFrench() for
+ *                 inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                 for inLocale would result in "Englisch". NULL may be used to specify the default.
+ * @param country the displayable country code for localeID
+ * @param countryCapacity the size of the country buffer to store the  
+ * displayable country code with
+ * @param status error information if retrieving the displayable country code failed
+ * @return the actual buffer size needed for the displayable country code.  If it's greater 
+ * than countryCapacity, the returned displayable country code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayCountry(const char* locale,
+                       const char* displayLocale,
+                       UChar* country,
+                       int32_t countryCapacity,
+                       UErrorCode* status);
+
+
+/**
+ * Gets the variant name suitable for display for the specified locale.
+ *
+ * @param locale the locale to get the displayable variant code with. NULL may be used to specify the default.
+ * @param displayLocale Specifies the locale to be used to display the name.  In other words,
+ *                 if the locale's language code is "en", passing Locale::getFrench() for
+ *                 inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                 for inLocale would result in "Englisch". NULL may be used to specify the default.
+ * @param variant the displayable variant code for localeID
+ * @param variantCapacity the size of the variant buffer to store the 
+ * displayable variant code with
+ * @param status error information if retrieving the displayable variant code failed
+ * @return the actual buffer size needed for the displayable variant code.  If it's greater 
+ * than variantCapacity, the returned displayable variant code will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayVariant(const char* locale,
+                       const char* displayLocale,
+                       UChar* variant,
+                       int32_t variantCapacity,
+                       UErrorCode* status);
+
+/**
+ * Gets the keyword name suitable for display for the specified locale.
+ * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display 
+ * string for the keyword collation. 
+ * Usage:
+ * <code>
+ *    UErrorCode status = U_ZERO_ERROR;
+ *    const char* keyword =NULL;
+ *    int32_t keywordLen = 0;
+ *    int32_t keywordCount = 0;
+ *    UChar displayKeyword[256];
+ *    int32_t displayKeywordLen = 0;
+ *    UEnumeration* keywordEnum = uloc_openKeywords("de_DE at collation=PHONEBOOK;calendar=TRADITIONAL", &status);
+ *    for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){
+ *          if(U_FAILURE(status)){
+ *              ...something went wrong so handle the error...
+ *              break;
+ *          }
+ *          // the uenum_next returns NUL terminated string
+ *          keyword = uenum_next(keywordEnum, &keywordLen, &status);
+ *          displayKeywordLen = uloc_getDisplayKeyword(keyword, "en_US", displayKeyword, 256);
+ *          ... do something interesting .....
+ *    }
+ *    uenum_close(keywordEnum);
+ * </code>
+ * @param keyword           The keyword whose display string needs to be returned.
+ * @param displayLocale     Specifies the locale to be used to display the name.  In other words,
+ *                          if the locale's language code is "en", passing Locale::getFrench() for
+ *                          inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                          for inLocale would result in "Englisch". NULL may be used to specify the default.
+ * @param dest              the buffer to which the displayable keyword should be written.
+ * @param destCapacity      The size of the buffer (number of UChars). If it is 0, then
+ *                          dest may be NULL and the function will only return the length of the 
+ *                          result without writing any of the result string (pre-flighting).
+ * @param status            error information if retrieving the displayable string failed. 
+ *                          Should not be NULL and should not indicate failure on entry.
+ * @return the actual buffer size needed for the displayable variant code.  
+ * @see #uloc_openKeywords
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayKeyword(const char* keyword,
+                       const char* displayLocale,
+                       UChar* dest,
+                       int32_t destCapacity,
+                       UErrorCode* status);
+/**
+ * Gets the value of the keyword suitable for display for the specified locale.
+ * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display 
+ * string for PHONEBOOK, in the display locale, when "collation" is specified as the keyword.
+ *
+ * @param locale            The locale to get the displayable variant code with. NULL may be used to specify the default.
+ * @param keyword           The keyword for whose value should be used.
+ * @param displayLocale     Specifies the locale to be used to display the name.  In other words,
+ *                          if the locale's language code is "en", passing Locale::getFrench() for
+ *                          inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                          for inLocale would result in "Englisch". NULL may be used to specify the default.
+ * @param dest              the buffer to which the displayable keyword should be written.
+ * @param destCapacity      The size of the buffer (number of UChars). If it is 0, then
+ *                          dest may be NULL and the function will only return the length of the 
+ *                          result without writing any of the result string (pre-flighting).
+ * @param status            error information if retrieving the displayable string failed. 
+ *                          Should not be NULL and must not indicate failure on entry.
+ * @return the actual buffer size needed for the displayable variant code.  
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayKeywordValue(   const char* locale,
+                               const char* keyword,
+                               const char* displayLocale,
+                               UChar* dest,
+                               int32_t destCapacity,
+                               UErrorCode* status);
+/**
+ * Gets the full name suitable for display for the specified locale.
+ *
+ * @param localeID the locale to get the displayable name with. NULL may be used to specify the default.
+ * @param inLocaleID Specifies the locale to be used to display the name.  In other words,
+ *                   if the locale's language code is "en", passing Locale::getFrench() for
+ *                   inLocale would result in "Anglais", while passing Locale::getGerman()
+ *                   for inLocale would result in "Englisch". NULL may be used to specify the default.
+ * @param result the displayable name for localeID
+ * @param maxResultSize the size of the name buffer to store the 
+ * displayable full name with
+ * @param err error information if retrieving the displayable name failed
+ * @return the actual buffer size needed for the displayable name.  If it's greater 
+ * than maxResultSize, the returned displayable name will be truncated.  
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getDisplayName(const char* localeID,
+            const char* inLocaleID,
+            UChar* result,
+            int32_t maxResultSize,
+            UErrorCode* err);
+
+
+/**
+ * Gets the specified locale from a list of all available locales.  
+ * The return value is a pointer to an item of 
+ * a locale name array.  Both this array and the pointers
+ * it contains are owned by ICU and should not be deleted or written through
+ * by the caller.  The locale name is terminated by a null pointer.
+ * @param n the specific locale name index of the available locale list
+ * @return a specified locale name of all available locales
+ * @stable ICU 2.0
+ */
+U_STABLE const char* U_EXPORT2
+uloc_getAvailable(int32_t n);
+
+/**
+ * Gets the size of the all available locale list.
+ *
+ * @return the size of the locale list
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2 uloc_countAvailable(void);
+
+/**
+ *
+ * Gets a list of all available language codes defined in ISO 639.  This is a pointer
+ * to an array of pointers to arrays of char.  All of these pointers are owned
+ * by ICU-- do not delete them, and do not write through them.  The array is
+ * terminated with a null pointer.
+ * @return a list of all available language codes
+ * @stable ICU 2.0
+ */
+U_STABLE const char* const* U_EXPORT2
+uloc_getISOLanguages(void);
+
+/**
+ *
+ * Gets a list of all available 2-letter country codes defined in ISO 639.  This is a
+ * pointer to an array of pointers to arrays of char.  All of these pointers are
+ * owned by ICU-- do not delete them, and do not write through them.  The array is
+ * terminated with a null pointer.
+ * @return a list of all available country codes
+ * @stable ICU 2.0
+ */
+U_STABLE const char* const* U_EXPORT2
+uloc_getISOCountries(void);
+
+/**
+ * Truncate the locale ID string to get the parent locale ID.
+ * Copies the part of the string before the last underscore.
+ * The parent locale ID will be an empty string if there is no
+ * underscore, or if there is only one underscore at localeID[0].
+ *
+ * @param localeID Input locale ID string.
+ * @param parent   Output string buffer for the parent locale ID.
+ * @param parentCapacity Size of the output buffer.
+ * @param err A UErrorCode value.
+ * @return The length of the parent locale ID.
+ * @stable ICU 2.0
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getParent(const char*    localeID,
+                 char* parent,
+                 int32_t parentCapacity,
+                 UErrorCode* err);
+
+
+
+
+/**
+ * Gets the full name for the specified locale.
+ * Note: This has the effect of 'canonicalizing' the string to
+ * a certain extent. Upper and lower case are set as needed,
+ * and if the components were in 'POSIX' format they are changed to
+ * ICU format.  It does NOT map aliased names in any way.
+ * See the top of this header file.
+ * This API strips off the keyword part, so "de_DE\@collation=phonebook" 
+ * will become "de_DE". 
+ * This API supports preflighting.
+ *
+ * @param localeID the locale to get the full name with
+ * @param name fill in buffer for the name without keywords.
+ * @param nameCapacity capacity of the fill in buffer.
+ * @param err error information if retrieving the full name failed
+ * @return the actual buffer size needed for the full name.  If it's greater 
+ * than nameCapacity, the returned full name will be truncated.  
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getBaseName(const char*    localeID,
+         char* name,
+         int32_t nameCapacity,
+         UErrorCode* err);
+
+/**
+ * Gets an enumeration of keywords for the specified locale. Enumeration
+ * must get disposed of by the client using uenum_close function.
+ *
+ * @param localeID the locale to get the variant code with
+ * @param status error information if retrieving the keywords failed
+ * @return enumeration of keywords or NULL if there are no keywords.
+ * @stable ICU 2.8
+ */
+U_STABLE UEnumeration* U_EXPORT2
+uloc_openKeywords(const char* localeID,
+                        UErrorCode* status);
+
+/**
+ * Get the value for a keyword. Locale name does not need to be normalized.
+ * 
+ * @param localeID locale name containing the keyword ("de_DE at currency=EURO;collation=PHONEBOOK")
+ * @param keywordName name of the keyword for which we want the value. Case insensitive.
+ * @param buffer receiving buffer
+ * @param bufferCapacity capacity of receiving buffer
+ * @param status containing error code - buffer not big enough.
+ * @return the length of keyword value
+ * @stable ICU 2.8
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_getKeywordValue(const char* localeID,
+                     const char* keywordName,
+                     char* buffer, int32_t bufferCapacity,
+                     UErrorCode* status);
+
+
+/**
+ * Set the value of the specified keyword.
+ * NOTE: Unlike almost every other ICU function which takes a
+ * buffer, this function will NOT truncate the output text. If a
+ * BUFFER_OVERFLOW_ERROR is received, it means that the original
+ * buffer is untouched. This is done to prevent incorrect or possibly
+ * even malformed locales from being generated and used.
+ * 
+ * @param keywordName name of the keyword to be set. Case insensitive.
+ * @param keywordValue value of the keyword to be set. If 0-length or
+ *  NULL, will result in the keyword being removed. No error is given if 
+ *  that keyword does not exist.
+ * @param buffer input buffer containing locale to be modified.
+ * @param bufferCapacity capacity of receiving buffer
+ * @param status containing error code - buffer not big enough.
+ * @return the length needed for the buffer
+ * @see uloc_getKeywordValue
+ * @stable ICU 3.2
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_setKeywordValue(const char* keywordName,
+                     const char* keywordValue,
+                     char* buffer, int32_t bufferCapacity,
+                     UErrorCode* status);
+
+/**
+ * enums for the 'outResult' parameter return value
+ * @see uloc_acceptLanguageFromHTTP
+ * @see uloc_acceptLanguage
+ * @stable ICU 3.2
+ */
+typedef enum {
+  ULOC_ACCEPT_FAILED   = 0,  /* No exact match was found. */
+  ULOC_ACCEPT_VALID    = 1,  /* An exact match was found. */
+  ULOC_ACCEPT_FALLBACK = 2   /* A fallback was found, for example, 
+                                Accept list contained 'ja_JP'
+                                which matched available locale 'ja'. */
+} UAcceptResult;
+
+
+/**
+ * Based on a HTTP header from a web browser and a list of available locales,
+ * determine an acceptable locale for the user.
+ * @param result - buffer to accept the result locale
+ * @param resultAvailable the size of the result buffer.
+ * @param outResult - An out parameter that contains the fallback status
+ * @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
+ * @param availableLocales - list of available locales to match
+ * @param status Error status, may be BUFFER_OVERFLOW_ERROR
+ * @return length needed for the locale.
+ * @stable ICU 3.2
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable,
+                            UAcceptResult *outResult,
+                            const char *httpAcceptLanguage,
+                            UEnumeration* availableLocales,
+                            UErrorCode *status);
+
+/**
+ * Based on a list of available locales,
+ * determine an acceptable locale for the user.
+ * @param result - buffer to accept the result locale
+ * @param resultAvailable the size of the result buffer.
+ * @param outResult - An out parameter that contains the fallback status
+ * @param acceptList - list of acceptable languages
+ * @param acceptListCount - count of acceptList items
+ * @param availableLocales - list of available locales to match
+ * @param status Error status, may be BUFFER_OVERFLOW_ERROR
+ * @return length needed for the locale.
+ * @stable ICU 3.2
+ */
+U_STABLE int32_t U_EXPORT2
+uloc_acceptLanguage(char *result, int32_t resultAvailable, 
+                    UAcceptResult *outResult, const char **acceptList,
+                    int32_t acceptListCount,
+                    UEnumeration* availableLocales,
+                    UErrorCode *status);
+
+
+/**
+ * Gets the ICU locale ID for the specified Win32 LCID value.
+ *
+ * @param hostID the Win32 LCID to translate
+ * @param locale the output buffer for the ICU locale ID, which will be NUL-terminated
+ *  if there is room.
+ * @param localeCapacity the size of the output buffer
+ * @param status an error is returned if the LCID is unrecognized or the output buffer
+ *  is too small
+ * @return actual the actual size of the locale ID, not including NUL-termination 
+ * @draft ICU 3.8
+ */
+U_DRAFT int32_t U_EXPORT2
+uloc_getLocaleForLCID(uint32_t hostid, char *locale, int32_t localeCapacity,
+                    UErrorCode *status);
+
+#endif /*_ULOC*/
+
+

Added: MacRuby/branches/icu/unicode/umachine.h
===================================================================
--- MacRuby/branches/icu/unicode/umachine.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/umachine.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,381 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  umachine.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999sep13
+*   created by: Markus W. Scherer
+*
+*   This file defines basic types and constants for utf.h to be
+*   platform-independent. umachine.h and utf.h are included into
+*   utypes.h to provide all the general definitions for ICU.
+*   All of these definitions used to be in utypes.h before
+*   the UTF-handling macros made this unmaintainable.
+*/
+
+#ifndef __UMACHINE_H__
+#define __UMACHINE_H__
+
+
+/**
+ * \file
+ * \brief Basic types and constants for UTF 
+ * 
+ * <h2> Basic types and constants for UTF </h2>
+ *   This file defines basic types and constants for utf.h to be
+ *   platform-independent. umachine.h and utf.h are included into
+ *   utypes.h to provide all the general definitions for ICU.
+ *   All of these definitions used to be in utypes.h before
+ *   the UTF-handling macros made this unmaintainable.
+ * 
+ */
+/*==========================================================================*/
+/* Include platform-dependent definitions                                   */
+/* which are contained in the platform-specific file platform.h             */
+/*==========================================================================*/
+
+#if defined(U_PALMOS)
+#   include "unicode/ppalmos.h"
+#elif defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#   include "unicode/pwin32.h"
+#else
+#   include "unicode/platform.h"
+#endif
+
+/*
+ * ANSI C headers:
+ * stddef.h defines wchar_t
+ */
+#include <stddef.h>
+
+/*==========================================================================*/
+/* XP_CPLUSPLUS is a cross-platform symbol which should be defined when     */
+/* using C++.  It should not be defined when compiling under C.             */
+/*==========================================================================*/
+
+#ifdef __cplusplus
+#   ifndef XP_CPLUSPLUS
+#       define XP_CPLUSPLUS
+#   endif
+#else
+#   undef XP_CPLUSPLUS
+#endif
+
+/*==========================================================================*/
+/* For C wrappers, we use the symbol U_STABLE.                                */
+/* This works properly if the includer is C or C++.                         */
+/* Functions are declared   U_STABLE return-type U_EXPORT2 function-name()... */
+/*==========================================================================*/
+
+/**
+ * \def U_CFUNC
+ * This is used in a declaration of a library private ICU C function.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_CDECL_BEGIN
+ * This is used to begin a declaration of a library private ICU C API.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_CDECL_END
+ * This is used to end a declaration of a library private ICU C API 
+ * @stable ICU 2.4
+ */
+
+#ifdef XP_CPLUSPLUS
+#   define U_CFUNC extern "C"
+#   define U_CDECL_BEGIN extern "C" {
+#   define U_CDECL_END   }
+#else
+#   define U_CFUNC extern
+#   define U_CDECL_BEGIN
+#   define U_CDECL_END
+#endif
+
+/**
+ * \def U_NAMESPACE_BEGIN
+ * This is used to begin a declaration of a public ICU C++ API.
+ * If the compiler doesn't support namespaces, this does nothing.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_NAMESPACE_END
+ * This is used to end a declaration of a public ICU C++ API 
+ * If the compiler doesn't support namespaces, this does nothing.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_NAMESPACE_USE
+ * This is used to specify that the rest of the code uses the
+ * public ICU C++ API namespace.
+ * If the compiler doesn't support namespaces, this does nothing.
+ * @stable ICU 2.4
+ */
+
+/**
+ * \def U_NAMESPACE_QUALIFIER
+ * This is used to qualify that a function or class is part of
+ * the public ICU C++ API namespace.
+ * If the compiler doesn't support namespaces, this does nothing.
+ * @stable ICU 2.4
+ */
+
+/* Define namespace symbols if the compiler supports it. */
+#if U_HAVE_NAMESPACE
+#   define U_NAMESPACE_BEGIN namespace U_ICU_NAMESPACE {
+#   define U_NAMESPACE_END  }
+#   define U_NAMESPACE_USE using namespace U_ICU_NAMESPACE;
+#   define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE::
+#else
+#   define U_NAMESPACE_BEGIN
+#   define U_NAMESPACE_END
+#   define U_NAMESPACE_USE
+#   define U_NAMESPACE_QUALIFIER
+#endif
+
+/** This is used to declare a function as a public ICU C API @stable ICU 2.0*/
+#define U_CAPI U_CFUNC U_EXPORT
+#define U_STABLE U_CAPI
+#define U_DRAFT  U_CAPI
+#define U_DEPRECATED U_CAPI
+#define U_OBSOLETE U_CAPI
+#define U_INTERNAL U_CAPI
+
+/*==========================================================================*/
+/* limits for int32_t etc., like in POSIX inttypes.h                        */
+/*==========================================================================*/
+
+#ifndef INT8_MIN
+/** The smallest value an 8 bit signed integer can hold @stable ICU 2.0 */
+#   define INT8_MIN        ((int8_t)(-128))
+#endif
+#ifndef INT16_MIN
+/** The smallest value a 16 bit signed integer can hold @stable ICU 2.0 */
+#   define INT16_MIN       ((int16_t)(-32767-1))
+#endif
+#ifndef INT32_MIN
+/** The smallest value a 32 bit signed integer can hold @stable ICU 2.0 */
+#   define INT32_MIN       ((int32_t)(-2147483647-1))
+#endif
+
+#ifndef INT8_MAX
+/** The largest value an 8 bit signed integer can hold @stable ICU 2.0 */
+#   define INT8_MAX        ((int8_t)(127))
+#endif
+#ifndef INT16_MAX
+/** The largest value a 16 bit signed integer can hold @stable ICU 2.0 */
+#   define INT16_MAX       ((int16_t)(32767))
+#endif
+#ifndef INT32_MAX
+/** The largest value a 32 bit signed integer can hold @stable ICU 2.0 */
+#   define INT32_MAX       ((int32_t)(2147483647))
+#endif
+
+#ifndef UINT8_MAX
+/** The largest value an 8 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT8_MAX       ((uint8_t)(255U))
+#endif
+#ifndef UINT16_MAX
+/** The largest value a 16 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT16_MAX      ((uint16_t)(65535U))
+#endif
+#ifndef UINT32_MAX
+/** The largest value a 32 bit unsigned integer can hold @stable ICU 2.0 */
+#   define UINT32_MAX      ((uint32_t)(4294967295U))
+#endif
+
+#if defined(U_INT64_T_UNAVAILABLE)
+# error int64_t is required for decimal format and rule-based number format.
+#else
+# ifndef INT64_C
+/**
+ * Provides a platform independent way to specify a signed 64-bit integer constant.
+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides INT64_C
+ * @stable ICU 2.8
+ */
+#   define INT64_C(c) c ## LL
+# endif
+# ifndef UINT64_C
+/**
+ * Provides a platform independent way to specify an unsigned 64-bit integer constant.
+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides UINT64_C
+ * @stable ICU 2.8
+ */
+#   define UINT64_C(c) c ## ULL
+# endif
+# ifndef U_INT64_MIN
+/** The smallest value a 64 bit signed integer can hold @stable ICU 2.8 */
+#     define U_INT64_MIN       ((int64_t)(INT64_C(-9223372036854775807)-1))
+# endif
+# ifndef U_INT64_MAX
+/** The largest value a 64 bit signed integer can hold @stable ICU 2.8 */
+#     define U_INT64_MAX       ((int64_t)(INT64_C(9223372036854775807)))
+# endif
+# ifndef U_UINT64_MAX
+/** The largest value a 64 bit unsigned integer can hold @stable ICU 2.8 */
+#     define U_UINT64_MAX      ((uint64_t)(UINT64_C(18446744073709551615)))
+# endif
+#endif
+
+/*==========================================================================*/
+/* Boolean data type                                                        */
+/*==========================================================================*/
+
+/** The ICU boolean type @stable ICU 2.0 */
+typedef int8_t UBool;
+
+#ifndef TRUE
+/** The TRUE value of a UBool @stable ICU 2.0 */
+#   define TRUE  1
+#endif
+#ifndef FALSE
+/** The FALSE value of a UBool @stable ICU 2.0 */
+#   define FALSE 0
+#endif
+
+
+/*==========================================================================*/
+/* Unicode data types                                                       */
+/*==========================================================================*/
+
+/* wchar_t-related definitions -------------------------------------------- */
+
+/**
+ * \def U_HAVE_WCHAR_H
+ * Indicates whether <wchar.h> is available (1) or not (0). Set to 1 by default.
+ *
+ * @stable ICU 2.0
+ */
+#ifndef U_HAVE_WCHAR_H
+#   define U_HAVE_WCHAR_H 1
+#endif
+
+/**
+ * \def U_SIZEOF_WCHAR_T
+ * U_SIZEOF_WCHAR_T==sizeof(wchar_t) (0 means it is not defined or autoconf could not set it)
+ *
+ * @stable ICU 2.0
+ */
+#if U_SIZEOF_WCHAR_T==0
+#   undef U_SIZEOF_WCHAR_T
+#   define U_SIZEOF_WCHAR_T 4
+#endif
+
+/*
+ * \def U_WCHAR_IS_UTF16
+ * Defined if wchar_t uses UTF-16.
+ *
+ * @stable ICU 2.0
+ */
+/*
+ * \def U_WCHAR_IS_UTF32
+ * Defined if wchar_t uses UTF-32.
+ *
+ * @stable ICU 2.0
+ */
+#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32)
+#   ifdef __STDC_ISO_10646__ 
+#       if (U_SIZEOF_WCHAR_T==2)
+#           define U_WCHAR_IS_UTF16
+#       elif (U_SIZEOF_WCHAR_T==4)
+#           define  U_WCHAR_IS_UTF32
+#       endif
+#   elif defined __UCS2__
+#       if (__OS390__ || __OS400__) && (U_SIZEOF_WCHAR_T==2)
+#           define U_WCHAR_IS_UTF16
+#       endif
+#   elif defined __UCS4__
+#       if (U_SIZEOF_WCHAR_T==4)
+#           define U_WCHAR_IS_UTF32
+#       endif
+#   elif defined(U_WINDOWS)
+#       define U_WCHAR_IS_UTF16    
+#   endif
+#endif
+
+/* UChar and UChar32 definitions -------------------------------------------- */
+
+/** Number of bytes in a UChar. @stable ICU 2.0 */
+#define U_SIZEOF_UCHAR 2
+
+/**
+ * \var UChar
+ * Define UChar to be wchar_t if that is 16 bits wide; always assumed to be unsigned.
+ * If wchar_t is not 16 bits wide, then define UChar to be uint16_t.
+ * This makes the definition of UChar platform-dependent
+ * but allows direct string type compatibility with platforms with
+ * 16-bit wchar_t types.
+ *
+ * @stable ICU 2.0
+ */
+
+/* Define UChar to be compatible with wchar_t if possible. */
+#if U_SIZEOF_WCHAR_T==2
+    typedef wchar_t UChar;
+#else
+    typedef uint16_t UChar;
+#endif
+
+/**
+ * Define UChar32 as a type for single Unicode code points.
+ * UChar32 is a signed 32-bit integer (same as int32_t).
+ *
+ * The Unicode code point range is 0..0x10ffff.
+ * All other values (negative or >=0x110000) are illegal as Unicode code points.
+ * They may be used as sentinel values to indicate "done", "error"
+ * or similar non-code point conditions.
+ *
+ * Before ICU 2.4 (Jitterbug 2146), UChar32 was defined
+ * to be wchar_t if that is 32 bits wide (wchar_t may be signed or unsigned)
+ * or else to be uint32_t.
+ * That is, the definition of UChar32 was platform-dependent.
+ *
+ * @see U_SENTINEL
+ * @stable ICU 2.4
+ */
+typedef int32_t UChar32;
+
+/*==========================================================================*/
+/* U_INLINE and U_ALIGN_CODE   Set default values if these are not already  */
+/*                             defined.  Definitions normally are in        */
+/*                             platform.h or the corresponding file for     */
+/*                             the OS in use.                               */
+/*==========================================================================*/
+
+#ifndef U_HIDE_INTERNAL_API
+
+/**
+ * \def U_ALIGN_CODE
+ * This is used to align code fragments to a specific byte boundary.
+ * This is useful for getting consistent performance test results.
+ * @internal
+ */
+#ifndef U_ALIGN_CODE
+#   define U_ALIGN_CODE(n)
+#endif
+
+#endif /* U_HIDE_INTERNAL_API */
+
+#ifndef U_INLINE
+#   ifdef XP_CPLUSPLUS
+#       define U_INLINE inline
+#   else
+#       define U_INLINE
+#   endif
+#endif
+
+#include "unicode/urename.h"
+
+#endif

Added: MacRuby/branches/icu/unicode/umisc.h
===================================================================
--- MacRuby/branches/icu/unicode/umisc.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/umisc.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,60 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   file name:  umisc.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999oct15
+*   created by: Markus W. Scherer
+*/
+
+#ifndef UMISC_H
+#define UMISC_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file
+ * \brief  C API:misc definitions 
+ *
+ *  This file contains miscellaneous definitions for the C APIs. 
+ */
+
+U_CDECL_BEGIN
+
+/** A struct representing a range of text containing a specific field 
+ *  @stable ICU 2.0
+ */
+typedef struct UFieldPosition {
+  /**
+   * The field 
+   * @stable ICU 2.0
+   */
+  int32_t field;
+  /**
+   * The start of the text range containing field 
+   * @stable ICU 2.0
+   */
+  int32_t beginIndex;
+  /** 
+   * The limit of the text range containing field 
+   * @stable ICU 2.0
+   */
+  int32_t endIndex;
+} UFieldPosition;
+
+#if !UCONFIG_NO_SERVICE
+/**
+ * Opaque type returned by registerInstance, registerFactory and unregister for service registration.
+ * @stable ICU 2.6
+ */
+typedef const void* URegistryKey;
+#endif
+
+U_CDECL_END
+
+#endif

Added: MacRuby/branches/icu/unicode/unifilt.h
===================================================================
--- MacRuby/branches/icu/unicode/unifilt.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/unifilt.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,127 @@
+/*
+**********************************************************************
+* Copyright (C) 1999-2006, International Business Machines Corporation and others.
+* All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   11/17/99    aliu        Creation.
+**********************************************************************
+*/
+#ifndef UNIFILT_H
+#define UNIFILT_H
+
+#include "unicode/unifunct.h"
+#include "unicode/unimatch.h"
+
+/**
+ * \file 
+ * \brief C++ API: Unicode Filter
+ */
+
+U_NAMESPACE_BEGIN
+
+/**
+ * U_ETHER is used to represent character values for positions outside
+ * a range.  For example, transliterator uses this to represent
+ * characters outside the range contextStart..contextLimit-1.  This
+ * allows explicit matching by rules and UnicodeSets of text outside a
+ * defined range.
+ * @stable ICU 3.0
+ */
+#define U_ETHER ((UChar)0xFFFF)
+
+/**
+ *
+ * <code>UnicodeFilter</code> defines a protocol for selecting a
+ * subset of the full range (U+0000 to U+10FFFF) of Unicode characters.
+ * Currently, filters are used in conjunction with classes like {@link
+ * Transliterator} to only process selected characters through a
+ * transformation.
+ *
+ * <p>Note: UnicodeFilter currently stubs out two pure virtual methods
+ * of its base class, UnicodeMatcher.  These methods are toPattern()
+ * and matchesIndexValue().  This is done so that filter classes that
+ * are not actually used as matchers -- specifically, those in the
+ * UnicodeFilterLogic component, and those in tests -- can continue to
+ * work without defining these methods.  As long as a filter is not
+ * used in an RBT during real transliteration, these methods will not
+ * be called.  However, this breaks the UnicodeMatcher base class
+ * protocol, and it is not a correct solution.
+ *
+ * <p>In the future we may revisit the UnicodeMatcher / UnicodeFilter
+ * hierarchy and either redesign it, or simply remove the stubs in
+ * UnicodeFilter and force subclasses to implement the full
+ * UnicodeMatcher protocol.
+ *
+ * @see UnicodeFilterLogic
+ * @stable ICU 2.0
+ */
+class U_COMMON_API UnicodeFilter : public UnicodeFunctor, public UnicodeMatcher {
+
+public:
+    /**
+     * Destructor
+     * @stable ICU 2.0
+     */
+    virtual ~UnicodeFilter();
+
+    /**
+     * Returns <tt>true</tt> for characters that are in the selected
+     * subset.  In other words, if a character is <b>to be
+     * filtered</b>, then <tt>contains()</tt> returns
+     * <b><tt>false</tt></b>.
+     * @stable ICU 2.0
+     */
+    virtual UBool contains(UChar32 c) const = 0;
+
+    /**
+     * UnicodeFunctor API.  Cast 'this' to a UnicodeMatcher* pointer
+     * and return the pointer.
+     * @stable ICU 2.4
+     */
+    virtual UnicodeMatcher* toMatcher() const;
+
+    /**
+     * Implement UnicodeMatcher API.
+     * @stable ICU 2.4
+     */
+    virtual UMatchDegree matches(const Replaceable& text,
+                                 int32_t& offset,
+                                 int32_t limit,
+                                 UBool incremental);
+
+    /**
+     * UnicodeFunctor API.  Nothing to do.
+     * @stable ICU 2.4
+     */
+    virtual void setData(const TransliterationRuleData*);
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.2
+     */
+    virtual UClassID getDynamicClassID() const = 0;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.2
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+protected:
+
+    /*
+     * Since this class has pure virtual functions,
+     * a constructor can't be used.
+     * @stable ICU 2.0
+     */
+/*    UnicodeFilter();*/
+};
+
+/*inline UnicodeFilter::UnicodeFilter() {}*/
+
+U_NAMESPACE_END
+
+#endif

Added: MacRuby/branches/icu/unicode/unifunct.h
===================================================================
--- MacRuby/branches/icu/unicode/unifunct.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/unifunct.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,125 @@
+/*
+**********************************************************************
+*   Copyright (c) 2002-2005, International Business Machines Corporation
+*   and others.  All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   01/14/2002  aliu        Creation.
+**********************************************************************
+*/
+#ifndef UNIFUNCT_H
+#define UNIFUNCT_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+
+/**
+ * \file 
+ * \brief C++ API: Unicode Functor
+ */
+ 
+U_NAMESPACE_BEGIN
+
+class UnicodeMatcher;
+class UnicodeReplacer;
+class TransliterationRuleData;
+
+/**
+ * <code>UnicodeFunctor</code> is an abstract base class for objects
+ * that perform match and/or replace operations on Unicode strings.
+ * @author Alan Liu
+ * @stable ICU 2.4
+ */
+class U_COMMON_API UnicodeFunctor : public UObject {
+
+public:
+
+    /**
+     * Destructor
+     * @stable ICU 2.4
+     */
+    virtual ~UnicodeFunctor();
+
+    /**
+     * Return a copy of this object.  All UnicodeFunctor objects
+     * have to support cloning in order to allow classes using
+     * UnicodeFunctor to implement cloning.
+     * @stable ICU 2.4
+     */
+    virtual UnicodeFunctor* clone() const = 0;
+
+    /**
+     * Cast 'this' to a UnicodeMatcher* pointer and return the
+     * pointer, or null if this is not a UnicodeMatcher*.  Subclasses
+     * that mix in UnicodeMatcher as a base class must override this.
+     * This protocol is required because a pointer to a UnicodeFunctor
+     * cannot be cast to a pointer to a UnicodeMatcher, since
+     * UnicodeMatcher is a mixin that does not derive from
+     * UnicodeFunctor.
+     * @stable ICU 2.4
+     */
+    virtual UnicodeMatcher* toMatcher() const;
+
+    /**
+     * Cast 'this' to a UnicodeReplacer* pointer and return the
+     * pointer, or null if this is not a UnicodeReplacer*.  Subclasses
+     * that mix in UnicodeReplacer as a base class must override this.
+     * This protocol is required because a pointer to a UnicodeFunctor
+     * cannot be cast to a pointer to a UnicodeReplacer, since
+     * UnicodeReplacer is a mixin that does not derive from
+     * UnicodeFunctor.
+     * @stable ICU 2.4
+     */
+    virtual UnicodeReplacer* toReplacer() const;
+
+    /**
+     * Return the class ID for this class.  This is useful only for
+     * comparing to a return value from getDynamicClassID().
+     * @return          The class ID for all objects of this class.
+     * @stable ICU 2.0
+     */
+    static UClassID U_EXPORT2 getStaticClassID(void);
+
+    /**
+     * Returns a unique class ID <b>polymorphically</b>.  This method
+     * is to implement a simple version of RTTI, since not all C++
+     * compilers support genuine RTTI.  Polymorphic operator==() and
+     * clone() methods call this method.
+     *
+     * <p>Concrete subclasses of UnicodeFunctor should use the macro
+     *    UOBJECT_DEFINE_RTTI_IMPLEMENTATION from uobject.h to
+     *    provide definitios getStaticClassID and getDynamicClassID.
+     *
+     * @return The class ID for this object. All objects of a given
+     * class have the same class ID.  Objects of other classes have
+     * different class IDs.
+     * @stable ICU 2.4
+     */
+    virtual UClassID getDynamicClassID(void) const = 0;
+
+    /**
+     * Set the data object associated with this functor.  The data
+     * object provides context for functor-to-standin mapping.  This
+     * method is required when assigning a functor to a different data
+     * object.  This function MAY GO AWAY later if the architecture is
+     * changed to pass data object pointers through the API.
+     * @internal ICU 2.1
+     */
+    virtual void setData(const TransliterationRuleData*) = 0;
+
+protected:
+
+    /**
+     * Since this class has pure virtual functions,
+     * a constructor can't be used.
+     * @stable ICU 2.0
+     */
+    /*UnicodeFunctor();*/
+
+};
+
+/*inline UnicodeFunctor::UnicodeFunctor() {}*/
+
+U_NAMESPACE_END
+
+#endif

Added: MacRuby/branches/icu/unicode/unimatch.h
===================================================================
--- MacRuby/branches/icu/unicode/unimatch.h	                        (rev 0)
+++ MacRuby/branches/icu/unicode/unimatch.h	2010-02-16 00:56:49 UTC (rev 3534)
@@ -0,0 +1,163 @@
+/*
+* Copyright (C) 2001-2005, International Business Machines Corporation and others. All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   07/18/01    aliu        Creation.
+**********************************************************************
+*/
+#ifndef UNIMATCH_H
+#define UNIMATCH_H
+
+#include "unicode/utypes.h"
+
+/**
+ * \file 
+ * \brief C++ API: Unicode Matcher
+ */
+
+
+U_NAMESPACE_BEGIN
+
+class Replaceable;
+class UnicodeString;
+class UnicodeSet;
+
+/**
+ * Constants returned by <code>UnicodeMatcher::matches()</code>
+ * indicating the degree of match.
+ * @stable ICU 2.4
+ */
+enum UMatchDegree {
+    /**
+     * Constant returned by <code>matches()</code> indicating a
+     * mismatch between the text and this matcher.  The text contains
+     * a character which does not match, or the text does not contain
+     * all desired characters for a non-incremental match.
+     * @stable ICU 2.4
+     */
+    U_MISMATCH,
+    
+    /**
+     * Constant returned by <code>matches()</code> indicating a
+     * partial match between the text and this matcher.  This value is
+     * only returned for incremental match operations.  All characters
+     * of the text match, but more characters are required for a
+     * complete match.  Alternatively, for variable-length matchers,
+     * all characters of the text match, and if more characters were
+     * supplied at limit, they might also match.
+     * @stable ICU 2.4
+     */
+    U_PARTIAL_MATCH,
+    
+    /**
+     * Constant returned by <code>matches()</code> indicating a
+     * complete match between the text and this matcher.  For an
+     * incremental variable-length match, this value is returned if
+     * the given text matches, and it is known that additional
+     * characters would not alter the extent of the match.
+     * @stable ICU 2.4
+     */
+    U_MATCH
+};
+
+/**
+ * <code>UnicodeMatcher</code> defines a protocol for objects that can
+ * match a range of characters in a Replaceable string.
+ * @stable ICU 2.4
+ */
+class U_COMMON_API UnicodeMatcher /* not : public UObject because this is an interface/mixin class */ {
+
+public:
+    /**
+     * Destructor.
+     * @stable ICU 2.4
+     */
+    virtual ~UnicodeMatcher();
+
+    /**
+     * Return a UMatchDegree value indicating the degree of match for
+     * the given text at the given offset.  Zero, one, or more
+     * characters may be matched.
+     *
+     * Matching in the forward direction is indicated by limit >
+     * offset.  Characters from offset forwards to limit-1 will be
+     * considered for matching.
+     * 
+     * Matching in the reverse direction is indicated by limit <
+     * offset.  Characters from offset backwards to limit+1 will be
+     * considered for matching.
+     *
+     * If limit == offset then the only match possible is a zero
+     * character match (which subclasses may implement if desired).
+     *
+     * As a side effect, advance the offset parameter to the limit of
+     * the matched substring.  In the forward direction, this will be
+     * the index of the last matched character plus one.  In the
+     * reverse direction, this will be the index of the last matched
+     * character minus one.
+     *
+     * <p>Note:  This method is not const because some classes may
+     * modify their state as the result of a match.
+     *
+     * @param text the text to be matched
+     * @param offset on input, the index into text at which to begin
+     * matching.  On output, the limit of the matched text.  The
+     * number of matched characters is the output value of offset
+     * minus the input value.  Offset should always point to the
+     * HIGH SURROGATE (leading code unit) of a pair of surrogates,
+     * both on entry and upon return.
+     * @param limit the limit index of text to be matched.  Greater
+     * than offset for a forward direction match, less than offset for
+     * a backward direction match.  The last character to be
+     * considered for matching will be text.charAt(limit-1) in the
+     * forward direction or text.charAt(limit+1) in the backward
+     * direction.
+     * @param in