source: XMLIO_V2/dev/dev_rv/src/xmlio/circular_buffer.cpp @ 198

Last change on this file since 198 was 198, checked in by hozdoba, 12 years ago
File size: 8.3 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         }
121         
122         if (this-> p_read == this-> p_unused)
123         {
124            this-> p_unused = this-> p_write;
125            this-> p_read   = 0;
126            return;
127         }
128         if (this-> p_read == this-> p_write)
129         {
130            this->clear();
131         }
132      }
133     
134      //-------------------------------------------------------------
135     
136      void CCircularBuffer::movePWrite(StdSize data_size)
137      {
138         if ((this-> p_write + data_size) > SuperClass::getSize())
139         {
140            this-> p_unused = this-> p_write;
141            this-> p_write  = data_size;
142            if (this-> p_read < (data_size))
143               ERROR("CCircularBuffer::movePWrite(data_size)",
144                     << " invalid position 1 !");
145         }
146         else
147         {
148            if ((this-> p_read > this-> p_write) &&
149                (this-> p_read < (this-> p_write + data_size)))
150               ERROR("CCircularBuffer::movePWrite(data_size)",
151                     << " invalid position 2 !");
152            this-> p_write += data_size;
153            if (this->p_read < this->p_write)
154               this-> p_unused = this-> p_write;
155         }
156      }
157
158      //-------------------------------------------------------------
159
160      bool CCircularBuffer::hasRequest(void) const
161      { 
162         return (this->nbrequest != 0); 
163      }
164     
165      //-------------------------------------------------------------
166     
167      bool CCircularBuffer::isAvailable(StdSize data_size) const
168      {
169         if (this->p_write == this->p_unused)
170            return (((SuperClass::getSize() - this->p_write) >= data_size) ||
171                   (this->p_read >= data_size));
172         else
173            return ((this->p_read - this->p_write) >= data_size);
174      }
175      //---------------------------------------------------------------
176
177      void CCircularBuffer::printToTextFile (const StdString & filename)
178      {
179         StdOFStream ofs(filename.c_str());
180         this->printToTextStream(ofs);
181         ofs.close();
182      }
183     
184      //-------------------------------------------------------------
185     
186      void CCircularBuffer::printToTextStream (StdOStream & ostr)
187      {
188         StdSize _p_write   = p_write,
189                 _p_read    = p_read,
190                 _p_unused  = p_unused,
191                 _nbrequest = nbrequest;
192
193         while (this->hasRequest())
194         {
195            this->getNextRequest().printToTextStream(ostr);
196            ostr << std::endl;
197         }
198
199         p_write   = _p_write;
200         p_read    = _p_read;
201         p_unused  = _p_unused;
202         nbrequest = _nbrequest;
203      }
204
205      //---------------------------------------------------------------
206
207      StdSize CCircularBuffer::getNumberOfRequest(void) const
208      { return (this->nbrequest); }
209
210      StdSize CCircularBuffer::getReadPosition(void) const
211      { return (this->p_read); }
212
213      StdSize CCircularBuffer::getWritePosition(void) const
214      { return (this->p_write); }
215
216      StdSize CCircularBuffer::getUnusedPosition(void) const
217      { return (this->p_unused); }
218
219      //---------------------------------------------------------------
220
221      void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)
222      {
223         StdSize position = data_begin;       
224         while (position != data_end)
225         {
226            this->nbrequest++;
227            position = SuperClass::getNextDataPosition(position); // manager id           
228            position = SuperClass::getNextDataPosition(position); // method id           
229            SuperClass::updateBufferData(position);
230            long int nbarg = SuperClass::getInt(position);
231            position = SuperClass::getNextDataPosition(position);
232            for (long int i = 0; i < nbarg; i++)
233               position = SuperClass::getNextDataPosition(position);
234               
235            if (position > data_end)
236              ERROR("CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)",
237                     << "[ position courante" << position
238                     << ", fin de traitement" << data_end << " ] "
239                     << "Impossible de mettre à jour la liste des requêtes !");
240         }
241      }
242
243      ///------------------------------------------------------------
244   } // namespace tree
245} // namespace xmlioserver
246
Note: See TracBrowser for help on using the repository browser.