/*
 * 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"
)

// MockWriteBufferByteBased is an autogenerated mock type for the WriteBufferByteBased type
type MockWriteBufferByteBased struct {
	mock.Mock
}

type MockWriteBufferByteBased_Expecter struct {
	mock *mock.Mock
}

func (_m *MockWriteBufferByteBased) EXPECT() *MockWriteBufferByteBased_Expecter {
	return &MockWriteBufferByteBased_Expecter{mock: &_m.Mock}
}

// GetBytes provides a mock function with given fields:
func (_m *MockWriteBufferByteBased) GetBytes() []byte {
	ret := _m.Called()

	var r0 []byte
	if rf, ok := ret.Get(0).(func() []byte); ok {
		r0 = rf()
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]byte)
		}
	}

	return r0
}

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

// GetBytes is a helper method to define mock.On call
func (_e *MockWriteBufferByteBased_Expecter) GetBytes() *MockWriteBufferByteBased_GetBytes_Call {
	return &MockWriteBufferByteBased_GetBytes_Call{Call: _e.mock.On("GetBytes")}
}

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

func (_c *MockWriteBufferByteBased_GetBytes_Call) Return(_a0 []byte) *MockWriteBufferByteBased_GetBytes_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferByteBased_GetBytes_Call) RunAndReturn(run func() []byte) *MockWriteBufferByteBased_GetBytes_Call {
	_c.Call.Return(run)
	return _c
}

// GetPos provides a mock function with given fields:
func (_m *MockWriteBufferByteBased) 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
}

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

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

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

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

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

// GetTotalBytes provides a mock function with given fields:
func (_m *MockWriteBufferByteBased) GetTotalBytes() uint64 {
	ret := _m.Called()

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

	return r0
}

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

// GetTotalBytes is a helper method to define mock.On call
func (_e *MockWriteBufferByteBased_Expecter) GetTotalBytes() *MockWriteBufferByteBased_GetTotalBytes_Call {
	return &MockWriteBufferByteBased_GetTotalBytes_Call{Call: _e.mock.On("GetTotalBytes")}
}

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

func (_c *MockWriteBufferByteBased_GetTotalBytes_Call) Return(_a0 uint64) *MockWriteBufferByteBased_GetTotalBytes_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferByteBased_GetTotalBytes_Call) RunAndReturn(run func() uint64) *MockWriteBufferByteBased_GetTotalBytes_Call {
	_c.Call.Return(run)
	return _c
}

// PopContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

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

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

func (_c *MockWriteBufferByteBased_PopContext_Call) Run(run func(logicalName string, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_PopContext_Call) Return(_a0 error) *MockWriteBufferByteBased_PopContext_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// PushContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

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

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

func (_c *MockWriteBufferByteBased_PushContext_Call) Run(run func(logicalName string, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_PushContext_Call) Return(_a0 error) *MockWriteBufferByteBased_PushContext_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteBigFloat provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteBigFloat_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigFloat'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteBigFloat(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteBigFloat_Call {
	return &MockWriteBufferByteBased_WriteBigFloat_Call{Call: _e.mock.On("WriteBigFloat",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteBigFloat_Call) Run(run func(logicalName string, bitLength uint8, value *big.Float, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteBigFloat_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteBigFloat_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteBigInt provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteBigInt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigInt'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteBigInt(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteBigInt_Call {
	return &MockWriteBufferByteBased_WriteBigInt_Call{Call: _e.mock.On("WriteBigInt",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteBigInt_Call) Run(run func(logicalName string, bitLength uint8, value *big.Int, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteBigInt_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteBigInt_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteBit provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

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

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

func (_c *MockWriteBufferByteBased_WriteBit_Call) Run(run func(logicalName string, value bool, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteBit_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteBit_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteByte provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

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

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

func (_c *MockWriteBufferByteBased_WriteByte_Call) Run(run func(logicalName string, value byte, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteByte_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteByte_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteByteArray provides a mock function with given fields: logicalName, data, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

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

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

func (_c *MockWriteBufferByteBased_WriteByteArray_Call) Run(run func(logicalName string, data []byte, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteByteArray_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteByteArray_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteFloat32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteFloat32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat32'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteFloat32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteFloat32_Call {
	return &MockWriteBufferByteBased_WriteFloat32_Call{Call: _e.mock.On("WriteFloat32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteFloat32_Call) Run(run func(logicalName string, bitLength uint8, value float32, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteFloat32_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteFloat32_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteFloat64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteFloat64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat64'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteFloat64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteFloat64_Call {
	return &MockWriteBufferByteBased_WriteFloat64_Call{Call: _e.mock.On("WriteFloat64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteFloat64_Call) Run(run func(logicalName string, bitLength uint8, value float64, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteFloat64_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteFloat64_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteInt16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteInt16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt16'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteInt16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteInt16_Call {
	return &MockWriteBufferByteBased_WriteInt16_Call{Call: _e.mock.On("WriteInt16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteInt16_Call) Run(run func(logicalName string, bitLength uint8, value int16, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteInt16_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteInt16_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteInt32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteInt32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt32'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteInt32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteInt32_Call {
	return &MockWriteBufferByteBased_WriteInt32_Call{Call: _e.mock.On("WriteInt32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteInt32_Call) Run(run func(logicalName string, bitLength uint8, value int32, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteInt32_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteInt32_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteInt64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteInt64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt64'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteInt64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteInt64_Call {
	return &MockWriteBufferByteBased_WriteInt64_Call{Call: _e.mock.On("WriteInt64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteInt64_Call) Run(run func(logicalName string, bitLength uint8, value int64, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteInt64_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteInt64_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteInt8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteInt8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt8'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteInt8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteInt8_Call {
	return &MockWriteBufferByteBased_WriteInt8_Call{Call: _e.mock.On("WriteInt8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteInt8_Call) Run(run func(logicalName string, bitLength uint8, value int8, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteInt8_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteInt8_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteSerializable provides a mock function with given fields: ctx, serializable
func (_m *MockWriteBufferByteBased) 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
}

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

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

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

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

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

// WriteString provides a mock function with given fields: logicalName, bitLength, encoding, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteString'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteString(logicalName interface{}, bitLength interface{}, encoding interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteString_Call {
	return &MockWriteBufferByteBased_WriteString_Call{Call: _e.mock.On("WriteString",
		append([]interface{}{logicalName, bitLength, encoding, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteString_Call) Run(run func(logicalName string, bitLength uint32, encoding string, value string, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteString_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteString_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteUint16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteUint16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint16'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteUint16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteUint16_Call {
	return &MockWriteBufferByteBased_WriteUint16_Call{Call: _e.mock.On("WriteUint16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteUint16_Call) Run(run func(logicalName string, bitLength uint8, value uint16, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteUint16_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteUint16_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteUint32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteUint32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint32'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteUint32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteUint32_Call {
	return &MockWriteBufferByteBased_WriteUint32_Call{Call: _e.mock.On("WriteUint32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteUint32_Call) Run(run func(logicalName string, bitLength uint8, value uint32, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteUint32_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteUint32_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteUint64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteUint64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint64'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteUint64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteUint64_Call {
	return &MockWriteBufferByteBased_WriteUint64_Call{Call: _e.mock.On("WriteUint64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteUint64_Call) Run(run func(logicalName string, bitLength uint8, value uint64, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteUint64_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteUint64_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteUint8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteUint8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint8'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteUint8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteUint8_Call {
	return &MockWriteBufferByteBased_WriteUint8_Call{Call: _e.mock.On("WriteUint8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteUint8_Call) Run(run func(logicalName string, bitLength uint8, value uint8, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteUint8_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteUint8_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// WriteVirtual provides a mock function with given fields: ctx, logicalName, value, writerArgs
func (_m *MockWriteBufferByteBased) 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
}

// MockWriteBufferByteBased_WriteVirtual_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteVirtual'
type MockWriteBufferByteBased_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 *MockWriteBufferByteBased_Expecter) WriteVirtual(ctx interface{}, logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferByteBased_WriteVirtual_Call {
	return &MockWriteBufferByteBased_WriteVirtual_Call{Call: _e.mock.On("WriteVirtual",
		append([]interface{}{ctx, logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferByteBased_WriteVirtual_Call) Run(run func(ctx context.Context, logicalName string, value interface{}, writerArgs ...WithWriterArgs)) *MockWriteBufferByteBased_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 *MockWriteBufferByteBased_WriteVirtual_Call) Return(_a0 error) *MockWriteBufferByteBased_WriteVirtual_Call {
	_c.Call.Return(_a0)
	return _c
}

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

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

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

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

	return mock
}
