From b75f980bc456078b09344982045f0177796bcf21 Mon Sep 17 00:00:00 2001 From: Dustin Oprea Date: Thu, 3 May 2018 11:13:34 -0400 Subject: [PATCH] ifd_enumerate: Create II when `Ifd` is constructed. - ..rather than on-the-fly. Now efficient, especially now that it's used for find operations. --- ifd_builder.go | 8 +++++++- ifd_builder_test.go | 5 +++-- ifd_enumerate.go | 15 ++++++--------- tags.go | 4 ++-- tags_test.go | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ifd_builder.go b/ifd_builder.go index f70efd9..3889eb9 100644 --- a/ifd_builder.go +++ b/ifd_builder.go @@ -235,7 +235,13 @@ func NewIfdBuilder(ii IfdIdentity, byteOrder binary.ByteOrder) (ib *IfdBuilder) // information as the given IFD. func NewIfdBuilderWithExistingIfd(ifd *Ifd) (ib *IfdBuilder) { 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{ ii: ii, diff --git a/ifd_builder_test.go b/ifd_builder_test.go index 41406c7..d56d352 100644 --- a/ifd_builder_test.go +++ b/ifd_builder_test.go @@ -1162,14 +1162,15 @@ func TestNewIfdBuilderFromExistingChain(t *testing.T) { func TestNewIfdBuilderWithExistingIfd(t *testing.T) { - ii, _ := IfdIdOrFail(IfdStandard, IfdGps) - tagId := IfdTagIdWithIdentityOrFail(ii) + tagId := IfdTagIdWithIdentityOrFail(GpsIi) parentIfd := &Ifd{ + Ii: RootIi, Name: IfdStandard, } ifd := &Ifd{ + Ii: GpsIi, Name: IfdGps, ByteOrder: TestDefaultByteOrder, Offset: 0x123, diff --git a/ifd_enumerate.go b/ifd_enumerate.go index 2aff1e5..a6b8521 100644 --- a/ifd_enumerate.go +++ b/ifd_enumerate.go @@ -273,6 +273,8 @@ func (ie *IfdEnumerate) Scan(ifdOffset uint32, visitor TagVisitor) (err error) { type Ifd struct { ByteOrder binary.ByteOrder + Ii IfdIdentity + Id int ParentIfd *Ifd Name string @@ -347,15 +349,7 @@ func (ifd Ifd) String() string { } func (ifd Ifd) Identity() IfdIdentity { - parentIfdName := "" - 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 + return ifd.Ii } 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 + + name := ii.IfdName index := queue[0].Index offset := queue[0].Offset @@ -453,6 +449,7 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error ifd := Ifd{ ByteOrder: ie.byteOrder, + Ii: ii, Id: id, ParentIfd: parentIfd, Name: name, diff --git a/tags.go b/tags.go index 2de9643..50538eb 100644 --- a/tags.go +++ b/tags.go @@ -315,14 +315,14 @@ func IfdTagIdWithIdentityOrFail(ii IfdIdentity) (tagId uint16) { if tagId, found = tags[ii.IfdName]; found == true { if tagId == 0 { // 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 } } - log.Panicf("no tag for invalid IFD identity") + log.Panicf("no tag for invalid IFD identity: %v", ii) return 0 } diff --git a/tags_test.go b/tags_test.go index b2d45d1..50170e9 100644 --- a/tags_test.go +++ b/tags_test.go @@ -108,7 +108,7 @@ func TestIfdTagIdWithIdentityOrFail_Miss(t *testing.T) { defer func() { if state := recover(); state != nil { err := log.Wrap(state.(error)) - if err.Error() != "no tag for invalid IFD identity" { + if err.Error() != "no tag for invalid IFD identity: IfdIdentity" { log.Panic(err) } }