Stringp ProgramClass::readLine() { AvmCore* core = this->core(); Stringp s = core->kEmptyString; wchar wc[64]; int i=0; for( int c = getchar(); c != '\n' && c != EOF; c = getchar() ) { wc[i++] = (wchar)c; if( i == 63 ) { wc[i] = 0; s = s->append16(wc); i = 0; } } if( i > 0 ) { wc[i] = 0; s = s->append16(wc); } return s; }
Stringp StringClass::AS3_fromCharCode(Atom *argv, int argc) { AvmCore* core = this->core(); Stringp out = core->kEmptyString; for (int i=0; i<argc; i++) { wchar c = wchar(AvmCore::integer(argv[i])); if (c <= 0xff) { // append16 will always append as k16, forcing the string // to be widened, as String::_append doesn't understand kAuto. // That can/should probably be smarted, but for now, // improve the smarts here: uint8_t c8 = uint8_t(c); out = out->appendLatin1((char*)&c8, 1); } else { // note: this code is allowed to construct a string // containing illegal UTF16 sequences! // (eg, String.fromCharCode(0xD800).charCodeAt(0) -> 0xD800). out = out->append16(&c, 1); } } return out; }
Stringp XMLParser::unescape(int32_t start, int32_t last, bool intern) { Stringp dest = core->kEmptyString; if (start == last) return dest; int32_t bgn = m_str->indexOfCharCode('&', start, last); if (bgn < 0) { return intern ? m_str->intern_substring(start, last) : m_str->substring(start, last); } int32_t end = start; while (bgn >= start && bgn < last) { int32_t ampEnd = m_str->indexOfCharCode(';', ++bgn, last); if (ampEnd < 0) // &xxx without semicolon - we are done break; // add the text between the last sequence and this sequence dest = dest->append(m_str->substring(end, bgn-1)); end = ampEnd; int32_t len = end - bgn; // an &xx; sequence is at least two characters bool ok = true; if (len >= 2) { int32_t ch = m_str[bgn]; if (ch == '#') { // Parse a &#xx; decimal sequence. Or a Ý hex sequence ch = m_str[++bgn]; len--; int base = 10; if (len >= 2 && ch == 'x') base = 16, bgn++, len--; if (len > 0) { int32_t value = 0; while (len-- && ok) { ch = m_str[bgn++]; if (ch >= 'A' && ch <= 'F') ch -= 7; ch -= '0'; if (ch >= 0 && ch < base) value = (value * base) + ch; else ok = false; if (value > 0xFFFF) ok = false; } if (ok) { wchar c = (wchar) value; // note: this code is allowed to construct a string // containing illegal UTF16 sequences! dest = dest->append16(&c, 1); bgn = ++end; } } } else if (len <= 4) // Our xmlEntities are only 4 characters or less { Atom entityAtom = m_str->intern_substring(bgn, end)->atom(); Atom result = core->xmlEntities->get(entityAtom); if (result != undefinedAtom) { AvmAssert(atomIsIntptr(result)); wchar c = (wchar) atomGetIntptr(result); // note: this code is allowed to construct a string // containing illegal UTF16 sequences! dest = dest->append16(&c, 1); bgn = ++end; } else ok = false; } else ok = false; } if (!ok) bgn = end + 1; bgn = m_str->indexOfCharCode('&', bgn, last); } // add any remaining text if (end < last) dest = dest->append(m_str->substring(end, last)); if (intern) dest = core->internString(dest); return dest; }