[152] | 1 | #include "circular_buffer.hpp" |
---|
| 2 | |
---|
| 3 | #include "linear_buffer_impl.hpp" |
---|
| 4 | |
---|
| 5 | namespace xmlioserver |
---|
| 6 | { |
---|
| 7 | namespace comm |
---|
| 8 | { |
---|
| 9 | /// ////////////////////// Définitions ////////////////////// /// |
---|
| 10 | CCircularBuffer::CCircularBuffer(StdSize size) |
---|
[196] | 11 | : SuperClass(size) |
---|
| 12 | , p_write(0), p_read(0), p_unused(0) |
---|
| 13 | , nbrequest(0) |
---|
[152] | 14 | { /* Ne rien faire de plus */ } |
---|
| 15 | |
---|
[196] | 16 | CCircularBuffer::CCircularBuffer(const CCircularBuffer & cbuffer) |
---|
| 17 | : SuperClass(cbuffer) |
---|
| 18 | , p_write(cbuffer.p_write), p_read(cbuffer.p_read), p_unused(cbuffer.p_unused) |
---|
| 19 | , nbrequest(cbuffer.nbrequest) |
---|
| 20 | { /* Ne rien faire de plus */ } |
---|
| 21 | |
---|
| 22 | CCircularBuffer::CCircularBuffer(const CCircularBuffer * const cbuffer) |
---|
| 23 | : SuperClass(cbuffer) |
---|
| 24 | , p_write(cbuffer->p_write), p_read(cbuffer->p_read), p_unused(cbuffer->p_unused) |
---|
| 25 | , nbrequest(cbuffer->nbrequest) |
---|
| 26 | { /* Ne rien faire de plus */ } |
---|
| 27 | |
---|
[152] | 28 | CCircularBuffer::~CCircularBuffer(void) |
---|
| 29 | { /* Ne rien faire de plus */ } |
---|
| 30 | |
---|
| 31 | ///-------------------------------------------------------------- |
---|
| 32 | |
---|
| 33 | void CCircularBuffer::clear(void) |
---|
| 34 | { |
---|
| 35 | this-> p_write = 0; |
---|
| 36 | this-> p_read = 0; |
---|
| 37 | this-> p_unused = 0; |
---|
| 38 | } |
---|
| 39 | |
---|
| 40 | //------------------------------------------------------------- |
---|
| 41 | |
---|
| 42 | StdSize CCircularBuffer::getNextRequestSize(void) const |
---|
| 43 | { |
---|
| 44 | if (!this->hasRequest()) |
---|
| 45 | ERROR("CCircularBuffer::getNextRequestSize()", |
---|
| 46 | << " invalid call !"); |
---|
| 47 | long int nbargs = 0; |
---|
| 48 | StdSize startpos = this-> p_read; |
---|
| 49 | StdSize currsize = 2 * SuperClass::getRequestedSize(nbargs); |
---|
| 50 | nbargs = SuperClass::getInt(startpos + currsize); |
---|
| 51 | currsize += SuperClass::getRequestedSize(nbargs); |
---|
[198] | 52 | |
---|
[152] | 53 | for (long int i = 0; i < nbargs; i++) |
---|
| 54 | { |
---|
| 55 | CBufferData bufdata; |
---|
[198] | 56 | SuperClass::getBufferData(bufdata, startpos + currsize); |
---|
[152] | 57 | currsize += (bufdata.size + DATA_HEADER_SIZE); |
---|
| 58 | } |
---|
| 59 | return (currsize); |
---|
| 60 | } |
---|
[196] | 61 | |
---|
| 62 | //------------------------------------------------------------- |
---|
| 63 | |
---|
[152] | 64 | CLinearBuffer CCircularBuffer::getNextRequest(void) |
---|
| 65 | { |
---|
| 66 | StdSize startpos = this-> p_read; |
---|
| 67 | StdSize currsize = this->getNextRequestSize(); |
---|
[198] | 68 | |
---|
[152] | 69 | this->movePRead(currsize); |
---|
| 70 | this->nbrequest--; |
---|
[199] | 71 | //std::cout << this->nbrequest << std::endl; |
---|
[198] | 72 | |
---|
[152] | 73 | return (CLinearBuffer(SuperClass::getData(startpos), currsize)); |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | //------------------------------------------------------------- |
---|
| 77 | |
---|
| 78 | void CCircularBuffer::appendRequest(const CLinearBuffer & brequest) |
---|
| 79 | { |
---|
| 80 | StdSize usedsize = brequest.getUsedSize(); |
---|
| 81 | if (!this->isAvailable(usedsize)) |
---|
| 82 | ERROR("CCircularBuffer::appendRequest(brequest)", |
---|
| 83 | << " invalid call !"); |
---|
| 84 | StdSize data_begin = this->prepareNextDataPosition(usedsize); |
---|
| 85 | SuperClass::setData(brequest.getData(), usedsize, data_begin); |
---|
| 86 | this->updateNbRequests(data_begin, data_begin + usedsize); |
---|
| 87 | } |
---|
| 88 | |
---|
| 89 | //------------------------------------------------------------- |
---|
| 90 | |
---|
| 91 | char * CCircularBuffer::prepareNextData(StdSize data_size) |
---|
| 92 | { |
---|
| 93 | return (SuperClass::getData(this->prepareNextDataPosition(data_size))); |
---|
| 94 | } |
---|
[196] | 95 | |
---|
| 96 | //------------------------------------------------------------- |
---|
[152] | 97 | |
---|
| 98 | StdSize CCircularBuffer::prepareNextDataPosition(StdSize data_size) |
---|
| 99 | { |
---|
| 100 | StdSize startpos = this-> p_write; |
---|
| 101 | if (!this->isAvailable(data_size)) |
---|
| 102 | ERROR("CCircularBuffer::prepareNextDataPosition(data_size)", |
---|
| 103 | << " invalid call !"); |
---|
| 104 | if ((this-> p_write + data_size) > SuperClass::getSize()) |
---|
| 105 | startpos = 0; |
---|
| 106 | |
---|
| 107 | this->movePWrite(data_size); |
---|
| 108 | return (startpos); |
---|
| 109 | } |
---|
| 110 | |
---|
| 111 | //------------------------------------------------------------- |
---|
| 112 | |
---|
| 113 | void CCircularBuffer::movePRead(StdSize data_size) |
---|
| 114 | { |
---|
| 115 | this-> p_read += data_size; |
---|
[198] | 116 | if ((this-> p_read == this-> p_unused) && |
---|
| 117 | (this-> p_read == this-> p_write)) |
---|
| 118 | { |
---|
| 119 | this->clear(); |
---|
[199] | 120 | return; |
---|
[198] | 121 | } |
---|
| 122 | |
---|
[152] | 123 | if (this-> p_read == this-> p_unused) |
---|
| 124 | { |
---|
| 125 | this-> p_unused = this-> p_write; |
---|
| 126 | this-> p_read = 0; |
---|
[198] | 127 | return; |
---|
[152] | 128 | } |
---|
| 129 | if (this-> p_read == this-> p_write) |
---|
[198] | 130 | { |
---|
[152] | 131 | this->clear(); |
---|
[198] | 132 | } |
---|
[152] | 133 | } |
---|
[196] | 134 | |
---|
| 135 | //------------------------------------------------------------- |
---|
| 136 | |
---|
[152] | 137 | void CCircularBuffer::movePWrite(StdSize data_size) |
---|
| 138 | { |
---|
| 139 | if ((this-> p_write + data_size) > SuperClass::getSize()) |
---|
| 140 | { |
---|
| 141 | this-> p_unused = this-> p_write; |
---|
| 142 | this-> p_write = data_size; |
---|
| 143 | if (this-> p_read < (data_size)) |
---|
| 144 | ERROR("CCircularBuffer::movePWrite(data_size)", |
---|
| 145 | << " invalid position 1 !"); |
---|
| 146 | } |
---|
| 147 | else |
---|
| 148 | { |
---|
| 149 | if ((this-> p_read > this-> p_write) && |
---|
| 150 | (this-> p_read < (this-> p_write + data_size))) |
---|
| 151 | ERROR("CCircularBuffer::movePWrite(data_size)", |
---|
| 152 | << " invalid position 2 !"); |
---|
| 153 | this-> p_write += data_size; |
---|
| 154 | if (this->p_read < this->p_write) |
---|
| 155 | this-> p_unused = this-> p_write; |
---|
| 156 | } |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | //------------------------------------------------------------- |
---|
| 160 | |
---|
| 161 | bool CCircularBuffer::hasRequest(void) const |
---|
[196] | 162 | { |
---|
| 163 | return (this->nbrequest != 0); |
---|
| 164 | } |
---|
| 165 | |
---|
| 166 | //------------------------------------------------------------- |
---|
| 167 | |
---|
[152] | 168 | bool CCircularBuffer::isAvailable(StdSize data_size) const |
---|
| 169 | { |
---|
| 170 | if (this->p_write == this->p_unused) |
---|
| 171 | return (((SuperClass::getSize() - this->p_write) >= data_size) || |
---|
| 172 | (this->p_read >= data_size)); |
---|
| 173 | else |
---|
| 174 | return ((this->p_read - this->p_write) >= data_size); |
---|
| 175 | } |
---|
| 176 | //--------------------------------------------------------------- |
---|
| 177 | |
---|
| 178 | void CCircularBuffer::printToTextFile (const StdString & filename) |
---|
| 179 | { |
---|
| 180 | StdOFStream ofs(filename.c_str()); |
---|
| 181 | this->printToTextStream(ofs); |
---|
| 182 | ofs.close(); |
---|
| 183 | } |
---|
[196] | 184 | |
---|
| 185 | //------------------------------------------------------------- |
---|
| 186 | |
---|
[152] | 187 | void CCircularBuffer::printToTextStream (StdOStream & ostr) |
---|
| 188 | { |
---|
| 189 | StdSize _p_write = p_write, |
---|
| 190 | _p_read = p_read, |
---|
| 191 | _p_unused = p_unused, |
---|
| 192 | _nbrequest = nbrequest; |
---|
| 193 | |
---|
| 194 | while (this->hasRequest()) |
---|
| 195 | { |
---|
| 196 | this->getNextRequest().printToTextStream(ostr); |
---|
| 197 | ostr << std::endl; |
---|
| 198 | } |
---|
| 199 | |
---|
| 200 | p_write = _p_write; |
---|
| 201 | p_read = _p_read; |
---|
| 202 | p_unused = _p_unused; |
---|
| 203 | nbrequest = _nbrequest; |
---|
| 204 | } |
---|
| 205 | |
---|
| 206 | //--------------------------------------------------------------- |
---|
| 207 | |
---|
| 208 | StdSize CCircularBuffer::getNumberOfRequest(void) const |
---|
[199] | 209 | { |
---|
| 210 | return (this->nbrequest); |
---|
| 211 | } |
---|
[152] | 212 | |
---|
[199] | 213 | //--------------------------------------------------------------- |
---|
| 214 | |
---|
[152] | 215 | StdSize CCircularBuffer::getReadPosition(void) const |
---|
[199] | 216 | { |
---|
| 217 | return (this->p_read); |
---|
| 218 | } |
---|
[152] | 219 | |
---|
[199] | 220 | //--------------------------------------------------------------- |
---|
| 221 | |
---|
[152] | 222 | StdSize CCircularBuffer::getWritePosition(void) const |
---|
[199] | 223 | { |
---|
| 224 | return (this->p_write); |
---|
| 225 | } |
---|
[152] | 226 | |
---|
[199] | 227 | //--------------------------------------------------------------- |
---|
| 228 | |
---|
[152] | 229 | StdSize CCircularBuffer::getUnusedPosition(void) const |
---|
[199] | 230 | { |
---|
| 231 | return (this->p_unused); |
---|
| 232 | } |
---|
[152] | 233 | |
---|
| 234 | //--------------------------------------------------------------- |
---|
| 235 | |
---|
| 236 | void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end) |
---|
| 237 | { |
---|
[198] | 238 | StdSize position = data_begin; |
---|
[152] | 239 | while (position != data_end) |
---|
| 240 | { |
---|
| 241 | this->nbrequest++; |
---|
[198] | 242 | position = SuperClass::getNextDataPosition(position); // manager id |
---|
| 243 | position = SuperClass::getNextDataPosition(position); // method id |
---|
| 244 | SuperClass::updateBufferData(position); |
---|
[152] | 245 | long int nbarg = SuperClass::getInt(position); |
---|
| 246 | position = SuperClass::getNextDataPosition(position); |
---|
| 247 | for (long int i = 0; i < nbarg; i++) |
---|
| 248 | position = SuperClass::getNextDataPosition(position); |
---|
[198] | 249 | |
---|
| 250 | if (position > data_end) |
---|
| 251 | ERROR("CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)", |
---|
| 252 | << "[ position courante" << position |
---|
| 253 | << ", fin de traitement" << data_end << " ] " |
---|
| 254 | << "Impossible de mettre à jour la liste des requêtes !"); |
---|
[152] | 255 | } |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | ///------------------------------------------------------------ |
---|
| 259 | } // namespace tree |
---|
| 260 | } // namespace xmlioserver |
---|
| 261 | |
---|