YARP
Yet Another Robot Platform
NetType.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2006-2010 RobotCub Consortium
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <yarp/os/NetType.h>
11 
12 #include <yarp/os/ManagedBytes.h>
14 
15 #include <clocale>
16 #include <cstdlib>
17 #include <cstring>
18 #include <limits>
19 
20 
21 /*
22  * The maximum string length for a 'double' printed as a string using ("%.*g", DECIMAL_DIG) will be:
23  * Initial +/- sign 1 char
24  * First digit for exponential notation 1 char
25  * '.' decimal separator char 1 char
26  * DECIMAL_DIG digits for the mantissa DECIMAL_DIG chars
27  * 'e+/-' 2 chars
28  * YARP_DBL_EXP_DIG for the exponential YARP_DBL_EXP_DIG chars
29  * string terminator 1 char
30  * FILLER 10 chars (you know, for safety)
31  * -----------------------------------------------------
32  * TOTAL is 16 + DECIMAL_DIG + YARP_DBL_EXP_DIG
33  */
34 #define YARP_DOUBLE_TO_STRING_MAX_LENGTH (16 + DECIMAL_DIG + YARP_DBL_EXP_DIG)
35 
36 
37 using namespace yarp::os::impl;
38 using namespace yarp::os;
39 
40 namespace {
41 
42 YARP_OS_LOG_COMPONENT(NETTYPE, "yarp.os.NetType")
43 
44 /*
45  * Converts a floating point number to a string, dealing with locale issues
46  */
47 template <typename T>
48 inline std::string fp_to_string(T x)
49 {
50  char buf[YARP_DOUBLE_TO_STRING_MAX_LENGTH]; // -> see comment at the top of the file
51  std::snprintf(buf, YARP_DOUBLE_TO_STRING_MAX_LENGTH, "%.*g", DECIMAL_DIG, x);
52  std::string str(buf);
53 
54  // If locale is set, the locale version of the decimal point is used.
55  // In this case we change it to the standard "."
56  // If there is no decimal point, and it is not being used the exponential
57  // notation (i.e. the number is in integer form, for example 100000 and not
58  // 1e5) we add ".0" to ensure that it will be interpreted as a double.
59  struct lconv* lc = localeconv();
60  size_t offset = str.find(lc->decimal_point);
61  if (offset != std::string::npos) {
62  str[offset] = '.';
63  } else if (str.find('e') == std::string::npos && str != "inf" && str != "-inf" && str != "nan") {
64  str += ".0";
65  }
66  return str;
67 }
68 
69 /*
70  * Converts a string to a floating point number, dealing with locale issues
71  */
72 template <typename T>
73 inline T fp_from_string(std::string src)
74 {
75  if (src == "inf") {
76  return std::numeric_limits<T>::infinity();
77  }
78  if (src == "-inf") {
79  return -std::numeric_limits<T>::infinity();
80  }
81  if (src == "nan") {
82  return std::numeric_limits<T>::quiet_NaN();
83  }
84  // YARP Bug 2526259: Locale settings influence YARP behavior
85  // Need to deal with alternate versions of the decimal point.
86  size_t offset = src.find('.');
87  if (offset != std::string::npos) {
88  struct lconv* lc = localeconv();
89  src[offset] = lc->decimal_point[0];
90  }
91  return static_cast<T>(strtod(src.c_str(), nullptr));
92 }
93 
94 } // namespace
95 
97 {
98  yCAssert(NETTYPE, code.length() == sizeof(NetInt32));
99  NetInt32 tmp;
100  memcpy((char*)(&tmp), code.get(), code.length());
101  return tmp;
102 }
103 
104 bool NetType::netInt(int data, yarp::os::Bytes& code)
105 {
106  NetInt32 i = data;
107  yarp::os::Bytes b((char*)(&i), sizeof(i));
108  if (code.length() != sizeof(i)) {
109  yCError(NETTYPE, "not enough room for integer");
110  return false;
111  }
112  memcpy(code.get(), b.get(), code.length());
113  return true;
114 }
115 
116 std::string NetType::toHexString(int x)
117 {
118  char buf[256];
119  sprintf(buf, "%x", x);
120  return buf;
121 }
122 
123 std::string NetType::toHexString(long x)
124 {
125  char buf[256];
126  sprintf(buf, "%lx", x);
127  return buf;
128 }
129 
130 std::string NetType::toHexString(unsigned int x)
131 {
132  char buf[256];
133  sprintf(buf, "%x", x);
134  return buf;
135 }
136 
137 
138 std::string NetType::toString(int x)
139 {
140  char buf[256];
141  sprintf(buf, "%d", x);
142  return buf;
143 }
144 
145 std::string NetType::toString(long x)
146 {
147  char buf[256];
148  sprintf(buf, "%ld", x);
149  return buf;
150 }
151 
152 std::string NetType::toString(unsigned int x)
153 {
154  char buf[256];
155  sprintf(buf, "%u", x);
156  return buf;
157 }
158 
159 
160 int NetType::toInt(const std::string& x)
161 {
162  return atoi(x.c_str());
163 }
164 
165 
167 {
168  return fp_to_string(x);
169 }
170 
172 {
173  return fp_to_string(x);
174 }
175 
177 {
178  return fp_from_string<yarp::conf::float32_t>(s);
179 }
180 
182 {
183  return fp_from_string<yarp::conf::float64_t>(s);
184 }
185 
187 {
188  return fp_from_string<yarp::conf::float32_t>(std::move(s));
189 }
190 
192 {
193  return fp_from_string<yarp::conf::float64_t>(std::move(s));
194 }
195 
196 
197 /*
198  PNG's nice and simple CRC code
199  (from http://www.w3.org/TR/PNG-CRCAppendix.html)
200 */
201 
202 /* Table of CRCs of all 8-bit messages. */
203 static unsigned long crc_table[256];
204 
205 /* Flag: has the table been computed? Initially false. */
206 static int crc_table_computed = 0;
207 
208 /* Make the table for a fast CRC. */
209 static void make_crc_table()
210 {
211  unsigned long c;
212  int n;
213  int k;
214 
215  for (n = 0; n < 256; n++) {
216  c = (unsigned long)n;
217  for (k = 0; k < 8; k++) {
218  if ((c & 1) != 0) {
219  c = 0xedb88320L ^ (c >> 1);
220  } else {
221  c = c >> 1;
222  }
223  }
224  crc_table[n] = c;
225  }
226  crc_table_computed = 1;
227 }
228 
229 /* Update a running CRC with the bytes buf[0..len-1]--the CRC
230  should be initialized to all 1's, and the transmitted value
231  is the 1's complement of the final running CRC (see the
232  crc() routine below)). */
233 
234 static unsigned long update_crc(unsigned long crc, unsigned char* buf, size_t len)
235 {
236 
237  unsigned long c = crc;
238  size_t n;
239 
240  if (crc_table_computed == 0) {
241  make_crc_table();
242  }
243  for (n = 0; n < len; n++) {
244  c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
245  }
246  return c;
247 }
248 
249 /* Return the CRC of the bytes buf[0..len-1]. */
250 unsigned long NetType::getCrc(char* buf, size_t len)
251 {
252  return update_crc(0xffffffffL, (unsigned char*)buf, len) ^ 0xffffffffL;
253 }
make_crc_table
static void make_crc_table()
Definition: NetType.cpp:209
YARP_DOUBLE_TO_STRING_MAX_LENGTH
#define YARP_DOUBLE_TO_STRING_MAX_LENGTH
Definition: NetType.cpp:34
yarp::os::NetType::getCrc
static unsigned long int getCrc(char *buf, size_t len)
Definition: NetType.cpp:250
yarp::os::NetType::toFloat64
static yarp::conf::float64_t toFloat64(const std::string &s)
Definition: NetType.cpp:181
update_crc
static unsigned long update_crc(unsigned long crc, unsigned char *buf, size_t len)
Definition: NetType.cpp:234
LogComponent.h
NetType.h
ManagedBytes.h
yarp::os::NetType::toFloat32
static yarp::conf::float32_t toFloat32(const std::string &s)
Definition: NetType.cpp:176
yarp::os::Bytes::get
const char * get() const
Definition: Bytes.cpp:30
yarp::os::NetType::toHexString
static std::string toHexString(int x)
Definition: NetType.cpp:116
yarp::os::Bytes::length
size_t length() const
Definition: Bytes.cpp:25
crc_table
static unsigned long crc_table[256]
Definition: NetType.cpp:203
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
yCAssert
#define yCAssert(component, x)
Definition: LogComponent.h:172
yarp::conf::float32_t
float float32_t
Definition: numeric.h:50
yarp::os::NetType::toString
static std::string toString(int x)
Definition: NetType.cpp:138
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
crc_table_computed
static int crc_table_computed
Definition: NetType.cpp:206
yarp::conf::float64_t
double float64_t
Definition: numeric.h:51
YARP_OS_LOG_COMPONENT
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:37
yarp::os::impl
The components from which ports and connections are built.
yarp::os::NetType::netInt
static int netInt(const yarp::os::Bytes &code)
Definition: NetType.cpp:96
yarp::os::NetType::toInt
static int toInt(const std::string &x)
Definition: NetType.cpp:160
yarp::os::NetInt32
std::int32_t NetInt32
Definition of the NetInt32 type.
Definition: NetInt32.h:33