source: XMLIO_V2/dev/common/src/xmlio/circular_buffer.cpp @ 219

Last change on this file since 219 was 219, checked in by hozdoba, 10 years ago

Préparation nouvelle arborescence

File size: 8.6 KB
Line 
1#include "circular_buffer.hpp"
2
3#include "linear_buffer_impl.hpp"
4
5namespace xmlioserver
6{
7   namespace comm
8   {
9      /// ////////////////////// Définitions ////////////////////// ///
10      CCircularBuffer::CCircularBuffer(StdSize size)
11         : SuperClass(size)
12         , p_write(0), p_read(0), p_unused(0)
13         , nbrequest(0)
14      { /* Ne rien faire de plus */ }
15
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
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);
52         
53         for (long int i = 0; i < nbargs; i++)
54         {
55            CBufferData bufdata;
56            SuperClass::getBufferData(bufdata, startpos + currsize);
57            currsize += (bufdata.size + DATA_HEADER_SIZE);
58         }
59         return (currsize);
60      }
61     
62      //-------------------------------------------------------------
63     
64      CLinearBuffer CCircularBuffer::getNextRequest(void)
65      {
66         StdSize startpos = this-> p_read;
67         StdSize currsize = this->getNextRequestSize();
68       
69         this->movePRead(currsize);
70         this->nbrequest--;
71         //std::cout <<  this->nbrequest << std::endl;
72       
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      }
95     
96      //-------------------------------------------------------------
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;
116         if ((this-> p_read == this-> p_unused) &&
117             (this-> p_read == this-> p_write))
118         {
119            this->clear();
120            return;
121         }
122         
123         if (this-> p_read == this-> p_unused)
124         {
125            this-> p_unused = this-> p_write;
126            this-> p_read   = 0;
127            return;
128         }
129         if (this-> p_read == this-> p_write)
130         {
131            this->clear();
132         }
133      }
134     
135      //-------------------------------------------------------------
136     
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
162      { 
163         return (this->nbrequest != 0); 
164      }
165     
166      //-------------------------------------------------------------
167     
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      }
184     
185      //-------------------------------------------------------------
186     
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
209      { 
210         return (this->nbrequest); 
211      }
212
213      //---------------------------------------------------------------
214
215      StdSize CCircularBuffer::getReadPosition(void) const
216      { 
217         return (this->p_read); 
218      }
219
220      //---------------------------------------------------------------
221
222      StdSize CCircularBuffer::getWritePosition(void) const
223      { 
224         return (this->p_write); 
225      }
226
227      //---------------------------------------------------------------
228
229      StdSize CCircularBuffer::getUnusedPosition(void) const
230      { 
231         return (this->p_unused); 
232      }
233
234      //---------------------------------------------------------------
235
236      void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)
237      {
238         StdSize position = data_begin;       
239         while (position != data_end)
240         {
241            this->nbrequest++;
242            position = SuperClass::getNextDataPosition(position); // manager id           
243            position = SuperClass::getNextDataPosition(position); // method id           
244            SuperClass::updateBufferData(position);
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);
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 !");
255         }
256      }
257
258      ///------------------------------------------------------------
259   } // namespace tree
260} // namespace xmlioserver
261
Note: See TracBrowser for help on using the repository browser.