value_context.go: Add and integrate `(*ValueContext).Undefined()` method

pull/28/head
Dustin Oprea 2019-12-31 06:41:31 -05:00
parent 79b37fc0e1
commit fb1db098b9
6 changed files with 37 additions and 10 deletions

View File

@ -108,7 +108,7 @@ func main() {
var value interface{}
if tagType.Type() == exif.TypeUndefined {
var err error
value, err = exif.UndefinedValue(ifdPath, tagId, valueContext, tagType.ByteOrder())
value, err = valueContext.Undefined()
if log.Is(err, exif.ErrUnhandledUnknownTypedTag) {
value = nil
} else if err != nil {

View File

@ -81,7 +81,7 @@ func TestVisit(t *testing.T) {
valueString := ""
if tagType.Type() == TypeUndefined {
value, err := UndefinedValue(ifdPath, tagId, valueContext, tagType.ByteOrder())
value, err := valueContext.Undefined()
if log.Is(err, ErrUnhandledUnknownTypedTag) {
valueString = "!UNDEFINED!"
} else if err != nil {

View File

@ -235,11 +235,11 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
// (`ValueString`) is easy because we can just pass everything to
// `Sprintf()`. Returning the raw, typed value (`Value`) is easy
// (obviously). However, here, in order to produce the list of bytes, we
// need to coerce whatever `UndefinedValue()` returns.
// need to coerce whatever `Undefined()` returns.
if ite.TagType == TypeUndefined {
valueContext := ie.GetValueContext(ite)
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
value, err := valueContext.Undefined()
if err != nil {
if log.Is(err, ErrUnhandledUnknownTypedTag) == true {
valueBytes = []byte(UnparseableUnknownTagValuePlaceholder)

View File

@ -47,6 +47,18 @@ func (ite *IfdTagEntry) String() string {
return fmt.Sprintf("IfdTagEntry<TAG-IFD-PATH=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.IfdPath, ite.TagId, TypeNames[ite.TagType], ite.UnitCount)
}
// TODO(dustin): TODO(dustin): Stop exporting IfdPath and TagId.
//
// func (ite *IfdTagEntry) IfdPath() string {
// return ite.IfdPath
// }
// TODO(dustin): TODO(dustin): Stop exporting IfdPath and TagId.
//
// func (ite *IfdTagEntry) TagId() uint16 {
// return ite.TagId
// }
// ValueString renders a string from whatever the value in this tag is.
func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.ByteOrder) (value string, err error) {
defer func() {
@ -62,7 +74,7 @@ func (ite *IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.Byt
byteOrder)
if ite.TagType == TypeUndefined {
valueRaw, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
valueRaw, err := valueContext.Undefined()
log.PanicIf(err)
value = fmt.Sprintf("%v", valueRaw)
@ -86,7 +98,7 @@ func (ite *IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.Byte
// (`ValueString`) is easy because we can just pass everything to
// `Sprintf()`. Returning the raw, typed value (`Value`) is easy
// (obviously). However, here, in order to produce the list of bytes, we
// need to coerce whatever `UndefinedValue()` returns.
// need to coerce whatever `Undefined()` returns.
if ite.TagType == TypeUndefined {
valueContext :=
newValueContextFromTag(
@ -94,7 +106,7 @@ func (ite *IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.Byte
addressableData,
byteOrder)
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
value, err := valueContext.Undefined()
log.PanicIf(err)
switch value.(type) {
@ -153,7 +165,7 @@ func (ite *IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder
byteOrder)
if ite.TagType == TypeUndefined {
value, err = UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
value, err = valueContext.Undefined()
log.PanicIf(err)
} else {
tt := NewTagType(ite.TagType, byteOrder)

View File

@ -326,7 +326,7 @@ func (tt TagType) ReadSignedRationalValues(valueContext ValueContext) (value []S
//
// Since this method lacks the information to process unknown-type tags (e.g.
// byte-order, tag-ID, IFD type), it will return an error if attempted. See
// `UndefinedValue()`.
// `Undefined()`.
func (tt TagType) ResolveAsString(valueContext ValueContext, justFirst bool) (value string, err error) {
defer func() {
if state := recover(); state != nil {
@ -349,7 +349,7 @@ func (tt TagType) ResolveAsString(valueContext ValueContext, justFirst bool) (va
//
// Since this method lacks the information to process unknown-type tags (e.g.
// byte-order, tag-ID, IFD type), it will return an error if attempted. See
// `UndefinedValue()`.
// `Undefined()`.
func (tt TagType) Resolve(valueContext *ValueContext) (values interface{}, err error) {
defer func() {
if state := recover(); state != nil {

View File

@ -341,6 +341,21 @@ func (vc *ValueContext) Values() (value interface{}, err error) {
return value, nil
}
// Undefined attempts to identify and decode supported undefined-type fields.
// This is the primary, preferred interface to reading undefined values.
func (vc *ValueContext) Undefined() (value interface{}, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
value, err = UndefinedValue(vc.ifdPath, vc.tagId, vc, vc.byteOrder)
log.PanicIf(err)
return value, nil
}
func init() {
parser = &Parser{}
}