mirror of https://github.com/dsoprea/go-exif.git
ifd_tag_entry: Implemented Value() and ValueString() wrappers.
- type: Added `(TagType).Resolve()` to return the parsed, typed value.pull/3/head
parent
89cfa38cfc
commit
6ffca34f8e
|
@ -32,6 +32,37 @@ func (ite IfdTagEntry) String() string {
|
|||
return fmt.Sprintf("IfdTagEntry<TAG-IFD=[%s] TAG-ID=(0x%02x) TAG-TYPE=[%s] UNIT-COUNT=(%d)>", ite.ChildIfdName, ite.TagId, TypeNames[ite.TagType], ite.UnitCount)
|
||||
}
|
||||
|
||||
// ValueString renders a string from whatever the value in this tag is.
|
||||
func (ite IfdTagEntry) ValueString(byteOrder binary.ByteOrder, addressableData []byte) (value string, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
vc := ValueContext{
|
||||
UnitCount: ite.UnitCount,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueRaw, err = UndefinedValue(ite.Ii, ite.TagId, vc, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
||||
value = fmt.Sprintf("%v", valueRaw)
|
||||
} else {
|
||||
tt := NewTagType(ite.TagType, byteOrder)
|
||||
|
||||
value, err = tt.ValueString(vc, false)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// ValueBytes renders a specific list of bytes from the value in this tag.
|
||||
func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteOrder) (value []byte, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
|
@ -39,6 +70,11 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||
}
|
||||
}()
|
||||
|
||||
// Return the exact bytes of the unknown-type value. Returning a string
|
||||
// (`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.
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueContext := ValueContext{
|
||||
UnitCount: ite.UnitCount,
|
||||
|
@ -88,6 +124,34 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||
return value, nil
|
||||
}
|
||||
|
||||
// Value returns the specific, parsed, typed value from the tag.
|
||||
func (ite IfdTagEntry) Value(byteOrder binary.ByteOrder, addressableData []byte) (value interface{}, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
vc := ValueContext{
|
||||
UnitCount: ite.UnitCount,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
value, err = UndefinedValue(ite.Ii, ite.TagId, vc, byteOrder)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
tt := NewTagType(ite.TagType, byteOrder)
|
||||
|
||||
value, err = tt.Resolve(vc)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
|
||||
// IfdTagEntryValueResolver instances know how to resolve the values for any
|
||||
// tag for a particular EXIF block.
|
||||
|
@ -108,6 +172,7 @@ func NewIfdTagEntryValueResolver(exifData []byte, byteOrder binary.ByteOrder) (i
|
|||
}
|
||||
}
|
||||
|
||||
// ValueBytes will resolve embedded or allocated data from the tag and return the raw bytes.
|
||||
func (itevr *IfdTagEntryValueResolver) ValueBytes(ite *IfdTagEntry) (value []byte, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
|
|
101
type.go
101
type.go
|
@ -416,8 +416,6 @@ func (tt TagType) ReadAsciiValue(valueContext ValueContext) (value string, err e
|
|||
} else {
|
||||
typeLogger.Debugf(nil, "Reading ASCII value (no-nul; at offset).")
|
||||
|
||||
fmt.Printf("Reading (%d) bytes of allocated ASCII from (%d) bytes of allocated data at offset (%d).\n", valueContext.UnitCount, len(valueContext.AddressableData), valueContext.ValueOffset)
|
||||
|
||||
value, err = tt.ParseAscii(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
@ -576,8 +574,8 @@ func (tt TagType) ValueString(valueContext ValueContext, justFirst bool) (value
|
|||
}
|
||||
}()
|
||||
|
||||
// TODO(dustin): Implement Value(), below.
|
||||
// valueRaw, err := tt.Value(valueContext)
|
||||
// TODO(dustin): Implement Resolve(), below.
|
||||
// valueRaw, err := tt.Resolve(valueContext)
|
||||
// log.PanicIf(err)
|
||||
|
||||
typeId := tt.Type()
|
||||
|
@ -676,59 +674,58 @@ func (tt TagType) ValueString(valueContext ValueContext, justFirst bool) (value
|
|||
}
|
||||
}
|
||||
|
||||
// // Value knows how to resolve the given value.
|
||||
// //
|
||||
// // 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()`.
|
||||
// Value knows how to resolve the given value.
|
||||
//
|
||||
// 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()`.
|
||||
func (tt TagType) Resolve(valueContext ValueContext) (value interface{}, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
// // TODO(dustin): !! Rename to Resolve() (to make clear that we're parsing not encoding)
|
||||
typeId := tt.Type()
|
||||
|
||||
// func (tt TagType) Value(valueContext ValueContext) (value interface{}, err error) {
|
||||
// defer func() {
|
||||
// if state := recover(); state != nil {
|
||||
// err = log.Wrap(state.(error))
|
||||
// }
|
||||
// }()
|
||||
if typeId == TypeByte {
|
||||
value, err = tt.ReadByteValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeAscii {
|
||||
value, err = tt.ReadAsciiValue(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeAsciiNoNul {
|
||||
value, err = tt.ReadAsciiNoNulValue(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeShort {
|
||||
value, err = tt.ReadShortValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeLong {
|
||||
value, err = tt.ReadLongValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeRational {
|
||||
value, err = tt.ReadRationalValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeSignedLong {
|
||||
value, err = tt.ReadSignedLongValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeSignedRational {
|
||||
value, err = tt.ReadSignedRationalValues(valueContext)
|
||||
log.PanicIf(err)
|
||||
} else if typeId == TypeUndefined {
|
||||
log.Panicf("will not parse unknown-type value: %v", tt)
|
||||
|
||||
// typeId := tt.Type()
|
||||
// Never called.
|
||||
return nil, nil
|
||||
} else {
|
||||
log.Panicf("value of type (%d) [%s] is unparseable", typeId, tt)
|
||||
|
||||
// if typeId == TypeByte {
|
||||
// value, err = tt.ReadByteValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeAscii {
|
||||
// value, err = tt.ReadAsciiValue(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeAsciiNoNul {
|
||||
// value, err = tt.ReadAsciiNoNulValue(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeShort {
|
||||
// value, err = tt.ReadShortValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeLong {
|
||||
// value, err = tt.ReadLongValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeRational {
|
||||
// value, err = tt.ReadRationalValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeSignedLong {
|
||||
// value, err = tt.ReadSignedLongValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeSignedRational {
|
||||
// value, err = tt.ReadSignedRationalValues(valueContext)
|
||||
// log.PanicIf(err)
|
||||
// } else if typeId == TypeUndefined {
|
||||
// log.Panicf("will not parse unknown-type value: %v", tt)
|
||||
// Never called.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// // Never called.
|
||||
// return "", nil
|
||||
// } else {
|
||||
// log.Panicf("value of type (%d) [%s] is unparseable", typeId, tt)
|
||||
|
||||
// // Never called.
|
||||
// return "", nil
|
||||
// }
|
||||
// }
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// ValueBytes knows how to encode the given value to a byte slice.
|
||||
|
||||
|
|
Loading…
Reference in New Issue