OSDN Git Service

Thanos did someting
[bytom/vapor.git] / vendor / golang.org / x / text / internal / catmsg / codec.go
diff --git a/vendor/golang.org/x/text/internal/catmsg/codec.go b/vendor/golang.org/x/text/internal/catmsg/codec.go
deleted file mode 100644 (file)
index ab587f8..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2017 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.
-
-package catmsg
-
-import (
-       "errors"
-       "fmt"
-
-       "golang.org/x/text/language"
-)
-
-// A Renderer renders a Message.
-type Renderer interface {
-       // Render renders the given string. The given string may be interpreted as a
-       // format string, such as the one used by the fmt package or a template.
-       Render(s string)
-
-       // Arg returns the i-th argument passed to format a message. This method
-       // should return nil if there is no such argument. Messages need access to
-       // arguments to allow selecting a message based on linguistic features of
-       // those arguments.
-       Arg(i int) interface{}
-}
-
-// A Dictionary specifies a source of messages, including variables or macros.
-type Dictionary interface {
-       // Lookup returns the message for the given key. It returns false for ok if
-       // such a message could not be found.
-       Lookup(key string) (data string, ok bool)
-
-       // TODO: consider returning an interface, instead of a string. This will
-       // allow implementations to do their own message type decoding.
-}
-
-// An Encoder serializes a Message to a string.
-type Encoder struct {
-       // The root encoder is used for storing encoded variables.
-       root *Encoder
-       // The parent encoder provides the surrounding scopes for resolving variable
-       // names.
-       parent *Encoder
-
-       tag language.Tag
-
-       // buf holds the encoded message so far. After a message completes encoding,
-       // the contents of buf, prefixed by the encoded length, are flushed to the
-       // parent buffer.
-       buf []byte
-
-       // vars is the lookup table of variables in the current scope.
-       vars []keyVal
-
-       err    error
-       inBody bool // if false next call must be EncodeMessageType
-}
-
-type keyVal struct {
-       key    string
-       offset int
-}
-
-// Language reports the language for which the encoded message will be stored
-// in the Catalog.
-func (e *Encoder) Language() language.Tag { return e.tag }
-
-func (e *Encoder) setError(err error) {
-       if e.root.err == nil {
-               e.root.err = err
-       }
-}
-
-// EncodeUint encodes x.
-func (e *Encoder) EncodeUint(x uint64) {
-       e.checkInBody()
-       var buf [maxVarintBytes]byte
-       n := encodeUint(buf[:], x)
-       e.buf = append(e.buf, buf[:n]...)
-}
-
-// EncodeString encodes s.
-func (e *Encoder) EncodeString(s string) {
-       e.checkInBody()
-       e.EncodeUint(uint64(len(s)))
-       e.buf = append(e.buf, s...)
-}
-
-// EncodeMessageType marks the current message to be of type h.
-//
-// It must be the first call of a Message's Compile method.
-func (e *Encoder) EncodeMessageType(h Handle) {
-       if e.inBody {
-               panic("catmsg: EncodeMessageType not the first method called")
-       }
-       e.inBody = true
-       e.EncodeUint(uint64(h))
-}
-
-// EncodeMessage serializes the given message inline at the current position.
-func (e *Encoder) EncodeMessage(m Message) error {
-       e = &Encoder{root: e.root, parent: e, tag: e.tag}
-       err := m.Compile(e)
-       if _, ok := m.(*Var); !ok {
-               e.flushTo(e.parent)
-       }
-       return err
-}
-
-func (e *Encoder) checkInBody() {
-       if !e.inBody {
-               panic("catmsg: expected prior call to EncodeMessageType")
-       }
-}
-
-// stripPrefix indicates the number of prefix bytes that must be stripped to
-// turn a single-element sequence into a message that is just this single member
-// without its size prefix. If the message can be stripped, b[1:n] contains the
-// size prefix.
-func stripPrefix(b []byte) (n int) {
-       if len(b) > 0 && Handle(b[0]) == msgFirst {
-               x, n, _ := decodeUint(b[1:])
-               if 1+n+int(x) == len(b) {
-                       return 1 + n
-               }
-       }
-       return 0
-}
-
-func (e *Encoder) flushTo(dst *Encoder) {
-       data := e.buf
-       p := stripPrefix(data)
-       if p > 0 {
-               data = data[1:]
-       } else {
-               // Prefix the size.
-               dst.EncodeUint(uint64(len(data)))
-       }
-       dst.buf = append(dst.buf, data...)
-}
-
-func (e *Encoder) addVar(key string, m Message) error {
-       for _, v := range e.parent.vars {
-               if v.key == key {
-                       err := fmt.Errorf("catmsg: duplicate variable %q", key)
-                       e.setError(err)
-                       return err
-               }
-       }
-       scope := e.parent
-       // If a variable message is Incomplete, and does not evaluate to a message
-       // during execution, we fall back to the variable name. We encode this by
-       // appending the variable name if the message reports it's incomplete.
-
-       err := m.Compile(e)
-       if err != ErrIncomplete {
-               e.setError(err)
-       }
-       switch {
-       case len(e.buf) == 1 && Handle(e.buf[0]) == msgFirst: // empty sequence
-               e.buf = e.buf[:0]
-               e.inBody = false
-               fallthrough
-       case len(e.buf) == 0:
-               // Empty message.
-               if err := String(key).Compile(e); err != nil {
-                       e.setError(err)
-               }
-       case err == ErrIncomplete:
-               if Handle(e.buf[0]) != msgFirst {
-                       seq := &Encoder{root: e.root, parent: e}
-                       seq.EncodeMessageType(First)
-                       e.flushTo(seq)
-                       e = seq
-               }
-               // e contains a sequence; append the fallback string.
-               e.EncodeMessage(String(key))
-       }
-
-       // Flush result to variable heap.
-       offset := len(e.root.buf)
-       e.flushTo(e.root)
-       e.buf = e.buf[:0]
-
-       // Record variable offset in current scope.
-       scope.vars = append(scope.vars, keyVal{key: key, offset: offset})
-       return err
-}
-
-const (
-       substituteVar = iota
-       substituteMacro
-       substituteError
-)
-
-// EncodeSubstitution inserts a resolved reference to a variable or macro.
-//
-// This call must be matched with a call to ExecuteSubstitution at decoding
-// time.
-func (e *Encoder) EncodeSubstitution(name string, arguments ...int) {
-       if arity := len(arguments); arity > 0 {
-               // TODO: also resolve macros.
-               e.EncodeUint(substituteMacro)
-               e.EncodeString(name)
-               for _, a := range arguments {
-                       e.EncodeUint(uint64(a))
-               }
-               return
-       }
-       for scope := e; scope != nil; scope = scope.parent {
-               for _, v := range scope.vars {
-                       if v.key != name {
-                               continue
-                       }
-                       e.EncodeUint(substituteVar) // TODO: support arity > 0
-                       e.EncodeUint(uint64(v.offset))
-                       return
-               }
-       }
-       // TODO: refer to dictionary-wide scoped variables.
-       e.EncodeUint(substituteError)
-       e.EncodeString(name)
-       e.setError(fmt.Errorf("catmsg: unknown var %q", name))
-}
-
-// A Decoder deserializes and evaluates messages that are encoded by an encoder.
-type Decoder struct {
-       tag    language.Tag
-       dst    Renderer
-       macros Dictionary
-
-       err  error
-       vars string
-       data string
-
-       macroArg int // TODO: allow more than one argument
-}
-
-// NewDecoder returns a new Decoder.
-//
-// Decoders are designed to be reused for multiple invocations of Execute.
-// Only one goroutine may call Execute concurrently.
-func NewDecoder(tag language.Tag, r Renderer, macros Dictionary) *Decoder {
-       return &Decoder{
-               tag:    tag,
-               dst:    r,
-               macros: macros,
-       }
-}
-
-func (d *Decoder) setError(err error) {
-       if d.err == nil {
-               d.err = err
-       }
-}
-
-// Language returns the language in which the message is being rendered.
-//
-// The destination language may be a child language of the language used for
-// encoding. For instance, a decoding language of "pt-PT"" is consistent with an
-// encoding language of "pt".
-func (d *Decoder) Language() language.Tag { return d.tag }
-
-// Done reports whether there are more bytes to process in this message.
-func (d *Decoder) Done() bool { return len(d.data) == 0 }
-
-// Render implements Renderer.
-func (d *Decoder) Render(s string) { d.dst.Render(s) }
-
-// Arg implements Renderer.
-//
-// During evaluation of macros, the argument positions may be mapped to
-// arguments that differ from the original call.
-func (d *Decoder) Arg(i int) interface{} {
-       if d.macroArg != 0 {
-               if i != 1 {
-                       panic("catmsg: only macros with single argument supported")
-               }
-               i = d.macroArg
-       }
-       return d.dst.Arg(i)
-}
-
-// DecodeUint decodes a number that was encoded with EncodeUint and advances the
-// position.
-func (d *Decoder) DecodeUint() uint64 {
-       x, n, err := decodeUintString(d.data)
-       d.data = d.data[n:]
-       if err != nil {
-               d.setError(err)
-       }
-       return x
-}
-
-// DecodeString decodes a string that was encoded with EncodeString and advances
-// the position.
-func (d *Decoder) DecodeString() string {
-       size := d.DecodeUint()
-       s := d.data[:size]
-       d.data = d.data[size:]
-       return s
-}
-
-// SkipMessage skips the message at the current location and advances the
-// position.
-func (d *Decoder) SkipMessage() {
-       n := int(d.DecodeUint())
-       d.data = d.data[n:]
-}
-
-// Execute decodes and evaluates msg.
-//
-// Only one goroutine may call execute.
-func (d *Decoder) Execute(msg string) error {
-       d.err = nil
-       if !d.execute(msg) {
-               return ErrNoMatch
-       }
-       return d.err
-}
-
-func (d *Decoder) execute(msg string) bool {
-       saved := d.data
-       d.data = msg
-       ok := d.executeMessage()
-       d.data = saved
-       return ok
-}
-
-// executeMessageFromData is like execute, but also decodes a leading message
-// size and clips the given string accordingly.
-//
-// It reports the number of bytes consumed and whether a message was selected.
-func (d *Decoder) executeMessageFromData(s string) (n int, ok bool) {
-       saved := d.data
-       d.data = s
-       size := int(d.DecodeUint())
-       n = len(s) - len(d.data)
-       // Sanitize the setting. This allows skipping a size argument for
-       // RawString and method Done.
-       d.data = d.data[:size]
-       ok = d.executeMessage()
-       n += size - len(d.data)
-       d.data = saved
-       return n, ok
-}
-
-var errUnknownHandler = errors.New("catmsg: string contains unsupported handler")
-
-// executeMessage reads the handle id, initializes the decoder and executes the
-// message. It is assumed that all of d.data[d.p:] is the single message.
-func (d *Decoder) executeMessage() bool {
-       if d.Done() {
-               // We interpret no data as a valid empty message.
-               return true
-       }
-       handle := d.DecodeUint()
-
-       var fn Handler
-       mutex.Lock()
-       if int(handle) < len(handlers) {
-               fn = handlers[handle]
-       }
-       mutex.Unlock()
-       if fn == nil {
-               d.setError(errUnknownHandler)
-               d.execute(fmt.Sprintf("\x02$!(UNKNOWNMSGHANDLER=%#x)", handle))
-               return true
-       }
-       return fn(d)
-}
-
-// ExecuteMessage decodes and executes the message at the current position.
-func (d *Decoder) ExecuteMessage() bool {
-       n, ok := d.executeMessageFromData(d.data)
-       d.data = d.data[n:]
-       return ok
-}
-
-// ExecuteSubstitution executes the message corresponding to the substitution
-// as encoded by EncodeSubstitution.
-func (d *Decoder) ExecuteSubstitution() {
-       switch x := d.DecodeUint(); x {
-       case substituteVar:
-               offset := d.DecodeUint()
-               d.executeMessageFromData(d.vars[offset:])
-       case substituteMacro:
-               name := d.DecodeString()
-               data, ok := d.macros.Lookup(name)
-               old := d.macroArg
-               // TODO: support macros of arity other than 1.
-               d.macroArg = int(d.DecodeUint())
-               switch {
-               case !ok:
-                       // TODO: detect this at creation time.
-                       d.setError(fmt.Errorf("catmsg: undefined macro %q", name))
-                       fallthrough
-               case !d.execute(data):
-                       d.dst.Render(name) // fall back to macro name.
-               }
-               d.macroArg = old
-       case substituteError:
-               d.dst.Render(d.DecodeString())
-       default:
-               panic("catmsg: unreachable")
-       }
-}