Esempio n. 1
0
/* check char range (kanji 1st) */
boolean iskanji1(int c)
{
    if (is_internalUPTEX()) return (isUTF8(2,1,c) ||
                                    isUTF8(3,1,c) ||
                                    isUTF8(4,1,c));
    if (is_internalSJIS()) return isSJISkanji1(c);
    /* EUC */              return isEUCkanji1(c);
}
Esempio n. 2
0
/* getc() with check of broken encoding of UTF-8 */
static int getcUTF8(FILE *fp)
{
    int c = getc4(fp);

    if (isUTF8(2,2,c)) return c;
    ungetc4(c, fp);
    return EOF;
}
Esempio n. 3
0
void CFfmpegDec::GetMeta(AVDictionary * metadata)
{
	AVDictionaryEntry *tag = NULL;
	while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
		if(!strcasecmp(tag->key,"Title")) {
			if (title.empty()) {
				title = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value);
				title = trim(title);
			}
			continue;
		}
		if(!strcasecmp(tag->key,"Artist")) {
			if (artist.empty()) {
				artist = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value);
				artist = trim(artist);
			}
			continue;
		}
		if(!strcasecmp(tag->key,"Year")) {
			if (date.empty()) {
				date = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value);
				date = trim(date);
			}
			continue;
		}
		if(!strcasecmp(tag->key,"Album")) {
			if (album.empty()) {
				album = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value);
				album = trim(album);
			}
			continue;
		}
		if(!strcasecmp(tag->key,"Genre")) {
			if (genre.empty()) {
				genre = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value);
				genre = trim(genre);
			}
			continue;
		}
	}
}
Esempio n. 4
0
/* with strict range check */
int UTF8Slength(unsigned char *buff, int buff_len)
{
    int i, len;

    len = UTF8length(buff[0]);
    if (len < 0) return -2; /* illegal */
    if (len > buff_len) return -3; /* overflow */
    for (i=0; i<len; i++) {
        if (!isUTF8(len, 1+i, buff[i])) return -1; /* not UTF-8 */
    }
    return len;
}
Esempio n. 5
0
void CAudioPlayer::sc_callback(void *arg)
{
  bool changed=false;
  CSTATE *stat = (CSTATE*)arg;

  const std::string artist	= isUTF8(stat->artist)	? stat->artist	: convertLatin1UTF8(stat->artist);
  const std::string title	= isUTF8(stat->title)	? stat->title	: convertLatin1UTF8(stat->title);
  const std::string station	= isUTF8(stat->station)	? stat->station	: convertLatin1UTF8(stat->station);
  const std::string genre	= isUTF8(stat->genre)	? stat->artist	: convertLatin1UTF8(stat->genre);

  if(m_Audiofile.MetaData.artist != artist)
  {
	  m_Audiofile.MetaData.artist = artist;
	  changed=true;
  }
  if (m_Audiofile.MetaData.title != title)
  {
	  m_Audiofile.MetaData.title = title;
	  changed=true;
  }
  if (m_Audiofile.MetaData.sc_station != station)
  {
	  m_Audiofile.MetaData.sc_station = station;
	  changed=true;
  }
  if (m_Audiofile.MetaData.genre != genre)
  {
	  m_Audiofile.MetaData.genre = genre;
	  changed=true;
  }
  if(changed)
  {
	  m_played_time = 0;
  }
  m_sc_buffered = stat->buffered;
  m_Audiofile.MetaData.changed = changed;
  //printf("Callback %s %s %s %d\n",stat->artist, stat->title, stat->station, stat->buffered);
}
Esempio n. 6
0
/* check char range */
boolean ismultichr (int length, int nth, int c)
{
    if (is_internalUPTEX()) return isUTF8(length, nth, c);
    if (length == 2) {
        if (nth == 1) {
            if (is_internalSJIS()) return isSJISkanji1(c);
            /* EUC */              return isEUCkanji1(c);
        } else if (nth == 2) {
            if (is_internalSJIS()) return isSJISkanji2(c);
            /* EUC */              return isEUCkanji2(c);
        }
    }
    if ((length == 3 || length == 4) &&
        (0 < nth && nth <= length)) return false;
    fprintf(stderr, "ismultichr: unexpected param length=%d, nth=%d\n",
            length, nth);
    return false;
}
Esempio n. 7
0
std::string StringUtil::StrToUTF8(const char* src) {
	if (isUTF8(src)) return std::string(src);

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
	int len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, src, -1, wstr, len);

	std::string utf = WStrToUTF8(wstr);
	if (wstr) delete[] wstr;
	return utf;
#else
	/*std::string chars(src);
	std::wstring wide_chars(chars.begin(), chars.end());

	return WStrToUTF8(wide_chars.c_str());*/
	return src;
