Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/builtin/intl/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 12 kB image not shown  

Quelle  SharedIntlData.h

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef builtin_intl_SharedIntlData_h
#define builtin_intl_SharedIntlData_h

#include "mozilla/MemoryReporting.h"
#include "mozilla/Span.h"
#include "mozilla/UniquePtr.h"

#include <stddef.h>
#include <string_view>

#include "js/AllocPolicy.h"
#include "js/GCAPI.h"
#include "js/GCHashTable.h"
#include "js/Result.h"
#include "js/RootingAPI.h"
#include "js/Utility.h"
#include "util/LanguageId.h"
#include "vm/StringType.h"

namespace mozilla::intl {
class DateTimePatternGenerator;
}  // namespace mozilla::intl

namespace js {

class ArrayObject;

namespace intl {

enum class AvailableLocaleKind {
  Collator,
  DateTimeFormat,
  DisplayNames,
  DurationFormat,
  ListFormat,
  NumberFormat,
  PluralRules,
  RelativeTimeFormat,
  Segmenter,
};

/**
 * This deleter class exists so that mozilla::intl::DateTimePatternGenerator
 * can be a forward declaration, but still be used inside of a UniquePtr.
 */

class DateTimePatternGeneratorDeleter {
 public:
  void operator()(mozilla::intl::DateTimePatternGenerator* ptr);
};

/**
 * Stores Intl data which can be shared across compartments (but not contexts).
 *
 * Used for data which is expensive when computed repeatedly or is not
 * available through ICU.
 */

class SharedIntlData {
  struct LinearStringLookup {
    union {
      const JS::Latin1Char* latin1Chars;
      const char16_t* twoByteChars;
    };
    bool isLatin1;
    size_t length;
    JS::AutoCheckCannotGC nogc;
    HashNumber hash = 0;

    explicit LinearStringLookup(const JSLinearString* string)
        : isLatin1(string->hasLatin1Chars()), length(string->length()) {
      if (isLatin1) {
        latin1Chars = string->latin1Chars(nogc);
      } else {
        twoByteChars = string->twoByteChars(nogc);
      }
    }

    explicit LinearStringLookup(std::string_view string)
        : isLatin1(true), length(string.length()) {
      latin1Chars = reinterpret_cast<const JS::Latin1Char*>(string.data());
    }

    explicit LinearStringLookup(std::u16string_view string)
        : isLatin1(false), length(string.length()) {
      twoByteChars = string.data();
    }
  };

 public:
  /**
   * Information tracking the set of the supported time zone names, derived
   * from the IANA time zone database <https://www.iana.org/time-zones>.
   *
   * There are two kinds of IANA time zone names: Zone and Link (denoted as
   * such in database source files). Zone names are the canonical, preferred
   * name for a time zone, e.g. Asia/Kolkata. Link names simply refer to
   * target Zone names for their meaning, e.g. Asia/Calcutta targets
   * Asia/Kolkata. That a name is a Link doesn't *necessarily* reflect a
   * sense of deprecation: some Link names also exist partly for convenience,
   * e.g. UTC and GMT as Link names targeting the Zone name Etc/UTC.
   *
   * Two data sources determine the time zone names we support: those ICU
   * supports and IANA's zone information.
   *
   * Unfortunately the names ICU and IANA support, and their Link
   * relationships from name to target, aren't identical, so we can't simply
   * implicitly trust ICU's name handling. We must perform various
   * preprocessing of user-provided zone names and post-processing of
   * ICU-provided zone names to implement ECMA-402's IANA-consistent behavior.
   *
   * Also see <https://ssl.icu-project.org/trac/ticket/12044> and
   * <http://unicode.org/cldr/trac/ticket/9892>.
   */


  using TimeZoneName = JSAtom*;

  struct AvailableTimeZoneHasher {
    struct Lookup : LinearStringLookup {
      explicit Lookup(const JSLinearString* timeZone);
      explicit Lookup(std::string_view timeZone);
      explicit Lookup(std::u16string_view timeZone);
    };

    static js::HashNumber hash(const Lookup& lookup) { return lookup.hash; }
    static bool match(TimeZoneName key, const Lookup& lookup);
  };

  struct TimeZoneHasher {
    using Lookup = TimeZoneName;

