示例#1
0
END_NATIVE_FUNCTION
AVES_API NATIVE_FUNCTION(aves_StringBuffer_get_length)
{
	StringBuffer *buf = THISV.Get<StringBuffer>();
	VM_PushInt(thread, (int64_t)buf->GetLength());
	RETURN_SUCCESS;
}
ECode MessageFormat::FormatToCharacterIterator(
    /* [in] */ IInterface* object,
    /* [out] */ IAttributedCharacterIterator** characterIterator)
{
    VALIDATE_NOT_NULL(characterIterator);
    *characterIterator = NULL;
    VALIDATE_NOT_NULL(object);

    StringBuffer buffer;
    List<AutoPtr<FieldContainer> > fields;

    // format the message, and find fields
    AutoPtr<IFieldPosition> position;
    CFieldPosition::New(0, (IFieldPosition**)&position);
    AutoPtr<ArrayOf<IInterface*> > arr = ArrayOf<IInterface*>::Alloc(1);
    arr->Set(0, object);
    FormatImpl(arr, &buffer, position, &fields);

    // create an AttributedString with the formatted buffer
    AutoPtr<IAttributedString> as;
    String outstr;
    buffer.Substring(0, buffer.GetLength(),&outstr);
    CAttributedString::New(outstr, (IAttributedString**)&as);

    // add MessageFormat field attributes and values to the AttributedString
    List<AutoPtr<FieldContainer> >::Iterator fc = fields.Begin();
    for ( ; fc != fields.End(); ++fc) {
        FAIL_RETURN(as->AddAttribute((*fc)->mAttribute, (*fc)->mValue, (*fc)->mStart, (*fc)->mEnd));
    }

    // return the CharacterIterator from AttributedString
    return as->GetIterator(characterIterator);
}
示例#3
0
END_NATIVE_FUNCTION
AVES_API BEGIN_NATIVE_FUNCTION(aves_StringBuffer_set_item)
{
	Aves *aves = Aves::Get(thread);

	StringBuffer *buf = THISV.Get<StringBuffer>();
	CHECKED(IntFromValue(thread, args + 1));
	if (args[2].type != aves->aves.Char)
	{
		VM_PushString(thread, strings::value); // paramName
		return VM_ThrowErrorOfType(thread, aves->aves.ArgumentTypeError, 1);
	}

	if (args[1].v.integer < 0 || args[1].v.integer >= buf->GetLength())
	{
		VM_PushString(thread, strings::index); // paramName
		return VM_ThrowErrorOfType(thread, aves->aves.ArgumentRangeError, 1);
	}
	if (args[2].v.uinteger > 0xFFFF)
	{
		VM_PushString(thread, strings::value);
		return VM_ThrowErrorOfType(thread, aves->aves.ArgumentRangeError, 1);
	}

	size_t index = (size_t)args[1].v.integer;
	buf->GetDataPointer()[index] = (ovchar_t)args[2].v.uinteger;
}
示例#4
0
void testChineseImpl(StringBuffer& sb)
{
    printf("\n");
    sb.DbgPrint();
    Int32 length = sb.GetLength();
    String str;
    for (Int32 i = -1; i <= length + 2; i++) {
        sb.Substring(i, &str);
        printf(" >> Char from index %d is %s\n", i, str.string());
    }
}
示例#5
0
NAMESPACE_UPP

