(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 humberto 1.8  // Modified By:
 33               //
 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               void LanguageParser::parseHdr(Array<String> &values, String & hdr){
 48               	// 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 humberto 1.8  	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               Real32 LanguageParser::parseAcceptLanguageValue(String &language_tag, String & hdr){
 69               	// 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 humberto 1.8      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               		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 humberto 1.8  				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               			//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 humberto 1.8  			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               	return quality;
133               }
134               
135               String LanguageParser::parseContentLanguageValue(String & hdr){
136               	// we are looking for the language part of the hdr only,
137 humberto 1.8  	// 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               	}
158 humberto 1.8  	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               String LanguageParser::getLanguage(String & language_tag){
172               	// 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 humberto 1.8  String LanguageParser::getCountry(String & language_tag){
180               	// 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               String LanguageParser::getVariant(String & language_tag){
191               	// 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 humberto 1.8      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               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 humberto 1.8  			//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               	// 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 humberto 1.8  	//}
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