fde2b16f8274b06f9dd0c12e9dba85e54e3067a4
1 #ifndef __PEDROUTIL_H__
2 #define __PEDROUTIL_H__
3 /*
4 * Support classes for the Pedro mini-XMPP client.
5 *
6 * Authors:
7 * Bob Jamison
8 *
9 * Copyright (C) 2005-2007 Bob Jamison
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <vector>
30 #include <string>
32 #include "pedrodom.h"
35 #ifdef HAVE_SSL
36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
38 #endif
42 namespace Pedro
43 {
48 //########################################################################
49 //########################################################################
50 //# B A S E 6 4
51 //########################################################################
52 //########################################################################
55 //#################
56 //# ENCODER
57 //#################
60 /**
61 * This class is for Base-64 encoding
62 */
63 class Base64Encoder
64 {
66 public:
68 Base64Encoder()
69 {
70 reset();
71 }
73 virtual ~Base64Encoder()
74 {}
76 virtual void reset()
77 {
78 outBuf = 0L;
79 bitCount = 0;
80 buf = "";
81 }
83 virtual void append(int ch);
85 virtual void append(char *str);
87 virtual void append(unsigned char *str, int len);
89 virtual void append(const DOMString &str);
91 virtual DOMString finish();
93 static DOMString encode(const DOMString &str);
96 private:
99 unsigned long outBuf;
101 int bitCount;
103 DOMString buf;
105 };
110 //#################
111 //# DECODER
112 //#################
114 class Base64Decoder
115 {
116 public:
117 Base64Decoder()
118 {
119 reset();
120 }
122 virtual ~Base64Decoder()
123 {}
125 virtual void reset()
126 {
127 inCount = 0;
128 buf.clear();
129 }
132 virtual void append(int ch);
134 virtual void append(char *str);
136 virtual void append(const DOMString &str);
138 std::vector<unsigned char> finish();
140 static std::vector<unsigned char> decode(const DOMString &str);
142 static DOMString decodeToString(const DOMString &str);
144 private:
146 int inBytes[4];
147 int inCount;
148 std::vector<unsigned char> buf;
149 };
154 //########################################################################
155 //########################################################################
156 //### S H A 1 H A S H I N G
157 //########################################################################
158 //########################################################################
160 /**
161 * This class performs a slow SHA1 hash on a stream of input data.
162 */
163 class Sha1
164 {
165 public:
167 /**
168 * Constructor
169 */
170 Sha1()
171 { init(); }
173 /**
174 *
175 */
176 virtual ~Sha1()
177 { init(); }
180 /**
181 * Static convenience method. This would be the most commonly used
182 * version;
183 * @parm digest points to a bufer of 20 unsigned chars
184 */
185 static void hash(unsigned char *dataIn, int len, unsigned char *digest);
187 /**
188 * Static convenience method. This will fill a string with the hex
189 * coded string.
190 */
191 static DOMString hashHex(unsigned char *dataIn, int len);
193 /**
194 * Static convenience method.
195 */
196 static DOMString hashHex(const DOMString &str);
198 /**
199 * Initialize the context (also zeroizes contents)
200 */
201 virtual void init();
203 /**
204 * Append a single character
205 */
206 virtual void append(unsigned char ch);
208 /**
209 * Append a data buffer
210 */
211 virtual void append(unsigned char *dataIn, int len);
213 /**
214 * Append a String
215 */
216 virtual void append(const DOMString &str);
218 /**
219 *
220 * @parm digest points to a bufer of 20 unsigned chars
221 */
222 virtual void finish(unsigned char *digest);
225 private:
227 void transform();
229 unsigned long hashBuf[5];
230 unsigned long inBuf[80];
231 unsigned long nrBytesHi;
232 unsigned long nrBytesLo;
233 int longNr;
234 int byteNr;
235 unsigned long inb[4];
237 };
243 //########################################################################
244 //########################################################################
245 //### M D 5 H A S H I N G
246 //########################################################################
247 //########################################################################
250 /**
251 * This is a utility version of a simple MD5 hash algorithm. This is
252 * neither efficient nor fast. It is intended to be a small simple utility
253 * for hashing small amounts of data in a non-time-critical place.
254 *
255 * Note that this is a rewrite whose purpose is to remove any
256 * machine dependencies.
257 */
258 class Md5
259 {
260 public:
262 /**
263 * Constructor
264 */
265 Md5()
266 { init(); }
268 /**
269 * Destructor
270 */
271 virtual ~Md5()
272 {}
274 /**
275 * Static convenience method.
276 * @parm digest points to an buffer of 16 unsigned chars
277 */
278 static void hash(unsigned char *dataIn,
279 unsigned long len, unsigned char *digest);
281 /**
282 * Static convenience method.
283 * Hash a byte array of a given length
284 */
285 static DOMString hashHex(unsigned char *dataIn, unsigned long len);
287 /**
288 * Static convenience method.
289 * Hash a String
290 */
291 static DOMString hashHex(const DOMString &str);
293 /**
294 * Initialize the context (also zeroizes contents)
295 */
296 virtual void init();
298 /*
299 * Update with one character
300 */
301 virtual void append(unsigned char ch);
303 /**
304 * Update with a byte buffer of a given length
305 */
306 virtual void append(unsigned char *dataIn, unsigned long len);
308 /**
309 * Update with a string
310 */
311 virtual void append(const DOMString &str);
313 /**
314 * Finalize and output the hash.
315 * @parm digest points to an buffer of 16 unsigned chars
316 */
317 virtual void finish(unsigned char *digest);
320 /**
321 * Same as above , but hex to an output String
322 */
323 virtual DOMString finishHex();
325 private:
327 void transform();
329 unsigned long hashBuf[4];
330 unsigned long inBuf[16];
331 unsigned long nrBytesHi;
332 unsigned long nrBytesLo;
334 unsigned long inb[4]; // Buffer for input bytes as longs
335 int byteNr; // which byte in long
336 int longNr; // which long in 8 long segment
338 };
344 //########################################################################
345 //########################################################################
346 //### T H R E A D
347 //########################################################################
348 //########################################################################
352 /**
353 * This is the interface for a delegate class which can
354 * be run by a Thread.
355 * Thread thread(runnable);
356 * thread.start();
357 */
358 class Runnable
359 {
360 public:
362 Runnable()
363 {}
364 virtual ~Runnable()
365 {}
367 /**
368 * The method of a delegate class which can
369 * be run by a Thread. Thread is completed when this
370 * method is done.
371 */
372 virtual void run() = 0;
374 };
378 /**
379 * A simple wrapper of native threads in a portable class.
380 * It can be used either to execute its own run() method, or
381 * delegate to a Runnable class's run() method.
382 */
383 class Thread
384 {
385 public:
387 /**
388 * Create a thread which will execute its own run() method.
389 */
390 Thread()
391 { runnable = NULL ; started = false; }
393 /**
394 * Create a thread which will run a Runnable class's run() method.
395 */
396 Thread(const Runnable &runner)
397 { runnable = (Runnable *)&runner; started = false; }
399 /**
400 * This does not kill a spawned thread.
401 */
402 virtual ~Thread()
403 {}
405 /**
406 * Static method to pause the current thread for a given
407 * number of milliseconds.
408 */
409 static void sleep(unsigned long millis);
411 /**
412 * This method will be executed if the Thread was created with
413 * no delegated Runnable class. The thread is completed when
414 * the method is done.
415 */
416 virtual void run()
417 {}
419 /**
420 * Starts the thread.
421 */
422 virtual void start();
424 /**
425 * Calls either this class's run() method, or that of a Runnable.
426 * A user would normally not call this directly.
427 */
428 virtual void execute()
429 {
430 started = true;
431 if (runnable)
432 runnable->run();
433 else
434 run();
435 }
437 private:
439 Runnable *runnable;
441 bool started;
443 };
450 //########################################################################
451 //########################################################################
452 //### S O C K E T
453 //########################################################################
454 //########################################################################
458 /**
459 * A socket wrapper that provides cross-platform capability, plus SSL
460 */
461 class TcpSocket
462 {
463 public:
465 TcpSocket();
467 TcpSocket(const std::string &hostname, int port);
469 TcpSocket(const char *hostname, int port);
471 TcpSocket(const TcpSocket &other);
473 virtual ~TcpSocket();
475 void error(const char *fmt, ...);
477 DOMString &getLastError();
479 bool isConnected();
481 void enableSSL(bool val);
483 bool getEnableSSL();
485 bool getHaveSSL();
487 bool connect(const std::string &hostname, int portno);
489 bool connect(const char *hostname, int portno);
491 bool startTls();
493 bool connect();
495 bool disconnect();
497 bool setReceiveTimeout(unsigned long millis);
499 long available();
501 bool write(int ch);
503 bool write(char *str);
505 bool write(const std::string &str);
507 int read();
509 std::string readLine();
511 private:
512 void init();
514 DOMString lastError;
516 std::string hostname;
517 int portno;
518 int sock;
519 bool connected;
521 bool sslEnabled;
523 unsigned long receiveTimeout;
526 #ifdef HAVE_SSL
527 SSL_CTX *sslContext;
528 SSL *sslStream;
529 #endif
531 };
538 } //namespace Pedro
540 #endif /* __PEDROUTIL_H__ */
542 //########################################################################
543 //# E N D O F F I L E
544 //########################################################################