static Topic ReadTopic(const char *text)
{
	Topic topic;
	CParser p(text);
	try {
		if(p.Id("topic")) {
			topic.title = p.ReadString();
			p.Char(';');
			topic.text = p.GetPtr();
			return topic;
		}
		while(!p.IsEof()) {
			if(p.Id("TITLE")) {
				p.PassChar('(');
				topic.title = p.ReadString();
				p.PassChar(')');
			} else if(p.Id("REF")) {
				p.PassChar('(');
				p.ReadString();
				p.PassChar(')');
			} else if(p.Id("TOPIC_TEXT")) {
				p.PassChar('(');
				topic.text << p.ReadString();
				p.PassChar(')');
			} else if(p.Id("COMPRESSED")) {
				StringBuffer b;
				b.Reserve(1024);
				while(p.IsInt()) {
					b.Cat(p.ReadInt());
					p.PassChar(',');
				}
				topic.text = ZDecompress(~b, b.GetLength());
			} else {
				topic.text << p.GetPtr();
				break;
			}
		}
	}
	catch(CParser::Error e) {
		topic.text = String::GetVoid();
		topic.title = e;
	}
	return topic;
}
示例#6
0
String::String(StringBuffer& b)
{
	int l = b.GetLength();
	if(l <= 14) {
		Zero();
		memcpy(chr, b.begin, l);
		SLen() = l;
		b.Free();
	}
	else {
		ptr = b.begin;
		ptr[l] = 0;
		SLen() = 15;
		LLen() = l;
		chr[KIND] = min(b.GetAlloc(), 255);
	}
	b.Zero();
}
示例#7
0
String::String(StringBuffer& b)
{
	int l = b.GetLength();
	if(l <= 14) {
		Zero();
		memcpy(chr, b.begin, l);
		SLen() = l;
		b.Free();
	}
	else {
		ptr = b.begin;
		ptr[l] = 0;
		SLen() = 15;
		LLen() = l;
		chr[KIND] = b.limit - b.begin == 31 ? MEDIUM : REF;
	}
	b.Zero();
}
ECode MessageFormat::FormatImpl(
    /* [in] */ ArrayOf< IInterface* >* objects,
    /* [in] */ IStringBuffer* inbuffer,
    /* [in] */ IFieldPosition* position,
    /* [in] */ List<AutoPtr<FieldContainer> >* fields)
{
    VALIDATE_NOT_NULL(inbuffer);

    StringBuffer * buffer = (StringBuffer *)inbuffer;
    AutoPtr<IFieldPosition> passedField;
    CFieldPosition::New(0, (IFieldPosition**)&passedField);

    Int32 begin;
    String result;
    for (Int32 i = 0; i <= mMaxOffset; i++) {
        *buffer += (*mStrings)[i];
        begin = buffer->GetLength();
        AutoPtr<IInterface> arg;
        if (objects != NULL && (*mArgumentNumbers)[i] < objects->GetLength()) {
            arg = (*objects)[(*mArgumentNumbers)[i]];
        }
        else {
            buffer->AppendChar('{');
            *buffer += (*mArgumentNumbers)[i];
            buffer->AppendChar('}');
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i],
                    position, fields);
            continue;
        }

        AutoPtr<IFormat> format = (*mFormats)[i];
        if (format == NULL || arg == NULL) {
            if (INumber::Probe(arg) != NULL) {
                AutoPtr<INumberFormat> nf;
                NumberFormat::GetInstance((INumberFormat**)&nf);
                format = IFormat::Probe(nf);
            }
            else if (IDate::Probe(arg) != NULL) {
                AutoPtr<IDateFormat> df;
                DateFormat::GetInstance((IDateFormat**)&df);
                format = IFormat::Probe(df);
            }
            else {
                buffer->Append(Object::ToString(arg));
                HandleArgumentField(begin, buffer->GetLength(),
                        (*mArgumentNumbers)[i], position, fields);
                continue;
            }
        }

        if (IChoiceFormat::Probe(format) != NULL) {
            format->Format(arg, &result);
            AutoPtr<IMessageFormat> mf;
            CMessageFormat::New(result, (IMessageFormat**)&mf);
            mf->SetLocale(mLocale);
            mf->Format(objects, buffer , passedField);
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i], position, fields);
            HandleFormat(format, arg, begin, fields);
        }
        else {
            format->Format(arg, buffer, passedField);
            HandleArgumentField(begin, buffer->GetLength(), (*mArgumentNumbers)[i], position, fields);
            HandleFormat(format, arg, begin, fields);
        }
    }
    if (mMaxOffset + 1 < mStrings->GetLength()) {
        (*buffer) += (*mStrings)[mMaxOffset + 1];
    }

    return NOERROR;
}
示例#9
0
String WriteIcon(const Vector<Image>& icons, int flags)
{
	Vector<byte> bpp;
	if(flags & WI_32BIT) bpp.Add(32);
	if(flags & WI_8BIT) bpp.Add(8);
	if(flags & WI_4BIT) bpp.Add(4);
	if(flags & WI_MONO) bpp.Add(1);
	ASSERT(!bpp.IsEmpty());
	int hdrsize =  sizeof(BMP_ICONDIR) + icons.GetCount() * bpp.GetCount() * sizeof(BMP_ICONDIRENTRY);
	StringBuffer out;
	out.SetCount(hdrsize);
	memset(~out, 0, hdrsize);
	Poke16le(~out + OFFSETOF(BMP_ICONDIR, idType), flags & WI_CURSOR ? 2 : 1);
	Poke16le(~out + OFFSETOF(BMP_ICONDIR, idCount), icons.GetCount() * bpp.GetCount());
	int icx = 0;
	for(int b = 0; b < bpp.GetCount(); b++) {
		int bits = bpp[b];
		RasterFormat format;
		switch(bits) {
			case 1: format.Set1mf(); break;
			case 4: format.Set4mf(); break;
			case 8: format.Set8(); break;
			default: format.Set32le(0xff0000, 0x00ff00, 0x0000ff, 0xff000000); break;
		}
		for(int i = 0; i < icons.GetCount(); i++) {
			int out_offset = out.GetLength();
			Image img = icons[i];
			Size sz = img.GetSize();
			int rowbytes = ((sz.cx * bits + 31) >> 3) & -4;
			int maskbytes = ((sz.cx + 31) >> 3) & -4;
			BMP_INFOHEADER bmih;
			Zero(bmih);
			bmih.biSize = sizeof(bmih);
			bmih.biWidth = sz.cx;
			bmih.biHeight = 2 * sz.cy;
			bmih.biBitCount = bpp[b];
			bmih.biPlanes = 1;
			bmih.biCompression = 0; //BI_RGB
			bmih.biSizeImage = sz.cy * (rowbytes + maskbytes);
			One<PaletteCv> cv;
			out.Cat((const char *)&bmih, sizeof(bmih));
			if(bits <= 8) {
				int ncolors = 1 << bits;
				Buffer<RGBA> palette(ncolors);
				ImageRaster ir(img);
				CreatePalette(ir, ~palette, ncolors);
				cv = new PaletteCv();
				CreatePaletteCv(palette, ncolors, *cv);
				for(int c = 0; c < ncolors; c++) {
					BMP_RGB quad;
					quad.rgbRed = palette[c].r;
					quad.rgbGreen = palette[c].g;
					quad.rgbBlue = palette[c].b;
					quad.rgbReserved = 0;
					out.Cat((const char *)&quad, sizeof(quad));
				}
			}
			int bmpoff = out.GetLength();
			out.Cat(0, bmih.biSizeImage);
			byte *data = (byte *)~out + bmpoff;
			for(int y = sz.cy; --y >= 0; data += rowbytes)
				format.Write(data, img[y], sz.cx, ~cv);
			for(int y = sz.cy; --y >= 0; data += maskbytes) {
				int cx = sz.cx;
				byte *out = data;
				const RGBA *in = img[y];
				while(cx >= 8) {
					byte b = 0;
					if(!in[0].a) b |= 0x80;
					if(!in[1].a) b |= 0x40;
					if(!in[2].a) b |= 0x20;
					if(!in[3].a) b |= 0x10;
					if(!in[4].a) b |= 0x08;
					if(!in[5].a) b |= 0x04;
					if(!in[6].a) b |= 0x02;
					if(!in[7].a) b |= 0x01;
					in += 8;
					cx -= 8;
					*out++ = b;
				}
				if(cx) {
					byte b = 0, mask = 0x80;
					do {
						if(in++->a) b |= mask;
						mask >>= 1;
					}
					while(--cx);
					*out = b;
				}
			}
			char *entry = ~out + sizeof(BMP_ICONDIR) + sizeof(BMP_ICONDIRENTRY) * icx++;
			entry[OFFSETOF(BMP_ICONDIRENTRY, bWidth)] = sz.cx;
			entry[OFFSETOF(BMP_ICONDIRENTRY, bHeight)] = sz.cy;
			//entry[OFFSETOF(BMP_ICONDIRENTRY, bColorCount)];
			//Poke16le(entry + OFFSETOF(BMP_ICONDIRENTRY, wPlanes)
			//Poke16le(entry + OFFSETOF(BMP_ICONDIRENTRY, wBitCount)
			Poke32le(entry + OFFSETOF(BMP_ICONDIRENTRY, dwBytesInRes), out.GetLength() - out_offset);
			Poke32le(entry + OFFSETOF(BMP_ICONDIRENTRY, dwImageOffset), out_offset);
		}
	}
	return out;
}
示例#10
0
void XmlParser::Next()
{
	nattr.Clear();
	nattr1 = nattrval1 = Null;
	if(empty_tag) {
		empty_tag = false;
		type = XML_END;
		return;
	}

	type = Null;
	StringBuffer raw_text;
	for(;;) {
		if(*term == '\0') {
			type = XML_EOF;
			return;
		}
		if(*term == '<') {
			if(term[1] == '!' && term[2] == '[' &&
			   term[3] == 'C' && term[4] == 'D' && term[5] == 'A' && term[6] == 'T' && term[7] == 'A' &&
			   term[8] == '[') { // ![CDATA[
				term += 9;
				for(;;) {
					if(*term == '\0')
						throw XmlError("Unterminated CDATA");
					if(term[0] == ']' && term[1] == ']' && term[2] == '>') { // ]]>
						term += 3;
						break;
					}
					if(*term == '\n')
						line++;
					raw_text.Cat(*term++);
				}
				type = XML_TEXT;
				continue;
			}
			else
				break;
		}
		if(*term == '\n')
			line++;
		if(*term == '&') {
			Ent(raw_text);
			type = XML_TEXT;
		}
		else {
			if((byte)*term > ' ')
				type = XML_TEXT;
			raw_text.Cat(*term++);
		}
	}
	cdata = FromUtf8(String(raw_text)).ToString();

	if(cdata.GetCount() && (npreserve || preserveall))
		type = XML_TEXT;
	
	if(type == XML_TEXT)
		return;
	
	term++;
	if(*term == '!') {
		type = XML_DECL;
		term++;
		if(term[0] == '-' && term[1] == '-') {
			type = XML_COMMENT;
			term += 2;
			for(;;) {
				if(term[0] == '-' && term[1] == '-' && term[2] == '>')
					break;
				if(*term == '\0')
					throw XmlError("Unterminated comment");
				if(*term == '\n')
					line++;
				tagtext.Cat(*term++);
			}
			term += 3;
			return;
		}
		bool intdt = false;
		for(;;) {
			if (*term == '[')
				intdt = true;
			if(*term == '>' && intdt == false) {
				term++;
				break;
			}
			if(intdt == true && term[0] == ']' && term[1] == '>') {
				tagtext.Cat(*term++);
				term++;
				break;
			}
			if(*term == '\0')
				throw XmlError("Unterminated declaration");
			if(*term == '\n')
				line++;
			tagtext.Cat(*term++);
		}
	}
	else
	if(*term == '?') {
		type = XML_PI;
		term++;
		for(;;) {
			if(term[0] == '?' && term[1] == '>') {
				term += 2;
				return;
			}
			if(*term == '\0')
				throw XmlError("Unterminated processing info");
			if(*term == '\n')
				line++;
			tagtext.Cat(*term++);
		}
	}
	else
	if(*term == '/') {
		type = XML_END;
		term++;
		const char *t = term;
		while(IsXmlNameChar(*term))
			term++;
		tagtext = String(t, term);
		if(*term != '>')
			throw XmlError("Unterminated end-tag");
		term++;
	}
	else {
		type = XML_TAG;
		const char *t = term;
		while(IsXmlNameChar(*term))
			term++;
		tagtext = String(t, term);
		for(;;) {
			SkipWhites();
			if(*term == '>') {
				term++;
				break;
			}
			if(term[0] == '/' && term[1] == '>') {
				cdata.Clear();
				empty_tag = true;
				term += 2;
				break;
			}
			if(*term == '\0')
				throw XmlError("Unterminated tag");
			const char *t = term++;
			while((byte)*term > ' ' && *term != '=' && *term != '>')
				term++;
			String attr(t, term);
			SkipWhites();
			if(*term == '=') {
				term++;
				SkipWhites();
				StringBuffer attrval;
				if(*term == '\"')
					ReadAttr(attrval, '\"');
				else
				if(*term == '\'')
					ReadAttr(attrval, '\'');
				else
					while((byte)*term > ' ' && *term != '>' && *term != '/')
						if(*term == '&')
							Ent(attrval);
						else {
							const char *e = term;
							while((byte)*++e > ' ' && *e != '>' && *e != '&')
								;
							attrval.Cat(term,(int) (e - term));
							term = e;
						}
				if(attr == "xml:space" && attrval.GetLength() == 8 && !memcmp(~attrval, "preserve", 8))
					npreserve = true;
				String aval = FromUtf8(~attrval, attrval.GetLength()).ToString();
				if(IsNull(nattr1)) {
					nattr1 = attr;
					nattrval1 = aval;
				}
				else
					nattr.Add(attr, aval);
			}
		}
	}
}
示例#11
0
void testMisc()
{
    printf("\n==== Leave testAutoPtr ====\n");
    {
        StringBuffer sb(20);
        String str;
        for (Int32 i = 0; i < 20; i++) {
            sb.AppendChar('A' + i);
        }

        str = sb.ToString();
        printf(" >> Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.TrimToSize();
        printf(" >> Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());
    }

    {
        StringBuffer sb;
        String str;
        for (Int32 i = 0; i < 20; i++) {
            sb.AppendChar('A' + i);
        }

        sb.InsertString(0, String("0123456789"));
        str = sb.ToString();
        printf("\n >> InsertString Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());
    }

    {
        StringBuffer sb;
        String str;
        sb.AppendNULL();
        str = sb.ToString();
        printf("\n >> AppendNULL Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());
    }

    {
        StringBuffer sb(5);
        String str;
        for (Int32 i = 0; i < 5; ++i) {
            sb.AppendChar('1' + i);
        }
        str = sb.ToString();
        printf("\n >> BeforeReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 5, String("ABCDE"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 4, String("444"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 3, String("UVWXYZ"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 7, String("1234567"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 0, String("ABC"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(0, 10, String("0123456789"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(10, 10, String("ABC"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());

        sb.Replace(14, 18, String("XYZ"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());
        sb.Replace(12, 13, String("0"));
        str = sb.ToString();
        printf(" >> AfterReplace Capacity %d, length %d, str: %s\n", sb.mCapacity, sb.GetLength(), str.string());
    }

    printf("==== Leave testAutoPtr ====\n");
}
示例#12
0
void testStringBuffer()
{
    printf("==== Enter testStringBuffer ====\n");

    printf("\n === Construct === \n");

    StringBuffer sbc(String("Construct from String"));
    String str = sbc.ToString();
    printf(" > Construct:\n%s\n", (const char*)str);

    printf("\n === Append === \n");

    Char32 a = 'A';
    StringBuffer sb;
    ECode ec = sb.ToString(&str);
    printf(">> Get string from emtpy StringBuffer %s, %08x - %08x\n", str.string(), NOERROR, ec);

    sb.AppendCStr(">>Start\n");
    sb.AppendNULL();
    sb.AppendChar('_');
    sb.AppendChar(a);
    sb.AppendChar('_');
    sb.AppendBoolean(TRUE);
    sb.AppendChar('_');
    sb.AppendBoolean(FALSE);
    sb.AppendChar('_');
    sb.AppendInt32(32);
    sb.AppendChar('_');
    sb.AppendInt32(-32);
    sb.AppendChar('_');
    sb.AppendInt64(64);
    sb.AppendChar('_');
    sb.AppendInt64(-64);
    sb.AppendChar('_');
    sb.AppendFloat(10.0f);
    sb.AppendChar('_');
    sb.AppendDouble(101010.1010);
    sb.AppendChar('_');
    sb.AppendString(String("String"));
    sb.AppendCStr("\n<<End");

    str = sb.ToString();
    printf(" > AppendTest:\n%s\n", (const char*)str);


    printf("\n === Index ===\n");
    Int32 index = 0;
    String subStr("32");
    sb.IndexOf(subStr, &index);
    printf(" > IndexOf %s is %d\n", (const char*)subStr, index);

    subStr = String("_NOT_");
    sb.IndexOf(subStr, &index);
    printf(" > IndexOf %s is %d\n", (const char*)subStr, index);

    subStr = String("32");
    sb.LastIndexOf(subStr, &index);
    printf(" > LastIndexOf %s is %d\n", (const char*)subStr, index);

    subStr = String("_NOT_");
    sb.LastIndexOf(subStr, &index);
    printf(" > LastIndexOf %s is %d\n", (const char*)subStr, index);


    printf("\n === Substring ===\n");
    Int32 start = 30, end = 32;
    sb.Substring(start, &subStr);
    printf(" > Substring from %d is : %s\n", start, (const char*)subStr);
    sb.SubstringEx(start, end, &subStr);
    printf(" > Substring from %d to %d is : %s\n", start, end, (const char*)subStr);

    printf("\n === Get ===\n");
    Char32 ch = 0;
    sb.GetChar(start, &ch);
    printf(" > GetChar at %d is : %c\n", start, ch);
    sb.GetLength(&end);
    printf(" > GetLength is : %d\n", end);
    sb.GetByteCount(&end);
    printf(" > GetByteCount is : %d\n", end);
    sb.GetCapacity(&end);
    printf(" > GetCapacity is : %d\n", end);

    printf("\n === Set/Replace/Insert ===\n");
    sb.SetChar(13, 'B');
    sb.ToString(&str);
    printf(" > SetCharAt:\n%s\n", (const char*)str);
    sb.Replace(15, 15 + 4, String("Replace"));
    sb.ToString(&str);
    printf(" > Replace:\n%s\n", (const char*)str);
    sb.InsertString(15, String("Insert_"));
    sb.ToString(&str);
    printf(" > InsertString:\n%s\n", (const char*)str);
    sb.InsertString(0, String("HeadInsert_"));
    sb.ToString(&str);
    printf(" > InsertString in head:\n%s\n", (const char*)str);
    sb.InsertChar(19, '_');
    sb.ToString(&str);
    printf(" > InsertChar:\n%s\n", (const char*)str);
    sb.InsertBoolean(19, TRUE);
    sb.ToString(&str);
    printf(" > InsertBoolean:\n%s\n", (const char*)str);
    sb.InsertInt32(19, 32);
    sb.ToString(&str);
    printf(" > InsertInt32:\n%s\n", (const char*)str);
    sb.InsertInt64(19, 64);
    sb.ToString(&str);
    printf(" > InsertInt64:\n%s\n", (const char*)str);
    sb.InsertFloat(19, 128.0);
    sb.ToString(&str);
    printf(" > InsertFloat:\n%s\n", (const char*)str);
    sb.InsertDouble(19, 10000.00001);
    sb.ToString(&str);
    printf(" > InsertDouble:\n%s\n", (const char*)str);

    ArrayOf<Char32>* chars = ArrayOf<Char32>::Alloc(10);
    for (Int32 i = 0; i < chars->GetLength(); ++i) {
        (*chars)[i] = 'A' + i;
    }
    sb.InsertChars(19, *chars);
    sb.ToString(&str);
    printf(" > InsertChars:\n%s\n", (const char*)str);
    sb.InsertCharsEx(19, *chars, 5, 5);
    sb.ToString(&str);
    printf(" > InsertCharsEx:\n%s\n", (const char*)str);

    printf("\n === Delete ===\n");
    sb.Delete(19, 24);
    sb.ToString(&str);
    printf(" > Delete:\n%s\n", (const char*)str);
    sb.DeleteChar(1);
    sb.ToString(&str);
    printf(" > DeleteChar:\n%s\n", (const char*)str);

    printf("\n === Reverse ===\n");
    sb.Reverse();
    sb.ToString(&str);
    printf(" > Reverse:\n%s\n", (const char*)str);

    printf("==== Leave testStringBuffer ====\n");
}