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

Last change on this file since 152 was 152, checked in by hozdoba, 12 years ago
File size: 6.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), p_write(0), p_read(0), p_unused(0), nbrequest(0)
12      { /* Ne rien faire de plus */ }
13
14      CCircularBuffer::~CCircularBuffer(void)
15      { /* Ne rien faire de plus */ }
16
17      ///--------------------------------------------------------------
18
19      void CCircularBuffer::clear(void)
20      {
21         this-> p_write  = 0;
22         this-> p_read   = 0;
23         this-> p_unused = 0;
24      }
25
26      //-------------------------------------------------------------
27
28      StdSize CCircularBuffer::getNextRequestSize(void) const
29      {
30         if (!this->hasRequest())
31            ERROR("CCircularBuffer::getNextRequestSize()",
32                  << " invalid call !");
33         long int nbargs  = 0;
34         StdSize startpos = this-> p_read;
35         StdSize currsize = 2 * SuperClass::getRequestedSize(nbargs);
36         nbargs    = SuperClass::getInt(startpos + currsize);
37         currsize += SuperClass::getRequestedSize(nbargs);
38
39         for (long int i = 0; i < nbargs; i++)
40         {
41            CBufferData bufdata;
42            SuperClass::getBufferData(bufdata, currsize);
43            currsize += (bufdata.size + DATA_HEADER_SIZE);
44         }
45         return (currsize);
46      }
47
48      CLinearBuffer CCircularBuffer::getNextRequest(void)
49      {
50         StdSize startpos = this-> p_read;
51         StdSize currsize = this->getNextRequestSize();
52         this->movePRead(currsize);
53         this->nbrequest--;
54         return (CLinearBuffer(SuperClass::getData(startpos), currsize));
55      }
56
57      //-------------------------------------------------------------
58
59      void CCircularBuffer::appendRequest(const CLinearBuffer & brequest)
60      {
61         StdSize usedsize   = brequest.getUsedSize();
62         if (!this->isAvailable(usedsize))
63            ERROR("CCircularBuffer::appendRequest(brequest)",
64                  << " invalid call !");
65         StdSize data_begin = this->prepareNextDataPosition(usedsize);
66         SuperClass::setData(brequest.getData(), usedsize, data_begin);
67         this->updateNbRequests(data_begin, data_begin + usedsize);
68      }
69
70      //-------------------------------------------------------------
71
72      char * CCircularBuffer::prepareNextData(StdSize data_size)
73      {
74         return (SuperClass::getData(this->prepareNextDataPosition(data_size)));
75      }
76
77
78      StdSize CCircularBuffer::prepareNextDataPosition(StdSize data_size)
79      {
80         StdSize startpos = this-> p_write;
81         if (!this->isAvailable(data_size))
82            ERROR("CCircularBuffer::prepareNextDataPosition(data_size)",
83                  << " invalid call !");
84         if ((this-> p_write + data_size) > SuperClass::getSize())
85            startpos = 0;
86
87         this->movePWrite(data_size);
88         return (startpos);
89      }
90
91      //-------------------------------------------------------------
92
93      void CCircularBuffer::movePRead(StdSize data_size)
94      {
95         this-> p_read += data_size;
96         if (this-> p_read == this-> p_unused)
97         {
98            this-> p_unused = this-> p_write;
99            this-> p_read   = 0;
100         }
101         if (this-> p_read == this-> p_write)
102            this->clear();
103      }
104
105      void CCircularBuffer::movePWrite(StdSize data_size)
106      {
107         if ((this-> p_write + data_size) > SuperClass::getSize())
108         {
109            this-> p_unused = this-> p_write;
110            this-> p_write  = data_size;
111            if (this-> p_read < (data_size))
112               ERROR("CCircularBuffer::movePWrite(data_size)",
113                     << " invalid position 1 !");
114         }
115         else
116         {
117            if ((this-> p_read > this-> p_write) &&
118                (this-> p_read < (this-> p_write + data_size)))
119               ERROR("CCircularBuffer::movePWrite(data_size)",
120                     << " invalid position 2 !");
121            this-> p_write += data_size;
122            if (this->p_read < this->p_write)
123               this-> p_unused = this-> p_write;
124         }
125      }
126
127      //-------------------------------------------------------------
128
129      bool CCircularBuffer::hasRequest(void) const
130      { return (this->nbrequest != 0); }
131
132      bool CCircularBuffer::isAvailable(StdSize data_size) const
133      {
134         if (this->p_write == this->p_unused)
135            return (((SuperClass::getSize() - this->p_write) >= data_size) ||
136                   (this->p_read >= data_size));
137         else
138            return ((this->p_read - this->p_write) >= data_size);
139      }
140      //---------------------------------------------------------------
141
142      void CCircularBuffer::printToTextFile (const StdString & filename)
143      {
144         StdOFStream ofs(filename.c_str());
145         this->printToTextStream(ofs);
146         ofs.close();
147      }
148
149      void CCircularBuffer::printToTextStream (StdOStream & ostr)
150      {
151         StdSize _p_write   = p_write,
152                 _p_read    = p_read,
153                 _p_unused  = p_unused,
154                 _nbrequest = nbrequest;
155
156         while (this->hasRequest())
157         {
158            this->getNextRequest().printToTextStream(ostr);
159            ostr << std::endl;
160         }
161
162         p_write   = _p_write;
163         p_read    = _p_read;
164         p_unused  = _p_unused;
165         nbrequest = _nbrequest;
166      }
167
168      //---------------------------------------------------------------
169
170      StdSize CCircularBuffer::getNumberOfRequest(void) const
171      { return (this->nbrequest); }
172
173      StdSize CCircularBuffer::getReadPosition(void) const
174      { return (this->p_read); }
175
176      StdSize CCircularBuffer::getWritePosition(void) const
177      { return (this->p_write); }
178
179      StdSize CCircularBuffer::getUnusedPosition(void) const
180      { return (this->p_unused); }
181
182      //---------------------------------------------------------------
183
184      void CCircularBuffer::updateNbRequests(StdSize data_begin, StdSize data_end)
185      {
186         StdSize position = data_begin;
187         while (position != data_end)
188         {
189            this->nbrequest++;
190            position = SuperClass::getNextDataPosition(position); // manager id
191            position = SuperClass::getNextDataPosition(position); // method id
192            long int nbarg = SuperClass::getInt(position);
193            position = SuperClass::getNextDataPosition(position);
194            for (long int i = 0; i < nbarg; i++)
195               position = SuperClass::getNextDataPosition(position);
196         }
197      }
198
199      ///------------------------------------------------------------
200   } // namespace tree
201} // namespace xmlioserver
202
Note: See TracBrowser for help on using the repository browser.