Re: ICU Accept Language API Proposal

"Steven R. Loomis" <[email protected]> Wed, 20 Oct 2004 13:38:50 -0700
Newsgroups gmane.comp.lib.icu.general
Message-ID <[email protected]>
Update:
  * Changed the function signature to be fillin for C.  Updated 
documentation of functions.
  * Changed function to take/return String instead of ULocale for Java, 
for flexibility.

-s

On 08-Ott-2004, at 6:35 PM, Steven R. Loomis wrote:

> Jitterbug #3591  [   
> http://www.jtcsv.com/cgibin/icu-bugs/others?id=3591  ]
> Date:     8  October 2004 amended 20 October 2004
> Expires:  25 October 2004
>
> ------------------------
> Motivation / Background:
>
> These APIs provide a function to negotiate the best locale to use for 
> an operation, given a user's list of acceptable locales, and the 
> application's list of available locales.
>
> One of the intended uses of this API is with the HTTP Accept-Language: 
> field, see:
>  http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
>
> Here is another article which describes some of the cautions about 
> using accept-language:
>  http://www.w3.org/International/questions/qa-accept-lang-locales
>
> ------------------------
> Theory of operation:
>
> Two input lists are passed to the function:
>
> 1. The "Accept List" is from the user/client preference, for example, 
> from the HTTP request header.  It is ordered in decreasing order of 
> preference.
> 2. The "Available List" is from the application, for example, from the 
> list of installed locales. It is not ordered.
>
>
>  In the best-case situation, the earliest (preferred) locale from the 
> Accept list is matched to an exact match in the available list. In 
> this situation, a 'Valid' locale is returned.
>
>  Before failing completely, the ICU API will attempt a fallback from 
> the Accept list.   Note that this differs from the HTTP specification, 
> and is noted appropriately in the return values of the API as a 
> 'Fallback'.
>
>  To illustrate the fallback behavior, consider the following examples.
> An input accept list of "de_LX, ja"  behaves like "de_LX, ja, (de)", 
> with "de" being fallback behavior, only if the other two locales were 
> not found. Similarly, an input accept list of "de_LX_FOO, de_CH_BAR, 
> ja_JP" behaves like "de_LX_FOO, de_CH_BAR, ja_JP, (de_LX, de_CH, de, 
> ja)".  The Fallback locales are considered in descending order of 
> length, following the requested locales.
>   The HTTP specification says that de_LX should not match de. As well, 
> HTTP spec says that 'de' in the accept-list should match 'de_LX'. 
> However, we assume that application and ICU locale bundles are 
> well-formed, so that if there is a 'de_LX' there will be 'de' and we 
> will match it.  Therefore, we will not match an accept-locale of 'de' 
> to an available locale of 'de_LX'.
>
>
>
>  Two versions of the API are provided for C and Java.  One is passed 
> the Accept-Language field from HTTP (as a single string), and the 
> other an array of Locales.  Note that the numeric weights of the 
> Accept-Language are only used to order the accept list items, their 
> values are otherwise unimportant.

C
-

typedef enum {
         ULOC_ACCEPT_VALID = 0,  /* An exact match was found. */
         ULOC_ACCEPT_FALLBACK = 1    /* A fallback was found, for 
example, Accept list contained 'ja_JP'
				   which matched available locale 'ja'. */
} UAcceptResult;


/**
  * @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
  * @param result - buffer to accept the result locale
  * @param resultAvailable the size of the result buffer.
  * @param availableLocales - list of available locales to match
  * @param status Error status, may be BUFFER_OVERFLOW_ERROR
  * @return length needed for the locale.
  */
int32_t
uloc_acceptLanguageFromHTTP(char *result, int32_t *resultAvailable, 
UAcceptResult *outResult,
			const char *httpAcceptLanguage,
                           UEnumeration* availableLocales,
                           UErrorCode *status);

/**
  * @param acceptList -list of accceptable languages
  * @param result - buffer to accept the result locale
  * @param resultAvailable the size of the result buffer.
  * @param availableLocales - list of available locales to match
  * @param status Error status, may be BUFFER_OVERFLOW_ERROR
  * @return length needed for the locale.
  */
int32_t
uloc_acceptLanguage(char *result, int32_t resultAvailable, 
UAcceptResult *outResult, const char *acceptList[],
                           UEnumeration* availableLocales,
                           UAcceptResult *outResult,
                           UErrorCode *status);


JAVA
----

static public final int         ACCEPT_VALID = 0;  /* An exact match 
was found. */
static public final int         ACCEPT_FALLBACK = 1    /* A fallback 
was found, for example, Accept list contained 'ja_JP' which matched 
available locale 'ja'. */

/**
  * @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
  * @param availableLocales - list of available locales to match
  * @param outResult - output parameter, indicating whether the match 
was VALID or FALLBACK.
  * @return a matching available locale (from the availableLocales list)
  */
static
String   ULocale.acceptLanguageFromHTTP(String httpAcceptLanguage,
                      StringEnumeration availableLocales,
                      int outResult[]);

/**
  * @param acceptArray -string of 'accept'  locales
  * @param availableLocales - list of available locales to match
  * @param outResult - output parameter, indicating whether the match 
was VALID or FALLBACK.
  * @return a matching available locale (from the availableLocales list)
  */
static
String   ULocale.acceptLanguage(String acceptArray[],
                      StringEnumeration availableLocales,
                      int outResult[]);