uri.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,303 行 · 第 1/3 页

CPP
1,303
字号
    // authority     = [ userinfo "@" ] host [ ":" port ]
    if (*uri == wxT('/') && *(uri+1) == wxT('/'))
    {
        //skip past the two slashes
        uri += 2;

        // ############# DEVIATION FROM RFC #########################
        // Don't parse the server component for file URIs
        if(m_scheme != wxT("file"))
        {
            //normal way
        uri = ParseUserInfo(uri);
        uri = ParseServer(uri);
        return ParsePort(uri);
        }
    }

    return uri;
}

const wxChar* wxURI::ParseUserInfo(const wxChar* uri)
{
    wxASSERT(uri != NULL);

    //copy of the uri - used for figuring out
    //length of each component
    const wxChar* uricopy = uri;

    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
    while(*uri && *uri != wxT('@') && *uri != wxT('/') && *uri != wxT('#') && *uri != wxT('?'))
    {
        if(IsUnreserved(*uri) ||
           IsSubDelim(*uri) || *uri == wxT(':'))
            m_userinfo += *uri++;
        else if (IsEscape(uri))
        {
            m_userinfo += *uri++;
            m_userinfo += *uri++;
            m_userinfo += *uri++;
        }
        else
            Escape(m_userinfo, *uri++);
    }

    if(*uri == wxT('@'))
    {
        //valid userinfo
        m_fields |= wxURI_USERINFO;

        uricopy = ++uri;
    }
    else
        m_userinfo = wxEmptyString;

    return uricopy;
}

const wxChar* wxURI::ParseServer(const wxChar* uri)
{
    wxASSERT(uri != NULL);

    //copy of the uri - used for figuring out
    //length of each component
    const wxChar* uricopy = uri;

    // host          = IP-literal / IPv4address / reg-name
    // IP-literal    = "[" ( IPv6address / IPvFuture  ) "]"
    if (*uri == wxT('['))
    {
        ++uri; //some compilers don't support *&ing a ++*
        if (ParseIPv6address(uri) && *uri == wxT(']'))
        {
            ++uri;
            m_hostType = wxURI_IPV6ADDRESS;

            wxStringBufferLength theBuffer(m_server, uri - uricopy);
            wxTmemcpy(theBuffer, uricopy, uri-uricopy);
            theBuffer.SetLength(uri-uricopy);
        }
        else
        {
            uri = uricopy;

            ++uri; //some compilers don't support *&ing a ++*
            if (ParseIPvFuture(uri) && *uri == wxT(']'))
            {
                ++uri;
                m_hostType = wxURI_IPVFUTURE;

                wxStringBufferLength theBuffer(m_server, uri - uricopy);
                wxTmemcpy(theBuffer, uricopy, uri-uricopy);
                theBuffer.SetLength(uri-uricopy);
            }
            else
                uri = uricopy;
        }
    }
    else
    {
        if (ParseIPv4address(uri))
        {
            m_hostType = wxURI_IPV4ADDRESS;

            wxStringBufferLength theBuffer(m_server, uri - uricopy);
            wxTmemcpy(theBuffer, uricopy, uri-uricopy);
            theBuffer.SetLength(uri-uricopy);
        }
        else
            uri = uricopy;
    }

    if(m_hostType == wxURI_REGNAME)
    {
        uri = uricopy;
        // reg-name      = *( unreserved / pct-encoded / sub-delims )
        while(*uri && *uri != wxT('/') && *uri != wxT(':') && *uri != wxT('#') && *uri != wxT('?'))
        {
            if(IsUnreserved(*uri) ||  IsSubDelim(*uri))
                m_server += *uri++;
            else if (IsEscape(uri))
            {
                m_server += *uri++;
                m_server += *uri++;
                m_server += *uri++;
            }
            else
                Escape(m_server, *uri++);
        }
    }

    //mark the server as valid
    m_fields |= wxURI_SERVER;

    return uri;
}


const wxChar* wxURI::ParsePort(const wxChar* uri)
{
    wxASSERT(uri != NULL);

    // port          = *DIGIT
    if(*uri == wxT(':'))
    {
        ++uri;
        while(IsDigit(*uri))
        {
            m_port += *uri++;
        }

        //mark the port as valid
        m_fields |= wxURI_PORT;
    }

    return uri;
}

