// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:generate go run gen.go gen_common.go

// Package number contains tools and data for formatting numbers.
package number import ( ) // Info holds number formatting configuration data. type Info struct { system systemData // numbering system information symIndex symOffset // index to symbols } // InfoFromLangID returns a Info for the given compact language identifier and // numbering system identifier. If system is the empty string, the default // numbering system will be taken for that language. func ( compact.ID, string) Info { := langToDefaults[] // Lookup the entry for the language. := symOffset(0) // Default: Latin, default symbols , := systemMap[] if ! { // Take the value for the default numbering system. This is by far the // most common case as an alternative numbering system is hardly used. if &hasNonLatnMask == 0 { // Latn digits. = } else { // Non-Latn or multiple numbering systems. // Take the first entry from the alternatives list. := langToAlt[&^hasNonLatnMask] = .symIndex = .system } } else { := := : for ; ; = langToDefaults[] { if &hasNonLatnMask == 0 { if == 0 { // The index directly points to the symbol data. = break } // Move to the parent and retry. = .Parent() } else { // The index points to a list of symbol data indexes. for , := range langToAlt[&^hasNonLatnMask:] { if .compactTag != { if == 0 { // The CLDR root defines full symbol information for // all numbering systems (even though mostly by // means of aliases). Fall back to the default entry // for Latn if there is no data for the numbering // system of this language. if == 0 { break } // Fall back to Latin and start from the original // language. See // https://unicode.org/reports/tr35/#Locale_Inheritance. = numLatn = continue } // Fall back to parent. = .Parent() } else if .system == { = .symIndex break } } } } } if int() >= len(numSysData) { // algorithmic // Will generate ASCII digits in case the user inadvertently calls // WriteDigit or Digit on it. := numSysData[0] .id = return Info{ system: , symIndex: , } } return Info{ system: numSysData[], symIndex: , } } // InfoFromTag returns a Info for the given language tag. func ( language.Tag) Info { return InfoFromLangID(tagToID(), .TypeForKey("nu")) } // IsDecimal reports if the numbering system can convert decimal to native // symbols one-to-one. func ( Info) () bool { return int(.system.id) < len(numSysData) } // WriteDigit writes the UTF-8 sequence for n corresponding to the given ASCII // digit to dst and reports the number of bytes written. dst must be large // enough to hold the rune (can be up to utf8.UTFMax bytes). func ( Info) ( []byte, rune) int { copy(, .system.zero[:.system.digitSize]) [.system.digitSize-1] += byte( - '0') return int(.system.digitSize) } // AppendDigit appends the UTF-8 sequence for n corresponding to the given digit // to dst and reports the number of bytes written. dst must be large enough to // hold the rune (can be up to utf8.UTFMax bytes). func ( Info) ( []byte, byte) []byte { = append(, .system.zero[:.system.digitSize]...) [len()-1] += return } // Digit returns the digit for the numbering system for the corresponding ASCII // value. For example, ni.Digit('3') could return 'δΈ‰'. Note that the argument // is the rune constant '3', which equals 51, not the integer constant 3. func ( Info) ( rune) rune { var [utf8.UTFMax]byte .WriteDigit([:], ) , := utf8.DecodeRune([:]) return } // Symbol returns the string for the given symbol type. func ( Info) ( SymbolType) string { return symData.Elem(int(symIndex[.symIndex][])) } func formatForLang( language.Tag, []byte) *Pattern { return &formats[[tagToID()]] } func tagToID( language.Tag) compact.ID { , := compact.RegionalID(compact.Tag()) return }