    static js::HashNumber hash(const Lookup& lookup) { return lookup->hash(); }
    static bool match(TimeZoneName key, const Lookup& lookup) {
      return key == lookup;
    }
  };

  using AvailableTimeZoneSet =
      GCHashSet<TimeZoneName, AvailableTimeZoneHasher, SystemAllocPolicy>;
  using TimeZoneSet =
      GCHashSet<TimeZoneName, TimeZoneHasher, SystemAllocPolicy>;
  using TimeZoneMap =
      GCHashMap<TimeZoneName, TimeZoneName, TimeZoneHasher, SystemAllocPolicy>;

 private:
  /**
   * As a threshold matter, available time zones are those time zones ICU
   * supports, via ucal_openTimeZones. But ICU supports additional non-IANA
   * time zones described in intl/icu/source/tools/tzcode/icuzones (listed in
   * TimeZoneDataGenerated.h's |legacyICUTimeZones|) for its own backwards
   * compatibility purposes. This set consists of ICU's supported time zones,
   * minus all backwards-compatibility time zones.
   */

  AvailableTimeZoneSet availableTimeZones;

  /**
   * IANA treats some time zone names as Zones, that ICU instead treats as
   * Links. For example, IANA considers "America/Indiana/Indianapolis" to be
   * a Zone and "America/Fort_Wayne" a Link that targets it, but ICU
   * considers the former a Link that targets "America/Indianapolis" (which
   * IANA treats as a Link).
   *
   * ECMA-402 requires that we respect IANA data, so if we're asked to
   * canonicalize a time zone name in this set, we must *not* return ICU's
   * canonicalization.
   */

  TimeZoneSet ianaZonesTreatedAsLinksByICU;

  /**
   * IANA treats some time zone names as Links to one target, that ICU
   * instead treats as either Zones, or Links to different targets. An
   * example of the former is "Asia/Calcutta, which IANA assigns the target
   * "Asia/Kolkata" but ICU considers its own Zone. An example of the latter
   * is "US/East-Indiana", which IANA assigns the target
   * "America/Indiana/Indianapolis" but ICU assigns the target
   * "America/Indianapolis".
   *
   * ECMA-402 requires that we respect IANA data, so if we're asked to
   * canonicalize a time zone name that's a key in this map, we *must* return
   * the corresponding value and *must not* return ICU's canonicalization.
   */

  TimeZoneMap ianaLinksCanonicalizedDifferentlyByICU;

  bool timeZoneDataInitialized = false;

  /**
   * Precomputes the available time zone names, because it's too expensive to
   * call ucal_openTimeZones() repeatedly.
   */

  bool ensureTimeZones(JSContext* cx);

  /**
   * Returns the canonical time zone name. |availableTimeZone| must be an
   * available time zone name. If no canonical name was found, returns
   * |nullptr|.
   *
   * This method only handles time zones which are canonicalized differently
   * by ICU when compared to IANA.
   */

  JSAtom* tryCanonicalizeTimeZoneConsistentWithIANA(JSAtom* availableTimeZone);

  /**
   * Returns the canonical time zone name. |availableTimeZone| must be an
   * available time zone name.
   */

  JSAtom* canonicalizeAvailableTimeZone(JSContext* cx,
                                        JS::Handle<JSAtom*> availableTimeZone);

  /**
   * Validates and canonicalizes a time zone name. Returns the case-normalized
   * identifier in |identifier| and its primary time zone in |primary|. If the
   * input time zone isn't a valid IANA time zone name, |identifier| and
   * |primary| both remain unchanged.
   */

  bool validateAndCanonicalizeTimeZone(
      JSContext* cx, const AvailableTimeZoneSet::Lookup& lookup,
      JS::MutableHandle<JSAtom*> identifier,
      JS::MutableHandle<JSAtom*> primary);

 public:
  /**
   * Returns the canonical time zone name. |timeZone| must be a valid time zone
   * name.
   */

  JSLinearString* canonicalizeTimeZone(JSContext* cx,
                                       JS::Handle<JSLinearString*> timeZone);

