00001 /* 00002 * Copyright 2005-2006 Intel Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 #include <ctype.h> 00019 00020 #include "applib/dtn_types.h" 00021 #include "EndpointID.h" 00022 #include "Scheme.h" 00023 #include "SchemeTable.h" 00024 00025 namespace dtn { 00026 00032 bool 00033 EndpointID::parse() 00034 { 00035 size_t pos; 00036 00037 scheme_ = NULL; 00038 scheme_str_.erase(); 00039 ssp_.erase(); 00040 valid_ = false; 00041 00042 if ((pos = str_.find(':')) == std::string::npos) 00043 return false; // no : 00044 00045 if (pos == 0) { 00046 return false; // empty scheme 00047 } 00048 00049 scheme_str_.assign(str_, 0, pos); 00050 00051 if (!is_pattern_) { 00052 // validate that scheme is composed of legitimate characters 00053 // according to the URI spec (RFC 3986) 00054 std::string::iterator iter = scheme_str_.begin(); 00055 if (! isalpha(*iter)) { 00056 return false; 00057 } 00058 ++iter; 00059 for (; iter != scheme_str_.end(); ++iter) { 00060 char c = *iter; 00061 if (isalnum(c) || (c == '+') || (c == '-') || (c == '.')) 00062 continue; 00063 00064 return false; // invalid character 00065 } 00066 } 00067 00068 // XXX/demmer should really validate the rest of it, but the URI 00069 // validation rules are actually a bit complex... 00070 scheme_ = SchemeTable::instance()->lookup(scheme_str_); 00071 00072 if (pos == str_.length() - 1) { 00073 return false; // empty scheme or ssp 00074 } 00075 ssp_.assign(str_, pos + 1, str_.length() - pos); 00076 00077 00078 if (scheme_) { 00079 valid_ = scheme_->validate(ssp_, is_pattern_); 00080 } else { 00081 valid_ = true; 00082 } 00083 00084 return valid_; 00085 } 00086 00094 bool 00095 EndpointID::append_service_tag(const char* tag) 00096 { 00097 if (!scheme_) 00098 return false; 00099 00100 bool ok = scheme_->append_service_tag(&ssp_, tag); 00101 if (!ok) 00102 return false; 00103 00104 // rebuild the string 00105 str_ = scheme_str_ + ":" + ssp_; 00106 00107 return true; 00108 } 00109 00115 bool 00116 EndpointID::assign(const dtn_endpoint_id_t* eid) 00117 { 00118 str_.assign(eid->uri); 00119 return parse(); 00120 } 00121 00126 void 00127 EndpointID::copyto(dtn_endpoint_id_t* eid) const 00128 { 00129 ASSERT(str_.length() <= DTN_MAX_ENDPOINT_ID + 1); 00130 strcpy(eid->uri, str_.c_str()); 00131 } 00132 00133 00137 void 00138 EndpointID::serialize(oasys::SerializeAction* a) 00139 { 00140 a->process("uri", &str_); 00141 if (a->action_code() == oasys::Serialize::UNMARSHAL) { 00142 parse(); 00143 } 00144 } 00145 00146 00151 bool 00152 EndpointIDPattern::match(const EndpointID& eid) const 00153 { 00154 if (! known_scheme()) { 00155 return false; 00156 } 00157 00158 return scheme()->match(*this, eid); 00159 } 00160 00161 00162 } // namespace dtn