1/** 2 * Copyright 2010 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// Author: Shawn Ligocki 18 19#include "phonenumbers/utf/unilib.h" 20 21#include "phonenumbers/base/basictypes.h" 22#include "phonenumbers/utf/utf.h" 23 24namespace i18n { 25namespace phonenumbers { 26namespace UniLib { 27 28namespace { 29 30// MOE: start_strip 31// MOE: end_strip 32// Codepoints not allowed for interchange are: 33// C0 (ASCII) controls: U+0000 to U+001F excluding Space (SP, U+0020), 34// Horizontal Tab (HT, U+0009), Line-Feed (LF, U+000A), 35// Form Feed (FF, U+000C) and Carriage-Return (CR, U+000D) 36// C1 controls: U+007F to U+009F 37// Surrogates: U+D800 to U+DFFF 38// Non-characters: U+FDD0 to U+FDEF and U+xxFFFE to U+xxFFFF for all xx 39inline bool IsInterchangeValidCodepoint(char32 c) { 40 return !((c >= 0x00 && c <= 0x08) || c == 0x0B || (c >= 0x0E && c <= 0x1F) || 41 (c >= 0x7F && c <= 0x9F) || 42 (c >= 0xD800 && c <= 0xDFFF) || 43 (c >= 0xFDD0 && c <= 0xFDEF) || (c&0xFFFE) == 0xFFFE); 44} 45 46} // namespace 47 48int SpanInterchangeValid(const char* begin, int byte_length) { 49 char32 rune; 50 const char* p = begin; 51 const char* end = begin + byte_length; 52 while (p < end) { 53 int bytes_consumed = charntorune(&rune, p, end - p); 54 // We want to accept Runeerror == U+FFFD as a valid char, but it is used 55 // by chartorune to indicate error. Luckily, the real codepoint is size 3 56 // while errors return bytes_consumed == 1. 57 if ((rune == Runeerror && bytes_consumed == 1) || 58 !IsInterchangeValidCodepoint(rune)) { 59 break; // Found 60 } 61 p += bytes_consumed; 62 } 63 return p - begin; 64} 65 66} // namespace UniLib 67} // namespace phonenumbers 68} // namespace i18n 69