diff --git a/exif-read-tool/main.go b/exif-read-tool/main.go index 1e63b93..ca513a2 100644 --- a/exif-read-tool/main.go +++ b/exif-read-tool/main.go @@ -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 { diff --git a/exif_test.go b/exif_test.go index b473222..8d4c4fc 100644 --- a/exif_test.go +++ b/exif_test.go @@ -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 { diff --git a/ifd_enumerate.go b/ifd_enumerate.go index b088971..49044e3 100644 --- a/ifd_enumerate.go +++ b/ifd_enumerate.go @@ -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) diff --git a/ifd_tag_entry.go b/ifd_tag_entry.go index 89902c1..7cb59a0 100644 --- a/ifd_tag_entry.go +++ b/ifd_tag_entry.go @@ -47,6 +47,18 @@ func (ite *IfdTagEntry) String() string { return fmt.Sprintf("IfdTagEntry", 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) diff --git a/tag_type.go b/tag_type.go index 3661778..e53b1c4 100644 --- a/tag_type.go +++ b/tag_type.go @@ -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 { diff --git a/value_context.go b/value_context.go index ef4ab75..e542ad1 100644 --- a/value_context.go +++ b/value_context.go @@ -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{} }