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

// MockReadBuffer is an autogenerated mock type for the ReadBuffer type
type MockReadBuffer struct {
	mock.Mock
}

type MockReadBuffer_Expecter struct {
	mock *mock.Mock
}

func (_m *MockReadBuffer) EXPECT() *MockReadBuffer_Expecter {
	return &MockReadBuffer_Expecter{mock: &_m.Mock}
}

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

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

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

func (_c *MockReadBuffer_CloseContext_Call) Run(run func(logicalName string, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_CloseContext_Call) Return(_a0 error) *MockReadBuffer_CloseContext_Call {
	_c.Call.Return(_a0)
	return _c
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

func (_c *MockReadBuffer_PullContext_Call) Run(run func(logicalName string, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_PullContext_Call) Return(_a0 error) *MockReadBuffer_PullContext_Call {
	_c.Call.Return(_a0)
	return _c
}

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

// ReadBigFloat provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadBigFloat_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadBigFloat_Call) Return(_a0 *big.Float, _a1 error) *MockReadBuffer_ReadBigFloat_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadBigInt provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadBigInt_Call) Run(run func(logicalName string, bitLength uint64, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadBigInt_Call) Return(_a0 *big.Int, _a1 error) *MockReadBuffer_ReadBigInt_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

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

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

func (_c *MockReadBuffer_ReadBit_Call) Run(run func(logicalName string, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadBit_Call) Return(_a0 bool, _a1 error) *MockReadBuffer_ReadBit_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

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

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

func (_c *MockReadBuffer_ReadByte_Call) Run(run func(logicalName string, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadByte_Call) Return(_a0 byte, _a1 error) *MockReadBuffer_ReadByte_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadByteArray provides a mock function with given fields: logicalName, numberOfBytes, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadByteArray_Call) Run(run func(logicalName string, numberOfBytes int, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadByteArray_Call) Return(_a0 []byte, _a1 error) *MockReadBuffer_ReadByteArray_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadFloat32 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadFloat32_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadFloat32_Call) Return(_a0 float32, _a1 error) *MockReadBuffer_ReadFloat32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadFloat64 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadFloat64_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadFloat64_Call) Return(_a0 float64, _a1 error) *MockReadBuffer_ReadFloat64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadInt16 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadInt16_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadInt16_Call) Return(_a0 int16, _a1 error) *MockReadBuffer_ReadInt16_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadInt32 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadInt32_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadInt32_Call) Return(_a0 int32, _a1 error) *MockReadBuffer_ReadInt32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadInt64 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadInt64_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadInt64_Call) Return(_a0 int64, _a1 error) *MockReadBuffer_ReadInt64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadInt8 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadInt8_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadInt8_Call) Return(_a0 int8, _a1 error) *MockReadBuffer_ReadInt8_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadString provides a mock function with given fields: logicalName, bitLength, encoding, readerArgs
func (_m *MockReadBuffer) 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
}

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

func (_c *MockReadBuffer_ReadString_Call) Run(run func(logicalName string, bitLength uint32, encoding string, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadString_Call) Return(_a0 string, _a1 error) *MockReadBuffer_ReadString_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadUint16 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadUint16_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadUint16_Call) Return(_a0 uint16, _a1 error) *MockReadBuffer_ReadUint16_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadUint32 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadUint32_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadUint32_Call) Return(_a0 uint32, _a1 error) *MockReadBuffer_ReadUint32_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadUint64 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadUint64_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadUint64_Call) Return(_a0 uint64, _a1 error) *MockReadBuffer_ReadUint64_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

// ReadUint8 provides a mock function with given fields: logicalName, bitLength, readerArgs
func (_m *MockReadBuffer) 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
}

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

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

func (_c *MockReadBuffer_ReadUint8_Call) Run(run func(logicalName string, bitLength uint8, readerArgs ...WithReaderArgs)) *MockReadBuffer_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 *MockReadBuffer_ReadUint8_Call) Return(_a0 uint8, _a1 error) *MockReadBuffer_ReadUint8_Call {
	_c.Call.Return(_a0, _a1)
	return _c
}

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

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

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

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

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

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

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

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

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

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

	return mock
}
