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