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

Last change on this file since 196 was 196, checked in by hozdoba, 12 years ago
File size: 7.7 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, 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         this->movePRead(currsize);
69         this->nbrequest--;
70         return (CLinearBuffer(SuperClass::getData(startpos), currsize));
71      }
72
73      //-------------------------------------------------------------
74
75      void CCircularBuffer::appendRequest(const CLinearBuffer & brequest)
76      {
77         StdSize usedsize   = brequest.getUsedSize();
78         if (!this->isAvailable(usedsize))
79            ERROR("CCircularBuffer::appendRequest(brequest)",
80                  << " invalid call !");
81         StdSize data_begin = this->prepareNextDataPosition(usedsize);
82         SuperClass::setData(brequest.getData(), usedsize, data_begin);
83         this->updateNbRequests(data_begin, data_begin + usedsize);
84      }
85
86      //-------------------------------------------------------------
87
88      char * CCircularBuffer::prepareNextData(StdSize data_size)
89      {
90         return (SuperClass::getData(this->prepareNextDataPosition(data_size)));
91      }
92     
93      //-------------------------------------------------------------
94
95      StdSize CCircularBuffer::prepareNextDataPosition(StdSize data_size)
96      {
97         StdSize startpos = this-> p_write;
98         if (!this->isAvailable(data_size))
99            ERROR("CCircularBuffer::prepareNextDataPosition(data_size)",
100                  << " invalid call !");
101         if ((this-> p_write + data_size) > SuperClass::getSize())
102            startpos = 0;
103
104         this->movePWrite(data_size);
105         return (startpos);
106      }
107
108      //-------------------------------------------------------------
109
110      void CCircularBuffer::movePRead(StdSize data_size)
111      {
112         this-> p_read += data_size;
113         if (this-> p_read == this-> p_unused)
114         {
115            this-> p_unused = this-> p_write;
116            this-> p_read   = 0;
117         }
118         if (this-> p_read == this-> p_write)
119            this->clear();
120      }
121     
122      //-------------------------------------------------------------
123     
124      void CCircularBuffer::movePWrite(StdSize data_size)
125      {
126         if ((this-> p_write + data_size) > SuperClass::getSize())
127         {
128            this-> p_unused = this-> p_write;
129            this-> p_write  = data_size;
130            if (this-> p_read < (data_size))
131               ERROR("CCircularBuffer::movePWrite(data_size)",
132                     << " invalid position 1 !");
133         }
134         else
135         {
136            if ((this-> p_read > this-> p_write) &&
137                (this-> p_read < (this-> p_write + data_size)))
138               ERROR("CCircularBuffer::movePWrite(data_size)",
139                     << " invalid position 2 !");
140            this-> p_write += data_size;
141            if (this->p_read < this->p_write)
142               this-> p_unused = this-> p_write;
143         }
144      }
145
146      //-------------------------------------------------------------
147
148      bool CCircularBuffer::hasRequest(void) const
149      { 
150         return (this->nbrequest != 0); 
151      }
152     
153      //-------------------------------------------------------------
154     
155      bool CCircularBuffer::isAvailable(StdSize data_size) const
156      {
157         if (this->p_write == this->p_unused)
158            return (((SuperClass::getSize() - this->p_write) >= data_size) ||
159                   (this->p_read >= data_size));
160         else
161            return ((this->p_read - this->p_write) >= data_size);
162      }
163      //---------------------------------------------------------------
164
165      void CCircularBuffer::printToTextFile (const StdString & filename)
166      {
167         StdOFStream ofs(filename.c_str());
168         this->printToTextStream(ofs);
169         ofs.close();
170      }
171     
172      //-------------------------------------------------------------
173     
174      void CCircularBuffer::printToTextStream (StdOStream & ostr)
175      {
176         StdSize _p_write   = p_write,
177                 _p_read    = p_read,
178                 _p_unused  = p_unused,
179                 _nbrequest = nbrequest;
180
181         while (this->hasRequest())
182         {
183            this->getNextRequest().printToTextStream(ostr);
184            ostr << std::endl;
185         }
186
187         p_write   = _p_write;
188         p_read    = _p_read;
189         p_unused  = _p_unused;
190         nbrequest = _nbrequest;
191      }
192
193      //---------------------------------------------------------------
194
195      StdSize CCircularBuffer::getNumberOfRequest(void) const
196      { return (this->nbrequest); }
197
198      StdSize CCircularBuffer::getReadPosition(void) const
199      { return (this->p_read); }
200
201      StdSize CCircularBuffer::getWritePosition(void) const
202      { return (this->p_write); }
203
204      StdSize CCircularBuffer::getUnusedPosition(void) const
205      { return (this->p_unused); }
206
207      //---------------------------------------------------------------
208
209      void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)
210      {
211         StdSize position = data_begin, i = 0;
212         while (position != data_end)
213         {
214            i++;
215            this->nbrequest++;
216            position = SuperClass::getNextDataPosition(position); // manager id
217            position = SuperClass::getNextDataPosition(position); // method id
218            long int nbarg = SuperClass::getInt(position);
219            position = SuperClass::getNextDataPosition(position);
220            for (long int i = 0; i < nbarg; i++)
221               position = SuperClass::getNextDataPosition(position);
222         }
223      }
224
225      ///------------------------------------------------------------
226   } // namespace tree
227} // namespace xmlioserver
228
Note: See TracBrowser for help on using the repository browser.