Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: merged the network branche back to trunk.

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