Qt-Function-QWebFrame->load()_04

来源:互联网 发布:手机编程软件大全 编辑:程序博客网 时间:2024/06/02 01:55

接03。http://blog.csdn.net/binzhouweichao/article/details/8101190

2012.10.23 于济南

qwebview.cpp中load2的内容,关于rawHeader部分。

    QList<QByteArray> httpHeaders = req.rawHeaderList();    for (int i = 0; i < httpHeaders.size(); ++i) {        const QByteArray &headerName = httpHeaders.at(i);        request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));    }

先说一下QList。从技术文档说起。

QList<T>,T是Type的缩写,也就是类型,是Qt的通用容器类。它存储了一些列的值,提供基于索引(index-based)的快速访问、插入、移动。QList就相当与一个数组,只不过它每个元素均为T类型,例如:

QList<QString> list; list << "one" << "two" << "three"; // list: ["one", "two", "three"]

list的第一个元素就是"one",第二个为"two",第三个是"three"。而且不用提前声明元素个数,相当与vector,动态大小。需要说明,其元素位置下标与数组相同,均从0开始。其元素的个数使用方法size(),某位置的元素使用方法at()来查看或者赋值(也可以使用方括号[],不如使用at()快)。

再说一下QByteArray,类似于QString却优于QString。QByteArray可以存储raw bytes(包含多个‘\0’空字符)和传统的8bit '\0'-终结字符(应该是指string以'\0'作为结束标志,而QByteArray突破了这个限制,可以包含多个)。使用QByteArray比使用char * 更方便。QByteArray可以用于存储raw binary数据。QByteArray的大小可以使用resize重新定义,元素的存取可以使用at(),也可以使用方括号,不如at()快。其元素单位是8bit(?貌似是一个char)。先说这些,来看具体的程序。

第1行,定义一个以QByteArray为类型的QList,命名为httpHeaders,初始化为req.rawHeaderList()。我们需要了解一下这个rawHeaderList(),req是QNetworkRequest的对象,如果找不到再去QNetworkRequestBase中查找。

QList<QByteArray> QNetworkRequest::rawHeaderList() const{    return d->rawHeadersKeys();}

这个d,是类QNetworkRequest的友元类QNetworkRequestPrivate的implicitly共享对象。在构造QNetworkRequest对象时初始化d。其具体的意义目前我也搞不懂。

再跳到rawHearsKeys():

QList<QByteArray> QNetworkHeadersPrivate::rawHeadersKeys() const{    QList<QByteArray> result;    RawHeadersList::ConstIterator it = rawHeaders.constBegin(),                                 end = rawHeaders.constEnd();    for ( ; it != end; ++it)        result << it->first;    return result;}

RawHeadersList是QList<RawHeaderPair>的typedef,也就是说,RawHeaderList声明的对象,是QList,元素类型是RawHeaderPair。而RawHeaderPair是QPair<QByteArray, QByteArray>的typedef。QPair<T1, T2>存储了两个类型T1、T2的Values,也可以认为是容器。调用的时候,使用first调用的是第一个类型T1的值,使用second调用的是第二个类型T2的值,例如:

QPair<QString, double> pair;pair.first = "pi";pair.second = 3.14159265358979323846;

由于RawHeadersList是QList类型,则ConstIterator也是QList中的类。发现ConstIterator是const_iterator的typedef。关于其用法可以参考技术文档中的例子:

 QList<QString> list; list.append("January"); list.append("February"); ... list.append("December"); QList<QString>::const_iterator i; for (i = list.constBegin(); i != list.constEnd(); ++i)     cout << *i << endl;

这样,我们回到源代码中,变量rawHeaders是RawHeaderList类型对象,也是QList,那么整段程序就是:将rawHeaders中的元素从开始到结束挨个送给result(也是QList),只传送QPair对的第一个类型的值(first)。最后将结果result返回给此函数值。

这里,我们需要知道变量rawHeaders中存放的东西是什么(只看QPair对的第一部分即可)。我们只找对rawHeaders赋值的地方。

第一个地方是在QNetworkRequestPrivate构造函数里,rawHeaders = other.rawHeaders。这个other也不明朗。

第二个地方是在函数setAllRawHeaders()中,rawHeader = list,何处被调用也不知道。

第三个地方是在函数setRawHeaderInternal()中,在原有基础上后缀附加,rawHeaders.appen(pair),也不清楚调用的地方。同一函数内,还有个rawHeaders.erase()。

要想了解rawHeader这些操作,必须将调用的地方找到。。。不然没有明确的实参。


回到qwebframe.cpp中查看对httpHeaders的操作。

先看for循环,遍历整个QList,元素单位是QByteArray,也就是rawHeaders中的first的单位。将元素放入QByteArray &headerName中,具体看一下addHTTPHeaderField()。

是父类ResourceRequestBase中的函数:

void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value) {    updateResourceRequest();    pair<HTTPHeaderMap::iterator, bool> result = m_httpHeaderFields.add(name, value);     if (!result.second)        result.first->second += "," + value;    if (url().protocolInHTTPFamily())        m_platformRequestUpdated = false;}

第1行,更新ResourceRequest。

第2行,定义pair类型的对象result,pair相当与QPair,两个类型,两个值。m_httpHeaderFields是类HTTPHeaderMap的对象,属于WebCore部分,没有文档,应该是header的映射表。add()是这个类的成员方法,调用的是类HashMap的成员add(),线索中断。通过函数表面和入口形参,我们可以目测result两部分的内容,第一部分就是name,此name应该是http协议中header中列举的各名称,第二部分应该是value,是header中对应的value值,类型是string。

来看下面的if判断,如果result.second为假,也就是没有,目测是value值没有,那么就在result.first的第二部分中添加逗号和value。这部分具体操作还得等到将add()找到后才清楚。

最后是设置更新标志为false,也就是当调用platform的更新函数时,就需要更新。

在此,我们只能目测该函数实现的功能是,将name和value添加到header中,也就是对象request的header域依次添加上httpHeaders的rawHeader,按照name value的方式添加(两者之间是用逗号还是空格还是冒号分隔暂不清楚,http协议中是使用冒号分开的)。


总结一下,此段程序就是将引用对象req的rawHeaderList()添加到对象request的HTTPHeader域。


下一部分分析body域。

原创粉丝点击