1 /* 2 * This file is part of Licq, an instant messaging client for UNIX. 3 * Copyright (C) 2010-2014 Licq developers <licq-dev@googlegroups.com> 4 * 5 * Licq is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * Licq is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Licq; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 #ifndef LICQ_BUFFER_H 21 #define LICQ_BUFFER_H 22 23 #include "logging/log.h" 24 #include "macro.h" 25 26 #include <string> 27 28 29 namespace Licq 30 { 31 32 class Buffer 33 { 34 public: 35 Buffer(); 36 Buffer(unsigned long _nSize); 37 Buffer(const Buffer&); 38 virtual ~Buffer(); 39 40 virtual Buffer& operator=(const Buffer&); 41 Buffer& operator+=(const Buffer&); 42 friend Buffer operator+(const Buffer&, const Buffer&); 43 44 /// Add an unsigned 32 bit little endian integer from the buffer 45 void packUInt32LE(uint32_t data); 46 47 /// Add an unsigned 32 bit big endian integer from the buffer 48 void packUInt32BE(uint32_t data); 49 50 /// Add an unsigned 16 bit little endian integer from the buffer 51 void packUInt16LE(uint16_t data); 52 53 /// Add an unsigned 16 bit big endian integer from the buffer 54 void packUInt16BE(uint16_t data); 55 56 /// Add an unsigned 8 bit integer from the buffer 57 void packUInt8(uint8_t data); 58 59 /// Add an signed 8 bit integer from the buffer 60 void packInt8(int8_t data); 61 62 /// Add binary data 63 void packRaw(const void* data, size_t length); packRaw(const std::string & data)64 void packRaw(const std::string& data) { packRaw(data.c_str(), data.size()); } 65 66 /// Add a null terminated string preceded by a 16bit little endian length 67 void packShortNullStringLE(const std::string& data); 68 69 /// Add a string preceded by a 16bit big endian length 70 void packString16BE(const char* data, size_t length); packString16BE(const std::string & data)71 void packString16BE(const std::string& data) 72 { packString16BE(data.c_str(), data.size()); } 73 74 /// Add a string preceded by a 32bit little endian length 75 void packString32LE(const char* data, size_t length); packString32LE(const std::string & data)76 void packString32LE(const std::string& data) 77 { packString32LE(data.c_str(), data.size()); } 78 79 void Pack(Buffer*); 80 81 void Copy(Buffer*); 82 83 // Deprecated add functions PackUnsignedLong(unsigned long data)84 void PackUnsignedLong(unsigned long data) { packUInt32LE(data); } PackUnsignedLongBE(unsigned long data)85 void PackUnsignedLongBE(unsigned long data) { packUInt32BE(data); } PackUnsignedShort(unsigned short data)86 void PackUnsignedShort(unsigned short data) { packUInt16LE(data); } PackUnsignedShortBE(unsigned short data)87 void PackUnsignedShortBE(unsigned short data) { packUInt16BE(data); } PackChar(char data)88 void PackChar(char data) { packInt8(data); } Pack(const char * data,int size)89 void Pack(const char* data, int size) { packRaw(data, size); } Pack(const uint8_t * data,int size)90 void Pack(const uint8_t* data, int size) { packRaw(data, size); } pack(const std::string & data)91 void pack(const std::string& data) { packRaw(data); } PackString(const char * data)92 void PackString(const char *data) { packShortNullStringLE(data); } packString(const std::string & data)93 void packString(const std::string& data) { packShortNullStringLE(data); } 94 95 /** 96 * Log the packet with the given message. 97 */ 98 void log(Log::Level level, const char* format, ...) const LICQ_FORMAT(3, 4); 99 100 virtual void Clear(); 101 void Reset(); 102 bool Empty() const; 103 bool Full() const; End()104 bool End() { return ( getDataPosRead() >= (getDataStart() + getDataSize()) ); } 105 void Create(unsigned long _nDataSize = 0); 106 107 Buffer& operator>>(char &in); 108 Buffer& operator>>(unsigned char &in); 109 Buffer& operator>>(unsigned short &in); 110 Buffer& operator>>(unsigned long &in); 111 112 /** 113 * Get several bytes from the buffer 114 * 115 * @param size Number of bytes to read 116 * @return A string containing the requested bytes 117 */ 118 std::string unpackRawString(size_t size); 119 120 /** 121 * Get a string from the buffer 122 * Length of string is a 8 bit byte at beginning of data 123 * 124 * @return String read 125 */ 126 std::string unpackByteString(); 127 128 /** 129 * Get a string from the buffer 130 * Length of string is a 16 bit little endian word at beginning of data 131 * 132 * @return String read 133 */ 134 std::string unpackShortStringLE(); 135 136 /** 137 * Get a string from the buffer 138 * Length of string is a 16 bit big endian word at beginning of data 139 * 140 * @return String read 141 */ 142 std::string unpackShortStringBE(); 143 144 /** 145 * Get a string from the buffer 146 * Length of string is a 32 bit little endian word at beginning of data 147 * 148 * @return String read 149 */ 150 std::string unpackLongStringLE(); 151 152 /** 153 * Get a string from the buffer 154 * Length of string is a 32 bit big endian word at beginning of data 155 * 156 * @return String read 157 */ 158 std::string unpackLongStringBE(); 159 160 /// Get an unsigned 32 bit little endian integer from the buffer 161 uint32_t unpackUInt32LE(); 162 163 /// Get an unsigned 32 bit big endian integer from the buffer 164 uint32_t unpackUInt32BE(); 165 166 /// Get an unsigned 16 bit little endian integer from the buffer 167 uint16_t unpackUInt16LE(); 168 169 /// Get an unsigned 16 bit big endian integer from the buffer 170 uint16_t unpackUInt16BE(); 171 172 /// Get an unsigned 8 bit integer from the buffer 173 uint8_t unpackUInt8(); 174 175 /// Get a signed 8 bit integer from the buffer 176 int8_t unpackInt8(); 177 178 // Deprecated integer access functions UnpackUnsignedLongBE()179 unsigned long UnpackUnsignedLongBE() { return unpackUInt32BE(); } UnpackUnsignedShortBE()180 unsigned short UnpackUnsignedShortBE() { return unpackUInt16BE(); } UnpackUnsignedLong()181 unsigned long UnpackUnsignedLong() { return unpackUInt32LE(); } UnpackUnsignedShort()182 unsigned short UnpackUnsignedShort() { return unpackUInt16LE(); } UnpackChar()183 char UnpackChar() { return unpackInt8(); } 184 getDataStart()185 char *getDataStart() const { return m_pDataStart; }; getDataPosRead()186 char *getDataPosRead() const { return m_pDataPosRead; }; getDataPosWrite()187 char *getDataPosWrite() const { return m_pDataPosWrite; }; getDataSize()188 unsigned long getDataSize() const { return m_pDataPosWrite - m_pDataStart; }; getDataMaxSize()189 unsigned long getDataMaxSize() const { return m_nDataSize; }; 190 191 /** 192 * Get number of available bytes left to read 193 */ remainingDataToRead()194 size_t remainingDataToRead() const 195 { return m_pDataPosWrite - m_pDataPosRead; } 196 197 /** 198 * Get number of available bytes left to write 199 */ remainingDataToWrite()200 size_t remainingDataToWrite() const 201 { return m_pDataStart + m_nDataSize - m_pDataPosWrite; } 202 setDataSize(unsigned long _nDataSize)203 void setDataSize(unsigned long _nDataSize) { m_nDataSize = _nDataSize; }; setDataPosWrite(char * _pDataPosWrite)204 void setDataPosWrite(char *_pDataPosWrite) { m_pDataPosWrite = _pDataPosWrite; }; setDataPosRead(char * _pDataPosRead)205 void setDataPosRead(char *_pDataPosRead) { m_pDataPosRead = _pDataPosRead; }; incDataPosWrite(unsigned long c)206 void incDataPosWrite(unsigned long c) { m_pDataPosWrite += c; }; incDataPosRead(unsigned long c)207 void incDataPosRead(unsigned long c) { m_pDataPosRead += c; }; 208 209 protected: 210 211 char *m_pDataStart, 212 *m_pDataPosWrite, 213 *m_pDataPosRead; 214 unsigned long m_nDataSize; 215 }; 216 217 Buffer operator+(const Buffer& b0, const Buffer& b1); 218 219 } // namespace Licq 220 221 #endif 222