const wxChar* wxURI::ParsePath(const wxChar* uri, bool bReference, bool bNormalize)
{
    wxASSERT(uri != NULL);

    //copy of the uri - used for figuring out
    //length of each component
    const wxChar* uricopy = uri;

    /// hier-part     = "//" authority path-abempty
    ///               / path-absolute
    ///               / path-rootless
    ///               / path-empty
    ///
    /// relative-part = "//" authority path-abempty
    ///               / path-absolute
    ///               / path-noscheme
    ///               / path-empty
    ///
    /// path-abempty  = *( "/" segment )
    /// path-absolute = "/" [ segment-nz *( "/" segment ) ]
    /// path-noscheme = segment-nz-nc *( "/" segment )
    /// path-rootless = segment-nz *( "/" segment )
    /// path-empty    = 0<pchar>
    ///
    /// segment       = *pchar
    /// segment-nz    = 1*pchar
    /// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
    ///               ; non-zero-length segment without any colon ":"
    ///
    /// pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
    if (*uri == wxT('/'))
    {
        m_path += *uri++;

        while(*uri && *uri != wxT('#') && *uri != wxT('?'))
        {
            if( IsUnreserved(*uri) || IsSubDelim(*uri) ||
                *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
                m_path += *uri++;
            else if (IsEscape(uri))
            {
                m_path += *uri++;
                m_path += *uri++;
                m_path += *uri++;
            }
            else
                Escape(m_path, *uri++);
        }

        if (bNormalize)
        {
            wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
#if wxUSE_STL
            wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
#endif
            Normalize(theBuffer, true);
            theBuffer.SetLength(wxStrlen(theBuffer));
        }
        //mark the path as valid
        m_fields |= wxURI_PATH;
    }
    else if(*uri) //Relative path
    {
        if (bReference)
        {
            //no colon allowed
            while(*uri && *uri != wxT('#') && *uri != wxT('?'))
            {
                if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
                  *uri == wxT('@') || *uri == wxT('/'))
                    m_path += *uri++;
                else if (IsEscape(uri))
                {
                    m_path += *uri++;
                    m_path += *uri++;
                    m_path += *uri++;
                }
                else
                    Escape(m_path, *uri++);
            }
        }
        else
        {
            while(*uri && *uri != wxT('#') && *uri != wxT('?'))
            {
                if(IsUnreserved(*uri) || IsSubDelim(*uri) ||
                   *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/'))
                    m_path += *uri++;
                else if (IsEscape(uri))
                {
                    m_path += *uri++;
                    m_path += *uri++;
                    m_path += *uri++;
                }
                else
                    Escape(m_path, *uri++);
            }
        }

        if (uri != uricopy)
        {
            if (bNormalize)
            {
                wxStringBufferLength theBuffer(m_path, m_path.length() + 1);
#if wxUSE_STL
                wxTmemcpy(theBuffer, m_path.c_str(), m_path.length()+1);
#endif
                Normalize(theBuffer);
                theBuffer.SetLength(wxStrlen(theBuffer));
            }

            //mark the path as valid
            m_fields |= wxURI_PATH;
        }
    }

    return uri;
}


const wxChar* wxURI::ParseQuery(const wxChar* uri)
{
    wxASSERT(uri != NULL);

    // query         = *( pchar / "/" / "?" )
    if (*uri == wxT('?'))
    {
        ++uri;
        while(*uri && *uri != wxT('#'))
        {
            if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
                *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
                  m_query += *uri++;
            else if (IsEscape(uri))
            {
                  m_query += *uri++;
                  m_query += *uri++;
                  m_query += *uri++;
            }
            else
                  Escape(m_query, *uri++);
        }

        //mark the server as valid
        m_fields |= wxURI_QUERY;
    }

    return uri;
}


const wxChar* wxURI::ParseFragment(const wxChar* uri)
{
    wxASSERT(uri != NULL);

    // fragment      = *( pchar / "/" / "?" )
    if (*uri == wxT('#'))
    {
        ++uri;
        while(*uri)
        {
            if (IsUnreserved(*uri) || IsSubDelim(*uri) ||
                *uri == wxT(':') || *uri == wxT('@') || *uri == wxT('/') || *uri == wxT('?'))
                  m_fragment += *uri++;
            else if (IsEscape(uri))
            {
                  m_fragment += *uri++;
                  m_fragment += *uri++;
                  m_fragment += *uri++;
            }
            else
                  Escape(m_fragment, *uri++);
        }

        //mark the server as valid
        m_fields |= wxURI_FRAGMENT;
    }

    return uri;
}

// ---------------------------------------------------------------------------
// Resolve
//
// Builds missing components of this uri from a base uri
//
// A version of the algorithm outlined in the RFC is used here
// (it is shown in comments)
//
// Note that an empty URI inherits all components
// ---------------------------------------------------------------------------

void wxURI::Resolve(const wxURI& base, int flags)
{
    wxASSERT_MSG(!base.IsReference(),
                wxT("wxURI to inherit from must not be a reference!"));

    // If we arn't being strict, enable the older (pre-RFC2396)
    // loophole that allows this uri to inherit other
    // properties from the base uri - even if the scheme
    // is defined
    if ( !(flags & wxURI_STRICT) &&
            HasScheme() && base.HasScheme() &&
                m_scheme == base.m_scheme )
    {
        m_fields -= wxURI_SCHEME;
    }


    // Do nothing if this is an absolute wxURI
    //    if defined(R.scheme) then
    //       T.scheme    = R.scheme;
    //       T.authority = R.authority;
    //       T.path      = remove_dot_segments(R.path);
    //       T.query     = R.query;
    if (HasScheme())
    {
        return;
    }

    //No scheme - inherit
    m_scheme = base.m_scheme;
    m_fields |= wxURI_SCHEME;

    // All we need to do for relative URIs with an
    // authority component is just inherit the scheme
    //       if defined(R.authority) then
    //          T.authority = R.authority;
    //          T.path      = remove_dot_segments(R.path);
    //          T.query     = R.query;
    if (HasServer())
    {
        return;
    }

    //No authority - inherit
    if (base.HasUserInfo())
    {
        m_userinfo = base.m_userinfo;
        m_fields |= wxURI_USERINFO;
    }

    m_server = base.m_server;
    m_hostType = base.m_hostType;
    m_fields |= wxURI_SERVER;

    if (base.HasPort())
    {
        m_port = base.m_port;
        m_fields |= wxURI_PORT;
    }


    // Simple path inheritance from base
    if (!HasPath())
    {
        //             T.path = Base.path;
        m_path = base.m_path;
        m_fields |= wxURI_PATH;


        //             if defined(R.query) then
        //                T.query = R.query;
        //             else
        //                T.query = Base.query;
        //             endif;
        if (!HasQuery())
        {
            m_query = base.m_query;
            m_fields |= wxURI_QUERY;
        }
    }
    else
    {
        //             if (R.path starts-with "/") then
        //                T.path = remove_dot_segments(R.path);
        //             else
        //                T.path = merge(Base.path, R.path);

⌨️ 快捷键说明

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