blob: 42b6ceb0b972866767cd604bf2703f756a49bdc3 [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schema
import (
"fmt"
"strings"
"android.googlesource.com/platform/tools/gpu/binary"
)
// Method denotes the encoding/decoding method a primitive type will use.
type Method int
// binary: Method.String = false
const (
ID Method = iota
Bool
Int8
Uint8
Int16
Uint16
Int32
Uint32
Int64
Uint64
Float32
Float64
String
)
var (
methodToString = map[Method]string{
ID: "ID",
Bool: "Bool",
Int8: "Int8",
Uint8: "Uint8",
Int16: "Int16",
Uint16: "Uint16",
Int32: "Int32",
Uint32: "Uint32",
Int64: "Int64",
Uint64: "Uint64",
Float32: "Float32",
Float64: "Float64",
String: "String",
}
stringToMethod = map[string]Method{}
methodToBase = map[Method]string{
ID: "binary.ID",
Bool: "bool",
Int8: "int8",
Uint8: "uint8",
Int16: "int16",
Uint16: "uint16",
Int32: "int32",
Uint32: "uint32",
Int64: "int64",
Uint64: "uint64",
Float32: "float32",
Float64: "float64",
String: "string",
}
)
func init() {
for m, s := range methodToString {
stringToMethod[s] = m
}
}
// Primitive is the kind for primitive types with corresponding direct methods on
// Encoder and Decoder
type Primitive struct {
binary.Generate
Name string // The simple name of the type.
Method Method // The enocde/decode method to use.
}
// Native returns the go native type name for this primitive.
func (p *Primitive) Native() string {
switch p.Method {
case ID:
return "binary.ID"
default:
return strings.ToLower(p.Method.String())
}
}
func (p *Primitive) Basename() string {
return methodToBase[p.Method]
}
func (p *Primitive) Typename() string {
return p.Name
}
func (p *Primitive) String() string {
return p.Name
}
func (p *Primitive) Encode(e binary.Encoder, value interface{}) error {
switch p.Method {
case ID:
return e.ID(value.(binary.ID))
case Bool:
return e.Bool(value.(bool))
case Int8:
return e.Int8(value.(int8))
case Uint8:
return e.Uint8(value.(uint8))
case Int16:
return e.Int16(value.(int16))
case Uint16:
return e.Uint16(value.(uint16))
case Int32:
return e.Int32(value.(int32))
case Uint32:
return e.Uint32(value.(uint32))
case Int64:
return e.Int64(value.(int64))
case Uint64:
return e.Uint64(value.(uint64))
case Float32:
return e.Float32(value.(float32))
case Float64:
return e.Float64(value.(float64))
case String:
return e.String(value.(string))
default:
return fmt.Errorf("Unknown encode method %q", p.Method)
}
}
func (p *Primitive) Decode(d binary.Decoder) (interface{}, error) {
switch p.Method {
case ID:
return d.ID()
case Bool:
return d.Bool()
case Int8:
return d.Int8()
case Uint8:
return d.Uint8()
case Int16:
return d.Int16()
case Uint16:
return d.Uint16()
case Int32:
return d.Int32()
case Uint32:
return d.Uint32()
case Int64:
return d.Int64()
case Uint64:
return d.Uint64()
case Float32:
return d.Float32()
case Float64:
return d.Float64()
case String:
return d.String()
default:
return nil, fmt.Errorf("Unknown decode method %q", p.Method)
}
}
// Implements binary.Class
func (p *Primitive) Skip(d binary.Decoder) error {
var err error
switch p.Method {
case ID:
return d.SkipID()
case Bool:
_, err = d.Bool()
case Int8:
_, err = d.Int8()
case Uint8:
_, err = d.Uint8()
case Int16:
_, err = d.Int16()
case Uint16:
_, err = d.Uint16()
case Int32:
_, err = d.Int32()
case Uint32:
_, err = d.Uint32()
case Int64:
_, err = d.Int64()
case Uint64:
_, err = d.Uint64()
case Float32:
_, err = d.Float32()
case Float64:
_, err = d.Float64()
return err
case String:
return d.SkipString()
default:
err = fmt.Errorf("Unknown skip method %q", p.Method)
}
return err
}
// This will convert a string to a Method, or return an error if the string was
// not a valid method name.
func ParseMethod(s string) (Method, error) {
if m, ok := stringToMethod[s]; ok {
return m, nil
}
return 0, fmt.Errorf("Invalid Method name %s", s)
}
func (m Method) String() string {
if s, ok := methodToString[m]; ok {
return s
}
return fmt.Sprintf("Method(%d)", m)
}
// Skippable returns true if the method has a complimentary skip method on the
// decoder interface. If this is not true, the normal decoding method is used
// during skipping.
func (m Method) Skippable() bool {
return m == ID || m == String
}