github.com/ergo-services/ergo@v1.999.224/etf/encode_test.go (about)

     1  package etf
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"reflect"
     7  	"testing"
     8  
     9  	"github.com/ergo-services/ergo/lib"
    10  )
    11  
    12  func TestEncodeBool(t *testing.T) {
    13  	b := lib.TakeBuffer()
    14  	defer lib.ReleaseBuffer(b)
    15  
    16  	err := Encode(false, b, EncodeOptions{})
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  	if !reflect.DeepEqual(b.B, []byte{ettSmallAtom, 5, 'f', 'a', 'l', 's', 'e'}) {
    21  		t.Fatal("incorrect value")
    22  	}
    23  }
    24  
    25  func TestEncodeBoolWithAtomCache(t *testing.T) {
    26  	b := lib.TakeBuffer()
    27  	defer lib.ReleaseBuffer(b)
    28  
    29  	senderAtomCache := make(map[Atom]CacheItem)
    30  	encodingAtomCache := TakeEncodingAtomCache()
    31  	atomCache := NewAtomCache()
    32  	ci := CacheItem{ID: 499, Encoded: true, Name: "false"}
    33  
    34  	senderAtomCache["false"] = ci
    35  
    36  	encodeOptions := EncodeOptions{
    37  		AtomCache:         atomCache.Out,
    38  		SenderAtomCache:   senderAtomCache,
    39  		EncodingAtomCache: encodingAtomCache,
    40  	}
    41  
    42  	err := Encode(false, b, encodeOptions)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  
    47  	if encodingAtomCache.Len() != 1 || encodingAtomCache.L[0] != ci {
    48  		t.Fatal("incorrect cache value")
    49  	}
    50  
    51  	if !reflect.DeepEqual(b.B, []byte{ettCacheRef, 0}) {
    52  		t.Fatal("incorrect value")
    53  	}
    54  
    55  }
    56  
    57  type integerCase struct {
    58  	name     string
    59  	integer  interface{}
    60  	expected []byte
    61  }
    62  
    63  func integerCases() []integerCase {
    64  	bigInt := big.Int{}
    65  	bigInt.SetString("9223372036854775807123456789", 10)
    66  	bigIntNegative := big.Int{}
    67  	bigIntNegative.SetString("-9223372036854775807123456789", 10)
    68  
    69  	return []integerCase{
    70  		//
    71  		// unsigned integers
    72  		//
    73  		{"uint8::255", uint8(255), []byte{ettSmallInteger, 255}},
    74  		{"uint16::255", uint16(255), []byte{ettSmallInteger, 255}},
    75  		{"uint32::255", uint32(255), []byte{ettSmallInteger, 255}},
    76  		{"uint64::255", uint64(255), []byte{ettSmallInteger, 255}},
    77  		{"uint::255", uint(255), []byte{ettSmallInteger, 255}},
    78  
    79  		{"uint16::256", uint16(256), []byte{ettInteger, 0, 0, 1, 0}},
    80  
    81  		{"uint16::65535", uint16(65535), []byte{ettInteger, 0, 0, 255, 255}},
    82  		{"uint32::65535", uint32(65535), []byte{ettInteger, 0, 0, 255, 255}},
    83  		{"uint64::65535", uint64(65535), []byte{ettInteger, 0, 0, 255, 255}},
    84  
    85  		{"uint64::65536", uint64(65536), []byte{ettInteger, 0, 1, 0, 0}},
    86  
    87  		// treat as an int32
    88  		{"uint32::2147483647", uint32(2147483647), []byte{ettInteger, 127, 255, 255, 255}},
    89  		{"uint64::2147483647", uint64(2147483647), []byte{ettInteger, 127, 255, 255, 255}},
    90  		{"uint64::2147483648", uint64(2147483648), []byte{ettSmallBig, 4, 0, 0, 0, 0, 128}},
    91  
    92  		{"uint32::4294967295", uint32(4294967295), []byte{ettSmallBig, 4, 0, 255, 255, 255, 255}},
    93  		{"uint64::4294967295", uint64(4294967295), []byte{ettSmallBig, 4, 0, 255, 255, 255, 255}},
    94  		{"uint64::4294967296", uint64(4294967296), []byte{ettSmallBig, 5, 0, 0, 0, 0, 0, 1}},
    95  
    96  		{"uint64::18446744073709551615", uint64(18446744073709551615), []byte{ettSmallBig, 8, 0, 255, 255, 255, 255, 255, 255, 255, 255}},
    97  
    98  		//
    99  		// signed integers
   100  		//
   101  
   102  		// negative is always ettInteger for the numbers within the range of int32
   103  		{"int8::-127", int8(-127), []byte{ettInteger, 255, 255, 255, 129}},
   104  		{"int16::-127", int16(-127), []byte{ettInteger, 255, 255, 255, 129}},
   105  		{"int32::-127", int32(-127), []byte{ettInteger, 255, 255, 255, 129}},
   106  		{"int64::-127", int64(-127), []byte{ettInteger, 255, 255, 255, 129}},
   107  		{"int::-127", int(-127), []byte{ettInteger, 255, 255, 255, 129}},
   108  
   109  		// positive within a range of int8 treats as ettSmallInteger
   110  		{"int8::127", int8(127), []byte{ettSmallInteger, 127}},
   111  		{"int16::127", int16(127), []byte{ettSmallInteger, 127}},
   112  		{"int32::127", int32(127), []byte{ettSmallInteger, 127}},
   113  		{"int64::127", int64(127), []byte{ettSmallInteger, 127}},
   114  
   115  		// a positive int[16,32,64] value within the range of uint8 treats as an uint8
   116  		{"int16::128", int16(128), []byte{ettSmallInteger, 128}},
   117  		{"int32::128", int32(128), []byte{ettSmallInteger, 128}},
   118  		{"int64::128", int64(128), []byte{ettSmallInteger, 128}},
   119  		{"int::128", int(128), []byte{ettSmallInteger, 128}},
   120  
   121  		// whether its positive or negative value within the range of int16 its treating as an int32
   122  		{"int16::-32767", int16(-32767), []byte{ettInteger, 255, 255, 128, 1}},
   123  		{"int16::32767", int16(32767), []byte{ettInteger, 0, 0, 127, 255}},
   124  
   125  		// treat as an int32
   126  		{"int32::2147483647", int32(2147483647), []byte{ettInteger, 127, 255, 255, 255}},
   127  		{"int32::-2147483648", int32(-2147483648), []byte{ettInteger, 128, 0, 0, 0}},
   128  		{"int64::2147483647", int64(2147483647), []byte{ettInteger, 127, 255, 255, 255}},
   129  		{"int64::-2147483648", int64(-2147483648), []byte{ettInteger, 128, 0, 0, 0}},
   130  
   131  		{"int64::2147483648", int64(2147483648), []byte{ettSmallBig, 4, 0, 0, 0, 0, 128}},
   132  
   133  		// int64 treats as ettSmallBig whether its positive or negative
   134  		{"int64::9223372036854775807", int64(9223372036854775807), []byte{ettSmallBig, 8, 0, 255, 255, 255, 255, 255, 255, 255, 127}},
   135  		{"int64::-9223372036854775808", int64(-9223372036854775808), []byte{ettSmallBig, 8, 1, 0, 0, 0, 0, 0, 0, 0, 128}},
   136  
   137  		{"big.int::-9223372036854775807123456789", bigIntNegative, []byte{ettSmallBig, 12, 1, 21, 3, 193, 203, 255, 255, 255, 255, 255, 100, 205, 29}},
   138  	}
   139  }
   140  
   141  func TestEncodeInteger(t *testing.T) {
   142  	b := lib.TakeBuffer()
   143  	defer lib.ReleaseBuffer(b)
   144  
   145  	for _, c := range integerCases() {
   146  		t.Run(c.name, func(t *testing.T) {
   147  			b.Reset()
   148  
   149  			err := Encode(c.integer, b, EncodeOptions{})
   150  			if err != nil {
   151  				t.Fatal(err)
   152  			}
   153  			if !reflect.DeepEqual(b.B, c.expected) {
   154  				fmt.Println("exp ", c.expected)
   155  				fmt.Println("got ", b.B)
   156  				t.Fatal("incorrect value")
   157  			}
   158  		})
   159  	}
   160  }
   161  
   162  func TestEncodeFloat(t *testing.T) {
   163  	b := lib.TakeBuffer()
   164  	defer lib.ReleaseBuffer(b)
   165  
   166  	expected := []byte{ettNewFloat, 64, 9, 30, 184, 81, 235, 133, 31}
   167  
   168  	err := Encode(float64(3.14), b, EncodeOptions{})
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  
   173  	if !reflect.DeepEqual(b.B, expected) {
   174  		fmt.Println("exp", expected)
   175  		fmt.Println("got", b.B)
   176  		t.Fatal("incorrect value")
   177  	}
   178  
   179  	b.Reset()
   180  	err = Encode(float32(3.14), b, EncodeOptions{})
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	// float32 to float64 casting makes some changes, thats why 'expected'
   186  	// has different set of bytes
   187  	expected = []byte{ettNewFloat, 64, 9, 30, 184, 96, 0, 0, 0}
   188  	if !reflect.DeepEqual(b.B, expected) {
   189  		fmt.Println("exp", expected)
   190  		fmt.Println("got", b.B)
   191  		t.Fatal("incorrect value")
   192  	}
   193  
   194  }
   195  
   196  func TestEncodeString(t *testing.T) {
   197  	b := lib.TakeBuffer()
   198  	defer lib.ReleaseBuffer(b)
   199  
   200  	expected := []byte{ettString, 0, 52, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 46, 32, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 46, 32, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 32, 208, 188, 208, 184, 209, 128, 46, 32, 240, 159, 154, 128}
   201  	err := Encode("Hello World. 你好世界. Привет мир. 🚀", b, EncodeOptions{})
   202  	if err != nil {
   203  		t.Fatal(err)
   204  	}
   205  
   206  	if !reflect.DeepEqual(b.B, expected) {
   207  		fmt.Println("exp", expected)
   208  		fmt.Println("got", b.B)
   209  		t.Fatal("incorrect value")
   210  	}
   211  }
   212  
   213  func TestEncodeAtom(t *testing.T) {
   214  	b := lib.TakeBuffer()
   215  	defer lib.ReleaseBuffer(b)
   216  
   217  	expected := []byte{ettSmallAtomUTF8, 14, 69, 114, 103, 111, 32, 70, 114, 97, 109, 101, 119,
   218  		111, 114, 107}
   219  
   220  	err := Encode(Atom("Ergo Framework"), b, EncodeOptions{})
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  
   225  	if !reflect.DeepEqual(b.B, expected) {
   226  		fmt.Println("exp", expected)
   227  		fmt.Println("got", b.B)
   228  		t.Fatal("incorrect value")
   229  	}
   230  
   231  	b.Reset()
   232  
   233  	// longAtom with 255 utf-8 symbols 446 bytes
   234  	longAtom := Atom("你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好世界ПриветМирHelloWorld你好")
   235  	err = Encode(longAtom, b, EncodeOptions{})
   236  
   237  	expected = []byte{ettAtomUTF8, 1, 190, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 208, 156, 208, 184, 209, 128, 72, 101, 108, 108, 111, 87, 111, 114, 108, 100, 228, 189, 160, 229, 165, 189}
   238  	if !reflect.DeepEqual(b.B, expected) {
   239  		fmt.Println("exp", expected)
   240  		fmt.Println("got", b.B)
   241  		t.Fatal("incorrect value")
   242  	}
   243  
   244  	b.Reset()
   245  
   246  	// long Atom. longer 255 symbols. Should return ErrAtomTooLong
   247  	longAtom = Atom("Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework Ergo Framework")
   248  	err = Encode(longAtom, b, EncodeOptions{})
   249  	if err != ErrAtomTooLong {
   250  		t.Fatal("incorrect value")
   251  	}
   252  }
   253  
   254  func TestEncodeAtomWithCache(t *testing.T) {
   255  	b := lib.TakeBuffer()
   256  	defer lib.ReleaseBuffer(b)
   257  
   258  	senderAtomCache := make(map[Atom]CacheItem)
   259  	encodingAtomCache := TakeEncodingAtomCache()
   260  
   261  	atomCache := NewAtomCache()
   262  
   263  	ci := CacheItem{ID: 2020, Encoded: true, Name: "cached atom"}
   264  	senderAtomCache["cached atom"] = ci
   265  
   266  	encodeOptions := EncodeOptions{
   267  		AtomCache:         atomCache.Out,
   268  		SenderAtomCache:   senderAtomCache,
   269  		EncodingAtomCache: encodingAtomCache,
   270  	}
   271  
   272  	err := Encode(Atom("cached atom"), b, encodeOptions)
   273  	if err != nil {
   274  		t.Fatal(err)
   275  	}
   276  
   277  	if encodingAtomCache.Len() != 1 || encodingAtomCache.L[0] != ci {
   278  		t.Fatal("incorrect cache value")
   279  	}
   280  
   281  	if !reflect.DeepEqual(b.B, []byte{ettCacheRef, 0}) {
   282  		t.Fatal("incorrect value")
   283  	}
   284  
   285  	b.Reset()
   286  
   287  	err = Encode(Atom("not cached atom"), b, encodeOptions)
   288  	if err != nil {
   289  		t.Fatal(err)
   290  	}
   291  
   292  	if encodingAtomCache.Len() != 1 || encodingAtomCache.L[0] != ci {
   293  		t.Fatal("incorrect cache value")
   294  	}
   295  
   296  	expected := []byte{ettSmallAtomUTF8, 15, 110, 111, 116, 32, 99, 97, 99, 104, 101, 100, 32, 97, 116, 111, 109}
   297  	if !reflect.DeepEqual(b.B, expected) {
   298  		t.Fatal("incorrect value")
   299  	}
   300  }
   301  
   302  func TestEncodeBinary(t *testing.T) {
   303  	b := lib.TakeBuffer()
   304  	defer lib.ReleaseBuffer(b)
   305  
   306  	err := Encode([]byte{1, 2, 3, 4, 5}, b, EncodeOptions{})
   307  	if err != nil {
   308  		t.Fatal(err)
   309  	}
   310  
   311  	expected := []byte{ettBinary, 0, 0, 0, 5, 1, 2, 3, 4, 5}
   312  	if !reflect.DeepEqual(b.B, expected) {
   313  		t.Fatal("incorrect value")
   314  	}
   315  }
   316  
   317  func TestEncodeList(t *testing.T) {
   318  	b := lib.TakeBuffer()
   319  	defer lib.ReleaseBuffer(b)
   320  
   321  	expected := []byte{ettList, 0, 0, 0, 3, ettSmallAtomUTF8, 1, 97, ettSmallInteger, 2, ettSmallInteger, 3, ettNil}
   322  	term := List{Atom("a"), 2, 3}
   323  	err := Encode(term, b, EncodeOptions{})
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  
   328  	if !reflect.DeepEqual(b.B, expected) {
   329  		fmt.Println("exp", expected)
   330  		fmt.Println("got", b.B)
   331  		t.Fatal("incorrect value")
   332  	}
   333  }
   334  func TestEncodeListImproper(t *testing.T) {
   335  	b := lib.TakeBuffer()
   336  	defer lib.ReleaseBuffer(b)
   337  
   338  	expected := []byte{ettList, 0, 0, 0, 2, ettSmallAtomUTF8, 1, 97, ettSmallInteger, 2, ettSmallInteger, 3}
   339  	term := ListImproper{Atom("a"), 2, 3}
   340  	err := Encode(term, b, EncodeOptions{})
   341  	if err != nil {
   342  		t.Fatal(err)
   343  	}
   344  
   345  	if !reflect.DeepEqual(b.B, expected) {
   346  		fmt.Println("exp", expected)
   347  		fmt.Println("got", b.B)
   348  		t.Fatal("incorrect value")
   349  	}
   350  }
   351  
   352  func TestEncodeSlice(t *testing.T) {
   353  	b := lib.TakeBuffer()
   354  	defer lib.ReleaseBuffer(b)
   355  	expected := []byte{108, 0, 0, 0, 4, 98, 0, 0, 48, 57, 98, 0, 1, 9, 50, 98, 0, 0, 48, 57,
   356  		98, 0, 1, 9, 50, 106}
   357  	//expected := []byte{ettList, 0, 0, 0, 3, ettSmallAtomUTF8, 1, 97, ettSmallInteger, 2, ettSmallInteger, 3, ettNil}
   358  	term := []int{12345, 67890, 12345, 67890}
   359  	err := Encode(term, b, EncodeOptions{})
   360  	if err != nil {
   361  		t.Fatal(err)
   362  	}
   363  
   364  	if !reflect.DeepEqual(b.B, expected) {
   365  		fmt.Println("exp", expected)
   366  		fmt.Println("got", b.B)
   367  		t.Fatal("incorrect value")
   368  	}
   369  
   370  	b.Reset()
   371  
   372  	expected = []byte{108, 0, 0, 0, 3, 119, 1, 97, 119, 1, 98, 119, 1, 99, 106}
   373  	termAtoms := []Atom{Atom("a"), Atom("b"), Atom("c")}
   374  	err = Encode(termAtoms, b, EncodeOptions{})
   375  	if err != nil {
   376  		t.Fatal(err)
   377  	}
   378  
   379  	if !reflect.DeepEqual(b.B, expected) {
   380  		fmt.Println("exp", expected)
   381  		fmt.Println("got", b.B)
   382  		t.Fatal("incorrect value")
   383  	}
   384  }
   385  
   386  func TestEncodeListNested(t *testing.T) {
   387  	b := lib.TakeBuffer()
   388  	defer lib.ReleaseBuffer(b)
   389  	expected := []byte{108, 0, 0, 0, 2, 119, 1, 97, 108, 0, 0, 0, 4, 119, 1, 98, 97, 2, 108,
   390  		0, 0, 0, 2, 119, 1, 99, 97, 3, 106, 97, 4, 106, 106}
   391  
   392  	term := List{Atom("a"), List{Atom("b"), 2, List{Atom("c"), 3}, 4}}
   393  	err := Encode(term, b, EncodeOptions{})
   394  	if err != nil {
   395  		t.Fatal(err)
   396  	}
   397  
   398  	if !reflect.DeepEqual(b.B, expected) {
   399  		fmt.Println("exp", expected)
   400  		fmt.Println("got", b.B)
   401  		t.Fatal("incorrect value")
   402  	}
   403  }
   404  
   405  func TestEncodeTupleNested(t *testing.T) {
   406  	b := lib.TakeBuffer()
   407  	defer lib.ReleaseBuffer(b)
   408  	expected := []byte{104, 2, 119, 1, 97, 104, 4, 119, 1, 98, 97, 2, 104, 2, 119, 1, 99,
   409  		97, 3, 97, 4}
   410  
   411  	term := Tuple{Atom("a"), Tuple{Atom("b"), 2, Tuple{Atom("c"), 3}, 4}}
   412  	err := Encode(term, b, EncodeOptions{})
   413  	if err != nil {
   414  		t.Fatal(err)
   415  	}
   416  
   417  	if !reflect.DeepEqual(b.B, expected) {
   418  		fmt.Println("exp", expected)
   419  		fmt.Println("got", b.B)
   420  		t.Fatal("incorrect value")
   421  	}
   422  }
   423  
   424  func TestEncodeTuple(t *testing.T) {
   425  	b := lib.TakeBuffer()
   426  	defer lib.ReleaseBuffer(b)
   427  
   428  	expected := []byte{ettSmallTuple, 3, ettSmallAtomUTF8, 1, 97, ettSmallInteger, 2, ettSmallInteger, 3}
   429  	term := Tuple{Atom("a"), 2, 3}
   430  	err := Encode(term, b, EncodeOptions{})
   431  	if err != nil {
   432  		t.Fatal(err)
   433  	}
   434  
   435  	if !reflect.DeepEqual(b.B, expected) {
   436  		fmt.Println("exp", expected)
   437  		fmt.Println("got", b.B)
   438  		t.Fatal("incorrect value")
   439  	}
   440  }
   441  
   442  func TestEncodeMap(t *testing.T) {
   443  	b := lib.TakeBuffer()
   444  	defer lib.ReleaseBuffer(b)
   445  
   446  	// map has no guarantee of key order, so the result could be different
   447  	expected := []byte{116, 0, 0, 0, 2, 119, 4, 107, 101, 121, 49, 98, 0, 0, 48, 57, 119, 4,
   448  		107, 101, 121, 50, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111,
   449  		114, 108, 100}
   450  	expected1 := []byte{116, 0, 0, 0, 2, 119, 4, 107, 101, 121, 50, 107, 0, 11, 104, 101,
   451  		108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 107, 101, 121, 49, 98, 0, 0,
   452  		48, 57}
   453  	term := Map{
   454  		Atom("key1"): 12345,
   455  		Atom("key2"): "hello world",
   456  	}
   457  
   458  	err := Encode(term, b, EncodeOptions{})
   459  	if err != nil {
   460  		t.Fatal(err)
   461  	}
   462  
   463  	if !reflect.DeepEqual(b.B, expected) && !reflect.DeepEqual(b.B, expected1) {
   464  		fmt.Println("exp", expected)
   465  		fmt.Println("got", b.B)
   466  		t.Fatal("incorrect value")
   467  	}
   468  }
   469  
   470  func TestEncodeGoMap(t *testing.T) {
   471  	b := lib.TakeBuffer()
   472  	defer lib.ReleaseBuffer(b)
   473  
   474  	// map has no guarantee of key order, so the result could be different
   475  	expected := []byte{116, 0, 0, 0, 2, 119, 4, 107, 101, 121, 49, 98, 0, 0, 48, 57, 119, 4,
   476  		107, 101, 121, 50, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111,
   477  		114, 108, 100}
   478  	expected1 := []byte{116, 0, 0, 0, 2, 119, 4, 107, 101, 121, 50, 107, 0, 11, 104, 101,
   479  		108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 107, 101, 121, 49, 98, 0, 0,
   480  		48, 57}
   481  	term := map[Atom]interface{}{
   482  		Atom("key1"): 12345,
   483  		Atom("key2"): "hello world",
   484  	}
   485  
   486  	err := Encode(term, b, EncodeOptions{})
   487  	if err != nil {
   488  		t.Fatal(err)
   489  	}
   490  
   491  	if !reflect.DeepEqual(b.B, expected) && !reflect.DeepEqual(b.B, expected1) {
   492  		fmt.Println("exp", expected)
   493  		fmt.Println("got", b.B)
   494  		t.Fatal("incorrect value")
   495  	}
   496  }
   497  
   498  func TestEncodeStruct(t *testing.T) {
   499  	b := lib.TakeBuffer()
   500  	defer lib.ReleaseBuffer(b)
   501  
   502  	expected := []byte{116, 0, 0, 0, 3, 119, 15, 83, 116, 114, 117, 99, 116, 84, 111, 77, 97, 112, 75, 101, 121, 49, 98, 0, 0, 48, 57, 119, 15, 83, 116, 114, 117, 99, 116, 84, 111, 77, 97, 112, 75, 101, 121, 50, 107, 0, 22, 112, 111, 105, 110, 116, 101, 114, 32, 116, 111, 32, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 15, 83, 116, 114, 117, 99, 116, 84, 111, 77, 97, 112, 75, 101, 121, 51, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}
   503  
   504  	s := "pointer to hello world"
   505  	term := struct {
   506  		StructToMapKey1 int
   507  		StructToMapKey2 string
   508  		StructToMapKey3 string
   509  	}{
   510  		StructToMapKey1: 12345,
   511  		StructToMapKey2: s,
   512  		StructToMapKey3: "hello world",
   513  	}
   514  
   515  	err := Encode(term, b, EncodeOptions{})
   516  	if err != nil {
   517  		t.Fatal(err)
   518  	}
   519  
   520  	if !reflect.DeepEqual(b.B, expected) {
   521  		fmt.Println("exp", expected)
   522  		fmt.Println("got", b.B)
   523  		t.Fatal("incorrect value")
   524  	}
   525  	b1 := lib.TakeBuffer()
   526  	defer lib.ReleaseBuffer(b1)
   527  
   528  	term1 := struct {
   529  		StructToMapKey1 int
   530  		StructToMapKey2 *string
   531  		StructToMapKey3 string
   532  	}{
   533  		StructToMapKey1: 12345,
   534  		StructToMapKey2: &s,
   535  		StructToMapKey3: "hello world",
   536  	}
   537  
   538  	err = Encode(term1, b1, EncodeOptions{})
   539  	if err != nil {
   540  		t.Fatal(err)
   541  	}
   542  
   543  	if !reflect.DeepEqual(b1.B, expected) {
   544  		fmt.Println("exp", expected)
   545  		fmt.Println("got", b1.B)
   546  		t.Fatal("incorrect value")
   547  	}
   548  }
   549  
   550  func TestEncodeStructWithNestedPointers(t *testing.T) {
   551  	b := lib.TakeBuffer()
   552  	defer lib.ReleaseBuffer(b)
   553  
   554  	type Nested struct {
   555  		Key1 string
   556  		Key2 *string
   557  		Key3 int
   558  		Key4 *int
   559  		Key5 float64
   560  		Key6 *float64
   561  		Key7 bool
   562  		Key8 *bool
   563  	}
   564  	type Tst struct {
   565  		Nested
   566  		Key9 *Nested
   567  	}
   568  	ValueString := "hello world"
   569  	ValueInt := 123
   570  	ValueFloat := 3.14
   571  	ValueBool := true
   572  
   573  	nested := Nested{
   574  		Key1: ValueString,
   575  		Key2: &ValueString,
   576  		Key3: ValueInt,
   577  		Key4: &ValueInt,
   578  		Key5: ValueFloat,
   579  		Key6: &ValueFloat,
   580  		Key7: ValueBool,
   581  		Key8: &ValueBool,
   582  	}
   583  	term := Tst{
   584  		Nested: nested,
   585  		Key9:   &nested,
   586  	}
   587  
   588  	expected := []byte{116, 0, 0, 0, 2, 119, 6, 78, 101, 115, 116, 101, 100, 116, 0, 0, 0, 8, 119, 4, 75, 101, 121, 49, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 50, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 51, 97, 123, 119, 4, 75, 101, 121, 52, 97, 123, 119, 4, 75, 101, 121, 53, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 54, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 55, 115, 4, 116, 114, 117, 101, 119, 4, 75, 101, 121, 56, 115, 4, 116, 114, 117, 101, 119, 4, 75, 101, 121, 57, 116, 0, 0, 0, 8, 119, 4, 75, 101, 121, 49, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 50, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 51, 97, 123, 119, 4, 75, 101, 121, 52, 97, 123, 119, 4, 75, 101, 121, 53, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 54, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 55, 115, 4, 116, 114, 117, 101, 119, 4, 75, 101, 121, 56, 115, 4, 116, 114, 117, 101}
   589  
   590  	err := Encode(term, b, EncodeOptions{})
   591  	if err != nil {
   592  		t.Fatal(err)
   593  	}
   594  	if !reflect.DeepEqual(b.B, expected) {
   595  		fmt.Println("exp", expected)
   596  		fmt.Println("got", b.B)
   597  		t.Fatal("incorrect value")
   598  	}
   599  
   600  	b1 := lib.TakeBuffer()
   601  	defer lib.ReleaseBuffer(b1)
   602  	termWithNil := Tst{
   603  		Nested: nested,
   604  	}
   605  	expectedWithNil := []byte{116, 0, 0, 0, 2, 119, 6, 78, 101, 115, 116, 101, 100, 116, 0, 0, 0, 8, 119, 4, 75, 101, 121, 49, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 50, 107, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 119, 4, 75, 101, 121, 51, 97, 123, 119, 4, 75, 101, 121, 52, 97, 123, 119, 4, 75, 101, 121, 53, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 54, 70, 64, 9, 30, 184, 81, 235, 133, 31, 119, 4, 75, 101, 121, 55, 115, 4, 116, 114, 117, 101, 119, 4, 75, 101, 121, 56, 115, 4, 116, 114, 117, 101, 119, 4, 75, 101, 121, 57, 106}
   606  
   607  	err = Encode(termWithNil, b1, EncodeOptions{})
   608  	if err != nil {
   609  		t.Fatal(err)
   610  	}
   611  	if !reflect.DeepEqual(b1.B, expectedWithNil) {
   612  		fmt.Println("exp", expectedWithNil)
   613  		fmt.Println("got", b1.B)
   614  		t.Fatal("incorrect value")
   615  	}
   616  }
   617  
   618  func TestEncodeStructWithTags(t *testing.T) {
   619  	b := lib.TakeBuffer()
   620  	defer lib.ReleaseBuffer(b)
   621  
   622  	expected := []byte{116, 0, 0, 0, 4, 119, 4, 75, 101, 121, 49, 107, 0, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 119, 17, 99, 117, 115, 116, 111, 109, 95, 102, 105, 101, 108, 100, 95, 110, 97, 109, 101, 108, 0, 0, 0, 3, 108, 0, 0, 0, 7, 98, 0, 0, 79, 96, 98, 0, 0, 89, 125, 98, 0, 0, 78, 22, 98, 0, 0, 117, 76, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 13, 98, 0, 0, 4, 31, 98, 0, 0, 4, 64, 98, 0, 0, 4, 56, 98, 0, 0, 4, 50, 98, 0, 0, 4, 53, 98, 0, 0, 4, 66, 97, 32, 98, 0, 0, 4, 28, 98, 0, 0, 4, 56, 98, 0, 0, 4, 64, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 14, 97, 72, 97, 101, 97, 108, 97, 108, 97, 111, 97, 32, 97, 87, 97, 111, 97, 114, 97, 108, 97, 100, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 106, 119, 4, 75, 101, 121, 51, 116, 0, 0, 0, 2, 119, 10, 78, 101, 115, 116, 101, 100, 75, 101, 121, 49, 107, 0, 52, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 32, 228, 189, 160, 229, 165, 189, 228, 184, 150, 231, 149, 140, 33, 32, 208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 32, 208, 156, 208, 184, 209, 128, 33, 32, 240, 159, 154, 128, 119, 5, 102, 105, 101, 108, 100, 116, 0, 0, 0, 1, 107, 0, 7, 109, 97, 112, 95, 107, 101, 121, 108, 0, 0, 0, 32, 97, 72, 97, 101, 97, 108, 97, 108, 97, 111, 97, 32, 97, 87, 97, 111, 97, 114, 97, 108, 97, 100, 97, 33, 97, 32, 98, 0, 0, 79, 96, 98, 0, 0, 89, 125, 98, 0, 0, 78, 22, 98, 0, 0, 117, 76, 97, 33, 97, 32, 98, 0, 0, 4, 31, 98, 0, 0, 4, 64, 98, 0, 0, 4, 56, 98, 0, 0, 4, 50, 98, 0, 0, 4, 53, 98, 0, 0, 4, 66, 97, 32, 98, 0, 0, 4, 28, 98, 0, 0, 4, 56, 98, 0, 0, 4, 64, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 119, 4, 75, 101, 121, 52, 108, 0, 0, 0, 2, 108, 0, 0, 0, 3, 108, 0, 0, 0, 7, 98, 0, 0, 79, 96, 98, 0, 0, 89, 125, 98, 0, 0, 78, 22, 98, 0, 0, 117, 76, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 13, 98, 0, 0, 4, 31, 98, 0, 0, 4, 64, 98, 0, 0, 4, 56, 98, 0, 0, 4, 50, 98, 0, 0, 4, 53, 98, 0, 0, 4, 66, 97, 32, 98, 0, 0, 4, 28, 98, 0, 0, 4, 56, 98, 0, 0, 4, 64, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 14, 97, 72, 97, 101, 97, 108, 97, 108, 97, 111, 97, 32, 97, 87, 97, 111, 97, 114, 97, 108, 97, 100, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 106, 108, 0, 0, 0, 3, 108, 0, 0, 0, 7, 98, 0, 0, 79, 96, 98, 0, 0, 89, 125, 98, 0, 0, 78, 22, 98, 0, 0, 117, 76, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 13, 98, 0, 0, 4, 31, 98, 0, 0, 4, 64, 98, 0, 0, 4, 56, 98, 0, 0, 4, 50, 98, 0, 0, 4, 53, 98, 0, 0, 4, 66, 97, 32, 98, 0, 0, 4, 28, 98, 0, 0, 4, 56, 98, 0, 0, 4, 64, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 108, 0, 0, 0, 14, 97, 72, 97, 101, 97, 108, 97, 108, 97, 111, 97, 32, 97, 87, 97, 111, 97, 114, 97, 108, 97, 100, 97, 33, 97, 32, 98, 0, 1, 246, 128, 106, 106, 106}
   623  
   624  	type Nested struct {
   625  		NestedKey1 string
   626  		NestedKey2 map[string]*Charlist `etf:"field"`
   627  	}
   628  	type StructWithTags struct {
   629  		Key1 string
   630  		Key2 []*Charlist `etf:"custom_field_name"`
   631  		Key3 *Nested
   632  		Key4 [][]*Charlist
   633  	}
   634  
   635  	nestedMap := make(map[string]*Charlist)
   636  	value1 := Charlist("Hello World! 你好世界! Привет Мир! 🚀")
   637  	value11 := "Hello World! 你好世界! Привет Мир! 🚀"
   638  	nestedMap["map_key"] = &value1
   639  
   640  	nested := Nested{
   641  		NestedKey1: value11,
   642  		NestedKey2: nestedMap,
   643  	}
   644  
   645  	value2 := Charlist("你好世界! 🚀")
   646  	value3 := Charlist("Привет Мир! 🚀")
   647  	value4 := Charlist("Hello World! 🚀")
   648  	term := StructWithTags{
   649  		Key1: "Hello World!",
   650  		Key2: []*Charlist{&value2, &value3, &value4},
   651  		Key3: &nested,
   652  		Key4: [][]*Charlist{{&value2, &value3, &value4}, {&value2, &value3, &value4}},
   653  	}
   654  	err := Encode(term, b, EncodeOptions{})
   655  	if err != nil {
   656  		t.Fatal(err)
   657  	}
   658  	if !reflect.DeepEqual(b.B, expected) {
   659  		fmt.Println("exp", expected)
   660  		fmt.Println("got", b.B)
   661  		t.Fatal("incorrect value")
   662  	}
   663  }
   664  
   665  func TestEncodePid(t *testing.T) {
   666  	b := lib.TakeBuffer()
   667  	defer lib.ReleaseBuffer(b)
   668  
   669  	// FlagBigPidRef disabled. max value for ID (15 bits), serial 0
   670  	expected := []byte{ettPid, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64, 49, 50,
   671  		55, 46, 48, 46, 48, 46, 49, 0, 0, 127, 255, 0, 0, 0, 0, 2}
   672  	term := Pid{Node: "erl-demo@127.0.0.1", ID: 32767, Creation: 2}
   673  
   674  	err := Encode(term, b, EncodeOptions{})
   675  	if err != nil {
   676  		t.Fatal(err)
   677  	}
   678  
   679  	if !reflect.DeepEqual(b.B, expected) {
   680  		fmt.Println("exp", expected)
   681  		fmt.Println("got", b.B)
   682  		t.Fatal("incorrect value")
   683  	}
   684  
   685  	// FlagBigPidRef disabled. overflowed 15 bit. ID 0, serial 1
   686  	b.Reset()
   687  	expected = []byte{ettPid, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64, 49, 50,
   688  		55, 46, 48, 46, 48, 46, 49, 0, 0, 0, 0, 0, 0, 0, 1, 2}
   689  	term = Pid{Node: "erl-demo@127.0.0.1", ID: 32768, Creation: 2}
   690  
   691  	err = Encode(term, b, EncodeOptions{})
   692  	if err != nil {
   693  		t.Fatal(err)
   694  	}
   695  
   696  	if !reflect.DeepEqual(b.B, expected) {
   697  		fmt.Println("exp", expected)
   698  		fmt.Println("got", b.B)
   699  		t.Fatal("incorrect value")
   700  	}
   701  
   702  	// BigCreation, FlagBigPidRef enabled. max value for ID (32 bits), serial 0
   703  	b.Reset()
   704  	expected = []byte{ettNewPid, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64, 49, 50,
   705  		55, 46, 48, 46, 48, 46, 49, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 2}
   706  	term = Pid{Node: "erl-demo@127.0.0.1", ID: 4294967295, Creation: 2}
   707  
   708  	options := EncodeOptions{
   709  		FlagBigCreation: true,
   710  		FlagBigPidRef:   true,
   711  	}
   712  	err = Encode(term, b, options)
   713  	if err != nil {
   714  		t.Fatal(err)
   715  	}
   716  
   717  	if !reflect.DeepEqual(b.B, expected) {
   718  		fmt.Println("exp", expected)
   719  		fmt.Println("got", b.B)
   720  		t.Fatal("incorrect value")
   721  	}
   722  
   723  	// BigCreation, FlagBigPidRef enabled. max value for ID (32 bits), max value for Serial (32 bits)
   724  	b.Reset()
   725  	expected = []byte{ettNewPid, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64, 49, 50,
   726  		55, 46, 48, 46, 48, 46, 49, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 2}
   727  	term = Pid{Node: "erl-demo@127.0.0.1", ID: 18446744073709551615, Creation: 2}
   728  
   729  	options = EncodeOptions{
   730  		FlagBigCreation: true,
   731  		FlagBigPidRef:   true,
   732  	}
   733  	err = Encode(term, b, options)
   734  	if err != nil {
   735  		t.Fatal(err)
   736  	}
   737  
   738  	if !reflect.DeepEqual(b.B, expected) {
   739  		fmt.Println("exp", expected)
   740  		fmt.Println("got", b.B)
   741  		t.Fatal("incorrect value")
   742  	}
   743  }
   744  
   745  func TestEncodePidWithAtomCache(t *testing.T) {
   746  	b := lib.TakeBuffer()
   747  	defer lib.ReleaseBuffer(b)
   748  
   749  	expected := []byte{103, 82, 0, 0, 0, 1, 56, 0, 0, 0, 0, 2}
   750  	term := Pid{Node: "erl-demo@127.0.0.1", ID: 312, Creation: 2}
   751  
   752  	senderAtomCache := make(map[Atom]CacheItem)
   753  	encodingAtomCache := TakeEncodingAtomCache()
   754  	atomCache := NewAtomCache()
   755  
   756  	ci := CacheItem{ID: 2020, Encoded: true, Name: "erl-demo@127.0.0.1"}
   757  	senderAtomCache["erl-demo@127.0.0.1"] = ci
   758  	encodeOptions := EncodeOptions{
   759  		AtomCache:         atomCache.Out,
   760  		SenderAtomCache:   senderAtomCache,
   761  		EncodingAtomCache: encodingAtomCache,
   762  	}
   763  	err := Encode(term, b, encodeOptions)
   764  	if err != nil {
   765  		t.Fatal(err)
   766  	}
   767  
   768  	if encodingAtomCache.Len() != 1 || encodingAtomCache.L[0] != ci {
   769  		t.Fatal("incorrect cache value")
   770  	}
   771  
   772  	if !reflect.DeepEqual(b.B, expected) {
   773  		fmt.Println("exp", expected)
   774  		fmt.Println("got", b.B)
   775  		t.Fatal("incorrect value")
   776  	}
   777  
   778  }
   779  
   780  func TestEncodeRef(t *testing.T) {
   781  	b := lib.TakeBuffer()
   782  	defer lib.ReleaseBuffer(b)
   783  
   784  	// FlagBigCreation = false, FlagBigPidRef = false
   785  	expected := []byte{ettNewRef, 0, 3, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64,
   786  		49, 50, 55, 46, 48, 46, 48, 46, 49, 3, 0, 1, 30, 228, 183, 192, 0, 1, 141,
   787  		122, 203, 35}
   788  
   789  	term := Ref{
   790  		Node: Atom("erl-demo@127.0.0.1"),
   791  		// Creation must be encoded as 3
   792  		// Only one byte long and only two bits are significant, the rest must be 0.
   793  		Creation: 7,
   794  		ID:       [5]uint32{73444, 3082813441, 2373634851},
   795  	}
   796  
   797  	err := Encode(term, b, EncodeOptions{})
   798  	if err != nil {
   799  		t.Fatal(err)
   800  	}
   801  
   802  	if !reflect.DeepEqual(b.B, expected) {
   803  		fmt.Println("exp", expected)
   804  		fmt.Println("got", b.B)
   805  		t.Fatal("incorrect value")
   806  	}
   807  
   808  	// FlagBigCreation = true, FlagBigPidRef = false
   809  	b.Reset()
   810  	expected = []byte{ettNewerRef, 0, 3, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64,
   811  		49, 50, 55, 46, 48, 46, 48, 46, 49, 0, 0, 0, 8, 0, 1, 30, 228, 183, 192, 0, 1, 141,
   812  		122, 203, 35}
   813  
   814  	term = Ref{
   815  		Node:     Atom("erl-demo@127.0.0.1"),
   816  		Creation: 8,
   817  		ID:       [5]uint32{73444, 3082813441, 2373634851, 1, 2},
   818  	}
   819  
   820  	options := EncodeOptions{
   821  		FlagBigCreation: true,
   822  	}
   823  	err = Encode(term, b, options)
   824  	if err != nil {
   825  		t.Fatal(err)
   826  	}
   827  
   828  	if !reflect.DeepEqual(b.B, expected) {
   829  		fmt.Println("exp", expected)
   830  		fmt.Println("got", b.B)
   831  		t.Fatal("incorrect value")
   832  	}
   833  
   834  	//
   835  	// FIXME Erlang 24 has a bug https://github.com/erlang/otp/issues/5097
   836  	// uncomment once they fix it
   837  	//
   838  	// FlagBigCreation = true, FlagBigPidRef = true
   839  	//b.Reset()
   840  	//expected = []byte{ettNewerRef, 0, 5, 119, 18, 101, 114, 108, 45, 100, 101, 109, 111, 64,
   841  	//	49, 50, 55, 46, 48, 46, 48, 46, 49, 0, 0, 0, 8, 0, 1, 30, 228, 183, 192, 0, 1, 141,
   842  	//	122, 203, 35, 0, 0, 0, 1, 0, 0, 0, 2}
   843  
   844  	//term = Ref{
   845  	//	Node:     Atom("erl-demo@127.0.0.1"),
   846  	//	Creation: 8,
   847  	//	ID:       [5]uint32{73444, 3082813441, 2373634851, 1, 2},
   848  	//}
   849  
   850  	//options = EncodeOptions{
   851  	//	FlagBigCreation: true,
   852  	//	FlagBigPidRef:        true,
   853  	//}
   854  	//err = Encode(term, b, options)
   855  	//if err != nil {
   856  	//	t.Fatal(err)
   857  	//}
   858  
   859  	//if !reflect.DeepEqual(b.B, expected) {
   860  	//	fmt.Println("exp", expected)
   861  	//	fmt.Println("got", b.B)
   862  	//	t.Fatal("incorrect value")
   863  	//}
   864  }
   865  
   866  func TestEncodeTupleRefPid(t *testing.T) {
   867  	b := lib.TakeBuffer()
   868  	defer lib.ReleaseBuffer(b)
   869  
   870  	expected := []byte{ettSmallTuple, 2, ettNewRef, 0, 3, ettSmallAtomUTF8, 18, 101, 114, 108, 45, 100, 101, 109,
   871  		111, 64, 49, 50, 55, 46, 48, 46, 48, 46, 49, 2, 0, 1, 31, 28, 183, 192, 0,
   872  		1, 141, 122, 203, 35, 103, ettSmallAtomUTF8, 18, 101, 114, 108, 45, 100, 101,
   873  		109, 111, 64, 49, 50, 55, 46, 48, 46, 48, 46, 49, 0, 0, 1, 56, 0, 0, 0, 0,
   874  		2}
   875  
   876  	term := Tuple{
   877  		Ref{
   878  			Node:     Atom("erl-demo@127.0.0.1"),
   879  			Creation: 2,
   880  			ID:       [5]uint32{0x11f1c, 0xb7c00001, 0x8d7acb23}},
   881  		Pid{
   882  			Node:     Atom("erl-demo@127.0.0.1"),
   883  			ID:       312,
   884  			Creation: 2}}
   885  
   886  	err := Encode(term, b, EncodeOptions{})
   887  	if err != nil {
   888  		t.Fatal(err)
   889  	}
   890  
   891  	if !reflect.DeepEqual(b.B, expected) {
   892  		fmt.Println("exp", expected)
   893  		fmt.Println("got", b.B)
   894  		t.Fatal("incorrect value")
   895  	}
   896  }
   897  
   898  func TestEncodeGoPtrNil(t *testing.T) {
   899  	var x *int
   900  	b := lib.TakeBuffer()
   901  	defer lib.ReleaseBuffer(b)
   902  
   903  	err := Encode(x, b, EncodeOptions{})
   904  
   905  	if err != nil {
   906  		t.Fatal(err)
   907  	}
   908  	expected := []byte{ettNil}
   909  	if !reflect.DeepEqual(b.B, expected) {
   910  		fmt.Println("exp", expected)
   911  		fmt.Println("got", b.B)
   912  		t.Fatal("incorrect value")
   913  	}
   914  }
   915  
   916  func TestEncodeRegisteredType(t *testing.T) {
   917  	var tmp int
   918  	type regTypeStruct1 struct {
   919  		a int
   920  	}
   921  	type regTypeStruct3 struct {
   922  		C string
   923  	}
   924  	type regTypeStruct2 struct {
   925  		A int
   926  		B regTypeStruct3
   927  	}
   928  	type regTypeMap map[string]regTypeStruct3
   929  	type regTypeSlice []regTypeStruct3
   930  	type regTypeArray [5]regTypeStruct3
   931  
   932  	// only struct/map/slice/array types are supported
   933  	if _, err := RegisterType(tmp, RegisterTypeOptions{}); err == nil {
   934  		t.Fatal("must be error here")
   935  	}
   936  
   937  	// only struct with no unexported fields
   938  	if _, err := RegisterType(regTypeStruct1{}, RegisterTypeOptions{}); err == nil {
   939  		t.Fatal("must be error here")
   940  	}
   941  
   942  	// all nested struct must be registered first
   943  	if _, err := RegisterType(regTypeStruct2{}, RegisterTypeOptions{}); err == nil {
   944  		t.Fatal("must be error here")
   945  	}
   946  
   947  	if a, err := RegisterType(regTypeStruct3{}, RegisterTypeOptions{}); err != nil {
   948  		t.Fatal(err)
   949  	} else {
   950  		defer UnregisterType(a)
   951  	}
   952  	if a, err := RegisterType(regTypeStruct2{}, RegisterTypeOptions{}); err != nil {
   953  		t.Fatal(err)
   954  	} else {
   955  		defer UnregisterType(a)
   956  	}
   957  
   958  	if a, err := RegisterType(regTypeMap{}, RegisterTypeOptions{}); err != nil {
   959  		t.Fatal(err)
   960  	} else {
   961  		defer UnregisterType(a)
   962  	}
   963  
   964  	if a, err := RegisterType(regTypeSlice{}, RegisterTypeOptions{}); err != nil {
   965  		t.Fatal(err)
   966  	} else {
   967  		defer UnregisterType(a)
   968  	}
   969  
   970  	if a, err := RegisterType(regTypeArray{}, RegisterTypeOptions{}); err != nil {
   971  		t.Fatal(err)
   972  	} else {
   973  		defer UnregisterType(a)
   974  	}
   975  
   976  	b := lib.TakeBuffer()
   977  	defer lib.ReleaseBuffer(b)
   978  
   979  	x := regTypeStruct2{}
   980  	x.A = 123
   981  	x.B.C = "hello"
   982  
   983  	expected := []byte{ettSmallTuple, 3, ettSmallAtomUTF8, 49, 35, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 101, 114, 103, 111, 45, 115, 101, 114, 118, 105, 99, 101, 115, 47, 101, 114, 103, 111, 47, 101, 116, 102, 47, 114, 101, 103, 84, 121, 112, 101, 83, 116, 114, 117, 99, 116, 50, ettSmallInteger, 123, ettSmallTuple, 2, ettSmallAtomUTF8, 49, 35, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 101, 114, 103, 111, 45, 115, 101, 114, 118, 105, 99, 101, 115, 47, 101, 114, 103, 111, 47, 101, 116, 102, 47, 114, 101, 103, 84, 121, 112, 101, 83, 116, 114, 117, 99, 116, 51, ettString, 0, 5, 104, 101, 108, 108, 111}
   984  	err := Encode(x, b, EncodeOptions{})
   985  
   986  	if err != nil {
   987  		t.Fatal(err)
   988  	}
   989  
   990  	if !reflect.DeepEqual(b.B, expected) {
   991  		fmt.Println("exp", expected)
   992  		fmt.Println("got", b.B)
   993  		t.Fatal("incorrect value")
   994  	}
   995  }
   996  
   997  type testMarshal struct{}
   998  
   999  func (testMarshal) MarshalETF() ([]byte, error) {
  1000  	return []byte{1, 2, 3}, nil
  1001  }
  1002  
  1003  func TestEncodeMarshal(t *testing.T) {
  1004  	var x testMarshal
  1005  
  1006  	b := lib.TakeBuffer()
  1007  	defer lib.ReleaseBuffer(b)
  1008  
  1009  	err := Encode(x, b, EncodeOptions{})
  1010  	if err != nil {
  1011  		t.Fatal(err)
  1012  	}
  1013  	expected := []byte{ettBinary, 0, 0, 0, 3, 1, 2, 3}
  1014  	if !reflect.DeepEqual(b.B, expected) {
  1015  		fmt.Println("exp", expected)
  1016  		fmt.Println("got", b.B)
  1017  		t.Fatal("incorrect value")
  1018  	}
  1019  }
  1020  
  1021  func BenchmarkEncodeBool(b *testing.B) {
  1022  
  1023  	buf := lib.TakeBuffer()
  1024  	defer lib.ReleaseBuffer(buf)
  1025  
  1026  	b.ResetTimer()
  1027  	for i := 0; i < b.N; i++ {
  1028  		err := Encode(false, buf, EncodeOptions{})
  1029  		if err != nil {
  1030  			b.Fatal(err)
  1031  		}
  1032  	}
  1033  }
  1034  
  1035  func BenchmarkEncodeBoolWithAtomCache(b *testing.B) {
  1036  
  1037  	buf := lib.TakeBuffer()
  1038  	defer lib.ReleaseBuffer(buf)
  1039  
  1040  	senderAtomCache := make(map[Atom]CacheItem)
  1041  	encodingAtomCache := TakeEncodingAtomCache()
  1042  	atomCache := NewAtomCache()
  1043  
  1044  	senderAtomCache["false"] = CacheItem{ID: 499, Encoded: true, Name: "false"}
  1045  
  1046  	encodeOptions := EncodeOptions{
  1047  		AtomCache:         atomCache.Out,
  1048  		SenderAtomCache:   senderAtomCache,
  1049  		EncodingAtomCache: encodingAtomCache,
  1050  	}
  1051  	b.ResetTimer()
  1052  	for i := 0; i < b.N; i++ {
  1053  		err := Encode(false, buf, encodeOptions)
  1054  		buf.Reset()
  1055  		if err != nil {
  1056  			b.Fatal(err)
  1057  		}
  1058  	}
  1059  }
  1060  
  1061  func BenchmarkEncodeInteger(b *testing.B) {
  1062  	for _, c := range integerCases() {
  1063  		b.Run(c.name, func(b *testing.B) {
  1064  			buf := lib.TakeBuffer()
  1065  			defer lib.ReleaseBuffer(buf)
  1066  
  1067  			for i := 0; i < b.N; i++ {
  1068  				err := Encode(c.integer, buf, EncodeOptions{})
  1069  				if err != nil {
  1070  					b.Fatal(err)
  1071  				}
  1072  			}
  1073  		})
  1074  	}
  1075  }
  1076  
  1077  func BenchmarkEncodeFloat32(b *testing.B) {
  1078  	buf := lib.TakeBuffer()
  1079  	defer lib.ReleaseBuffer(buf)
  1080  
  1081  	b.ResetTimer()
  1082  	for i := 0; i < b.N; i++ {
  1083  		err := Encode(float32(3.14), buf, EncodeOptions{})
  1084  		if err != nil {
  1085  			b.Fatal(err)
  1086  		}
  1087  	}
  1088  }
  1089  
  1090  func BenchmarkEncodeFloat64(b *testing.B) {
  1091  	buf := lib.TakeBuffer()
  1092  	defer lib.ReleaseBuffer(buf)
  1093  
  1094  	b.ResetTimer()
  1095  	for i := 0; i < b.N; i++ {
  1096  		err := Encode(float64(3.14), buf, EncodeOptions{})
  1097  		if err != nil {
  1098  			b.Fatal(err)
  1099  		}
  1100  	}
  1101  }
  1102  
  1103  func BenchmarkEncodeString(b *testing.B) {
  1104  	buf := lib.TakeBuffer()
  1105  	defer lib.ReleaseBuffer(buf)
  1106  
  1107  	b.ResetTimer()
  1108  	for i := 0; i < b.N; i++ {
  1109  		err := Encode("Ergo Framework", buf, EncodeOptions{})
  1110  		if err != nil {
  1111  			b.Fatal(err)
  1112  		}
  1113  	}
  1114  }
  1115  
  1116  func BenchmarkEncodeAtom(b *testing.B) {
  1117  	buf := lib.TakeBuffer()
  1118  	defer lib.ReleaseBuffer(buf)
  1119  
  1120  	b.ResetTimer()
  1121  	for i := 0; i < b.N; i++ {
  1122  		err := Encode(Atom("Ergo Framework"), buf, EncodeOptions{})
  1123  		if err != nil {
  1124  			b.Fatal(err)
  1125  		}
  1126  	}
  1127  }
  1128  
  1129  func BenchmarkEncodeAtomWithCache(b *testing.B) {
  1130  	buf := lib.TakeBuffer()
  1131  	defer lib.ReleaseBuffer(buf)
  1132  
  1133  	senderAtomCache := make(map[Atom]CacheItem)
  1134  	encodingAtomCache := TakeEncodingAtomCache()
  1135  	atomCache := NewAtomCache()
  1136  
  1137  	ci := CacheItem{ID: 2020, Encoded: true, Name: "cached atom"}
  1138  	senderAtomCache["cached atom"] = ci
  1139  
  1140  	encodeOptions := EncodeOptions{
  1141  		AtomCache:         atomCache.Out,
  1142  		SenderAtomCache:   senderAtomCache,
  1143  		EncodingAtomCache: encodingAtomCache,
  1144  	}
  1145  
  1146  	b.ResetTimer()
  1147  	for i := 0; i < b.N; i++ {
  1148  		err := Encode(Atom("cached atom"), buf, encodeOptions)
  1149  		buf.Reset()
  1150  		if err != nil {
  1151  			b.Fatal(err)
  1152  		}
  1153  	}
  1154  
  1155  }
  1156  
  1157  func BenchmarkEncodeBinary(b *testing.B) {
  1158  	buf := lib.TakeBuffer()
  1159  	defer lib.ReleaseBuffer(buf)
  1160  	bytes := []byte{1, 2, 3, 4, 5}
  1161  	b.ResetTimer()
  1162  	for i := 0; i < b.N; i++ {
  1163  		err := Encode(bytes, buf, EncodeOptions{})
  1164  		buf.Reset()
  1165  		if err != nil {
  1166  			b.Fatal(err)
  1167  		}
  1168  	}
  1169  }
  1170  
  1171  func BenchmarkEncodeList(b *testing.B) {
  1172  	buf := lib.TakeBuffer()
  1173  	defer lib.ReleaseBuffer(buf)
  1174  
  1175  	term := List{Atom("a"), 2, 3}
  1176  	b.ResetTimer()
  1177  
  1178  	for i := 0; i < b.N; i++ {
  1179  		err := Encode(term, buf, EncodeOptions{})
  1180  		buf.Reset()
  1181  		if err != nil {
  1182  			b.Fatal(err)
  1183  		}
  1184  	}
  1185  
  1186  }
  1187  
  1188  func BenchmarkEncodeListNested(b *testing.B) {
  1189  	buf := lib.TakeBuffer()
  1190  	defer lib.ReleaseBuffer(buf)
  1191  
  1192  	term := List{Atom("a"), List{Atom("b"), 2, List{Atom("c"), 3}, 4}}
  1193  	b.ResetTimer()
  1194  
  1195  	for i := 0; i < b.N; i++ {
  1196  		err := Encode(term, buf, EncodeOptions{})
  1197  		buf.Reset()
  1198  		if err != nil {
  1199  			b.Fatal(err)
  1200  		}
  1201  	}
  1202  
  1203  }
  1204  
  1205  func BenchmarkEncodeTuple(b *testing.B) {
  1206  	buf := lib.TakeBuffer()
  1207  	defer lib.ReleaseBuffer(buf)
  1208  
  1209  	term := Tuple{Atom("a"), 2, 3}
  1210  	b.ResetTimer()
  1211  
  1212  	for i := 0; i < b.N; i++ {
  1213  		err := Encode(term, buf, EncodeOptions{})
  1214  		buf.Reset()
  1215  		if err != nil {
  1216  			b.Fatal(err)
  1217  		}
  1218  	}
  1219  
  1220  }
  1221  
  1222  func BenchmarkEncodeTupleNested(b *testing.B) {
  1223  	buf := lib.TakeBuffer()
  1224  	defer lib.ReleaseBuffer(buf)
  1225  
  1226  	term := Tuple{Atom("a"), Tuple{Atom("b"), 2, Tuple{Atom("c"), 3}, 4}}
  1227  	b.ResetTimer()
  1228  
  1229  	for i := 0; i < b.N; i++ {
  1230  		err := Encode(term, buf, EncodeOptions{})
  1231  		buf.Reset()
  1232  		if err != nil {
  1233  			b.Fatal(err)
  1234  		}
  1235  	}
  1236  
  1237  }
  1238  
  1239  func BenchmarkEncodeSlice(b *testing.B) {
  1240  	buf := lib.TakeBuffer()
  1241  	defer lib.ReleaseBuffer(buf)
  1242  
  1243  	term := []int{12345, 67890, 12345, 67890}
  1244  	b.ResetTimer()
  1245  
  1246  	for i := 0; i < b.N; i++ {
  1247  		err := Encode(term, buf, EncodeOptions{})
  1248  		buf.Reset()
  1249  		if err != nil {
  1250  			b.Fatal(err)
  1251  		}
  1252  	}
  1253  }
  1254  
  1255  func BenchmarkEncodeArray(b *testing.B) {
  1256  	buf := lib.TakeBuffer()
  1257  	defer lib.ReleaseBuffer(buf)
  1258  
  1259  	term := [4]int{12345, 67890, 12345, 67890}
  1260  	b.ResetTimer()
  1261  
  1262  	for i := 0; i < b.N; i++ {
  1263  		err := Encode(term, buf, EncodeOptions{})
  1264  		buf.Reset()
  1265  		if err != nil {
  1266  			b.Fatal(err)
  1267  		}
  1268  	}
  1269  }
  1270  
  1271  func BenchmarkEncodeMap(b *testing.B) {
  1272  	buf := lib.TakeBuffer()
  1273  	defer lib.ReleaseBuffer(buf)
  1274  
  1275  	term := Map{
  1276  		Atom("key1"): 12345,
  1277  		Atom("key2"): "hello world",
  1278  	}
  1279  	b.ResetTimer()
  1280  
  1281  	for i := 0; i < b.N; i++ {
  1282  		err := Encode(term, buf, EncodeOptions{})
  1283  		buf.Reset()
  1284  		if err != nil {
  1285  			b.Fatal(err)
  1286  		}
  1287  	}
  1288  }
  1289  
  1290  func BenchmarkEncodeGoMap(b *testing.B) {
  1291  	buf := lib.TakeBuffer()
  1292  	defer lib.ReleaseBuffer(buf)
  1293  
  1294  	term := map[Atom]interface{}{
  1295  		Atom("key1"): 12345,
  1296  		Atom("key2"): "hello world",
  1297  	}
  1298  	b.ResetTimer()
  1299  
  1300  	for i := 0; i < b.N; i++ {
  1301  		err := Encode(term, buf, EncodeOptions{})
  1302  		buf.Reset()
  1303  		if err != nil {
  1304  			b.Fatal(err)
  1305  		}
  1306  	}
  1307  }
  1308  
  1309  func BenchmarkEncodeGoStruct(b *testing.B) {
  1310  	buf := lib.TakeBuffer()
  1311  	defer lib.ReleaseBuffer(buf)
  1312  
  1313  	term := struct {
  1314  		StructToMapKey1 int
  1315  		StructToMapKey2 string
  1316  	}{
  1317  		StructToMapKey1: 12345,
  1318  		StructToMapKey2: "hello world",
  1319  	}
  1320  	b.ResetTimer()
  1321  
  1322  	for i := 0; i < b.N; i++ {
  1323  		err := Encode(term, buf, EncodeOptions{})
  1324  		buf.Reset()
  1325  		if err != nil {
  1326  			b.Fatal(err)
  1327  		}
  1328  	}
  1329  }
  1330  
  1331  func BenchmarkEncodePid(b *testing.B) {
  1332  	buf := lib.TakeBuffer()
  1333  	defer lib.ReleaseBuffer(buf)
  1334  
  1335  	term := Pid{Node: "erl-demo@127.0.0.1", ID: 312, Creation: 2}
  1336  
  1337  	b.ResetTimer()
  1338  	for i := 0; i < b.N; i++ {
  1339  		err := Encode(term, buf, EncodeOptions{})
  1340  		buf.Reset()
  1341  		if err != nil {
  1342  			b.Fatal(err)
  1343  		}
  1344  	}
  1345  }
  1346  
  1347  func BenchmarkEncodePidWithAtomCache(b *testing.B) {
  1348  	buf := lib.TakeBuffer()
  1349  	defer lib.ReleaseBuffer(buf)
  1350  
  1351  	term := Pid{Node: "erl-demo@127.0.0.1", ID: 312, Creation: 2}
  1352  
  1353  	senderAtomCache := make(map[Atom]CacheItem)
  1354  	encodingAtomCache := TakeEncodingAtomCache()
  1355  	atomCache := NewAtomCache()
  1356  
  1357  	ci := CacheItem{ID: 2020, Encoded: true, Name: "erl-demo@127.0.0.1"}
  1358  	senderAtomCache["erl-demo@127.0.0.1"] = ci
  1359  
  1360  	encodeOptions := EncodeOptions{
  1361  		AtomCache:         atomCache.Out,
  1362  		SenderAtomCache:   senderAtomCache,
  1363  		EncodingAtomCache: encodingAtomCache,
  1364  	}
  1365  
  1366  	b.ResetTimer()
  1367  	for i := 0; i < b.N; i++ {
  1368  		err := Encode(term, buf, encodeOptions)
  1369  		buf.Reset()
  1370  		if err != nil {
  1371  			b.Fatal(err)
  1372  		}
  1373  	}
  1374  }
  1375  
  1376  func BenchmarkEncodeRef(b *testing.B) {
  1377  	buf := lib.TakeBuffer()
  1378  	defer lib.ReleaseBuffer(buf)
  1379  
  1380  	term := Ref{
  1381  		Node:     Atom("erl-demo@127.0.0.1"),
  1382  		Creation: 2,
  1383  		ID:       [5]uint32{73444, 3082813441, 2373634851},
  1384  	}
  1385  
  1386  	for i := 0; i < b.N; i++ {
  1387  		err := Encode(term, buf, EncodeOptions{})
  1388  		buf.Reset()
  1389  		if err != nil {
  1390  			b.Fatal(err)
  1391  		}
  1392  	}
  1393  }
  1394  
  1395  func BenchmarkEncodeRefWithAtomCache(b *testing.B) {
  1396  	buf := lib.TakeBuffer()
  1397  	defer lib.ReleaseBuffer(buf)
  1398  
  1399  	term := Ref{
  1400  		Node:     Atom("erl-demo@127.0.0.1"),
  1401  		Creation: 2,
  1402  		ID:       [5]uint32{73444, 3082813441, 2373634851},
  1403  	}
  1404  
  1405  	senderAtomCache := make(map[Atom]CacheItem)
  1406  	encodingAtomCache := TakeEncodingAtomCache()
  1407  	atomCache := NewAtomCache()
  1408  
  1409  	ci := CacheItem{ID: 2020, Encoded: true, Name: "erl-demo@127.0.0.1"}
  1410  	senderAtomCache["erl-demo@127.0.0.1"] = ci
  1411  
  1412  	encodeOptions := EncodeOptions{
  1413  		AtomCache:         atomCache.Out,
  1414  		SenderAtomCache:   senderAtomCache,
  1415  		EncodingAtomCache: encodingAtomCache,
  1416  	}
  1417  
  1418  	b.ResetTimer()
  1419  	for i := 0; i < b.N; i++ {
  1420  		err := Encode(term, buf, encodeOptions)
  1421  		buf.Reset()
  1422  		if err != nil {
  1423  			b.Fatal(err)
  1424  		}
  1425  	}
  1426  }
  1427  
  1428  func BenchmarkEncodeTupleRefPid(b *testing.B) {
  1429  	buf := lib.TakeBuffer()
  1430  	defer lib.ReleaseBuffer(buf)
  1431  
  1432  	term := Tuple{
  1433  		Ref{
  1434  			Node:     Atom("erl-demo@127.0.0.1"),
  1435  			Creation: 2,
  1436  			ID:       [5]uint32{0x11f1c, 0xb7c00001, 0x8d7acb23}},
  1437  		Pid{
  1438  			Node:     Atom("erl-demo@127.0.0.1"),
  1439  			ID:       312,
  1440  			Creation: 2}}
  1441  
  1442  	b.ResetTimer()
  1443  	for i := 0; i < b.N; i++ {
  1444  		err := Encode(term, buf, EncodeOptions{})
  1445  		buf.Reset()
  1446  		if err != nil {
  1447  			b.Fatal(err)
  1448  		}
  1449  	}
  1450  }
  1451  
  1452  func BenchmarkEncodeTupleRefPidWithAtomCache(b *testing.B) {
  1453  	buf := lib.TakeBuffer()
  1454  	defer lib.ReleaseBuffer(buf)
  1455  
  1456  	term := Tuple{
  1457  		Ref{
  1458  			Node:     Atom("erl-demo@127.0.0.1"),
  1459  			Creation: 2,
  1460  			ID:       [5]uint32{0x11f1c, 0xb7c00001, 0x8d7acb23}},
  1461  		Pid{
  1462  			Node:     Atom("erl-demo@127.0.0.1"),
  1463  			ID:       312,
  1464  			Creation: 2}}
  1465  
  1466  	senderAtomCache := make(map[Atom]CacheItem)
  1467  	encodingAtomCache := TakeEncodingAtomCache()
  1468  	defer ReleaseEncodingAtomCache(encodingAtomCache)
  1469  	atomCache := NewAtomCache()
  1470  
  1471  	ci := CacheItem{ID: 2020, Encoded: true, Name: "erl-demo@127.0.0.1"}
  1472  	senderAtomCache["erl-demo@127.0.0.1"] = ci
  1473  
  1474  	encodeOptions := EncodeOptions{
  1475  		AtomCache:         atomCache.Out,
  1476  		SenderAtomCache:   senderAtomCache,
  1477  		EncodingAtomCache: encodingAtomCache,
  1478  	}
  1479  
  1480  	b.ResetTimer()
  1481  	for i := 0; i < b.N; i++ {
  1482  		err := Encode(term, buf, encodeOptions)
  1483  		buf.Reset()
  1484  		encodingAtomCache.Reset()
  1485  		if err != nil {
  1486  			b.Fatal(err)
  1487  		}
  1488  	}
  1489  }