ifd_enumerate: Create II when Ifd is constructed.

- ..rather than on-the-fly. Now efficient, especially now that it's used
  for find operations.
This commit is contained in:
Dustin Oprea 2018-05-03 11:13:34 -04:00
parent 8c09d04212
commit b75f980bc4
5 changed files with 19 additions and 15 deletions

View File

@ -235,7 +235,13 @@ func NewIfdBuilder(ii IfdIdentity, byteOrder binary.ByteOrder) (ib *IfdBuilder)
// information as the given IFD. // information as the given IFD.
func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) { func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) {
ii := ifd.Identity() ii := ifd.Identity()
ifdTagId := IfdTagIdWithIdentityOrFail(ii)
var ifdTagId uint16
// There is no tag-ID for the root IFD. It will never be a child IFD.
if ii != RootIi {
ifdTagId = IfdTagIdWithIdentityOrFail(ii)
}
ib = &IfdBuilder{ ib = &IfdBuilder{
ii: ii, ii: ii,

View File

@ -1162,14 +1162,15 @@ func TestNewIfdBuilderFromExistingChain(t *testing.T) {
func TestNewIfdBuilderWithExistingIfd(t *testing.T) { func TestNewIfdBuilderWithExistingIfd(t *testing.T) {
ii, _ := IfdIdOrFail(IfdStandard, IfdGps) tagId := IfdTagIdWithIdentityOrFail(GpsIi)
tagId := IfdTagIdWithIdentityOrFail(ii)
parentIfd := &Ifd{ parentIfd := &Ifd{
Ii: RootIi,
Name: IfdStandard, Name: IfdStandard,
} }
ifd := &Ifd{ ifd := &Ifd{
Ii: GpsIi,
Name: IfdGps, Name: IfdGps,
ByteOrder: TestDefaultByteOrder, ByteOrder: TestDefaultByteOrder,
Offset: 0x123, Offset: 0x123,

View File

@ -273,6 +273,8 @@ func (ie *IfdEnumerate) Scan(ifdOffset uint32, visitor TagVisitor) (err error) {
type Ifd struct { type Ifd struct {
ByteOrder binary.ByteOrder ByteOrder binary.ByteOrder
Ii IfdIdentity
Id int Id int
ParentIfd *Ifd ParentIfd *Ifd
Name string Name string
@ -347,15 +349,7 @@ func (ifd Ifd) String() string {
} }
func (ifd Ifd) Identity() IfdIdentity { func (ifd Ifd) Identity() IfdIdentity {
parentIfdName := "" return ifd.Ii
if ifd.ParentIfd != nil {
parentIfdName = ifd.ParentIfd.Name
}
// TODO(dustin): !! We should be checking using the parent ID, not the parent name.
ii, _ := IfdIdOrFail(parentIfdName, ifd.Name)
return ii
} }
func (ifd Ifd) printNode(level int, nextLink bool) { func (ifd Ifd) printNode(level int, nextLink bool) {
@ -426,6 +420,8 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
} }
ii := queue[0].Ii ii := queue[0].Ii
name := ii.IfdName name := ii.IfdName
index := queue[0].Index index := queue[0].Index
offset := queue[0].Offset offset := queue[0].Offset
@ -453,6 +449,7 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error
ifd := Ifd{ ifd := Ifd{
ByteOrder: ie.byteOrder, ByteOrder: ie.byteOrder,
Ii: ii,
Id: id, Id: id,
ParentIfd: parentIfd, ParentIfd: parentIfd,
Name: name, Name: name,

View File

@ -315,14 +315,14 @@ func IfdTagIdWithIdentityOrFail(ii IfdIdentity) (tagId uint16) {
if tagId, found = tags[ii.IfdName]; found == true { if tagId, found = tags[ii.IfdName]; found == true {
if tagId == 0 { if tagId == 0 {
// This IFD is not the type that can be linked to from a tag. // This IFD is not the type that can be linked to from a tag.
log.Panicf("not a child IFD") log.Panicf("not a child IFD: [%s]", ii.IfdName)
} }
return tagId return tagId
} }
} }
log.Panicf("no tag for invalid IFD identity") log.Panicf("no tag for invalid IFD identity: %v", ii)
return 0 return 0
} }

View File

@ -108,7 +108,7 @@ func TestIfdTagIdWithIdentityOrFail_Miss(t *testing.T) {
defer func() { defer func() {
if state := recover(); state != nil { if state := recover(); state != nil {
err := log.Wrap(state.(error)) err := log.Wrap(state.(error))
if err.Error() != "no tag for invalid IFD identity" { if err.Error() != "no tag for invalid IFD identity: IfdIdentity<PARENT-NAME=[invalid-parent] NAME=[invalid-child]>" {
log.Panic(err) log.Panic(err)
} }
} }