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

📄 kwqkurl.cpp

📁 最新Nokia手机浏览器全套源代码完美版。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
void KURL::setPath(const QString &s)
{
    if (m_isValid) {

      // TODO: since encode_string is not implemented becuase utf8 is not implemented,
      // just skip the encode_string for now, need to change back when utf8 is implemented.
  QString newURL = urlString.left(portEndPos) + /*encode_string(s)*/s + urlString.mid(pathEndPos);
  parse(newURL.ascii(), &newURL);
    }
}

QString KURL::canonicalURL() const
{
#ifdef CONSTRUCT_CANONICAL_STRING
    bool hadPrePathComponent = false;
    QString canonicalURL;

    if (!protocol().isEmpty()) {
        canonicalURL += protocol();
        canonicalURL += "://";
        hadPrePathComponent = true;
    }
    if (!_user().isEmpty()) {
        canonicalURL += _user();
        if (!_pass().isEmpty()){
            canonicalURL += ":";
            canonicalURL += _pass();
        }
        canonicalURL += "@";
        hadPrePathComponent = true;
    }
    if (!_host().isEmpty()) {
        canonicalURL += _host();
        unsigned short int p = port();
        if (p != 0) {
            canonicalURL += ":";
            canonicalURL += QString::number(p);
        }
        hadPrePathComponent = true;
    }
    if (hadPrePathComponent && (strncasecmp ("http", url, schemeEnd) == 0 ||
        strncasecmp ("https", url, schemeEnd) == 0) && _path().isEmpty()) {
        canonicalURL += "/";
    }
    if (!_path().isEmpty()) {
        canonicalURL += _path();
    }
    if (!query().isEmpty()) {
        canonicalURL += "?";
        canonicalURL += query();
    }
    if (!ref().isEmpty()) {
        canonicalURL += "#";
        canonicalURL += ref();
    }
    return canonicalURL;
#else
    return urlString;
#endif
}


QString KURL::prettyURL() const
{
    if (!m_isValid) {
        return urlString;
    }

    QString result = protocol() + ":";

    QString authority;

    if (hostEndPos != passwordEndPos) {
  if (userEndPos != userStartPos) {
      authority += user();
      authority += "@";
  }
  authority += host();
  if (port() != 0) {
      authority += ":";
      authority += QString::number(port());
  }
    }

    if (!authority.isEmpty()) {
        result += "//" + authority;
    }

    result += path();
    result += query();

    if (fragmentEndPos != queryEndPos) {
        result += "#" + ref();
    }

    return result;
}

QString KURL::decode_string(const QString &urlString, const QTextCodec *codec)
{
    static const QTextCodec UTF8Codec(KCharacterSetIdentifierUtf8);

    QString result("");

    char staticBuffer[256];
    char *buffer = staticBuffer;
    int bufferLength = sizeof(staticBuffer);

    int length = urlString.length();
    int decodedPosition = 0;
    int searchPosition = 0;
    int encodedRunPosition;
    while ((encodedRunPosition = urlString.find('%', searchPosition)) > 0) {
        // Find the sequence of %-escape codes.
        int encodedRunEnd = encodedRunPosition;
        while (length - encodedRunEnd >= 3
                && urlString[encodedRunEnd] == '%'
                && isHexDigit(urlString[encodedRunEnd + 1].latin1())
                && isHexDigit(urlString[encodedRunEnd + 2].latin1()))
            encodedRunEnd += 3;
        if (encodedRunEnd == encodedRunPosition) {
            ++searchPosition;
            continue;
        }
        searchPosition = encodedRunEnd;

        // Copy the entire %-escape sequence into an 8-bit buffer.
        int encodedRunLength = encodedRunEnd - encodedRunPosition;
        if (encodedRunLength + 1 > bufferLength) {
            if (buffer != staticBuffer)
#ifndef __OOM__
        free(buffer);
#else
      MemoryManager::Free( buffer );
#endif
            bufferLength = malloc_good_size(encodedRunLength + 1);
#ifndef __OOM__
            buffer = static_cast<char *>(malloc(bufferLength));
#else
            buffer = static_cast<char *>(MemoryManager::Alloc(bufferLength));
#endif
        }
        urlString.copyLatin1(buffer, encodedRunPosition, encodedRunLength);

        // Decode the %-escapes into bytes.
        char *p = buffer;
        const char *q = buffer;
        while (*q) {
            *p++ = (hexDigitValue(q[1]) << 4) | hexDigitValue(q[2]);
            q += 3;
        }

        // Decode the bytes into Unicode characters.
        QString decoded = (codec ? codec : &UTF8Codec)->toUnicode(buffer, p - buffer);
        if (decoded.isEmpty()) {
            continue;
        }

        // Build up the string with what we just skipped and what we just decoded.
        result.append(urlString.mid(decodedPosition, encodedRunPosition - decodedPosition));
        result.append(decoded);
        decodedPosition = encodedRunEnd;
    }

    result.append(urlString.mid(decodedPosition, length - decodedPosition));

    if (buffer != staticBuffer)
#ifndef __OOM__
        free(buffer);
#else
      MemoryManager::Free( buffer );
#endif

    return result;
}