#endif
}
Esempio n. 8
0
void guess_encoding(const char *data, size_t size)
{
#define FOUND(name) \
    do { \
        if (found) fputs(", ", stdout); \
        fputs(name, stdout); \
        found = 1; \
    } while (0)

    int found = 0;

    dump_byte_string(stdout, "guess_encoding(\"", data, size, "\"): ");

    if (size >= 3) {
        if (memcmp(data, UTF_8_BOM, 3) == 0)
            FOUND("UTF-8 (BOM)");
    }
    if (size >= 4) {
        if (memcmp(data, UTF_32_LE_BOM, 4) == 0)
            FOUND("UTF-32-LE (BOM)");
        if (memcmp(data, UTF_32_BE_BOM, 4) == 0)
            FOUND("UTF-32-BE (BOM)");
    }
    if (size >= 2) {
        if (memcmp(data, UTF_16_LE_BOM, 2) == 0)
            FOUND("UTF-16-LE (BOM)");
        if (memcmp(data, UTF_16_BE_BOM, 2) == 0)
            FOUND("UTF-16-BE (BOM)");
    }

    if (isASCII(data, size)) { FOUND("ASCII"); }

    if (isUTF8(data, size)) { FOUND("UTF-8"); }

    if (!found)
        printf("<unknown>");
    fputs("\n", stdout);

}
Esempio n. 9
0
int test(char** argv)
{
    verbose = getenv("PEGASUS_TEST_VERBOSE") ? true : false;

    String s1 = "Hello World";
    String s2 = s1;
    String s3(s2);

    PEGASUS_TEST_ASSERT(String::equal(s1, s3));

    // Test append characters to String
    String s4 = "Hello";
    s4.append(Char16(0x0000));
    s4.append(Char16(0x1234));
    s4.append(Char16(0x5678));
    s4.append(Char16(0x9cde));
    s4.append(Char16(0xffff));

    {
#ifdef HAVE_SSTREAM
        stringstream os;
#endif
#ifdef HAVE_STRSTREAM
        ostrstream os;
#endif
        os << s4;
#ifdef HAVE_STRSTREAM
        os.put('\0');
#endif
#ifndef PEGASUS_HAS_ICU
        const char EXPECTED[] = "Hello\\x0000\\x1234\\x5678\\x9CDE\\xFFFF";
#else
        CString cstr = s4.getCString();
        const char * EXPECTED = (const char *)cstr;
#endif

#ifdef HAVE_SSTREAM
    string os_str = os.str();
    const char* tmp = os_str.c_str();
#endif
#ifdef HAVE_STRSTREAM
        char *tmp = os.str();
#endif

        PEGASUS_TEST_ASSERT(strcmp(EXPECTED, tmp) == 0);
#ifdef PEGASUS_PLATFORM_AIX_RS_IBMCXX
        os.freeze(false);
#else

#ifdef HAVE_STRSTREAM
        delete tmp;
#endif

#endif
    }

    {
        // Test getCString
        const char STR0[] = "one two three four";
        String s = STR0;
        PEGASUS_TEST_ASSERT(strcmp(s.getCString(), STR0) == 0);
    }

    {
        // Test remove
        String s = "abcdefg";
        s.remove(3, 3);
        PEGASUS_TEST_ASSERT(String::equal(s, "abcg"));
        PEGASUS_TEST_ASSERT(s.size() == 4);

        s = "abcdefg";
        s.remove(3, 4);
        PEGASUS_TEST_ASSERT(String::equal(s, "abc"));
        PEGASUS_TEST_ASSERT(s.size() == 3);

        s = "abcdefg";
        s.remove(3);
        PEGASUS_TEST_ASSERT(String::equal(s, "abc"));
        PEGASUS_TEST_ASSERT(s.size() == 3);

        s = "abc";
        s.remove(3);
        PEGASUS_TEST_ASSERT(String::equal(s, "abc"));
        PEGASUS_TEST_ASSERT(s.size() == 3);

        s = "abc";
        s.remove(0);
        PEGASUS_TEST_ASSERT(String::equal(s, ""));
        PEGASUS_TEST_ASSERT(s.size() == 0);

        s = "abc";
        s.remove(0, 1);
        PEGASUS_TEST_ASSERT(String::equal(s, "bc"));
        PEGASUS_TEST_ASSERT(s.size() == 2);

        String t1 = "HELLO";
        String t2 = t1;
        t2.toLower();
        PEGASUS_TEST_ASSERT(String::equal(t1, "HELLO"));
        PEGASUS_TEST_ASSERT(String::equal(t2, "hello"));
    }

    {
        // another test of the append method
        String t1 = "one";
        t1.append(" two");
        PEGASUS_TEST_ASSERT(String::equal(t1, "one two"));
        t1.append(' ');
        t1.append('t');
        t1.append('h');
        t1.append('r');
        t1.append("ee");
        PEGASUS_TEST_ASSERT(String::equal(t1,"one two three"));

        // used as example in Doc.
        String test = "abc";
        test.append("def");
        PEGASUS_TEST_ASSERT(test == "abcdef");
    }

    // Test of the different overload operators
    {
        // Test the == overload operator
        String t1 = "one";
        String t2 = "one";
        PEGASUS_TEST_ASSERT(t1 == "one");
        PEGASUS_TEST_ASSERT("one" == t1);
        PEGASUS_TEST_ASSERT(t1 == t2);
        PEGASUS_TEST_ASSERT(t2 == t1);
        PEGASUS_TEST_ASSERT(String("one") == "one");

        const char STR0[] = "one two three four";
        String s = STR0;
        CString tmp = s.getCString();
        PEGASUS_TEST_ASSERT(tmp == s);
        PEGASUS_TEST_ASSERT(s == tmp);
    }

    {
        // Tests of the + Overload operator
        String t1 = "abc";
        String t2 = t1 + t1;
        PEGASUS_TEST_ASSERT(t2 == "abcabc");
        t1 = "abc";
        t2 = t1 + "def";
        PEGASUS_TEST_ASSERT(t2 == "abcdef");

        t1 = "ghi";
        PEGASUS_TEST_ASSERT(t1 == "ghi");

        // ATTN: the following fails because there
        // is no single character overload operator
        // KS: Apr 2001
        // t2 = t1 + 'k' + 'l' + 'm' + "nop";
        t2 = t1 + "k" + "l" + "m" + "nop";
        PEGASUS_TEST_ASSERT(t2 == "ghiklmnop");
        PEGASUS_TEST_ASSERT(String::equal(t2,"ghiklmnop"));

        // add tests for != operator.

        t1 = "abc";
        PEGASUS_TEST_ASSERT(t1 != "ghi");
        PEGASUS_TEST_ASSERT(t1 != t2);

        // add tests for other compare operators

        // Operater <
        t1 = "ab";
        t2 = "cde";
        PEGASUS_TEST_ASSERT(t1 < t2);
        PEGASUS_TEST_ASSERT(t1 <= t2);
        PEGASUS_TEST_ASSERT(t2 > t1);
        PEGASUS_TEST_ASSERT(t2 >=t1);
        PEGASUS_TEST_ASSERT(String::compare(t1,t2) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t2,t1) > 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 1) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t2, t1, 1) > 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 10) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t2, t1, 10) > 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 0) == 0);
        t2 = t1;
        PEGASUS_TEST_ASSERT(t1 <= t2);
        PEGASUS_TEST_ASSERT(t1 >= t2);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2) == 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 0) == 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 1) == 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 10) == 0);


        // Tests for compare with same length
        t1 = "abc";
        t2 = "def";
        PEGASUS_TEST_ASSERT(t1 < t2);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t2, t1) > 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 10) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 0) == 0);

        t1 = "abc";
        t2 = "ABC";
        PEGASUS_TEST_ASSERT(String::equalNoCase(t1,t2));
        PEGASUS_TEST_ASSERT(!String::equal(t1,t2));
        PEGASUS_TEST_ASSERT(String::compareNoCase(t1,t2) == 0);
        t1.toUpper();
        t2.toLower();
        PEGASUS_TEST_ASSERT(String::equal(t1, "ABC"));
        PEGASUS_TEST_ASSERT(String::equal(t2, "abc"));

        t1 = "1000";
        t2 = "1001";
        PEGASUS_TEST_ASSERT(String::compareNoCase(t1,t2) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2) < 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 3) == 0);
        PEGASUS_TEST_ASSERT(String::compare(t1, t2, 4) < 0);

#ifdef PEGASUS_HAS_ICU
        //
        // Strings used to test non-ascii case mappings
        // Tests context sensitve mappings (eg. greek)
        // Tests expansion after mapping (eg german)
        //

        // Lower case german and greek
        // --latin small letter sharp s (german) (2 of these to cause
        //  ICU overflow error inside of String)
        // --greek small letter sigma (followed by another letter)
        // --latin small a
        // --greek small letter sigma (NOT followed by another letter)
        const Char16 lowermap[] = {
                                   0xdf,
                                   0xdf,
                                   0x3c3,
                                   'a',
                                   0x3c2,
                                   0x00};
        String degkLow(lowermap);

        // Needed because the german char does not round trip
        // after an uppercase followed by lower case.
        // --latin small letters 's' 's' (4 of these due to expansion)
        // --greek small letter sigma (followed by another letter)
        // --latin small a
        // --greek small letter sigma (NOT followed by another letter)
        const Char16 lowermap2[] = {
                                   's', 's', 's', 's',
                                   0x3c3,
                                   'a',
                                   0x3c2,
                                   0x00};
        String degkLow2(lowermap2);

        // Upper case greek and german
        // latin cap letter sharp s (german) (4 of these due to expansion)
        // greek cap letter sigma (followed by another letter)
        // latin cap A
        // greek cap letter sigma (NOT followed by another letter)
        const Char16 uppermap[] = {
                                  'S', 'S', 'S', 'S',
                                   0x3a3,
                                   'A',
                                   0x3a3,
                                   0x00};
        String degkUp(uppermap);


        PEGASUS_TEST_ASSERT(String::compareNoCase(degkLow,degkUp) == 0);
        // does a binary compare, so lower > upper
        PEGASUS_TEST_ASSERT(String::compare(degkLow,degkUp) > 0);
        PEGASUS_TEST_ASSERT(String::equalNoCase(degkLow,degkUp));

        String mapTest(degkLow);
        mapTest.toUpper();
        PEGASUS_TEST_ASSERT(String::equal(mapTest, degkUp));

        // Note that the German char does not round trip
        mapTest.toLower();
        PEGASUS_TEST_ASSERT(String::equal(mapTest, degkLow2));
