mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-10-19 21:59:54 +00:00
91774fc936
Uses github.com/libopenstorage/secrets to communicate with Vault. This removes the need for maintaining our own limited Vault APIs. By adding the new dependency, several other packages got updated in the process. Unused indirect dependencies have been removed from go.mod. Signed-off-by: Niels de Vos <ndevos@redhat.com>
214 lines
5.9 KiB
Go
214 lines
5.9 KiB
Go
// Copyright 2018 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 defval marshals and unmarshals textual forms of default values.
|
|
//
|
|
// This package handles both the form historically used in Go struct field tags
|
|
// and also the form used by google.protobuf.FieldDescriptorProto.default_value
|
|
// since they differ in superficial ways.
|
|
package defval
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"strconv"
|
|
|
|
ptext "google.golang.org/protobuf/internal/encoding/text"
|
|
errors "google.golang.org/protobuf/internal/errors"
|
|
pref "google.golang.org/protobuf/reflect/protoreflect"
|
|
)
|
|
|
|
// Format is the serialization format used to represent the default value.
|
|
type Format int
|
|
|
|
const (
|
|
_ Format = iota
|
|
|
|
// Descriptor uses the serialization format that protoc uses with the
|
|
// google.protobuf.FieldDescriptorProto.default_value field.
|
|
Descriptor
|
|
|
|
// GoTag uses the historical serialization format in Go struct field tags.
|
|
GoTag
|
|
)
|
|
|
|
// Unmarshal deserializes the default string s according to the given kind k.
|
|
// When k is an enum, a list of enum value descriptors must be provided.
|
|
func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) {
|
|
switch k {
|
|
case pref.BoolKind:
|
|
if f == GoTag {
|
|
switch s {
|
|
case "1":
|
|
return pref.ValueOfBool(true), nil, nil
|
|
case "0":
|
|
return pref.ValueOfBool(false), nil, nil
|
|
}
|
|
} else {
|
|
switch s {
|
|
case "true":
|
|
return pref.ValueOfBool(true), nil, nil
|
|
case "false":
|
|
return pref.ValueOfBool(false), nil, nil
|
|
}
|
|
}
|
|
case pref.EnumKind:
|
|
if f == GoTag {
|
|
// Go tags use the numeric form of the enum value.
|
|
if n, err := strconv.ParseInt(s, 10, 32); err == nil {
|
|
if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil {
|
|
return pref.ValueOfEnum(ev.Number()), ev, nil
|
|
}
|
|
}
|
|
} else {
|
|
// Descriptor default_value use the enum identifier.
|
|
ev := evs.ByName(pref.Name(s))
|
|
if ev != nil {
|
|
return pref.ValueOfEnum(ev.Number()), ev, nil
|
|
}
|
|
}
|
|
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
|
|
if v, err := strconv.ParseInt(s, 10, 32); err == nil {
|
|
return pref.ValueOfInt32(int32(v)), nil, nil
|
|
}
|
|
case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
|
|
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
|
|
return pref.ValueOfInt64(int64(v)), nil, nil
|
|
}
|
|
case pref.Uint32Kind, pref.Fixed32Kind:
|
|
if v, err := strconv.ParseUint(s, 10, 32); err == nil {
|
|
return pref.ValueOfUint32(uint32(v)), nil, nil
|
|
}
|
|
case pref.Uint64Kind, pref.Fixed64Kind:
|
|
if v, err := strconv.ParseUint(s, 10, 64); err == nil {
|
|
return pref.ValueOfUint64(uint64(v)), nil, nil
|
|
}
|
|
case pref.FloatKind, pref.DoubleKind:
|
|
var v float64
|
|
var err error
|
|
switch s {
|
|
case "-inf":
|
|
v = math.Inf(-1)
|
|
case "inf":
|
|
v = math.Inf(+1)
|
|
case "nan":
|
|
v = math.NaN()
|
|
default:
|
|
v, err = strconv.ParseFloat(s, 64)
|
|
}
|
|
if err == nil {
|
|
if k == pref.FloatKind {
|
|
return pref.ValueOfFloat32(float32(v)), nil, nil
|
|
} else {
|
|
return pref.ValueOfFloat64(float64(v)), nil, nil
|
|
}
|
|
}
|
|
case pref.StringKind:
|
|
// String values are already unescaped and can be used as is.
|
|
return pref.ValueOfString(s), nil, nil
|
|
case pref.BytesKind:
|
|
if b, ok := unmarshalBytes(s); ok {
|
|
return pref.ValueOfBytes(b), nil, nil
|
|
}
|
|
}
|
|
return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s)
|
|
}
|
|
|
|
// Marshal serializes v as the default string according to the given kind k.
|
|
// When specifying the Descriptor format for an enum kind, the associated
|
|
// enum value descriptor must be provided.
|
|
func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) {
|
|
switch k {
|
|
case pref.BoolKind:
|
|
if f == GoTag {
|
|
if v.Bool() {
|
|
return "1", nil
|
|
} else {
|
|
return "0", nil
|
|
}
|
|
} else {
|
|
if v.Bool() {
|
|
return "true", nil
|
|
} else {
|
|
return "false", nil
|
|
}
|
|
}
|
|
case pref.EnumKind:
|
|
if f == GoTag {
|
|
return strconv.FormatInt(int64(v.Enum()), 10), nil
|
|
} else {
|
|
return string(ev.Name()), nil
|
|
}
|
|
case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
|
|
return strconv.FormatInt(v.Int(), 10), nil
|
|
case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind:
|
|
return strconv.FormatUint(v.Uint(), 10), nil
|
|
case pref.FloatKind, pref.DoubleKind:
|
|
f := v.Float()
|
|
switch {
|
|
case math.IsInf(f, -1):
|
|
return "-inf", nil
|
|
case math.IsInf(f, +1):
|
|
return "inf", nil
|
|
case math.IsNaN(f):
|
|
return "nan", nil
|
|
default:
|
|
if k == pref.FloatKind {
|
|
return strconv.FormatFloat(f, 'g', -1, 32), nil
|
|
} else {
|
|
return strconv.FormatFloat(f, 'g', -1, 64), nil
|
|
}
|
|
}
|
|
case pref.StringKind:
|
|
// String values are serialized as is without any escaping.
|
|
return v.String(), nil
|
|
case pref.BytesKind:
|
|
if s, ok := marshalBytes(v.Bytes()); ok {
|
|
return s, nil
|
|
}
|
|
}
|
|
return "", errors.New("could not format value for %v: %v", k, v)
|
|
}
|
|
|
|
// unmarshalBytes deserializes bytes by applying C unescaping.
|
|
func unmarshalBytes(s string) ([]byte, bool) {
|
|
// Bytes values use the same escaping as the text format,
|
|
// however they lack the surrounding double quotes.
|
|
v, err := ptext.UnmarshalString(`"` + s + `"`)
|
|
if err != nil {
|
|
return nil, false
|
|
}
|
|
return []byte(v), true
|
|
}
|
|
|
|
// marshalBytes serializes bytes by using C escaping.
|
|
// To match the exact output of protoc, this is identical to the
|
|
// CEscape function in strutil.cc of the protoc source code.
|
|
func marshalBytes(b []byte) (string, bool) {
|
|
var s []byte
|
|
for _, c := range b {
|
|
switch c {
|
|
case '\n':
|
|
s = append(s, `\n`...)
|
|
case '\r':
|
|
s = append(s, `\r`...)
|
|
case '\t':
|
|
s = append(s, `\t`...)
|
|
case '"':
|
|
s = append(s, `\"`...)
|
|
case '\'':
|
|
s = append(s, `\'`...)
|
|
case '\\':
|
|
s = append(s, `\\`...)
|
|
default:
|
|
if printableASCII := c >= 0x20 && c <= 0x7e; printableASCII {
|
|
s = append(s, c)
|
|
} else {
|
|
s = append(s, fmt.Sprintf(`\%03o`, c)...)
|
|
}
|
|
}
|
|
}
|
|
return string(s), true
|
|
}
|