blob: 9b0b6c4d1a9802da8c13a110fa60889465874087 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19#include <rdr/HexOutStream.h>
20#include <rdr/Exception.h>
21
22using namespace rdr;
23
24const int DEFAULT_BUF_LEN = 16384;
25
26static inline int min(int a, int b) {return a<b ? a : b;}
27
28HexOutStream::HexOutStream(OutStream& os, int buflen)
29: out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
30{
31 if (bufSize % 2)
32 bufSize--;
33 ptr = start = new U8[bufSize];
34 end = start + bufSize;
35}
36
37HexOutStream::~HexOutStream() {
38 delete [] start;
39}
40
41
42char HexOutStream::intToHex(int i) {
43 if ((i>=0) && (i<=9))
44 return '0'+i;
45 else if ((i>=10) && (i<=15))
46 return 'a'+(i-10);
47 else
48 throw rdr::Exception("intToHex failed");
49}
50
51char* HexOutStream::binToHexStr(const char* data, int length) {
52 char* buffer = new char[length*2+1];
53 for (int i=0; i<length; i++) {
54 buffer[i*2] = intToHex((data[i] >> 4) & 15);
55 buffer[i*2+1] = intToHex((data[i] & 15));
56 if (!buffer[i*2] || !buffer[i*2+1]) {
57 delete [] buffer;
58 return 0;
59 }
60 }
61 buffer[length*2] = 0;
62 return buffer;
63}
64
65
66void
67HexOutStream::writeBuffer() {
68 U8* pos = start;
69 while (pos != ptr) {
70 out_stream.check(2);
71 U8* optr = out_stream.getptr();
72 U8* oend = out_stream.getend();
73 int length = min(ptr-pos, (oend-optr)/2);
74
75 for (int i=0; i<length; i++) {
76 optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
77 optr[i*2+1] = intToHex(pos[i] & 0xf);
78 }
79
80 out_stream.setptr(optr + length*2);
81 pos += length;
82 }
83 offset += ptr - start;
84 ptr = start;
85}
86
87int HexOutStream::length()
88{
89 return offset + ptr - start;
90}
91
92void
93HexOutStream::flush() {
94 writeBuffer();
95 out_stream.flush();
96}
97
98int
99HexOutStream::overrun(int itemSize, int nItems) {
100 if (itemSize > bufSize)
101 throw Exception("HexOutStream overrun: max itemSize exceeded");
102
103 writeBuffer();
104
105 if (itemSize * nItems > end - ptr)
106 nItems = (end - ptr) / itemSize;
107
108 return nItems;
109}
110