⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kurl.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    } else if (protocolIs("file")) {        result.append('/');        result.append('/');    }    append(result, path());    if (m_pathEnd != m_queryEnd) {        result.append('?');        append(result, query());    }    if (m_fragmentEnd != m_queryEnd) {        result.append('#');        append(result, ref());    }    return String::adopt(result);}String decodeURLEscapeSequences(const String& str){    return decodeURLEscapeSequences(str, UTF8Encoding());}String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding){    Vector<UChar> result;    CharBuffer buffer;    int length = str.length();    int decodedPosition = 0;    int searchPosition = 0;    int encodedRunPosition;    while ((encodedRunPosition = str.find('%', searchPosition)) >= 0) {        // Find the sequence of %-escape codes.        int encodedRunEnd = encodedRunPosition;        while (length - encodedRunEnd >= 3                && str[encodedRunEnd] == '%'                && isASCIIHexDigit(str[encodedRunEnd + 1])                && isASCIIHexDigit(str[encodedRunEnd + 2]))            encodedRunEnd += 3;        if (encodedRunEnd == encodedRunPosition) {            ++searchPosition;            continue;        }        searchPosition = encodedRunEnd;        // Decode the %-escapes into bytes.        unsigned runLength = (encodedRunEnd - encodedRunPosition) / 3;        buffer.resize(runLength);        char* p = buffer.data();        const UChar* q = str.characters() + encodedRunPosition;        for (unsigned i = 0; i < runLength; ++i) {            *p++ = (hexDigitValue(q[1]) << 4) | hexDigitValue(q[2]);            q += 3;        }        // Decode the bytes into Unicode characters.        String decoded = (encoding.isValid() ? encoding : UTF8Encoding()).decode(buffer.data(), p - buffer.data());        if (decoded.isEmpty())            continue;        // Build up the string with what we just skipped and what we just decoded.        result.append(str.characters() + decodedPosition, encodedRunPosition - decodedPosition);        result.append(decoded.characters(), decoded.length());        decodedPosition = encodedRunEnd;    }    result.append(str.characters() + decodedPosition, length - decodedPosition);    return String::adopt(result);}bool KURL::isLocalFile() const{    // Including feed here might be a bad idea since drag and drop uses this check    // and including feed would allow feeds to potentially let someone's blog    // read the contents of the clipboard on a drag, even without a drop.    // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function.    return protocolIs("file");}static void appendEscapingBadChars(char*& buffer, const char* strStart, size_t length){    char* p = buffer;    const char* str = strStart;    const char* strEnd = strStart + length;    while (str < strEnd) {        unsigned char c = *str++;        if (isBadChar(c)) {            if (c == '%' || c == '?') {                *p++ = c;            } else if (c != 0x09 && c != 0x0a && c != 0x0d) {                *p++ = '%';                *p++ = hexDigits[c >> 4];                *p++ = hexDigits[c & 0xF];            }        } else {            *p++ = c;        }    }    buffer = p;}// copy a path, accounting for "." and ".." segmentsstatic int copyPathRemovingDots(char* dst, const char* src, int srcStart, int srcEnd){    char* bufferPathStart = dst;    // empty path is a special case, and need not have a leading slash    if (srcStart != srcEnd) {        const char* baseStringStart = src + srcStart;        const char* baseStringEnd = src + srcEnd;        const char* baseStringPos = baseStringStart;        // this code is unprepared for paths that do not begin with a        // slash and we should always have one in the source string        ASSERT(baseStringPos[0] == '/');        // copy the leading slash into the destination        *dst = *baseStringPos;        baseStringPos++;        dst++;        while (baseStringPos < baseStringEnd) {            if (baseStringPos[0] == '.' && dst[-1] == '/') {                if (baseStringPos[1] == '/' || baseStringPos + 1 == baseStringEnd) {                    // skip over "." segment                    baseStringPos += 2;                    continue;                } else if (baseStringPos[1] == '.' && (baseStringPos[2] == '/' ||                                       baseStringPos + 2 == baseStringEnd)) {                    // skip over ".." segment and rewind the last segment                    // the RFC leaves it up to the app to decide what to do with excess                    // ".." segments - we choose to drop them since some web content                    // relies on this.                    baseStringPos += 3;                    if (dst > bufferPathStart + 1)                        dst--;                    // Note that these two while blocks differ subtly.                    // The first helps to remove multiple adjoining slashes as we rewind.                    // The +1 to bufferPathStart in the first while block prevents eating a leading slash                    while (dst > bufferPathStart + 1 && dst[-1] == '/')                        dst--;                    while (dst > bufferPathStart && dst[-1] != '/')                        dst--;                    continue;                }            }            *dst = *baseStringPos;            baseStringPos++;            dst++;        }    }    *dst = '\0';    return dst - bufferPathStart;}static inline bool hasSlashDotOrDotDot(const char* str){    const unsigned char* p = reinterpret_cast<const unsigned char*>(str);    if (!*p)        return false;    unsigned char pc = *p;    while (unsigned char c = *++p) {        if (c == '.' && (pc == '/' || pc == '.'))            return true;        pc = c;    }    return false;}static inline bool matchLetter(char c, char lowercaseLetter){    return (c | 0x20) == lowercaseLetter;}void KURL::parse(const String& string){    checkEncodedString(string);    CharBuffer buffer(string.length() + 1);    copyASCII(string.characters(), string.length(), buffer.data());    buffer[string.length()] = '\0';    parse(buffer.data(), &string);}void KURL::parse(const char* url, const String* originalString){    if (!url || url[0] == '\0') {        // valid URL must be non-empty        m_string = originalString ? *originalString : url;        invalidate();        return;    }    if (!isSchemeFirstChar(url[0])) {        // scheme must start with an alphabetic character        m_string = originalString ? *originalString : url;        invalidate();        return;    }    int schemeEnd = 0;    while (isSchemeChar(url[schemeEnd]))        schemeEnd++;    if (url[schemeEnd] != ':') {        m_string = originalString ? *originalString : url;        invalidate();        return;    }    int userStart = schemeEnd + 1;    int userEnd;    int passwordStart;    int passwordEnd;    int hostStart;    int hostEnd;    int portStart;    int portEnd;    bool hierarchical = url[schemeEnd + 1] == '/';    bool isFile = schemeEnd == 4        && matchLetter(url[0], 'f')        && matchLetter(url[1], 'i')        && matchLetter(url[2], 'l')        && matchLetter(url[3], 'e');    m_protocolInHTTPFamily = matchLetter(url[0], 'h')        && matchLetter(url[1], 't')        && matchLetter(url[2], 't')        && matchLetter(url[3], 'p')        && (url[4] == ':' || (matchLetter(url[4], 's') && url[5] == ':'));    if (hierarchical && url[schemeEnd + 2] == '/') {        // The part after the scheme is either a net_path or an abs_path whose first path segment is empty.        // Attempt to find an authority.        // FIXME: Authority characters may be scanned twice, and it would be nice to be faster.        userStart += 2;        userEnd = userStart;        int colonPos = 0;        while (isUserInfoChar(url[userEnd])) {            if (url[userEnd] == ':' && colonPos == 0)                colonPos = userEnd;            userEnd++;        }        if (url[userEnd] == '@') {            // actual end of the userinfo, start on the host            if (colonPos != 0) {                passwordEnd = userEnd;                userEnd = colonPos;                passwordStart = colonPos + 1;            } else                passwordStart = passwordEnd = userEnd;            hostStart = passwordEnd + 1;        } else if (url[userEnd] == '[' || isPathSegmentEndChar(url[userEnd])) {            // hit the end of the authority, must have been no user            // or looks like an IPv6 hostname            // either way, try to parse it as a hostname            userEnd = userStart;            passwordStart = passwordEnd = userEnd;            hostStart = userStart;        } else {            // invalid character            m_string = originalString ? *originalString : url;            invalidate();            return;        }        hostEnd = hostStart;        // IPV6 IP address        if (url[hostEnd] == '[') {            hostEnd++;            while (isIPv6Char(url[hostEnd]))                hostEnd++;            if (url[hostEnd] == ']')                hostEnd++;            else {                // invalid character                m_string = originalString ? *originalString : url;                invalidate();                return;            }        } else {            while (isHostnameChar(url[hostEnd]))                hostEnd++;        }                if (url[hostEnd] == ':') {            portStart = portEnd = hostEnd + 1;             // possible start of port            portEnd = portStart;            while (isASCIIDigit(url[portEnd]))                portEnd++;        } else            portStart = portEnd = hostEnd;        if (!isPathSegmentEndChar(url[portEnd])) {            // invalid character            m_string = originalString ? *originalString : url;            invalidate();            return;        }        if (userStart == portEnd && !m_protocolInHTTPFamily && !isFile) {            // No authority found, which means that this is not a net_path, but rather an abs_path whose first two            // path segments are empty. For file, http and https only, an empty authority is allowed.            userStart -= 2;            userEnd = userStart;            passwordStart = userEnd;            passwordEnd = passwordStart;            hostStart = passwordEnd;            hostEnd = hostStart;            portStart = hostEnd;            portEnd = hostEnd;        }    } else {        // the part after the scheme must be an opaque_part or an abs_path        userEnd = userStart;        passwordStart = passwordEnd = userEnd;        hostStart = hostEnd = passwordEnd;        portStart = portEnd = hostEnd;    }    int pathStart = portEnd;    int pathEnd = pathStart;    while (url[pathEnd] && url[pathEnd] != '?' && url[pathEnd] != '#')        pathEnd++;    int queryStart = pathEnd;    int queryEnd = queryStart;    if (url[queryStart] == '?') {        while (url[queryEnd] && url[queryEnd] != '#')            queryEnd++;    }    int fragmentStart = queryEnd;    int fragmentEnd = fragmentStart;    if (url[fragmentStart] == '#') {        fragmentStart++;        fragmentEnd = fragmentStart;        while (url[fragmentEnd])            fragmentEnd++;    }    // assemble it all, remembering the real ranges    Vector<char, 4096> buffer(fragmentEnd * 3 + 1);    char *p = buffer.data();    const char *strPtr = url;    // copy in the scheme    const char *schemeEndPtr = url + schemeEnd;    while (strPtr < schemeEndPtr)        *p++ = *strPtr++;    m_schemeEnd = p - buffer.data();    bool hostIsLocalHost = portEnd - userStart == 9        && matchLetter(url[userStart], 'l')        && matchLetter(url[userStart+1], 'o')        && matchLetter(url[userStart+2], 'c')        && matchLetter(url[userStart+3], 'a')        && matchLetter(url[userStart+4], 'l')        && matchLetter(url[userStart+5], 'h')        && matchLetter(url[userStart+6], 'o')        && matchLetter(url[userStart+7], 's')        && matchLetter(url[userStart+8], 't');    // File URLs need a host part unless it is just file:// or file://localhost    bool degenFilePath = pathStart == pathEnd && (hostStart == hostEnd || hostIsLocalHost);    bool haveNonHostAuthorityPart = userStart != userEnd || passwordStart != passwordEnd || portStart != portEnd;    // add ":" after scheme    *p++ = ':';    // if we have at least one authority part or a file URL - add "//" and authority    if (isFile ? !degenFilePath : (haveNonHostAuthorityPart || hostStart != hostEnd)) {        *p++ = '/';        *p++ = '/';        m_userStart = p - buffer.data();        // copy in the user        strPtr = url + userStart;        const char* userEndPtr = url + userEnd;        while (strPtr < userEndPtr)            *p++ = *strPtr++;        m_userEnd = p - buffer.data();        // copy in the password        if (passwordEnd != passwordStart) {            *p++ = ':';            strPtr = url + passwordStart;            const char* passwordEndPtr = url + passwordEnd;            while (strPtr < passwordEndPtr)                *p++ = *strPtr++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -