/*
 * 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 (
	big "math/big"

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

// MockReadBufferByteBased is an autogenerated mock type for the ReadBufferByteBased type
type MockReadBufferByteBased struct {
	mock.Mock
}

type MockReadBufferByteBased_Expecter struct {
	mock *mock.Mock
}

func (_m *MockReadBufferByteBased) EXPECT() *MockReadBufferByteBased_Expecter {
	return &MockReadBufferByteBased_Expecter{mock: &_m.Mock}
}

// CloseContext provides a mock function with given fields: logicalName, readerArgs
func (_m *MockReadBufferByteBased) CloseContext(logicalName string, readerArgs ...WithReaderArgs) error {
	_va := make([]interface{}, len(readerArgs))
	for _i := range readerArgs {
		_va[_i] = readerArgs[_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, ...WithReaderArgs) error); ok {
		r0 = rf(logicalName, readerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

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

// CloseContext is a helper method to define mock.On call
//   - logicalName string
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) CloseContext(logicalName interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_CloseContext_Call {
	return &MockReadBufferByteBased_CloseContext_Call{Call: _e.mock.On("CloseContext",
		append([]interface{}{logicalName}, readerArgs...)...)}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// HasMore provides a mock function with given fields: bitLength
func (_m *MockReadBufferByteBased) HasMore(bitLength uint8) bool {
	ret := _m.Called(bitLength)

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

	return r0
}

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

// HasMore is a helper method to define mock.On call
//   - bitLength uint8
func (_e *MockReadBufferByteBased_Expecter) HasMore(bitLength interface{}) *MockReadBufferByteBased_HasMore_Call {
	return &MockReadBufferByteBased_HasMore_Call{Call: _e.mock.On("HasMore", bitLength)}
}

func (_c *MockReadBufferByteBased_HasMore_Call) Run(run func(bitLength uint8)) *MockReadBufferByteBased_HasMore_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(uint8))
	})
	return _c
}

func (_c *MockReadBufferByteBased_HasMore_Call) Return(_a0 bool) *MockReadBufferByteBased_HasMore_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockReadBufferByteBased_HasMore_Call) RunAndReturn(run func(uint8) bool) *MockReadBufferByteBased_HasMore_Call {
	_c.Call.Return(run)
	return _c
}

// PeekByte provides a mock function with given fields: offset
func (_m *MockReadBufferByteBased) PeekByte(offset byte) byte {
	ret := _m.Called(offset)

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

	return r0
}

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

// PeekByte is a helper method to define mock.On call
//   - offset byte
func (_e *MockReadBufferByteBased_Expecter) PeekByte(offset interface{}) *MockReadBufferByteBased_PeekByte_Call {
	return &MockReadBufferByteBased_PeekByte_Call{Call: _e.mock.On("PeekByte", offset)}
}

func (_c *MockReadBufferByteBased_PeekByte_Call) Run(run func(offset byte)) *MockReadBufferByteBased_PeekByte_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(byte))
	})
	return _c
}

func (_c *MockReadBufferByteBased_PeekByte_Call) Return(_a0 byte) *MockReadBufferByteBased_PeekByte_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockReadBufferByteBased_PeekByte_Call) RunAndReturn(run func(byte) byte) *MockReadBufferByteBased_PeekByte_Call {
	_c.Call.Return(run)
	return _c
}

// PullContext provides a mock function with given fields: logicalName, readerArgs
func (_m *MockReadBufferByteBased) PullContext(logicalName string, readerArgs ...WithReaderArgs) error {
	_va := make([]interface{}, len(readerArgs))
	for _i := range readerArgs {
		_va[_i] = readerArgs[_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, ...WithReaderArgs) error); ok {
		r0 = rf(logicalName, readerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

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

// PullContext is a helper method to define mock.On call
//   - logicalName string
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) PullContext(logicalName interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_PullContext_Call {
	return &MockReadBufferByteBased_PullContext_Call{Call: _e.mock.On("PullContext",
		append([]interface{}{logicalName}, readerArgs...)...)}
}

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

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

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

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

	var r0 *big.Float
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (*big.Float, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) *big.Float); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*big.Float)
		}
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadBigFloat is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadBigFloat(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadBigFloat_Call {
	return &MockReadBufferByteBased_ReadBigFloat_Call{Call: _e.mock.On("ReadBigFloat",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadBigFloat_Call) Return(_a0 *big.Float, _a1 error) *MockReadBufferByteBased_ReadBigFloat_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadBigInt provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBufferByteBased) ReadBigInt(logicalName string, bitLength uint64, readerArgs ...WithReaderArgs) (*big.Int, error) {
	_va := make([]interface{}, len(readerArgs))
	for _i := range readerArgs {
		_va[_i] = readerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 *big.Int
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint64, ...WithReaderArgs) (*big.Int, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint64, ...WithReaderArgs) *big.Int); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*big.Int)
		}
	}

	if rf, ok := ret.Get(1).(func(string, uint64, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadBigInt is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint64
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadBigInt(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadBigInt_Call {
	return &MockReadBufferByteBased_ReadBigInt_Call{Call: _e.mock.On("ReadBigInt",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadBigInt_Call) Return(_a0 *big.Int, _a1 error) *MockReadBufferByteBased_ReadBigInt_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

func (_c *MockReadBufferByteBased_ReadBigInt_Call) RunAndReturn(run func(string, uint64, ...WithReaderArgs) (*big.Int, error)) *MockReadBufferByteBased_ReadBigInt_Call {
	_c.Call.Return(run)
	return _c
}

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

	var r0 bool
	var r1 error
	if rf, ok := ret.Get(0).(func(string, ...WithReaderArgs) (bool, error)); ok {
		return rf(logicalName, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, ...WithReaderArgs) bool); ok {
		r0 = rf(logicalName, readerArgs...)
	} else {
		r0 = ret.Get(0).(bool)
	}

	if rf, ok := ret.Get(1).(func(string, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadBit is a helper method to define mock.On call
//   - logicalName string
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadBit(logicalName interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadBit_Call {
	return &MockReadBufferByteBased_ReadBit_Call{Call: _e.mock.On("ReadBit",
		append([]interface{}{logicalName}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadBit_Call) Return(_a0 bool, _a1 error) *MockReadBufferByteBased_ReadBit_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 byte
	var r1 error
	if rf, ok := ret.Get(0).(func(string, ...WithReaderArgs) (byte, error)); ok {
		return rf(logicalName, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, ...WithReaderArgs) byte); ok {
		r0 = rf(logicalName, readerArgs...)
	} else {
		r0 = ret.Get(0).(byte)
	}

	if rf, ok := ret.Get(1).(func(string, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadByte is a helper method to define mock.On call
//   - logicalName string
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadByte(logicalName interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadByte_Call {
	return &MockReadBufferByteBased_ReadByte_Call{Call: _e.mock.On("ReadByte",
		append([]interface{}{logicalName}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadByte_Call) Return(_a0 byte, _a1 error) *MockReadBufferByteBased_ReadByte_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadByteArray provides a mock function with given fields: logicalName, numberOfBytes, readerArgs
func (_m *MockReadBufferByteBased) ReadByteArray(logicalName string, numberOfBytes int, readerArgs ...WithReaderArgs) ([]byte, error) {
	_va := make([]interface{}, len(readerArgs))
	for _i := range readerArgs {
		_va[_i] = readerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, numberOfBytes)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 []byte
	var r1 error
	if rf, ok := ret.Get(0).(func(string, int, ...WithReaderArgs) ([]byte, error)); ok {
		return rf(logicalName, numberOfBytes, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, int, ...WithReaderArgs) []byte); ok {
		r0 = rf(logicalName, numberOfBytes, readerArgs...)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]byte)
		}
	}

	if rf, ok := ret.Get(1).(func(string, int, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, numberOfBytes, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadByteArray is a helper method to define mock.On call
//   - logicalName string
//   - numberOfBytes int
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadByteArray(logicalName interface{}, numberOfBytes interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadByteArray_Call {
	return &MockReadBufferByteBased_ReadByteArray_Call{Call: _e.mock.On("ReadByteArray",
		append([]interface{}{logicalName, numberOfBytes}, readerArgs...)...)}
}

func (_c *MockReadBufferByteBased_ReadByteArray_Call) Run(run func(logicalName string, numberOfBytes int, readerArgs ...WithReaderArgs)) *MockReadBufferByteBased_ReadByteArray_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]WithReaderArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(WithReaderArgs)
			}
		}
		run(args[0].(string), args[1].(int), variadicArgs...)
	})
	return _c
}

func (_c *MockReadBufferByteBased_ReadByteArray_Call) Return(_a0 []byte, _a1 error) *MockReadBufferByteBased_ReadByteArray_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

func (_c *MockReadBufferByteBased_ReadByteArray_Call) RunAndReturn(run func(string, int, ...WithReaderArgs) ([]byte, error)) *MockReadBufferByteBased_ReadByteArray_Call {
	_c.Call.Return(run)
	return _c
}

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

	var r0 float32
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (float32, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) float32); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(float32)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadFloat32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadFloat32(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadFloat32_Call {
	return &MockReadBufferByteBased_ReadFloat32_Call{Call: _e.mock.On("ReadFloat32",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadFloat32_Call) Return(_a0 float32, _a1 error) *MockReadBufferByteBased_ReadFloat32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 float64
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (float64, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) float64); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(float64)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadFloat64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadFloat64(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadFloat64_Call {
	return &MockReadBufferByteBased_ReadFloat64_Call{Call: _e.mock.On("ReadFloat64",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadFloat64_Call) Return(_a0 float64, _a1 error) *MockReadBufferByteBased_ReadFloat64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 int16
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (int16, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) int16); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(int16)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadInt16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadInt16(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadInt16_Call {
	return &MockReadBufferByteBased_ReadInt16_Call{Call: _e.mock.On("ReadInt16",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadInt16_Call) Return(_a0 int16, _a1 error) *MockReadBufferByteBased_ReadInt16_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 int32
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (int32, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) int32); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(int32)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadInt32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadInt32(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadInt32_Call {
	return &MockReadBufferByteBased_ReadInt32_Call{Call: _e.mock.On("ReadInt32",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadInt32_Call) Return(_a0 int32, _a1 error) *MockReadBufferByteBased_ReadInt32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 int64
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (int64, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) int64); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(int64)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadInt64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadInt64(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadInt64_Call {
	return &MockReadBufferByteBased_ReadInt64_Call{Call: _e.mock.On("ReadInt64",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadInt64_Call) Return(_a0 int64, _a1 error) *MockReadBufferByteBased_ReadInt64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 int8
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (int8, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) int8); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(int8)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadInt8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadInt8(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadInt8_Call {
	return &MockReadBufferByteBased_ReadInt8_Call{Call: _e.mock.On("ReadInt8",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadInt8_Call) Return(_a0 int8, _a1 error) *MockReadBufferByteBased_ReadInt8_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 string
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint32, string, ...WithReaderArgs) (string, error)); ok {
		return rf(logicalName, bitLength, encoding, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint32, string, ...WithReaderArgs) string); ok {
		r0 = rf(logicalName, bitLength, encoding, readerArgs...)
	} else {
		r0 = ret.Get(0).(string)
	}

	if rf, ok := ret.Get(1).(func(string, uint32, string, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, encoding, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadString is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint32
//   - encoding string
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadString(logicalName interface{}, bitLength interface{}, encoding interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadString_Call {
	return &MockReadBufferByteBased_ReadString_Call{Call: _e.mock.On("ReadString",
		append([]interface{}{logicalName, bitLength, encoding}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadString_Call) Return(_a0 string, _a1 error) *MockReadBufferByteBased_ReadString_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 uint16
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (uint16, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) uint16); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(uint16)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadUint16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadUint16(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadUint16_Call {
	return &MockReadBufferByteBased_ReadUint16_Call{Call: _e.mock.On("ReadUint16",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadUint16_Call) Return(_a0 uint16, _a1 error) *MockReadBufferByteBased_ReadUint16_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 uint32
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (uint32, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) uint32); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(uint32)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadUint32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadUint32(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadUint32_Call {
	return &MockReadBufferByteBased_ReadUint32_Call{Call: _e.mock.On("ReadUint32",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadUint32_Call) Return(_a0 uint32, _a1 error) *MockReadBufferByteBased_ReadUint32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 uint64
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (uint64, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) uint64); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(uint64)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadUint64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadUint64(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadUint64_Call {
	return &MockReadBufferByteBased_ReadUint64_Call{Call: _e.mock.On("ReadUint64",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadUint64_Call) Return(_a0 uint64, _a1 error) *MockReadBufferByteBased_ReadUint64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

	var r0 uint8
	var r1 error
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) (uint8, error)); ok {
		return rf(logicalName, bitLength, readerArgs...)
	}
	if rf, ok := ret.Get(0).(func(string, uint8, ...WithReaderArgs) uint8); ok {
		r0 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r0 = ret.Get(0).(uint8)
	}

	if rf, ok := ret.Get(1).(func(string, uint8, ...WithReaderArgs) error); ok {
		r1 = rf(logicalName, bitLength, readerArgs...)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

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

// ReadUint8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - readerArgs ...WithReaderArgs
func (_e *MockReadBufferByteBased_Expecter) ReadUint8(logicalName interface{}, bitLength interface{}, readerArgs ...interface{}) *MockReadBufferByteBased_ReadUint8_Call {
	return &MockReadBufferByteBased_ReadUint8_Call{Call: _e.mock.On("ReadUint8",
		append([]interface{}{logicalName, bitLength}, readerArgs...)...)}
}

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

func (_c *MockReadBufferByteBased_ReadUint8_Call) Return(_a0 uint8, _a1 error) *MockReadBufferByteBased_ReadUint8_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// Reset provides a mock function with given fields: pos
func (_m *MockReadBufferByteBased) Reset(pos uint16) {
	_m.Called(pos)
}

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

// Reset is a helper method to define mock.On call
//   - pos uint16
func (_e *MockReadBufferByteBased_Expecter) Reset(pos interface{}) *MockReadBufferByteBased_Reset_Call {
	return &MockReadBufferByteBased_Reset_Call{Call: _e.mock.On("Reset", pos)}
}

func (_c *MockReadBufferByteBased_Reset_Call) Run(run func(pos uint16)) *MockReadBufferByteBased_Reset_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(uint16))
	})
	return _c
}

func (_c *MockReadBufferByteBased_Reset_Call) Return() *MockReadBufferByteBased_Reset_Call {
	_c.Call.Return()
	return _c
}

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

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

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

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

	return mock
}
