From 383780b3d8cee1149b85f8994483c9ea9b483098 Mon Sep 17 00:00:00 2001 From: Dustin Oprea Date: Wed, 25 Apr 2018 11:51:08 -0400 Subject: [PATCH] ifd_builder_encode: Began writing tests. Began with encodeTagToBytes. More tests to go. --- ifd_builder_encode_test.go | 144 +++++++++++++++++++++++++++++++++++++ utility.go | 14 ++++ 2 files changed, 158 insertions(+) create mode 100644 utility.go diff --git a/ifd_builder_encode_test.go b/ifd_builder_encode_test.go index 81e641e..70f9e35 100644 --- a/ifd_builder_encode_test.go +++ b/ifd_builder_encode_test.go @@ -167,3 +167,147 @@ func Test_IfdDataAllocator_Allocate_InitialOffset2(t *testing.T) { t.Fatalf("buffer not correct after write (2)") } } + + +func Test_IfdByteEncoder__Arithmetic(t *testing.T) { + ibe := NewIfdByteEncoder() + + if (ibe.TableSize(1) - ibe.TableSize(0)) != ibe.EntrySize() { + t.Fatalf("table-size/entry-size not consistent (1)") + } else if (ibe.TableSize(11) - ibe.TableSize(10)) != ibe.EntrySize() { + t.Fatalf("table-size/entry-size not consistent (2)") + } +} + +func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) { + ibe := NewIfdByteEncoder() + + ib := &IfdBuilder{ + ifdName: IfdGps, + } + + bt := &builderTag{ + tagId: 0x0000, + value: NewIfdBuilderTagValueFromBytes([]byte { 0x12 }), + } + + b := new(bytes.Buffer) + bw := NewByteWriter(b, binary.BigEndian) + + addressableOffset := uint32(0x1234) + ida := newIfdDataAllocator(addressableOffset) + +// TODO(dustin): !! Test with and without nextIfdOffsetToWrite. +// TODO(dustin): !! Generating a BT properly and testing here for every type. Make sure everythign is properly encoded as slices. + childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) + log.PanicIf(err) + + if childIfdBlock != nil { + t.Fatalf("no child-IFDs were expected to be allocated") + } else if bytes.Compare(b.Bytes(), []byte { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00 }) != 0 { + t.Fatalf("encoded tag-entry bytes not correct") + } else if ida.NextOffset() != addressableOffset { + t.Fatalf("allocation were done but not expected") + } +} + +func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded2(t *testing.T) { + ibe := NewIfdByteEncoder() + + ib := &IfdBuilder{ + ifdName: IfdGps, + } + + bt := &builderTag{ + tagId: 0x0000, + value: NewIfdBuilderTagValueFromBytes([]byte { 0x12, 0x34, 0x56, 0x78 }), + } + + b := new(bytes.Buffer) + bw := NewByteWriter(b, binary.BigEndian) + + addressableOffset := uint32(0x1234) + ida := newIfdDataAllocator(addressableOffset) + +// TODO(dustin): !! Test with and without nextIfdOffsetToWrite. +// TODO(dustin): !! Generating a BT properly and testing here for every type. Make sure everythign is properly encoded as slices. + childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) + log.PanicIf(err) + + if childIfdBlock != nil { + t.Fatalf("no child-IFDs were expected to be allocated") + } else if bytes.Compare(b.Bytes(), []byte { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78 }) != 0 { + t.Fatalf("encoded tag-entry bytes not correct") + } else if ida.NextOffset() != addressableOffset { + t.Fatalf("allocation were done but not expected") + } +} + +func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) { + ibe := NewIfdByteEncoder() + + ib := &IfdBuilder{ + ifdName: IfdGps, + } + + b := new(bytes.Buffer) + bw := NewByteWriter(b, binary.BigEndian) + + addressableOffset := uint32(0x1234) + ida := newIfdDataAllocator(addressableOffset) + + bt := &builderTag{ + tagId: 0x0000, + value: NewIfdBuilderTagValueFromBytes([]byte { 0x12, 0x34, 0x56, 0x78, 0x9A }), + } + +// TODO(dustin): !! Test with and without nextIfdOffsetToWrite. +// TODO(dustin): !! Generating a BT properly and testing here for every type. Make sure everythign is properly encoded as slices. + childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) + log.PanicIf(err) + + if childIfdBlock != nil { + t.Fatalf("no child-IFDs were expected to be allocated (1)") + } else if bytes.Compare(b.Bytes(), []byte { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x12, 0x34 }) != 0 { + t.Fatalf("encoded tag-entry bytes not correct (1)") + } else if ida.NextOffset() != addressableOffset + uint32(5) { + t.Fatalf("allocation offset not expected (1)") + } else if bytes.Compare(ida.Bytes(), []byte { 0x12, 0x34, 0x56, 0x78, 0x9A }) != 0 { + t.Fatalf("allocated data not correct (1)") + } + + // Test that another allocation encodes to the new offset. + + bt = &builderTag{ + tagId: 0x0000, + value: NewIfdBuilderTagValueFromBytes([]byte { 0xbc, 0xde, 0xf0, 0x12, 0x34 }), + } + +// TODO(dustin): !! Test with and without nextIfdOffsetToWrite. +// TODO(dustin): !! Generating a BT properly and testing here for every type. Make sure everythign is properly encoded as slices. + childIfdBlock, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0)) + log.PanicIf(err) + + if childIfdBlock != nil { + t.Fatalf("no child-IFDs were expected to be allocated (2)") + } else if bytes.Compare(b.Bytes(), []byte { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x12, 0x34, // Tag 1 + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x12, 0x39, // Tag 2 + }) != 0 { + t.Fatalf("encoded tag-entry bytes not correct (2)") + } else if ida.NextOffset() != addressableOffset + uint32(10) { + t.Fatalf("allocation offset not expected (2)") + } else if bytes.Compare(ida.Bytes(), []byte { + 0x12, 0x34, 0x56, 0x78, 0x9A, + 0xbc, 0xde, 0xf0, 0x12, 0x34, + }) != 0 { + t.Fatalf("allocated data not correct (2)") + } +} + +// TODO(dustin): !! Test all types. +// TODO(dustin): !! Test specific unknown-type tags. +// TODO(dustin): !! Test what happens with unhandled unknown-type tags (though it should never get to this point in the normal workflow). +// TODO(dustin): !! Test child IFDs (may not be possible until after writing tests for higher-level IB encode). + + diff --git a/utility.go b/utility.go new file mode 100644 index 0000000..8e65316 --- /dev/null +++ b/utility.go @@ -0,0 +1,14 @@ +package exif + +import ( + "fmt" +) + +func DumpBytes(data []byte) { + fmt.Printf("DUMP: ") + for _, x := range data { + fmt.Printf("%02x ", x) + } + + fmt.Printf("\n") +}