mirror of https://github.com/dsoprea/go-exif.git
type: Now support marshaling from string to all types.
parent
9b70a9180c
commit
d79470a4f4
67
type.go
67
type.go
|
@ -4,6 +4,8 @@ import (
|
|||
"errors"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"encoding/binary"
|
||||
|
||||
|
@ -739,3 +741,68 @@ func (tt TagType) Encode(value interface{}) (encoded []byte, err error) {
|
|||
|
||||
return ed.Encoded, err
|
||||
}
|
||||
|
||||
func (tt TagType) FromString(valueString string) (value interface{}, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
if tt.tagType == TypeUndefined {
|
||||
// TODO(dustin): Circle back to this.
|
||||
log.Panicf("undefined-type values are not supported")
|
||||
}
|
||||
|
||||
if tt.tagType == TypeByte {
|
||||
return []byte(valueString), nil
|
||||
} else if tt.tagType == TypeAscii {
|
||||
return fmt.Sprintf("%s\n", valueString), nil
|
||||
} else if tt.tagType == TypeShort {
|
||||
n, err := strconv.ParseUint(valueString, 10, 16)
|
||||
log.PanicIf(err)
|
||||
|
||||
return uint16(n), nil
|
||||
} else if tt.tagType == TypeLong {
|
||||
n, err := strconv.ParseUint(valueString, 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
return uint32(n), nil
|
||||
} else if tt.tagType == TypeRational {
|
||||
parts := strings.SplitN(valueString, "/", 2)
|
||||
|
||||
numerator, err := strconv.ParseUint(parts[0], 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
denominator, err := strconv.ParseUint(parts[1], 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
return Rational{
|
||||
Numerator: uint32(numerator),
|
||||
Denominator: uint32(denominator),
|
||||
}, nil
|
||||
} else if tt.tagType == TypeSignedLong {
|
||||
n, err := strconv.ParseInt(valueString, 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
return int32(n), nil
|
||||
} else if tt.tagType == TypeSignedRational {
|
||||
parts := strings.SplitN(valueString, "/", 2)
|
||||
|
||||
numerator, err := strconv.ParseInt(parts[0], 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
denominator, err := strconv.ParseInt(parts[1], 10, 32)
|
||||
log.PanicIf(err)
|
||||
|
||||
return SignedRational{
|
||||
Numerator: int32(numerator),
|
||||
Denominator: int32(denominator),
|
||||
}, nil
|
||||
} else if tt.tagType == TypeAsciiNoNul {
|
||||
return valueString, nil
|
||||
}
|
||||
|
||||
log.Panicf("from-string encoding for type not supported; this shouldn't happen: (%d)", tt.Type)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
135
type_test.go
135
type_test.go
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/dsoprea/go-logging"
|
||||
)
|
||||
|
||||
func Test_TagType_EncodeDecode_Byte(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_Byte(t *testing.T) {
|
||||
tt := NewTagType(TypeByte, TestDefaultByteOrder)
|
||||
|
||||
data := []byte { 0x11, 0x22, 0x33, 0x44, 0x55 }
|
||||
|
@ -29,7 +29,7 @@ func Test_TagType_EncodeDecode_Byte(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_Ascii(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_Ascii(t *testing.T) {
|
||||
tt := NewTagType(TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
data := "hello"
|
||||
|
@ -49,7 +49,7 @@ func Test_TagType_EncodeDecode_Ascii(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_Shorts(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_Shorts(t *testing.T) {
|
||||
tt := NewTagType(TypeShort, TestDefaultByteOrder)
|
||||
|
||||
data := []uint16 { 0x11, 0x22, 0x33 }
|
||||
|
@ -69,7 +69,7 @@ func Test_TagType_EncodeDecode_Shorts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_Long(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_Long(t *testing.T) {
|
||||
tt := NewTagType(TypeLong, TestDefaultByteOrder)
|
||||
|
||||
data := []uint32 { 0x11, 0x22, 0x33 }
|
||||
|
@ -89,7 +89,7 @@ func Test_TagType_EncodeDecode_Long(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_Rational(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_Rational(t *testing.T) {
|
||||
tt := NewTagType(TypeRational, TestDefaultByteOrder)
|
||||
|
||||
data := []Rational {
|
||||
|
@ -112,7 +112,7 @@ func Test_TagType_EncodeDecode_Rational(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_SignedLong(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_SignedLong(t *testing.T) {
|
||||
tt := NewTagType(TypeSignedLong, TestDefaultByteOrder)
|
||||
|
||||
data := []int32 { 0x11, 0x22, 0x33 }
|
||||
|
@ -132,7 +132,7 @@ func Test_TagType_EncodeDecode_SignedLong(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_SignedRational(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_SignedRational(t *testing.T) {
|
||||
tt := NewTagType(TypeSignedRational, TestDefaultByteOrder)
|
||||
|
||||
data := []SignedRational {
|
||||
|
@ -155,7 +155,7 @@ func Test_TagType_EncodeDecode_SignedRational(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_TagType_EncodeDecode_AsciiNoNul(t *testing.T) {
|
||||
func TestTagType_EncodeDecode_AsciiNoNul(t *testing.T) {
|
||||
tt := NewTagType(TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
|
||||
data := "hello"
|
||||
|
@ -176,3 +176,122 @@ func Test_TagType_EncodeDecode_AsciiNoNul(t *testing.T) {
|
|||
}
|
||||
|
||||
// TODO(dustin): Add tests for TypeUndefined.
|
||||
|
||||
func TestTagType_FromString_Undefined(t *testing.T) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
log.PrintErrorf(err, "Test failure.")
|
||||
|
||||
log.Panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tt := NewTagType(TypeUndefined, TestDefaultByteOrder)
|
||||
|
||||
_, err := tt.FromString("")
|
||||
if err == nil {
|
||||
t.Fatalf("no error for undefined-type")
|
||||
} else if err.Error() != "undefined-type values are not supported" {
|
||||
fmt.Printf("[%s]\n", err.Error())
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_Byte(t *testing.T) {
|
||||
tt := NewTagType(TypeByte, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("abc")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, []byte { 'a', 'b', 'c' }) != true {
|
||||
t.Fatalf("byte value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_Ascii(t *testing.T) {
|
||||
tt := NewTagType(TypeAscii, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("abc")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, "abc\n") != true {
|
||||
t.Fatalf("ASCII value not correct: [%s]", value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_Short(t *testing.T) {
|
||||
tt := NewTagType(TypeShort, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("55")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, uint16(55)) != true {
|
||||
t.Fatalf("short value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_Long(t *testing.T) {
|
||||
tt := NewTagType(TypeLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("66000")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, uint32(66000)) != true {
|
||||
t.Fatalf("long value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_Rational(t *testing.T) {
|
||||
tt := NewTagType(TypeRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("12/34")
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := Rational{
|
||||
Numerator: 12,
|
||||
Denominator: 34,
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(value, expected) != true {
|
||||
t.Fatalf("rational value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_SignedLong(t *testing.T) {
|
||||
tt := NewTagType(TypeSignedLong, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("-66000")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, int32(-66000)) != true {
|
||||
t.Fatalf("signed-long value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_SignedRational(t *testing.T) {
|
||||
tt := NewTagType(TypeSignedRational, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("-12/34")
|
||||
log.PanicIf(err)
|
||||
|
||||
expected := SignedRational{
|
||||
Numerator: -12,
|
||||
Denominator: 34,
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(value, expected) != true {
|
||||
t.Fatalf("signd-rational value not correct")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagType_FromString_AsciiNoNul(t *testing.T) {
|
||||
tt := NewTagType(TypeAsciiNoNul, TestDefaultByteOrder)
|
||||
|
||||
value, err := tt.FromString("abc")
|
||||
log.PanicIf(err)
|
||||
|
||||
if reflect.DeepEqual(value, "abc") != true {
|
||||
t.Fatalf("ASCII-no-nul value not correct")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue