/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// Code generated by mockery v2.28.2. DO NOT EDIT.

package utils

import (
	context "context"
	big "math/big"

	mock "github.com/stretchr/testify/mock"
)

// MockWriteBufferBoxBased is an autogenerated mock type for the WriteBufferBoxBased type
type MockWriteBufferBoxBased struct {
	mock.Mock
}

type MockWriteBufferBoxBased_Expecter struct {
	mock *mock.Mock
}

func (_m *MockWriteBufferBoxBased) EXPECT() *MockWriteBufferBoxBased_Expecter {
	return &MockWriteBufferBoxBased_Expecter{mock: &_m.Mock}
}

// GetBox provides a mock function with given fields:
func (_m *MockWriteBufferBoxBased) GetBox() AsciiBox {
	ret := _m.Called()

	var r0 AsciiBox
	if rf, ok := ret.Get(0).(func() AsciiBox); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(AsciiBox)
	}

	return r0
}

// MockWriteBufferBoxBased_GetBox_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBox'
type MockWriteBufferBoxBased_GetBox_Call struct {
	*mock.Call
}

// GetBox is a helper method to define mock.On call
func (_e *MockWriteBufferBoxBased_Expecter) GetBox() *MockWriteBufferBoxBased_GetBox_Call {
	return &MockWriteBufferBoxBased_GetBox_Call{Call: _e.mock.On("GetBox")}
}

func (_c *MockWriteBufferBoxBased_GetBox_Call) Run(run func()) *MockWriteBufferBoxBased_GetBox_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run()
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_GetBox_Call) Return(_a0 AsciiBox) *MockWriteBufferBoxBased_GetBox_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_GetBox_Call) RunAndReturn(run func() AsciiBox) *MockWriteBufferBoxBased_GetBox_Call {
	_c.Call.Return(run)
	return _c
}

// GetPos provides a mock function with given fields:
func (_m *MockWriteBufferBoxBased) GetPos() uint16 {
	ret := _m.Called()

	var r0 uint16
	if rf, ok := ret.Get(0).(func() uint16); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(uint16)
	}

	return r0
}

// MockWriteBufferBoxBased_GetPos_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPos'
type MockWriteBufferBoxBased_GetPos_Call struct {
	*mock.Call
}

// GetPos is a helper method to define mock.On call
func (_e *MockWriteBufferBoxBased_Expecter) GetPos() *MockWriteBufferBoxBased_GetPos_Call {
	return &MockWriteBufferBoxBased_GetPos_Call{Call: _e.mock.On("GetPos")}
}

func (_c *MockWriteBufferBoxBased_GetPos_Call) Run(run func()) *MockWriteBufferBoxBased_GetPos_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run()
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_GetPos_Call) Return(_a0 uint16) *MockWriteBufferBoxBased_GetPos_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_GetPos_Call) RunAndReturn(run func() uint16) *MockWriteBufferBoxBased_GetPos_Call {
	_c.Call.Return(run)
	return _c
}

// PopContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferBoxBased) PopContext(logicalName string, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_PopContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PopContext'
type MockWriteBufferBoxBased_PopContext_Call struct {
	*mock.Call
}

