Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/converter.cc @ 10674

Last change on this file since 10674 was 9869, checked in by bensch, 18 years ago

orxonox/trunk: merged the new_class_id branche back to the trunk.
merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/new_class_id trunk -r9683:HEAD
no conflicts… puh..

File size: 11.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Wuest (bwuest@ee.ethz.ch)
13   co-programmer: Christoph Renner (rennerc@ee.ethz.ch)
14*/
15
16
17/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
18   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
19*/
20#define DEBUG_MODULE_NETWORK
21
22/* include your own header */
23#include "converter.h"
24#include "shell_command.h"
25#include "debug.h"
26#include <limits>
27
28SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
29
30ObjectListDefinition(Converter);
31/* using namespace std is default, this needs to be here */
32
33
34/*!
35 * Standard constructor
36 */
37Converter::Converter()
38{
39  /* set the class id for the base object */
40}
41
42/*!
43 * Standard destructor
44 */
45Converter::~Converter()
46{
47}
48
49const int sgnadd = 128; // = 2^7
50
51/*!
52 * Converts an int into a byte-array
53 * @remarks: The int is stored in big-endian
54 * @param x: The int which is to convert
55 * @return: A byte-array that accords the given int value
56 */
57byte* Converter::intToByteArray(int x)
58{
59  const int mod = 256; // = 2^8
60
61
62  byte* result = new byte[INTSIZE];
63  int sgn;
64  if (x >= 0)
65    sgn = 1;
66  else
67  {
68    sgn = -1;
69    x = -x;
70  }
71
72  for (int i = 0; i < INTSIZE; i++)
73  {
74    result[i] = x % mod;
75    x /= mod;
76  }
77
78  if (sgn == -1)
79    result[INTSIZE - 1] += sgnadd;
80
81
82  return result;
83}
84
85/*!
86 * Converts an int into a byte-array and stores the result into a given byte-array
87 * @remarks: The int is stored in big-endian
88 * @param x: The int which is to convert
89 * @return: The number of written bytes
90 */
91int Converter::_intToByteArray(int x, byte* a, int length)
92{
93  if (length < INTSIZE)
94  {
95    PRINTF(1)("byte buffer to short to store an int. Needed length %i. Avaiable length %i", INTSIZE, length);
96    return -1;
97  }
98
99  const int mod = 256; // = 2^8
100
101  int sgn;
102  if (x >= 0)
103    sgn = 1;
104  else
105  {
106    sgn = -1;
107    x = -x;
108  }
109
110  for (int i = 0; i < INTSIZE; i++)
111  {
112    a[i] = x % mod;
113    x /= mod;
114  }
115
116  if (sgn == -1)
117    a[INTSIZE - 1] += sgnadd;
118
119  return INTSIZE;
120}
121
122/*!
123 * Converts a byte-array into an int
124 * @param a: The byte-array which is to convert
125 * @param x: The place where the result is stored
126 * @return: The number of read bytes
127 */
128int Converter::_byteArrayToInt(const byte* a, int* x)
129{
130  int mult = 1;
131  const int step = 256; // = 2 ^ 8
132  *x = 0;
133  for (int i = 0; i < INTSIZE - 1; i++)
134  {
135    *x += a[i] * mult;
136    mult *= step;
137  }
138
139  if (a[INTSIZE - 1] >= sgnadd)
140  {
141    *x += (a[INTSIZE - 1] - sgnadd) * mult;
142    *x *= -1;
143  }
144  else
145    *x += a[INTSIZE - 1] * mult;
146
147  return INTSIZE;
148}
149
150int Converter::byteArrayToInt(const byte* a, int* x)
151{
152  memcpy( x, a, INTSIZE );
153  return INTSIZE;
154}
155
156int Converter::intToByteArray(int x, byte* a, int length)
157{
158  if ( length< INTSIZE )
159  {
160    PRINTF(1)("Byte Array to small : %d\n", length);
161    return 0;
162  }
163  memcpy(a, &x, INTSIZE);
164  return INTSIZE;
165}
166
167/*!
168 * Converts a float into a string containing its binary representation
169 * @param x: The float which is to convert
170 * @return: A string containing the float's binary representation
171 */
172char* Converter::floatToBinString(float x)
173{
174  char* result = new char[200];
175  int pos = 0;
176
177  if (x < 0)
178  {
179    result[pos++] = '-';
180    x = -x;
181  }
182
183  float sub = 1;
184  while (sub < x)
185    sub *= 2;
186
187  while ((x > 0 || sub >= 1) && pos < 200)
188  {
189    if (x >= sub)
190    {
191      result[pos] = '1';
192      x -= sub;
193    }
194    else
195      result[pos] = '0';
196    pos++;
197    sub /= 2;
198
199    if (sub == 0.5f)
200      result[pos++] = '.';
201  }
202
203  return result;
204}
205
206const int expmult = 8388608; //2^23
207
208float Converter::getDenormConst()
209{
210  const int exp = 126;
211  float result = 1.0f;
212  for (int i = 0; i < exp; i++)
213    result /= 2.0f;
214  return result;
215}
216
217/*!
218 * Converts a float value into a byte-array and stores the result into a given byte-array
219 * @param x: The float which is to convert
220 * @param a: The byte array where the result is to store
221 * @param length: The length of the array a
222 * @return: The number of written bytes
223 */
224int Converter::_floatToByteArray(float x, byte* a, int length)
225{
226  if (length < FLOATSIZE)
227  {
228    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
229    return -1;
230  }
231
232  //handle 0 else function will loop for ever
233  /*if ( x == 0 )
234  {
235    for ( int i = 0; i<FLOATSIZE; i++)
236      a[i] = 0;
237    return FLOATSIZE;
238}*/
239
240  int mantisse = 0;
241  int exponent = 128;
242
243  int sgn;
244  if (x < 0)
245  {
246    x = -x;
247    sgn = -1;
248  }
249  else
250    sgn = 1;
251
252  if (x == 0)
253  {
254    exponent = 255;
255    mantisse = 0;
256  }
257  else
258  {
259    //if (x < getDenormConst())
260    //  printf("Denormalisiert!\n");
261    //printf("DenormConst = %e", getDenormConst());
262
263    float sub = 1;
264    while (sub < x)
265    {
266      sub *= 2;
267      exponent++;
268    }
269
270    while (x > 0)
271    {
272      if (x >= sub)
273      {
274        mantisse += 1;
275        x -= sub;
276      }
277
278      mantisse *= 2;
279      exponent--;
280      sub /= 2;
281    }
282    exponent++;
283    mantisse /= 2;
284
285
286///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
287
288
289    //if (mantisse != 0)
290    //{
291      while (mantisse < expmult)
292      {
293        mantisse *= 2;
294        exponent--;
295      }
296
297      if (exponent >= 0)
298        mantisse -= expmult;
299      else
300      {
301        //Denormalized
302        while (exponent < 0)
303        {
304          mantisse /= 2;
305          exponent++;
306        }
307        printf("Conv: Denorm");
308      }
309    //}
310  }
311
312///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
313
314
315  int hx = mantisse + expmult * exponent;
316  //int result = intToByteArray(hx, a, length);
317  intToByteArray(hx, a, length);
318  if (sgn == -1)
319    a[3] += sgnadd;
320
321
322//  int hx = mantisse + expmult * exponent;
323//  byte* result = intToByteArray(hx);
324//  if (sgn == -1)
325//    result[3] += sgnadd;
326
327  //return result;
328  return FLOATSIZE;
329}
330
331
332/*!
333 * Converts a byte-array into a float value
334 * @param a: The byte-array which is to convert
335 * @param x: The place where the result is to store
336 * @return: The number of read bytes
337 */
338int Converter::_byteArrayToFloat(const byte* a, float* x)
339{
340    //handle 0
341  /*for (int i = 0; i<FLOATSIZE; i++)
342  {
343    if (a[i]!=0)
344      break;
345    if ( i==FLOATSIZE-1 )
346    {
347      *x = 0.0f;
348      return FLOATSIZE;
349    }
350}*/
351
352  int hexp = a[2] + a[3] * 256;
353  int exponent = (hexp / 128) % 256;
354
355  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
356  int mantisse = hmant % expmult;
357
358  //handle 0
359  if (mantisse == 0 && exponent == 255)
360  {
361    *x = 0;
362    return FLOATSIZE;
363  }
364  else if (exponent == 0 && mantisse != 0)
365  {
366    exponent = -126;
367    printf("ReConv: Denorm");
368  }
369  else
370  {
371    mantisse += expmult;
372    exponent -= 128;
373  }
374
375  int sgn;
376  if (a[3] >= sgnadd)
377    sgn = -1;
378  else
379    sgn = 1;
380
381///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
382
383  float emult = 1;
384  if (exponent > 0)
385    for (int i = 0; i < exponent; i++)
386      emult *= 2;
387  else if (exponent < 0)
388    for (int i = 0; i > exponent; i--)
389      emult /= 2;
390
391  /*
392  float result = mantisse * emult;
393  if (sgn == -1)
394    result = -result;
395
396  return result;
397  */
398
399  *x = mantisse * emult;
400  if (sgn == -1)
401    *x = -  *x;
402
403  return FLOATSIZE;
404}
405
406/*!
407 * Converts a float value into a byte-array
408 * @param x: The float which is to convert
409 * @param a: The array where the result is to store
410 * @param length: The length of the array a
411 * @return: The number of written bytes
412 */
413int Converter::floatToByteArray(float x, byte* a, int length)
414{
415  if ( length< FLOATSIZE )
416  {
417    PRINTF(1)("Byte Array to small\n");
418    return 0;
419  }
420  byte* p = (byte*)&x;
421
422  for (int i = 0; i < 4; i++)
423    a[i] = p[i];
424
425  return FLOATSIZE;
426}
427
428
429/*!
430 * Converts a byte-array into a float value
431 * @param a: The byte-array which is to convert
432 * @param x: The place where the result is to store
433 * @return: The number of read bytes
434 */
435int Converter::byteArrayToFloat(const byte* a, float* x)
436{
437  *x = *((float*)a);
438
439  return FLOATSIZE;
440}
441
442
443
444
445
446
447
448
449
450
451/**
452 * copies a strint to a byte array
453 * @param s: string to copy
454 * @param a: byte array
455 * @param length: string length
456 * @return: the used number of bytes in byte array
457 */
458int Converter::stringToByteArray( const std::string & s, byte * a, int maxLength )
459{
460  if ( s.length()+INTSIZE > maxLength )
461  {
462    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, s.length()+INTSIZE);
463    return -1;
464  }
465
466  int n = Converter::intToByteArray( s.length(), a, maxLength );
467
468  memcpy( a+INTSIZE, s.c_str(), s.length() );
469
470  return s.length() + INTSIZE;
471}
472
473/**
474 * reads a string out of a byte array
475 * @param a: byte array
476 * @param s: string
477 * @param maxLength: max bytes to copy
478 * @return: the number of read bytes in byte array
479 */
480int Converter::byteArrayToString( const byte * a, std::string&s, int maxLength )
481{
482  int length;
483
484  int n = Converter::byteArrayToInt( a, &length );
485
486
487  if ( length+1 > maxLength )
488  {
489    PRINTF(1)("something went wrong length > remaining bytes in buffer\n" );
490
491    //TODO remove this
492    for ( int i = -1000; i < 1001; i++ )
493    {
494      if ( ( a[i] > 'a' && a[i] < 'z' ) || ( a[i] > 'A' && a[i] < 'Z' ) )
495        printf("%c", a[i]);
496      else
497        printf(".");
498    }
499    printf("\n");
500
501    s = "";
502    return -1;
503  }
504
505  s = "";
506  s.append( (char*)a+n, length );
507
508  return n+length;
509}
510
511#if 0
512/**
513 * reads a string out of a byte array and allocates memory for string
514 * @param a: byte array
515 * @param s: string
516 * @param maxLength: max bytes to copy
517 * @return: the number of read bytes in byte array
518 */
519int Converter::byteArrayToStringM( const byte * a, char*& s )
520{
521  int length;
522
523  int n = Converter::byteArrayToInt( a, &length );
524
525  s = new char[length+1];
526
527  if ( !s )
528  {
529    PRINTF(1)("Could not allocate memory!\n" );
530    return -1;
531  }
532
533  memcpy( s, a+n, length );
534  s[length] = '\0';
535
536  return n+length;
537}
538#endif
539
540
541
542void Converter::floatTest(float x)
543{
544  //float x = 8.0f;
545  //float x = numeric_limits<float>::infinity();
546
547  printf("To Convert: %e\n", x);
548
549//  byte* res = floatToByteArray(x);
550//   for (int i = 0; i < 4; i++)
551//     printf("%i ", res[i]);
552//   printf("\n");
553
554//  float y = byteArrayToFloat(res);
555//   printf("ReConvert: %e\n", y);
556
557//   if (x == y)
558//     printf("equal\n");
559//   else
560//     printf("different\n");
561}
562
563void Converter::ArrayfloatTest(float x)
564{
565  //float x = 8.0f;
566  //float x = numeric_limits<float>::infinity();
567
568  printf("To Convert: %e\n", x);
569  byte* res = new byte[4];
570
571  int wr = floatToByteArray(x, res, 4);
572  for (int i = 0; i < 4; i++)
573    printf("%i ", res[i]);
574  printf("  written bytes: %i \n", wr);
575
576  float y;
577  int rd = byteArrayToFloat(res, &y);
578  printf("ReConvert: %e\n", y);
579  printf("Read bytes: %i   ->  ", rd);
580
581  if (x == y)
582    printf("equal\n");
583  else
584    printf("different\n");
585}
586
587void Converter::debug()
588{
589  printf("We rulez\n");
590
591  ArrayfloatTest(0.125f);
592  ArrayfloatTest(64.0f);
593  ArrayfloatTest(0.0f);
594  ArrayfloatTest(5.00091e-29f);
595
596  //floatTest(-18.0098f);
597  //floatTest(-24.07e23f);
598  //floatTest(-0.0f);
599  //floatTest(-5.67e-29f);
600
601
602  //floatTest(-45.7e-32f);
603  //floatTest(45.7e-33f);
604  //floatTest(-45.7e-34f);
605  //floatTest(45.7e-35f);
606}
Note: See TracBrowser for help on using the repository browser.