Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6784 was 6753, checked in by patrick, 19 years ago

trunk: merged network back to trunk

File size: 10.7 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 */
92int Converter::intToByteArray(int x, byte* a, int length)
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 */
[6341]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
[6341]151/*!
152 * Converts a float into a string containing its binary representation
[6737]153 * @param x: The float which is to convert
154 * @return: A string containing the float's binary representation
[6341]155 */
156char* Converter::floatToBinString(float x)
[6128]157{
158  char* result = new char[200];
159  int pos = 0;
[6341]160
161  if (x < 0)
[6128]162  {
[6341]163    result[pos++] = '-';
164    x = -x;
[6128]165  }
[6341]166
167  float sub = 1;
168  while (sub < x)
169    sub *= 2;
170
171  while ((x > 0 || sub >= 1) && pos < 200)
[6128]172  {
173    if (x >= sub)
174    {
175      result[pos] = '1';
176      x -= sub;
177    }
178    else
179      result[pos] = '0';
180    pos++;
181    sub /= 2;
[6341]182
183    if (sub == 0.5f)
184      result[pos++] = '.';
[6128]185  }
[6341]186
[6128]187  return result;
[6341]188}
[6128]189
[6341]190const int expmult = 8388608; //2^23
191
[6634]192float Converter::getDenormConst()
193{
194  const int exp = 126;
195  float result = 1.0f;
196  for (int i = 0; i < exp; i++)
197    result /= 2.0f;
198  return result;
199}
200
[6341]201/*!
202 * Converts a float value into a byte-array and stores the result into a given byte-array
203 * @param x: The float which is to convert
[6737]204 * @param a: The byte array where the result is to store
205 * @param length: The length of the array a
206 * @return: The number of written bytes
[6341]207 */
[6753]208int Converter::_floatToByteArray(float x, byte* a, int length)
[6341]209{
210  if (length < FLOATSIZE)
211  {
212    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
213    return -1;
214  }
215
216  //handle 0 else function will loop for ever
[6634]217  /*if ( x == 0 )
[6341]218  {
219    for ( int i = 0; i<FLOATSIZE; i++)
220      a[i] = 0;
221    return FLOATSIZE;
[6634]222}*/
[6341]223
224  int mantisse = 0;
225  int exponent = 128;
226
227  int sgn;
228  if (x < 0)
229  {
230    x = -x;
231    sgn = -1;
232  }
233  else
234    sgn = 1;
235
[6634]236  if (x == 0)
[6341]237  {
[6634]238    exponent = 255;
239    mantisse = 0;
[6341]240  }
[6634]241  else
242  {
243    //if (x < getDenormConst())
244    //  printf("Denormalisiert!\n");
245    //printf("DenormConst = %e", getDenormConst());
[6341]246
[6634]247    float sub = 1;
248    while (sub < x)
[6128]249    {
[6634]250      sub *= 2;
251      exponent++;
[6128]252    }
[6341]253
[6634]254    while (x > 0)
255    {
256      if (x >= sub)
257      {
258        mantisse += 1;
259        x -= sub;
260      }
261
262      mantisse *= 2;
263      exponent--;
264      sub /= 2;
265    }
266    exponent++;
267    mantisse /= 2;
268
269
270///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
271
272
[6737]273    //if (mantisse != 0)
274    //{
[6634]275      while (mantisse < expmult)
276      {
277        mantisse *= 2;
278        exponent--;
279      }
280
[6737]281      if (exponent >= 0)
282        mantisse -= expmult;
283      else
284      {
285        //Denormalized
286        while (exponent < 0)
287        {
288          mantisse /= 2;
289          exponent++;
290        }
291        printf("Conv: Denorm");
292      }
293    //}
[6128]294  }
[6341]295
[6634]296///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]297
298
299  int hx = mantisse + expmult * exponent;
[6737]300  //int result = intToByteArray(hx, a, length);
301  intToByteArray(hx, a, length);
[6341]302  if (sgn == -1)
303    a[3] += sgnadd;
304
[6634]305
306//  int hx = mantisse + expmult * exponent;
307//  byte* result = intToByteArray(hx);
308//  if (sgn == -1)
309//    result[3] += sgnadd;
310
[6737]311  //return result;
312  return FLOATSIZE;
[6128]313}
[6341]314
315
316/*!
317 * Converts a byte-array into a float value
318 * @param a: The byte-array which is to convert
[6737]319 * @param x: The place where the result is to store
320 * @return: The number of read bytes
[6341]321 */
[6753]322int Converter::_byteArrayToFloat(const byte* a, float* x)
[6341]323{
[6634]324    //handle 0
325  /*for (int i = 0; i<FLOATSIZE; i++)
[6341]326  {
327    if (a[i]!=0)
328      break;
329    if ( i==FLOATSIZE-1 )
330    {
331      *x = 0.0f;
332      return FLOATSIZE;
333    }
[6634]334}*/
[6341]335
[6634]336  int hexp = a[2] + a[3] * 256;
337  int exponent = (hexp / 128) % 256;
[6341]338
339  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
340  int mantisse = hmant % expmult;
[6634]341
342  //handle 0
343  if (mantisse == 0 && exponent == 255)
344  {
345    *x = 0;
346    return FLOATSIZE;
347  }
[6737]348  else if (exponent == 0 && mantisse != 0)
349  {
350    exponent = -126;
351    printf("ReConv: Denorm");
352  }
353  else
354  {
355    mantisse += expmult;
356    exponent -= 128;
357  }
[6634]358
[6341]359  int sgn;
360  if (a[3] >= sgnadd)
361    sgn = -1;
362  else
363    sgn = 1;
364
[6634]365///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]366
367  float emult = 1;
368  if (exponent > 0)
369    for (int i = 0; i < exponent; i++)
370      emult *= 2;
371  else if (exponent < 0)
372    for (int i = 0; i > exponent; i--)
373      emult /= 2;
374
[6634]375  /*
376  float result = mantisse * emult;
377  if (sgn == -1)
378    result = -result;
379
380  return result;
381  */
382
[6341]383  *x = mantisse * emult;
384  if (sgn == -1)
385    *x = -  *x;
386
387  return FLOATSIZE;
388}
389
[6634]390/*!
391 * Converts a float value into a byte-array
392 * @param x: The float which is to convert
[6737]393 * @param a: The array where the result is to store
394 * @param length: The length of the array a
395 * @return: The number of written bytes
[6634]396 */
[6753]397int Converter::floatToByteArray(float x, byte* a, int length)
[6634]398{
[6737]399  if ( length< FLOATSIZE )
[6634]400  {
401    PRINTF(1)("Byte Array to small\n");
402    return 0;
403  }
404  byte* p = (byte*)&x;
405
406  for (int i = 0; i < 4; i++)
407    a[i] = p[i];
[6753]408
[6737]409  return FLOATSIZE;
[6634]410}
411
412
413/*!
414 * Converts a byte-array into a float value
415 * @param a: The byte-array which is to convert
[6737]416 * @param x: The place where the result is to store
417 * @return: The number of read bytes
[6634]418 */
[6753]419int Converter::byteArrayToFloat(const byte* a, float* x)
[6634]420{
421  *x = *((float*)a);
422
[6737]423  return FLOATSIZE;
[6634]424}
425
[6737]426
427
428
429
430
431
432
433
434
[6341]435/**
436 * copies a strint to a byte array
437 * @param s: string to copy
438 * @param a: byte array
439 * @param length: string length
440 * @return: the used number of bytes in byte array
441 */
442int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
443{
444  if ( length+INTSIZE > maxLength )
445  {
446    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
447    return -1;
448  }
449
450  int n = Converter::intToByteArray( length, a, maxLength );
451
452  memcpy( a+INTSIZE, s, length );
453
454  return length + INTSIZE;
455}
456
457/**
458 * reads a string out of a byte array
459 * @param a: byte array
460 * @param s: string
461 * @param maxLength: max bytes to copy
462 * @return: the number of read bytes in byte array
463 */
464int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
465{
466  int length;
467
468  int n = Converter::byteArrayToInt( a, &length );
469
470
471  if ( length+1 > maxLength )
472  {
473    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
474    strncpy(s,"",maxLength);
475    return -1;
476  }
477
478  memcpy( s, a+n, length );
479  s[length] = '\0';
480
481  return n+length;
482}
483
484/**
485 * reads a string out of a byte array and allocates memory for string
486 * @param a: byte array
487 * @param s: string
488 * @param maxLength: max bytes to copy
489 * @return: the number of read bytes in byte array
490 */
491int Converter::byteArrayToStringM( const byte * a, char*& s )
492{
493  int length;
494
495  int n = Converter::byteArrayToInt( a, &length );
496
497  s = new char[length+1];
498
499  if ( !s )
500  {
501    PRINTF(1)("Could not allocate memory!\n" );
502    return -1;
503  }
504
505  memcpy( s, a+n, length );
506  s[length] = '\0';
507
508  return n+length;
509}
510
[6634]511
512
513
514void Converter::floatTest(float x)
515{
516  //float x = 8.0f;
517  //float x = numeric_limits<float>::infinity();
518
519  printf("To Convert: %e\n", x);
520
[6753]521//  byte* res = floatToByteArray(x);
522//   for (int i = 0; i < 4; i++)
523//     printf("%i ", res[i]);
524//   printf("\n");
[6634]525
[6753]526//  float y = byteArrayToFloat(res);
527//   printf("ReConvert: %e\n", y);
[6634]528
[6753]529//   if (x == y)
530//     printf("equal\n");
531//   else
532//     printf("different\n");
[6634]533}
534
[6737]535void Converter::ArrayfloatTest(float x)
536{
537  //float x = 8.0f;
538  //float x = numeric_limits<float>::infinity();
539
540  printf("To Convert: %e\n", x);
541  byte* res = new byte[4];
542
543  int wr = floatToByteArray(x, res, 4);
544  for (int i = 0; i < 4; i++)
545    printf("%i ", res[i]);
546  printf("  written bytes: %i \n", wr);
547
548  float y;
549  int rd = byteArrayToFloat(res, &y);
550  printf("ReConvert: %e\n", y);
551  printf("Read bytes: %i   ->  ", rd);
552
553  if (x == y)
554    printf("equal\n");
555  else
556    printf("different\n");
557}
558
[6634]559void Converter::debug()
560{
561  printf("We rulez\n");
562
[6737]563  ArrayfloatTest(0.125f);
564  ArrayfloatTest(64.0f);
565  ArrayfloatTest(0.0f);
566  ArrayfloatTest(5.00091e-29f);
[6634]567
568  //floatTest(-18.0098f);
569  //floatTest(-24.07e23f);
570  //floatTest(-0.0f);
571  //floatTest(-5.67e-29f);
[6753]572
573
[6737]574  //floatTest(-45.7e-32f);
575  //floatTest(45.7e-33f);
576  //floatTest(-45.7e-34f);
577  //floatTest(45.7e-35f);
[6634]578}
Note: See TracBrowser for help on using the repository browser.