source: XMLIO_V2/dev/common/src/circular_buffer.cpp @ 300

Last change on this file since 300 was 300, checked in by ymipsl, 12 years ago

nouvelle version de developpement de xios

  • nouvelle interface fortran
  • recodage complet de la couche de communication
  • et bien d'autres choses...

YM

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       
72         return (CLinearBuffer(SuperClass::getData(startpos), currsize));
73      }
74
75      //-------------------------------------------------------------
76
77      void CCircularBuffer::appendRequest(const CLinearBuffer & brequest)
78      {
79         StdSize usedsize   = brequest.getUsedSize();
80         if (!this->isAvailable(usedsize))
81            ERROR("CCircularBuffer::appendRequest(brequest)",
82                  << " invalid call !");
83         StdSize data_begin = this->prepareNextDataPosition(usedsize);
84         SuperClass::setData(brequest.getData(), usedsize, data_begin);
85         this->updateNbRequests(data_begin, data_begin + usedsize);
86      }
87
88      //-------------------------------------------------------------
89
90      char * CCircularBuffer::prepareNextData(StdSize data_size)
91      {
92         return (SuperClass::getData(this->prepareNextDataPosition(data_size)));
93      }
94     
95      //-------------------------------------------------------------
96
97      StdSize CCircularBuffer::prepareNextDataPosition(StdSize data_size)
98      {
99         StdSize startpos = this-> p_write;
100         if (!this->isAvailable(data_size))
101            ERROR("CCircularBuffer::prepareNextDataPosition(data_size)",
102                  << " invalid call !");
103         if ((this-> p_write + data_size) > SuperClass::getSize())
104            startpos = 0;
105
106         this->movePWrite(data_size);
107         return (startpos);
108      }
109
110      //-------------------------------------------------------------
111
112      void CCircularBuffer::movePRead(StdSize data_size)
113      {
114         this-> p_read += data_size;
115         if ((this-> p_read == this-> p_unused) &&
116             (this-> p_read == this-> p_write))
117         {
118            this->clear();
119            return;
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      { 
209         return (this->nbrequest); 
210      }
211
212      //---------------------------------------------------------------
213
214      StdSize CCircularBuffer::getReadPosition(void) const
215      { 
216         return (this->p_read); 
217      }
218
219      //---------------------------------------------------------------
220
221      StdSize CCircularBuffer::getWritePosition(void) const
222      { 
223         return (this->p_write); 
224      }
225
226      //---------------------------------------------------------------
227
228      StdSize CCircularBuffer::getUnusedPosition(void) const
229      { 
230         return (this->p_unused); 
231      }
232
233      //---------------------------------------------------------------
234
235      void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)
236      {
237         StdSize position = data_begin;       
238         while (position != data_end)
239         {
240            this->nbrequest++;
241            position = SuperClass::getNextDataPosition(position); // manager id           
242            position = SuperClass::getNextDataPosition(position); // method id           
243            SuperClass::updateBufferData(position);
244            long int nbarg = SuperClass::getInt(position);
245            position = SuperClass::getNextDataPosition(position);
246            for (long int i = 0; i < nbarg; i++)
247               position = SuperClass::getNextDataPosition(position);
248               
249            if (position > data_end)
250              ERROR("CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)",
251                     << "[ position courante" << position
252                     << ", fin de traitement" << data_end << " ] "
253                     << "Impossible de mettre à jour la liste des requêtes !");
254         }
255      }
256
257      ///------------------------------------------------------------
258   } // namespace tree
259} // namespace xmlioserver
260
Note: See TracBrowser for help on using the repository browser.