1 /*
2 * This file is part of Licq, an instant messaging client for UNIX.
3 * Copyright (C) 2004-2013 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 #include <cstdlib>
21 #include <cstring>
22 #include "msnbuffer.h"
23
24 using namespace LicqMsn;
25 using std::list;
26 using std::string;
27
CMSNBuffer(CMSNBuffer & b)28 CMSNBuffer::CMSNBuffer(CMSNBuffer &b)
29 : Licq::Buffer(b)
30 {
31 m_nDataSize = b.getDataMaxSize();
32 if (m_nDataSize)
33 {
34 m_pDataStart = new char[m_nDataSize];
35 memcpy(m_pDataStart, b.getDataStart(), m_nDataSize);
36 }
37 else
38 {
39 m_pDataStart = NULL;
40 }
41 m_pDataPosRead = m_pDataStart + (b.getDataPosRead() - b.getDataStart());
42 m_pDataPosWrite = m_pDataStart + (b.getDataPosWrite() - b.getDataStart());
43 }
44
CMSNBuffer(Licq::Buffer & b)45 CMSNBuffer::CMSNBuffer(Licq::Buffer& b)
46 {
47 m_nDataSize = b.getDataMaxSize();
48 if (m_nDataSize)
49 {
50 m_pDataStart = new char[m_nDataSize];
51 memcpy(m_pDataStart, b.getDataStart(), m_nDataSize);
52 }
53 else
54 {
55 m_pDataStart = NULL;
56 }
57 m_pDataPosRead = m_pDataStart + (b.getDataPosRead() - b.getDataStart());
58 m_pDataPosWrite = m_pDataStart + (b.getDataPosWrite() - b.getDataStart());
59 }
60
ParseHeaders()61 bool CMSNBuffer::ParseHeaders()
62 {
63 char ctmp = 0;
64 int counter = 0;
65 string stmp = "", strHeader, strData;
66 struct SHeader *pHeader = 0;
67
68 if (m_lHeader.size() > 0)
69 ClearHeaders();
70
71 while (!End())
72 {
73 *this >> ctmp;
74
75 // Get header
76 while (ctmp != ':' && ctmp != '\r' && ctmp != 0)
77 {
78 stmp += ctmp;
79 *this >> ctmp;
80 }
81
82 // Check for the end of the headers list
83 if (ctmp == '\r')
84 {
85 while (ctmp == '\r' || ctmp == '\n')
86 {
87 counter++;
88 *this >> ctmp;
89
90 if (counter == 2)
91 {
92 setDataPosRead(getDataPosRead() - 1);
93 return true;
94 }
95 }
96
97 counter = 0;
98 }
99
100 *this >> ctmp; // skip ':'
101
102 strHeader = stmp;
103 // Skip whitespace
104 while (ctmp == ' ' && ctmp != 0) *this >> ctmp;
105
106 stmp = "";
107
108 // Get data
109 while (ctmp != '\r' && ctmp != 0)
110 {
111 stmp += ctmp;
112 *this >> ctmp;
113 }
114
115 // Finish the \n
116 *this >> ctmp;
117
118 strData = stmp;
119 pHeader = new SHeader;
120
121 if (!pHeader) return false;
122 pHeader->strHeader = strHeader;
123 pHeader->strValue = strData;
124 m_lHeader.push_back(pHeader);
125
126 stmp = "";
127 }
128
129 return true;
130 }
131
GetValue(const string & strKey)132 string CMSNBuffer::GetValue(const string& strKey)
133 {
134 string strReturn = "";
135 list<SHeader *>::iterator it;
136 for (it = m_lHeader.begin(); it != m_lHeader.end(); it++)
137 {
138 if ((*it)->strHeader == strKey)
139 {
140 strReturn = (*it)->strValue;
141 }
142 }
143
144 return strReturn;
145 }
146
HasHeader(const string & strKey)147 bool CMSNBuffer::HasHeader(const string& strKey)
148 {
149 list<SHeader *>::iterator it;
150 for (it = m_lHeader.begin(); it != m_lHeader.end(); it++)
151 {
152 if ((*it)->strHeader == strKey)
153 {
154 return true;
155 }
156 }
157
158 return false;
159 }
160
ClearHeaders()161 void CMSNBuffer::ClearHeaders()
162 {
163 list<SHeader *>::iterator it;
164 for (it = m_lHeader.begin(); it != m_lHeader.end(); ++it)
165 {
166 if (*it)
167 {
168 delete *it;
169 *it = 0;
170 }
171 }
172 m_lHeader.clear();
173 }
174
SkipParameter()175 void CMSNBuffer::SkipParameter()
176 {
177 char cCheck;
178 *this >> cCheck;
179
180 if (isspace(cCheck))
181 {
182 // Leading space to next paramater
183 while (isspace(cCheck) && !End())
184 *this >> cCheck;
185 }
186
187 // Now skip the paramater
188 while (!isspace(cCheck) && !End())
189 *this>> cCheck;
190 }
191
SkipRN()192 void CMSNBuffer::SkipRN()
193 {
194 char cCheck;
195 *this >> cCheck;
196
197 while ((cCheck == '\r' || cCheck == '\n') && !End())
198 *this >> cCheck;
199
200 setDataPosRead(getDataPosRead() - 1);
201 }
202
GetParameter()203 string CMSNBuffer::GetParameter()
204 {
205 char cCheck;
206 string strParam;
207 *this >> cCheck;
208
209 if (cCheck == ' ')
210 {
211 while (cCheck == ' ' && !End())
212 *this >> cCheck;
213 }
214
215 setDataPosRead(getDataPosRead() - 1);
216
217 while (cCheck != ' ' && cCheck != '\r' && !End())
218 {
219 *this >> cCheck;
220 if (cCheck != ' ' && cCheck != '\r' && cCheck != '\n')
221 strParam += cCheck;
222 }
223
224 return strParam;
225 }
226
GetParameterUnsignedShort()227 unsigned short CMSNBuffer::GetParameterUnsignedShort()
228 {
229 string strValue = GetParameter();
230 unsigned short nValue = (unsigned short)atoi(strValue.c_str());
231 return nValue;
232 }
233
GetParameterUnsignedLong()234 unsigned long CMSNBuffer::GetParameterUnsignedLong()
235 {
236 string strValue = GetParameter();
237 unsigned long nValue = strtoul(strValue.c_str(), (char **)NULL, 10);
238 return nValue;
239 }
SkipPacket()240 void CMSNBuffer::SkipPacket()
241 {
242 char cCheck = 0;
243
244 while (cCheck != '\n' && !End())
245 *this >> cCheck;
246 }
247
Skip(unsigned long _nSize)248 void CMSNBuffer::Skip(unsigned long _nSize)
249 {
250 incDataPosRead(_nSize);
251 }
252
253