Menu

[r24]: / trunk / uploader / libctb / src / fifo.cpp  Maximize  Restore  History

Download this file

131 lines (118 with data), 3.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/////////////////////////////////////////////////////////////////////////////
// Name: fifo.cpp
// Purpose:
// Author: Joachim Buermann, Michael Hungershausen
// Id: $Id$
// Copyright: (c) 2006,2007 Joachim Buermann
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "ctb-0.16/fifo.h"
namespace ctb {
Fifo::Fifo(size_t size) :
m_size(size)
{
m_begin = new char[size];
m_end = m_begin + m_size;
m_rdptr = m_wrptr = m_begin;
};
Fifo::~Fifo()
{
delete m_begin;
};
void Fifo::clear()
{
m_rdptr = m_wrptr = m_begin;
};
int Fifo::get(char* ch)
{
if(m_rdptr != m_wrptr) {
*ch = *m_rdptr++;
if(m_rdptr >= m_end) {
m_rdptr = m_begin;
}
return 1;
}
return 0;
};
size_t Fifo::items()
{
char* tmp_wrptr = m_wrptr;
// the rdptr will only changed by the reader. If we suppose, that
// the caller of the items() method is identical with the reader,
// this should be thread save.
char* tmp_rdptr = m_rdptr;
// if the write pointer is identical with the read, there are no
// more data in the Fifo
if(tmp_wrptr == tmp_rdptr) {
return 0;
}
// the write pointer is greater as the read pointer, so we just
// can calculate the difference for the remaining data
if(tmp_wrptr > tmp_rdptr) {
return (tmp_wrptr - tmp_rdptr);
}
// the write pointer has circulate and stands against the read
// pointer
else {
return (m_size - (tmp_rdptr - tmp_wrptr));
}
};
int Fifo::put(char ch)
{
// for a thread safe operation, the write of a data byte must be
// atomic. So we first assign the current position of the write
// pointer to a temporary pointer.
// Increment it for the comparison with the end of the internal
// buffer and the read pointer
char* tmp_wrptr = m_wrptr + 1;
if(tmp_wrptr >= m_end) {
tmp_wrptr = m_begin;
}
if(tmp_wrptr == m_rdptr) {
return 0;
}
// this don't changes the write pointer!
*m_wrptr = ch;
// that's the trick! The following assignment is atomic and cannot
// interrupted within a read access by the read thread
m_wrptr = tmp_wrptr;
return 1;
};
int Fifo::read(char* data,int n)
{
int nresult = 0;
while(n--) {
// the same as get()
if(m_rdptr != m_wrptr) {
*data = *m_rdptr++;
if(m_rdptr >= m_end) {
m_rdptr = m_begin;
}
}
else {
break;
}
nresult++;
data++;
}
return nresult;
};
int Fifo::write(char* data,int n)
{
int nresult = 0;
while(n--) {
// the same as put()
char* tmp_wrptr = m_wrptr + 1;
if(tmp_wrptr >= m_end) {
tmp_wrptr = m_begin;
}
if(tmp_wrptr == m_rdptr) {
break;
}
*m_wrptr = *data++;
m_wrptr = tmp_wrptr;
nresult++;
}
return nresult;
};
} // namespace ctb
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.