Query.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "Query.h"
00025 
00026 using namespace Gnutella::Packets;
00027 
00029 enum Constants
00030 {
00031     MinimalPayloadLength = 3,   
00032     DefaultQueryTtl = 4         
00033 };
00034 
00038 Query::Query (const QByteArray &rawHeader, const QByteArray &rawPayload)
00039     : Packet (rawHeader, rawPayload)
00040 {
00041     parse();
00042 }
00043 
00044 Query::Query (const QString &searchCriteria, quint16 minimumSpeed)
00045     : Packet (QueryDescriptor)
00046 {
00047     setTtl (DefaultQueryTtl);   // May become obsolete with dynamic quering.
00048     setSearchCriteria (searchCriteria);
00049     setMinimumSpeed (minimumSpeed);
00050 }
00051 
00052 Query::~Query()
00053 {
00054 }
00055 
00056 bool Query::prepareReadPayload (const QByteArray &rawPayload)
00057 {
00058     int payloadLength = rawPayload.length();
00059     if (payloadLength < MinimalPayloadLength)
00060         return false;
00061 
00062     int i = 0;
00063     for (i = 2; i < payloadLength; i++)
00064         if (rawPayload.at (i) == 0)
00065             break;
00066     if (i == payloadLength) // No '\0' was found.
00067         return false;
00068 
00069     p.rawSearchCriteria.resize (i + 1 - 2); // include the zero, but not the min speed field.
00070 
00071     // Everything after the '\0' is query data.
00072     int rawQueryDataSize = payloadLength - i - 1;
00073     // Some servents may terminate the extension block with a zero.
00074     if (rawPayload.at (payloadLength - 1) == 0)
00075         rawQueryDataSize--;
00076 
00077     QByteArray rawQueryData = QByteArray::fromRawData (rawPayload.data() + i + 1, rawQueryDataSize);
00078     p.queryData.prepareRead (rawQueryData);
00079     return true;
00080 }
00081 
00082 void Query::readPayload (QDataStream &stream)
00083 {
00084     stream.setByteOrder (QDataStream::BigEndian);
00085     stream >> p.minimumSpeed;
00086     stream.setByteOrder (QDataStream::LittleEndian);
00087 
00088     stream.readRawData (p.rawSearchCriteria.data(), p.rawSearchCriteria.size());
00089     p.searchCriteria = QString::fromLatin1 (p.rawSearchCriteria);
00090     p.rawSearchCriteria = QByteArray();
00091 
00092     p.queryData.read (stream);
00093 }
00094 
00095 int Query::prepareWritePayload() const
00096 {
00097     p.rawSearchCriteria = p.searchCriteria.toLatin1(); // The latin1 encoded string is NOT zero-terminated.
00098     return 2 + p.rawSearchCriteria.length() + 1 + p.queryData.prepareWrite();
00099     // \todo Limewire puts an additional zero after all extensions, is such are there.
00100 }
00101 
00102 void Query::writePayload (QDataStream &stream) const
00103 {
00104     stream.setByteOrder (QDataStream::BigEndian);
00105     stream << p.minimumSpeed;
00106     stream.setByteOrder (QDataStream::LittleEndian);
00107 
00108     stream.writeRawData (p.rawSearchCriteria.data(), p.rawSearchCriteria.length());
00109     stream << uchar (0);
00110     p.queryData.write (stream);
00111 
00112     p.rawSearchCriteria = QByteArray();
00113 }
00114 
00115 quint16 Query::minimumSpeed() const
00116 {
00117     return p.minimumSpeed;
00118 }
00119 
00120 QString Query::searchCriteria() const
00121 {
00122     return p.searchCriteria;
00123 }
00124 
00125 /*Query::QueryData Query::queryData() const
00126 {
00127     return p.queryData;
00128 }*/
00129 
00130 void Query::setMinimumSpeed (const quint16 &minimumSpeed)
00131 {
00132     p.minimumSpeed = minimumSpeed;
00133     invalidatePayload();
00134 }
00135 
00136 void Query::setSearchCriteria (const QString &searchCriteria)
00137 {
00138     p.searchCriteria = searchCriteria;
00139     invalidatePayload();
00140 }
00141