Ggep.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 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 }