collect: Added a massive test for collected structure.

pull/3/head
Dustin Oprea 2018-04-19 01:02:03 -04:00
parent 679ea19d6c
commit 52dafd070a
3 changed files with 122 additions and 19 deletions

View File

@ -142,7 +142,7 @@ func (e *Exif) Visit(data []byte, visitor TagVisitor) (err error) {
return nil
}
func (e *Exif) Collect(data []byte) (rootIfd *Ifd, tree map[int]*Ifd, ifds []*Ifd, err error) {
func (e *Exif) Collect(data []byte) (index IfdIndex, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
@ -154,8 +154,8 @@ func (e *Exif) Collect(data []byte) (rootIfd *Ifd, tree map[int]*Ifd, ifds []*If
ie := NewIfdEnumerate(data, eh.ByteOrder)
rootIfd, tree, ifds, err = ie.Collect(eh.FirstIfdOffset)
index, err = ie.Collect(eh.FirstIfdOffset)
log.PanicIf(err)
return rootIfd, tree, ifds, nil
return index, nil
}

View File

@ -202,25 +202,102 @@ func TestCollect(t *testing.T) {
rawExif, err := e.SearchAndExtractExif(filepath)
log.PanicIf(err)
rootIfd, tree, ifds, err := e.Collect(rawExif)
index, err := e.Collect(rawExif)
log.PanicIf(err)
rootIfd = rootIfd
tree = tree
ifds = ifds
rootIfd := index.RootIfd
ifds := index.Ifds
tree := index.Tree
lookup := index.Lookup
if rootIfd.Offset != 0x0008 {
t.Fatalf("Root-IFD not correct: (0x%04d).", rootIfd)
} else if rootIfd.Id != 0 {
t.Fatalf("Root-IFD does not have the right ID: (%d)", rootIfd.Id)
} else if tree[0] != rootIfd {
t.Fatalf("Root-IFD is not indexed properly.")
} else if len(ifds) != 5 {
t.Fatalf("The IFD list is not the right size: (%d)", len(ifds))
} else if len(tree) != 5 {
t.Fatalf("The IFD tree is not the right size: (%d)", len(tree))
} else if len(lookup) != 4 {
t.Fatalf("The IFD lookup is not the right size: (%d)", len(lookup))
}
// TODO(dustin): !! Finish test.
if rootIfd.NextIfdOffset != 0x2c54 {
t.Fatalf("Root IFD does not continue correctly: (0x%04x)", rootIfd.NextIfdOffset)
} else if rootIfd.NextIfd.Offset != rootIfd.NextIfdOffset {
t.Fatalf("Root IFD neighbor object does not have the right offset: (0x%04x != 0x%04x)", rootIfd.NextIfd.Offset, rootIfd.NextIfdOffset)
} else if rootIfd.NextIfd.NextIfdOffset != 0 {
t.Fatalf("Root IFD chain not terminated correctly (1).")
} else if rootIfd.NextIfd.NextIfd != nil {
t.Fatalf("Root IFD chain not terminated correctly (2).")
}
if rootIfd.Name != IfdStandard {
t.Fatalf("Root IFD is not labeled correctly: [%s]", rootIfd.Name)
} else if rootIfd.NextIfd.Name != IfdStandard {
t.Fatalf("Root IFD sibling is not labeled correctly: [%s]", rootIfd.Name)
} else if rootIfd.Children[0].Name != IfdExif {
t.Fatalf("Root IFD child (0) is not labeled correctly: [%s]", rootIfd.Children[0].Name)
} else if rootIfd.Children[1].Name != IfdGps {
t.Fatalf("Root IFD child (1) is not labeled correctly: [%s]", rootIfd.Children[1].Name)
} else if rootIfd.Children[0].Children[0].Name != IfdIop {
t.Fatalf("Exif IFD child is not an IOP IFD: [%s]", rootIfd.Children[0].Children[0].Name)
}
// rootIfd.PrintTree()
if lookup[IfdStandard][0].Name != IfdStandard {
t.Fatalf("Lookup for standard IFD not correct.")
} else if lookup[IfdStandard][1].Name != IfdStandard {
t.Fatalf("Lookup for standard IFD not correct.")
} else if lookup[IfdExif][0].Name != IfdExif {
t.Fatalf("Lookup for EXIF IFD not correct.")
} else if lookup[IfdGps][0].Name != IfdGps {
t.Fatalf("Lookup for EXIF IFD not correct.")
} else if lookup[IfdIop][0].Name != IfdIop {
t.Fatalf("Lookup for EXIF IFD not correct.")
}
// expected := []string {
// }
foundExif := 0
foundGps := 0
for _, ite := range lookup[IfdStandard][0].Entries {
if ite.IfdName == IfdExif {
foundExif++
// if reflect.DeepEqual(tags, expected) == false {
// t.Fatalf("tags not correct:\n%v", tags)
// }
if IfdTags[ite.TagId] != IfdExif {
t.Fatalf("EXIF IFD tag-ID mismatch: (0x%02x) [%s] != [%s]", ite.TagId, IfdTags[ite.TagId], IfdExif)
}
}
if ite.IfdName == IfdGps {
foundGps++
if IfdTags[ite.TagId] != IfdGps {
t.Fatalf("EXIF GPS tag-ID mismatch: (0x%02x) [%s] != [%s]", ite.TagId, IfdTags[ite.TagId] != IfdGps)
}
}
}
if foundExif != 1 {
t.Fatalf("Exactly one EXIF IFD tag wasn't found: (%d)", foundExif)
} else if foundGps != 1 {
t.Fatalf("Exactly one GPS IFD tag wasn't found: (%d)", foundGps)
}
foundIop := 0
for _, ite := range lookup[IfdExif][0].Entries {
if ite.IfdName == IfdIop {
foundIop++
if IfdTags[ite.TagId] != IfdIop {
t.Fatalf("IOP IFD tag-ID mismatch: (0x%02x) [%s] != [%s]", ite.TagId, IfdTags[ite.TagId], IfdIop)
}
}
}
if foundIop != 1 {
t.Fatalf("Exactly one IOP IFD tag wasn't found: (%d)", foundIop)
}
}
func init() {

View File

@ -305,16 +305,26 @@ type QueuedIfd struct {
Parent *Ifd
}
type IfdIndex struct {
RootIfd *Ifd
Ifds []*Ifd
Tree map[int]*Ifd
Lookup map[string][]*Ifd
}
// Scan enumerates the different EXIF blocks (called IFDs).
func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (rootIfd *Ifd, tree map[int]*Ifd, ifds []*Ifd, err error) {
func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (index IfdIndex, err error) {
defer func() {
if state := recover(); state != nil {
err = log.Wrap(state.(error))
}
}()
tree = make(map[int]*Ifd)
ifds = make([]*Ifd, 0)
tree := make(map[int]*Ifd)
ifds := make([]*Ifd, 0)
lookup := make(map[string][]*Ifd)
queue := []QueuedIfd {
{
@ -357,9 +367,20 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (rootIfd *Ifd, tree map[in
// Add ourselves to a big list of IFDs.
ifds = append(ifds, &ifd)
// Install ourselves into a lookup table.
// Install ourselves into a by-id lookup table (keys are unique).
tree[id] = &ifd
// Install into by-name buckets.
if list_, found := lookup[name]; found == true {
lookup[name] = append(list_, &ifd)
} else {
list_ = make([]*Ifd, 1)
list_[0] = &ifd
lookup[name] = list_
}
// Add a link from the previous IFD in the chain to us.
if previousIfd, found := edges[offset]; found == true {
previousIfd.NextIfd = &ifd
@ -402,5 +423,10 @@ func (ie *IfdEnumerate) Collect(rootIfdOffset uint32) (rootIfd *Ifd, tree map[in
}
}
return tree[0], tree, ifds, nil
index.RootIfd = tree[0]
index.Ifds = ifds
index.Tree = tree
index.Lookup = lookup
return index, nil
}