// PopContext is a helper method to define mock.On call
//   - logicalName string
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) PopContext(logicalName interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_PopContext_Call {
	return &MockWriteBufferBoxBased_PopContext_Call{Call: _e.mock.On("PopContext",
		append([]interface{}{logicalName}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_PopContext_Call) Run(run func(logicalName string, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_PopContext_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-1)
		for i, a := range args[1:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_PopContext_Call) Return(_a0 error) *MockWriteBufferBoxBased_PopContext_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_PopContext_Call) RunAndReturn(run func(string, ...WithWriterArgs) error) *MockWriteBufferBoxBased_PopContext_Call {
	_c.Call.Return(run)
	return _c
}

// PushContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferBoxBased) PushContext(logicalName string, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_PushContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PushContext'
type MockWriteBufferBoxBased_PushContext_Call struct {
	*mock.Call
}

// PushContext is a helper method to define mock.On call
//   - logicalName string
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) PushContext(logicalName interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_PushContext_Call {
	return &MockWriteBufferBoxBased_PushContext_Call{Call: _e.mock.On("PushContext",
		append([]interface{}{logicalName}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_PushContext_Call) Run(run func(logicalName string, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_PushContext_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-1)
		for i, a := range args[1:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_PushContext_Call) Return(_a0 error) *MockWriteBufferBoxBased_PushContext_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_PushContext_Call) RunAndReturn(run func(string, ...WithWriterArgs) error) *MockWriteBufferBoxBased_PushContext_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBigFloat provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteBigFloat(logicalName string, bitLength uint8, value *big.Float, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, *big.Float, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteBigFloat_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigFloat'
type MockWriteBufferBoxBased_WriteBigFloat_Call struct {
	*mock.Call
}

// WriteBigFloat is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value *big.Float
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteBigFloat(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteBigFloat_Call {
	return &MockWriteBufferBoxBased_WriteBigFloat_Call{Call: _e.mock.On("WriteBigFloat",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteBigFloat_Call) Run(run func(logicalName string, bitLength uint8, value *big.Float, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteBigFloat_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(*big.Float), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBigFloat_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteBigFloat_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBigFloat_Call) RunAndReturn(run func(string, uint8, *big.Float, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteBigFloat_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBigInt provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteBigInt(logicalName string, bitLength uint8, value *big.Int, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, *big.Int, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteBigInt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigInt'
type MockWriteBufferBoxBased_WriteBigInt_Call struct {
	*mock.Call
}

// WriteBigInt is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value *big.Int
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteBigInt(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteBigInt_Call {
	return &MockWriteBufferBoxBased_WriteBigInt_Call{Call: _e.mock.On("WriteBigInt",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteBigInt_Call) Run(run func(logicalName string, bitLength uint8, value *big.Int, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteBigInt_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(*big.Int), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBigInt_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteBigInt_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBigInt_Call) RunAndReturn(run func(string, uint8, *big.Int, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteBigInt_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBit provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteBit(logicalName string, value bool, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, bool, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteBit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBit'
type MockWriteBufferBoxBased_WriteBit_Call struct {
	*mock.Call
}

// WriteBit is a helper method to define mock.On call
//   - logicalName string
//   - value bool
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteBit(logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteBit_Call {
	return &MockWriteBufferBoxBased_WriteBit_Call{Call: _e.mock.On("WriteBit",
		append([]interface{}{logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteBit_Call) Run(run func(logicalName string, value bool, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteBit_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(bool), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBit_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteBit_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteBit_Call) RunAndReturn(run func(string, bool, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteBit_Call {
	_c.Call.Return(run)
	return _c
}

// WriteByte provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteByte(logicalName string, value byte, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, byte, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteByte_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteByte'
type MockWriteBufferBoxBased_WriteByte_Call struct {
	*mock.Call
}

// WriteByte is a helper method to define mock.On call
//   - logicalName string
//   - value byte
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteByte(logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteByte_Call {
	return &MockWriteBufferBoxBased_WriteByte_Call{Call: _e.mock.On("WriteByte",
		append([]interface{}{logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteByte_Call) Run(run func(logicalName string, value byte, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteByte_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(byte), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteByte_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteByte_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteByte_Call) RunAndReturn(run func(string, byte, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteByte_Call {
	_c.Call.Return(run)
	return _c
}

// WriteByteArray provides a mock function with given fields: logicalName, data, writerArgs
func (_m *MockWriteBufferBoxBased) WriteByteArray(logicalName string, data []byte, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, data)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, []byte, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, data, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteByteArray_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteByteArray'
type MockWriteBufferBoxBased_WriteByteArray_Call struct {
	*mock.Call
}

// WriteByteArray is a helper method to define mock.On call
//   - logicalName string
//   - data []byte
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteByteArray(logicalName interface{}, data interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteByteArray_Call {
	return &MockWriteBufferBoxBased_WriteByteArray_Call{Call: _e.mock.On("WriteByteArray",
		append([]interface{}{logicalName, data}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteByteArray_Call) Run(run func(logicalName string, data []byte, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteByteArray_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].([]byte), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteByteArray_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteByteArray_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteByteArray_Call) RunAndReturn(run func(string, []byte, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteByteArray_Call {
	_c.Call.Return(run)
	return _c
}

// WriteFloat32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteFloat32(logicalName string, bitLength uint8, value float32, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, float32, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteFloat32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat32'
type MockWriteBufferBoxBased_WriteFloat32_Call struct {
	*mock.Call
}

// WriteFloat32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value float32
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteFloat32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteFloat32_Call {
	return &MockWriteBufferBoxBased_WriteFloat32_Call{Call: _e.mock.On("WriteFloat32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteFloat32_Call) Run(run func(logicalName string, bitLength uint8, value float32, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteFloat32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(float32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteFloat32_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteFloat32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteFloat32_Call) RunAndReturn(run func(string, uint8, float32, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteFloat32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteFloat64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteFloat64(logicalName string, bitLength uint8, value float64, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, float64, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteFloat64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat64'
type MockWriteBufferBoxBased_WriteFloat64_Call struct {
	*mock.Call
}

// WriteFloat64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value float64
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteFloat64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteFloat64_Call {
	return &MockWriteBufferBoxBased_WriteFloat64_Call{Call: _e.mock.On("WriteFloat64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteFloat64_Call) Run(run func(logicalName string, bitLength uint8, value float64, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteFloat64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(float64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteFloat64_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteFloat64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteFloat64_Call) RunAndReturn(run func(string, uint8, float64, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteFloat64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteInt16(logicalName string, bitLength uint8, value int16, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int16, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteInt16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt16'
type MockWriteBufferBoxBased_WriteInt16_Call struct {
	*mock.Call
}

// WriteInt16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int16
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteInt16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteInt16_Call {
	return &MockWriteBufferBoxBased_WriteInt16_Call{Call: _e.mock.On("WriteInt16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteInt16_Call) Run(run func(logicalName string, bitLength uint8, value int16, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteInt16_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int16), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt16_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteInt16_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt16_Call) RunAndReturn(run func(string, uint8, int16, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteInt16_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteInt32(logicalName string, bitLength uint8, value int32, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int32, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteInt32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt32'
type MockWriteBufferBoxBased_WriteInt32_Call struct {
	*mock.Call
}

// WriteInt32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int32
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteInt32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteInt32_Call {
	return &MockWriteBufferBoxBased_WriteInt32_Call{Call: _e.mock.On("WriteInt32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteInt32_Call) Run(run func(logicalName string, bitLength uint8, value int32, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteInt32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt32_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteInt32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt32_Call) RunAndReturn(run func(string, uint8, int32, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteInt32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteInt64(logicalName string, bitLength uint8, value int64, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int64, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteInt64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt64'
type MockWriteBufferBoxBased_WriteInt64_Call struct {
	*mock.Call
}

// WriteInt64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int64
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteInt64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteInt64_Call {
	return &MockWriteBufferBoxBased_WriteInt64_Call{Call: _e.mock.On("WriteInt64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteInt64_Call) Run(run func(logicalName string, bitLength uint8, value int64, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteInt64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt64_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteInt64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt64_Call) RunAndReturn(run func(string, uint8, int64, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteInt64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteInt8(logicalName string, bitLength uint8, value int8, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int8, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteInt8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt8'
type MockWriteBufferBoxBased_WriteInt8_Call struct {
	*mock.Call
}

// WriteInt8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int8
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteInt8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteInt8_Call {
	return &MockWriteBufferBoxBased_WriteInt8_Call{Call: _e.mock.On("WriteInt8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteInt8_Call) Run(run func(logicalName string, bitLength uint8, value int8, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteInt8_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int8), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt8_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteInt8_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteInt8_Call) RunAndReturn(run func(string, uint8, int8, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteInt8_Call {
	_c.Call.Return(run)
	return _c
}

// WriteSerializable provides a mock function with given fields: ctx, serializable
func (_m *MockWriteBufferBoxBased) WriteSerializable(ctx context.Context, serializable Serializable) error {
	ret := _m.Called(ctx, serializable)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, Serializable) error); ok {
		r0 = rf(ctx, serializable)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteSerializable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteSerializable'
type MockWriteBufferBoxBased_WriteSerializable_Call struct {
	*mock.Call
}

// WriteSerializable is a helper method to define mock.On call
//   - ctx context.Context
//   - serializable Serializable
func (_e *MockWriteBufferBoxBased_Expecter) WriteSerializable(ctx interface{}, serializable interface{}) *MockWriteBufferBoxBased_WriteSerializable_Call {
	return &MockWriteBufferBoxBased_WriteSerializable_Call{Call: _e.mock.On("WriteSerializable", ctx, serializable)}
}

func (_c *MockWriteBufferBoxBased_WriteSerializable_Call) Run(run func(ctx context.Context, serializable Serializable)) *MockWriteBufferBoxBased_WriteSerializable_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(context.Context), args[1].(Serializable))
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteSerializable_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteSerializable_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteSerializable_Call) RunAndReturn(run func(context.Context, Serializable) error) *MockWriteBufferBoxBased_WriteSerializable_Call {
	_c.Call.Return(run)
	return _c
}

// WriteString provides a mock function with given fields: logicalName, bitLength, encoding, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteString(logicalName string, bitLength uint32, encoding string, value string, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, encoding, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint32, string, string, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, encoding, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteString'
type MockWriteBufferBoxBased_WriteString_Call struct {
	*mock.Call
}

// WriteString is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint32
//   - encoding string
//   - value string
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteString(logicalName interface{}, bitLength interface{}, encoding interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteString_Call {
	return &MockWriteBufferBoxBased_WriteString_Call{Call: _e.mock.On("WriteString",
		append([]interface{}{logicalName, bitLength, encoding, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteString_Call) Run(run func(logicalName string, bitLength uint32, encoding string, value string, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteString_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-4)
		for i, a := range args[4:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint32), args[2].(string), args[3].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteString_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteString_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteString_Call) RunAndReturn(run func(string, uint32, string, string, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteString_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteUint16(logicalName string, bitLength uint8, value uint16, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint16, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteUint16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint16'
type MockWriteBufferBoxBased_WriteUint16_Call struct {
	*mock.Call
}

// WriteUint16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint16
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteUint16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteUint16_Call {
	return &MockWriteBufferBoxBased_WriteUint16_Call{Call: _e.mock.On("WriteUint16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteUint16_Call) Run(run func(logicalName string, bitLength uint8, value uint16, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteUint16_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint16), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint16_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteUint16_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint16_Call) RunAndReturn(run func(string, uint8, uint16, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteUint16_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteUint32(logicalName string, bitLength uint8, value uint32, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint32, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteUint32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint32'
type MockWriteBufferBoxBased_WriteUint32_Call struct {
	*mock.Call
}

// WriteUint32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint32
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteUint32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteUint32_Call {
	return &MockWriteBufferBoxBased_WriteUint32_Call{Call: _e.mock.On("WriteUint32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteUint32_Call) Run(run func(logicalName string, bitLength uint8, value uint32, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteUint32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint32_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteUint32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint32_Call) RunAndReturn(run func(string, uint8, uint32, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteUint32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteUint64(logicalName string, bitLength uint8, value uint64, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint64, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteUint64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint64'
type MockWriteBufferBoxBased_WriteUint64_Call struct {
	*mock.Call
}

// WriteUint64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint64
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteUint64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteUint64_Call {
	return &MockWriteBufferBoxBased_WriteUint64_Call{Call: _e.mock.On("WriteUint64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteUint64_Call) Run(run func(logicalName string, bitLength uint8, value uint64, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteUint64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint64_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteUint64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint64_Call) RunAndReturn(run func(string, uint8, uint64, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteUint64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteUint8(logicalName string, bitLength uint8, value uint8, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint8, ...WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteUint8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint8'
type MockWriteBufferBoxBased_WriteUint8_Call struct {
	*mock.Call
}

// WriteUint8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint8
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteUint8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteUint8_Call {
	return &MockWriteBufferBoxBased_WriteUint8_Call{Call: _e.mock.On("WriteUint8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteUint8_Call) Run(run func(logicalName string, bitLength uint8, value uint8, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteUint8_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint8), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint8_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteUint8_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteUint8_Call) RunAndReturn(run func(string, uint8, uint8, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteUint8_Call {
	_c.Call.Return(run)
	return _c
}

// WriteVirtual provides a mock function with given fields: ctx, logicalName, value, writerArgs
func (_m *MockWriteBufferBoxBased) WriteVirtual(ctx context.Context, logicalName string, value interface{}, writerArgs ...WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, interface{}, ...WithWriterArgs) error); ok {
		r0 = rf(ctx, logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferBoxBased_WriteVirtual_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteVirtual'
type MockWriteBufferBoxBased_WriteVirtual_Call struct {
	*mock.Call
}

// WriteVirtual is a helper method to define mock.On call
//   - ctx context.Context
//   - logicalName string
//   - value interface{}
//   - writerArgs ...WithWriterArgs
func (_e *MockWriteBufferBoxBased_Expecter) WriteVirtual(ctx interface{}, logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferBoxBased_WriteVirtual_Call {
	return &MockWriteBufferBoxBased_WriteVirtual_Call{Call: _e.mock.On("WriteVirtual",
		append([]interface{}{ctx, logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferBoxBased_WriteVirtual_Call) Run(run func(ctx context.Context, logicalName string, value interface{}, writerArgs ...WithWriterArgs)) *MockWriteBufferBoxBased_WriteVirtual_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(WithWriterArgs)
			}
		}
		run(args[0].(context.Context), args[1].(string), args[2].(interface{}), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteVirtual_Call) Return(_a0 error) *MockWriteBufferBoxBased_WriteVirtual_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferBoxBased_WriteVirtual_Call) RunAndReturn(run func(context.Context, string, interface{}, ...WithWriterArgs) error) *MockWriteBufferBoxBased_WriteVirtual_Call {
	_c.Call.Return(run)
	return _c
}

type mockConstructorTestingTNewMockWriteBufferBoxBased interface {
	mock.TestingT
	Cleanup(func())
}

// NewMockWriteBufferBoxBased creates a new instance of MockWriteBufferBoxBased. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewMockWriteBufferBoxBased(t mockConstructorTestingTNewMockWriteBufferBoxBased) *MockWriteBufferBoxBased {
	mock := &MockWriteBufferBoxBased{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
