This file is indexed.

/usr/share/doc/libpion-doc/html/algorithm_8cpp_source.html is in libpion-doc 5.0.4+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>pion: src/algorithm.cpp Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
    </ul>
  </div>
<h1>src/algorithm.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00002"></a>00002 <span class="comment">// pion:  a Boost C++ framework for building lightweight HTTP interfaces</span>
<a name="l00003"></a>00003 <span class="comment">// ---------------------------------------------------------------------</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.com)</span>
<a name="l00005"></a>00005 <span class="comment">//</span>
<a name="l00006"></a>00006 <span class="comment">// Distributed under the Boost Software License, Version 1.0.</span>
<a name="l00007"></a>00007 <span class="comment">// See http://www.boost.org/LICENSE_1_0.txt</span>
<a name="l00008"></a>00008 <span class="comment">//</span>
<a name="l00009"></a>00009 
<a name="l00010"></a>00010 <span class="preprocessor">#include &lt;cmath&gt;</span>
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;cstdlib&gt;</span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;cstdio&gt;</span>
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;cstring&gt;</span>
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;pion/algorithm.hpp&gt;</span>
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;boost/assert.hpp&gt;</span>
<a name="l00016"></a>00016 
<a name="l00017"></a>00017 <span class="comment">// macro to shift bitmask by a single bit</span>
<a name="l00018"></a>00018 <span class="preprocessor">#define SHIFT_BITMASK(ptr, mask)    if (mask &amp; 0x01) { mask = 0x80; ++ptr; } else mask &gt;&gt;= 1;</span>
<a name="l00019"></a>00019 <span class="preprocessor"></span>
<a name="l00020"></a>00020 
<a name="l00021"></a>00021 <span class="keyword">namespace </span>pion {        <span class="comment">// begin namespace pion</span>
<a name="l00022"></a>00022 
<a name="l00023"></a>00023 
<a name="l00024"></a><a class="code" href="structpion_1_1algorithm.html#ad1700ce7cf8e29bb7600d5729fd4cdad">00024</a> <span class="keywordtype">bool</span> <a class="code" href="structpion_1_1algorithm.html#ad1700ce7cf8e29bb7600d5729fd4cdad">algorithm::base64_decode</a>(<span class="keyword">const</span> std::string &amp;input, std::string &amp;output)
<a name="l00025"></a>00025 {
<a name="l00026"></a>00026     <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> nop = -1; 
<a name="l00027"></a>00027     <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> decoding_data[] = {
<a name="l00028"></a>00028         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00029"></a>00029         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00030"></a>00030         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop, 62, nop,nop,nop, 63,
<a name="l00031"></a>00031         52, 53, 54,  55,  56, 57, 58, 59,  60, 61,nop,nop, nop,nop,nop,nop,
<a name="l00032"></a>00032         nop, 0,  1,   2,   3,  4,  5,  6,   7,  8,  9, 10,  11, 12, 13, 14,
<a name="l00033"></a>00033         15, 16, 17,  18,  19, 20, 21, 22,  23, 24, 25,nop, nop,nop,nop,nop,
<a name="l00034"></a>00034         nop,26, 27,  28,  29, 30, 31, 32,  33, 34, 35, 36,  37, 38, 39, 40,
<a name="l00035"></a>00035         41, 42, 43,  44,  45, 46, 47, 48,  49, 50, 51,nop, nop,nop,nop,nop,
<a name="l00036"></a>00036         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00037"></a>00037         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00038"></a>00038         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00039"></a>00039         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00040"></a>00040         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00041"></a>00041         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00042"></a>00042         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop,
<a name="l00043"></a>00043         nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop
<a name="l00044"></a>00044         };
<a name="l00045"></a>00045 
<a name="l00046"></a>00046     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> input_length=input.size();
<a name="l00047"></a>00047     <span class="keyword">const</span> <span class="keywordtype">char</span> * input_ptr = input.data();
<a name="l00048"></a>00048 
<a name="l00049"></a>00049     <span class="comment">// allocate space for output string</span>
<a name="l00050"></a>00050     output.clear();
<a name="l00051"></a>00051     output.reserve(((input_length+2)/3)*4);
<a name="l00052"></a>00052 
<a name="l00053"></a>00053     <span class="comment">// for each 4-bytes sequence from the input, extract 4 6-bits sequences by droping first two bits</span>
<a name="l00054"></a>00054     <span class="comment">// and regenerate into 3 8-bits sequence</span>
<a name="l00055"></a>00055 
<a name="l00056"></a>00056     <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;input_length;i++) {
<a name="l00057"></a>00057         <span class="keywordtype">char</span> base64code0;
<a name="l00058"></a>00058         <span class="keywordtype">char</span> base64code1;
<a name="l00059"></a>00059         <span class="keywordtype">char</span> base64code2 = 0;   <span class="comment">// initialized to 0 to suppress warnings</span>
<a name="l00060"></a>00060         <span class="keywordtype">char</span> base64code3;
<a name="l00061"></a>00061 
<a name="l00062"></a>00062         base64code0 = decoding_data[<span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(input_ptr[i])];
<a name="l00063"></a>00063         <span class="keywordflow">if</span>(base64code0==nop)            <span class="comment">// non base64 character</span>
<a name="l00064"></a>00064             <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00065"></a>00065         <span class="keywordflow">if</span>(!(++i&lt;input_length)) <span class="comment">// we need at least two input bytes for first byte output</span>
<a name="l00066"></a>00066             <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00067"></a>00067         base64code1 = decoding_data[<span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(input_ptr[i])];
<a name="l00068"></a>00068         <span class="keywordflow">if</span>(base64code1==nop)            <span class="comment">// non base64 character</span>
<a name="l00069"></a>00069             <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00070"></a>00070 
<a name="l00071"></a>00071         output += ((base64code0 &lt;&lt; 2) | ((base64code1 &gt;&gt; 4) &amp; 0x3));
<a name="l00072"></a>00072 
<a name="l00073"></a>00073         <span class="keywordflow">if</span>(++i&lt;input_length) {
<a name="l00074"></a>00074             <span class="keywordtype">char</span> c = input_ptr[i];
<a name="l00075"></a>00075             <span class="keywordflow">if</span>(c ==<span class="charliteral">&apos;=&apos;</span>) { <span class="comment">// padding , end of input</span>
<a name="l00076"></a>00076                 BOOST_ASSERT( (base64code1 &amp; 0x0f)==0);
<a name="l00077"></a>00077                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00078"></a>00078             }
<a name="l00079"></a>00079             base64code2 = decoding_data[<span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(input_ptr[i])];
<a name="l00080"></a>00080             <span class="keywordflow">if</span>(base64code2==nop)            <span class="comment">// non base64 character</span>
<a name="l00081"></a>00081                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00082"></a>00082 
<a name="l00083"></a>00083             output += ((base64code1 &lt;&lt; 4) &amp; 0xf0) | ((base64code2 &gt;&gt; 2) &amp; 0x0f);
<a name="l00084"></a>00084         }
<a name="l00085"></a>00085 
<a name="l00086"></a>00086         <span class="keywordflow">if</span>(++i&lt;input_length) {
<a name="l00087"></a>00087             <span class="keywordtype">char</span> c = input_ptr[i];
<a name="l00088"></a>00088             <span class="keywordflow">if</span>(c ==<span class="charliteral">&apos;=&apos;</span>) { <span class="comment">// padding , end of input</span>
<a name="l00089"></a>00089                 BOOST_ASSERT( (base64code2 &amp; 0x03)==0);
<a name="l00090"></a>00090                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00091"></a>00091             }
<a name="l00092"></a>00092             base64code3 = decoding_data[<span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(input_ptr[i])];
<a name="l00093"></a>00093             <span class="keywordflow">if</span>(base64code3==nop)            <span class="comment">// non base64 character</span>
<a name="l00094"></a>00094                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00095"></a>00095 
<a name="l00096"></a>00096             output += (((base64code2 &lt;&lt; 6) &amp; 0xc0) | base64code3 );
<a name="l00097"></a>00097         }
<a name="l00098"></a>00098 
<a name="l00099"></a>00099     }
<a name="l00100"></a>00100 
<a name="l00101"></a>00101     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00102"></a>00102 }
<a name="l00103"></a>00103 
<a name="l00104"></a><a class="code" href="structpion_1_1algorithm.html#ae5f52e52ac349ecf20410f2ad3e257dd">00104</a> <span class="keywordtype">bool</span> <a class="code" href="structpion_1_1algorithm.html#ae5f52e52ac349ecf20410f2ad3e257dd">algorithm::base64_encode</a>(<span class="keyword">const</span> std::string &amp;input, std::string &amp;output)
<a name="l00105"></a>00105 {
<a name="l00106"></a>00106     <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> encoding_data[] = 
<a name="l00107"></a>00107         <span class="stringliteral">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&quot;</span>;
<a name="l00108"></a>00108 
<a name="l00109"></a>00109     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> input_length=input.size();
<a name="l00110"></a>00110     <span class="keyword">const</span> <span class="keywordtype">char</span> * input_ptr = input.data();
<a name="l00111"></a>00111 
<a name="l00112"></a>00112     <span class="comment">// allocate space for output string</span>
<a name="l00113"></a>00113     output.clear();
<a name="l00114"></a>00114     output.reserve(((input_length+2)/3)*4);
<a name="l00115"></a>00115 
<a name="l00116"></a>00116     <span class="comment">// for each 3-bytes sequence from the input, extract 4 6-bits sequences and encode using </span>
<a name="l00117"></a>00117     <span class="comment">// encoding_data lookup table.</span>
<a name="l00118"></a>00118     <span class="comment">// if input do not contains enough chars to complete 3-byte sequence,use pad char &apos;=&apos; </span>
<a name="l00119"></a>00119     <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;input_length;i++) {
<a name="l00120"></a>00120         <span class="keywordtype">int</span> base64code0=0;
<a name="l00121"></a>00121         <span class="keywordtype">int</span> base64code1=0;
<a name="l00122"></a>00122         <span class="keywordtype">int</span> base64code2=0;
<a name="l00123"></a>00123         <span class="keywordtype">int</span> base64code3=0;
<a name="l00124"></a>00124 
<a name="l00125"></a>00125         base64code0 = (input_ptr[i] &gt;&gt; 2)  &amp; 0x3f;  <span class="comment">// 1-byte 6 bits</span>
<a name="l00126"></a>00126         output += encoding_data[base64code0];
<a name="l00127"></a>00127         base64code1 = (input_ptr[i] &lt;&lt; 4 ) &amp; 0x3f;  <span class="comment">// 1-byte 2 bits +</span>
<a name="l00128"></a>00128 
<a name="l00129"></a>00129         <span class="keywordflow">if</span> (++i &lt; input_length) {
<a name="l00130"></a>00130             base64code1 |= (input_ptr[i] &gt;&gt; 4) &amp; 0x0f; <span class="comment">// 2-byte 4 bits</span>
<a name="l00131"></a>00131             output += encoding_data[base64code1];
<a name="l00132"></a>00132             base64code2 = (input_ptr[i] &lt;&lt; 2) &amp; 0x3f;  <span class="comment">// 2-byte 4 bits + </span>
<a name="l00133"></a>00133 
<a name="l00134"></a>00134             <span class="keywordflow">if</span> (++i &lt; input_length) {
<a name="l00135"></a>00135                 base64code2 |= (input_ptr[i] &gt;&gt; 6) &amp; 0x03; <span class="comment">// 3-byte 2 bits</span>
<a name="l00136"></a>00136                 base64code3  = input_ptr[i] &amp; 0x3f;       <span class="comment">// 3-byte 6 bits</span>
<a name="l00137"></a>00137                 output += encoding_data[base64code2];
<a name="l00138"></a>00138                 output += encoding_data[base64code3];
<a name="l00139"></a>00139             } <span class="keywordflow">else</span> {
<a name="l00140"></a>00140                 output += encoding_data[base64code2];
<a name="l00141"></a>00141                 output += <span class="charliteral">&apos;=&apos;</span>;
<a name="l00142"></a>00142             }
<a name="l00143"></a>00143         } <span class="keywordflow">else</span> {
<a name="l00144"></a>00144             output += encoding_data[base64code1];
<a name="l00145"></a>00145             output += <span class="charliteral">&apos;=&apos;</span>;
<a name="l00146"></a>00146             output += <span class="charliteral">&apos;=&apos;</span>;
<a name="l00147"></a>00147         }
<a name="l00148"></a>00148     }
<a name="l00149"></a>00149 
<a name="l00150"></a>00150     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00151"></a>00151 }
<a name="l00152"></a>00152 
<a name="l00153"></a><a class="code" href="structpion_1_1algorithm.html#a440bd54b07a24c80bc939fdb03583721">00153</a> std::string <a class="code" href="structpion_1_1algorithm.html#a440bd54b07a24c80bc939fdb03583721" title="escapes URL-encoded strings (a20value+with20spaces)">algorithm::url_decode</a>(<span class="keyword">const</span> std::string&amp; str)
<a name="l00154"></a>00154 {
<a name="l00155"></a>00155     <span class="keywordtype">char</span> decode_buf[3];
<a name="l00156"></a>00156     std::string result;
<a name="l00157"></a>00157     result.reserve(str.size());
<a name="l00158"></a>00158     
<a name="l00159"></a>00159     <span class="keywordflow">for</span> (std::string::size_type pos = 0; pos &lt; str.size(); ++pos) {
<a name="l00160"></a>00160         <span class="keywordflow">switch</span>(str[pos]) {
<a name="l00161"></a>00161         <span class="keywordflow">case</span> <span class="charliteral">&apos;+&apos;</span>:
<a name="l00162"></a>00162             <span class="comment">// convert to space character</span>
<a name="l00163"></a>00163             result += <span class="charliteral">&apos; &apos;</span>;
<a name="l00164"></a>00164             <span class="keywordflow">break</span>;
<a name="l00165"></a>00165         <span class="keywordflow">case</span> <span class="charliteral">&apos;%&apos;</span>:
<a name="l00166"></a>00166             <span class="comment">// decode hexidecimal value</span>
<a name="l00167"></a>00167             <span class="keywordflow">if</span> (pos + 2 &lt; str.size()) {
<a name="l00168"></a>00168                 decode_buf[0] = str[++pos];
<a name="l00169"></a>00169                 decode_buf[1] = str[++pos];
<a name="l00170"></a>00170                 decode_buf[2] = <span class="charliteral">&apos;\0&apos;</span>;
<a name="l00171"></a>00171                 result += <span class="keyword">static_cast&lt;</span><span class="keywordtype">char</span><span class="keyword">&gt;</span>( strtol(decode_buf, 0, 16) );
<a name="l00172"></a>00172             } <span class="keywordflow">else</span> {
<a name="l00173"></a>00173                 <span class="comment">// recover from error by not decoding character</span>
<a name="l00174"></a>00174                 result += <span class="charliteral">&apos;%&apos;</span>;
<a name="l00175"></a>00175             }
<a name="l00176"></a>00176             <span class="keywordflow">break</span>;
<a name="l00177"></a>00177         <span class="keywordflow">default</span>:
<a name="l00178"></a>00178             <span class="comment">// character does not need to be escaped</span>
<a name="l00179"></a>00179             result += str[pos];
<a name="l00180"></a>00180         }
<a name="l00181"></a>00181     };
<a name="l00182"></a>00182     
<a name="l00183"></a>00183     <span class="keywordflow">return</span> result;
<a name="l00184"></a>00184 }
<a name="l00185"></a>00185     
<a name="l00186"></a><a class="code" href="structpion_1_1algorithm.html#aa4eaedaecac95a638cedf5c4884de1b8">00186</a> std::string <a class="code" href="structpion_1_1algorithm.html#aa4eaedaecac95a638cedf5c4884de1b8" title="encodes strings so that they are safe for URLs (with20spaces)">algorithm::url_encode</a>(<span class="keyword">const</span> std::string&amp; str)
<a name="l00187"></a>00187 {
<a name="l00188"></a>00188     <span class="keywordtype">char</span> encode_buf[4];
<a name="l00189"></a>00189     std::string result;
<a name="l00190"></a>00190     encode_buf[0] = <span class="charliteral">&apos;%&apos;</span>;
<a name="l00191"></a>00191     result.reserve(str.size());
<a name="l00192"></a>00192 
<a name="l00193"></a>00193     <span class="comment">// character selection for this algorithm is based on the following url:</span>
<a name="l00194"></a>00194     <span class="comment">// http://www.blooberry.com/indexdot/html/topics/urlencoding.htm</span>
<a name="l00195"></a>00195     
<a name="l00196"></a>00196     <span class="keywordflow">for</span> (std::string::size_type pos = 0; pos &lt; str.size(); ++pos) {
<a name="l00197"></a>00197         <span class="keywordflow">switch</span>(str[pos]) {
<a name="l00198"></a>00198         <span class="keywordflow">default</span>:
<a name="l00199"></a>00199             <span class="keywordflow">if</span> (str[pos] &gt; 32 &amp;&amp; str[pos] &lt; 127) {
<a name="l00200"></a>00200                 <span class="comment">// character does not need to be escaped</span>
<a name="l00201"></a>00201                 result += str[pos];
<a name="l00202"></a>00202                 <span class="keywordflow">break</span>;
<a name="l00203"></a>00203             }
<a name="l00204"></a>00204             <span class="comment">// else pass through to next case</span>
<a name="l00205"></a>00205         <span class="keywordflow">case</span> <span class="charliteral">&apos; &apos;</span>:   
<a name="l00206"></a>00206         <span class="keywordflow">case</span> <span class="charliteral">&apos;$&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;&amp;&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;+&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;,&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;/&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;:&apos;</span>:
<a name="l00207"></a>00207         <span class="keywordflow">case</span> <span class="charliteral">&apos;;&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;=&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;?&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;@&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;&quot;&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;&lt;&apos;</span>:
<a name="l00208"></a>00208         <span class="keywordflow">case</span> <span class="charliteral">&apos;&gt;&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;#&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;%&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;{&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;}&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;|&apos;</span>:
<a name="l00209"></a>00209         <span class="keywordflow">case</span> <span class="charliteral">&apos;\\&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;^&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;~&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;[&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;]&apos;</span>: <span class="keywordflow">case</span> <span class="charliteral">&apos;`&apos;</span>:
<a name="l00210"></a>00210             <span class="comment">// the character needs to be encoded</span>
<a name="l00211"></a>00211             sprintf(encode_buf+1, <span class="stringliteral">&quot;%.2X&quot;</span>, (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>)(str[pos]));
<a name="l00212"></a>00212             result += encode_buf;
<a name="l00213"></a>00213             <span class="keywordflow">break</span>;
<a name="l00214"></a>00214         }
<a name="l00215"></a>00215     };
<a name="l00216"></a>00216     
<a name="l00217"></a>00217     <span class="keywordflow">return</span> result;
<a name="l00218"></a>00218 }
<a name="l00219"></a>00219 
<a name="l00220"></a>00220 <span class="comment">// TODO</span>
<a name="l00221"></a>00221 <span class="comment">//std::string algorithm::xml_decode(const std::string&amp; str)</span>
<a name="l00222"></a>00222 <span class="comment">//{</span>
<a name="l00223"></a>00223 <span class="comment">//}</span>
<a name="l00224"></a>00224 
<a name="l00225"></a><a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb">00225</a> std::string <a class="code" href="structpion_1_1algorithm.html#a2177ca0d0f01e6ef6d4d3bceb73d82bb" title="TODO: escapes XML/HTML-encoded strings (1 &amp;lt; 2).">algorithm::xml_encode</a>(<span class="keyword">const</span> std::string&amp; str)
<a name="l00226"></a>00226 {
<a name="l00227"></a>00227     std::string result;
<a name="l00228"></a>00228     result.reserve(str.size() + 20);    <span class="comment">// Assume ~5 characters converted (length increases)</span>
<a name="l00229"></a>00229     <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *ptr = <span class="keyword">reinterpret_cast&lt;</span><span class="keyword">const </span><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>*<span class="keyword">&gt;</span>(str.c_str());
<a name="l00230"></a>00230     <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *end_ptr = ptr + str.size();
<a name="l00231"></a>00231     <span class="keywordflow">while</span> (ptr &lt; end_ptr) {
<a name="l00232"></a>00232         <span class="comment">// check byte ranges for valid UTF-8</span>
<a name="l00233"></a>00233         <span class="comment">// see http://en.wikipedia.org/wiki/UTF-8</span>
<a name="l00234"></a>00234         <span class="comment">// also, see http://www.w3.org/TR/REC-xml/#charsets</span>
<a name="l00235"></a>00235         <span class="comment">// this implementation is the strictest subset of both</span>
<a name="l00236"></a>00236         <span class="keywordflow">if</span> ((*ptr &gt;= 0x20 &amp;&amp; *ptr &lt;= 0x7F) || *ptr == 0x9 || *ptr == 0xa || *ptr == 0xd) {
<a name="l00237"></a>00237             <span class="comment">// regular ASCII character</span>
<a name="l00238"></a>00238             <span class="keywordflow">switch</span>(*ptr) {
<a name="l00239"></a>00239                     <span class="comment">// Escape special XML characters.</span>
<a name="l00240"></a>00240                 <span class="keywordflow">case</span> <span class="charliteral">&apos;&amp;&apos;</span>:
<a name="l00241"></a>00241                     result += <span class="stringliteral">&quot;&amp;amp;&quot;</span>;
<a name="l00242"></a>00242                     <span class="keywordflow">break</span>;
<a name="l00243"></a>00243                 <span class="keywordflow">case</span> <span class="charliteral">&apos;&lt;&apos;</span>:
<a name="l00244"></a>00244                     result += <span class="stringliteral">&quot;&amp;lt;&quot;</span>;
<a name="l00245"></a>00245                     <span class="keywordflow">break</span>;
<a name="l00246"></a>00246                 <span class="keywordflow">case</span> <span class="charliteral">&apos;&gt;&apos;</span>:
<a name="l00247"></a>00247                     result += <span class="stringliteral">&quot;&amp;gt;&quot;</span>;
<a name="l00248"></a>00248                     <span class="keywordflow">break</span>;
<a name="l00249"></a>00249                 <span class="keywordflow">case</span> <span class="charliteral">&apos;\&quot;&apos;</span>:
<a name="l00250"></a>00250                     result += <span class="stringliteral">&quot;&amp;quot;&quot;</span>;
<a name="l00251"></a>00251                     <span class="keywordflow">break</span>;
<a name="l00252"></a>00252                 <span class="keywordflow">case</span> <span class="charliteral">&apos;\&apos;&apos;</span>:
<a name="l00253"></a>00253                     result += <span class="stringliteral">&quot;&amp;apos;&quot;</span>;
<a name="l00254"></a>00254                     <span class="keywordflow">break</span>;
<a name="l00255"></a>00255                 <span class="keywordflow">default</span>:
<a name="l00256"></a>00256                     result += *ptr;
<a name="l00257"></a>00257             }
<a name="l00258"></a>00258         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*ptr &gt;= 0xC2 &amp;&amp; *ptr &lt;= 0xDF) {
<a name="l00259"></a>00259             <span class="comment">// two-byte sequence</span>
<a name="l00260"></a>00260             <span class="keywordflow">if</span> (*(ptr+1) &gt;= 0x80 &amp;&amp; *(ptr+1) &lt;= 0xBF) {
<a name="l00261"></a>00261                 result += *ptr;
<a name="l00262"></a>00262                 result += *(++ptr);
<a name="l00263"></a>00263             } <span class="keywordflow">else</span> {
<a name="l00264"></a>00264                 <span class="comment">// insert replacement char</span>
<a name="l00265"></a>00265                 result += 0xef;
<a name="l00266"></a>00266                 result += 0xbf;
<a name="l00267"></a>00267                 result += 0xbd;
<a name="l00268"></a>00268             }
<a name="l00269"></a>00269         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*ptr &gt;= 0xE0 &amp;&amp; *ptr &lt;= 0xEF) {
<a name="l00270"></a>00270             <span class="comment">// three-byte sequence</span>
<a name="l00271"></a>00271             <span class="keywordflow">if</span> (*(ptr+1) &gt;= 0x80 &amp;&amp; *(ptr+1) &lt;= 0xBF
<a name="l00272"></a>00272                 &amp;&amp; *(ptr+2) &gt;= 0x80 &amp;&amp; *(ptr+2) &lt;= 0xBF) {
<a name="l00273"></a>00273                 result += *ptr;
<a name="l00274"></a>00274                 result += *(++ptr);
<a name="l00275"></a>00275                 result += *(++ptr);
<a name="l00276"></a>00276             } <span class="keywordflow">else</span> {
<a name="l00277"></a>00277                 <span class="comment">// insert replacement char</span>
<a name="l00278"></a>00278                 result += 0xef;
<a name="l00279"></a>00279                 result += 0xbf;
<a name="l00280"></a>00280                 result += 0xbd;
<a name="l00281"></a>00281             }
<a name="l00282"></a>00282         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*ptr &gt;= 0xF0 &amp;&amp; *ptr &lt;= 0xF4) {
<a name="l00283"></a>00283             <span class="comment">// four-byte sequence</span>
<a name="l00284"></a>00284             <span class="keywordflow">if</span> (*(ptr+1) &gt;= 0x80 &amp;&amp; *(ptr+1) &lt;= 0xBF
<a name="l00285"></a>00285                 &amp;&amp; *(ptr+2) &gt;= 0x80 &amp;&amp; *(ptr+2) &lt;= 0xBF
<a name="l00286"></a>00286                 &amp;&amp; *(ptr+3) &gt;= 0x80 &amp;&amp; *(ptr+3) &lt;= 0xBF) {
<a name="l00287"></a>00287                 result += *ptr;
<a name="l00288"></a>00288                 result += *(++ptr);
<a name="l00289"></a>00289                 result += *(++ptr);
<a name="l00290"></a>00290                 result += *(++ptr);
<a name="l00291"></a>00291             } <span class="keywordflow">else</span> {
<a name="l00292"></a>00292                 <span class="comment">// insert replacement char</span>
<a name="l00293"></a>00293                 result += 0xef;
<a name="l00294"></a>00294                 result += 0xbf;
<a name="l00295"></a>00295                 result += 0xbd;
<a name="l00296"></a>00296             }
<a name="l00297"></a>00297         } <span class="keywordflow">else</span> {
<a name="l00298"></a>00298             <span class="comment">// insert replacement char</span>
<a name="l00299"></a>00299             result += 0xef;
<a name="l00300"></a>00300             result += 0xbf;
<a name="l00301"></a>00301             result += 0xbd;
<a name="l00302"></a>00302         }
<a name="l00303"></a>00303         ++ptr;
<a name="l00304"></a>00304     }
<a name="l00305"></a>00305     
<a name="l00306"></a>00306     <span class="keywordflow">return</span> result;
<a name="l00307"></a>00307 }
<a name="l00308"></a>00308 
<a name="l00309"></a><a class="code" href="structpion_1_1algorithm.html#ab3cce74846661c3585ec5f540a99ff07">00309</a> <span class="keywordtype">void</span> <a class="code" href="structpion_1_1algorithm.html#ab3cce74846661c3585ec5f540a99ff07">algorithm::float_from_bytes</a>(<span class="keywordtype">long</span> <span class="keywordtype">double</span>&amp; value, <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *ptr, <span class="keywordtype">size_t</span> num_exp_bits, <span class="keywordtype">size_t</span> num_fraction_bits)
<a name="l00310"></a>00310 {
<a name="l00311"></a>00311     <span class="comment">// get sign of the number from the first bit</span>
<a name="l00312"></a>00312     <span class="keyword">const</span> <span class="keywordtype">int</span> value_sign = (*ptr &amp; 0x80) ? -1 : 1;
<a name="l00313"></a>00313     
<a name="l00314"></a>00314     <span class="comment">// build exponent value from bitstream</span>
<a name="l00315"></a>00315     <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> mask = 0x80;
<a name="l00316"></a>00316     boost::int16_t exponent = 0;
<a name="l00317"></a>00317     <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> n = 0; n &lt; num_exp_bits; ++n) {
<a name="l00318"></a>00318         SHIFT_BITMASK(ptr, mask);
<a name="l00319"></a>00319         exponent *= 2;
<a name="l00320"></a>00320         <span class="keywordflow">if</span> (*ptr &amp; mask)
<a name="l00321"></a>00321             exponent += 1;
<a name="l00322"></a>00322     }
<a name="l00323"></a>00323     
<a name="l00324"></a>00324     <span class="comment">// build significand from bitstream</span>
<a name="l00325"></a>00325     <span class="keywordtype">long</span> <span class="keywordtype">double</span> significand = exponent ? 1.0 : 0.0;
<a name="l00326"></a>00326     <span class="keywordtype">long</span> <span class="keywordtype">double</span> significand_value = 1.0;
<a name="l00327"></a>00327     <span class="keywordflow">while</span> (num_fraction_bits) {
<a name="l00328"></a>00328         SHIFT_BITMASK(ptr, mask);
<a name="l00329"></a>00329         significand_value /= 2;
<a name="l00330"></a>00330         <span class="keywordflow">if</span> (*ptr &amp; mask)
<a name="l00331"></a>00331             significand += significand_value;
<a name="l00332"></a>00332         --num_fraction_bits;
<a name="l00333"></a>00333     }
<a name="l00334"></a>00334     
<a name="l00335"></a>00335     <span class="comment">// calculate final value</span>
<a name="l00336"></a>00336     exponent -= (::pow((<span class="keywordtype">long</span> double)2, (<span class="keywordtype">int</span>)(num_exp_bits - 1)) - 1);
<a name="l00337"></a>00337     value = value_sign * significand * ::pow((<span class="keywordtype">long</span> double)2, exponent);
<a name="l00338"></a>00338 }
<a name="l00339"></a>00339 
<a name="l00340"></a><a class="code" href="structpion_1_1algorithm.html#a61872c7ccf75793a16d8ce7961f28842">00340</a> <span class="keywordtype">void</span> <a class="code" href="structpion_1_1algorithm.html#a61872c7ccf75793a16d8ce7961f28842">algorithm::float_to_bytes</a>(<span class="keywordtype">long</span> <span class="keywordtype">double</span> value, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *buf, <span class="keywordtype">size_t</span> num_exp_bits, <span class="keywordtype">size_t</span> num_fraction_bits)
<a name="l00341"></a>00341 {
<a name="l00342"></a>00342     <span class="comment">// first initialize output buffer to zeros</span>
<a name="l00343"></a>00343     <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *ptr = buf;
<a name="l00344"></a>00344     memset(ptr, 0x00, ::ceil(static_cast&lt;float&gt;(num_exp_bits + num_fraction_bits + 1) / 8));
<a name="l00345"></a>00345     
<a name="l00346"></a>00346     <span class="comment">// initialize first byte starting with sign of number</span>
<a name="l00347"></a>00347     <span class="keywordflow">if</span> (value &lt; 0) {
<a name="l00348"></a>00348         *ptr = 0x80;
<a name="l00349"></a>00349         value *= -1;
<a name="l00350"></a>00350     }
<a name="l00351"></a>00351     
<a name="l00352"></a>00352     <span class="comment">// break down numbers &gt;= 1.0 by incrementing the exponent &amp; dividing by 2</span>
<a name="l00353"></a>00353     boost::int16_t exponent = 0;
<a name="l00354"></a>00354     <span class="keywordflow">while</span> (value &gt;= 1) {
<a name="l00355"></a>00355         value /= 2;
<a name="l00356"></a>00356         ++exponent;
<a name="l00357"></a>00357     }
<a name="l00358"></a>00358 
<a name="l00359"></a>00359     <span class="comment">// skip past exponent bits because we don&apos;t know the value yet</span>
<a name="l00360"></a>00360     <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> mask = 0x40;
<a name="l00361"></a>00361     <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> n = num_exp_bits; n &gt; 0; --n) {
<a name="l00362"></a>00362         <span class="keywordflow">if</span> (n &gt;= 8) {
<a name="l00363"></a>00363             ++ptr;
<a name="l00364"></a>00364             n -= 7;
<a name="l00365"></a>00365         } <span class="keywordflow">else</span> {
<a name="l00366"></a>00366             SHIFT_BITMASK(ptr, mask);
<a name="l00367"></a>00367         }
<a name="l00368"></a>00368     }
<a name="l00369"></a>00369     
<a name="l00370"></a>00370     <span class="comment">// serialize fractional value &lt; 1.0</span>
<a name="l00371"></a>00371     <span class="keywordtype">bool</span> got_exponent = <span class="keyword">false</span>;
<a name="l00372"></a>00372     boost::uint16_t num_bits = 0;
<a name="l00373"></a>00373     <span class="keywordflow">while</span> (value &amp;&amp; num_bits &lt; num_fraction_bits) {
<a name="l00374"></a>00374         value *= 2;
<a name="l00375"></a>00375         <span class="keywordflow">if</span> (got_exponent) {
<a name="l00376"></a>00376             <span class="keywordflow">if</span> (value &gt;= 1.0) {
<a name="l00377"></a>00377                 *ptr |= mask;
<a name="l00378"></a>00378                 value -= 1.0;
<a name="l00379"></a>00379             }
<a name="l00380"></a>00380             SHIFT_BITMASK(ptr, mask);
<a name="l00381"></a>00381             ++num_bits;
<a name="l00382"></a>00382         } <span class="keywordflow">else</span> {
<a name="l00383"></a>00383             --exponent;
<a name="l00384"></a>00384             <span class="keywordflow">if</span> (value &gt;= 1.0) {
<a name="l00385"></a>00385                 value -= 1.0;
<a name="l00386"></a>00386                 got_exponent = <span class="keyword">true</span>;
<a name="l00387"></a>00387             }
<a name="l00388"></a>00388         }
<a name="l00389"></a>00389     }
<a name="l00390"></a>00390     
<a name="l00391"></a>00391     <span class="comment">// normalize exponent.</span>
<a name="l00392"></a>00392     <span class="comment">// note: we should have a zero exponent if value == 0</span>
<a name="l00393"></a>00393     boost::int32_t high_bit = ::pow((<span class="keywordtype">long</span> double)2, (<span class="keywordtype">int</span>)(num_exp_bits - 1));
<a name="l00394"></a>00394     <span class="keywordflow">if</span> (got_exponent)
<a name="l00395"></a>00395         exponent += (high_bit - 1);
<a name="l00396"></a>00396     <span class="keywordflow">else</span>
<a name="l00397"></a>00397         exponent = 0;
<a name="l00398"></a>00398     
<a name="l00399"></a>00399     <span class="comment">// serialize exponent bits</span>
<a name="l00400"></a>00400     ptr = buf;
<a name="l00401"></a>00401     mask = 0x80;
<a name="l00402"></a>00402     <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> n = 0; n &lt; num_exp_bits; ++n) {
<a name="l00403"></a>00403         SHIFT_BITMASK(ptr, mask);
<a name="l00404"></a>00404         <span class="keywordflow">if</span> (exponent &gt;= high_bit) {
<a name="l00405"></a>00405             *ptr |= mask;
<a name="l00406"></a>00406             exponent -= high_bit;
<a name="l00407"></a>00407         }
<a name="l00408"></a>00408         high_bit /= 2;
<a name="l00409"></a>00409     }
<a name="l00410"></a>00410 }
<a name="l00411"></a>00411     
<a name="l00412"></a>00412 }   <span class="comment">// end namespace pion</span>
</pre></div></div>
<hr size="1"/><address style="text-align: right;"><small>Generated on 16 Sep 2013 for pion by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.1 </small></address>
</body>
</html>