Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: src/url_canon_ip.cc

Issue 10919114: Expose functions to stringify IPv4 and IPv6 addresses (Closed) Base URL: http://git.chromium.org/external/google-url.git@master
Patch Set: moar Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/url_canon_ip.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009, Google Inc. 1 // Copyright 2009, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 174
175 // Check for 32-bit overflow. 175 // Check for 32-bit overflow.
176 if (num > kuint32max) 176 if (num > kuint32max)
177 return CanonHostInfo::BROKEN; 177 return CanonHostInfo::BROKEN;
178 178
179 // No overflow. Success! 179 // No overflow. Success!
180 *number = static_cast<uint32>(num); 180 *number = static_cast<uint32>(num);
181 return CanonHostInfo::IPV4; 181 return CanonHostInfo::IPV4;
182 } 182 }
183 183
184 // Writes the given address (with each character representing one dotted
185 // part of an IPv4 address) to the output, and updating |*out_host| to
186 // identify the added portion.
187 void AppendIPv4Address(const unsigned char address[4],
188 CanonOutput* output,
189 url_parse::Component* out_host) {
190 out_host->begin = output->length();
191 for (int i = 0; i < 4; i++) {
192 char str[16];
193 _itoa_s(address[i], str, 10);
194
195 for (int ch = 0; str[ch] != 0; ch++)
196 output->push_back(str[ch]);
197
198 if (i != 3)
199 output->push_back('.');
200 }
201 out_host->len = output->length() - out_host->begin;
202 }
203
204 // See declaration of IPv4AddressToNumber for documentation. 184 // See declaration of IPv4AddressToNumber for documentation.
205 template<typename CHAR> 185 template<typename CHAR>
206 CanonHostInfo::Family DoIPv4AddressToNumber(const CHAR* spec, 186 CanonHostInfo::Family DoIPv4AddressToNumber(const CHAR* spec,
207 const url_parse::Component& host, 187 const url_parse::Component& host,
208 unsigned char address[4], 188 unsigned char address[4],
209 int* num_ipv4_components) { 189 int* num_ipv4_components) {
210 // The identified components. Not all may exist. 190 // The identified components. Not all may exist.
211 url_parse::Component components[4]; 191 url_parse::Component components[4];
212 if (!FindIPv4Components(spec, host, components)) 192 if (!FindIPv4Components(spec, host, components))
213 return CanonHostInfo::NEUTRAL; 193 return CanonHostInfo::NEUTRAL;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 bool DoCanonicalizeIPv4Address(const CHAR* spec, 254 bool DoCanonicalizeIPv4Address(const CHAR* spec,
275 const url_parse::Component& host, 255 const url_parse::Component& host,
276 CanonOutput* output, 256 CanonOutput* output,
277 CanonHostInfo* host_info) { 257 CanonHostInfo* host_info) {
278 host_info->family = IPv4AddressToNumber( 258 host_info->family = IPv4AddressToNumber(
279 spec, host, host_info->address, &host_info->num_ipv4_components); 259 spec, host, host_info->address, &host_info->num_ipv4_components);
280 260
281 switch (host_info->family) { 261 switch (host_info->family) {
282 case CanonHostInfo::IPV4: 262 case CanonHostInfo::IPV4:
283 // Definitely an IPv4 address. 263 // Definitely an IPv4 address.
284 AppendIPv4Address(host_info->address, output, &host_info->out_host); 264 host_info->out_host.begin = output->length();
265 AppendIPv4Address(host_info->address, output);
266 host_info->out_host.len = output->length() - host_info->out_host.begin;
285 return true; 267 return true;
286 case CanonHostInfo::BROKEN: 268 case CanonHostInfo::BROKEN:
287 // Definitely broken. 269 // Definitely broken.
288 return true; 270 return true;
289 default: 271 default:
290 // Could be IPv6 or a hostname. 272 // Could be IPv6 or a hostname.
291 return false; 273 return false;
292 } 274 }
293 } 275 }
294 276
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 } 598 }
617 } 599 }
618 600
619 // No invalid characters. Could still be IPv4 or a hostname. 601 // No invalid characters. Could still be IPv4 or a hostname.
620 host_info->family = CanonHostInfo::NEUTRAL; 602 host_info->family = CanonHostInfo::NEUTRAL;
621 return false; 603 return false;
622 } 604 }
623 605
624 host_info->out_host.begin = output->length(); 606 host_info->out_host.begin = output->length();
625 output->push_back('['); 607 output->push_back('[');
608 AppendIPv6Address(host_info->address, output);
609 output->push_back(']');
610 host_info->out_host.len = output->length() - host_info->out_host.begin;
626 611
627 // We will now output the address according to the rules in: 612 host_info->family = CanonHostInfo::IPV6;
613 return true;
614 }
615
616 } // namespace
617
618 void AppendIPv4Address(const unsigned char address[4], CanonOutput* output) {
619 for (int i = 0; i < 4; i++) {
620 char str[16];
621 _itoa_s(address[i], str, 10);
622
623 for (int ch = 0; str[ch] != 0; ch++)
624 output->push_back(str[ch]);
625
626 if (i != 3)
627 output->push_back('.');
628 }
629 }
630
631 void AppendIPv6Address(const unsigned char address[16], CanonOutput* output) {
632 // We will output the address according to the rules in:
628 // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#secti on-4 633 // http://tools.ietf.org/html/draft-kawamura-ipv6-text-representation-01#secti on-4
629 634
630 // Start by finding where to place the "::" contraction (if any). 635 // Start by finding where to place the "::" contraction (if any).
631 url_parse::Component contraction_range; 636 url_parse::Component contraction_range;
632 ChooseIPv6ContractionRange(host_info->address, &contraction_range); 637 ChooseIPv6ContractionRange(address, &contraction_range);
633 638
634 for (int i = 0; i <= 14;) { 639 for (int i = 0; i <= 14;) {
635 // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive. 640 // We check 2 bytes at a time, from bytes (0, 1) to (14, 15), inclusive.
636 DCHECK(i % 2 == 0); 641 DCHECK(i % 2 == 0);
637 if (i == contraction_range.begin && contraction_range.len > 0) { 642 if (i == contraction_range.begin && contraction_range.len > 0) {
638 // Jump over the contraction. 643 // Jump over the contraction.
639 if (i == 0) 644 if (i == 0)
640 output->push_back(':'); 645 output->push_back(':');
641 output->push_back(':'); 646 output->push_back(':');
642 i = contraction_range.end(); 647 i = contraction_range.end();
643 } else { 648 } else {
644 // Consume the next 16 bits from |host_info->address|. 649 // Consume the next 16 bits from |address|.
645 int x = host_info->address[i] << 8 | host_info->address[i + 1]; 650 int x = address[i] << 8 | address[i + 1];
646 651
647 i += 2; 652 i += 2;
648 653
649 // Stringify the 16 bit number (at most requires 4 hex digits). 654 // Stringify the 16 bit number (at most requires 4 hex digits).
650 char str[5]; 655 char str[5];
651 _itoa_s(x, str, 16); 656 _itoa_s(x, str, 16);
652 for (int ch = 0; str[ch] != 0; ++ch) 657 for (int ch = 0; str[ch] != 0; ++ch)
653 output->push_back(str[ch]); 658 output->push_back(str[ch]);
654 659
655 // Put a colon after each number, except the last. 660 // Put a colon after each number, except the last.
656 if (i < 16) 661 if (i < 16)
657 output->push_back(':'); 662 output->push_back(':');
658 } 663 }
659 } 664 }
660
661 output->push_back(']');
662 host_info->out_host.len = output->length() - host_info->out_host.begin;
663
664 host_info->family = CanonHostInfo::IPV6;
665 return true;
666 } 665 }
667 666
668 } // namespace
669
670 bool FindIPv4Components(const char* spec, 667 bool FindIPv4Components(const char* spec,
671 const url_parse::Component& host, 668 const url_parse::Component& host,
672 url_parse::Component components[4]) { 669 url_parse::Component components[4]) {
673 return DoFindIPv4Components<char, unsigned char>(spec, host, components); 670 return DoFindIPv4Components<char, unsigned char>(spec, host, components);
674 } 671 }
675 672
676 bool FindIPv4Components(const char16* spec, 673 bool FindIPv4Components(const char16* spec,
677 const url_parse::Component& host, 674 const url_parse::Component& host,
678 url_parse::Component components[4]) { 675 url_parse::Component components[4]) {
679 return DoFindIPv4Components<char16, char16>(spec, host, components); 676 return DoFindIPv4Components<char16, char16>(spec, host, components);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 unsigned char address[16]) { 720 unsigned char address[16]) {
724 return DoIPv6AddressToNumber<char, unsigned char>(spec, host, address); 721 return DoIPv6AddressToNumber<char, unsigned char>(spec, host, address);
725 } 722 }
726 723
727 bool IPv6AddressToNumber(const char16* spec, 724 bool IPv6AddressToNumber(const char16* spec,
728 const url_parse::Component& host, 725 const url_parse::Component& host,
729 unsigned char address[16]) { 726 unsigned char address[16]) {
730 return DoIPv6AddressToNumber<char16, char16>(spec, host, address); 727 return DoIPv6AddressToNumber<char16, char16>(spec, host, address);
731 } 728 }
732 729
733
734 } // namespace url_canon 730 } // namespace url_canon
OLDNEW
« no previous file with comments | « src/url_canon_ip.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698