version 1.1.2.1, 2003/07/16 21:45:25
|
version 1.16, 2005/05/30 13:49:46
|
|
|
//%///////////////////////////////////////////////////////////////////////////// |
//%2005//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM, |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// The Open Group, Tivoli Systems |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation, The Open Group. |
|
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; VERITAS Software Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// | // |
// Author: Humberto Rivero (hurivero@us.ibm.com) | // Author: Humberto Rivero (hurivero@us.ibm.com) |
// | // |
// Modified By: |
// Modified By: Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3697, 3698, 3699, 3700 |
|
// Aruran, IBM (ashanmug@in.ibm.com) for Bug# 3701 |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/LanguageParser.h> | #include <Pegasus/Common/LanguageParser.h> |
#include <Pegasus/Common/InternalException.h> | #include <Pegasus/Common/InternalException.h> |
#include <Pegasus/Common/Tracer.h> | #include <Pegasus/Common/Tracer.h> |
|
#include <Pegasus/Common/MessageLoader.h> //l10n |
#include <cstring> | #include <cstring> |
| |
//PEGASUS_USING_STD; | //PEGASUS_USING_STD; |
|
|
| |
const LanguageParser LanguageParser::EMPTY = LanguageParser(); | const LanguageParser LanguageParser::EMPTY = LanguageParser(); |
| |
void LanguageParser::parseHdr(Array<String> &values, String & hdr){ |
void LanguageParser::parseHdr(Array<String> &values, String hdr){ |
// look for ',' which designates distict (Accept/Content)-Language fields | // look for ',' which designates distict (Accept/Content)-Language fields |
// the form: [languagetag, languagetag, languagetag] so whitespace removal | // the form: [languagetag, languagetag, languagetag] so whitespace removal |
// may be necessary. | // may be necessary. |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
Real32 LanguageParser::parseAcceptLanguageValue(String &language_tag, String & hdr){ |
Real32 LanguageParser::parseAcceptLanguageValue(String &language_tag, String hdr){ |
// look for ';' in hdr, that means we have a quality value to capture | // look for ';' in hdr, that means we have a quality value to capture |
// if not, we only have a language | // if not, we only have a language |
| |
|
|
if(i != PEG_NOT_FOUND){ // extract and store language and quality | if(i != PEG_NOT_FOUND){ // extract and store language and quality |
if(isValid(hdr.subString(0,i), validate_length)){ | if(isValid(hdr.subString(0,i), validate_length)){ |
language_tag = hdr.subString(0,i); | language_tag = hdr.subString(0,i); |
|
if(hdr.size() > i + 3) |
hdr.remove(0,i+3); // remove everything but the quality value | hdr.remove(0,i+3); // remove everything but the quality value |
|
else{ |
|
MessageLoaderParms parms("Common.LanguageParser.INVALID_QUALITY_VALUE", |
|
"AcceptLanguage contains an invalid quality value"); |
|
throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms)); |
|
} |
} | } |
else{ | else{ |
throw InvalidAcceptLanguageHeader( |
//l10n |
|
//throw InvalidAcceptLanguageHeader( |
|
//"AcceptLanguage contains too many characters or non-alpha characters"); |
|
MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_AL", |
"AcceptLanguage contains too many characters or non-alpha characters"); | "AcceptLanguage contains too many characters or non-alpha characters"); |
|
throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms)); |
} | } |
//validate quality | //validate quality |
quality = atof(hdr.getCString()); | quality = atof(hdr.getCString()); |
if(quality > 1.0 || quality < 0.0){ | if(quality > 1.0 || quality < 0.0){ |
throw InvalidAcceptLanguageHeader( |
//l10n |
|
//throw InvalidAcceptLanguageHeader( |
|
//"AcceptLanguage contains an invalid quality value"); |
|
MessageLoaderParms parms("Common.LanguageParser.INVALID_QUALITY_VALUE", |
"AcceptLanguage contains an invalid quality value"); | "AcceptLanguage contains an invalid quality value"); |
|
throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms)); |
} | } |
} | } |
else{ // extract and store language, quality defaults to 1.0 | else{ // extract and store language, quality defaults to 1.0 |
if(isValid(hdr, validate_length)) language_tag = hdr; | if(isValid(hdr, validate_length)) language_tag = hdr; |
else throw InvalidAcceptLanguageHeader( |
else{ |
|
//l10n |
|
//throw InvalidAcceptLanguageHeader( |
|
//"AcceptLanguage contains too many characters or non-alpha characters"); |
|
MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_AL", |
"AcceptLanguage contains too many characters or non-alpha characters"); | "AcceptLanguage contains too many characters or non-alpha characters"); |
|
throw InvalidAcceptLanguageHeader(MessageLoader::getMessage(parms)); |
|
} |
} | } |
| |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return quality; | return quality; |
} | } |
| |
String LanguageParser::parseContentLanguageValue(String & hdr){ |
String LanguageParser::parseContentLanguageValue(const String& hdr){ |
// we are looking for the language part of the hdr only, | // we are looking for the language part of the hdr only, |
// according to the RFC, there may be parenthesized strings | // according to the RFC, there may be parenthesized strings |
// that describe the purpose of the language, we need to ignore those | // that describe the purpose of the language, we need to ignore those |
|
|
while((i = value.find("(")) != PEG_NOT_FOUND){ // get rid of anything in parenthesis in hdr if found | while((i = value.find("(")) != PEG_NOT_FOUND){ // get rid of anything in parenthesis in hdr if found |
if((j = value.find(")")) != PEG_NOT_FOUND) | if((j = value.find(")")) != PEG_NOT_FOUND) |
value.remove(i, (j-i)+1); | value.remove(i, (j-i)+1); |
else throw InvalidContentLanguageHeader( |
else{ |
|
//l10n |
|
//throw InvalidContentLanguageHeader( |
|
//"ContentLanguage does not contain terminating ) character"); |
|
MessageLoaderParms parms("Common.LanguageParser.DOES_NOT_CONTAIN_TERMINATING", |
"ContentLanguage does not contain terminating ) character"); | "ContentLanguage does not contain terminating ) character"); |
|
throw InvalidContentLanguageHeader(MessageLoader::getMessage(parms)); |
|
} |
} | } |
// get rid of any beginning or trailing whitespaces | // get rid of any beginning or trailing whitespaces |
while( (i = value.find(" ")) != PEG_NOT_FOUND ){ | while( (i = value.find(" ")) != PEG_NOT_FOUND ){ |
value.remove(i,1); | value.remove(i,1); |
} | } |
if(!isValid(value)) throw InvalidContentLanguageHeader( |
if(!isValid(value)){ |
|
//l10n |
|
//throw InvalidContentLanguageHeader( |
|
//"ContentLanguage contains too many characters or non-alpha characters"); |
|
MessageLoaderParms parms("Common.LanguageParser.TOO_MANY_OR_NON_ALPHA_CHARACTERS_CL", |
"ContentLanguage contains too many characters or non-alpha characters"); | "ContentLanguage contains too many characters or non-alpha characters"); |
|
throw InvalidContentLanguageHeader(MessageLoader::getMessage(parms)); |
|
|
|
} |
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return value; | return value; |
} | } |
| |
String LanguageParser::getLanguage(String & language_tag){ |
String LanguageParser::getLanguage(const String & language_tag){ |
// given a language_tag: en-US-mn we want to return "en" | // given a language_tag: en-US-mn we want to return "en" |
Uint32 i; | Uint32 i; |
if((i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND) | if((i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND) |
|
|
return String(language_tag); | return String(language_tag); |
} | } |
| |
String LanguageParser::getCountry(String & language_tag){ |
String LanguageParser::getCountry(const String & language_tag){ |
// given a language_tag: en-US-mn we want to return "US" | // given a language_tag: en-US-mn we want to return "US" |
Uint32 i,j; | Uint32 i,j; |
if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND ) | if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND ) |
|
|
return String::EMPTY; | return String::EMPTY; |
} | } |
| |
String LanguageParser::getVariant(String & language_tag){ |
String LanguageParser::getVariant(const String & language_tag){ |
// given a language_tag: en-US-mn we want to return "mn" | // given a language_tag: en-US-mn we want to return "mn" |
Uint32 i; | Uint32 i; |
if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND ) | if( (i = language_tag.find(findSeparator(language_tag.getCString()))) != PEG_NOT_FOUND ) |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
Boolean LanguageParser::isValid(String language_tag, Boolean validate_length){ |
Boolean LanguageParser::isValid(const String& language_tag, Boolean validate_length){ |
//break the String down into parts(subtags), then validate each part | //break the String down into parts(subtags), then validate each part |
| |
if(language_tag == "*") return true; | if(language_tag == "*") return true; |
|
|
Array<String> subtags; | Array<String> subtags; |
parseLanguageSubtags(subtags, language_tag); | parseLanguageSubtags(subtags, language_tag); |
if(subtags.size() > 0){ | if(subtags.size() > 0){ |
for(int i = 0; i < subtags.size(); i++){ |
for(Uint32 i = 0; i < subtags.size(); i++){ |
//length should be 8 or less AND all characters should be A-Z or a-z | //length should be 8 or less AND all characters should be A-Z or a-z |
if((validate_length && subtags[i].size() > 8) || !checkAlpha(subtags[i].getCString())) | if((validate_length && subtags[i].size() > 8) || !checkAlpha(subtags[i].getCString())) |
return false; | return false; |
|
|
| |
String LanguageParser::convertPrivateLanguageTag(String language_tag){ | String LanguageParser::convertPrivateLanguageTag(String language_tag){ |
// figure out if its a unix style locale or windows locale | // figure out if its a unix style locale or windows locale |
int i; |
Uint32 i; |
if(( i = language_tag.find("pegasus-")) != PEG_NOT_FOUND ){ | if(( i = language_tag.find("pegasus-")) != PEG_NOT_FOUND ){ |
language_tag = language_tag.subString(i+5); // capture the remainder of the string | language_tag = language_tag.subString(i+5); // capture the remainder of the string |
return String(replaceSeparator(language_tag.getCString(), '-')); | return String(replaceSeparator(language_tag.getCString(), '-')); |
|
|
} | } |
| |
Boolean LanguageParser::checkAlpha(CString _str){ | Boolean LanguageParser::checkAlpha(CString _str){ |
for(int i = 0; i < strlen(_str); i++) |
Uint32 length = (Uint32) strlen(_str); |
|
for(Uint32 i = 0; i < length; i++) |
if( !isalpha(_str[i]) ) | if( !isalpha(_str[i]) ) |
return false; | return false; |
return true; | return true; |
} | } |
| |
char LanguageParser::findSeparator(CString _str){ | char LanguageParser::findSeparator(CString _str){ |
for(int i = 0; i < strlen(_str); i++) |
Uint32 length = (Uint32) strlen(_str); |
|
for(Uint32 i = 0; i < length; i++) |
if(!isalnum(_str[i])) | if(!isalnum(_str[i])) |
return _str[i]; | return _str[i]; |
return '\0'; | return '\0'; |
|
|
| |
CString LanguageParser::replaceSeparator(CString _s, char new_sep){ | CString LanguageParser::replaceSeparator(CString _s, char new_sep){ |
char * _str = const_cast<char *>((const char*)_s); | char * _str = const_cast<char *>((const char*)_s); |
for(int i = 0; i < strlen(_str); i++) |
Uint32 length = (Uint32) strlen(_str); |
|
for(Uint32 i = 0; i < length; i++) |
_str[i] = (!isalnum(_str[i])) ? new_sep : _str[i]; | _str[i] = (!isalnum(_str[i])) ? new_sep : _str[i]; |
return (String(_str)).getCString(); | return (String(_str)).getCString(); |
} | } |