Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8219 was 7954, checked in by patrick, 19 years ago

trunk: merged the network branche back to trunk.

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