Commit bc091f31 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Removing experimental i18n code from v8 repository. Internationalization...

Removing experimental i18n code from v8 repository. Internationalization support is hosted under code.google.com/p/v8-i18n for couple months now.

TEST=Chromium/WebKit builds should pass.

Review URL: https://chromiumcodereview.appspot.com/9016034

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10471 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8c776261
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/extensions/experimental/break-iterator.h"
#include <string.h>
#include "unicode/brkiter.h"
#include "unicode/locid.h"
#include "unicode/rbbi.h"
namespace v8 {
namespace internal {
v8::Persistent<v8::FunctionTemplate> BreakIterator::break_iterator_template_;
icu::BreakIterator* BreakIterator::UnpackBreakIterator(
v8::Handle<v8::Object> obj) {
if (break_iterator_template_->HasInstance(obj)) {
return static_cast<icu::BreakIterator*>(
obj->GetPointerFromInternalField(0));
}
return NULL;
}
icu::UnicodeString* BreakIterator::ResetAdoptedText(
v8::Handle<v8::Object> obj, v8::Handle<v8::Value> value) {
// Get the previous value from the internal field.
icu::UnicodeString* text = static_cast<icu::UnicodeString*>(
obj->GetPointerFromInternalField(1));
delete text;
// Assign new value to the internal pointer.
v8::String::Value text_value(value);
text = new icu::UnicodeString(
reinterpret_cast<const UChar*>(*text_value), text_value.length());
obj->SetPointerInInternalField(1, text);
// Return new unicode string pointer.
return text;
}
void BreakIterator::DeleteBreakIterator(v8::Persistent<v8::Value> object,
void* param) {
v8::Persistent<v8::Object> persistent_object =
v8::Persistent<v8::Object>::Cast(object);
// First delete the hidden C++ object.
// Unpacking should never return NULL here. That would only happen if
// this method is used as the weak callback for persistent handles not
// pointing to a break iterator.
delete UnpackBreakIterator(persistent_object);
delete static_cast<icu::UnicodeString*>(
persistent_object->GetPointerFromInternalField(1));
// Then dispose of the persistent handle to JS object.
persistent_object.Dispose();
}
// Throws a JavaScript exception.
static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
// Returns undefined, and schedules an exception to be thrown.
return v8::ThrowException(v8::Exception::Error(
v8::String::New("BreakIterator method called on an object "
"that is not a BreakIterator.")));
}
v8::Handle<v8::Value> BreakIterator::BreakIteratorAdoptText(
const v8::Arguments& args) {
if (args.Length() != 1 || !args[0]->IsString()) {
return v8::ThrowException(v8::Exception::SyntaxError(
v8::String::New("Text input is required.")));
}
icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
if (!break_iterator) {
return ThrowUnexpectedObjectError();
}
break_iterator->setText(*ResetAdoptedText(args.Holder(), args[0]));
return v8::Undefined();
}
v8::Handle<v8::Value> BreakIterator::BreakIteratorFirst(
const v8::Arguments& args) {
icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
if (!break_iterator) {
return ThrowUnexpectedObjectError();
}
return v8::Int32::New(break_iterator->first());
}
v8::Handle<v8::Value> BreakIterator::BreakIteratorNext(
const v8::Arguments& args) {
icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
if (!break_iterator) {
return ThrowUnexpectedObjectError();
}
return v8::Int32::New(break_iterator->next());
}
v8::Handle<v8::Value> BreakIterator::BreakIteratorCurrent(
const v8::Arguments& args) {
icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
if (!break_iterator) {
return ThrowUnexpectedObjectError();
}
return v8::Int32::New(break_iterator->current());
}
v8::Handle<v8::Value> BreakIterator::BreakIteratorBreakType(
const v8::Arguments& args) {
icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
if (!break_iterator) {
return ThrowUnexpectedObjectError();
}
// TODO(cira): Remove cast once ICU fixes base BreakIterator class.
icu::RuleBasedBreakIterator* rule_based_iterator =
static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
int32_t status = rule_based_iterator->getRuleStatus();
// Keep return values in sync with JavaScript BreakType enum.
if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
return v8::Int32::New(UBRK_WORD_NONE);
} else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
return v8::Int32::New(UBRK_WORD_NUMBER);
} else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
return v8::Int32::New(UBRK_WORD_LETTER);
} else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
return v8::Int32::New(UBRK_WORD_KANA);
} else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
return v8::Int32::New(UBRK_WORD_IDEO);
} else {
return v8::Int32::New(-1);
}
}
v8::Handle<v8::Value> BreakIterator::JSBreakIterator(
const v8::Arguments& args) {
v8::HandleScope handle_scope;
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
return v8::ThrowException(v8::Exception::SyntaxError(
v8::String::New("Locale and iterator type are required.")));
}
v8::String::Utf8Value locale(args[0]);
icu::Locale icu_locale(*locale);
UErrorCode status = U_ZERO_ERROR;
icu::BreakIterator* break_iterator = NULL;
v8::String::Utf8Value type(args[1]);
if (!strcmp(*type, "character")) {
break_iterator =
icu::BreakIterator::createCharacterInstance(icu_locale, status);
} else if (!strcmp(*type, "word")) {
break_iterator =
icu::BreakIterator::createWordInstance(icu_locale, status);
} else if (!strcmp(*type, "sentence")) {
break_iterator =
icu::BreakIterator::createSentenceInstance(icu_locale, status);
} else if (!strcmp(*type, "line")) {
break_iterator =
icu::BreakIterator::createLineInstance(icu_locale, status);
} else {
return v8::ThrowException(v8::Exception::SyntaxError(
v8::String::New("Invalid iterator type.")));
}
if (U_FAILURE(status)) {
delete break_iterator;
return v8::ThrowException(v8::Exception::Error(
v8::String::New("Failed to create break iterator.")));
}
if (break_iterator_template_.IsEmpty()) {
v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
raw_template->SetClassName(v8::String::New("v8Locale.v8BreakIterator"));
// Define internal field count on instance template.
v8::Local<v8::ObjectTemplate> object_template =
raw_template->InstanceTemplate();
// Set aside internal fields for icu break iterator and adopted text.
object_template->SetInternalFieldCount(2);
// Define all of the prototype methods on prototype template.
v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
proto->Set(v8::String::New("adoptText"),
v8::FunctionTemplate::New(BreakIteratorAdoptText));
proto->Set(v8::String::New("first"),
v8::FunctionTemplate::New(BreakIteratorFirst));
proto->Set(v8::String::New("next"),
v8::FunctionTemplate::New(BreakIteratorNext));
proto->Set(v8::String::New("current"),
v8::FunctionTemplate::New(BreakIteratorCurrent));
proto->Set(v8::String::New("breakType"),
v8::FunctionTemplate::New(BreakIteratorBreakType));
break_iterator_template_ =
v8::Persistent<v8::FunctionTemplate>::New(raw_template);
}
// Create an empty object wrapper.
v8::Local<v8::Object> local_object =
break_iterator_template_->GetFunction()->NewInstance();
v8::Persistent<v8::Object> wrapper =
v8::Persistent<v8::Object>::New(local_object);
// Set break iterator as internal field of the resulting JS object.
wrapper->SetPointerInInternalField(0, break_iterator);
// Make sure that the pointer to adopted text is NULL.
wrapper->SetPointerInInternalField(1, NULL);
// Make object handle weak so we can delete iterator once GC kicks in.
wrapper.MakeWeak(NULL, DeleteBreakIterator);
return wrapper;
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
#define V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
#include "include/v8.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class BreakIterator;
class UnicodeString;
}
namespace v8 {
namespace internal {
class BreakIterator {
public:
static v8::Handle<v8::Value> JSBreakIterator(const v8::Arguments& args);
// Helper methods for various bindings.
// Unpacks break iterator object from corresponding JavaScript object.
static icu::BreakIterator* UnpackBreakIterator(v8::Handle<v8::Object> obj);
// Deletes the old value and sets the adopted text in
// corresponding JavaScript object.
static icu::UnicodeString* ResetAdoptedText(v8::Handle<v8::Object> obj,
v8::Handle<v8::Value> text_value);
// Release memory we allocated for the BreakIterator once the JS object that
// holds the pointer gets garbage collected.
static void DeleteBreakIterator(v8::Persistent<v8::Value> object,
void* param);
// Assigns new text to the iterator.
static v8::Handle<v8::Value> BreakIteratorAdoptText(
const v8::Arguments& args);
// Moves iterator to the beginning of the string and returns new position.
static v8::Handle<v8::Value> BreakIteratorFirst(const v8::Arguments& args);
// Moves iterator to the next position and returns it.
static v8::Handle<v8::Value> BreakIteratorNext(const v8::Arguments& args);
// Returns current iterator's current position.
static v8::Handle<v8::Value> BreakIteratorCurrent(
const v8::Arguments& args);
// Returns type of the item from current position.
// This call is only valid for word break iterators. Others just return 0.
static v8::Handle<v8::Value> BreakIteratorBreakType(
const v8::Arguments& args);
private:
BreakIterator() {}
static v8::Persistent<v8::FunctionTemplate> break_iterator_template_;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/extensions/experimental/collator.h"
#include "unicode/coll.h"
#include "unicode/locid.h"
#include "unicode/ucol.h"
namespace v8 {
namespace internal {
v8::Persistent<v8::FunctionTemplate> Collator::collator_template_;
icu::Collator* Collator::UnpackCollator(v8::Handle<v8::Object> obj) {
if (collator_template_->HasInstance(obj)) {
return static_cast<icu::Collator*>(obj->GetPointerFromInternalField(0));
}
return NULL;
}
void Collator::DeleteCollator(v8::Persistent<v8::Value> object, void* param) {
v8::Persistent<v8::Object> persistent_object =
v8::Persistent<v8::Object>::Cast(object);
// First delete the hidden C++ object.
// Unpacking should never return NULL here. That would only happen if
// this method is used as the weak callback for persistent handles not
// pointing to a collator.
delete UnpackCollator(persistent_object);
// Then dispose of the persistent handle to JS object.
persistent_object.Dispose();
}
// Throws a JavaScript exception.
static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
// Returns undefined, and schedules an exception to be thrown.
return v8::ThrowException(v8::Exception::Error(
v8::String::New("Collator method called on an object "
"that is not a Collator.")));
}
// Extract a boolean option named in |option| and set it to |result|.
// Return true if it's specified. Otherwise, return false.
static bool ExtractBooleanOption(const v8::Local<v8::Object>& options,
const char* option,
bool* result) {
v8::HandleScope handle_scope;
v8::TryCatch try_catch;
v8::Handle<v8::Value> value = options->Get(v8::String::New(option));
if (try_catch.HasCaught()) {
return false;
}
// No need to check if |value| is empty because it's taken care of
// by TryCatch above.
if (!value->IsUndefined() && !value->IsNull()) {
if (value->IsBoolean()) {
*result = value->BooleanValue();
return true;
}
}
return false;
}
// When there's an ICU error, throw a JavaScript error with |message|.
static v8::Handle<v8::Value> ThrowExceptionForICUError(const char* message) {
return v8::ThrowException(v8::Exception::Error(v8::String::New(message)));
}
v8::Handle<v8::Value> Collator::CollatorCompare(const v8::Arguments& args) {
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
return v8::ThrowException(v8::Exception::SyntaxError(
v8::String::New("Two string arguments are required.")));
}
icu::Collator* collator = UnpackCollator(args.Holder());
if (!collator) {
return ThrowUnexpectedObjectError();
}
v8::String::Value string_value1(args[0]);
v8::String::Value string_value2(args[1]);
const UChar* string1 = reinterpret_cast<const UChar*>(*string_value1);
const UChar* string2 = reinterpret_cast<const UChar*>(*string_value2);
UErrorCode status = U_ZERO_ERROR;
UCollationResult result = collator->compare(
string1, string_value1.length(), string2, string_value2.length(), status);
if (U_FAILURE(status)) {
return ThrowExceptionForICUError(
"Unexpected failure in Collator.compare.");
}
return v8::Int32::New(result);
}
v8::Handle<v8::Value> Collator::JSCollator(const v8::Arguments& args) {
v8::HandleScope handle_scope;
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsObject()) {
return v8::ThrowException(v8::Exception::SyntaxError(
v8::String::New("Locale and collation options are required.")));
}
v8::String::AsciiValue locale(args[0]);
icu::Locale icu_locale(*locale);
icu::Collator* collator = NULL;
UErrorCode status = U_ZERO_ERROR;
collator = icu::Collator::createInstance(icu_locale, status);
if (U_FAILURE(status)) {
delete collator;
return ThrowExceptionForICUError("Failed to create collator.");
}
v8::Local<v8::Object> options(args[1]->ToObject());
// Below, we change collation options that are explicitly specified
// by a caller in JavaScript. Otherwise, we don't touch because
// we don't want to change the locale-dependent default value.
// The three options below are very likely to have the same default
// across locales, but I haven't checked them all. Others we may add
// in the future have certainly locale-dependent default (e.g.
// caseFirst is upperFirst for Danish while is off for most other locales).
bool ignore_case, ignore_accents, numeric;
if (ExtractBooleanOption(options, "ignoreCase", &ignore_case)) {
// We need to explicitly set the level to secondary to get case ignored.
// The default L3 ignores UCOL_CASE_LEVEL == UCOL_OFF !
if (ignore_case) {
collator->setStrength(icu::Collator::SECONDARY);
}
collator->setAttribute(UCOL_CASE_LEVEL, ignore_case ? UCOL_OFF : UCOL_ON,
status);
if (U_FAILURE(status)) {
delete collator;
return ThrowExceptionForICUError("Failed to set ignoreCase.");
}
}
// Accents are taken into account with strength secondary or higher.
if (ExtractBooleanOption(options, "ignoreAccents", &ignore_accents)) {
if (!ignore_accents) {
collator->setStrength(icu::Collator::SECONDARY);
} else {
collator->setStrength(icu::Collator::PRIMARY);
}
}
if (ExtractBooleanOption(options, "numeric", &numeric)) {
collator->setAttribute(UCOL_NUMERIC_COLLATION,
numeric ? UCOL_ON : UCOL_OFF, status);
if (U_FAILURE(status)) {
delete collator;
return ThrowExceptionForICUError("Failed to set numeric sort option.");
}
}
if (collator_template_.IsEmpty()) {
v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
raw_template->SetClassName(v8::String::New("v8Locale.Collator"));
// Define internal field count on instance template.
v8::Local<v8::ObjectTemplate> object_template =
raw_template->InstanceTemplate();
// Set aside internal fields for icu collator.
object_template->SetInternalFieldCount(1);
// Define all of the prototype methods on prototype template.
v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
proto->Set(v8::String::New("compare"),
v8::FunctionTemplate::New(CollatorCompare));
collator_template_ =
v8::Persistent<v8::FunctionTemplate>::New(raw_template);
}
// Create an empty object wrapper.
v8::Local<v8::Object> local_object =
collator_template_->GetFunction()->NewInstance();
v8::Persistent<v8::Object> wrapper =
v8::Persistent<v8::Object>::New(local_object);
// Set collator as internal field of the resulting JS object.
wrapper->SetPointerInInternalField(0, collator);
// Make object handle weak so we can delete iterator once GC kicks in.
wrapper.MakeWeak(NULL, DeleteCollator);
return wrapper;
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H
#define V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H_
#include "include/v8.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class Collator;
class UnicodeString;
}
namespace v8 {
namespace internal {
class Collator {
public:
static v8::Handle<v8::Value> JSCollator(const v8::Arguments& args);
// Helper methods for various bindings.
// Unpacks collator object from corresponding JavaScript object.
static icu::Collator* UnpackCollator(v8::Handle<v8::Object> obj);
// Release memory we allocated for the Collator once the JS object that
// holds the pointer gets garbage collected.
static void DeleteCollator(v8::Persistent<v8::Value> object, void* param);
// Compare two strings and returns -1, 0 and 1 depending on
// whether string1 is smaller than, equal to or larger than string2.
static v8::Handle<v8::Value> CollatorCompare(const v8::Arguments& args);
private:
Collator() {}
static v8::Persistent<v8::FunctionTemplate> collator_template_;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_COLLATOR
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
#define V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
#include "include/v8.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class SimpleDateFormat;
}
namespace v8 {
namespace internal {
class DateTimeFormat {
public:
static v8::Handle<v8::Value> JSDateTimeFormat(const v8::Arguments& args);
// Helper methods for various bindings.
// Unpacks date format object from corresponding JavaScript object.
static icu::SimpleDateFormat* UnpackDateTimeFormat(
v8::Handle<v8::Object> obj);
// Release memory we allocated for the DateFormat once the JS object that
// holds the pointer gets garbage collected.
static void DeleteDateTimeFormat(v8::Persistent<v8::Value> object,
void* param);
// Formats date and returns corresponding string.
static v8::Handle<v8::Value> Format(const v8::Arguments& args);
// All date time symbol methods below return stand-alone names in
// either narrow, abbreviated or wide width.
// Get list of months.
static v8::Handle<v8::Value> GetMonths(const v8::Arguments& args);
// Get list of weekdays.
static v8::Handle<v8::Value> GetWeekdays(const v8::Arguments& args);
// Get list of eras.
static v8::Handle<v8::Value> GetEras(const v8::Arguments& args);
// Get list of day periods.
static v8::Handle<v8::Value> GetAmPm(const v8::Arguments& args);
private:
DateTimeFormat();
static v8::Persistent<v8::FunctionTemplate> datetime_format_template_;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
'variables': {
# TODO(cira): Find out how to pass this value for arbitrary embedder.
# Chromium sets it in common.gypi and does force include of that file for
# all sub projects.
'icu_src_dir%': '../../../../third_party/icu',
},
'targets': [
{
'target_name': 'i18n_api',
'type': 'static_library',
'sources': [
'break-iterator.cc',
'break-iterator.h',
'collator.cc',
'collator.h',
'datetime-format.cc',
'datetime-format.h',
'i18n-extension.cc',
'i18n-extension.h',
'i18n-locale.cc',
'i18n-locale.h',
'i18n-natives.h',
'i18n-utils.cc',
'i18n-utils.h',
'language-matcher.cc',
'language-matcher.h',
'number-format.cc',
'number-format.h',
'<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
],
'include_dirs': [
'<(icu_src_dir)/public/common',
# v8/ is root for all includes.
'../../..'
],
'dependencies': [
'<(icu_src_dir)/icu.gyp:*',
'js2c_i18n#host',
'../../../tools/gyp/v8.gyp:v8',
],
'direct_dependent_settings': {
# Adds -Iv8 for embedders.
'include_dirs': [
'../../..'
],
},
},
{
'target_name': 'js2c_i18n',
'type': 'none',
'toolsets': ['host'],
'variables': {
'js_files': [
'i18n.js'
],
},
'actions': [
{
'action_name': 'js2c_i18n',
'inputs': [
'i18n-js2c.py',
'<@(js_files)',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
],
'action': [
'python',
'i18n-js2c.py',
'<@(_outputs)',
'<@(js_files)'
],
},
],
},
], # targets
}
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/extensions/experimental/i18n-extension.h"
#include "src/extensions/experimental/break-iterator.h"
#include "src/extensions/experimental/collator.h"
#include "src/extensions/experimental/datetime-format.h"
#include "src/extensions/experimental/i18n-locale.h"
#include "src/extensions/experimental/i18n-natives.h"
#include "src/extensions/experimental/number-format.h"
namespace v8 {
namespace internal {
I18NExtension* I18NExtension::extension_ = NULL;
I18NExtension::I18NExtension()
: v8::Extension("v8/i18n", I18Natives::GetScriptSource()) {
}
v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("NativeJSLocale"))) {
return v8::FunctionTemplate::New(I18NLocale::JSLocale);
} else if (name->Equals(v8::String::New("NativeJSBreakIterator"))) {
return v8::FunctionTemplate::New(BreakIterator::JSBreakIterator);
} else if (name->Equals(v8::String::New("NativeJSCollator"))) {
return v8::FunctionTemplate::New(Collator::JSCollator);
} else if (name->Equals(v8::String::New("NativeJSDateTimeFormat"))) {
return v8::FunctionTemplate::New(DateTimeFormat::JSDateTimeFormat);
} else if (name->Equals(v8::String::New("NativeJSNumberFormat"))) {
return v8::FunctionTemplate::New(NumberFormat::JSNumberFormat);
}
return v8::Handle<v8::FunctionTemplate>();
}
I18NExtension* I18NExtension::get() {
if (!extension_) {
extension_ = new I18NExtension();
}
return extension_;
}
void I18NExtension::Register() {
static v8::DeclareExtension i18n_extension_declaration(I18NExtension::get());
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
#define V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
#include "include/v8.h"
namespace v8 {
namespace internal {
class I18NExtension : public v8::Extension {
public:
I18NExtension();
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
v8::Handle<v8::String> name);
// V8 code prefers Register, while Chrome and WebKit use get kind of methods.
static void Register();
static I18NExtension* get();
private:
static I18NExtension* extension_;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
#!/usr/bin/env python
#
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a utility for converting I18N JavaScript source code into C-style
# char arrays. It is used for embedded JavaScript code in the V8
# library.
# This is a pared down copy of v8/tools/js2c.py that avoids use of
# v8/src/natives.h and produces different cc template.
import os, re, sys, string
def ToCArray(lines):
result = []
for chr in lines:
value = ord(chr)
assert value < 128
result.append(str(value))
result.append("0")
return ", ".join(result)
def RemoveCommentsAndTrailingWhitespace(lines):
lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments
lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments.
lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace
return lines
def ReadFile(filename):
file = open(filename, "rt")
try:
lines = file.read()
finally:
file.close()
return lines
EVAL_PATTERN = re.compile(r'\beval\s*\(');
WITH_PATTERN = re.compile(r'\bwith\s*\(');
def Validate(lines, file):
lines = RemoveCommentsAndTrailingWhitespace(lines)
# Because of simplified context setup, eval and with is not
# allowed in the natives files.
eval_match = EVAL_PATTERN.search(lines)
if eval_match:
raise ("Eval disallowed in natives: %s" % file)
with_match = WITH_PATTERN.search(lines)
if with_match:
raise ("With statements disallowed in natives: %s" % file)
HEADER_TEMPLATE = """\
// Copyright 2011 Google Inc. All Rights Reserved.
// This file was generated from .js source files by gyp. If you
// want to make changes to this file you should either change the
// javascript source files or the i18n-js2c.py script.
#include "src/extensions/experimental/i18n-natives.h"
namespace v8 {
namespace internal {
// static
const char* I18Natives::GetScriptSource() {
// JavaScript source gets injected here.
static const char i18n_source[] = {%s};
return i18n_source;
}
} // internal
} // v8
"""
def JS2C(source, target):
filename = str(source)
lines = ReadFile(filename)
Validate(lines, filename)
data = ToCArray(lines)
# Emit result
output = open(target, "w")
output.write(HEADER_TEMPLATE % data)
output.close()
def main():
target = sys.argv[1]
source = sys.argv[2]
JS2C(source, target)
if __name__ == "__main__":
main()
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/extensions/experimental/i18n-locale.h"
#include "src/extensions/experimental/i18n-utils.h"
#include "src/extensions/experimental/language-matcher.h"
#include "unicode/locid.h"
#include "unicode/uloc.h"
namespace v8 {
namespace internal {
const char* const I18NLocale::kLocaleID = "localeID";
const char* const I18NLocale::kRegionID = "regionID";
const char* const I18NLocale::kICULocaleID = "icuLocaleID";
v8::Handle<v8::Value> I18NLocale::JSLocale(const v8::Arguments& args) {
v8::HandleScope handle_scope;
if (args.Length() != 1 || !args[0]->IsObject()) {
return v8::Undefined();
}
v8::Local<v8::Object> settings = args[0]->ToObject();
// Get best match for locale.
v8::TryCatch try_catch;
v8::Handle<v8::Value> locale_id = settings->Get(v8::String::New(kLocaleID));
if (try_catch.HasCaught()) {
return v8::Undefined();
}
LocaleIDMatch result;
if (locale_id->IsArray()) {
LanguageMatcher::GetBestMatchForPriorityList(
v8::Handle<v8::Array>::Cast(locale_id), &result);
} else if (locale_id->IsString()) {
LanguageMatcher::GetBestMatchForString(locale_id->ToString(), &result);
} else {
LanguageMatcher::GetBestMatchForString(v8::String::New(""), &result);
}
// Get best match for region.
char region_id[ULOC_COUNTRY_CAPACITY];
I18NUtils::StrNCopy(region_id, ULOC_COUNTRY_CAPACITY, "");
v8::Handle<v8::Value> region = settings->Get(v8::String::New(kRegionID));
if (try_catch.HasCaught()) {
return v8::Undefined();
}
if (!GetBestMatchForRegionID(result.icu_id, region, region_id)) {
// Set region id to empty string because region couldn't be inferred.
I18NUtils::StrNCopy(region_id, ULOC_COUNTRY_CAPACITY, "");
}
// Build JavaScript object that contains bcp and icu locale ID and region ID.
v8::Handle<v8::Object> locale = v8::Object::New();
locale->Set(v8::String::New(kLocaleID), v8::String::New(result.bcp47_id));
locale->Set(v8::String::New(kICULocaleID), v8::String::New(result.icu_id));
locale->Set(v8::String::New(kRegionID), v8::String::New(region_id));
return handle_scope.Close(locale);
}
bool I18NLocale::GetBestMatchForRegionID(
const char* locale_id, v8::Handle<v8::Value> region_id, char* result) {
if (region_id->IsString() && region_id->ToString()->Length() != 0) {
icu::Locale user_locale(
icu::Locale("und", *v8::String::Utf8Value(region_id->ToString())));
I18NUtils::StrNCopy(
result, ULOC_COUNTRY_CAPACITY, user_locale.getCountry());
return true;
}
// Maximize locale_id to infer the region (e.g. expand "de" to "de-Latn-DE"
// and grab "DE" from the result).
UErrorCode status = U_ZERO_ERROR;
char maximized_locale[ULOC_FULLNAME_CAPACITY];
uloc_addLikelySubtags(
locale_id, maximized_locale, ULOC_FULLNAME_CAPACITY, &status);
uloc_getCountry(maximized_locale, result, ULOC_COUNTRY_CAPACITY, &status);
return !U_FAILURE(status);
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
#define V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
#include "include/v8.h"
namespace v8 {
namespace internal {
class I18NLocale {
public:
I18NLocale() {}
// Implementations of window.Locale methods.
static v8::Handle<v8::Value> JSLocale(const v8::Arguments& args);
// Infers region id given the locale id, or uses user specified region id.
// Result is canonicalized.
// Returns status of ICU operation (maximizing locale or get region call).
static bool GetBestMatchForRegionID(
const char* locale_id, v8::Handle<v8::Value> regions, char* result);
private:
// Key name for localeID parameter.
static const char* const kLocaleID;
// Key name for regionID parameter.
static const char* const kRegionID;
// Key name for the icuLocaleID result.
static const char* const kICULocaleID;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
#define V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
namespace v8 {
namespace internal {
class I18Natives {
public:
// Gets script source from generated file.
// Source is statically allocated string.
static const char* GetScriptSource();
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/extensions/experimental/i18n-utils.h"
#include <string.h>
#include "unicode/unistr.h"
namespace v8 {
namespace internal {
// static
void I18NUtils::StrNCopy(char* dest, int length, const char* src) {
if (!dest || !src) return;
strncpy(dest, src, length);
dest[length - 1] = '\0';
}
// static
bool I18NUtils::ExtractStringSetting(const v8::Handle<v8::Object>& settings,
const char* setting,
icu::UnicodeString* result) {
if (!setting || !result) return false;
v8::HandleScope handle_scope;
v8::TryCatch try_catch;
v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
if (try_catch.HasCaught()) {
return false;
}
// No need to check if |value| is empty because it's taken care of
// by TryCatch above.
if (!value->IsUndefined() && !value->IsNull() && value->IsString()) {
v8::String::Utf8Value utf8_value(value);
if (*utf8_value == NULL) return false;
result->setTo(icu::UnicodeString::fromUTF8(*utf8_value));
return true;
}
return false;
}
// static
void I18NUtils::AsciiToUChar(const char* source,
int32_t source_length,
UChar* target,
int32_t target_length) {
int32_t length =
source_length < target_length ? source_length : target_length;
if (length <= 0) {
return;
}
for (int32_t i = 0; i < length - 1; ++i) {
target[i] = static_cast<UChar>(source[i]);
}
target[length - 1] = 0x0u;
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
#define V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
#include "include/v8.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class UnicodeString;
}
namespace v8 {
namespace internal {
class I18NUtils {
public:
// Safe string copy. Null terminates the destination. Copies at most
// (length - 1) bytes.
// We can't use snprintf since it's not supported on all relevant platforms.
// We can't use OS::SNPrintF, it's only for internal code.
static void StrNCopy(char* dest, int length, const char* src);
// Extract a string setting named in |settings| and set it to |result|.
// Return true if it's specified. Otherwise, return false.
static bool ExtractStringSetting(const v8::Handle<v8::Object>& settings,
const char* setting,
icu::UnicodeString* result);
// Converts ASCII array into UChar array.
// Target is always \0 terminated.
static void AsciiToUChar(const char* source,
int32_t source_length,
UChar* target,
int32_t target_length);
private:
I18NUtils() {}
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
This diff is collapsed.
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// TODO(cira): Remove LanguageMatcher from v8 when ICU implements
// language matching API.
#include "src/extensions/experimental/language-matcher.h"
#include <string.h>
#include "src/extensions/experimental/i18n-utils.h"
#include "unicode/datefmt.h" // For getAvailableLocales
#include "unicode/locid.h"
#include "unicode/uloc.h"
namespace v8 {
namespace internal {
const unsigned int LanguageMatcher::kLanguageWeight = 75;
const unsigned int LanguageMatcher::kScriptWeight = 20;
const unsigned int LanguageMatcher::kRegionWeight = 5;
const unsigned int LanguageMatcher::kThreshold = 50;
const unsigned int LanguageMatcher::kPositionBonus = 1;
const char* const LanguageMatcher::kDefaultLocale = "root";
static const char* GetLanguageException(const char*);
static bool BCP47ToICUFormat(const char*, char*);
static int CompareLocaleSubtags(const char*, const char*);
static bool BuildLocaleName(const char*, const char*, LocaleIDMatch*);
LocaleIDMatch::LocaleIDMatch()
: score(-1) {
I18NUtils::StrNCopy(
bcp47_id, ULOC_FULLNAME_CAPACITY, LanguageMatcher::kDefaultLocale);
I18NUtils::StrNCopy(
icu_id, ULOC_FULLNAME_CAPACITY, LanguageMatcher::kDefaultLocale);
}
LocaleIDMatch& LocaleIDMatch::operator=(const LocaleIDMatch& rhs) {
I18NUtils::StrNCopy(this->bcp47_id, ULOC_FULLNAME_CAPACITY, rhs.bcp47_id);
I18NUtils::StrNCopy(this->icu_id, ULOC_FULLNAME_CAPACITY, rhs.icu_id);
this->score = rhs.score;
return *this;
}
// static
void LanguageMatcher::GetBestMatchForPriorityList(
v8::Handle<v8::Array> locales, LocaleIDMatch* result) {
v8::HandleScope handle_scope;
unsigned int position_bonus = locales->Length() * kPositionBonus;
int max_score = 0;
LocaleIDMatch match;
for (unsigned int i = 0; i < locales->Length(); ++i) {
position_bonus -= kPositionBonus;
v8::TryCatch try_catch;
v8::Local<v8::Value> locale_id = locales->Get(v8::Integer::New(i));
// Return default if exception is raised when reading parameter.
if (try_catch.HasCaught()) break;
// JavaScript arrays can be heterogenous so check each item
// if it's a string.
if (!locale_id->IsString()) continue;
if (!CompareToSupportedLocaleIDList(locale_id->ToString(), &match)) {
continue;
}
// Skip items under threshold.
if (match.score < kThreshold) continue;
match.score += position_bonus;
if (match.score > max_score) {
*result = match;
max_score = match.score;
}
}
}
// static
void LanguageMatcher::GetBestMatchForString(
v8::Handle<v8::String> locale, LocaleIDMatch* result) {
LocaleIDMatch match;
if (CompareToSupportedLocaleIDList(locale, &match) &&
match.score >= kThreshold) {
*result = match;
}
}
// static
bool LanguageMatcher::CompareToSupportedLocaleIDList(
v8::Handle<v8::String> locale_id, LocaleIDMatch* result) {
static int32_t available_count = 0;
// Depending on how ICU data is built, locales returned by
// Locale::getAvailableLocale() are not guaranteed to support DateFormat,
// Collation and other services. We can call getAvailableLocale() of all the
// services we want to support and take the intersection of them all, but
// using DateFormat::getAvailableLocales() should suffice.
// TODO(cira): Maybe make this thread-safe?
static const icu::Locale* available_locales =
icu::DateFormat::getAvailableLocales(available_count);
// Skip this locale_id if it's not in ASCII.
static LocaleIDMatch default_match;
v8::String::AsciiValue ascii_value(locale_id);
if (*ascii_value == NULL) return false;
char locale[ULOC_FULLNAME_CAPACITY];
if (!BCP47ToICUFormat(*ascii_value, locale)) return false;
icu::Locale input_locale(locale);
// Position of the best match locale in list of available locales.
int position = -1;
const char* language = GetLanguageException(input_locale.getLanguage());
const char* script = input_locale.getScript();
const char* region = input_locale.getCountry();
for (int32_t i = 0; i < available_count; ++i) {
int current_score = 0;
int sign =
CompareLocaleSubtags(language, available_locales[i].getLanguage());
current_score += sign * kLanguageWeight;
sign = CompareLocaleSubtags(script, available_locales[i].getScript());
current_score += sign * kScriptWeight;
sign = CompareLocaleSubtags(region, available_locales[i].getCountry());
current_score += sign * kRegionWeight;
if (current_score >= kThreshold && current_score > result->score) {
result->score = current_score;
position = i;
}
}
// Didn't find any good matches so use defaults.
if (position == -1) return false;
return BuildLocaleName(available_locales[position].getBaseName(),
input_locale.getName(), result);
}
// For some unsupported language subtags it is better to fallback to related
// language that is supported than to default.
static const char* GetLanguageException(const char* language) {
// Serbo-croatian to Serbian.
if (!strcmp(language, "sh")) return "sr";
// Norweigan to Norweiaan to Norwegian Bokmal.
if (!strcmp(language, "no")) return "nb";
// Moldavian to Romanian.
if (!strcmp(language, "mo")) return "ro";
// Tagalog to Filipino.
if (!strcmp(language, "tl")) return "fil";
return language;
}
// Converts user input from BCP47 locale id format to ICU compatible format.
// Returns false if uloc_forLanguageTag call fails or if extension is too long.
static bool BCP47ToICUFormat(const char* locale_id, char* result) {
UErrorCode status = U_ZERO_ERROR;
int32_t locale_size = 0;
char locale[ULOC_FULLNAME_CAPACITY];
I18NUtils::StrNCopy(locale, ULOC_FULLNAME_CAPACITY, locale_id);
// uloc_forLanguageTag has a bug where long extension can crash the code.
// We need to check if extension part of language id conforms to the length.
// ICU bug: http://bugs.icu-project.org/trac/ticket/8519
const char* extension = strstr(locale_id, "-u-");
if (extension != NULL &&
strlen(extension) > ULOC_KEYWORD_AND_VALUES_CAPACITY) {
// Truncate to get non-crashing string, but still preserve base language.
int base_length = strlen(locale_id) - strlen(extension);
locale[base_length] = '\0';
}
uloc_forLanguageTag(locale, result, ULOC_FULLNAME_CAPACITY,
&locale_size, &status);
return !U_FAILURE(status);
}
// Compares locale id subtags.
// Returns 1 for match or -1 for mismatch.
static int CompareLocaleSubtags(const char* lsubtag, const char* rsubtag) {
return strcmp(lsubtag, rsubtag) == 0 ? 1 : -1;
}
// Builds a BCP47 compliant locale id from base name of matched locale and
// full user specified locale.
// Returns false if uloc_toLanguageTag failed to convert locale id.
// Example:
// base_name of matched locale (ICU ID): de_DE
// input_locale_name (ICU ID): de_AT@collation=phonebk
// result (ICU ID): de_DE@collation=phonebk
// result (BCP47 ID): de-DE-u-co-phonebk
static bool BuildLocaleName(const char* base_name,
const char* input_locale_name,
LocaleIDMatch* result) {
I18NUtils::StrNCopy(result->icu_id, ULOC_LANG_CAPACITY, base_name);
// Get extensions (if any) from the original locale.
const char* extension = strchr(input_locale_name, ULOC_KEYWORD_SEPARATOR);
if (extension != NULL) {
I18NUtils::StrNCopy(result->icu_id + strlen(base_name),
ULOC_KEYWORD_AND_VALUES_CAPACITY, extension);
} else {
I18NUtils::StrNCopy(result->icu_id, ULOC_LANG_CAPACITY, base_name);
}
// Convert ICU locale name into BCP47 format.
UErrorCode status = U_ZERO_ERROR;
uloc_toLanguageTag(result->icu_id, result->bcp47_id,
ULOC_FULLNAME_CAPACITY, false, &status);
return !U_FAILURE(status);
}
} } // namespace v8::internal
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
#define V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
#include "include/v8.h"
#include "unicode/uloc.h"
namespace v8 {
namespace internal {
struct LocaleIDMatch {
LocaleIDMatch();
LocaleIDMatch& operator=(const LocaleIDMatch& rhs);
// Bcp47 locale id - "de-Latn-DE-u-co-phonebk".
char bcp47_id[ULOC_FULLNAME_CAPACITY];
// ICU locale id - "de_Latn_DE@collation=phonebk".
char icu_id[ULOC_FULLNAME_CAPACITY];
// Score for this locale.
int score;
};
class LanguageMatcher {
public:
// Default locale.
static const char* const kDefaultLocale;
// Finds best supported locale for a given a list of locale identifiers.
// It preserves the extension for the locale id.
static void GetBestMatchForPriorityList(
v8::Handle<v8::Array> locale_list, LocaleIDMatch* result);
// Finds best supported locale for a single locale identifier.
// It preserves the extension for the locale id.
static void GetBestMatchForString(
v8::Handle<v8::String> locale_id, LocaleIDMatch* result);
private:
// If langauge subtags match add this amount to the score.
static const unsigned int kLanguageWeight;
// If script subtags match add this amount to the score.
static const unsigned int kScriptWeight;
// If region subtags match add this amount to the score.
static const unsigned int kRegionWeight;
// LocaleID match score has to be over this number to accept the match.
static const unsigned int kThreshold;
// For breaking ties in priority queue.
static const unsigned int kPositionBonus;
LanguageMatcher();
// Compares locale_id to the supported list of locales and returns best
// match.
// Returns false if it fails to convert locale id from ICU to BCP47 format.
static bool CompareToSupportedLocaleIDList(v8::Handle<v8::String> locale_id,
LocaleIDMatch* result);
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
#define V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
#include "include/v8.h"
#include "unicode/uversion.h"
namespace U_ICU_NAMESPACE {
class DecimalFormat;
}
namespace v8 {
namespace internal {
class NumberFormat {
public:
// 3-letter ISO 4217 currency code plus \0.
static const int kCurrencyCodeLength;
static v8::Handle<v8::Value> JSNumberFormat(const v8::Arguments& args);
// Helper methods for various bindings.
// Unpacks date format object from corresponding JavaScript object.
static icu::DecimalFormat* UnpackNumberFormat(
v8::Handle<v8::Object> obj);
// Release memory we allocated for the NumberFormat once the JS object that
// holds the pointer gets garbage collected.
static void DeleteNumberFormat(v8::Persistent<v8::Value> object,
void* param);
// Formats number and returns corresponding string.
static v8::Handle<v8::Value> Format(const v8::Arguments& args);
private:
NumberFormat();
static v8::Persistent<v8::FunctionTemplate> number_format_template_;
};
} } // namespace v8::internal
#endif // V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment