Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6461 was 6341, checked in by bensch, 19 years ago

orxonox/trunk: merged the network branche back to the trunk, so we do not get away from each other to fast

File size: 9.3 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"
24
25
26/* using namespace std is default, this needs to be here */
27using namespace std;
28
29/*!
30 * Standard constructor
31 */
32Converter::Converter()
33{
34  /* set the class id for the base object */
35  //this->setClassID(CL_ENTITY_MANAGER, "EntityManager");
36}
37
38/*!
39 * Standard destructor
40 */
41Converter::~Converter()
42{
43}
44
45const int sgnadd = 128; // = 2^7
46
47/*!
48 * Converts an int into a byte-array
49 * @remarks: The int is stored in big-endian
50 * @param x: The int which is to convert
51 * @return: A byte-array that accords the given int value
52 */
53byte* Converter::intToByteArray(int x)
54{
55  const int mod = 256; // = 2^8
[6341]56
57
[6106]58  byte* result = new byte[INTSIZE];
59  int sgn;
60  if (x >= 0)
61    sgn = 1;
62  else
63  {
64    sgn = -1;
65    x = -x;
66  }
[6341]67
[6106]68  for (int i = 0; i < INTSIZE; i++)
69  {
70    result[i] = x % mod;
71    x /= mod;
72  }
[6341]73
[6106]74  if (sgn == -1)
75    result[INTSIZE - 1] += sgnadd;
[6341]76
77
[6106]78  return result;
79}
80
81/*!
[6341]82 * Converts an int into a byte-array and stores the result into a given byte-array
83 * @remarks: The int is stored in big-endian
84 * @param x: The int which is to convert
85 * @return: A byte-array that accords the given int value
86 */
87int Converter::intToByteArray(int x, byte* a, int length)
88{
89  if (length < INTSIZE)
90  {
91    PRINTF(1)("byte buffer to short to store an int. Needed length %i. Avaiable length %i", INTSIZE, length);
92    return -1;
93  }
94
95  const int mod = 256; // = 2^8
96
97  int sgn;
98  if (x >= 0)
99    sgn = 1;
100  else
101  {
102    sgn = -1;
103    x = -x;
104  }
105
106  for (int i = 0; i < INTSIZE; i++)
107  {
108    a[i] = x % mod;
109    x /= mod;
110  }
111
112  if (sgn == -1)
113    a[INTSIZE - 1] += sgnadd;
114
115  return INTSIZE;
116}
117
118/*!
[6106]119 * Converts a byte-array into an int
120 * @param a: The byte-array which is to convert
121 * @return: An int that accords the given byte-array
122 */
[6341]123int Converter::byteArrayToInt(const byte* a, int* x)
[6106]124{
125  int mult = 1;
126  const int step = 256; // = 2 ^ 8
[6341]127  *x = 0;
[6108]128  for (int i = 0; i < INTSIZE - 1; i++)
[6106]129  {
[6341]130    *x += a[i] * mult;
[6106]131    mult *= step;
132  }
[6341]133
[6108]134  if (a[INTSIZE - 1] >= sgnadd)
[6106]135  {
[6341]136    *x += (a[INTSIZE - 1] - sgnadd) * mult;
137    *x *= -1;
[6106]138  }
139  else
[6341]140    *x += a[INTSIZE - 1] * mult;
141
142  return INTSIZE;
[6106]143}
[6128]144
[6341]145/*!
146 * Converts a float into a string containing its binary representation
147 */
148char* Converter::floatToBinString(float x)
[6128]149{
150  char* result = new char[200];
151  int pos = 0;
[6341]152
153  if (x < 0)
[6128]154  {
[6341]155    result[pos++] = '-';
156    x = -x;
[6128]157  }
[6341]158
159  float sub = 1;
160  while (sub < x)
161    sub *= 2;
162
163  while ((x > 0 || sub >= 1) && pos < 200)
[6128]164  {
165    if (x >= sub)
166    {
167      result[pos] = '1';
168      x -= sub;
169    }
170    else
171      result[pos] = '0';
172    pos++;
173    sub /= 2;
[6341]174
175    if (sub == 0.5f)
176      result[pos++] = '.';
[6128]177  }
[6341]178
[6128]179  return result;
[6341]180}
[6128]181
[6341]182const int expmult = 8388608; //2^23
183
184/*!
185 * Converts a float value into a byte-array
186 * @param x: The float which is to convert
187 * @return: A byte-array which accords the given float
188 */
189byte* Converter::floatToByteArray(float x)
[6128]190{
[6341]191  int mantisse = 0;
192  int exponent = 128;
193
194  int sgn;
195  if (x < 0)
196  {
197    x = -x;
198    sgn = -1;
199  }
200  else
201    sgn = 1;
202
[6128]203  float sub = 1;
204  while (sub < x)
[6341]205  {
[6128]206    sub *= 2;
[6341]207    exponent++;
208  }
209
210  while (x > 0)
[6128]211  {
212    if (x >= sub)
213    {
[6341]214      mantisse += 1;
[6128]215      x -= sub;
216    }
[6341]217
218    mantisse *= 2;
219    exponent--;
[6128]220    sub /= 2;
221  }
[6341]222  exponent++;
223  mantisse /= 2;
224  while (mantisse < expmult)
[6128]225  {
[6341]226    mantisse *= 2;
227    exponent--;
228  }
229
230  //printf("mantisse = %i exponent = %i \n", mantisse, exponent);
231
232  mantisse -= expmult;
233
234  int hx = mantisse + expmult * exponent;
235  byte* result = intToByteArray(hx);
236  if (sgn == -1)
237    result[3] += sgnadd;
238
239  return result;
240}
241
242
243/*!
244 * Converts a byte-array into a float value
245 * @param a: The byte-array which is to convert
246 * @return: A float value which accords the given byte-array
247 */
248float Converter::byteArrayToFloat(byte* a)
249{
250  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
251  int mantisse = hmant % expmult;
252  mantisse += expmult;
253
254  int hexp = a[2] + a[3] * 256;
255  int exponent = (hexp / 128) % 256 - 128;
256
257  int sgn;
258  if (a[3] >= sgnadd)
259    sgn = -1;
260  else
261    sgn = 1;
262
263  //printf("mantisse = %i exponent = %i \n", mantisse, exponent);
264
265  float emult = 1;
266  if (exponent > 0)
267    for (int i = 0; i < exponent; i++)
268      emult *= 2;
269  else if (exponent < 0)
270    for (int i = 0; i > exponent; i--)
271      emult /= 2;
272
273  float result = mantisse * emult;
274  if (sgn == -1)
275    result = -result;
276
277  return result;
278}
279
280/*!
281 * Converts a float value into a byte-array
282 * @param x: The float which is to convert
283 * @return: A byte-array which accords the given float
284 */
285byte* Converter::_floatToByteArray(float x)
286{
287  byte* p = (byte*)&x;
288  byte* result = new byte[4];
289  for (int i = 0; i < 4; i++)
290    result[i] = p[i];
291  return result;
292}
293
294
295/*!
296 * Converts a byte-array into a float value
297 * @param a: The byte-array which is to convert
298 * @return: A float value which accords the given byte-array
299 */
300float Converter::_byteArrayToFloat(byte* a)
301{
302  float* p = (float*)a;
303  float result = *p;
304  return result;
305}
306
307/*!
308 * Converts a float value into a byte-array and stores the result into a given byte-array
309 * @param x: The float which is to convert
310 * @return: A byte-array which accords the given float
311 */
312int Converter::floatToByteArray(float x, byte* a, int length)
313{
314  if (length < FLOATSIZE)
315  {
316    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
317    return -1;
318  }
319
320  //handle 0 else function will loop for ever
321  if ( x == 0 )
322  {
323    for ( int i = 0; i<FLOATSIZE; i++)
324      a[i] = 0;
325    return FLOATSIZE;
326  }
327
328  int mantisse = 0;
329  int exponent = 128;
330
331  int sgn;
332  if (x < 0)
333  {
334    x = -x;
335    sgn = -1;
336  }
337  else
338    sgn = 1;
339
340  float sub = 1;
341  while (sub < x)
342  {
343    sub *= 2;
344    exponent++;
345  }
346
347  while (x > 0)
348  {
[6128]349    if (x >= sub)
350    {
[6341]351      mantisse += 1;
[6128]352      x -= sub;
353    }
[6341]354
355    mantisse *= 2;
356    exponent--;
[6128]357    sub /= 2;
358  }
[6341]359  exponent++;
360  mantisse /= 2;
361  while (mantisse < expmult)
362  {
363    mantisse *= 2;
364    exponent--;
365  }
366
367  //printf("mantisse = %i exponent = %i \n", mantisse, exponent);
368
369  mantisse -= expmult;
370
371  int hx = mantisse + expmult * exponent;
372  int result = intToByteArray(hx, a, length);
373  if (sgn == -1)
374    a[3] += sgnadd;
375
[6128]376  return result;
377}
[6341]378
379
380/*!
381 * Converts a byte-array into a float value
382 * @param a: The byte-array which is to convert
383 * @return: A float value which accords the given byte-array
384 */
385int Converter::byteArrayToFloat(const byte* a, float* x)
386{
387  //handle 0
388  for (int i = 0; i<FLOATSIZE; i++)
389  {
390    if (a[i]!=0)
391      break;
392    if ( i==FLOATSIZE-1 )
393    {
394      *x = 0.0f;
395      return FLOATSIZE;
396    }
397  }
398
399
400  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
401  int mantisse = hmant % expmult;
402  mantisse += expmult;
403
404  int hexp = a[2] + a[3] * 256;
405  int exponent = (hexp / 128) % 256 - 128;
406
407  int sgn;
408  if (a[3] >= sgnadd)
409    sgn = -1;
410  else
411    sgn = 1;
412
413  //printf("mantisse = %i exponent = %i \n", mantisse, exponent);
414
415  float emult = 1;
416  if (exponent > 0)
417    for (int i = 0; i < exponent; i++)
418      emult *= 2;
419  else if (exponent < 0)
420    for (int i = 0; i > exponent; i--)
421      emult /= 2;
422
423  *x = mantisse * emult;
424  if (sgn == -1)
425    *x = -  *x;
426
427  return FLOATSIZE;
428}
429
430/**
431 * copies a strint to a byte array
432 * @param s: string to copy
433 * @param a: byte array
434 * @param length: string length
435 * @return: the used number of bytes in byte array
436 */
437int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
438{
439  if ( length+INTSIZE > maxLength )
440  {
441    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
442    return -1;
443  }
444
445  int n = Converter::intToByteArray( length, a, maxLength );
446
447  memcpy( a+INTSIZE, s, length );
448
449  return length + INTSIZE;
450}
451
452/**
453 * reads a string out of a byte array
454 * @param a: byte array
455 * @param s: string
456 * @param maxLength: max bytes to copy
457 * @return: the number of read bytes in byte array
458 */
459int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
460{
461  int length;
462
463  int n = Converter::byteArrayToInt( a, &length );
464
465
466  if ( length+1 > maxLength )
467  {
468    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
469    strncpy(s,"",maxLength);
470    return -1;
471  }
472
473  memcpy( s, a+n, length );
474  s[length] = '\0';
475
476  return n+length;
477}
478
479/**
480 * reads a string out of a byte array and allocates memory for string
481 * @param a: byte array
482 * @param s: string
483 * @param maxLength: max bytes to copy
484 * @return: the number of read bytes in byte array
485 */
486int Converter::byteArrayToStringM( const byte * a, char*& s )
487{
488  int length;
489
490  int n = Converter::byteArrayToInt( a, &length );
491
492  s = new char[length+1];
493
494  if ( !s )
495  {
496    PRINTF(1)("Could not allocate memory!\n" );
497    return -1;
498  }
499
500  memcpy( s, a+n, length );
501  s[length] = '\0';
502
503  return n+length;
504}
505
Note: See TracBrowser for help on using the repository browser.