TEST(GTestXmlDom, TestElement) { Document::CPtr doc = Document::parse(sample); ASSERT_TRUE(!doc->asAttr()); ASSERT_TRUE(!doc->asElement()); ASSERT_TRUE(!!doc->asDocument()); Node::CPtr node = doc->firstChild(); ASSERT_TRUE(!node->asAttr()); ASSERT_TRUE(!!node->asElement()); ASSERT_TRUE(!node->asDocument()); Element::CPtr element = node->asElement(); String::CPtr tag = element->tagName(); String::CPtr attrVal1 = element->getAttribute(String::create("name")); String::CPtr attrVal2 = element->getAttribute(String::create("foo")); String::CPtr attrVal3 = element->getAttribute(String::null()); ASSERT_TRUE(tag->equals(String::create("team"))); ASSERT_TRUE(attrVal1->equals(String::create("foo"))); ASSERT_TRUE(attrVal2->equals(String::create())); ASSERT_TRUE(!attrVal3); ASSERT_TRUE(element->hasAttribute(String::create("name"))); ASSERT_FALSE(element->hasAttribute(String::create("foo"))); ASSERT_FALSE(element->hasAttribute(String::null())); Attr::CPtr attr1 = element->getAttributeNode(String::create("name")); Attr::CPtr attr2 = element->getAttributeNode(String::create("foo")); Attr::CPtr attr3 = element->getAttributeNode(String::null()); ASSERT_TRUE(!!attr1); ASSERT_TRUE(!attr2); ASSERT_TRUE(!attr3); }
String::CPtr resolve(JsArray::CPtr paths) { const Size kMax = 8192; char dir[kMax]; char* r = getcwd(dir, kMax); if (!r) return String::null(); if (!paths) return String::create(dir); StringBuilder::Ptr resolved = StringBuilder::create(); resolved->appendStr(dir); Size len = paths->length(); for (Size i = 0; i < len; i++) { String::CPtr path = paths->getCPtr<String>(i); if (path) { if (isSep(path->charAt(0))) { resolved = StringBuilder::create(); #ifdef LIBJ_PF_WINDOWS // append the drive letter resolved->appendChar(dir[0]); resolved->appendChar(dir[1]); } else if (isAlpha(path->charAt(0)) && path->charAt(1) == ':') { resolved = StringBuilder::create(); #endif } else if (!path->isEmpty()) { resolved->appendChar(SEP); } resolved->appendStr(path); } } return trimSeps(normalize(resolved->toString())); }
String::CPtr percentDecode(String::CPtr str, String::Encoding enc) { if (!str || str->isEmpty()) return String::create(); Size len = str->length() + 1; char* decoded = new char[len]; Size size = percentDecode(decoded, len, str->toStdString().c_str()); String::CPtr res; switch (enc) { case String::UTF8: res = String::create(decoded, enc, size); break; case String::UTF16: case String::UTF16BE: case String::UTF16LE: res = String::create(decoded, enc, size >> 1); break; case String::UTF32: case String::UTF32BE: case String::UTF32LE: res = String::create(decoded, enc, size >> 2); break; default: assert(false); res = String::null(); } delete[] decoded; return res; }
Boolean log(const Value& val) { String::CPtr s = String::valueOf(val); if (!s) return false; std::cout << s->toStdString() << std::endl; return true; }
static inline Size indexOfSep(String::CPtr str, Size from) { assert(str); Size len = str->length(); for (Size i = from; i < len; i++) { if (isSep(str->charAt(i))) return i; } return NO_POS; }
TEST(GTestJsClosure, TestClosure2) { String::CPtr abc = String::create("abc"); String::CPtr xyz = String::create("xyz"); JsClosure::Ptr concat = JsClosure::create( [abc, xyz] (JsArray::Ptr args) -> Value { return abc->concat(xyz); }); ASSERT_TRUE(concat->call().equals(String::create("abcxyz"))); }
Boolean error(const Value& val) { if (val.isUndefined() || !isPrintable(LEVEL_ERROR)) return false; String::CPtr s = toString(val); if (s) { error(s->toStdString().c_str()); return true; } else { return false; } }
Boolean warn(const Value& val) { if (val.isUndefined() || !isPrintable(LEVEL_WARNING)) return false; String::CPtr s = toString(val); if (s) { warn(s->toStdString().c_str()); return true; } else { return false; } }
Boolean log(const Value& val) { if (val.isUndefined() || !isPrintable(LEVEL_NORMAL)) return false; String::CPtr s = toString(val); if (s) { log(s->toStdString().c_str()); return true; } else { return false; } }
String::CPtr extname(String::CPtr path) { if (!path) return String::create(); String::CPtr base = basename(path); if (base->charAt(0) == '.') return String::create(); Size lastIndex = base->lastIndexOf('.'); if (lastIndex == NO_POS) { return String::create(); } else { return base->substring(lastIndex); } }
TEST(GTestValue, TestTo10) { Value v = String::create("abc"); String::CPtr s; ASSERT_TRUE(to<String::CPtr>(v, &s)); ASSERT_TRUE(s->equals(String::create("abc"))); Immutable::CPtr i1; ASSERT_FALSE(to<Immutable::CPtr>(v, &i1)); Immutable::CPtr i2 = String::create("123"); v = i2; Immutable::CPtr i3; ASSERT_TRUE(to<Immutable::CPtr>(v, &i3)); ASSERT_TRUE(i3->equals(String::create("123"))); }
TEST(GTestStringBuffer, TestToStdString) { const char u[] = { 0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0 }; String::CPtr s = String::create(u, String::UTF8); StringBuffer::Ptr sb = StringBuffer::create(s); ASSERT_EQ(s->toStdString(String::UTF8), sb->toStdString()); ASSERT_EQ(s->toStdString(String::UTF16), sb->toStdString(String::UTF16)); ASSERT_EQ(s->toStdString(String::UTF32), sb->toStdString(String::UTF32)); }
TEST(GTestJsRegExp, TestExec) { JsRegExp::Ptr re = JsRegExp::create(String::create("a+(b*)(c)")); JsArray::Ptr a = re->exec(String::create("xaacz")); ASSERT_EQ(3, a->length()); ASSERT_TRUE(toCPtr<String>(a->get(0))->equals(String::create("aac"))); ASSERT_TRUE(a->get(1).isUndefined()); ASSERT_TRUE(toCPtr<String>(a->get(2))->equals(String::create("c"))); Int index = -1; to<Int>(a->getProperty(String::create("index")), &index); ASSERT_EQ(1, index); String::CPtr input = toCPtr<String>(a->getProperty(String::create("input"))); ASSERT_TRUE(input->equals(String::create("xaacz"))); ASSERT_FALSE(re->exec(String::create("bc"))); }
static inline Size lastIndexOfSep(String::CPtr str, Size from = NO_POS) { assert(str); Size len = str->length(); if (!len) return NO_POS; if (from >= len) from = len - 1; Size i = from; while (1) { if (isSep(str->charAt(i))) return i; if (i) { i--; } else { break; } } return NO_POS; }
static inline String::CPtr trimSeps(String::CPtr str) { assert(str); Size len = str->length(); if (!len) return str; Size i = len - 1; while (1) { if (!isSep(str->charAt(i))) { return str->substring(0, i + 1); } if (i) { i--; } else { break; } } return str->substring(0, 1); }
TEST(GTestJsRegExp, TestExec2) { JsRegExp::Ptr re = JsRegExp::create(String::create("^([0-9]+)\\.([0-9]+)$")); JsArray::Ptr a = re->exec(String::create("1.23")); ASSERT_EQ(3, a->length()); ASSERT_TRUE(toCPtr<String>(a->get(0))->equals(String::create("1.23"))); ASSERT_TRUE(toCPtr<String>(a->get(1))->equals(String::create("1"))); ASSERT_TRUE(toCPtr<String>(a->get(2))->equals(String::create("23"))); Int index = -1; to<Int>(a->getProperty(String::create("index")), &index); ASSERT_EQ(0, index); String::CPtr input = toCPtr<String>(a->getProperty(String::create("input"))); ASSERT_TRUE(input->equals(String::create("1.23"))); ASSERT_FALSE(re->exec(String::create("1x23"))); ASSERT_FALSE(re->exec(String::create("v1.23"))); }
TEST(GTestStringBuffer, TestAppendManyTimes) { const char a[] = "abcde"; const char u[] = { 0xe7, 0x8c, 0xab, 0xe3, 0x81, 0xa8, 0xe6, 0x9a, 0xae, 0xe3, 0x82, 0x89, 0xe3, 0x81, 0x97, 0xe3, 0x81, 0x9f, 0xe3, 0x81, 0x84, // 猫と暮らしたい 0 }; String::CPtr s1 = String::create(a); String::CPtr s2 = String::create(u, String::UTF8); String::CPtr exp = String::create(""); StringBuffer::Ptr sb = StringBuffer::create(); for (int i = 0; i < 100; i++) { sb->append(s1); sb->append(s2); exp = exp->concat(s1)->concat(s2); } ASSERT_TRUE(sb->toString()->equals(exp)); }
String::CPtr percentEncode(String::CPtr str, String::Encoding enc) { static const Boolean isBigEndian = endian() == BIG; if (!str || str->length() == 0) return String::create(); Buffer::Ptr buf; switch (enc) { case String::UTF8: buf = Buffer::create(str, Buffer::UTF8); break; case String::UTF16: if (isBigEndian) { buf = Buffer::create(str, Buffer::UTF16BE); } else { buf = Buffer::create(str, Buffer::UTF16LE); } break; case String::UTF16BE: buf = Buffer::create(str, Buffer::UTF16BE); break; case String::UTF16LE: buf = Buffer::create(str, Buffer::UTF16LE); break; case String::UTF32: if (isBigEndian) { buf = Buffer::create(str, Buffer::UTF32BE); } else { buf = Buffer::create(str, Buffer::UTF32LE); } break; case String::UTF32BE: buf = Buffer::create(str, Buffer::UTF32BE); break; case String::UTF32LE: buf = Buffer::create(str, Buffer::UTF32LE); break; default: assert(false); buf = Buffer::null(); } Size sourceLen = buf->length(); const char* source = static_cast<const char*>(buf->data()); Size encodedLen = sourceLen * 3 + 1; char* encoded = new char[encodedLen]; percentEncode(encoded, encodedLen, source, sourceLen); String::CPtr res = String::create(encoded); delete[] encoded; return res; }
DiscoveryService::Ptr DiscoveryService::create( String::CPtr multicastAddr, Int port, UInt timeout) { LIBJ_STATIC_CONST_STRING_DEF(str239, "239."); if (net::isIPv4(multicastAddr) && multicastAddr->startsWith(str239) && port > 0) { return DiscoveryService::Ptr( new jsdp::detail::DiscoveryService(multicastAddr, port, timeout)); } else { return DiscoveryService::null(); } }
String::CPtr basename(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symNull, "null"); if (path) { path = trimSeps(path); } else { return symNull; } Size lastIndex = lastIndexOfSep(path); if (lastIndex == NO_POS) { return path; } else { return path->substring(lastIndex + 1); } }
String::CPtr dirname(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symCurrent, "."); if (!path) return symCurrent; path = trimSeps(path); String::CPtr base = basename(path); Size baseLen = base->length(); Size pathLen = path->length(); if (baseLen == pathLen) { return symCurrent; } else { Size sepPos = pathLen - baseLen - 1; assert(isSep(path->charAt(sepPos))); if (sepPos) { return path->substring(0, sepPos); } else { return path->substring(0, 1); } } }
String::CPtr normalize(String::CPtr path) { LIBJ_STATIC_SYMBOL_DEF(symCurrent, "."); LIBJ_STATIC_SYMBOL_DEF(symParent, ".."); LIBJ_STATIC_SYMBOL_DEF(symNull, "null"); if (!path) return symNull; Boolean absolute = false; Boolean endsWithSep = false; typedef TypedJsArray<String::CPtr> StringArray; StringArray::Ptr dirs = StringArray::create(); Size len = path->length(); for (Size i = 0; i < len;) { Size idx = indexOfSep(path, i); if (idx == 0) { absolute = true; } else if (idx != i) { String::CPtr dir; if (idx == NO_POS) { dir = path->substring(i); } else { dir = path->substring(i, idx); } if (dir->equals(symParent)) { Size numDirs = dirs->size(); if (numDirs > 0 && !dirs->getTyped(numDirs - 1)->equals(symParent)) { dirs->removeTyped(numDirs - 1); } else { dirs->addTyped(dir); } } else if (!dir->equals(symCurrent)) { dirs->addTyped(dir); } } if (idx == NO_POS) { endsWithSep = false; i = len; } else { endsWithSep = true; i = idx + 1; } } StringBuilder::Ptr normal = StringBuilder::create(); if (absolute) normal->appendChar(SEP); Size numDirs = dirs->size(); for (Size i = 0; i < numDirs; i++) { if (i) normal->appendChar(SEP); normal->appendStr(dirs->getTyped(i)); } if (numDirs > 0 && endsWithSep) normal->appendChar(SEP); if (normal->length() == 0) { return symCurrent; } else { return normal->toString(); } }
JsObject::Ptr parse(String::CPtr urlStr) { static const String::CPtr colon = String::create(":"); static const String::CPtr slash = String::create("/"); static const String::CPtr sharp = String::create("#"); static const String::CPtr question = String::create("?"); if (!urlStr) { LIBJ_NULL_PTR(JsObject, nullp); return nullp; } struct parsed_url* url = parse_url(urlStr->toStdString().c_str()); JsObject::Ptr obj = JsObject::create(); obj->put(HREF, urlStr); if (url->scheme) { obj->put(PROTOCOL, String::create(url->scheme)->toLowerCase()); } LIBJ_NULL_CPTR(String, port); if (url->port) { port = String::create(url->port); obj->put(PORT, port); } if (url->host) { String::CPtr hostname = String::create(url->host)->toLowerCase(); obj->put(HOSTNAME, hostname); if (port) { obj->put(HOST, hostname->concat(colon)->concat(port)); } else { obj->put(HOST, hostname); } } LIBJ_NULL_CPTR(String, query); if (url->query) { query = String::create(url->query); obj->put(QUERY, query); } if (url->path) { String::CPtr pathname = slash->concat(String::create(url->path)); obj->put(PATHNAME, pathname); if (query) { obj->put(PATH, pathname->concat(question)->concat(query)); } else { obj->put(PATH, pathname); } } if (url->username && url->password) { String::CPtr auth = String::create(url->username); auth = auth->concat(colon); auth = auth->concat(String::create(url->password)); obj->put(AUTH, auth); } if (url->fragment) { String::CPtr hash = sharp->concat(String::create(url->fragment)); obj->put(HASH, hash); } parsed_url_free(url); return obj; }
static inline Size lastIndexOfSep(String::CPtr str, Size from = NO_POS) { return str->lastIndexOf(SEP, from); }
static inline Size indexOfSep(String::CPtr str, Size from) { return str->indexOf(SEP, from); }
TEST(GTestQueryString, TestStringify) { JsObject::Ptr obj = JsObject::create(); String::CPtr query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create())); obj = JsObject::create(); obj->put(String::create("a"), String::create("b")); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("a=b"))); obj = JsObject::create(); obj->put(String::create("a"), String::create("b")); obj->put(String::create("x"), 1); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("a=b&x=1"))); obj = JsObject::create(); obj->put(String::create("a"), JsObject::create()); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("a="))); obj = JsObject::create(); obj->put(String::create("a"), JsArray::create()); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create())); obj = JsObject::create(); obj->put(String::create("a"), Object::null()); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("a="))); obj = JsObject::create(); obj->put(String::create("a"), UNDEFINED); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("a="))); obj = JsObject::create(); obj->put(String::create(), String::create()); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("="))); obj = JsObject::create(); obj->put(Object::null(), Object::null()); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("null="))); obj = JsObject::create(); JsArray::Ptr ary = JsArray::create(); ary->add(String::create("xyz")); ary->add(123); obj->put(UNDEFINED, ary); query = querystring::stringify(obj); ASSERT_TRUE(query->equals( String::create("undefined=xyz&undefined=123"))); obj = JsObject::create(); obj->put(String::create(" "), String::create(" ")); query = querystring::stringify(obj); ASSERT_TRUE(query->equals(String::create("%20=%20"))); }
JsObject::Ptr parse(String::CPtr urlStr) { if (!urlStr) return JsObject::null(); http_parser_url info; std::string str = urlStr->toStdString(); const char* cstr = str.c_str(); int r = http_parser_parse_url( cstr, str.length(), 0, &info); if (r) return JsObject::null(); String::CPtr scheme = getField(cstr, UF_SCHEMA, &info); String::CPtr host = getField(cstr, UF_HOST, &info); String::CPtr port = getField(cstr, UF_PORT, &info); String::CPtr path = getField(cstr, UF_PATH, &info); String::CPtr query = getField(cstr, UF_QUERY, &info); String::CPtr fragment = getField(cstr, UF_FRAGMENT, &info); String::CPtr userinfo = getField(cstr, UF_USERINFO, &info); JsObject::Ptr urlObj = JsObject::create(); // TODO(plenluno): protocol and host are lowercased urlObj->put(HREF, urlStr); if (scheme) { scheme = scheme->toLowerCase(); StringBuilder::Ptr sb = StringBuilder::create(); sb->appendStr(scheme); sb->appendChar(':'); urlObj->put(PROTOCOL, sb->toString()); } if (host) { host = host->toLowerCase(); urlObj->put(HOSTNAME, host); if (port) { StringBuilder::Ptr sb = StringBuilder::create(); sb->appendStr(host); sb->appendChar(':'); sb->appendStr(port); urlObj->put(HOST, sb->toString()); } else { urlObj->put(HOST, host); } } if (port) { urlObj->put(PORT, port); } if (path) { urlObj->put(PATHNAME, path); if (query) { StringBuilder::Ptr sb = StringBuilder::create(); sb->appendStr(path); sb->appendChar('?'); sb->appendStr(query); urlObj->put(PATH, sb->toString()); } else { urlObj->put(PATH, path); } } if (query) { urlObj->put(QUERY, query); StringBuilder::Ptr sb = StringBuilder::create(); sb->appendChar('?'); sb->appendStr(query); urlObj->put(SEARCH, sb->toString()); } if (fragment) { StringBuilder::Ptr sb = StringBuilder::create(); sb->appendChar('#'); sb->appendStr(fragment); urlObj->put(HASH, sb->toString()); } if (userinfo) { urlObj->put(AUTH, userinfo); } return urlObj; }