result_t net_base::connect(exlib::string url, int32_t timeout, obj_ptr<Stream_base>& retVal, AsyncEvent* ac) { if (!qstrcmp(url.c_str(), "ssl:", 4)) return ssl_base::connect(url, timeout, retVal, ac); if (qstrcmp(url.c_str(), "tcp:", 4)) return CHECK_ERROR(CALL_E_INVALIDARG); if (ac->isSync()) return CHECK_ERROR(CALL_E_NOSYNC); obj_ptr<Url> u = new Url(); result_t hr = u->parse(url); if (hr < 0) return hr; if (u->m_port.length() == 0) return CHECK_ERROR(CALL_E_INVALIDARG); int32_t nPort = atoi(u->m_port.c_str()); int32_t family = u->m_ipv6 ? net_base::_AF_INET6 : net_base::_AF_INET; obj_ptr<Socket_base> socket; hr = Socket_base::_new(family, net_base::_SOCK_STREAM, socket); if (hr < 0) return hr; socket->set_timeout(timeout); retVal = socket; return socket->connect(u->m_hostname, nPort, ac); }
result_t HttpCollection::parseCookie(exlib::string &str) { const char *pstr = str.c_str(); int32_t nSize = (int32_t) str.length(); const char *pstrTemp; exlib::string strKey, strValue; while (nSize) { while (nSize && *pstr == ' ') { pstr++; nSize--; } pstrTemp = pstr; while (nSize && *pstr != '=' && *pstr != ';') { pstr++; nSize--; } if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t) (pstr - pstrTemp), strKey, true); else strKey.clear(); if (nSize && *pstr == '=') { nSize--; pstr++; } pstrTemp = pstr; while (nSize && *pstr != ';') { pstr++; nSize--; } if (!strKey.empty()) { if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t) (pstr - pstrTemp), strValue, true); else strValue.clear(); } if (nSize) { nSize--; pstr++; } if (!strKey.empty()) add(strKey, strValue); } return 0; }
result_t X509Cert::get_serial(exlib::string &retVal) { mbedtls_x509_crt *crt = get_crt(); if (!crt) return CHECK_ERROR(CALL_E_INVALID_CALL); int32_t ret; mbedtls_mpi serial; mbedtls_mpi_init(&serial); ret = mbedtls_mpi_read_binary(&serial, crt->serial.p, crt->serial.len); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(8192); size_t sz = retVal.length(); ret = mbedtls_mpi_write_string(&serial, 10, &retVal[0], sz, &sz); mbedtls_mpi_free(&serial); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(sz - 1); return 0; }
result_t path_base::extname(exlib::string path, exlib::string &retVal) { char ch; const char *p1 = NULL; const char* c_str = path.c_str(); if (*c_str == '.') c_str++; while (*c_str) { ch = *c_str++; if (isPathSlash(ch)) { if (*c_str == '.') c_str++; p1 = NULL; } else if (ch == '.') p1 = c_str - 1; } if (p1) retVal.assign(p1, (int32_t) (c_str - p1)); return 0; }
result_t XmlParser::parse(XmlDocument* doc, exlib::string source) { XmlParser parser(doc, true); parser.m_now = doc; parser.m_list.push_back(doc); XML_Parser xml_parser = XML_ParserCreate(NULL); XML_SetParamEntityParsing(xml_parser, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); XML_SetUserData(xml_parser, &parser); XML_SetXmlDeclHandler(xml_parser, XmlDeclHandler); XML_SetElementHandler(xml_parser, StartElementHandler, EndElementHandler); XML_SetCharacterDataHandler(xml_parser, CharacterDataHandler); XML_SetProcessingInstructionHandler(xml_parser, ProcessingInstructionHandler); XML_SetCommentHandler(xml_parser, CommentHandler); XML_SetCdataSectionHandler(xml_parser, StartCdataSectionHandler, EndCdataSectionHandler); XML_SetStartDoctypeDeclHandler(xml_parser, StartDoctypeDeclHandler); if (XML_Parse(xml_parser, source.c_str(), (int32_t)source.length(), true) != XML_STATUS_OK) { char msg[128]; sprintf(msg, "XmlParser: error on line %lu at column %lu: %s", XML_GetCurrentLineNumber(xml_parser), XML_GetCurrentColumnNumber(xml_parser) + 1, XML_ErrorString(XML_GetErrorCode(xml_parser))); XML_ParserFree(xml_parser); return CHECK_ERROR(Runtime::setError(msg)); } XML_ParserFree(xml_parser); return 0; }
result_t XmlComment::toString(exlib::string &retVal) { retVal = "<!--"; retVal.append(m_data.data()); retVal.append("-->"); return 0; }
result_t Url::get_search(exlib::string& retVal) { if (m_query.length() > 0) { retVal.assign(1, '?'); retVal.append(m_query); } return 0; }
result_t SQLite::execute(exlib::string sql, obj_ptr<DBResult_base> &retVal, AsyncEvent *ac) { if (!m_db) return CHECK_ERROR(CALL_E_INVALID_CALL); if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); return execute(sql.c_str(), (int32_t) sql.length(), retVal); }
result_t X509Crl::load(exlib::string pemCrl) { int32_t ret; ret = mbedtls_x509_crl_parse(&m_crl, (const unsigned char *)pemCrl.c_str(), pemCrl.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
result_t fs_base::rename(exlib::string from, exlib::string to, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); if (::rename(from.c_str(), to.c_str())) return CHECK_ERROR(LastError()); return 0; }
result_t path_base::dirname(exlib::string path, exlib::string &retVal) { char ch; const char* c_str = path.c_str(); const char *p1 = c_str; const char *p2 = NULL; #ifdef _WIN32 if (c_str[0] != 0 && c_str[1] == ':') { c_str += 2; if (isPathSlash(*c_str)) c_str++; p2 = c_str; } else if (isPathSlash(c_str[0]) && isPathSlash(c_str[1])) { c_str += 2; while (*c_str && !isPathSlash(*c_str)) c_str++; if (*c_str) { c_str++; while (*c_str && !isPathSlash(*c_str)) c_str++; if (*c_str) c_str++; } p2 = c_str; } #endif while (*c_str) { ch = *c_str++; if (isPathSlash(ch) && *c_str) p2 = c_str - 1; } if (p2 == NULL) p2 = p1; if (isPathSlash(*p2) && p2 == p1) p2++; retVal.assign(p1, (int32_t) (p2 - p1)); return 0; }
result_t Url::get_href(exlib::string& retVal) { retVal.clear(); if (m_protocol.length() > 0) retVal.append(m_protocol); if (m_slashes) retVal.append("//", 2); exlib::string str; if (m_username.length() > 0) { get_auth(str); retVal.append(str); retVal.append(1, '@'); } get_host(str); retVal.append(str); get_path(str); retVal.append(str); retVal.append(m_hash); return 0; }
result_t Url::get_auth(exlib::string& retVal) { exlib::string str; encoding_base::encodeURIComponent(m_username, str); retVal = str; if (m_password.length() > 0) { retVal.append(1, ':'); encoding_base::encodeURIComponent(m_password, str); retVal.append(str); } return 0; }
result_t querystring_base::parse(exlib::string str, exlib::string sep, exlib::string eq, v8::Local<v8::Object> opt, obj_ptr<HttpCollection_base>& retVal) { result_t hr; obj_ptr<HttpCollection> c = new HttpCollection(); hr = c->parse(str, sep.c_str(), eq.c_str()); if (hr < 0) return hr; retVal = c; return 0; }
result_t net_base::isIPv6(exlib::string ip, bool& retVal) { result_t hr; retVal = true; const char* src = ip.c_str(); int len; char tmp[INET6_ADDRSTRLEN], *s, *p; unsigned char dst[sizeof(struct in6_addr)]; s = (char*)src; p = strchr(s, '%'); if (p != NULL) { s = tmp; len = (int32_t)(p - src); if (len > INET6_ADDRSTRLEN - 1) { retVal = false; return 0; } memcpy(s, src, len); s[len] = '\0'; } hr = inet_pton6(s, dst); if (hr != 0) retVal = false; return 0; }
result_t dns_base::resolve(exlib::string name, obj_ptr<NArray>& retVal, AsyncEvent* ac) { if (ac->isSync()) return CHECK_ERROR(CALL_E_LONGSYNC); addrinfo hints = { 0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0, 0 }; addrinfo* result = NULL; addrinfo* ptr = NULL; int res = getaddrinfo(name.c_str(), NULL, &hints, &result); if (res) return CHECK_ERROR(Runtime::setError(gai_strerror(res))); obj_ptr<NArray> arr = new NArray(); for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { inetAddr addr_info; addr_info.init(ptr->ai_addr); arr->append(addr_info.str()); } freeaddrinfo(result); retVal = arr; return 0; }
result_t fs_base::readTextFile(exlib::string fname, exlib::string& retVal, AsyncEvent* ac) { if (ac->isSync()) return CHECK_ERROR(CALL_E_NOSYNC); obj_ptr<SeekableStream_base> f; obj_ptr<Buffer_base> buf; result_t hr; hr = openFile(fname, "r", f, ac); if (hr < 0) return hr; hr = f->cc_readAll(buf); f->cc_close(); if (hr == CALL_RETURN_NULL) { retVal.clear(); return 0; } if (hr < 0) return hr; return buf->toString(retVal); }
inline result_t msgMethod(Message_base *msg, exlib::string &method) { exlib::string str; const char *p, *p1; msg->get_value(str); p = p1 = str.c_str(); while (true) { while (*p && *p != '.' && *p != '/' && *p != '\\') p++; if (p != p1) break; if (!*p) return CHECK_ERROR(Runtime::setError("JSHandler: method \"" + method + "\" not found.")); p++; p1 = p; } msg->set_value(*p ? p + 1 : ""); method.assign(p1, (int32_t) (p - p1)); return 0; }
result_t XmlElement::set_id(exlib::string newVal) { if (newVal.empty()) return removeAttribute("id"); return setAttribute("id", newVal); }
result_t path_base::fullpath(exlib::string path, exlib::string &retVal) { #ifdef _WIN32 exlib::wstring str = utf8to16String(path); exlib::wchar utf16_buffer[MAX_PATH]; DWORD utf16_len = GetFullPathNameW(str.c_str(), MAX_PATH, utf16_buffer, NULL); if (!utf16_len) return CHECK_ERROR(LastError()); retVal = utf16to8String(utf16_buffer, (int32_t)utf16_len); return 0; #else if (isPathSlash(path.c_str()[0])) return normalize(path, retVal); exlib::string str; process_base::cwd(str); str.append(1, PATH_SLASH); str.append(path); return normalize(str, retVal); #endif }
result_t fs_base::exists(exlib::string path, bool &retVal, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); retVal = access(path.c_str(), F_OK) == 0; return 0; }
result_t XmlElement::toString(exlib::string& retVal) { retVal = "<"; exlib::string tagName(m_tagName); if (!m_isXml) qstrlwr(&tagName[0]); if (m_prefix.empty()) { if (!m_namespaceURI.empty()) { bool skip_def_ns = false; if (m_parent) { int32_t type; m_parent->get_nodeType(type); if (type == xml_base::_ELEMENT_NODE) { exlib::string def_ns; ((XmlElement*)m_parent->m_node)->get_defaultNamespace(def_ns); if (def_ns == m_namespaceURI) skip_def_ns = true; } } if (!skip_def_ns) setAttribute("xmlns", m_namespaceURI); } retVal.append(tagName); } else { fix_prefix(m_namespaceURI, m_prefix); retVal.append(m_prefix); retVal += ':'; retVal.append(m_localName); } exlib::string strAttr; m_attrs->toString(strAttr); retVal.append(strAttr); if (m_childs->hasChildNodes()) { exlib::string strChild; m_childs->toString(strChild); retVal += '>'; retVal.append(strChild); retVal.append("</"); retVal.append(tagName); retVal += '>'; } else retVal.append("/>"); return 0; }
result_t os_base::time(exlib::string tmString, date_t& retVal) { if (tmString.empty()) retVal.now(); else retVal.parse(tmString); return 0; }
result_t base64vlq_base::decode(exlib::string data, v8::Local<v8::Array>& retVal) { static const char decodeTable[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, /* 2x !"#$%&'()*+,-./ */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 3x 0123456789:;<=>? */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 4x @ABCDEFGHIJKLMNO */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, /* 5X PQRSTUVWXYZ[\]^_ */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 6x `abcdefghijklmno */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 7X pqrstuvwxyz{\}~DEL */ }; const char* _data = data.c_str(); const char* end = _data + data.length(); int32_t cnt = 0; Isolate* isolate = Isolate::current(); retVal = v8::Array::New(isolate->m_isolate); while (_data < end) { uint32_t ch; int32_t bits = 0; int32_t num = 0; while ((ch = utf_getchar(_data, end)) != 0) { int32_t byte = (ch > 0x20 && ch < 0x80) ? decodeTable[ch - 0x20] : -1; if (byte != -1) { num += (byte & 0x1f) << (bits * 5); bits++; if (!(byte & 0x20)) break; } else break; } if (num & 1) num = -(num >> 1); else num = num >> 1; retVal->Set(cnt++, v8::Number::New(isolate->m_isolate, num)); }
result_t Stat::getStat(exlib::string path) { struct stat64 st; if (::stat64(path.c_str(), &st)) return CHECK_ERROR(LastError()); fill(path, st); return 0; }
result_t XmlElement::set_className(exlib::string newVal) { if (m_isXml) return CALL_E_INVALID_CALL; if (newVal.empty()) return removeAttribute("class"); return setAttribute("class", newVal); }
void Url::parseHost(const char*& url, exlib::string& hostname, exlib::string& port) { const char* p1 = url; const char* p2 = NULL; char ch; if (*p1 == '[') { p1++; while ((ch = *p1) && (qisxdigit(ch) || ch == ':' || ch == '.')) p1++; if (ch == ']') ch = *++p1; else url++; } else { while ((ch = *p1) && (qisascii(ch) || qisdigit(ch) || ch == '.' || ch == '_' || ch == '-' || ch < 0)) p1++; } if (ch == ':') { p2 = p1 + 1; while ((ch = *p2) && qisdigit(ch)) p2++; } if (*url == '[') hostname.assign(url + 1, p1 - url - 2); else hostname.assign(url, p1 - url); if (hostname.length() > 0) { qstrlwr(&hostname[0]); punycode_base::toASCII(hostname, hostname); } if (p2) port.assign(p1 + 1, p2 - p1 - 1); else port.clear(); url = p2 ? p2 : p1; }
result_t MongoCollection::runCommand(exlib::string cmd, exlib::string cmd1, exlib::string arg, v8::Local<v8::Object>& retVal) { obj_ptr<MongoDB> db(m_db); if (!db) return CHECK_ERROR(CALL_E_INVALID_CALL); bson bbq; bson_init(&bbq); bson_append_string(&bbq, cmd.c_str(), m_name.c_str()); if (!cmd1.empty()) bson_append_string(&bbq, cmd1.c_str(), arg.c_str()); bson_finish(&bbq); return db->bsonHandler(&bbq, retVal); }
result_t fs_base::rmdir(exlib::string path, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); if (::rmdir(path.c_str())) return CHECK_ERROR(LastError()); return 0; }
result_t fs_base::chmod(exlib::string path, int32_t mode, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); if (::chmod(path.c_str(), mode)) return CHECK_ERROR(LastError()); return 0; }