00001 /* 00002 * Copyright (C) 2006-2011, SRI International (R) 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU Lesser General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program 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 program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include <OpenKarto/Identifier.h> 00019 #include <OpenKarto/Exception.h> 00020 00021 namespace karto 00022 { 00023 00024 Identifier::Identifier() 00025 { 00026 } 00027 00028 Identifier::Identifier(const char* pString) 00029 { 00030 Parse(pString); 00031 } 00032 00033 Identifier::Identifier(const String& rString) 00034 { 00035 Parse(rString); 00036 } 00037 00038 Identifier::Identifier(const Identifier& rOther) 00039 { 00040 Parse(rOther.ToString()); 00041 } 00042 00043 Identifier::~Identifier() 00044 { 00045 } 00046 00047 const String& Identifier::GetName() const 00048 { 00049 return m_Name; 00050 } 00051 00052 void Identifier::SetName(const String& rName) 00053 { 00054 if (rName.Size() != 0) 00055 { 00056 std::string name(rName.ToCString()); 00057 00058 std::string::size_type pos = name.find_last_of('/'); 00059 if (pos != 0 && pos != std::string::npos) 00060 { 00061 throw Exception("Name can't contain a scope!"); 00062 } 00063 00064 m_Name = rName; 00065 } 00066 else 00067 { 00068 m_Name.Clear(); 00069 } 00070 00071 Update(); 00072 } 00073 00074 const String& Identifier::GetScope() const 00075 { 00076 return m_Scope; 00077 } 00078 00079 void Identifier::SetScope(const String& rScope) 00080 { 00081 if (rScope.Size() != 0) 00082 { 00083 m_Scope = rScope; 00084 } 00085 else 00086 { 00087 m_Scope.Clear(); 00088 } 00089 00090 Update(); 00091 } 00092 00093 const String& Identifier::ToString() const 00094 { 00095 return m_FullName; 00096 } 00097 00098 void Identifier::Clear() 00099 { 00100 m_Name.Clear(); 00101 m_Scope.Clear(); 00102 m_FullName.Clear(); 00103 } 00104 00105 void Identifier::Parse(const String& rString) 00106 { 00107 if (rString.Size() == 0) 00108 { 00109 Clear(); 00110 return; 00111 } 00112 00113 std::string id(rString.ToCString()); 00114 00115 std::string::size_type pos = id.find_last_of('/'); 00116 00117 if (pos == std::string::npos) 00118 { 00119 m_Name = rString; 00120 } 00121 else 00122 { 00123 m_Scope = rString.SubString(0, pos); 00124 m_Name = rString.SubString(pos+1, rString.Size()); 00125 00126 // remove '/' from m_Scope if first!! 00127 if (m_Scope.Size() > 0 && m_Scope[0] == '/') 00128 { 00129 m_Scope = m_Scope.SubString(1, m_Scope.Size()); 00130 } 00131 } 00132 00133 Update(); 00134 } 00135 00136 void Identifier::Validate(const String& rString) 00137 { 00138 if (rString.Size() == 0) 00139 { 00140 return; 00141 } 00142 00143 std::string id(rString.ToCString()); 00144 00145 char c = id[0]; 00146 if (IsValidFirst(c)) 00147 { 00148 for (size_t i = 1; i < id.size(); ++i) 00149 { 00150 c = id[i]; 00151 if (!IsValid(c)) 00152 { 00153 throw Exception("Invalid character in name. Valid characters must be within the ranges A-Z, a-z, 0-9, '/', '_' and '-'."); 00154 } 00155 } 00156 } 00157 else 00158 { 00159 throw Exception("Invalid first character in name. Valid characters must be within the ranges A-Z, a-z, and '/'."); 00160 } 00161 } 00162 00163 void Identifier::Update() 00164 { 00165 m_FullName.Clear(); 00166 00167 if (m_Scope.Size() > 0) 00168 { 00169 m_FullName.Append("/"); 00170 m_FullName.Append(m_Scope); 00171 m_FullName.Append("/"); 00172 } 00173 m_FullName.Append(m_Name); 00174 } 00175 00176 Identifier& Identifier::operator=(const Identifier& rOther) 00177 { 00178 if (&rOther != this) 00179 { 00180 m_Name = rOther.m_Name; 00181 m_Scope = rOther.m_Scope; 00182 m_FullName = rOther.m_FullName; 00183 } 00184 00185 return *this; 00186 } 00187 00188 kt_bool Identifier::operator==(const Identifier& rOther) const 00189 { 00190 return (m_FullName == rOther.m_FullName); 00191 } 00192 00193 kt_bool Identifier::operator<(const Identifier& rOther) const 00194 { 00195 return m_FullName < rOther.m_FullName; 00196 } 00197 00198 kt_size_t Identifier::Size() const 00199 { 00200 return m_FullName.Size(); 00201 } 00202 00203 }