Простите, что пишу в древнюю ветку, просто здесь не организовано разбиение на темы по модулям.
А вопрос у меня такой.
версия userlib.h: Version: v5.1.0
почему методы <write> и <read>, класса <ring_buffer> такие не единообразные?
bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt)
{
if( cnt > (Size - Count) )
return false;
for(S i = 0; i < cnt; i++)
push_item(*(data++));
return true;
}
void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt)
{
S nItems = cnt <= Count ? cnt : Count;
for(S i = 0; i < nItems; i++)
data[i] = pop_item();
}
т.е. что я имею ввиду:
<read>: контролирует кол-во данных и если их меньше, чем запрашивают, то считывает столько сколько есть, однако, при этом не возвращает кол-во считанных данных.
<write>: ничего не делает, если кол-во свободного места меньше, чем хотят записать, а не записывает столько сколько может (аналогично read), с последующим возвратом кол-во записанных данных.
Мне кажется, что более качественно было бы, если read считывал MIN(Count, cnt) и возвращал бы это кол-во данных, а write аналогично, писал бы MIN(Size-Count, cnt) и возвращал бы кол-во записанных данных.
Ведь тут <Count> - это не размер в байтах, а именно кол-во единиц элементов типа <T>.
Используется данный класс <ring_buffer> в компоненте <channel>, где тоже странная реализация у методов:
S OS::channel<T, Size, S>::write_isr(const T* data, const S count)
{
TCritSect cs;
const S free = pool.get_free_size();
S qty = free < count ? free : count;
pool.write(data, qty);
resume_all_isr(ConsumersProcessMap);
return qty;
}
S OS::channel<T, Size, S>::read_isr(T* const data, const S max_size)
{
TCritSect cs;
const S avail = pool.get_count();
S count = avail < max_size ? avail : max_size;
pool.read(data, count);
resume_all_isr(ProducersProcessMap);
return count;
}
т.е. метод write_isr пользуется методом <pool.write>, но не контролирует возвращаемый им признак.
А read_isr, зачем-то контролирует <pool.Count>, обрезает считываемый размер и при этом не смотрит на возращаемое значение pool.read, когда сам метод <ring_buffer.read> делает все тоже самое.. и по делу.
Куда компактней было бы написать так
(в случае, если бы методы ring_buffer: read/write были бы универсальными):
S OS::channel<T, Size, S>::write_isr(const T* data, const S count)
{
TCritSect cs;
S qty = pool.write(data, count);
resume_all_isr(ConsumersProcessMap);
return qty;
}
S OS::channel<T, Size, S>::read_isr(T* const data, const S max_size)
{
TCritSect cs;
S count = pool.read(data, max_size);
resume_all_isr(ProducersProcessMap);
return count;
}
Раз компонент <channel> использует свой (под себя написанный) класс <ring_buffer>, то и перезакладываться на контроль чужого (для класса channel) <Count> при вызове read/write нет никакой необходимости.
Я не прав?