1 karl 1.11 //%2005////////////////////////////////////////////////////////////////////////
|
2 humberto 1.8 //
|
3 karl 1.10 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.9 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.10 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.11 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 humberto 1.8 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Humberto Rivero (hurivero@us.ibm.com)
31 //
|
32 aruran.ms 1.15 // Modified By: Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3697, 3698, 3699, 3700
|
33 humberto 1.8 //
34 //%/////////////////////////////////////////////////////////////////////////////
35
36 #include <Pegasus/Common/LanguageParser.h>
37 #include <Pegasus/Common/InternalException.h>
38 #include <Pegasus/Common/Tracer.h>
39 #include <Pegasus/Common/MessageLoader.h> //l10n
40 #include <cstring>
41
42 //PEGASUS_USING_STD;
43 PEGASUS_NAMESPACE_BEGIN
44
45 const LanguageParser LanguageParser::EMPTY = LanguageParser();
46
|
47 aruran.ms 1.12 void LanguageParser::parseHdr(Array<String> &values, String hdr){
|
48 humberto 1.8 // look for ',' which designates distict (Accept/Content)-Language fields
49 // the form: [languagetag, languagetag, languagetag] so whitespace removal
50 // may be necessary.
51 // then store them in the array
52 PEG_METHOD_ENTER(TRC_L10N, "LanguageParser::parseHdr");
53 Uint32 i = 0;
54 while( i != PEG_NOT_FOUND ){
55 i = hdr.find(",");
56 if( i != PEG_NOT_FOUND ){
57 values.append(hdr.subString(0,i));
58 while(hdr[i+1] == ' ') i++; // get rid of whitespace after ","
59 hdr = hdr.subString(i+1);
60 }
61 else{ // only one field, build an object with it
62 values.append(hdr);
63 }
64 }
65 PEG_METHOD_EXIT();
66 }
67
|
68 aruran.ms 1.13 Real32 LanguageParser::parseAcceptLanguageValue(String &language_tag, String hdr){
|
69 humberto 1.8 // look for ';' in hdr, that means we have a quality value to capture
70 // if not, we only have a language
71
72 // if hdr begins with "x-" then we have a non-IANA (private) language tag
73 PEG_METHOD_ENTER(TRC_L10N, "LanguageParser::parseAcceptLanguageValue");
74 Uint32 i;
75 Boolean validate_length = true;
76 if((( i = hdr.find("x-")) != PEG_NOT_FOUND ) && (i == 0)){
77 hdr = convertPrivateLanguageTag(hdr);
78 validate_length = false;
79 }
80
81 // get rid of any beginning or trailing whitespaces
82 Uint32 j;
83 while( (j = hdr.find(" ")) != PEG_NOT_FOUND ){
84 hdr.remove(j,1);
85 }
86
87 Real32 quality = 1;
88 i = hdr.find(";");
89 if(i != PEG_NOT_FOUND){ // extract and store language and quality
90 humberto 1.8 if(isValid(hdr.subString(0,i), validate_length)){
91 language_tag = hdr.subString(0,i);
92 if(hdr.size() > i + 3)
93 hdr.remove(0,i+3); // remove everything but the quality value
94 else{
95 MessageLoaderParms parms("Common.LanguageParser.INVALID_QUALITY_VALUE",
96 "AcceptLanguage contains an invalid quality value");
97 throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms));
98 }
99 }
100 else{
101 //l10n
102 //throw InvalidAcceptLanguageHeader(
103 //"AcceptLanguage contains too many characters or non-alpha characters");
104 MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_AL",
105 "AcceptLanguage contains too many characters or non-alpha characters");
106 throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms));
107 }
108 //validate quality
109 quality = atof(hdr.getCString());
110 if(quality > 1.0 || quality < 0.0){
111 humberto 1.8 //l10n
112 //throw InvalidAcceptLanguageHeader(
113 //"AcceptLanguage contains an invalid quality value");
114 MessageLoaderParms parms("Common.LanguageParser.INVALID_QUALITY_VALUE",
115 "AcceptLanguage contains an invalid quality value");
116 throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms));
117 }
118 }
119 else{ // extract and store language, quality defaults to 1.0
120 if(isValid(hdr, validate_length)) language_tag = hdr;
121 else{
122 //l10n
123 //throw InvalidAcceptLanguageHeader(
124 //"AcceptLanguage contains too many characters or non-alpha characters");
125 MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_AL",
126 "AcceptLanguage contains too many characters or non-alpha characters");
127 throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms));
128 }
129 }
130
131 PEG_METHOD_EXIT();
132 humberto 1.8 return quality;
133 }
134
|
135 aruran.ms 1.14 String LanguageParser::parseContentLanguageValue(const String& hdr){
|
136 humberto 1.8 // we are looking for the language part of the hdr only,
137 // according to the RFC, there may be parenthesized strings
138 // that describe the purpose of the language, we need to ignore those
139 PEG_METHOD_ENTER(TRC_L10N, "LanguageParser::parseContentLanguageValue");
140 String value = hdr;
141 Uint32 i,j;
142 while((i = value.find("(")) != PEG_NOT_FOUND){ // get rid of anything in parenthesis in hdr if found
143 if((j = value.find(")")) != PEG_NOT_FOUND)
144 value.remove(i, (j-i)+1);
145 else{
146 //l10n
147 //throw InvalidContentLanguageHeader(
148 //"ContentLanguage does not contain terminating ) character");
149 MessageLoaderParms parms("Common.LanguageParser.DOES_NOT_CONTAIN_TERMINATING",
150 "ContentLanguage does not contain terminating ) character");
151 throw InvalidContentLanguageHeader(MessageLoader::getMessage(parms));
152 }
153 }
154 // get rid of any beginning or trailing whitespaces
155 while( (i = value.find(" ")) != PEG_NOT_FOUND ){
156 value.remove(i,1);
157 humberto 1.8 }
158 if(!isValid(value)){
159 //l10n
160 //throw InvalidContentLanguageHeader(
161 //"ContentLanguage contains too many characters or non-alpha characters");
162 MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_CL",
163 "ContentLanguage contains too many characters or non-alpha characters");
164 throw InvalidContentLanguageHeader(MessageLoader::getMessage(parms));
165
166 }
167 PEG_METHOD_EXIT();
168 return value;
169 }
170
|
171 aruran.ms 1.15 String LanguageParser::getLanguage(const String & language_tag){
|
172 humberto 1.8 // given a language_tag: en-US-mn we want to return "en"
173 Uint32 i;
174 if((i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND)
175 return language_tag.subString(0,i);
176 return String(language_tag);
177 }
178
|
179 aruran.ms 1.15 String LanguageParser::getCountry(const String & language_tag){
|
180 humberto 1.8 // given a language_tag: en-US-mn we want to return "US"
181 Uint32 i,j;
182 if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND )
183 if( (j = language_tag.find(i+1, findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND )
184 return language_tag.subString(i+1, j-(i+1));
185 else
186 return language_tag.subString(i+1);
187 return String::EMPTY;
188 }
189
|
190 aruran.ms 1.15 String LanguageParser::getVariant(const String & language_tag){
|
191 humberto 1.8 // given a language_tag: en-US-mn we want to return "mn"
192 Uint32 i;
193 if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND )
194 if( (i = language_tag.find(i+1, findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND )
195 return language_tag.subString(i+1);
196 return String::EMPTY;
197 }
198
199 void LanguageParser::parseLanguageSubtags(Array<String> &subtags, String language_tag){
200 PEG_METHOD_ENTER(TRC_L10N, "LanguageParser::parseLanguageSubtags");
201 Uint32 i;
202 char separator = findSeparator(language_tag.getCString());
203 while( (i = language_tag.find(Char16(separator))) != PEG_NOT_FOUND ){
204 subtags.append(language_tag.subString(0,i));
205 language_tag.remove(0,i + 1);
206 }
207 if(language_tag.size() > 0)
208 subtags.append(language_tag);
209 PEG_METHOD_EXIT();
210 }
211
212 humberto 1.8 Boolean LanguageParser::isValid(String language_tag, Boolean validate_length){
213 //break the String down into parts(subtags), then validate each part
214
215 if(language_tag == "*") return true;
216
217 Array<String> subtags;
218 parseLanguageSubtags(subtags, language_tag);
219 if(subtags.size() > 0){
220 for(Uint32 i = 0; i < subtags.size(); i++){
221 //length should be 8 or less AND all characters should be A-Z or a-z
222 if((validate_length && subtags[i].size() > 8) || !checkAlpha(subtags[i].getCString()))
223 return false;
224 }
225 }
226 else{ //nothing back from parseLanguageSubtags
227 return false;
228 }
229 return true;
230 }
231
232 String LanguageParser::convertPrivateLanguageTag(String language_tag){
233 humberto 1.8 // figure out if its a unix style locale or windows locale
234 Uint32 i;
235 if(( i = language_tag.find("pegasus-")) != PEG_NOT_FOUND ){
236 language_tag = language_tag.subString(i+5); // capture the remainder of the string
237 return String(replaceSeparator(language_tag.getCString(), '-'));
238 }
239 //else if( (i = language_tag.find("win-")) != PEG_NOT_FOUND ){
240 // return language_tag.subString(i+4); // capture the remainder of the string
241 // call windows ID to ICU convert routine or locmap.c function here
242 //}
243 else{
244 return language_tag;
245 }
246 }
247
248 Boolean LanguageParser::checkAlpha(CString _str){
|
249 humberto 1.7 Uint32 length = (Uint32) strlen(_str);
|
250 humberto 1.8 for(Uint32 i = 0; i < length; i++)
251 if( !isalpha(_str[i]) )
252 return false;
253 return true;
254 }
255
256 char LanguageParser::findSeparator(CString _str){
|
257 kumpf 1.4 Uint32 length = (Uint32) strlen(_str);
|
258 humberto 1.8 for(Uint32 i = 0; i < length; i++)
259 if(!isalnum(_str[i]))
260 return _str[i];
261 return '\0';
262 }
263
264 CString LanguageParser::replaceSeparator(CString _s, char new_sep){
265 char * _str = const_cast<char *>((const char*)_s);
|
266 kumpf 1.4 Uint32 length = (Uint32) strlen(_str);
|
267 humberto 1.8 for(Uint32 i = 0; i < length; i++)
268 _str[i] = (!isalnum(_str[i])) ? new_sep : _str[i];
269 return (String(_str)).getCString();
270 }
271
272
273 PEGASUS_NAMESPACE_END
|