bool KURL::isLocalFile() const
{
    // FIXME - include feed: here too?
    return protocol() == "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 == '%' && strEnd - str >= 2 && isHexDigit(str[0]) && isHexDigit(str[1])) {
                *p++ = c;
                *p++ = *str++;
                *p++ = *str++;
            } else if (c == '?') {
                *p++ = c;
            } else {
                *p++ = '%';
                *p++ = hexDigits[c >> 4];
                *p++ = hexDigits[c & 0xF];
            }
  } else {
      *p++ = c;
  }
    }

    buffer = p;
}

// copy a path, accounting for "." and ".." segments
static 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 char *p = str;
    if (!*p)
        return false;
    char pc = *p;
    while (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 char *url, const QString *originalString)
{
    m_isValid = true;

    if (url == NULL || url[0] == '\0') {
  // valid URL must be non-empty
  m_isValid = false;
  urlString = url;
  return;
    }

    if (!isSchemeFirstChar(url[0])) {
  // scheme must start with an alphabetic character
  m_isValid = false;
  urlString = url;
  return;
    }

    int schemeEnd = 0;

    while (isSchemeChar(url[schemeEnd])) {
  schemeEnd++;
    }

    if (url[schemeEnd] != ':') {
  m_isValid = false;
  urlString = url;
  return;
    }

    int userStart = schemeEnd + 1;
    int userEnd;
    int passwordStart;
    int passwordEnd;
    int hostStart;
    int hostEnd;
    int portStart;
    int portEnd;

    bool hierarchical = url[schemeEnd + 1] == '/';

    if (hierarchical && url[schemeEnd + 2] == '/') {
  // part after the scheme must be a net_path, parse the authority section

  // FIXME: authority characters may be scanned twice
  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_isValid = false;
      urlString = url;

      return;
  }

  hostEnd = hostStart;

  // IPV6 IP address
  if (url[hostEnd] == '[') {
      hostEnd++;
      while (isIPv6Char(url[hostEnd])) {
    hostEnd++;
      }

      if (url[hostEnd] == ']') {
    hostEnd++;
      } else {
    // invalid character
    m_isValid = false;
    urlString = url;

    return;
      }
  } else {
      while (isHostnameChar(url[hostEnd])) {
    hostEnd++;
      }

  }

  if (url[hostEnd] == ':') {
      portStart = portEnd = hostEnd + 1;

      // possible start of port
      portEnd = portStart;
      while (isdigit(url[portEnd])) {
    portEnd++;
      }

  } else {
      portStart = portEnd = hostEnd;
  }

  if (!isPathSegmentEndChar(url[portEnd])) {
      // invalid character
      m_isValid = false;
      urlString = url;
      return;
  }
    } 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;
    int queryStart;
    int queryEnd;
    int fragmentStart;
    int fragmentEnd;

    if (!hierarchical) {
        while (url[pathEnd] != '\0' && url[pathEnd] != '?') {
            pathEnd++;
        }

      queryStart = queryEnd = pathEnd;

        while (url[queryEnd] != '\0') {
            queryEnd++;
        }

      fragmentStart = fragmentEnd = queryEnd;
    }
    else {
        while (url[pathEnd] != '\0' && url[pathEnd] != '?' && url[pathEnd] != '#') {
            pathEnd++;

⌨️ 快捷键说明

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