(file) Return to LanguageParser.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2