#endif
    }

    {
        // Test of the [] operator
        String t1 = "abc";
        Char16 c = t1[1];
        // note c is Char16
        PEGASUS_TEST_ASSERT(c == 'b');

        //ATTN: test for outofbounds exception
        try
        {
            c = t1[200];
        }
        catch (IndexOutOfBoundsException&)
        {
        PEGASUS_TEST_ASSERT(true);
        }
    }

    {
        // Test the find function
        String t1 = "abcdef";
        String t2 = "cde";
        String t3 = "xyz";
        String t4 = "abc";
        String t5 = "abd";
        String t6 = "defg";
        PEGASUS_TEST_ASSERT(t1.find('c') == 2);
        PEGASUS_TEST_ASSERT(t1.find(t2)==2);
        PEGASUS_TEST_ASSERT(t1.find(t3)==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(t1.find(t4)==0);
        PEGASUS_TEST_ASSERT(t1.find(t5)==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(t1.find(t6)==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(t1.find("cde")==2);
        PEGASUS_TEST_ASSERT(t1.find("def")==3);
        PEGASUS_TEST_ASSERT(t1.find("xyz")==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(t1.find("a") ==0);

        // test for the case where string
        // partly occurs and then later
        // completely occurs
        String s = "this is an apple";
        PEGASUS_TEST_ASSERT(s.find("apple")==11);
        PEGASUS_TEST_ASSERT(s.find("appld")==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(s.find("this")==0);
        PEGASUS_TEST_ASSERT(s.find("t")==0);
        PEGASUS_TEST_ASSERT(s.find("e")==15);
        s = "a";
        PEGASUS_TEST_ASSERT(s.find("b")==PEG_NOT_FOUND);
        PEGASUS_TEST_ASSERT(s.find("a")==0);
        PEGASUS_TEST_ASSERT(s.find(s)==0);
        s = "aaaapple";
        PEGASUS_TEST_ASSERT(s.find("apple")==3);

        // 20020715-RK This method was removed from the String class
        //{
        //    String nameSpace = "a#b#c";
        //    nameSpace.translate('#', '/');
        //    PEGASUS_TEST_ASSERT(nameSpace == "a/b/c");
        //}
    }

    {
        //
        // Test String unicode enablement
        //

        char utf8chr[]    = {
                              '\xCE', '\x99', '\xCE', '\xBF', '\xCF', '\x8D',
                              '\xCE', '\xBD', '\xCE', '\xB9', '\xCE', '\xBA',
                              '\xCE', '\xBF', '\xCE', '\xBD', '\xCF', '\x84',
                              '\0'
                            }; // utf8 string with mutliple byte characters

        Char16 utf16chr[] = {
                              0x0399,0x03BF,0x03CD,0x03BD,0x03B9,
                              0x03BA,0x03BF,0x03BD,0x03C4,0x00
                            };  // utf16 representation of the utf8 string

        String utf16string(utf16chr);
        String utf8string(utf8chr);
        String utf16merge(utf8string.getChar16Data());

        CString temp = utf8string.getCString();
        CString temp2 = utf16string.getCString();

        PEGASUS_TEST_ASSERT(utf16string == utf8string);
        PEGASUS_TEST_ASSERT(utf16string == utf16merge);
        PEGASUS_TEST_ASSERT(utf16string == utf16chr);
        PEGASUS_TEST_ASSERT(utf8string  == utf16chr);

        PEGASUS_TEST_ASSERT(memcmp(utf8string.getChar16Data(),
                            utf16string.getChar16Data(),sizeof(utf16chr)) == 0);
        PEGASUS_TEST_ASSERT(strcmp(utf8string.getCString(),utf8chr) == 0);
        PEGASUS_TEST_ASSERT(strcmp(utf16string.getCString(),utf8chr) == 0);
        PEGASUS_TEST_ASSERT(strcmp(temp,utf8chr) == 0);
        PEGASUS_TEST_ASSERT(strcmp(temp2,utf8chr) == 0);

        Uint32 count = 0;
        Uint32 size = sizeof(utf8chr);
        while(count<size)
        {
                PEGASUS_TEST_ASSERT(isUTF8(&utf8chr[count]) == true);
                UTF8_NEXT(utf8chr,count);
        }

        // utf8 string with mutliple byte characters
        char utf8bad[] =
        {
            '\xFF','\xFF', '\xFF', '\0', '\0', '\0'
        };

        count = 0;
        size = 3;
        while(count<size)
        {
            PEGASUS_TEST_ASSERT(isUTF8(&utf8bad[count]) == false);
            UTF8_NEXT(utf8bad,count);
        }

        Char16 utf16Chars[] =
        {
        0x6A19, 0x6E96, 0x842C, 0x570B, 0x78BC,
        0x042E, 0x043D, 0x0438, 0x043A, 0x043E, 0x0434,
        0x110B, 0x1172, 0x1102, 0x1165, 0x110F, 0x1169, 0x11AE,
        0x10E3, 0x10DC, 0x10D8, 0x10D9, 0x10DD, 0x10D3, 0x10D8,
        0xdbc0, 0xdc01,
        0x05D9, 0x05D5, 0x05E0, 0x05D9, 0x05E7, 0x05D0, 0x05B8, 0x05D3,
        0x064A, 0x0648, 0x0646, 0x0650, 0x0643, 0x0648, 0x062F,
        0x092F, 0x0942, 0x0928, 0x093F, 0x0915, 0x094B, 0x0921,
        0x016A, 0x006E, 0x012D, 0x0063, 0x014D, 0x0064, 0x0065, 0x033D,
        0x00E0, 0x248B, 0x0061, 0x2173, 0x0062, 0x1EA6, 0xFF21, 0x00AA,
            0x0325, 0x2173, 0x249C, 0x0063,
        0x02C8, 0x006A, 0x0075, 0x006E, 0x026A, 0x02CC, 0x006B, 0x006F,
            0x02D0, 0x0064,
        0x30E6, 0x30CB, 0x30B3, 0x30FC, 0x30C9,
        0xFF95, 0xFF86, 0xFF7A, 0xFF70, 0xFF84, 0xFF9E,
        0xC720, 0xB2C8, 0xCF5B, 0x7D71, 0x4E00, 0x78BC,
        0xdbc0, 0xdc01,
        0x00};

        String ugly(utf16Chars);
        PEGASUS_TEST_ASSERT(ugly == utf16Chars);

        //
        // Test passing bad utf-8 into String
        //

        // A utf-8 sequence with a byte zeroed out in a bad spot
        char utf8bad1[]    = {
                              '\xCE', '\x99', '\xCE', '\xBF', '\xCF', '\x8D',
                              '\xCE', '\xBD', '\xCE', '\0', '\xCE', '\xBA',
                              '\xCE', '\xBF', '\xCE', '\xBD', '\xCF', '\x84',
                              '\0'
                            }; // utf8 string with mutliple byte characters

        // Test String(char *)
        try
        {
          // the first terminator causes invalid utf-8
          String tmp(utf8bad1);
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        // Test String(char *, Uint32)
        try
        {
          // bogus utf-8 char in the middle
          String tmp(utf8bad1, sizeof(utf8bad1)-1);
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        // Test String(char *, Uint32)
        try
        {
          // good, but the last utf-8 char extends past the last byte
          String tmp(utf8chr, sizeof(utf8chr) - 2);
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        // Test String::assign(char *)
        String assigntest(utf8chr);  // good so far
        try
        {
          // the first terminator causes invalid utf-8
          assigntest.assign(utf8bad1);  // bad
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        // Test String::assign(char *, Uint32)
        try
        {
          // bogus utf-8 char in the middle
          assigntest.assign(utf8bad1, sizeof(utf8bad1) - 1);  // bad
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        // Test String::assign(char *, Uint32)
        try
        {
          // good, but the last utf-8 char extends past the end
          assigntest.assign(utf8chr, sizeof(utf8chr) - 2);  // bad
          PEGASUS_TEST_ASSERT(false);
        }
        catch (Exception &)
        {
          // expect an error
        }

        //
        // Test passing in good utf-8 with an embedded terminator
        //

        // A utf-8 sequence with a byte zeroed out in an ok spot
        char utf8good1[]    = {
                              '\xCE', '\x99', '\xCE', '\xBF', '\xCF', '\x8D',
                              '\xCE', '\xBD', 'A', '\0', '\xCE', '\xBA',
                              '\xCE', '\xBF', '\xCE', '\xBD', '\xCF', '\x84',
                              '\0'
                            }; // utf8 string with mutliple byte characters

        // Test String(char *)
        try
        {
          // terminator after 5 chars
          String tmp(utf8good1);
          PEGASUS_TEST_ASSERT (tmp.size() == 5);
        }
        catch (Exception &)
        {
          // didn't see that one coming
          PEGASUS_TEST_ASSERT(false);
        }

        // Test String(char *, Uint32)
        try
        {
          // embedded terminator counts as 1 char
          String tmp(utf8good1, sizeof(utf8good1) - 1);
          PEGASUS_TEST_ASSERT (tmp.size() == 10);
        }
        catch (Exception &)
        {
          // didn't see that one coming
          PEGASUS_TEST_ASSERT(false);
        }

        assigntest.clear();

        // Test String::assign(char *)
        try
        {
          // terminator after 5 chars
          assigntest.assign(utf8good1);
          PEGASUS_TEST_ASSERT (assigntest.size() == 5);
        }
        catch (Exception &)
        {
          // didn't see that one coming
          PEGASUS_TEST_ASSERT(false);
        }

        assigntest.clear();

        // Test String::assign(char *, Uint32)
        try
        {
          // embedded terminator counts as 1 char
          assigntest.assign(utf8good1, sizeof(utf8good1) - 1);
          PEGASUS_TEST_ASSERT (assigntest.size() == 10);
        }
        catch (Exception &)
        {
          // didn't see that one coming
          PEGASUS_TEST_ASSERT(false);
        }


        //
        // Casing tests
        //

        String little("the quick brown fox jumped over the lazy dog");
        String    big("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG");

        String tmpBig = big;
        String tmpLittle = little;

        tmpBig.toLower();
        PEGASUS_TEST_ASSERT(tmpBig == little);

        tmpBig.toUpper();
        PEGASUS_TEST_ASSERT(tmpBig == big);
    }

#if 0
    // The match code has been removed from the String class
    // Test the string match functions
    {
        String abc = "abc";
        String ABC = "ABC";
        PEGASUS_TEST_ASSERT(String::match(abc, "abc"));
        PEGASUS_TEST_ASSERT(String::match(ABC, "ABC"));
        PEGASUS_TEST_ASSERT(!String::match(abc, "ABC"));
        PEGASUS_TEST_ASSERT(!String::match(ABC, "abc"));

        PEGASUS_TEST_ASSERT(String::matchNoCase(abc, "abc"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(ABC, "abc"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(abc, "ABC"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(ABC, "ABc"));

        PEGASUS_TEST_ASSERT(String::match(abc, "???"));
        PEGASUS_TEST_ASSERT(String::match(ABC, "???"));
        PEGASUS_TEST_ASSERT(String::match(abc, "*"));
        PEGASUS_TEST_ASSERT(String::match(ABC, "*"));

        PEGASUS_TEST_ASSERT(String::match(abc, "?bc"));
        PEGASUS_TEST_ASSERT(String::match(abc, "?b?"));
        PEGASUS_TEST_ASSERT(String::match(abc, "??c"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(ABC, "?bc"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(ABC, "?b?"));
        PEGASUS_TEST_ASSERT(String::matchNoCase(ABC, "??c"));


        PEGASUS_TEST_ASSERT(String::match(abc, "*bc"));
        PEGASUS_TEST_ASSERT(String::match(abc, "a*c"));
        PEGASUS_TEST_ASSERT(String::match(abc, "ab*"));
        PEGASUS_TEST_ASSERT(String::match(abc, "a*"));
        // ATTN-RK-P3-20020603: This match code is broken
        //PEGASUS_TEST_ASSERT(String::match(abc, "[axy]bc"));
        PEGASUS_TEST_ASSERT(!String::match(abc, "[xyz]bc"));

        PEGASUS_TEST_ASSERT(!String::match(abc, "def"));
        PEGASUS_TEST_ASSERT(!String::match(abc, "[de]bc"));
        // ATTN-RK-P3-20020603: This match code is broken
        //PEGASUS_TEST_ASSERT(String::match(abc, "a[a-c]c"));
        PEGASUS_TEST_ASSERT(!String::match(abc, "a[d-x]c"));
        // ATTN-RK-P3-20020603: This match code does not yet handle escape chars
        //PEGASUS_TEST_ASSERT(String::match("*test", "\\*test"));

        PEGASUS_TEST_ASSERT(String::match("abcdef123", "*[0-9]"));

        PEGASUS_TEST_ASSERT(String::match("This is a test", "*is*"));
        PEGASUS_TEST_ASSERT(String::matchNoCase("This is a test", "*IS*"));

        PEGASUS_TEST_ASSERT(String::match("Hello", "Hello"));
        PEGASUS_TEST_ASSERT(String::matchNoCase("HELLO", "hello"));
        PEGASUS_TEST_ASSERT(String::match("This is a test", "This is *"));
        PEGASUS_TEST_ASSERT(String::match("This is a test", "* is a test"));
        PEGASUS_TEST_ASSERT(!String::match("Hello", "Goodbye"));

        String tPattern =
            "When in the * of human*e??nts it be?ome[sS] [0-9] nec*";


        try
        {
            String x(reinterpret_cast<const char *>(0));
            cerr <<
                 "Error: Exception not thrown on NULL passed to"
                 " constructor(const char *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed to"
                " constructor(const char *)"
                << endl;
        }


        try
        {
            String x(reinterpret_cast<const Char16 *>(0));
            cerr <<
                "Error: Exception not thrown on NULL passed to"
                " constructor(const Char16 *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed to"
                " constructor(const Char16 *)"
                << endl;
        }


        try
        {
            String x;

            x.assign(reinterpret_cast<const char *>(0));
            cerr <<
                "Error: Exception not thrown on NULL passed to"
                " assign(const char *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed to"
                " assign(const char *)"
                << endl;
        }


        try
        {
            String x;

            x.assign(reinterpret_cast<const Char16 *>(0));
            cerr <<
                "Error: Exception not thrown on NULL passed to"
                " assign(const Char16 *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed to"
                " assign(const Char16 *)"
                << endl;
        }


        try
        {
            String x;

            x.append(reinterpret_cast<const char *>(0));
            cerr <<
                "Error: Exception not thrown on NULL passed to"
                " append(const char *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed to"
                " append(const char *)"
                << endl;
        }


        try
        {
            String x;

            x.append(reinterpret_cast<const Char16 *>(0));
            cerr <<
                "Error: Exception not thrown on NULL passed to"
                " append(const Char16 *)"
                << endl;
        }

        catch ( const NullPointer & )
        {
            // This is the exception that should be thrown.
        }

        catch ( ... )
        {
            cerr <<
                "Error: Wrong exception thrown on NULL passed"
                " to append(const Char16 *)"
                << endl;
        }

        // ATTN-RK-P3-20020603: This match code is broken
        //PEGASUS_TEST_ASSERT(String::match(
        //    "When in the course of human events it becomes 0 necessary",
        //    tPattern));
        //PEGASUS_TEST_ASSERT(String::match(
        //    "When in the xyz of human events it becomes 9 necessary",
        //    tPattern));
        //PEGASUS_TEST_ASSERT(String::match(
        //    "When in the  of human events it becomes 3 necessary",
        //    tPattern));
    }
#endif

    // string()
    {
    String s;
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s[0] == '\0');
    }

    // String(const String& s)
    {
    const String s("hello");
    const String t = s;
    PEGASUS_TEST_ASSERT(s.size() == strlen("hello"));
    PEGASUS_TEST_ASSERT(s == "hello");
    PEGASUS_TEST_ASSERT(t.size() == strlen("hello"));
    PEGASUS_TEST_ASSERT(t == "hello");
    }

    // String(const char*)
    {
    const String s("hello");
    PEGASUS_TEST_ASSERT(s.size() == strlen("hello"));
    PEGASUS_TEST_ASSERT(s == "hello");
    }

    // reserve()
    {
    String s;
    s.reserveCapacity(100);
    PEGASUS_TEST_ASSERT(s.size() == 0);
    // PEGASUS_TEST_ASSERT(s.getCapacity() >= 100);

    String t("hello world");
    PEGASUS_TEST_ASSERT(t.size() == strlen("hello world"));
    t.reserveCapacity(500);
    PEGASUS_TEST_ASSERT(t.size() == strlen("hello world"));
    PEGASUS_TEST_ASSERT(t == "hello world");
    }

    // assign(const String&)
    {
    String s("this is a test");
    String t;

    t = s;
    PEGASUS_TEST_ASSERT(s.size() == strlen("this is a test"));
    PEGASUS_TEST_ASSERT(s == "this is a test");
    PEGASUS_TEST_ASSERT(t.size() == strlen("this is a test"));
    PEGASUS_TEST_ASSERT(t == "this is a test");

    s = t;
    PEGASUS_TEST_ASSERT(s.size() == strlen("this is a test"));
    PEGASUS_TEST_ASSERT(s == "this is a test");
    PEGASUS_TEST_ASSERT(t.size() == strlen("this is a test"));
    PEGASUS_TEST_ASSERT(t == "this is a test");
    }

    // assign(const char*, size_t)
    {
    const char MESSAGE[] = "x";
    const size_t LENGTH = sizeof(MESSAGE) - 1;
    String s;
    s.assign(MESSAGE, LENGTH);
    PEGASUS_TEST_ASSERT(s.size() == LENGTH);
    PEGASUS_TEST_ASSERT(s == MESSAGE);

    String t("dummy", 5);
    t.assign(MESSAGE, LENGTH);
    PEGASUS_TEST_ASSERT(t.size() == LENGTH);
    PEGASUS_TEST_ASSERT(t == MESSAGE);
    }

    // assign(const char*)
    {
    const char MESSAGE[] = "x";
    const size_t LENGTH = sizeof(MESSAGE) - 1;
    String s;
    s.assign(MESSAGE);
    PEGASUS_TEST_ASSERT(s.size() == LENGTH);
    PEGASUS_TEST_ASSERT(s == MESSAGE);

    String t("dummy", 5);
    t.assign(MESSAGE);
    PEGASUS_TEST_ASSERT(t.size() == LENGTH);
    PEGASUS_TEST_ASSERT(t == MESSAGE);
    }

    // append(const String&)
    {
    String s;

    s.append(String("xxx"));
    PEGASUS_TEST_ASSERT(s.size() == 3);
    PEGASUS_TEST_ASSERT(s == "xxx");

    s.append(String("yyy"));
    PEGASUS_TEST_ASSERT(s.size() == 6);
    PEGASUS_TEST_ASSERT(s == "xxxyyy");

    s.append(String("zzz"));
    PEGASUS_TEST_ASSERT(s.size() == 9);
    PEGASUS_TEST_ASSERT(s == "xxxyyyzzz");
    }

    // append(const char*)
    {
    String s;

    s.append("xxx");
    PEGASUS_TEST_ASSERT(s.size() == 3);
    PEGASUS_TEST_ASSERT(s == "xxx");

    s.append("yyy");
    PEGASUS_TEST_ASSERT(s.size() == 6);
    PEGASUS_TEST_ASSERT(s == "xxxyyy");

    s.append("zzz");
    PEGASUS_TEST_ASSERT(s.size() == 9);
    PEGASUS_TEST_ASSERT(s == "xxxyyyzzz");
    }

    // append(const char*)
    {
    String s;

    s.append("xxx");
    PEGASUS_TEST_ASSERT(s.size() == 3);
    PEGASUS_TEST_ASSERT(s == "xxx");

    s.append("yyy");
    PEGASUS_TEST_ASSERT(s.size() == 6);
    PEGASUS_TEST_ASSERT(s == "xxxyyy");

    s.append("zzz");
    PEGASUS_TEST_ASSERT(s.size() == 9);
    PEGASUS_TEST_ASSERT(s == "xxxyyyzzz");
    }

    // append(char)
    {
    String s;

    for (int i = 'a'; i <= 'z'; i++)
    {
        Char16 c = i;
        s.append(c);
    }

    PEGASUS_TEST_ASSERT(s.size() == 26);
    PEGASUS_TEST_ASSERT(s == "abcdefghijklmnopqrstuvwxyz");
    }

    // clear()
    {
    String s("abc");
    String t = s;
    String u = s;

    s.clear();
    PEGASUS_TEST_ASSERT(t.size() == 3);
    PEGASUS_TEST_ASSERT(t == "abc");
    PEGASUS_TEST_ASSERT(t[0] == 'a');
    PEGASUS_TEST_ASSERT(u.size() == 3);
    PEGASUS_TEST_ASSERT(u == "abc");
    PEGASUS_TEST_ASSERT(u[0] == 'a');
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s[0] == '\0');

    t.clear();
    PEGASUS_TEST_ASSERT(t.size() == 0);
    PEGASUS_TEST_ASSERT(t[0] == '\0');
    PEGASUS_TEST_ASSERT(t == "");
    PEGASUS_TEST_ASSERT(u.size() == 3);
    PEGASUS_TEST_ASSERT(u == "abc");
    PEGASUS_TEST_ASSERT(u[0] == 'a');
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s == "");
    PEGASUS_TEST_ASSERT(s[0] == '\0');

    u.clear();
    PEGASUS_TEST_ASSERT(t.size() == 0);
    PEGASUS_TEST_ASSERT(t == "");
    PEGASUS_TEST_ASSERT(t[0] == '\0');
    PEGASUS_TEST_ASSERT(u.size() == 0);
    PEGASUS_TEST_ASSERT(u == "");
    PEGASUS_TEST_ASSERT(u[0] == '\0');
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s == "");
    PEGASUS_TEST_ASSERT(s[0] == '\0');
    }

    // c_str()
    {
    String s("abc");
    String t("abc");
    String u("def");
    String v;
    String w("");

    PEGASUS_TEST_ASSERT(s == "abc");
    PEGASUS_TEST_ASSERT(t == "abc");
    PEGASUS_TEST_ASSERT(u == "def");
    PEGASUS_TEST_ASSERT(s == t);
    PEGASUS_TEST_ASSERT(s != u);
    PEGASUS_TEST_ASSERT(v == "");
    PEGASUS_TEST_ASSERT(v[0] == '\0');
    PEGASUS_TEST_ASSERT(v[0] == '\0');
    PEGASUS_TEST_ASSERT(w.size() == 0);
    PEGASUS_TEST_ASSERT(w[0] == '\0');
    PEGASUS_TEST_ASSERT(w[0] == '\0');
    }

    // set(size_t, char)
    {
    String s("abcdefghijklmnopqrstuvwxyz");

    for (int i = 0; i < 26; i++)
        s[i] = toupper(s[i]);

    PEGASUS_TEST_ASSERT(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    }

    // equal(const String&)
    {
    String t("abc");
    String u("abc");
    String v("def");
    String w("defg");
    String x("");
    String y("");

    PEGASUS_TEST_ASSERT(String::equal(t, t));
    PEGASUS_TEST_ASSERT(String::equal(u, u));
    PEGASUS_TEST_ASSERT(String::equal(v, v));
    PEGASUS_TEST_ASSERT(String::equal(w, w));
    PEGASUS_TEST_ASSERT(String::equal(x, x));
    PEGASUS_TEST_ASSERT(String::equal(y, y));

    PEGASUS_TEST_ASSERT(String::equal(t, u));
    PEGASUS_TEST_ASSERT(String::equal(u, t));

    PEGASUS_TEST_ASSERT(!String::equal(t, v));
    PEGASUS_TEST_ASSERT(!String::equal(t, w));
    PEGASUS_TEST_ASSERT(!String::equal(t, x));
    PEGASUS_TEST_ASSERT(!String::equal(t, y));
    PEGASUS_TEST_ASSERT(!String::equal(v, t));
    PEGASUS_TEST_ASSERT(!String::equal(w, t));
    PEGASUS_TEST_ASSERT(!String::equal(x, t));
    PEGASUS_TEST_ASSERT(!String::equal(y, t));

    PEGASUS_TEST_ASSERT(!String::equal(v, w));
    PEGASUS_TEST_ASSERT(!String::equal(w, v));
    PEGASUS_TEST_ASSERT(String::equal(x, y));
    PEGASUS_TEST_ASSERT(String::equal(y, x));
    }

    // equal(const char*)
    {
    String t("abc");
    String u("abc");
    String v("def");
    String w("defg");
    String x("");
    String y("");

    PEGASUS_TEST_ASSERT(String::equal(t, "abc"));
    PEGASUS_TEST_ASSERT(String::equal(u, "abc"));
    PEGASUS_TEST_ASSERT(String::equal(v, "def"));
    PEGASUS_TEST_ASSERT(String::equal(w, "defg"));
    PEGASUS_TEST_ASSERT(String::equal(x, ""));
    PEGASUS_TEST_ASSERT(String::equal(y, ""));

    PEGASUS_TEST_ASSERT(String::equal(t, "abc"));
    PEGASUS_TEST_ASSERT(String::equal(u, "abc"));

    PEGASUS_TEST_ASSERT(!String::equal(t, "def"));
    PEGASUS_TEST_ASSERT(!String::equal(t, "defg"));
    PEGASUS_TEST_ASSERT(!String::equal(t, ""));
    PEGASUS_TEST_ASSERT(!String::equal(t, ""));
    PEGASUS_TEST_ASSERT(!String::equal(v, "abc"));
    PEGASUS_TEST_ASSERT(!String::equal(w, "abc"));
    PEGASUS_TEST_ASSERT(!String::equal(x, "abc"));
    PEGASUS_TEST_ASSERT(!String::equal(y, "abc"));

    PEGASUS_TEST_ASSERT(!String::equal(v, "defg"));
    PEGASUS_TEST_ASSERT(!String::equal(w, "def"));
    PEGASUS_TEST_ASSERT(String::equal(x, ""));
    PEGASUS_TEST_ASSERT(String::equal(y, ""));
    }

    // equali()
    {
    String s("abc");
    String t("abC");
    String u("ABC");
    String v("xyz");
    String w("");
    String x("");
    PEGASUS_TEST_ASSERT(String::equalNoCase(s, t));
    PEGASUS_TEST_ASSERT(String::equalNoCase(s, u));
    PEGASUS_TEST_ASSERT(!String::equalNoCase(s, v));
    PEGASUS_TEST_ASSERT(String::equalNoCase(w, x));
    PEGASUS_TEST_ASSERT(!String::equalNoCase(w, s));
    PEGASUS_TEST_ASSERT(!String::equalNoCase(w, t));
    PEGASUS_TEST_ASSERT(!String::equalNoCase(w, v));
    }

    {

    String t;
    const char MESSAGE[] = "hello";
    const size_t LENGTH = sizeof(MESSAGE) - 1;
    String s = String(MESSAGE);
    t = s;
    String u = String(t);

    PEGASUS_TEST_ASSERT(t.size() == LENGTH);
    PEGASUS_TEST_ASSERT(t == MESSAGE);
    PEGASUS_TEST_ASSERT(s.size() == LENGTH);
    PEGASUS_TEST_ASSERT(s == MESSAGE);
    PEGASUS_TEST_ASSERT(u.size() == LENGTH);
    PEGASUS_TEST_ASSERT(u == MESSAGE);

    PEGASUS_TEST_ASSERT(t[0] == 'h');
    PEGASUS_TEST_ASSERT(t[1] == 'e');
    PEGASUS_TEST_ASSERT(t[2] == 'l');
    PEGASUS_TEST_ASSERT(t[3] == 'l');
    PEGASUS_TEST_ASSERT(t[4] == 'o');
    PEGASUS_TEST_ASSERT(t[5] == '\0');

    t.append(" world");
    PEGASUS_TEST_ASSERT(t.size() == strlen("hello world"));
    PEGASUS_TEST_ASSERT(t == "hello world");
    PEGASUS_TEST_ASSERT(s != "hello world");
    PEGASUS_TEST_ASSERT(s == "hello");
    PEGASUS_TEST_ASSERT(s.size() == strlen("hello"));

    t[0] = 'x';
    PEGASUS_TEST_ASSERT(t == "xello world");
    }

    // remove()
    {
    String s("abcXYZdefLMNOP");

    s.remove(0,0);
    PEGASUS_TEST_ASSERT(s.size() == 14);
    PEGASUS_TEST_ASSERT(s == "abcXYZdefLMNOP");

    s.remove(0, 3);
    PEGASUS_TEST_ASSERT(s.size() == 11);
    PEGASUS_TEST_ASSERT(s == "XYZdefLMNOP");

    s.remove(3, 3);
    PEGASUS_TEST_ASSERT(s.size() == 8);
    PEGASUS_TEST_ASSERT(s == "XYZLMNOP");

    s.remove(7, 1);
    PEGASUS_TEST_ASSERT(s.size() == 7);
    PEGASUS_TEST_ASSERT(s == "XYZLMNO");

    s.remove(0, 1);
    PEGASUS_TEST_ASSERT(s.size() == 6);
    PEGASUS_TEST_ASSERT(s == "YZLMNO");

    s.remove(2, PEG_NOT_FOUND);
    PEGASUS_TEST_ASSERT(s.size() == 2);
    PEGASUS_TEST_ASSERT(s == "YZ");

    s.remove(2, 0);
    PEGASUS_TEST_ASSERT(s.size() == 2);
    PEGASUS_TEST_ASSERT(s == "YZ");

    s.remove(1, 1);
    PEGASUS_TEST_ASSERT(s.size() == 1);
    PEGASUS_TEST_ASSERT(s == "Y");

    s.remove(0, 1);
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s == "");
    PEGASUS_TEST_ASSERT(s[0] == '\0');

    s.remove(0,0);
    PEGASUS_TEST_ASSERT(s.size() == 0);
    PEGASUS_TEST_ASSERT(s == "");
    PEGASUS_TEST_ASSERT(s[0] == '\0');
    }

    // subString()
    {
    String s("one two three");
    PEGASUS_TEST_ASSERT(s.subString(0) == "one two three");
    PEGASUS_TEST_ASSERT(s.subString(0, 3) == "one");
    PEGASUS_TEST_ASSERT(s.subString(4, 3) == "two");
    PEGASUS_TEST_ASSERT(s.subString(8, 5) == "three");
    PEGASUS_TEST_ASSERT(s.subString(0, 0) == "");
    PEGASUS_TEST_ASSERT(s.subString(13, 0) == "");
    }

    // Overflow
    bool caught_bad_alloc = false;
    try
    {
    String s("junk", Uint32(0xFFFFFFFF));
    }
    catch(...)
    {
    caught_bad_alloc = true;
    }
    PEGASUS_TEST_ASSERT(caught_bad_alloc);

    // Added to test funtionality of String(const String& str, Uint32 n)
    // for memory overflow.
    Boolean caughtBadAlloc = false;
    try
    {
        String s("abc", 0xFFFF0000);   //to check for alloc
    }
    catch(const PEGASUS_STD(bad_alloc)&)
    {
        caughtBadAlloc = true;
    }

    // Added to test funtionality of
    // void reserveCapacity(Uint32 capacity) for memory overflow.
    caughtBadAlloc = false;
    try
    {
        String s;
        s.reserveCapacity(0xFFFF0000);   //to check for _reserve
    }
    catch (const PEGASUS_STD(bad_alloc)&)
    {
        caughtBadAlloc = true;
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // Added to test funtionality of
    // String& append(const char* str, Uint32 size) for memory overflow.
    caughtBadAlloc = false;
    try
    {
        String s;
        s.append("xxx", 0xFFFF0000);         //to check for _reserve
    }
    catch (const PEGASUS_STD(bad_alloc)&)
    {
        caughtBadAlloc = true;
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // Added to test funtionality of
    // String& append(const Char16* str, Uint32 n) for memory overflow.
    caughtBadAlloc = false;
    try
    {
        String s;
        s.append((Char16 *)"xxx", 0xFFFF0000); //to check for _reserve
    }
    catch (const PEGASUS_STD(bad_alloc)&)
    {
        caughtBadAlloc = true;
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // Added to test funtionality of
    // String& assign(const char* str, Uint32 n) for memory overflow.
    caughtBadAlloc = false;
    try
    {
        String s;
        s.assign("xxx", 0xFFFF0000);               //to check for alloc
    }
    catch (const PEGASUS_STD(bad_alloc)&)
    {
    caughtBadAlloc = true;
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // Added to test funtionality of
    // String& assign(const Char16* str, Uint32 n) for memory overflow.
    caughtBadAlloc = false;
    try
    {
        String s;
        s.assign((Char16 *)"xxx", 0xFFFF0000);   //to check for alloc
    }
    catch (const PEGASUS_STD(bad_alloc)&)
    {
        caughtBadAlloc = true;
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // Tests for the dump of a bad strings.

    // 40 good chars, bad char, 10 trailing chars.
    //    Testing the full range of printed data.

    caughtBadAlloc = false;
    try
    {
        String s1("1234567890123456789012345678901234567890""\xFF""1234567890");
    }
    catch ( Exception& ex )
    {
        caughtBadAlloc = true;
        PEGASUS_TEST_ASSERT(
            strstr((const char*)ex.getMessage().getCString(),
                ": 1234567890123456789012345678901234567890"
                    " 0xFF 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30")
            != 0);

    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // 7 good chars, bad char, 7 trailing chars.
    // Testing reduced number of chars arround the bad char.

    caughtBadAlloc = false;
    try
    {
        String s1("0123456""\xAA""0123456");
    }
    catch ( Exception& ex )
    {
        caughtBadAlloc = true;
        PEGASUS_TEST_ASSERT(
            strstr((const char*)ex.getMessage().getCString(),
                ": 0123456 0xAA 0x30 0x31 0x32 0x33 0x34 0x35 0x36")
            != 0);

    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // No good chars, bad char , 20 trailing chars
    // Testing no good chars, bad char at beginning,
    // more trailing chars available then printed.

    caughtBadAlloc = false;
    try
    {
        String s1("\xDD""0123456789012345679");
    }
    catch ( Exception& ex )
    {
        caughtBadAlloc = true;
        PEGASUS_TEST_ASSERT(
            strstr((const char*)ex.getMessage().getCString(),
                ":  0xDD 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39")
            != 0);

    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // 50 good chars ( more the printed ), bad char as last char,
    // no trailing chars.

    caughtBadAlloc = false;
    try
    {
        String s1("AAAAAAAAAA0123456789012345678901234567890123456789""\xBB");
    }
    catch ( Exception& ex )
    {
        caughtBadAlloc = true;
        PEGASUS_TEST_ASSERT(
            strstr((const char*)ex.getMessage().getCString(),
                ": 0123456789012345678901234567890123456789 0xBB")
            != 0);

    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    // no good chars, bad char as the only char, no trailing chars.

    caughtBadAlloc = false;
    try
    {
        String s1("\x80");
    }
    catch ( Exception& ex )
    {
        caughtBadAlloc = true;
        PEGASUS_TEST_ASSERT(
            strstr((const char*)ex.getMessage().getCString(),":  0x80") != 0);
    }
    PEGASUS_TEST_ASSERT(caughtBadAlloc);

    cout << argv[0] << " +++++ passed all tests" << endl;

    char* p = (char*)operator new(88888);
    operator delete(p);

    return 0;
}
Esempio n. 10
0
void CLCD::showAudioTrack(const std::string & artist, const std::string & title, const std::string & album)
{
	if (mode != MODE_AUDIO) 
	{
		return;
	}

	// reload specified line
	display.draw_fill_rect (-1, 10, LCD_COLS, 24, CLCDDisplay::PIXEL_OFF);
	display.draw_fill_rect (-1, 20, LCD_COLS, 37, CLCDDisplay::PIXEL_OFF);
	display.draw_fill_rect (-1, 33, LCD_COLS, 50, CLCDDisplay::PIXEL_OFF);
	fonts.menu->RenderString(0, 22, LCD_COLS + 5, artist.c_str(), CLCDDisplay::PIXEL_ON, 0, isUTF8(artist));
	fonts.menu->RenderString(0, 35, LCD_COLS + 5, album.c_str(),  CLCDDisplay::PIXEL_ON, 0, isUTF8(album));
	fonts.menu->RenderString(0, 48, LCD_COLS + 5, title.c_str(),  CLCDDisplay::PIXEL_ON, 0, isUTF8(title));
	wake_up();
	displayUpdate();

}
Esempio n. 11
0
/* display "big" and "small" text.
   TODO: right now, "big" is hardcoded as utf-8, small is not (for EPG)
 */
void CLCD::showTextScreen(const std::string & big, const std::string & small, const int showmode, const bool perform_wakeup)
{
	/* the "showmode" variable is a bit map:
		EPG_NAME	show "big" string
		EPG_SHORT	show only one line of "big" string
		EPG_TITLE	show "small" string
		EPG_SEPLINE	show separator line if big and small are present / shown
	 */

	/* draw_fill_rect is braindead: it actually fills _inside_ the described rectangle,
	   so that you have to give it one pixel additionally in every direction ;-(
	   this is where the "-1 to 120" intead of "0 to 119" comes from */
	display.draw_fill_rect(-1, 10, LCD_COLS, 51, CLCDDisplay::PIXEL_OFF);

	bool big_utf8 = false;
	bool small_utf8 = false;
	std::string cname[2];
	std::string event[4];
	int namelines = 0, eventlines = 0, maxnamelines = 2;
	if (showmode & EPG_SHORT)
		maxnamelines = 1;

	if ((showmode & EPG_NAME) && !big.empty())
	{
		bool dumb = false;
		big_utf8 = isUTF8(big);
		while (true)
		{
			namelines = 0;
			std::string title = big;
			do { // first try "intelligent" splitting
				cname[namelines] = splitString(title, LCD_COLS, fonts.channelname, dumb, big_utf8);
				title = removeLeadingSpaces(title.substr(cname[namelines].length()));
				namelines++;
			} while (!title.empty() && namelines < maxnamelines);
			if (title.empty())
				break;
			dumb = !dumb;	// retry with dumb splitting;
			if (!dumb)	// second retry -> get out;
				break;
		}
	}

	// one nameline => 2 eventlines, 2 namelines => 1 eventline
	int maxeventlines = 4 - (namelines * 3 + 1) / 2;

	if ((showmode & EPG_TITLE) && !small.empty())
	{
		bool dumb = false;
		small_utf8 = isUTF8(small);
		while (true)
		{
			eventlines = 0;
			std::string title = small;
			do { // first try "intelligent" splitting
				event[eventlines] = splitString(title, LCD_COLS, fonts.menu, dumb, small_utf8);
				title = removeLeadingSpaces(title.substr(event[eventlines].length()));
				/* DrDish TV appends a 0x0a to the EPG title. We could strip it in sectionsd...
				   ...instead, strip all control characters at the end of the text for now */
				if (!event[eventlines].empty() && event[eventlines].at(event[eventlines].length() - 1) < ' ')
					event[eventlines].erase(event[eventlines].length() - 1);
				eventlines++;
			} while (!title.empty() && eventlines < maxeventlines);
			if (title.empty())
				break;
			dumb = !dumb;	// retry with dumb splitting;
			if (!dumb)	// second retry -> get out;
				break;
		}
	}

	/* this values were determined empirically */
	int y = 8 + (41 - namelines*14 - eventlines*10)/2;
	int x = 1;
	for (int i = 0; i < namelines; i++) {
		y += 14;
		if (g_settings.lcd_setting[SNeutrinoSettings::LCD_EPGALIGN] == EPGALIGN_CENTER)
		{
			int w = fonts.channelname->getRenderWidth(cname[i].c_str(), big_utf8);
			x = (LCD_COLS - w) / 2;
		}
		fonts.channelname->RenderString(x, y, LCD_COLS + 10, cname[i].c_str(), CLCDDisplay::PIXEL_ON, 0, big_utf8);
	}
	y++;
	if (eventlines > 0 && namelines > 0 && (showmode & EPG_SEPLINE))
	{
		y++;
		display.draw_line(0, y, LCD_COLS - 1, y, CLCDDisplay::PIXEL_ON);
	}
	if (eventlines > 0)
	{
		for (int i = 0; i < eventlines; i++) {
			y += 10;
			if (g_settings.lcd_setting[SNeutrinoSettings::LCD_EPGALIGN] == EPGALIGN_CENTER)
			{
				int w = fonts.menu->getRenderWidth(event[i].c_str(), small_utf8);
				x = (LCD_COLS - w) / 2;
			}
			fonts.menu->RenderString(x, y, LCD_COLS + 10, event[i].c_str(), CLCDDisplay::PIXEL_ON, 0, small_utf8);
		}
	}

	if (perform_wakeup)
		wake_up();

	displayUpdate();
}
bool isUTF8(const std::string &text)
{
	return (isUTF8(text.c_str(), text.length()));
};
void CIMExportRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
{
    PEGASUS_ASSERT(httpMessage->message.size() != 0);

    // Save queueId and userName

    Uint32 queueId = httpMessage->queueId;
    String userName = httpMessage->authInfo->getAuthenticatedUser();

    Boolean closeConnect = httpMessage->getCloseConnect();
    PEG_TRACE((
                  TRC_HTTP,
                  Tracer::LEVEL4,
                  "CIMOperationRequestDecoder::handleHTTPMessage() -"
                  " httpMessage->getCloseConnect() returned %d",
                  httpMessage->getCloseConnect()));

    // Parse the HTTP message:

    String startLine;
    Array<HTTPHeader> headers;
    char* content;
    Uint32 contentLength;

    httpMessage->parse(startLine, headers, contentLength);

    // Parse the request line:

    String methodName;
    String requestUri;
    String httpVersion;
    HttpMethod httpMethod = HTTP_METHOD__POST;

    // ATTN-RK-P3-20020404: The requestUri may need to be pruned of the host
    // name.  All we care about at this point is the path.
    HTTPMessage::parseRequestLine(
        startLine, methodName, requestUri, httpVersion);

    //
    //  Set HTTP method for the request
    //
    if (methodName == "M-POST")
    {
        httpMethod = HTTP_METHOD_M_POST;
    }

    // Unsupported methods are caught in the HTTPAuthenticatorDelegator
    //<Bug #351>
    //PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");
    if (methodName != "M-POST" && methodName != "POST")
    {
        sendHttpError(
            queueId,
            HTTP_STATUS_NOTIMPLEMENTED,
            "Only POST and M-POST are implemented",
            String::EMPTY,
            closeConnect);
        return;
    }
    //</bug>
    //
    // Not true: "Mismatch of method and version is caught in
    // HTTPAuthenticatorDelegator", bug #351 fixes this:
    //
    //PEGASUS_ASSERT (!((httpMethod == HTTP_METHOD_M_POST) &&
    //                  (httpVersion == "HTTP/1.0")));
    if ((httpMethod == HTTP_METHOD_M_POST) &&
            (httpVersion == "HTTP/1.0"))
    {
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "M-POST method is not valid with version 1.0",
            String::EMPTY,
            closeConnect);
        return;
    }
    //</bug>

    // Process M-POST and POST messages:

    if (httpVersion == "HTTP/1.1")
    {
        // Validate the presence of a "Host" header.  The HTTP/1.1 specification
        // says this in section 14.23 regarding the Host header field:
        //
        //     All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad
        //     Request) status code to any HTTP/1.1 request message which lacks
        //     a Host header field.
        //
        // Note:  The Host header value is not validated.

        const char* hostHeader;
        Boolean hostHeaderFound = HTTPMessage::lookupHeader(
                                      headers, "Host", hostHeader, false);

        if (!hostHeaderFound)
        {
            MessageLoaderParms parms(
                "ExportServer.CIMExportRequestDecoder.MISSING_HOST_HEADER",
                "HTTP request message lacks a Host header field.");
            String msg(MessageLoader::getMessage(parms));
            sendHttpError(
                queueId,
                HTTP_STATUS_BADREQUEST,
                "",
                msg,
                closeConnect);
            return;
        }
    }

    // Validate the "CIMExport" header:

    const char* cimExport;
    Boolean exportHeaderFound = HTTPMessage::lookupHeader(
                                    headers, "CIMExport", cimExport, true);
    // If the CIMExport header was missing, the HTTPAuthenticatorDelegator
    // would not have passed the message to us.

    // <bug #351>
    // PEGASUS_ASSERT(exportHeaderFound);
    if (!exportHeaderFound)
    {
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "Export header not found",
            String::EMPTY,
            closeConnect);
        return;
    }
    // </bug>

    if (System::strcasecmp(cimExport, "MethodRequest") != 0)
    {
        // The Specification for CIM Operations over HTTP reads:
        //     3.3.5. CIMExport
        //     If a CIM Listener receives CIM Export request with this
        //     header, but with a missing value or a value that is not
        //     "MethodRequest", then it MUST fail the request with
        //     status "400 Bad Request". The CIM Server MUST include a
        //     CIMError header in the response with a value of
        //     unsupported-operation.
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "unsupported-operation",
            String::EMPTY,
            closeConnect);
        return;
    }

    // Validate the "CIMExportBatch" header:

    const char* cimExportBatch;
    if (HTTPMessage::lookupHeader(
                headers, "CIMExportBatch", cimExportBatch, true))
    {
        // The Specification for CIM Operations over HTTP reads:
        //     3.3.10. CIMExportBatch
        //     If a CIM Listener receives CIM Export Request for which the
        //     CIMExportBatch header is present, but the Listener does not
        //     support Multiple Exports, then it MUST fail the request and
        //     return a status of "501 Not Implemented".
        sendHttpError(
            queueId,
            HTTP_STATUS_NOTIMPLEMENTED,
            "multiple-requests-unsupported",
            String::EMPTY,
            closeConnect);
        return;
    }

    // Save these headers for later checking

    const char* cimProtocolVersion;
    if (!HTTPMessage::lookupHeader(
                headers, "CIMProtocolVersion", cimProtocolVersion, true))
    {
        // Mandated by the Specification for CIM Operations over HTTP
        cimProtocolVersion = "1.0";
    }

    const char* cimExportMethod;
    if (!HTTPMessage::lookupHeader(
                headers, "CIMExportMethod", cimExportMethod, true))
    {
        // The CIMExportMethod header is not present and we already know the
        // Export Request Message is a Simple Export Request.
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "header-mismatch",
            String::EMPTY,
            closeConnect);
        return;
    }

    AcceptLanguageList acceptLanguages;
    ContentLanguageList contentLanguages;
    try
    {
        if (httpMessage->acceptLanguagesDecoded)
        {
            acceptLanguages = httpMessage->acceptLanguages;
        }
        else
        {
            // Get and validate the Accept-Language header, if set
            String acceptLanguageHeader;
            if (HTTPMessage::lookupHeader(
                        headers,
                        "Accept-Language",
                        acceptLanguageHeader,
                        false))
            {
                acceptLanguages = LanguageParser::parseAcceptLanguageHeader(
                                      acceptLanguageHeader);
            }
        }

        if (httpMessage->contentLanguagesDecoded)
        {
            contentLanguages = httpMessage->contentLanguages;
        }
        else
        {
            // Get and validate the Content-Language header, if set
            String contentLanguageHeader;
            if (HTTPMessage::lookupHeader(
                        headers,
                        "Content-Language",
                        contentLanguageHeader,
                        false))
            {
                contentLanguages = LanguageParser::parseContentLanguageHeader(
                                       contentLanguageHeader);
            }
        }
    }
    catch (Exception& e)
    {
        Thread::clearLanguages();
        MessageLoaderParms msgParms(
            "ExportServer.CIMExportRequestDecoder.REQUEST_NOT_VALID",
            "request-not-valid");
        String msg(MessageLoader::getMessage(msgParms));
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            msg,
            e.getMessage(),
            closeConnect);
        return;
    }

    // Calculate the beginning of the content from the message size and
    // the content length.

    content = (char *) httpMessage->message.getData() +
              httpMessage->message.size() - contentLength;

    // Validate the "Content-Type" header:

    const char* cimContentType;
    Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(
                                         headers, "Content-Type", cimContentType, true);
    String type;
    String charset;

    if (!contentTypeHeaderFound ||
            !HTTPMessage::parseContentTypeHeader(cimContentType, type, charset) ||
            (!String::equalNoCase(type, "application/xml") &&
             !String::equalNoCase(type, "text/xml")) ||
            !String::equalNoCase(charset, "utf-8"))
    {
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "",
            "HTTP Content-Type header error.",
            closeConnect);
        return;
    }
    else
    {
        // Validating content falls within UTF8 (required to be complaint
        // with section C12 of Unicode 4.0 spec, chapter 3.)
        Uint32 count = 0;
        while(count<contentLength)
        {
            if (!(isUTF8((char *)&content[count])))
            {
                sendHttpError(
                    queueId,
                    HTTP_STATUS_BADREQUEST,
                    "request-not-valid",
                    "Invalid UTF-8 character detected.",
                    closeConnect);
                return;
            }
            UTF8_NEXT(content,count);
        }
    }

    // If it is a method call, then dispatch it to be handled:

    handleMethodRequest(
        queueId,
        httpMethod,
        content,
        requestUri,
        cimProtocolVersion,
        cimExportMethod,
        userName,
        httpMessage->ipAddress,
        acceptLanguages,
        contentLanguages,
        closeConnect);
}
Esempio n. 14
0
eService *eServiceHandlerDVB::createService(const eServiceReference &node)
{
#ifndef DISABLE_FILE
	if (node.data[0]>=0)
	{
		eString l=node.path.mid(node.path.rfind('/')+1);
		if (!isUTF8(l))
			l=convertLatin1UTF8(l);
		if (node.descr)
			l=node.descr;
/* moved to dvbservice.cpp, function eDVBServiceController::FillPIDsFromFile
		int fd=open(node.path.c_str(), O_RDONLY|O_LARGEFILE);
		if (fd < 0)
			return 0;
		__u8 packet[188];
		eServiceDVB *dvb=0;
		do
		{
			if (::read(fd, packet, 188) != 188)
				break;
				// i know that THIS is not really a SIT parser :)
			if ((packet[0] != 0x47) || (packet[1] != 0x40) || (packet[2] != 0x1f) || (packet[3] != 0x10))
				break;
			int nameoffset = 6;
			if (memcmp(packet+0x15, "ENIGMA", 6))
			{
				//failed so check another
				if (!memcmp(packet+0x15, "NEUTRINONG", 10))
					nameoffset = 10;
				else
					break;
			}
			// we found our private descriptor:
			__u8 *descriptor=packet+0x13;
			int len=descriptor[1];
			dvb=new eServiceDVB(eServiceID((packet[0xf]<<8)|packet[0x10]), l.c_str());
			len-=nameoffset;
			descriptor+=2+nameoffset; // skip tag, len, ENIGMA or NEUTRINONG
			for (int i=0; i<len; i+=descriptor[i+1]+2)
			{
				int tag=descriptor[i];
				switch (tag)
				{
				case eServiceDVB::cVPID:
					dvb->set(eServiceDVB::cVPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
					break;
				case eServiceDVB::cAPID:
					if (descriptor[i+4] == 0)
						dvb->set(eServiceDVB::cAPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
					else
						dvb->set(eServiceDVB::cAC3PID, (descriptor[i+2]<<8)|(descriptor[i+3]));
					break;
				case eServiceDVB::cTPID:
					dvb->set(eServiceDVB::cTPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
					break;
				case eServiceDVB::cPCRPID:
					dvb->set(eServiceDVB::cPCRPID, (descriptor[i+2]<<8)|(descriptor[i+3]));
					break;
				}
			}
		} while (0);
		close(fd);
		if (!dvb)
			return new eService(l);
		return dvb;
*/
		return new eServiceDVB(eServiceID(), l.c_str());
	}
#endif // DISABLE_FILE
	switch (node.data[0])
	{
	case -1: // for satellites...
	{
	    eSatellite *sat = eTransponderList::getInstance()->findSatellite(node.data[2] >> 16 );
	    if (!sat)
			return 0;
		else
			return new eService( eString().sprintf("%s - %s",sat->getDescription().c_str(),_("Providers")));
	}
	case -2: // for satellites...
	{
	    eSatellite *sat = eTransponderList::getInstance()->findSatellite(node.data[2] >> 16 );
	    if (!sat)
			return 0;
		else
			return new eService( eString().sprintf("%s - %s",sat->getDescription().c_str(),_("Services")));
	}
	case -5: // for satellites...
	{
	    eSatellite *sat = eTransponderList::getInstance()->findSatellite(node.data[2] >> 16 );
	    if (!sat)
			return 0;
		else
			return new eService( eString().sprintf("%s - %s",sat->getDescription().c_str(),_("new found")));
	}
	case -6: 
	{
		return new eService( _("current transponder"));
	}
	case -3:
	{
		eBouquet *b=eDVB::getInstance()->settings->getBouquet(node.data[2]);
		if (!b)
			return 0;
		return new eService(b->bouquet_name.c_str());
	}
	}
	return 0;
}