  /**
   * Validates and canonicalizes a time zone name. Returns the case-normalized
   * identifier in |identifier| and its primary time zone in |primary|. If the
   * input time zone isn't a valid IANA time zone name, |identifier| and
   * |primary| both remain unchanged.
   */

  bool validateAndCanonicalizeTimeZone(JSContext* cx,
                                       JS::Handle<JSLinearString*> timeZone,
                                       JS::MutableHandle<JSAtom*> identifier,
                                       JS::MutableHandle<JSAtom*> primary);

  /**
   * Validates and canonicalizes a time zone name. Returns the case-normalized
   * identifier in |identifier| and its primary time zone in |primary|. If the
   * input time zone isn't a valid IANA time zone name, |identifier| and
   * |primary| both remain unchanged.
   */

  bool validateAndCanonicalizeTimeZone(JSContext* cx,
                                       mozilla::Span<const char> timeZone,
                                       JS::MutableHandle<JSAtom*> identifier,
                                       JS::MutableHandle<JSAtom*> primary);

  /**
   * Returns an iterator over all available time zones supported by ICU. The
   * returned time zone names aren't canonicalized.
   */

  JS::Result<AvailableTimeZoneSet::Iterator> availableTimeZonesIteration(
      JSContext* cx);

 private:
  using Locale = LanguageId;

  struct LocaleHasher {
    using Lookup = Locale;

    static js::HashNumber hash(const Lookup& lookup) { return lookup.hash(); }

    static bool match(Locale key, const Lookup& lookup) {
      return key == lookup;
    }
  };

  using LocaleSet = HashSet<Locale, LocaleHasher, SystemAllocPolicy>;

  // Set of available locales for all Intl service constructors except Collator,
  // which uses its own set.
  //
  // UDateFormat:
  // udat_[count,get]Available() return the same results as their
  // uloc_[count,get]Available() counterparts.
  //
  // UNumberFormatter:
  // unum_[count,get]Available() return the same results as their
  // uloc_[count,get]Available() counterparts.
  //
  // UListFormatter, UPluralRules, and URelativeDateTimeFormatter:
  // We're going to use ULocale availableLocales as per ICU recommendation:
  // https://unicode-org.atlassian.net/browse/ICU-12756
  LocaleSet availableLocales;

  // ucol_[count,get]Available() return different results compared to
  // uloc_[count,get]Available(), we can't use |availableLocales| here.
  LocaleSet collatorAvailableLocales;

  bool availableLocalesInitialized = false;

  // CountAvailable and GetAvailable describe the signatures used for ICU API
  // to determine available locales for various functionality.
  using CountAvailable = int32_t (*)();
  using GetAvailable = const char* (*)(int32_t localeIndex);

  template <class AvailableLocales>
  static bool getAvailableLocales(JSContext* cx, LocaleSet& locales,
                                  const AvailableLocales& availableLocales);

  /**
   * Precomputes the available locales sets.
   */

  bool ensureAvailableLocales(JSContext* cx);

 public:
  /**
   * Sets |available| to true if |locale| is supported by the requested Intl
   * service constructor. Otherwise sets |available| to false.
   */

  [[nodiscard]] bool isAvailableLocale(JSContext* cx, AvailableLocaleKind kind,
                                       LanguageId locale, bool* available);

  /**
   * Returns all available locales for |kind|.
   */

  ArrayObject* availableLocalesOf(JSContext* cx, AvailableLocaleKind kind);

 private:
  using UniqueDateTimePatternGenerator =
      mozilla::UniquePtr<mozilla::intl::DateTimePatternGenerator,
                         DateTimePatternGeneratorDeleter>;

  UniqueDateTimePatternGenerator dateTimePatternGenerator;
  JS::UniqueChars dateTimePatternGeneratorLocale;

 public:
  /**
   * Get a non-owned cached instance of the DateTimePatternGenerator, which is
   * expensive to instantiate.
   *
   * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1549578
   */

  mozilla::intl::DateTimePatternGenerator* getDateTimePatternGenerator(
      JSContext* cx, const char* locale);

 public:
  void destroyInstance();

  void trace(JSTracer* trc);

  size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
};

}  // namespace intl

}  // namespace js

#endif /* builtin_intl_SharedIntlData_h */

Messung V0.5 in Prozent
C=97 H=100 G=98

¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.