6161#include < unicode/ucnv.h>
6262#include < unicode/udata.h>
6363#include < unicode/uidna.h>
64+ #include < unicode/uloc.h>
6465#include < unicode/ulocdata.h>
6566#include < unicode/urename.h>
6667#include < unicode/ustring.h>
@@ -601,6 +602,78 @@ void SetDefaultTimeZone(const char* tzid) {
601602 CHECK (U_SUCCESS (status));
602603}
603604
605+ static void GetDefaultLocale (const FunctionCallbackInfo<Value>& args) {
606+ Environment* env = Environment::GetCurrent (args);
607+ const char * locale = uloc_getDefault ();
608+
609+ std::string localeStr (locale);
610+
611+ for (char & c : localeStr) {
612+ if (c == ' _' ) {
613+ c = ' -' ;
614+ }
615+ }
616+
617+ args.GetReturnValue ().Set (
618+ String::NewFromUtf8 (env->isolate (),
619+ localeStr.c_str (),
620+ NewStringType::kNormal ,
621+ static_cast <int >(localeStr.size ()))
622+ .ToLocalChecked ());
623+ }
624+
625+ void GetAvailableLocales (const v8::FunctionCallbackInfo<v8::Value>& args) {
626+ v8::Isolate* isolate = args.GetIsolate ();
627+ int32_t locCount = uloc_countAvailable () - 1 ;
628+
629+ v8::Local<v8::Array> locales = v8::Array::New (isolate, locCount);
630+ v8::Local<v8::Context> context = isolate->GetCurrentContext ();
631+
632+ const char * defaultLocale = uloc_getDefault ();
633+ std::string defaultLocaleStr (defaultLocale);
634+
635+ for (char & c : defaultLocaleStr) {
636+ if (c == ' _' ) {
637+ c = ' -' ;
638+ }
639+ }
640+
641+ v8::Local<v8::String> defaultModifiedLocaleStr =
642+ v8::String::NewFromUtf8 (isolate,
643+ defaultLocaleStr.c_str (),
644+ v8::NewStringType::kNormal ,
645+ static_cast <int >(defaultLocaleStr.size ()))
646+ .ToLocalChecked ();
647+
648+ locales->Set (context, 0 , defaultModifiedLocaleStr).FromJust ();
649+
650+ for (int32_t i = 0 ; i < locCount; ++i) {
651+ const char * locale = uloc_getAvailable (i);
652+
653+ std::string localeStr (locale);
654+
655+ for (char & c : localeStr) {
656+ if (c == ' _' ) {
657+ c = ' -' ;
658+ }
659+ }
660+
661+ if (localeStr.compare (defaultLocaleStr) == 0 ) {
662+ continue ;
663+ }
664+
665+ v8::Local<v8::String> modifiedValue =
666+ v8::String::NewFromUtf8 (isolate,
667+ localeStr.c_str (),
668+ v8::NewStringType::kNormal ,
669+ static_cast <int >(localeStr.size ()))
670+ .ToLocalChecked ();
671+
672+ locales->Set (context, i + 1 , modifiedValue).FromJust ();
673+ }
674+ args.GetReturnValue ().Set (locales);
675+ }
676+
604677int32_t ToUnicode (MaybeStackBuffer<char >* buf,
605678 const char * input,
606679 size_t length) {
@@ -890,6 +963,8 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
890963 SetMethod (isolate, target, " getConverter" , ConverterObject::Create);
891964 SetMethod (isolate, target, " decode" , ConverterObject::Decode);
892965 SetMethod (isolate, target, " hasConverter" , ConverterObject::Has);
966+ SetMethod (isolate, target, " getDefaultLocale" , GetDefaultLocale);
967+ SetMethod (isolate, target, " getAvailableLocales" , GetAvailableLocales);
893968}
894969
895970void CreatePerContextProperties (Local<Object> target,
@@ -903,6 +978,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
903978 registry->Register (GetStringWidth);
904979 registry->Register (ICUErrorName);
905980 registry->Register (Transcode);
981+ registry->Register (GetDefaultLocale);
982+ registry->Register (GetAvailableLocales);
906983 registry->Register (ConverterObject::Create);
907984 registry->Register (ConverterObject::Decode);
908985 registry->Register (ConverterObject::Has);
0 commit comments