Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <opc/ua/protocol/string_utils.h>
00021 #include <cstring>
00022 #include <ctime>
00023 #include <stdexcept>
00024 #include <sstream>
00025 #include <iomanip>
00026 #include <iostream>
00027 #include <limits>
00028
00029
00030 std::string OpcUa::ToString(const NodeId& id)
00031 {
00032 std::stringstream stream;
00033
00034 if (id.HasServerIndex())
00035 {
00036 stream << "srv=" << id.ServerIndex << ";";
00037 }
00038 {
00039 if (id.HasNamespaceURI())
00040 stream << "nsu=" << id.NamespaceURI << ";";
00041 }
00042
00043 stream << "ns=" << id.GetNamespaceIndex() << ";";
00044 if (id.IsInteger())
00045 {
00046 stream << "i=" << id.GetIntegerIdentifier() << ";";
00047 }
00048 #ifndef __ENABLE_EMBEDDED_PROFILE__
00049 else if(id.IsString())
00050 {
00051 stream << "s=" << id.GetStringIdentifier() << ";";
00052 }
00053 else if (id.IsGuid())
00054 {
00055 stream << "g=" << ToString(id.GetGuidIdentifier()) << ";";
00056 }
00057 #endif
00058
00059 return stream.str();
00060 }
00061
00062
00063 std::string OpcUa::ToString(const OpcUa::Guid& guid)
00064 {
00065 char buf[36] = {0};
00066 sprintf(buf, "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
00067 return buf;
00068 }
00069
00070 OpcUa::Guid OpcUa::ToGuid(const std::string& str)
00071 {
00072 if (str.size() != 35)
00073 {
00074 return OpcUa::Guid();
00075 }
00076 Guid guid;
00077
00078 unsigned data1 = 0;
00079 unsigned data2 = 0;
00080 unsigned data3 = 0;
00081 unsigned data4 = 0;
00082 unsigned data5 = 0;
00083 unsigned data6 = 0;
00084 unsigned data7 = 0;
00085 unsigned data8 = 0;
00086 unsigned data9 = 0;
00087 unsigned data10 = 0;
00088 unsigned data11 = 0;
00089 const int parts = sscanf(str.c_str(), "%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X",
00090 &data1, &data2, &data3, &data4, &data5, &data6, &data7, &data8, &data9, &data10, &data11);
00091
00092 guid.Data1 = static_cast<uint32_t>(data1);
00093 guid.Data2 = static_cast<uint16_t>(data2);
00094 guid.Data3 = static_cast<uint16_t>(data3);
00095 guid.Data4[0] = static_cast<uint8_t>(data4);
00096 guid.Data4[1] = static_cast<uint8_t>(data5);
00097 guid.Data4[2] = static_cast<uint8_t>(data6);
00098 guid.Data4[3] = static_cast<uint8_t>(data7);
00099 guid.Data4[4] = static_cast<uint8_t>(data8);
00100 guid.Data4[5] = static_cast<uint8_t>(data9);
00101 guid.Data4[6] = static_cast<uint8_t>(data10);
00102 guid.Data4[7] = static_cast<uint8_t>(data11);
00103
00104 if (parts != 11)
00105 {
00106 return OpcUa::Guid();
00107 }
00108 return guid;
00109 }
00110
00111
00112 namespace
00113 {
00114 std::string GetNodeField(const std::string& data, const char* field)
00115 {
00116 std::size_t colon = 0;
00117 do
00118 {
00119
00120 if (colon)
00121 {
00122 ++colon;
00123 }
00124
00125 colon = data.find(field, colon);
00126
00127
00128 if (colon == std::string::npos)
00129 {
00130 return std::string();
00131 }
00132
00133 if (colon == 0)
00134 {
00135 break;
00136 }
00137 }
00138
00139
00140 while(data[colon - 1] != ';');
00141
00142 colon += std::strlen(field);
00143 const std::size_t semicolon = data.find(";", colon);
00144 if (semicolon == std::string::npos)
00145 {
00146 data.substr(colon);
00147 }
00148 return data.substr(colon, semicolon - colon);
00149 }
00150
00151 uint32_t GetInteger(const std::string&value)
00152 {
00153 if (value.empty())
00154 {
00155 return 0;
00156 }
00157 return std::stoul(value);
00158 }
00159
00160 }
00161
00162 OpcUa::NodeId OpcUa::ToNodeId(const std::string& data, uint32_t defaultNamespace)
00163 {
00164 OpcUa::NodeId result;
00165 uint32_t ns = defaultNamespace;
00166
00167 const std::string nsString = GetNodeField(data, "ns=");
00168 if (nsString.empty())
00169 {
00170 if (ns == std::numeric_limits<uint32_t>::max() )
00171 {
00172 throw(std::runtime_error("Namespace index coult not be parsed from string and not default index specified in string: " + data));
00173 }
00174 }
00175 else
00176 {
00177 ns = GetInteger(nsString);
00178 }
00179
00180 const std::string srv = GetNodeField(data, "srv=");
00181 if (!srv.empty())
00182 {
00183 result.SetServerIndex(GetInteger(srv));
00184 }
00185
00186 const std::string nsu = GetNodeField(data, "nsu=");
00187 if (!nsu.empty())
00188 {
00189 result.SetNamespaceURI(nsu);
00190 }
00191
00192 const std::string integer = GetNodeField(data, "i=");
00193 if (!integer.empty())
00194 {
00195 return OpcUa::NumericNodeId(GetInteger(integer), ns);
00196 }
00197
00198 const std::string str = GetNodeField(data, "s=");
00199 if (!str.empty())
00200 {
00201 return OpcUa::StringNodeId(str, ns);
00202 }
00203
00204 const std::string g = GetNodeField(data, "g=");
00205 if (!g.empty())
00206 {
00207 return OpcUa::GuidNodeId(ToGuid(g), ns);
00208 }
00209
00210 throw(std::runtime_error("No identifier found in string: '" + data +"'"));
00211 }
00212
00213 OpcUa::QualifiedName OpcUa::ToQualifiedName(const std::string& str, uint32_t default_ns)
00214 {
00215 std::size_t found = str.find(":");
00216 if (found != std::string::npos)
00217 {
00218 uint16_t ns = std::stoi(str.substr(0, found));
00219 std::string name = str.substr(found+1, str.length() - found);
00220 return QualifiedName(ns, name);
00221 }
00222
00223 if (default_ns == std::numeric_limits<uint32_t>::max() )
00224 {
00225 throw(std::runtime_error("Namespace index coult not be parsed from string and not default index specified in string: " + str));
00226 }
00227
00228 return QualifiedName(default_ns, str);
00229 }
00230
00231 std::string OpcUa::ToString(const OpcUa::BrowseDirection& direction)
00232 {
00233 switch (direction)
00234 {
00235 case OpcUa::BrowseDirection::Forward:
00236 return "forward";
00237 case OpcUa::BrowseDirection::Inverse:
00238 return "inverse";
00239 case OpcUa::BrowseDirection::Both:
00240 return "both";
00241 default:
00242 return "unknown";
00243 }
00244 }
00245
00246 std::string OpcUa::ToString(const OpcUa::DateTime& t)
00247 {
00248 std::time_t st = OpcUa::DateTime::ToTimeT(t);
00249 return std::ctime(&st);
00250 }
00251
00252 std::string OpcUa::ToString(const OpcUa::LocalizedText& t)
00253 {
00254 return t.Text;
00255 }
00256
00257
00258