mirror of https://github.com/dsoprea/go-exif.git
value_context.go: `ValueContext` now wraps members in accessors
It also embeds the type and byte-order so the VC can materialize/process values self-sufficiently.pull/28/head
parent
a69c3987eb
commit
7fb09bbf9f
|
@ -131,7 +131,7 @@ func main() {
|
|||
TagName: it.Name,
|
||||
TagTypeId: tagType.Type(),
|
||||
TagTypeName: tagType.Name(),
|
||||
UnitCount: valueContext.UnitCount,
|
||||
UnitCount: valueContext.UnitCount(),
|
||||
Value: value,
|
||||
ValueString: valueString,
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ func TestVisit(t *testing.T) {
|
|||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
description := fmt.Sprintf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]", ifdPath, tagId, it.Name, valueContext.UnitCount, tagType.Name(), valueString)
|
||||
description := fmt.Sprintf("IFD-PATH=[%s] ID=(0x%04x) NAME=[%s] COUNT=(%d) TYPE=[%s] VALUE=[%s]", ifdPath, tagId, it.Name, valueContext.UnitCount(), tagType.Name(), valueString)
|
||||
tags = append(tags, description)
|
||||
|
||||
return nil
|
||||
|
|
|
@ -233,12 +233,15 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
|
|||
// (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,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
valueContext :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
ie.byteOrder,
|
||||
)
|
||||
|
||||
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, ie.byteOrder)
|
||||
if err != nil {
|
||||
|
@ -338,12 +341,14 @@ func (ie *IfdEnumerate) ParseIfd(fqIfdPath string, ifdIndex int, ite *IfdTagEnum
|
|||
if visitor != nil {
|
||||
tt := NewTagType(tag.TagType, ie.byteOrder)
|
||||
|
||||
vc := ValueContext{
|
||||
UnitCount: tag.UnitCount,
|
||||
ValueOffset: tag.ValueOffset,
|
||||
RawValueOffset: tag.RawValueOffset,
|
||||
AddressableData: ie.exifData[ExifAddressableAreaStart:],
|
||||
}
|
||||
vc :=
|
||||
newValueContext(
|
||||
tag.UnitCount,
|
||||
tag.ValueOffset,
|
||||
tag.RawValueOffset,
|
||||
ie.exifData[ExifAddressableAreaStart:],
|
||||
tag.TagType,
|
||||
ie.byteOrder)
|
||||
|
||||
err := visitor(fqIfdPath, ifdIndex, tag.TagId, tt, vc)
|
||||
log.PanicIf(err)
|
||||
|
|
|
@ -55,12 +55,14 @@ func (ite IfdTagEntry) ValueString(addressableData []byte, byteOrder binary.Byte
|
|||
}
|
||||
}()
|
||||
|
||||
vc := ValueContext{
|
||||
UnitCount: ite.UnitCount,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
vc :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
byteOrder)
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
valueRaw, err := UndefinedValue(ite.IfdPath, ite.TagId, vc, byteOrder)
|
||||
|
@ -91,12 +93,14 @@ func (ite IfdTagEntry) ValueBytes(addressableData []byte, byteOrder binary.ByteO
|
|||
// (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,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
valueContext :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
byteOrder)
|
||||
|
||||
value, err := UndefinedValue(ite.IfdPath, ite.TagId, valueContext, byteOrder)
|
||||
log.PanicIf(err)
|
||||
|
@ -150,12 +154,14 @@ func (ite IfdTagEntry) Value(addressableData []byte, byteOrder binary.ByteOrder)
|
|||
}
|
||||
}()
|
||||
|
||||
vc := ValueContext{
|
||||
UnitCount: ite.UnitCount,
|
||||
ValueOffset: ite.ValueOffset,
|
||||
RawValueOffset: ite.RawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
}
|
||||
vc :=
|
||||
newValueContext(
|
||||
ite.UnitCount,
|
||||
ite.ValueOffset,
|
||||
ite.RawValueOffset,
|
||||
addressableData,
|
||||
ite.TagType,
|
||||
byteOrder)
|
||||
|
||||
if ite.TagType == TypeUndefined {
|
||||
value, err = UndefinedValue(ite.IfdPath, ite.TagId, vc, byteOrder)
|
||||
|
|
88
type.go
88
type.go
|
@ -158,11 +158,11 @@ func (tt TagType) readRawEncoded(valueContext ValueContext) (rawBytes []byte, er
|
|||
|
||||
unitSizeRaw := uint32(tt.tagType.Size())
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
byteLength := unitSizeRaw * valueContext.UnitCount
|
||||
return valueContext.RawValueOffset[:byteLength], nil
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
byteLength := unitSizeRaw * valueContext.UnitCount()
|
||||
return valueContext.RawValueOffset()[:byteLength], nil
|
||||
} else {
|
||||
return valueContext.AddressableData[valueContext.ValueOffset : valueContext.ValueOffset+valueContext.UnitCount*unitSizeRaw], nil
|
||||
return valueContext.AddressableData()[valueContext.ValueOffset() : valueContext.ValueOffset()+valueContext.UnitCount()*unitSizeRaw], nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,21 +409,21 @@ func (tt TagType) ReadByteValues(valueContext ValueContext) (value []byte, err e
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading BYTE value (embedded).")
|
||||
|
||||
// In this case, the bytes normally used for the offset are actually
|
||||
// data.
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseBytes(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseBytes(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading BYTE value (at offset).")
|
||||
|
||||
value, err = tt.ParseBytes(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseBytes(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -437,18 +437,18 @@ func (tt TagType) ReadAsciiValue(valueContext ValueContext) (value string, err e
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading ASCII value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseAscii(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseAscii(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading ASCII value (at offset).")
|
||||
|
||||
value, err = tt.ParseAscii(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseAscii(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -462,18 +462,18 @@ func (tt TagType) ReadAsciiNoNulValue(valueContext ValueContext) (value string,
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading ASCII value (no-nul; embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseAsciiNoNul(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseAsciiNoNul(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading ASCII value (no-nul; at offset).")
|
||||
|
||||
value, err = tt.ParseAsciiNoNul(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseAsciiNoNul(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -487,18 +487,18 @@ func (tt TagType) ReadShortValues(valueContext ValueContext) (value []uint16, er
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading SHORT value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseShorts(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseShorts(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading SHORT value (at offset).")
|
||||
|
||||
value, err = tt.ParseShorts(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseShorts(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -512,18 +512,18 @@ func (tt TagType) ReadLongValues(valueContext ValueContext) (value []uint32, err
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading LONG value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseLongs(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseLongs(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading LONG value (at offset).")
|
||||
|
||||
value, err = tt.ParseLongs(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseLongs(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -537,18 +537,18 @@ func (tt TagType) ReadRationalValues(valueContext ValueContext) (value []Rationa
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading RATIONAL value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseRationals(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseRationals(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading RATIONAL value (at offset).")
|
||||
|
||||
value, err = tt.ParseRationals(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseRationals(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -562,18 +562,18 @@ func (tt TagType) ReadSignedLongValues(valueContext ValueContext) (value []int32
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading SLONG value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseSignedLongs(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseSignedLongs(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading SLONG value (at offset).")
|
||||
|
||||
value, err = tt.ParseSignedLongs(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseSignedLongs(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
@ -587,18 +587,18 @@ func (tt TagType) ReadSignedRationalValues(valueContext ValueContext) (value []S
|
|||
}
|
||||
}()
|
||||
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount) == true {
|
||||
if tt.valueIsEmbedded(valueContext.UnitCount()) == true {
|
||||
typeLogger.Debugf(nil, "Reading SRATIONAL value (embedded).")
|
||||
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount
|
||||
rawValue := valueContext.RawValueOffset[:byteLength]
|
||||
byteLength := uint32(tt.tagType.Size()) * valueContext.UnitCount()
|
||||
rawValue := valueContext.RawValueOffset()[:byteLength]
|
||||
|
||||
value, err = tt.ParseSignedRationals(rawValue, valueContext.UnitCount)
|
||||
value, err = tt.ParseSignedRationals(rawValue, valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
typeLogger.Debugf(nil, "Reading SRATIONAL value (at offset).")
|
||||
|
||||
value, err = tt.ParseSignedRationals(valueContext.AddressableData[valueContext.ValueOffset:], valueContext.UnitCount)
|
||||
value, err = tt.ParseSignedRationals(valueContext.AddressableData()[valueContext.ValueOffset():], valueContext.UnitCount())
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,45 @@
|
|||
package exif
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// ValueContext describes all of the parameters required to find and extract
|
||||
// the actual tag value.
|
||||
type ValueContext struct {
|
||||
UnitCount uint32
|
||||
ValueOffset uint32
|
||||
RawValueOffset []byte
|
||||
AddressableData []byte
|
||||
unitCount uint32
|
||||
valueOffset uint32
|
||||
rawValueOffset []byte
|
||||
addressableData []byte
|
||||
|
||||
tagType TagTypePrimitive
|
||||
byteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
func newValueContext(unitCount, valueOffset uint32, rawValueOffset, addressableData []byte) ValueContext {
|
||||
func (vc ValueContext) UnitCount() uint32 {
|
||||
return vc.unitCount
|
||||
}
|
||||
|
||||
func (vc ValueContext) ValueOffset() uint32 {
|
||||
return vc.valueOffset
|
||||
}
|
||||
|
||||
func (vc ValueContext) RawValueOffset() []byte {
|
||||
return vc.rawValueOffset
|
||||
}
|
||||
|
||||
func (vc ValueContext) AddressableData() []byte {
|
||||
return vc.addressableData
|
||||
}
|
||||
|
||||
func newValueContext(unitCount, valueOffset uint32, rawValueOffset, addressableData []byte, tagType TagTypePrimitive, byteOrder binary.ByteOrder) ValueContext {
|
||||
return ValueContext{
|
||||
UnitCount: unitCount,
|
||||
ValueOffset: valueOffset,
|
||||
RawValueOffset: rawValueOffset,
|
||||
AddressableData: addressableData,
|
||||
unitCount: unitCount,
|
||||
valueOffset: valueOffset,
|
||||
rawValueOffset: rawValueOffset,
|
||||
addressableData: addressableData,
|
||||
|
||||
tagType: tagType,
|
||||
byteOrder: byteOrder,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue