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 writeData 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 "Ggep.h" 00025 #include "Ggeps/Unknown.h" 00026 #include "Imports.cpp" 00027 00028 00029 namespace Protocols { 00030 namespace Gnutella { 00031 namespace Packets { 00032 namespace Extensions { 00033 00034 enum Constants 00035 { 00036 MaximalGgepDataLength = 262143 00037 }; 00038 00039 } // namespace Extensions 00040 } // namespace Packets 00041 } // namespace Gnutella 00042 } // namespace Protocols 00043 00044 Ggep::Ggep (int flags_) 00045 : flags (0) 00046 { 00047 if (flags_ & Encoding) flags |= Encoding; 00048 if (flags_ & Compression) flags |= Compression; 00049 if (flags_ & Reserved) flags |= Reserved; 00050 } 00051 00052 Ggep::~Ggep() 00053 { 00054 } 00055 00056 Ggep * Ggep::fromId (const GgepId &id, int flags, const QByteArray &rawData) 00057 { 00058 Ggep* ggep = 0; 00081 // \todo refactor the Ggeps 00082 00083 if (ggep != 0 && ggep->parse (rawData)) 00084 return ggep; 00085 else { 00086 delete ggep; 00087 ggep = new Ggeps::Unknown (id, QByteArray(), flags); 00088 ggep->parse (rawData); 00089 return ggep; 00090 } 00091 } 00092 00093 bool Ggep::parse (const QByteArray &rawData) 00094 { 00095 QByteArray decodedData = rawData; // The raw data could be decoded already. 00096 00097 if (isFlagSet (Encoding)) // Decode data (COBS). 00098 decodedData = Utils::Encodings::Cobs::decode (decodedData); 00099 if (isFlagSet (Compression)) // Decompress data (inflate). 00100 decodedData = Utils::Encodings::Deflate::unCompress (decodedData); 00101 00102 BinaryReader reader (decodedData); 00103 readData (reader); 00104 return reader.hasReadAll() && !reader.hasReadPastEnd(); 00105 } 00106 00107 QByteArray Ggep::rawData() const 00108 { 00109 BinaryWriter writer; 00110 writeData (writer); // the Ggeps write the data. 00111 /* We must always generate correctly formated messages! The implementaion 00112 of writeData() might call reserve() and the following will assert if 00113 less or more than the reserved number of bytes has been written . */ 00114 Q_ASSERT (writer.hasWrittenAll() && !writer.hasWrittenPastEnd()); 00115 00116 QByteArray rawData (writer.buffer()); 00117 if (isFlagSet (Compression)) // Compress data if requested. 00118 rawData = Utils::Encodings::Deflate::compress (rawData); 00119 if (isFlagSet (Encoding)) // Encode data if requirested. 00120 rawData = Utils::Encodings::Cobs::encode (rawData); 00121 // The raw data must be no longer then the maximal allowed size: 00122 Q_ASSERT (rawData.length() >= 0 00123 && rawData.length() <= MaximalGgepDataLength); 00124 return rawData; 00125 } 00126 00127 bool Ggep::operator==( const Ggep &ggep ) const 00128 { 00129 bool result = true; 00130 result = id() == ggep.id() && \ 00131 isFlagSet (Encoding) == ggep.isFlagSet (Encoding) && \ 00132 isFlagSet (Compression) == ggep.isFlagSet (Compression) && \ 00133 isFlagSet (Reserved) == ggep.isFlagSet (Reserved) && \ 00134 rawData() == ggep.rawData(); 00135 return result; 00136 } 00137 00138 bool Ggep::operator!=( const Ggep &ggep ) const 00139 { 00140 return !operator==(ggep); 00141 }