OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/autofill/phone_field.h" | 5 #include "chrome/browser/autofill/phone_field.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "chrome/browser/autofill/autofill_field.h" | 12 #include "chrome/browser/autofill/autofill_field.h" |
13 #include "chrome/browser/autofill/autofill_regex_constants.h" | 13 #include "chrome/browser/autofill/autofill_regex_constants.h" |
14 #include "chrome/browser/autofill/autofill_scanner.h" | 14 #include "chrome/browser/autofill/autofill_scanner.h" |
15 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 // This string includes all area code separators, including NoText. | 19 // This string includes all area code separators, including NoText. |
20 string16 GetAreaRegex() { | 20 string16 GetAreaRegex() { |
21 string16 area_code = UTF8ToUTF16(autofill::kAreaCodeRe); | 21 string16 area_code = UTF8ToUTF16(autofill::kAreaCodeRe); |
22 area_code.append(ASCIIToUTF16("|")); // Regexp separator. | 22 area_code.append(ASCIIToUTF16("|")); // Regexp separator. |
23 area_code.append(UTF8ToUTF16(autofill::kAreaCodeNotextRe)); | 23 area_code.append(UTF8ToUTF16(autofill::kAreaCodeNotextRe)); |
24 return area_code; | 24 return area_code; |
25 } | 25 } |
26 | 26 |
27 } // namespace | 27 } // namespace |
28 | 28 |
29 PhoneField::~PhoneField() {} | |
30 | |
29 // Phone field grammars - first matched grammar will be parsed. Grammars are | 31 // Phone field grammars - first matched grammar will be parsed. Grammars are |
30 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are | 32 // separated by { REGEX_SEPARATOR, FIELD_NONE, 0 }. Suffix and extension are |
31 // parsed separately unless they are necessary parts of the match. | 33 // parsed separately unless they are necessary parts of the match. |
32 // The following notation is used to describe the patterns: | 34 // The following notation is used to describe the patterns: |
33 // <cc> - country code field. | 35 // <cc> - country code field. |
34 // <ac> - area code field. | 36 // <ac> - area code field. |
35 // <phone> - phone or prefix. | 37 // <phone> - phone or prefix. |
36 // <suffix> - suffix. | 38 // <suffix> - suffix. |
37 // <ext> - extension. | 39 // <ext> - extension. |
38 // :N means field is limited to N characters, otherwise it is unlimited. | 40 // :N means field is limited to N characters, otherwise it is unlimited. |
39 // (pattern <field>)? means pattern is optional and matched separately. | 41 // (pattern <field>)? means pattern is optional and matched separately. |
40 PhoneField::Parser PhoneField::phone_field_grammars_[] = { | 42 const PhoneField::Parser PhoneField::kPhoneFieldGrammars[] = { |
41 // Country code: <cc> Area Code: <ac> Phone: <phone> (- <suffix> | 43 // Country code: <cc> Area Code: <ac> Phone: <phone> (- <suffix> |
42 // (Ext: <ext>)?)? | 44 // (Ext: <ext>)?)? |
43 { PhoneField::REGEX_COUNTRY, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 45 { REGEX_COUNTRY, FIELD_COUNTRY_CODE, 0 }, |
44 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, | 46 { REGEX_AREA, FIELD_AREA_CODE, 0 }, |
45 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, | 47 { REGEX_PHONE, FIELD_PHONE, 0 }, |
46 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 48 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
47 // \( <ac> \) <phone>:3 <suffix>:4 (Ext: <ext>)? | 49 // \( <ac> \) <phone>:3 <suffix>:4 (Ext: <ext>)? |
48 { PhoneField::REGEX_AREA_NOTEXT, PhoneField::FIELD_AREA_CODE, 3 }, | 50 { REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 3 }, |
49 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 3 }, | 51 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3 }, |
50 { PhoneField::REGEX_PHONE, PhoneField::FIELD_SUFFIX, 4 }, | 52 { REGEX_PHONE, FIELD_SUFFIX, 4 }, |
51 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 53 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
52 // Phone: <cc> <ac>:3 - <phone>:3 - <suffix>:4 (Ext: <ext>)? | 54 // Phone: <cc> <ac>:3 - <phone>:3 - <suffix>:4 (Ext: <ext>)? |
53 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 55 { REGEX_PHONE, FIELD_COUNTRY_CODE, 0 }, |
54 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 3 }, | 56 { REGEX_PHONE, FIELD_AREA_CODE, 3 }, |
55 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 3 }, | 57 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3 }, |
56 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 4 }, | 58 { REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4 }, |
57 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 59 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
58 // Phone: <cc>:3 <ac>:3 <phone>:3 <suffix>:4 (Ext: <ext>)? | 60 // Phone: <cc>:3 <ac>:3 <phone>:3 <suffix>:4 (Ext: <ext>)? |
59 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 3 }, | 61 { REGEX_PHONE, FIELD_COUNTRY_CODE, 3 }, |
60 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 3 }, | 62 { REGEX_PHONE, FIELD_AREA_CODE, 3 }, |
61 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 3 }, | 63 { REGEX_PHONE, FIELD_PHONE, 3 }, |
62 { PhoneField::REGEX_PHONE, PhoneField::FIELD_SUFFIX, 4 }, | 64 { REGEX_PHONE, FIELD_SUFFIX, 4 }, |
63 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 65 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
64 // Area Code: <ac> Phone: <phone> (- <suffix> (Ext: <ext>)?)? | 66 // Area Code: <ac> Phone: <phone> (- <suffix> (Ext: <ext>)?)? |
65 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, | 67 { REGEX_AREA, FIELD_AREA_CODE, 0 }, |
66 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, | 68 { REGEX_PHONE, FIELD_PHONE, 0 }, |
67 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 69 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
68 // Phone: <ac> <phone>:3 <suffix>:4 (Ext: <ext>)? | 70 // Phone: <ac> <phone>:3 <suffix>:4 (Ext: <ext>)? |
69 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, | 71 { REGEX_PHONE, FIELD_AREA_CODE, 0 }, |
70 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 3 }, | 72 { REGEX_PHONE, FIELD_PHONE, 3 }, |
71 { PhoneField::REGEX_PHONE, PhoneField::FIELD_SUFFIX, 4 }, | 73 { REGEX_PHONE, FIELD_SUFFIX, 4 }, |
72 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 74 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
73 // Phone: <cc> \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? | 75 // Phone: <cc> \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? |
74 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 76 { REGEX_PHONE, FIELD_COUNTRY_CODE, 0 }, |
75 { PhoneField::REGEX_AREA_NOTEXT, PhoneField::FIELD_AREA_CODE, 0 }, | 77 { REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 0 }, |
76 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, | 78 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0 }, |
77 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 79 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
78 // Phone: \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? | 80 // Phone: \( <ac> \) <phone> (- <suffix> (Ext: <ext>)?)? |
79 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 81 { REGEX_PHONE, FIELD_COUNTRY_CODE, 0 }, |
80 { PhoneField::REGEX_AREA_NOTEXT, PhoneField::FIELD_AREA_CODE, 0 }, | 82 { REGEX_AREA_NOTEXT, FIELD_AREA_CODE, 0 }, |
81 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, | 83 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0 }, |
82 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 84 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
83 // Phone: <cc> - <ac> - <phone> - <suffix> (Ext: <ext>)? | 85 // Phone: <cc> - <ac> - <phone> - <suffix> (Ext: <ext>)? |
84 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 86 { REGEX_PHONE, FIELD_COUNTRY_CODE, 0 }, |
85 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_AREA_CODE, 0 }, | 87 { REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE, 0 }, |
86 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, | 88 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 0 }, |
87 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 0 }, | 89 { REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 0 }, |
88 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 90 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
89 // Phone: <ac> Prefix: <phone> Suffix: <suffix> (Ext: <ext>)? | 91 // Phone: <ac> Prefix: <phone> Suffix: <suffix> (Ext: <ext>)? |
90 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, | 92 { REGEX_PHONE, FIELD_AREA_CODE, 0 }, |
91 { PhoneField::REGEX_PREFIX, PhoneField::FIELD_PHONE, 0 }, | 93 { REGEX_PREFIX, FIELD_PHONE, 0 }, |
92 { PhoneField::REGEX_SUFFIX, PhoneField::FIELD_SUFFIX, 0 }, | 94 { REGEX_SUFFIX, FIELD_SUFFIX, 0 }, |
93 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 95 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
94 // Phone: <ac> - <phone>:3 - <suffix>:4 (Ext: <ext>)? | 96 // Phone: <ac> - <phone>:3 - <suffix>:4 (Ext: <ext>)? |
95 { PhoneField::REGEX_PHONE, PhoneField::FIELD_AREA_CODE, 0 }, | 97 { REGEX_PHONE, FIELD_AREA_CODE, 0 }, |
96 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_PHONE, 3 }, | 98 { REGEX_PREFIX_SEPARATOR, FIELD_PHONE, 3 }, |
97 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_SUFFIX, 4 }, | 99 { REGEX_SUFFIX_SEPARATOR, FIELD_SUFFIX, 4 }, |
98 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 100 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
99 // Phone: <cc> - <ac> - <phone> (Ext: <ext>)? | 101 // Phone: <cc> - <ac> - <phone> (Ext: <ext>)? |
100 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 0 }, | 102 { REGEX_PHONE, FIELD_COUNTRY_CODE, 0 }, |
101 { PhoneField::REGEX_PREFIX_SEPARATOR, PhoneField::FIELD_AREA_CODE, 0 }, | 103 { REGEX_PREFIX_SEPARATOR, FIELD_AREA_CODE, 0 }, |
102 { PhoneField::REGEX_SUFFIX_SEPARATOR, PhoneField::FIELD_PHONE, 0 }, | 104 { REGEX_SUFFIX_SEPARATOR, FIELD_PHONE, 0 }, |
103 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 105 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
104 // Phone: <ac> - <phone> (Ext: <ext>)? | 106 // Phone: <ac> - <phone> (Ext: <ext>)? |
105 { PhoneField::REGEX_AREA, PhoneField::FIELD_AREA_CODE, 0 }, | 107 { REGEX_AREA, FIELD_AREA_CODE, 0 }, |
106 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, | 108 { REGEX_PHONE, FIELD_PHONE, 0 }, |
107 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 109 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
108 // Phone: <cc>:3 - <phone>:10 (Ext: <ext>)? | 110 // Phone: <cc>:3 - <phone>:10 (Ext: <ext>)? |
109 { PhoneField::REGEX_PHONE, PhoneField::FIELD_COUNTRY_CODE, 3 }, | 111 { REGEX_PHONE, FIELD_COUNTRY_CODE, 3 }, |
110 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 10 }, | 112 { REGEX_PHONE, FIELD_PHONE, 10 }, |
111 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 113 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
112 // Phone: <phone> (Ext: <ext>)? | 114 // Phone: <phone> (Ext: <ext>)? |
113 { PhoneField::REGEX_PHONE, PhoneField::FIELD_PHONE, 0 }, | 115 { REGEX_PHONE, FIELD_PHONE, 0 }, |
114 { PhoneField::REGEX_SEPARATOR, FIELD_NONE, 0 }, | 116 { REGEX_SEPARATOR, FIELD_NONE, 0 }, |
115 }; | 117 }; |
116 | 118 |
117 PhoneField::~PhoneField() {} | |
118 | |
119 // static | 119 // static |
120 FormField* PhoneField::Parse(AutofillScanner* scanner, | 120 FormField* PhoneField::Parse(AutofillScanner* scanner, |
121 bool parse_new_field_types) { | 121 bool parse_new_field_types) { |
122 if (scanner->IsEnd()) | 122 if (scanner->IsEnd()) |
123 return NULL; | 123 return NULL; |
124 | 124 |
125 scanner->SaveCursor(); | |
126 | |
127 // The form owns the following variables, so they should not be deleted. | |
128 const AutofillField* parsed_fields[FIELD_MAX]; | |
129 | |
130 for (size_t i = 0; i < arraysize(kPhoneFieldGrammars); ++i) { | |
131 memset(parsed_fields, 0, sizeof(parsed_fields)); | |
132 scanner->SaveCursor(); | |
133 | |
134 // Attempt to parse according to the next grammar. | |
135 for (; i < arraysize(kPhoneFieldGrammars) && | |
136 kPhoneFieldGrammars[i].regex != REGEX_SEPARATOR; ++i) { | |
137 if (!ParseFieldSpecifics( | |
138 scanner, | |
139 GetRegExp(kPhoneFieldGrammars[i].regex), | |
140 MATCH_DEFAULT | MATCH_TELEPHONE, | |
141 &parsed_fields[kPhoneFieldGrammars[i].phone_part])) | |
142 break; | |
143 if (kPhoneFieldGrammars[i].max_size && | |
144 (!parsed_fields[kPhoneFieldGrammars[i].phone_part]->max_length || | |
145 kPhoneFieldGrammars[i].max_size < | |
146 parsed_fields[kPhoneFieldGrammars[i].phone_part]->max_length)) { | |
147 break; | |
148 } | |
149 } | |
150 | |
151 if (i >= arraysize(kPhoneFieldGrammars)) { | |
152 scanner->Rewind(); | |
153 return NULL; // Parsing failed. | |
154 } | |
155 if (kPhoneFieldGrammars[i].regex == REGEX_SEPARATOR) | |
156 break; // Parsing succeeded. | |
157 | |
158 // Proceed to the next grammar. | |
159 do { | |
160 ++i; | |
161 } while (i < arraysize(kPhoneFieldGrammars) && | |
162 kPhoneFieldGrammars[i].regex != REGEX_SEPARATOR); | |
163 | |
164 if (i + 1 == arraysize(kPhoneFieldGrammars)) { | |
165 scanner->Rewind(); | |
166 return NULL; // Tried through all the possibilities - did not match. | |
167 } | |
168 | |
169 scanner->Rewind(); | |
170 } | |
171 | |
172 if (!parsed_fields[FIELD_PHONE]) { | |
173 scanner->Rewind(); | |
174 return NULL; | |
175 } | |
176 | |
125 scoped_ptr<PhoneField> phone_field(new PhoneField); | 177 scoped_ptr<PhoneField> phone_field(new PhoneField); |
126 if (ParseInternal(phone_field.get(), scanner)) | 178 for (int i = 0; i < FIELD_MAX; ++i) |
127 return phone_field.release(); | 179 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; |
128 | 180 |
129 return NULL; | 181 // Look for optional fields. |
130 } | |
131 | 182 |
132 PhoneField::PhoneField() { | 183 // Look for a third text box. |
133 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); | 184 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { |
185 if (!ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixRe), | |
186 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { | |
187 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe), | |
188 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); | |
189 } | |
190 } | |
191 | |
192 // Now look for an extension. | |
193 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneExtensionRe), | |
194 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); | |
Ilya Sherman
2013/01/15 22:17:33
Lines 125-194 were just copy/pasted, with the only
| |
195 | |
196 return phone_field.release(); | |
134 } | 197 } |
135 | 198 |
136 bool PhoneField::ClassifyField(FieldTypeMap* map) const { | 199 bool PhoneField::ClassifyField(FieldTypeMap* map) const { |
137 bool ok = true; | 200 bool ok = true; |
138 | 201 |
139 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. | 202 DCHECK(parsed_phone_fields_[FIELD_PHONE]); // Phone was correctly parsed. |
140 | 203 |
141 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || | 204 if ((parsed_phone_fields_[FIELD_COUNTRY_CODE] != NULL) || |
142 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || | 205 (parsed_phone_fields_[FIELD_AREA_CODE] != NULL) || |
143 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { | 206 (parsed_phone_fields_[FIELD_SUFFIX] != NULL)) { |
(...skipping 27 matching lines...) Expand all Loading... | |
171 } | 234 } |
172 } else { | 235 } else { |
173 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], | 236 ok = AddClassification(parsed_phone_fields_[FIELD_PHONE], |
174 PHONE_HOME_WHOLE_NUMBER, | 237 PHONE_HOME_WHOLE_NUMBER, |
175 map); | 238 map); |
176 } | 239 } |
177 | 240 |
178 return ok; | 241 return ok; |
179 } | 242 } |
180 | 243 |
181 string16 PhoneField::GetRegExp(RegexType regex_id) const { | 244 PhoneField::PhoneField() { |
245 memset(parsed_phone_fields_, 0, sizeof(parsed_phone_fields_)); | |
246 } | |
247 | |
248 // static | |
249 string16 PhoneField::GetRegExp(RegexType regex_id) { | |
182 switch (regex_id) { | 250 switch (regex_id) { |
183 case REGEX_COUNTRY: | 251 case REGEX_COUNTRY: |
184 return UTF8ToUTF16(autofill::kCountryCodeRe); | 252 return UTF8ToUTF16(autofill::kCountryCodeRe); |
185 case REGEX_AREA: | 253 case REGEX_AREA: |
186 return GetAreaRegex(); | 254 return GetAreaRegex(); |
187 case REGEX_AREA_NOTEXT: | 255 case REGEX_AREA_NOTEXT: |
188 return UTF8ToUTF16(autofill::kAreaCodeNotextRe); | 256 return UTF8ToUTF16(autofill::kAreaCodeNotextRe); |
189 case REGEX_PHONE: | 257 case REGEX_PHONE: |
190 return UTF8ToUTF16(autofill::kPhoneRe); | 258 return UTF8ToUTF16(autofill::kPhoneRe); |
191 case REGEX_PREFIX_SEPARATOR: | 259 case REGEX_PREFIX_SEPARATOR: |
192 return UTF8ToUTF16(autofill::kPhonePrefixSeparatorRe); | 260 return UTF8ToUTF16(autofill::kPhonePrefixSeparatorRe); |
193 case REGEX_PREFIX: | 261 case REGEX_PREFIX: |
194 return UTF8ToUTF16(autofill::kPhonePrefixRe); | 262 return UTF8ToUTF16(autofill::kPhonePrefixRe); |
195 case REGEX_SUFFIX_SEPARATOR: | 263 case REGEX_SUFFIX_SEPARATOR: |
196 return UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe); | 264 return UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe); |
197 case REGEX_SUFFIX: | 265 case REGEX_SUFFIX: |
198 return UTF8ToUTF16(autofill::kPhoneSuffixRe); | 266 return UTF8ToUTF16(autofill::kPhoneSuffixRe); |
199 case REGEX_EXTENSION: | 267 case REGEX_EXTENSION: |
200 return UTF8ToUTF16(autofill::kPhoneExtensionRe); | 268 return UTF8ToUTF16(autofill::kPhoneExtensionRe); |
201 default: | 269 default: |
202 NOTREACHED(); | 270 NOTREACHED(); |
203 break; | 271 break; |
204 } | 272 } |
205 return string16(); | 273 return string16(); |
206 } | 274 } |
207 | |
208 // static | |
209 bool PhoneField::ParseInternal(PhoneField *phone_field, | |
210 AutofillScanner* scanner) { | |
211 DCHECK(phone_field); | |
212 scanner->SaveCursor(); | |
213 | |
214 // The form owns the following variables, so they should not be deleted. | |
215 const AutofillField* parsed_fields[FIELD_MAX]; | |
216 | |
217 for (size_t i = 0; i < arraysize(phone_field_grammars_); ++i) { | |
218 memset(parsed_fields, 0, sizeof(parsed_fields)); | |
219 scanner->SaveCursor(); | |
220 | |
221 // Attempt to parse according to the next grammar. | |
222 for (; i < arraysize(phone_field_grammars_) && | |
223 phone_field_grammars_[i].regex != REGEX_SEPARATOR; ++i) { | |
224 if (!ParseFieldSpecifics( | |
225 scanner, | |
226 phone_field->GetRegExp(phone_field_grammars_[i].regex), | |
227 MATCH_DEFAULT | MATCH_TELEPHONE, | |
228 &parsed_fields[phone_field_grammars_[i].phone_part])) | |
229 break; | |
230 if (phone_field_grammars_[i].max_size && | |
231 (!parsed_fields[phone_field_grammars_[i].phone_part]->max_length || | |
232 phone_field_grammars_[i].max_size < | |
233 parsed_fields[phone_field_grammars_[i].phone_part]->max_length)) { | |
234 break; | |
235 } | |
236 } | |
237 | |
238 if (i >= arraysize(phone_field_grammars_)) { | |
239 scanner->Rewind(); | |
240 return false; // Parsing failed. | |
241 } | |
242 if (phone_field_grammars_[i].regex == REGEX_SEPARATOR) | |
243 break; // Parsing succeeded. | |
244 | |
245 // Proceed to the next grammar. | |
246 do { | |
247 ++i; | |
248 } while (i < arraysize(phone_field_grammars_) && | |
249 phone_field_grammars_[i].regex != REGEX_SEPARATOR); | |
250 | |
251 if (i + 1 == arraysize(phone_field_grammars_)) { | |
252 scanner->Rewind(); | |
253 return false; // Tried through all the possibilities - did not match. | |
254 } | |
255 | |
256 scanner->Rewind(); | |
257 } | |
258 | |
259 if (!parsed_fields[FIELD_PHONE]) { | |
260 scanner->Rewind(); | |
261 return false; | |
262 } | |
263 | |
264 for (int i = 0; i < FIELD_MAX; ++i) | |
265 phone_field->parsed_phone_fields_[i] = parsed_fields[i]; | |
266 | |
267 // Look for optional fields. | |
268 | |
269 // Look for a third text box. | |
270 if (!phone_field->parsed_phone_fields_[FIELD_SUFFIX]) { | |
271 if (!ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixRe), | |
272 &phone_field->parsed_phone_fields_[FIELD_SUFFIX])) { | |
273 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneSuffixSeparatorRe), | |
274 &phone_field->parsed_phone_fields_[FIELD_SUFFIX]); | |
275 } | |
276 } | |
277 | |
278 // Now look for an extension. | |
279 ParseField(scanner, UTF8ToUTF16(autofill::kPhoneExtensionRe), | |
280 &phone_field->parsed_phone_fields_[FIELD_EXTENSION]); | |
281 | |
282 return true; | |
283 } | |
OLD | NEW |