source: XMLIO_V2/dev/dev_rv/src4/xmlio/buffer/circular_buffer.cpp @ 264

Last change on this file since 264 was 264, checked in by hozdoba, 13 years ago

Ajout de classes pour la version 4

File size: 9.0 KB
Line 
1/* ************************************************************************** *
2 *      Copyright © IPSL/LSCE, XMLIOServer, Avril 2010 - Octobre 2011         *
3 * ************************************************************************** */
4 
5#ifndef __XIOS_NO_EXTERN
6
7// C++ standard headers
8#include <fstream>
9
10#endif // __XIOS_NO_EXTERN
11
12// XMLIOServer headers
13#include "circular_buffer.hpp"
14#include "buffer_impl.hpp"
15
16// /////////////////////////////// Définitions ////////////////////////////// //
17
18namespace xmlioserver {
19namespace comm {
20 
21   // ------------------------------ Constructeurs -----------------------------
22   
23   CCircularBuffer::CCircularBuffer(std::size_t _size)
24      : SuperClass(_size)
25      , p_write(0), p_read(0), p_unused(0)
26      , p_wait(0), locked_data(0)
27      , nbrequest(0)
28   { /* Ne rien faire de plus */ }
29
30   CCircularBuffer::CCircularBuffer(const CCircularBuffer & _cbuffer_ref)
31      : SuperClass(_cbuffer_ref)
32      , p_write(_cbuffer_ref.p_write), p_read(_cbuffer_ref.p_read), p_unused(_cbuffer_ref.p_unused)
33      , p_wait(_cbuffer_ref.p_wait), locked_data(_cbuffer_ref.locked_data)
34      , nbrequest(_cbuffer_ref.nbrequest)
35   { /* Ne rien faire de plus */ }
36   
37   CCircularBuffer::CCircularBuffer(const CCircularBuffer * const _cbuffer_ptr)
38      : SuperClass(_cbuffer_ptr)
39      , p_write(_cbuffer_ptr->p_write), p_read(_cbuffer_ptr->p_read), p_unused(_cbuffer_ptr->p_unused)
40      , p_wait(_cbuffer_ptr->p_wait), locked_data(_cbuffer_ptr->locked_data)
41      , nbrequest(_cbuffer_ptr->nbrequest)
42   { /* Ne rien faire de plus */ }
43   
44   // ------------------------------- Destructeur ------------------------------
45   
46   CCircularBuffer::~CCircularBuffer(void)
47   { /* Ne rien faire de plus */ }
48   
49   // ------------------------------ Remise à zéro -----------------------------
50   
51   void CCircularBuffer::clear(void)
52   {
53      this-> p_write     = 0;
54      this-> p_read      = 0;
55      this-> p_unused    = 0;
56      this-> p_wait      = 0;
57      this-> locked_data = 0;
58      this-> nbrequest   = 0;
59   }
60
61   // ------------------------------- Accesseurs -------------------------------
62
63   std::size_t CCircularBuffer::getNextRequestSize(void) const
64   {
65      if (!this->hasRequest())
66         XIOS_ERROR("CCircularBuffer::getNextRequestSize()",
67                     << " invalid call !");
68      long int nbargs  = 0;
69      std::size_t startpos = this-> p_read;
70      std::size_t currsize = 2 * SuperClass::getRequestedSize(nbargs);
71      nbargs    = SuperClass::getInt(startpos + currsize);
72      currsize += SuperClass::getRequestedSize(nbargs);
73     
74      for (long int i = 0; i < nbargs; i++)
75      {
76         CBufferData bufdata;
77         SuperClass::getBufferData(bufdata, startpos + currsize);
78         currsize += (bufdata.size + DATA_HEADER_SIZE);
79      }
80      return (currsize);
81   }
82       
83   CLinearBuffer CCircularBuffer::getNextRequest(void)
84   {
85      std::size_t startpos = this-> p_read;
86      std::size_t currsize = this->getNextRequestSize();
87     
88      this->movePRead(currsize);
89      this->nbrequest--;
90      //std::cout <<  this->nbrequest << std::endl;
91     
92      return (CLinearBuffer(SuperClass::getData(startpos), currsize));
93   }
94   
95   // ------------------------------- Mutateurs --------------------------------
96   
97   void CCircularBuffer::appendRequest(const CLinearBuffer & _brequest)
98   {
99      std::size_t usedsize   = _brequest.getUsedSize();
100      if (!this->isAvailable(usedsize))
101         XIOS_ERROR("CCircularBuffer::appendRequest(brequest)",
102               << " invalid call !");
103      std::size_t data_begin = this->prepareNextDataPosition(usedsize);
104      SuperClass::setData(_brequest.getData(), usedsize, data_begin);
105      this->updateNbRequests(data_begin, data_begin + usedsize);
106   }
107
108   char * CCircularBuffer::prepareNextData(std::size_t data_size)
109   {
110      return (SuperClass::getData(this->prepareNextDataPosition(data_size)));
111   }
112   
113   std::size_t CCircularBuffer::prepareNextDataPosition(std::size_t data_size)
114   {
115      this->p_wait = this-> p_write;   
116      this->locked_data = data_size;   
117      if (!this->isAvailable(data_size))
118         XIOS_ERROR("CCircularBuffer::prepareNextDataPosition(data_size)",
119               << " invalid call !");
120      if ((this->p_write + this->locked_data) > SuperClass::getSize())
121           this->p_wait = 0;
122
123      this->movePWrite(this->locked_data);
124      return (this->p_wait);
125   }
126   
127   // ------------------ Déplacements de pointeurs internes -------------------
128   
129   void CCircularBuffer::movePRead(std::size_t data_size)
130   {
131      this-> p_read += data_size;
132      if ((this-> p_read == this-> p_unused) &&
133          (this-> p_read == this-> p_write))
134      {
135         this->clear();
136         return;
137      }
138     
139      if (this-> p_read == this-> p_unused)
140      {
141         this-> p_unused = this-> p_write;
142         this-> p_read   = 0;
143         return;
144      }
145      if (this-> p_read == this-> p_write)
146      {
147         this->clear();
148      }
149   }
150   
151   void CCircularBuffer::movePWrite(std::size_t data_size)
152   {
153      if ((this-> p_write + data_size) > SuperClass::getSize())
154      {
155         this-> p_unused = this-> p_write;
156         this-> p_write  = data_size;
157         if (this-> p_read < (data_size))
158            XIOS_ERROR("CCircularBuffer::movePWrite(data_size)",
159                       << " invalid position 1 !");
160      }
161      else
162      {
163         if ((this-> p_read > this-> p_write) &&
164             (this-> p_read < (this-> p_write + data_size)))
165            XIOS_ERROR("CCircularBuffer::movePWrite(data_size)",
166                        << " invalid position 2 !");
167         this-> p_write += data_size;
168         if (this->p_read < this->p_write)
169            this-> p_unused = this-> p_write;
170      }
171   }
172
173   // --------------------------- Tests sur le buffer --------------------------
174   
175   bool CCircularBuffer::hasRequest(void) const
176   { 
177      return (this->nbrequest != 0); 
178   }
179   
180   bool CCircularBuffer::isAvailable(std::size_t data_size) const
181   {
182      if (this->p_write == this->p_unused)
183         return (((SuperClass::getSize() - this->p_write) >= data_size) ||
184                (this->p_read >= data_size));
185      else
186         return ((this->p_read - this->p_write) >= data_size);
187   }
188
189   // ------------------------- Ecriture fichier -------------------------------
190
191   void CCircularBuffer::printToTextFile (const std::string & _filename)
192   {
193      std::ofstream ofs(_filename.c_str());
194      this->printToTextStream(ofs);
195      ofs.close();
196   }
197   
198   void CCircularBuffer::printToTextStream (std::ostream & _ostr)
199   {
200      std::size_t _p_write     = p_write,
201                  _p_read      = p_read,
202                  _p_unused    = p_unused,
203                  _p_wait      = p_wait,
204                  _locked_data = locked_data,
205                  _nbrequest   = nbrequest;
206
207      while (this->hasRequest())
208      {
209         this->getNextRequest().printToTextStream(_ostr);
210         _ostr << std::endl;
211      }
212
213      p_write     = _p_write;
214      p_read      = _p_read;
215      p_unused    = _p_unused;
216      p_wait      = _p_wait;
217      locked_data = _locked_data;
218      nbrequest   = _nbrequest;
219   }
220
221   // ------------------------------- Accesseurs -------------------------------
222   
223   std::size_t CCircularBuffer::getNumberOfRequest(void) const
224   { 
225      return (this->nbrequest); 
226   }
227
228   std::size_t CCircularBuffer::getReadPosition(void) const
229   { 
230      return (this->p_read); 
231   }
232
233   std::size_t CCircularBuffer::getWritePosition(void) const
234   { 
235      return (this->p_write); 
236   }
237
238   std::size_t CCircularBuffer::getUnusedPosition(void) const
239   { 
240      return (this->p_unused); 
241   }
242   
243   std::size_t CCircularBuffer::getWaitPosition(void) const
244   { 
245      return (this->p_wait); 
246   }
247
248
249   // ------------------------- Mise à jour des données -----------------------
250   
251   void CCircularBuffer::updateNbRequests(void)
252   {
253      this->updateNbRequests(this->p_wait, this->p_wait + this->locked_data);
254   }
255
256   void CCircularBuffer::updateNbRequests(std::size_t _data_begin, std::size_t _data_end)
257   {
258      this-> p_wait        = 0;
259      this-> locked_data   = 0;
260      std::size_t position = _data_begin;       
261      while (position != _data_end)
262      {
263         this->nbrequest++;
264         position = SuperClass::getNextDataPosition(position); // manager id           
265         position = SuperClass::getNextDataPosition(position); // method id           
266         SuperClass::updateBufferData(position);
267         long int nbarg = SuperClass::getInt(position);
268         position = SuperClass::getNextDataPosition(position);
269         for (long int i = 0; i < nbarg; i++)
270            position = SuperClass::getNextDataPosition(position);
271           
272         if (position > _data_end)
273           XIOS_ERROR("CCircularBuffer::updateNbRequests(std::size_t data_begin, std::size_t data_end)",
274                      << "[ position courante" << position
275                      << ", fin de traitement" << _data_end << " ] "
276                      << "Impossible de mettre à jour la liste des requêtes !");
277      }
278   }
279     
280} // namespace comm
281} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.