mirror of https://github.com/dsoprea/go-exif.git
ifd_builder: `builderTag` is now passed by reference.
parent
0a561e98ed
commit
abbf7e0d92
127
ifd_builder.go
127
ifd_builder.go
|
@ -97,8 +97,8 @@ type builderTag struct {
|
|||
value *IfdBuilderTagValue
|
||||
}
|
||||
|
||||
func NewBuilderTag(ii IfdIdentity, tagId uint16, typeId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
return builderTag{
|
||||
func NewBuilderTag(ii IfdIdentity, tagId uint16, typeId uint16, value *IfdBuilderTagValue) *builderTag {
|
||||
return &builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: typeId,
|
||||
|
@ -106,13 +106,13 @@ func NewBuilderTag(ii IfdIdentity, tagId uint16, typeId uint16, value *IfdBuilde
|
|||
}
|
||||
}
|
||||
|
||||
func NewStandardBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
func NewStandardBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) *builderTag {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(ii, tagId)
|
||||
log.PanicIf(err)
|
||||
|
||||
return builderTag{
|
||||
return &builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: it.Type,
|
||||
|
@ -120,8 +120,8 @@ func NewStandardBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagVal
|
|||
}
|
||||
}
|
||||
|
||||
func NewChildIfdBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) builderTag {
|
||||
return builderTag{
|
||||
func NewChildIfdBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagValue) *builderTag {
|
||||
return &builderTag{
|
||||
ii: ii,
|
||||
tagId: tagId,
|
||||
typeId: TypeLong,
|
||||
|
@ -129,17 +129,47 @@ func NewChildIfdBuilderTag(ii IfdIdentity, tagId uint16, value *IfdBuilderTagVal
|
|||
}
|
||||
}
|
||||
|
||||
func (bt builderTag) Value() (value *IfdBuilderTagValue) {
|
||||
func (bt *builderTag) Value() (value *IfdBuilderTagValue) {
|
||||
return bt.value
|
||||
}
|
||||
|
||||
func (bt builderTag) String() string {
|
||||
func (bt *builderTag) String() string {
|
||||
return fmt.Sprintf("BuilderTag<IFD=[%s] TAG-ID=(0x%04x) TAG-TYPE=[%s] VALUE=[%s]>", bt.ii, bt.tagId, TypeNames[bt.typeId], bt.value)
|
||||
}
|
||||
|
||||
func (bt *builderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO(dustin): !! Add test.
|
||||
|
||||
tt := NewTagType(bt.typeId, byteOrder)
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
|
||||
var ed EncodedData
|
||||
if bt.typeId == TypeUndefined {
|
||||
var err error
|
||||
|
||||
ed, err = EncodeUndefined(bt.ii, bt.tagId, value)
|
||||
log.PanicIf(err)
|
||||
} else {
|
||||
var err error
|
||||
|
||||
ed, err = ve.EncodeWithType(tt, value)
|
||||
log.PanicIf(err)
|
||||
}
|
||||
|
||||
bt.value = NewIfdBuilderTagValueFromBytes(ed.Encoded)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewStandardBuilderTagFromConfig constructs a `builderTag` instance. The type
|
||||
// is looked up. `ii` is the type of IFD that owns this tag.
|
||||
func NewStandardBuilderTagFromConfig(ii IfdIdentity, tagId uint16, byteOrder binary.ByteOrder, value interface{}) builderTag {
|
||||
func NewStandardBuilderTagFromConfig(ii IfdIdentity, tagId uint16, byteOrder binary.ByteOrder, value interface{}) *builderTag {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.Get(ii, tagId)
|
||||
|
@ -174,7 +204,7 @@ func NewStandardBuilderTagFromConfig(ii IfdIdentity, tagId uint16, byteOrder bin
|
|||
|
||||
// NewStandardBuilderTagFromConfig constructs a `builderTag` instance. The type is
|
||||
// explicitly provided. `ii` is the type of IFD that owns this tag.
|
||||
func NewBuilderTagFromConfig(ii IfdIdentity, tagId uint16, typeId uint16, byteOrder binary.ByteOrder, value interface{}) builderTag {
|
||||
func NewBuilderTagFromConfig(ii IfdIdentity, tagId uint16, typeId uint16, byteOrder binary.ByteOrder, value interface{}) *builderTag {
|
||||
tt := NewTagType(typeId, byteOrder)
|
||||
|
||||
ve := NewValueEncoder(byteOrder)
|
||||
|
@ -204,7 +234,7 @@ func NewBuilderTagFromConfig(ii IfdIdentity, tagId uint16, typeId uint16, byteOr
|
|||
// NewStandardBuilderTagFromConfigWithName allows us to easily generate solid, consistent tags
|
||||
// for testing with. `ii` is the type of IFD that owns this tag. This can not be
|
||||
// an IFD (IFDs are not associated with standardized, official names).
|
||||
func NewStandardBuilderTagFromConfigWithName(ii IfdIdentity, tagName string, byteOrder binary.ByteOrder, value interface{}) builderTag {
|
||||
func NewStandardBuilderTagFromConfigWithName(ii IfdIdentity, tagName string, byteOrder binary.ByteOrder, value interface{}) *builderTag {
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.GetWithName(ii, tagName)
|
||||
|
@ -247,7 +277,7 @@ type IfdBuilder struct {
|
|||
byteOrder binary.ByteOrder
|
||||
|
||||
// Includes both normal tags and IFD tags (which point to child IFDs).
|
||||
tags []builderTag
|
||||
tags []*builderTag
|
||||
|
||||
// existingOffset will be the offset that this IFD is currently found at if
|
||||
// it represents an IFD that has previously been stored (or 0 if not).
|
||||
|
@ -272,7 +302,7 @@ func NewIfdBuilder(ii IfdIdentity, byteOrder binary.ByteOrder) (ib *IfdBuilder)
|
|||
ifdTagId: ifdTagId,
|
||||
|
||||
byteOrder: byteOrder,
|
||||
tags: make([]builderTag, 0),
|
||||
tags: make([]*builderTag, 0),
|
||||
}
|
||||
|
||||
return ib
|
||||
|
@ -337,7 +367,7 @@ func (ib *IfdBuilder) String() string {
|
|||
return fmt.Sprintf("IfdBuilder<PARENT-IFD=[%s] IFD=[%s] TAG-ID=(0x%04x) COUNT=(%d) OFF=(0x%04x) NEXT-IFD=(0x%04x)>", ib.ii.ParentIfdName, ib.ii.IfdName, ib.ifdTagId, len(ib.tags), ib.existingOffset, nextIfdPhrase)
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) Tags() (tags []builderTag) {
|
||||
func (ib *IfdBuilder) Tags() (tags []*builderTag) {
|
||||
return ib.tags
|
||||
}
|
||||
|
||||
|
@ -612,7 +642,7 @@ func (ib *IfdBuilder) DeleteAll(tagId uint16) (n int, err error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) ReplaceAt(position int, bt builderTag) (err error) {
|
||||
func (ib *IfdBuilder) ReplaceAt(position int, bt *builderTag) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -630,7 +660,7 @@ func (ib *IfdBuilder) ReplaceAt(position int, bt builderTag) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) Replace(tagId uint16, bt builderTag) (err error) {
|
||||
func (ib *IfdBuilder) Replace(tagId uint16, bt *builderTag) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -646,7 +676,7 @@ func (ib *IfdBuilder) Replace(tagId uint16, bt builderTag) (err error) {
|
|||
}
|
||||
|
||||
// Set will add a new entry or update an existing entry.
|
||||
func (ib *IfdBuilder) Set(bt builderTag) (err error) {
|
||||
func (ib *IfdBuilder) Set(bt *builderTag) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -704,7 +734,50 @@ func (ib *IfdBuilder) Find(tagId uint16) (position int, err error) {
|
|||
return found[0], nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) add(bt builderTag) (err error) {
|
||||
func (ib *IfdBuilder) FindTag(tagId uint16) (bt *builderTag, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
found, err := ib.FindN(tagId, 1)
|
||||
log.PanicIf(err)
|
||||
|
||||
if len(found) == 0 {
|
||||
log.Panic(ErrTagEntryNotFound)
|
||||
}
|
||||
|
||||
position := found[0]
|
||||
|
||||
return ib.tags[position], nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) FindTagWithName(tagName string) (bt *builderTag, err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
}
|
||||
}()
|
||||
|
||||
ti := NewTagIndex()
|
||||
|
||||
it, err := ti.GetWithName(ib.ii, tagName)
|
||||
log.PanicIf(err)
|
||||
|
||||
found, err := ib.FindN(it.Id, 1)
|
||||
log.PanicIf(err)
|
||||
|
||||
if len(found) == 0 {
|
||||
log.Panic(ErrTagEntryNotFound)
|
||||
}
|
||||
|
||||
position := found[0]
|
||||
|
||||
return ib.tags[position], nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) add(bt *builderTag) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -723,7 +796,7 @@ func (ib *IfdBuilder) add(bt builderTag) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) Add(bt builderTag) (err error) {
|
||||
func (ib *IfdBuilder) Add(bt *builderTag) (err error) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err = log.Wrap(state.(error))
|
||||
|
@ -769,7 +842,7 @@ func (ib *IfdBuilder) AddChildIb(childIb *IfdBuilder) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ib *IfdBuilder) NewBuilderTagFromBuilder(childIb *IfdBuilder) (bt builderTag) {
|
||||
func (ib *IfdBuilder) NewBuilderTagFromBuilder(childIb *IfdBuilder) (bt *builderTag) {
|
||||
defer func() {
|
||||
if state := recover(); state != nil {
|
||||
err := log.Wrap(state.(error))
|
||||
|
@ -799,27 +872,15 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
|||
|
||||
thumbnailData, err := ifd.Thumbnail()
|
||||
if err == nil {
|
||||
|
||||
// TODO(dustin): The thumbnail tags will be added out of order.
|
||||
|
||||
// TODO(dustin): !! Debugging.
|
||||
// fmt.Printf("Importing thumbnail: %s\n", ifd.Identity())
|
||||
|
||||
err = ib.SetThumbnail(thumbnailData)
|
||||
log.PanicIf(err)
|
||||
} else if log.Is(err, ErrNoThumbnail) == false {
|
||||
log.Panic(err)
|
||||
} else {
|
||||
|
||||
// TODO(dustin): !! Debugging.
|
||||
// fmt.Printf("NO THUMBNAIL FOUND: %s\n", ifd.Identity())
|
||||
|
||||
}
|
||||
|
||||
for i, ite := range ifd.Entries {
|
||||
if ite.TagId == ThumbnailOffsetTagId || ite.TagId == ThumbnailSizeTagId {
|
||||
// These will be added on-the-fly when we encode.
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -853,7 +914,7 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
|
|||
}
|
||||
}
|
||||
|
||||
var bt builderTag
|
||||
var bt *builderTag
|
||||
|
||||
if ite.ChildIfdName != "" {
|
||||
// If we want to add an IFD tag, we'll have to build it first and
|
||||
|
|
|
@ -336,7 +336,7 @@ func (ibe *IfdByteEncoder) encodeIfdToBytes(ib *IfdBuilder, ifdAddressableOffset
|
|||
// we can't parse will not be present here (using AddTagsFromExisting(), at
|
||||
// least).
|
||||
for _, bt := range ib.tags {
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, nextIfdOffsetToWrite)
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite)
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
|
|
@ -200,7 +200,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded1(t *testing.T) {
|
|||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
@ -225,7 +225,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_embedded2(t *testing.T) {
|
|||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
@ -250,7 +250,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
|
|||
|
||||
bt := NewStandardBuilderTagFromConfig(GpsIi, uint16(0x0000), TestDefaultByteOrder, []uint8 { uint8(0x12), uint8(0x34), uint8(0x56), uint8(0x78), uint8(0x9a) })
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
@ -267,7 +267,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_bytes_allocated(t *testing.T) {
|
|||
|
||||
bt = NewStandardBuilderTagFromConfig(GpsIi, uint16(0x0000), TestDefaultByteOrder, []uint8 { uint8(0xbc), uint8(0xde), uint8(0xf0), uint8(0x12), uint8(0x34) })
|
||||
|
||||
childIfdBlock, err = ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
childIfdBlock, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
@ -303,7 +303,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withoutAllocate(t *testing.T
|
|||
bt := NewChildIfdBuilderTag(RootIi, IfdExifId, tagValue)
|
||||
|
||||
nextIfdOffsetToWrite := uint32(0)
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, nextIfdOffsetToWrite)
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite)
|
||||
log.PanicIf(err)
|
||||
|
||||
if childIfdBlock != nil {
|
||||
|
@ -358,7 +358,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_childIfd__withAllocate(t *testing.T) {
|
|||
// stream. Just used for arithmetic.
|
||||
nextIfdOffsetToWrite := uint32(2000)
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, nextIfdOffsetToWrite)
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, nextIfdOffsetToWrite)
|
||||
log.PanicIf(err)
|
||||
|
||||
if ida.NextOffset() != addressableOffset {
|
||||
|
@ -450,7 +450,7 @@ func Test_IfdByteEncoder_encodeTagToBytes_simpleTag_allocate(t *testing.T) {
|
|||
addressableOffset := uint32(0x1234)
|
||||
ida := newIfdDataAllocator(addressableOffset)
|
||||
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
childIfdBlock, err := ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
if ida.NextOffset() == addressableOffset {
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
func TestAdd(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -24,7 +24,7 @@ func TestAdd(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -34,7 +34,7 @@ func TestAdd(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -46,7 +46,7 @@ func TestAdd(t *testing.T) {
|
|||
|
||||
originalBytes := []byte { 0x11, 0x22, 0x33 }
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x44,
|
||||
|
@ -119,7 +119,7 @@ func TestAddChildIb(t *testing.T) {
|
|||
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -135,7 +135,7 @@ func TestAddChildIb(t *testing.T) {
|
|||
err = ib.AddChildIb(ibChild)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -291,7 +291,7 @@ func TestAddTagsFromExisting__Excludes(t *testing.T) {
|
|||
func TestFindN_First_1(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -301,7 +301,7 @@ func TestFindN_First_1(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -311,7 +311,7 @@ func TestFindN_First_1(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -341,7 +341,7 @@ func TestFindN_First_1(t *testing.T) {
|
|||
func TestFindN_First_2_1Returned(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -351,7 +351,7 @@ func TestFindN_First_2_1Returned(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -361,7 +361,7 @@ func TestFindN_First_2_1Returned(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -391,7 +391,7 @@ func TestFindN_First_2_1Returned(t *testing.T) {
|
|||
func TestFindN_First_2_2Returned(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -401,7 +401,7 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -411,7 +411,7 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -421,7 +421,7 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -431,7 +431,7 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -468,7 +468,7 @@ func TestFindN_First_2_2Returned(t *testing.T) {
|
|||
func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -478,7 +478,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -488,7 +488,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -498,7 +498,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -508,7 +508,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -518,7 +518,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -548,7 +548,7 @@ func TestFindN_Middle_WithDuplicates(t *testing.T) {
|
|||
func TestFindN_Middle_NoDuplicates(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -558,7 +558,7 @@ func TestFindN_Middle_NoDuplicates(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -568,7 +568,7 @@ func TestFindN_Middle_NoDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -578,7 +578,7 @@ func TestFindN_Middle_NoDuplicates(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -619,7 +619,7 @@ func TestFindN_Miss(t *testing.T) {
|
|||
func TestFind_Hit(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -629,7 +629,7 @@ func TestFind_Hit(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -639,7 +639,7 @@ func TestFind_Hit(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -649,7 +649,7 @@ func TestFind_Hit(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -677,7 +677,7 @@ func TestFind_Hit(t *testing.T) {
|
|||
func TestFind_Miss(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -687,7 +687,7 @@ func TestFind_Miss(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -697,7 +697,7 @@ func TestFind_Miss(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -707,7 +707,7 @@ func TestFind_Miss(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -728,7 +728,7 @@ func TestFind_Miss(t *testing.T) {
|
|||
func TestReplace(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -738,7 +738,7 @@ func TestReplace(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -748,7 +748,7 @@ func TestReplace(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -767,7 +767,7 @@ func TestReplace(t *testing.T) {
|
|||
t.Fatalf("Pre-replace tags are not correct.")
|
||||
}
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x99,
|
||||
|
@ -790,7 +790,7 @@ func TestReplace(t *testing.T) {
|
|||
func TestReplaceN(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -800,7 +800,7 @@ func TestReplaceN(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -810,7 +810,7 @@ func TestReplaceN(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -829,7 +829,7 @@ func TestReplaceN(t *testing.T) {
|
|||
t.Fatalf("Pre-replace tags are not correct.")
|
||||
}
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0xA9,
|
||||
|
@ -852,7 +852,7 @@ func TestReplaceN(t *testing.T) {
|
|||
func TestDeleteFirst(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -862,7 +862,7 @@ func TestDeleteFirst(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -872,7 +872,7 @@ func TestDeleteFirst(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -882,7 +882,7 @@ func TestDeleteFirst(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -952,7 +952,7 @@ func TestDeleteFirst(t *testing.T) {
|
|||
func TestDeleteN(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -962,7 +962,7 @@ func TestDeleteN(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -972,7 +972,7 @@ func TestDeleteN(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -982,7 +982,7 @@ func TestDeleteN(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -1052,7 +1052,7 @@ func TestDeleteN(t *testing.T) {
|
|||
func TestDeleteN_Two(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -1062,7 +1062,7 @@ func TestDeleteN_Two(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -1072,7 +1072,7 @@ func TestDeleteN_Two(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -1082,7 +1082,7 @@ func TestDeleteN_Two(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -1135,7 +1135,7 @@ func TestDeleteN_Two(t *testing.T) {
|
|||
func TestDeleteAll(t *testing.T) {
|
||||
ib := NewIfdBuilder(RootIi, TestDefaultByteOrder)
|
||||
|
||||
bt := builderTag{
|
||||
bt := &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x11,
|
||||
|
@ -1145,7 +1145,7 @@ func TestDeleteAll(t *testing.T) {
|
|||
err := ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -1155,7 +1155,7 @@ func TestDeleteAll(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x22,
|
||||
|
@ -1165,7 +1165,7 @@ func TestDeleteAll(t *testing.T) {
|
|||
err = ib.Add(bt)
|
||||
log.PanicIf(err)
|
||||
|
||||
bt = builderTag{
|
||||
bt = &builderTag{
|
||||
ii: RootIi,
|
||||
typeId: TypeByte,
|
||||
tagId: 0x33,
|
||||
|
@ -1420,6 +1420,137 @@ func Test_IfdBuilder_CreateIfdBuilderFromExistingChain_RealData(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// func Test_IfdBuilder_CreateIfdBuilderFromExistingChain_RealData_WithUpdate(t *testing.T) {
|
||||
// filepath := path.Join(assetsPath, "NDM_8901.jpg")
|
||||
|
||||
// e := NewExif()
|
||||
|
||||
|
||||
// rawExif, err := e.SearchAndExtractExif(filepath)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// // Decode from binary.
|
||||
|
||||
// _, originalIndex, err := e.Collect(rawExif)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// originalThumbnailData, err := originalIndex.RootIfd.NextIfd.Thumbnail()
|
||||
// log.PanicIf(err)
|
||||
|
||||
// originalTags := originalIndex.RootIfd.DumpTags()
|
||||
|
||||
|
||||
// // Encode back to binary.
|
||||
|
||||
// ibe := NewIfdByteEncoder()
|
||||
|
||||
// itevr := NewIfdTagEntryValueResolver(rawExif, originalIndex.RootIfd.ByteOrder)
|
||||
// rootIb := NewIfdBuilderFromExistingChain(originalIndex.RootIfd, itevr)
|
||||
|
||||
|
||||
// // Update a tag,.
|
||||
|
||||
// exifBt, err := rootIb.FindWithName("ExifTag")
|
||||
// log.PanicIf(err)
|
||||
|
||||
// ucBt, err := exifBt.value.Ib().FindWithName("UserComment")
|
||||
// log.PanicIf(err)
|
||||
|
||||
// err = ucBt.SetValue(rootIb.ByteOrder, "TEST CHANGE")
|
||||
// log.PanicIf(err)
|
||||
|
||||
|
||||
// // Encode.
|
||||
|
||||
// updatedExif, err := ibe.EncodeToExif(rootIb)
|
||||
// log.PanicIf(err)
|
||||
|
||||
|
||||
// // Parse again.
|
||||
|
||||
// _, recoveredIndex, err := e.Collect(updatedExif)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// recoveredTags := recoveredIndex.RootIfd.DumpTags()
|
||||
|
||||
|
||||
// recoveredThumbnailData, err := recoveredIndex.RootIfd.NextIfd.Thumbnail()
|
||||
// log.PanicIf(err)
|
||||
|
||||
|
||||
// // Check the thumbnail.
|
||||
|
||||
// if bytes.Compare(recoveredThumbnailData, originalThumbnailData) != 0 {
|
||||
// t.Fatalf("recovered thumbnail does not match original")
|
||||
// }
|
||||
|
||||
|
||||
// // Validate that all of the same IFDs were presented.
|
||||
|
||||
// originalIfdTags := make([][2]interface{}, 0)
|
||||
// for _, ite := range originalTags {
|
||||
// if ite.ChildIfdName != "" {
|
||||
// originalIfdTags = append(originalIfdTags, [2]interface{} { ite.Ii, ite.TagId })
|
||||
// }
|
||||
// }
|
||||
|
||||
// recoveredIfdTags := make([][2]interface{}, 0)
|
||||
// for _, ite := range recoveredTags {
|
||||
// if ite.ChildIfdName != "" {
|
||||
// recoveredIfdTags = append(recoveredIfdTags, [2]interface{} { ite.Ii, ite.TagId })
|
||||
// }
|
||||
// }
|
||||
|
||||
// if reflect.DeepEqual(recoveredIfdTags, originalIfdTags) != true {
|
||||
// fmt.Printf("Original IFD tags:\n\n")
|
||||
|
||||
// for i, x := range originalIfdTags {
|
||||
// fmt.Printf(" %02d %v\n", i, x)
|
||||
// }
|
||||
|
||||
// fmt.Printf("\nRecovered IFD tags:\n\n")
|
||||
|
||||
// for i, x := range recoveredIfdTags {
|
||||
// fmt.Printf(" %02d %v\n", i, x)
|
||||
// }
|
||||
|
||||
// fmt.Printf("\n")
|
||||
|
||||
// t.Fatalf("Recovered IFD tags are not correct.")
|
||||
// }
|
||||
|
||||
|
||||
// // Validate that all of the tags owned by the IFDs were presented. Note
|
||||
// // that the thumbnail tags are not kept but only produced on the fly, which
|
||||
// // is why we check it above.
|
||||
|
||||
// for i, recoveredIte := range recoveredTags {
|
||||
// if recoveredIte.ChildIfdName != "" {
|
||||
// continue
|
||||
// }
|
||||
|
||||
// originalIte := originalTags[i]
|
||||
|
||||
// if recoveredIte.Ii != originalIte.Ii {
|
||||
// t.Fatalf("IfdIdentify not as expected: %s != %s ITE=%s", recoveredIte.Ii, originalIte.Ii, recoveredIte)
|
||||
// } else if recoveredIte.TagId != originalIte.TagId {
|
||||
// t.Fatalf("Tag-ID not as expected: %s != %s ITE=%s", recoveredIte.TagId, originalIte.TagId, recoveredIte)
|
||||
// } else if recoveredIte.TagType != originalIte.TagType {
|
||||
// t.Fatalf("Tag-type not as expected: %d != %d ITE=%s", recoveredIte.TagType, originalIte.TagType, recoveredIte)
|
||||
// }
|
||||
|
||||
// originalValueBytes, err := originalIte.ValueBytes(originalIndex.RootIfd.addressableData, originalIndex.RootIfd.ByteOrder)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// recoveredValueBytes, err := recoveredIte.ValueBytes(recoveredIndex.RootIfd.addressableData, recoveredIndex.RootIfd.ByteOrder)
|
||||
// log.PanicIf(err)
|
||||
|
||||
// if bytes.Compare(originalValueBytes, recoveredValueBytes) != 0 {
|
||||
// t.Fatalf("bytes of tag content not correct: %s != %s", originalIte, recoveredIte)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func Test_IfdBuilder_CreateIfdBuilderWithExistingIfd(t *testing.T) {
|
||||
tagId := IfdTagIdWithIdentityOrFail(GpsIi)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestUndefinedValue_ExifVersion(t *testing.T) {
|
|||
|
||||
// Encode.
|
||||
|
||||
_, err = ibe.encodeTagToBytes(ib, &bt, bw, ida, uint32(0))
|
||||
_, err = ibe.encodeTagToBytes(ib, bt, bw, ida, uint32(0))
|
||||
log.PanicIf(err)
|
||||
|
||||
tagBytes := b.Bytes()
|
||||
|
|
Loading…
Reference in New Issue