Go to the documentation of this file.00001 #include <socketcan_interface/string.h>
00002
00003 namespace can {
00004
00005 bool hex2dec(uint8_t& d, const char& h) {
00006 if ('0' <= h && h <= '9')
00007 d = h - '0';
00008 else if ('a' <= h && h <= 'f')
00009 d = h - 'a' + 10;
00010 else if ('A' <= h && h <= 'F')
00011 d = h - 'A' + 10;
00012 else
00013 return false;
00014
00015 return true;
00016 }
00017
00018 bool hex2buffer(std::string& out, const std::string& in_raw, bool pad) {
00019 std::string in(in_raw);
00020 if ((in.size() % 2) != 0) {
00021 if (pad)
00022 in.insert(0, "0");
00023 else
00024 return false;
00025 }
00026 out.resize(in.size() >> 1);
00027 for (size_t i = 0; i < out.size(); ++i) {
00028 uint8_t hi, lo;
00029 if (!hex2dec(hi, in[i << 1]) || !hex2dec(lo, in[(i << 1) + 1]))
00030 return false;
00031
00032 out[i] = (hi << 4) | lo;
00033 }
00034 return true;
00035 }
00036
00037 bool dec2hex(char& h, const uint8_t& d, bool lc) {
00038 if (d < 10) {
00039 h = '0' + d;
00040 } else if (d < 16 && lc) {
00041 h = 'a' + (d - 10);
00042 } else if (d < 16 && !lc) {
00043 h = 'A' + (d - 10);
00044 } else {
00045 h='?';
00046 return false;
00047 }
00048 return true;
00049 }
00050
00051 std::string byte2hex(const uint8_t& d, bool pad, bool lc) {
00052 uint8_t hi = d >> 4;
00053 char c=0;
00054 std::string s;
00055 if (hi || pad) {
00056 dec2hex(c, hi, lc);
00057 s += c;
00058 }
00059 dec2hex(c, d & 0xf, lc);
00060 s += c;
00061 return s;
00062 }
00063
00064 std::string buffer2hex(const std::string& in, bool lc) {
00065 std::string s;
00066 s.reserve(in.size() * 2);
00067 for (size_t i = 0; i < in.size(); ++i) {
00068 std::string b = byte2hex(in[i], true, lc);
00069 if (b.empty())
00070 return b;
00071
00072 s += b;
00073 }
00074 return s;
00075 }
00076
00077 std::string tostring(const Header& h, bool lc) {
00078 std::string s;
00079 s.reserve(8);
00080 std::stringstream buf;
00081 buf << std::hex;
00082 if (lc)
00083 buf << std::nouppercase;
00084 else
00085 buf << std::uppercase;
00086
00087 buf << (int) (h);
00088 return buf.str();
00089 }
00090
00091 Header toheader(const std::string& s) {
00092 if (s.empty() || s.size() > 4)
00093 return MsgHeader(0xfff);
00094
00095 std::stringstream stream;
00096 stream << std::hex << s;
00097 unsigned int h = 0;
00098 stream >> h;
00099 return Header(h & Header::ID_MASK, h & Header::EXTENDED_MASK,
00100 h & Header::RTR_MASK, h & Header::ERROR_MASK);
00101 }
00102
00103 std::string tostring(const Frame& f, bool lc) {
00104 std::string s;
00105 s.resize(f.dlc);
00106 for (uint8_t i = 0; i < f.dlc; ++i) {
00107 s[i] = f.data[i];
00108 }
00109 return tostring((const Header&) (f), lc) + '#' + buffer2hex(s, lc);
00110 }
00111
00112 Frame toframe(const std::string& s) {
00113 size_t sep = s.find('#');
00114 if (sep == std::string::npos)
00115 return MsgHeader(0xfff);
00116
00117 Header header = toheader(s.substr(0, sep));
00118 Frame frame(header);
00119 std::string buffer;
00120 if (header.isValid() && hex2buffer(buffer, s.substr(sep + 1), false)) {
00121 if (buffer.size() > 8)
00122 return MsgHeader(0xfff);
00123
00124 for (size_t i = 0; i < buffer.size(); ++i) {
00125 frame.data[i] = buffer[i];
00126 }
00127 frame.dlc = buffer.size();
00128 }
00129 return frame;
00130 }
00131
00132 }
00133
00134 std::ostream& operator <<(std::ostream& stream, const can::Header& h) {
00135 return stream << can::tostring(h, true);
00136 }
00137
00138 std::ostream& operator <<(std::ostream& stream, const can::Frame& f) {
00139 return stream << can::tostring(f, true);
00140 }