Go to the documentation of this file.00001
00005
00006
00007
00008
00009 #define _CRT_SECURE_NO_WARNINGS
00010
00011 #include "sick_scan/tcp/colaa.hpp"
00012 #include <cstring>
00013 #include <cassert>
00014 #include <stdexcept>
00015 #include "sick_scan/tcp/toolbox.hpp"
00016 #include "sick_scan/tcp/errorhandler.hpp"
00017 #include <stdlib.h>
00018 #include <limits>
00019
00020
00021 namespace colaa
00022 {
00023
00024
00025
00026
00027 UINT16 getValueOfChar(UINT8 c)
00028 {
00029 UINT16 value = 0;
00030
00031 if ((c >= '0') && (c <= '9'))
00032 {
00033 value = c - '0';
00034 }
00035 else if ((c >= 'A') && (c <= 'F'))
00036 {
00037 value = 10 + c - 'A';
00038 }
00039 else
00040 {
00041
00042 throw std::out_of_range("Unknown character where 0..9 or A..F was expected: '" + std::string(c, 1) + "'");
00043 }
00044
00045 return value;
00046 }
00047
00048
00049
00050
00051
00052
00053 UINT8 nibbleToAscii(UINT8 value)
00054 {
00055 UINT8 c;
00056
00057 if (value > 0x0f)
00058 {
00059 throw std::out_of_range("Tried to convert value > 0x0f into hex-nibble: " + toString((INT16)value));
00060 }
00061
00062 if (value < 10)
00063 {
00064 c = ('0' + value);
00065 }
00066 else
00067 {
00068 c = ('A' + (value - 10));
00069 }
00070
00071 return c;
00072 }
00073
00074
00082 void addFrameToBuffer(UINT8* sendBuffer, UINT8* cmdBuffer, UINT16* len)
00083 {
00084 UINT16 pos = 0;
00085
00086
00087 sendBuffer[pos++] = 0x02;
00088 sendBuffer[pos++] = 's';
00089
00090
00091 memcpy(&(sendBuffer[pos]), cmdBuffer, *len);
00092 pos += *len;
00093
00094
00095
00096
00097
00098
00099
00100 sendBuffer[pos++] = 0x03;
00101
00102
00103 *len = pos;
00104 }
00111 UINT16 addUINT8ToBuffer(UINT8* buffer, UINT8 value)
00112 {
00113 UINT16 len;
00114
00115 len = addUINT32ToBuffer(buffer, (UINT32)value);
00116
00117 return len;
00118 }
00125 UINT16 addUINT16ToBuffer(UINT8* buffer, UINT16 value)
00126 {
00127 UINT16 len;
00128
00129 len = addUINT32ToBuffer(buffer, (UINT32)value);
00130
00131 return len;
00132 }
00133
00139 UINT16 addINT8ToBuffer(UINT8* buffer, INT8 value)
00140 {
00141 UINT16 stellenwert;
00142 UINT8 c;
00143 UINT16 pos = 0;
00144 bool firstZero = true;
00145
00146
00147 if (value < 0)
00148 {
00149 buffer[pos++] = '-';
00150 value *= -1;
00151 }
00152 else
00153 {
00154 buffer[pos++] = '+';
00155 }
00156
00157
00158 stellenwert = 100;
00159
00160 while (stellenwert > 0)
00161 {
00162 c = value / stellenwert;
00163 if ((c != 0) || (firstZero == false) || (stellenwert == 1))
00164 {
00165
00166 buffer[pos++] = ('0' + c);
00167 }
00168 if (c != 0)
00169 {
00170
00171 firstZero = false;
00172 }
00173 value -= c * stellenwert;
00174 stellenwert /= 10;
00175 }
00176
00177 return pos;
00178 }
00185 UINT16 addINT32ToBuffer(UINT8* buffer, INT32 value)
00186 {
00187 UINT32 uValue = (UINT32)value;
00188
00189 UINT16 pos = addUINT32ToBuffer(buffer, uValue);
00190
00191 return pos;
00192 }
00193
00200 UINT16 addUINT32ToBuffer(UINT8* buffer, UINT32 value)
00201 {
00202
00203 bool firstZero = true;
00204 UINT16 pos = 0;
00205 UINT8 nibble;
00206
00207 for (INT16 i = 7; i >= 0; i -= 1)
00208 {
00209 nibble = (value >> (i * 4)) & 0x0F;
00210 if ((nibble != 0) || (firstZero == false) || (i == 0))
00211 {
00212 buffer[pos++] = nibbleToAscii(nibble);
00213 firstZero = false;
00214 }
00215 }
00216
00217 return pos;
00218 }
00224 UINT16 addStringToBuffer(UINT8* buffer, const std::string& text)
00225 {
00226 UINT16 len = (UINT16)text.length();
00227
00228
00229 strcpy ((char*)buffer, text.c_str());
00230
00231 return len;
00232 }
00233
00234 UINT16 detail::writeToBuffer(BYTE* buffer, double value)
00235 {
00236 std::string tmp(toString(value, 6));
00237 printWarning("detail::writeToBuffer: Warning - Writing of floating-point values has not been cross-checked in Cola-A format!");
00238 return addStringToBuffer(buffer, tmp);
00239 }
00240
00246 std::string getNextStringToken(std::string* rxData)
00247 {
00248 typedef std::string::size_type size_type;
00249
00250
00251 size_type tokenStart = rxData->find_first_not_of(' ');
00252 size_type tokenEnd = rxData->find(' ', tokenStart);
00253 size_type tokenLength = tokenEnd - tokenStart;
00254
00255
00256 std::string token = rxData->substr(tokenStart, tokenLength);
00257
00258
00259 *rxData = rxData->substr(tokenEnd + 1);
00260
00261
00262 return token;
00263 }
00264
00265
00271 std::string getNextStringToken(UINT8* rxData)
00272 {
00273
00274
00275 UINT16 pos = 0;
00276 std::string token;
00277
00278
00279 while (rxData[pos] != 0x00)
00280 {
00281 if (rxData[pos] != ' ')
00282 {
00283 break;
00284 }
00285 pos++;
00286 }
00287
00288
00289 if (rxData[pos] != 0x00)
00290 {
00291
00292
00293 while ((rxData[pos] != 0x00) && (rxData[pos] != ' '))
00294 {
00295 token += rxData[pos];
00296 pos++;
00297 }
00298 }
00299
00300
00301 return token;
00302 }
00303
00304
00305 bool GetNibble(unsigned char data, unsigned char& rNibble)
00306 {
00307 rNibble = 0;
00308 bool validHexData = true;
00309 if ((data >= '0') && (data <= '9'))
00310 {
00311 rNibble = (unsigned char)(data - '0');
00312 }
00313 else if ((data >= 'A') && (data <= 'F'))
00314 {
00315 rNibble = (unsigned char)(data - 'A' + 10);
00316 }
00317 else if ((data >= 'a') && (data <= 'f'))
00318 {
00319 rNibble = (unsigned char)(data - 'a' + 10);
00320 }
00321 else
00322 {
00323 validHexData = false;
00324 }
00325 return validHexData;
00326 }
00327
00332 double decodeReal(std::string* rxData)
00333 {
00334 double value = std::numeric_limits<double>::quiet_NaN();
00335 std::string text = colaa::getNextStringToken(rxData);
00336 if (text.empty() == false)
00337 {
00338
00339 if ((text[0] == '+') || (text[0] == '-'))
00340 {
00341
00342 value = atof(text.c_str());
00343 }
00344 else
00345 {
00346
00347
00348 union
00349 {
00350 float f;
00351 unsigned char c[4];
00352 } converter;
00353 memset(&converter, 0, sizeof(converter));
00354
00355 if (text.length() == 8)
00356 {
00357 int hexIndex = 0;
00358 int shift = 0;
00359 bool success = true;
00360 for (int i = 7; i >= 0; --i)
00361 {
00362 unsigned char nibble;
00363 success &= GetNibble(text[i], nibble);
00364 converter.c[hexIndex] |= (nibble << shift);
00365 hexIndex += (shift >> 2);
00366 shift ^= 4;
00367 }
00368 if (success == true)
00369 {
00370 value = converter.f;
00371 }
00372 }
00373 }
00374 }
00375
00376 return value;
00377 }
00378
00383 double decodeReal(const std::string& rxData)
00384 {
00385 double value = std::numeric_limits<double>::quiet_NaN();
00386 const std::string& text = rxData;
00387 if (text.empty() == false)
00388 {
00389
00390 if ((text[0] == '+') || (text[0] == '-'))
00391 {
00392
00393 value = atof(text.c_str());
00394 }
00395 else
00396 {
00397
00398
00399 union
00400 {
00401 float f;
00402 unsigned char c[4];
00403 } converter;
00404 memset(&converter, 0, sizeof(converter));
00405
00406 if (text.length() == 8)
00407 {
00408 int hexIndex = 0;
00409 int shift = 0;
00410 bool success = true;
00411 for (int i = 7; i >= 0; --i)
00412 {
00413 unsigned char nibble;
00414 success &= GetNibble(text[i], nibble);
00415 converter.c[hexIndex] |= (nibble << shift);
00416 hexIndex += (shift >> 2);
00417 shift ^= 4;
00418 }
00419 if (success == true)
00420 {
00421 value = converter.f;
00422 }
00423 }
00424 }
00425 }
00426
00427 return value;
00428 }
00429
00430
00434 UINT32 decodeUINT32(std::string* rxData)
00435 {
00436 UINT32 value = 0;
00437 UINT32 tempVal;
00438 UINT32 factor = 1;
00439 UINT32 baseFactor = 10;
00440 UINT16 digits;
00441
00442
00443 std::string number = colaa::getNextStringToken(rxData);
00444
00445 if (number.at(0) == '+')
00446 {
00447
00448 baseFactor = 10;
00449 number = number.substr(1);
00450 }
00451 else
00452 {
00453
00454 baseFactor = 16;
00455 }
00456 digits = (UINT16)number.length();
00457
00458
00459 for (INT16 d = digits - 1; d >= 0; d -= 1)
00460 {
00461 tempVal = colaa::getValueOfChar(number.at(d));
00462 value += tempVal * factor;
00463 factor *= baseFactor;
00464 }
00465
00466 return value;
00467 }
00468
00472 INT16 decodeINT16(std::string* rxData)
00473 {
00474 INT32 value = decodeINT32(rxData);
00475 assert ((value >= -32768) && (value <= 32767));
00476 return (INT16)value;
00477 }
00478
00483 INT32 decodeINT32(std::string* rxData)
00484 {
00485 INT32 value = 0;
00486 INT32 tempVal;
00487 INT32 factor = 1;
00488 INT32 baseFactor = 10;
00489 INT32 sign = 1;
00490 UINT16 digits;
00491
00492
00493 std::string number = colaa::getNextStringToken(rxData);
00494
00495
00496 if (number.at(0) == '+')
00497 {
00498
00499 number = number.substr(1);
00500 }
00501 else if (number.at(0) == '-')
00502 {
00503
00504 sign = -1;
00505 number = number.substr(1);
00506 }
00507 else
00508 {
00509
00510 baseFactor = 16;
00511 }
00512
00513
00514 digits = (UINT16)number.length();
00515
00516
00517 for (INT16 d = digits - 1; d >= 0; d -= 1)
00518 {
00519 tempVal = colaa::getValueOfChar(number.at(d));
00520 value += tempVal * factor;
00521 factor *= baseFactor;
00522 }
00523
00524
00525 value *= sign;
00526
00527 return value;
00528 }
00529
00530
00534 INT16 decodeINT16(const std::string& rxData)
00535 {
00536 INT32 value = decodeINT32(rxData);
00537 assert ((value >= -32768) && (value <= 32767));
00538 return (INT16)value;
00539 }
00540
00545 INT32 decodeINT32(const std::string& rxData)
00546 {
00547 INT32 value = 0;
00548 INT32 tempVal;
00549 INT32 factor = 1;
00550 INT32 baseFactor = 10;
00551 INT32 sign = 1;
00552 UINT16 digits;
00553 UINT16 offset = 0;
00554
00555
00556 const std::string number = rxData;
00557
00558
00559 if (number.at(0) == '+')
00560 {
00561
00562
00563 offset = 1;
00564 }
00565 else if (number.at(0) == '-')
00566 {
00567
00568 sign = -1;
00569
00570 offset = 1;
00571 }
00572 else
00573 {
00574
00575 baseFactor = 16;
00576 }
00577
00578
00579 digits = (UINT16)number.length();
00580
00581
00582 for (INT16 d = digits - 1; d >= offset; d -= 1)
00583 {
00584 tempVal = colaa::getValueOfChar(number.at(d));
00585 value += tempVal * factor;
00586 factor *= baseFactor;
00587 }
00588
00589
00590 value *= sign;
00591
00592 return value;
00593 }
00594
00595
00603 std::string decodeString(std::string* rxData, UINT16 len)
00604 {
00605 std::string text;
00606
00607
00608 if (len == 0)
00609 {
00610
00611 text = colaa::getNextStringToken(rxData);
00612 }
00613 else
00614 {
00615
00616 text = rxData->substr(0, len);
00617
00618 *rxData = rxData->substr(len + 1);
00619 }
00620
00621 return text;
00622 }
00623
00624
00625
00626
00627 UINT16 decodeUINT16(BYTE* buffer)
00628 {
00629 std::string data = getNextStringToken(buffer);
00630 return decodeUINT16(data);
00631 }
00632
00633
00634
00635
00636 UINT16 decodeUINT16(std::string* rxData)
00637 {
00638 UINT32 value;
00639
00640 value = decodeUINT32(rxData);
00641
00642 assert (value < 0x10000);
00643 return (UINT16)value;
00644 }
00645
00649 UINT8 decodeUINT8(std::string* rxData)
00650 {
00651 UINT32 value;
00652
00653 value = decodeUINT32(rxData);
00654
00655 assert (value < 256);
00656 return (UINT8)value;
00657 }
00658
00662 UINT16 decodeUINT16(const std::string& rxData)
00663 {
00664 UINT32 value;
00665
00666 value = decodeUINT32(rxData);
00667
00668 assert (value < 0x10000);
00669 return (UINT16)value;
00670 }
00671
00675 UINT8 decodeUINT8(const std::string& rxData)
00676 {
00677 UINT32 value;
00678
00679 value = decodeUINT32(rxData);
00680
00681 assert (value < 256);
00682 return (UINT8)value;
00683 }
00684
00690 UINT32 decodeUINT32(const std::string& rxData)
00691 {
00692 UINT32 value = 0;
00693 UINT32 factor = 1;
00694 UINT32 tempVal;
00695 UINT32 baseFactor = 10;
00696 UINT16 digits;
00697 UINT16 offset = 0;
00698
00699
00700 const std::string& number = rxData;
00701
00702
00703 if (number.at(0) == '+')
00704 {
00705
00706
00707 offset = 1;
00708 }
00709 else
00710 {
00711
00712 baseFactor = 16;
00713 }
00714
00715
00716 digits = (UINT16)number.length();
00717
00718
00719 for (INT16 d = digits - 1; d >= offset; d -= 1)
00720 {
00721 tempVal = colaa::getValueOfChar(number.at(d));
00722 value += tempVal * factor;
00723 factor *= baseFactor;
00724 }
00725
00726 return value;
00727 }
00728
00735 UINT32 decodeXByte(std::string* rxData, UINT16 len)
00736 {
00737 UINT32 value;
00738 UINT32 result = 0;
00739
00740 assert (len < 5);
00741
00742 for (UINT16 i = 0; i < len; i++)
00743 {
00744 value = decodeUINT32(rxData);
00745 assert (value < 256);
00746 result += (value << (i * 8));
00747 }
00748
00749 return result;
00750 }
00751
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 std::string convertRxBufferToString(UINT8* buffer, UINT16 bufferLen)
00794 {
00795 buffer[bufferLen-1] = 0x00;
00796 std::string result = std::string((char*)(&(buffer[2])));
00797 return result;
00798 }
00799
00800
00801 }