string_utils.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  *   Copyright (C) 2013-2014 by Alexander Rykovanov                        *
00003  *   rykovanov.as@gmail.com                                                   *
00004  *                                                                            *
00005  *   This library is free software; you can redistribute it and/or modify     *
00006  *   it under the terms of the GNU Lesser General Public License as           *
00007  *   published by the Free Software Foundation; version 3 of the License.     *
00008  *                                                                            *
00009  *   This library is distributed in the hope that it will be useful,          *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00012  *   GNU Lesser General Public License for more details.                      *
00013  *                                                                            *
00014  *   You should have received a copy of the GNU Lesser General Public License *
00015  *   along with this library; if not, write to the                            *
00016  *   Free Software Foundation, Inc.,                                          *
00017  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                *
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       // if something found at previous cycle
00120       if (colon)
00121       {
00122         ++colon;
00123       }
00124       // find field string
00125       colon = data.find(field, colon);
00126 
00127       // if found nothing
00128       if (colon == std::string::npos)
00129       {
00130         return std::string();
00131       }
00132       // if found at the begin
00133       if (colon == 0)
00134       {
00135         break;
00136       }
00137     }
00138     // if finding 's=' in the 'ns=1;i-3;' will be found field 'ns=1;'
00139     // check that previous character is the ';' if not then search next.
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 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:57