1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/jid.h" 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <ctype.h> 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <algorithm> 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <string> 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h" 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/constants.h" 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace buzz { 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::Jid() : data_(NULL) { 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::Jid(bool is_special, const std::string & special) { 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = is_special ? new Data(special, STR_EMPTY, STR_EMPTY) : NULL; 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::Jid(const std::string & jid_string) { 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (jid_string == STR_EMPTY) { 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = NULL; 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // First find the slash and slice of that part 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t slash = jid_string.find('/'); 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string resource_name = (slash == std::string::npos ? STR_EMPTY : 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch jid_string.substr(slash + 1)); 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Now look for the node 60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string node_name; 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t at = jid_string.find('@'); 62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t domain_begin; 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (at < slash && at != std::string::npos) { 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch node_name = jid_string.substr(0, at); 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_begin = at + 1; 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_begin = 0; 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Now take what is left as the domain 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t domain_length = 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ( slash == std::string::npos 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ? jid_string.length() - domain_begin 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : slash - domain_begin); 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // avoid allocating these constants repeatedly 77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string domain_name; 78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (domain_length == 9 && jid_string.find("gmail.com", domain_begin) == domain_begin) { 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name = STR_GMAIL_COM; 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (domain_length == 14 && jid_string.find("googlemail.com", domain_begin) == domain_begin) { 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name = STR_GOOGLEMAIL_COM; 84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (domain_length == 10 && jid_string.find("google.com", domain_begin) == domain_begin) { 86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name = STR_GOOGLE_COM; 87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else { 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name = jid_string.substr(domain_begin, domain_length); 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If the domain is empty we have a non-valid jid and we should empty 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // everything else out 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (domain_name.empty()) { 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = NULL; 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_node; 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_node = prepNode(node_name, 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch node_name.begin(), node_name.end(), &valid_node); 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_domain; 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_domain = prepDomain(domain_name, 104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name.begin(), domain_name.end(), &valid_domain); 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_resource; 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_resource = prepResource(resource_name, 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch resource_name.begin(), resource_name.end(), &valid_resource); 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!valid_node || !valid_domain || !valid_resource) { 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = NULL; 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = new Data(validated_node, validated_domain, validated_resource); 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::Jid(const std::string & node_name, 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string & domain_name, 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string & resource_name) { 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (domain_name.empty()) { 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = NULL; 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_node; 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_node = prepNode(node_name, 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch node_name.begin(), node_name.end(), &valid_node); 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_domain; 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_domain = prepDomain(domain_name, 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch domain_name.begin(), domain_name.end(), &valid_domain); 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool valid_resource; 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string validated_resource = prepResource(resource_name, 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch resource_name.begin(), resource_name.end(), &valid_resource); 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!valid_node || !valid_domain || !valid_resource) { 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = NULL; 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_ = new Data(validated_node, validated_domain, validated_resource); 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string Jid::Str() const { 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!IsValid()) 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string ret; 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!data_->node_name_.empty()) 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret = data_->node_name_ + "@"; 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(data_->domain_name_ != STR_EMPTY); 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret += data_->domain_name_; 154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!data_->resource_name_.empty()) 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ret += "/" + data_->resource_name_; 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ret; 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::IsValid() const { 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return data_ != NULL && !data_->domain_name_.empty(); 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::IsBare() const { 168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (Compare(JID_EMPTY) == 0) { 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LS_VERBOSE) << "Warning: Calling IsBare() on the empty jid"; 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return IsValid() && 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_->resource_name_.empty(); 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::IsFull() const { 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return IsValid() && 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch !data_->resource_name_.empty(); 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::BareJid() const { 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!IsValid()) 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return Jid(); 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!IsFull()) 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return *this; 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return Jid(data_->node_name_, data_->domain_name_, STR_EMPTY); 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if 0 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::set_node(const std::string & node_name) { 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_->node_name_ = node_name; 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::set_domain(const std::string & domain_name) { 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_->domain_name_ = domain_name; 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::set_resource(const std::string & res_name) { 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch data_->resource_name_ = res_name; 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::BareEquals(const Jid & other) const { 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (other.data_ == data_ || 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (data_ != NULL && 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_ != NULL && 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_->node_name_ == data_->node_name_ && 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_->domain_name_ == data_->domain_name_)); 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::operator==(const Jid & other) const { 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (other.data_ == data_ || 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (data_ != NULL && 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_ != NULL && 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_->node_name_ == data_->node_name_ && 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_->domain_name_ == data_->domain_name_ && 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch other.data_->resource_name_ == data_->resource_name_)); 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::Compare(const Jid & other) const { 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (other.data_ == data_) 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (data_ == NULL) 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return -1; 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (other.data_ == NULL) 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 1; 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int compare_result; 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch compare_result = data_->node_name_.compare(other.data_->node_name_); 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 != compare_result) 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return compare_result; 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch compare_result = data_->domain_name_.compare(other.data_->domain_name_); 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (0 != compare_result) 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return compare_result; 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch compare_result = data_->resource_name_.compare(other.data_->resource_name_); 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return compare_result; 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochuint32 Jid::ComputeLameHash() const { 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint32 hash = 0; 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Hash the node portion 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch { 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string &str = node(); 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (int i = 0; i < static_cast<int>(str.size()); ++i) { 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch hash = ((hash << 2) + hash) + str[i]; 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Hash the domain portion 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch { 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string &str = domain(); 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (int i = 0; i < static_cast<int>(str.size()); ++i) 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch hash = ((hash << 2) + hash) + str[i]; 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Hash the resource portion 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch { 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string &str = resource(); 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (int i = 0; i < static_cast<int>(str.size()); ++i) 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch hash = ((hash << 2) + hash) + str[i]; 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return hash; 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// --- JID parsing code: --- 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks and normalizes the node part of a JID. 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepNode(const std::string str, std::string::const_iterator start, 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator end, bool *valid) { 278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string result; 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (std::string::const_iterator i = start; i < end; i++) { 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool char_valid = true; 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch unsigned char ch = *i; 284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ch <= 0x7F) { 285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result += prepNodeAscii(ch, &char_valid); 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else { 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: implement the correct stringprep protocol for these 289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result += tolower(ch); 290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!char_valid) { 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result.length() > 1023) { 297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Returns the appropriate mapping for an ASCII character in a node. 305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochchar 306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepNodeAscii(char ch, bool *valid) { 307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (ch) { 309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'V': case 'W': case 'X': case 'Y': case 'Z': 313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (char)(ch + ('a' - 'A')); 314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: 316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: 317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: 318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: 319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ' ': case '&': case '/': case ':': case '<': case '>': case '@': 320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case '\"': case '\'': 321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x7F: 322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ch; 327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks and normalizes the resource part of a JID. 332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string 333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepResource(const std::string str, std::string::const_iterator start, 334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator end, bool *valid) { 335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string result; 337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (std::string::const_iterator i = start; i < end; i++) { 339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool char_valid = true; 340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch unsigned char ch = *i; 341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ch <= 0x7F) { 342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result += prepResourceAscii(ch, &char_valid); 343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else { 345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: implement the correct stringprep protocol for these 346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch result += ch; 347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result.length() > 1023) { 351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Returns the appropriate mapping for an ASCII character in a resource. 358f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochchar 359f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepResourceAscii(char ch, bool *valid) { 360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (ch) { 362f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: 363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: 364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: 365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: 366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x7F: 367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ch; 372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks and normalizes the domain part of a JID. 376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string 377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepDomain(const std::string str, std::string::const_iterator start, 378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator end, bool *valid) { 379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string result; 381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: if the domain contains a ':', then we should parse it 383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // as an IPv6 address rather than giving an error about illegal domain. 384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch prepDomain(str, start, end, &result, valid); 385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!*valid) { 386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (result.length() > 1023) { 390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STR_EMPTY; 391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return result; 394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks and normalizes an IDNA domain. 398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepDomain(const std::string str, std::string::const_iterator start, 400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator end, std::string *buf, bool *valid) { 401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator last = start; 403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (std::string::const_iterator i = start; i < end; i++) { 404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool label_valid = true; 405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char ch = *i; 406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (ch) { 407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x002E: 408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if 0 // FIX: This isn't UTF-8-aware. 409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x3002: 410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0xFF0E: 411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0xFF61: 412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif 413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch prepDomainLabel(str, last, i, buf, &label_valid); 414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *buf += '.'; 415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch last = i + 1; 416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch break; 417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!label_valid) { 419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch prepDomainLabel(str, last, end, buf, valid); 423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Checks and normalizes a domain label. 426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid 427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepDomainLabel(const std::string str, std::string::const_iterator start, 428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string::const_iterator end, std::string *buf, bool *valid) { 429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int startLen = buf->length(); 432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (std::string::const_iterator i = start; i < end; i++) { 433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bool char_valid = true; 434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch unsigned char ch = *i; 435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (ch <= 0x7F) { 436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *buf += prepDomainLabelAscii(ch, &char_valid); 437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else { 439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: implement ToASCII for these 440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *buf += ch; 441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!char_valid) { 443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch int count = buf->length() - startLen; 448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (count == 0) { 449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch else if (count > 63) { 452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Is this check needed? See comment in prepDomainLabelAscii. 456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((*buf)[startLen] == '-') { 457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((*buf)[buf->length() - 1] == '-') { 460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch// Returns the appropriate mapping for an ASCII character in a domain label. 467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochchar 468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochJid::prepDomainLabelAscii(char ch, bool *valid) { 469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = true; 470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: A literal reading of the spec seems to say that we do 471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // not need to check for these illegal characters (an "internationalized 472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // domain label" runs ToASCII with UseSTD3... set to false). But that 473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // can't be right. We should at least be checking that there are no '/' 474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // or '@' characters in the domain. Perhaps we should see what others 475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // do in this case. 476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (ch) { 478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 'V': case 'W': case 'X': case 'Y': case 'Z': 482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (char)(ch + ('a' - 'A')); 483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: 485f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: 486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: 487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: 488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: 489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23: 490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: 491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A: 492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40: 493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60: 494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: 495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *valid = false; 496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ch; 500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 504