Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10230 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
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:
[9406]12   main-programmer: Benjamin Wuest (bwuest@ee.ethz.ch)
13   co-programmer: Christoph Renner (rennerc@ee.ethz.ch)
[6106]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"
[8362]25#include "debug.h"
[6634]26#include <limits>
[6106]27
[6634]28SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
29
[9869]30ObjectListDefinition(Converter);
[6106]31/* using namespace std is default, this needs to be here */
32
[9406]33
[6106]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
[6341]60
61
[6106]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  }
[6341]71
[6106]72  for (int i = 0; i < INTSIZE; i++)
73  {
74    result[i] = x % mod;
75    x /= mod;
76  }
[6341]77
[6106]78  if (sgn == -1)
79    result[INTSIZE - 1] += sgnadd;
[6341]80
81
[6106]82  return result;
83}
84
85/*!
[6341]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
[6737]89 * @return: The number of written bytes
[6341]90 */
[6959]91int Converter::_intToByteArray(int x, byte* a, int length)
[6341]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/*!
[6106]123 * Converts a byte-array into an int
124 * @param a: The byte-array which is to convert
[6737]125 * @param x: The place where the result is stored
126 * @return: The number of read bytes
[6106]127 */
[6959]128int Converter::_byteArrayToInt(const byte* a, int* x)
[6106]129{
130  int mult = 1;
131  const int step = 256; // = 2 ^ 8
[6341]132  *x = 0;
[6108]133  for (int i = 0; i < INTSIZE - 1; i++)
[6106]134  {
[6341]135    *x += a[i] * mult;
[6106]136    mult *= step;
137  }
[6341]138
[6108]139  if (a[INTSIZE - 1] >= sgnadd)
[6106]140  {
[6341]141    *x += (a[INTSIZE - 1] - sgnadd) * mult;
142    *x *= -1;
[6106]143  }
144  else
[6341]145    *x += a[INTSIZE - 1] * mult;
146
147  return INTSIZE;
[6106]148}
[6128]149
[6959]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  {
[7230]160    PRINTF(1)("Byte Array to small : %d\n", length);
[6959]161    return 0;
162  }
163  memcpy(a, &x, INTSIZE);
164  return INTSIZE;
165}
166
[6341]167/*!
168 * Converts a float into a string containing its binary representation
[6737]169 * @param x: The float which is to convert
170 * @return: A string containing the float's binary representation
[6341]171 */
172char* Converter::floatToBinString(float x)
[6128]173{
174  char* result = new char[200];
175  int pos = 0;
[6341]176
177  if (x < 0)
[6128]178  {
[6341]179    result[pos++] = '-';
180    x = -x;
[6128]181  }
[6341]182
183  float sub = 1;
184  while (sub < x)
185    sub *= 2;
186
187  while ((x > 0 || sub >= 1) && pos < 200)
[6128]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;
[6341]198
199    if (sub == 0.5f)
200      result[pos++] = '.';
[6128]201  }
[6341]202
[6128]203  return result;
[6341]204}
[6128]205
[6341]206const int expmult = 8388608; //2^23
207
[6634]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
[6341]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
[6737]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
[6341]223 */
[6753]224int Converter::_floatToByteArray(float x, byte* a, int length)
[6341]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
[6634]233  /*if ( x == 0 )
[6341]234  {
235    for ( int i = 0; i<FLOATSIZE; i++)
236      a[i] = 0;
237    return FLOATSIZE;
[6634]238}*/
[6341]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
[6634]252  if (x == 0)
[6341]253  {
[6634]254    exponent = 255;
255    mantisse = 0;
[6341]256  }
[6634]257  else
258  {
259    //if (x < getDenormConst())
260    //  printf("Denormalisiert!\n");
261    //printf("DenormConst = %e", getDenormConst());
[6341]262
[6634]263    float sub = 1;
264    while (sub < x)
[6128]265    {
[6634]266      sub *= 2;
267      exponent++;
[6128]268    }
[6341]269
[6634]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
[6737]289    //if (mantisse != 0)
290    //{
[6634]291      while (mantisse < expmult)
292      {
293        mantisse *= 2;
294        exponent--;
295      }
296
[6737]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    //}
[6128]310  }
[6341]311
[6634]312///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]313
314
315  int hx = mantisse + expmult * exponent;
[6737]316  //int result = intToByteArray(hx, a, length);
317  intToByteArray(hx, a, length);
[6341]318  if (sgn == -1)
319    a[3] += sgnadd;
320
[6634]321
322//  int hx = mantisse + expmult * exponent;
323//  byte* result = intToByteArray(hx);
324//  if (sgn == -1)
325//    result[3] += sgnadd;
326
[6737]327  //return result;
328  return FLOATSIZE;
[6128]329}
[6341]330
331
332/*!
333 * Converts a byte-array into a float value
334 * @param a: The byte-array which is to convert
[6737]335 * @param x: The place where the result is to store
336 * @return: The number of read bytes
[6341]337 */
[6753]338int Converter::_byteArrayToFloat(const byte* a, float* x)
[6341]339{
[6634]340    //handle 0
341  /*for (int i = 0; i<FLOATSIZE; i++)
[6341]342  {
343    if (a[i]!=0)
344      break;
345    if ( i==FLOATSIZE-1 )
346    {
347      *x = 0.0f;
348      return FLOATSIZE;
349    }
[6634]350}*/
[6341]351
[6634]352  int hexp = a[2] + a[3] * 256;
353  int exponent = (hexp / 128) % 256;
[6341]354
355  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
356  int mantisse = hmant % expmult;
[6634]357
358  //handle 0
359  if (mantisse == 0 && exponent == 255)
360  {
361    *x = 0;
362    return FLOATSIZE;
363  }
[6737]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  }
[6634]374
[6341]375  int sgn;
376  if (a[3] >= sgnadd)
377    sgn = -1;
378  else
379    sgn = 1;
380
[6634]381///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]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
[6634]391  /*
392  float result = mantisse * emult;
393  if (sgn == -1)
394    result = -result;
395
396  return result;
397  */
398
[6341]399  *x = mantisse * emult;
400  if (sgn == -1)
401    *x = -  *x;
402
403  return FLOATSIZE;
404}
405
[6634]406/*!
407 * Converts a float value into a byte-array
408 * @param x: The float which is to convert
[6737]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
[6634]412 */
[6753]413int Converter::floatToByteArray(float x, byte* a, int length)
[6634]414{
[6737]415  if ( length< FLOATSIZE )
[6634]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];
[6753]424
[6737]425  return FLOATSIZE;
[6634]426}
427
428
429/*!
430 * Converts a byte-array into a float value
431 * @param a: The byte-array which is to convert
[6737]432 * @param x: The place where the result is to store
433 * @return: The number of read bytes
[6634]434 */
[6753]435int Converter::byteArrayToFloat(const byte* a, float* x)
[6634]436{
437  *x = *((float*)a);
438
[6737]439  return FLOATSIZE;
[6634]440}
441
[6737]442
443
444
445
446
447
448
449
450
[6341]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 */
[7230]458int Converter::stringToByteArray( const std::string & s, byte * a, int maxLength )
[6341]459{
[7230]460  if ( s.length()+INTSIZE > maxLength )
[6341]461  {
[7230]462    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, s.length()+INTSIZE);
[6341]463    return -1;
464  }
465
[7230]466  int n = Converter::intToByteArray( s.length(), a, maxLength );
[6341]467
[7230]468  memcpy( a+INTSIZE, s.c_str(), s.length() );
[6341]469
[7230]470  return s.length() + INTSIZE;
[6341]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 */
[7230]480int Converter::byteArrayToString( const byte * a, std::string&s, int maxLength )
[6341]481{
482  int length;
483
484  int n = Converter::byteArrayToInt( a, &length );
485
486
487  if ( length+1 > maxLength )
488  {
[7230]489    PRINTF(1)("something went wrong length > remaining bytes in buffer\n" );
[8362]490
[7954]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");
[8362]500
[7230]501    s = "";
[6341]502    return -1;
503  }
504
[7954]505  s = "";
[7230]506  s.append( (char*)a+n, length );
[6341]507
508  return n+length;
509}
510
[7230]511#if 0
[6341]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}
[7230]538#endif
[6341]539
[6634]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
[6753]549//  byte* res = floatToByteArray(x);
550//   for (int i = 0; i < 4; i++)
551//     printf("%i ", res[i]);
552//   printf("\n");
[6634]553
[6753]554//  float y = byteArrayToFloat(res);
555//   printf("ReConvert: %e\n", y);
[6634]556
[6753]557//   if (x == y)
558//     printf("equal\n");
559//   else
560//     printf("different\n");
[6634]561}
562
[6737]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
[6634]587void Converter::debug()
588{
589  printf("We rulez\n");
590
[6737]591  ArrayfloatTest(0.125f);
592  ArrayfloatTest(64.0f);
593  ArrayfloatTest(0.0f);
594  ArrayfloatTest(5.00091e-29f);
[6634]595
596  //floatTest(-18.0098f);
597  //floatTest(-24.07e23f);
598  //floatTest(-0.0f);
599  //floatTest(-5.67e-29f);
[6753]600
601
[6737]602  //floatTest(-45.7e-32f);
603  //floatTest(45.7e-33f);
604  //floatTest(-45.7e-34f);
605  //floatTest(45.7e-35f);
[6634]606}
Note: See TracBrowser for help on using the repository browser.