From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/buf__fifo_8cpp-source.html | 746 ++++++++++++++++++++++++++++ 1 file changed, 746 insertions(+) create mode 100644 docs/doxygen/nel/buf__fifo_8cpp-source.html (limited to 'docs/doxygen/nel/buf__fifo_8cpp-source.html') diff --git a/docs/doxygen/nel/buf__fifo_8cpp-source.html b/docs/doxygen/nel/buf__fifo_8cpp-source.html new file mode 100644 index 00000000..4b8a0f2a --- /dev/null +++ b/docs/doxygen/nel/buf__fifo_8cpp-source.html @@ -0,0 +1,746 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

buf_fifo.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdmisc.h"
+00027 
+00028 #include "nel/misc/time_nl.h"
+00029 
+00030 #include "nel/misc/buf_fifo.h"
+00031 
+00032 using namespace std;
+00033 
+00034 #define DEBUG_FIFO 0
+00035 
+00036 namespace NLMISC {
+00037 
+00038 
+00039 CBufFIFO::CBufFIFO() : _Buffer(NULL), _BufferSize(0), _Empty(true), _Head(NULL), _Tail(NULL), _Rewinder(NULL)
+00040 {
+00041         // reset statistic
+00042         _BiggestBlock = 0;
+00043         _SmallestBlock = 999999999;
+00044         _BiggestBuffer = 0;
+00045         _SmallestBuffer = 999999999;
+00046         _Pushed = 0;
+00047         _Fronted = 0;
+00048         _Resized = 0;
+00049         _PushedTime = 0;
+00050         _FrontedTime = 0;
+00051         _ResizedTime = 0;
+00052 }
+00053 
+00054 CBufFIFO::~CBufFIFO()
+00055 {
+00056         if (_Buffer != NULL)
+00057         {
+00058                 delete _Buffer;
+00059 #if DEBUG_FIFO
+00060                 nldebug("%p delete", this);
+00061 #endif
+00062         }
+00063 }
+00064 
+00065 void     CBufFIFO::push (const uint8 *buffer, uint32 size)
+00066 {
+00067         // if the buffer is more than 1 meg, there s surely a problem, no?
+00068 //      nlassert( buffer.size() < 1000000 ); // size check in debug mode
+00069 
+00070         TTicks before = CTime::getPerformanceTime();
+00071 
+00072 #if DEBUG_FIFO
+00073         nldebug("%p push(%d)", this, size);
+00074 #endif
+00075 
+00076         nlassert(size > 0 && size < pow(2, sizeof(TFifoSize)*8));
+00077 
+00078         // stat code
+00079         if (size > _BiggestBlock) _BiggestBlock = size;
+00080         if (size < _SmallestBlock) _SmallestBlock = size;
+00081         _Pushed++;
+00082 
+00083         while (!canFit (size + sizeof (TFifoSize)))
+00084         {
+00085                 resize(_BufferSize * 2);
+00086         }
+00087 
+00088         *(TFifoSize *)_Head = size;
+00089         _Head += sizeof(TFifoSize);
+00090 
+00091         CFastMem::memcpy(_Head, buffer, size);
+00092 
+00093         _Head += size;
+00094 
+00095         _Empty = false;
+00096 
+00097         // stat code
+00098         TTicks after = CTime::getPerformanceTime();
+00099         _PushedTime += after - before;
+00100 
+00101 #if DEBUG_FIFO
+00102         display ();
+00103 #endif
+00104 }
+00105 
+00106 void CBufFIFO::push(const std::vector<uint8> &buffer1, const std::vector<uint8> &buffer2)
+00107 {
+00108         TTicks before = CTime::getPerformanceTime();
+00109 
+00110         TFifoSize size = buffer1.size() + buffer2.size ();
+00111 
+00112 #if DEBUG_FIFO
+00113         nldebug("%p push2(%d)", this, size);
+00114 #endif
+00115 
+00116         nlassert((buffer1.size() + buffer2.size ()) > 0 && (buffer1.size() + buffer2.size ()) < pow(2, sizeof(TFifoSize)*8));
+00117 
+00118         // avoid too big fifo
+00119         if (this->size() > 10000000)
+00120         {
+00121                 throw Exception ("CBufFIFO::push(): stack full (more than 10mb)");
+00122         }
+00123 
+00124 
+00125         // stat code
+00126         if (size > _BiggestBlock) _BiggestBlock = size;
+00127         if (size < _SmallestBlock) _SmallestBlock = size;
+00128 
+00129         _Pushed++;
+00130 
+00131         // resize while the buffer is enough big to accept the block
+00132         while (!canFit (size + sizeof (TFifoSize)))
+00133         {
+00134                 resize(_BufferSize * 2);
+00135         }
+00136 
+00137         // store the size of the block
+00138         *(TFifoSize *)_Head = size;
+00139         _Head += sizeof(TFifoSize);
+00140 
+00141         // store the block itself
+00142         CFastMem::memcpy(_Head, &(buffer1[0]), buffer1.size ());
+00143         CFastMem::memcpy(_Head + buffer1.size(), &(buffer2[0]), buffer2.size ());
+00144         _Head += size;
+00145 
+00146         _Empty = false;
+00147 
+00148         // stat code
+00149         TTicks after = CTime::getPerformanceTime();
+00150         _PushedTime += after - before;
+00151 
+00152 #if DEBUG_FIFO
+00153         display ();
+00154 #endif
+00155 }
+00156 
+00157 void CBufFIFO::pop ()
+00158 {
+00159         if (empty ())
+00160         {
+00161                 nlwarning("Try to pop an empty fifo!");
+00162                 return;
+00163         }
+00164 
+00165         if (_Rewinder != NULL && _Tail == _Rewinder)
+00166         {
+00167 #if DEBUG_FIFO
+00168                 nldebug("%p pop rewind!", this);
+00169 #endif
+00170 
+00171                 // need to rewind
+00172                 _Tail = _Buffer;
+00173                 _Rewinder = NULL;
+00174         }
+00175 
+00176         TFifoSize size = *(TFifoSize *)_Tail;
+00177 
+00178 #if DEBUG_FIFO
+00179         nldebug("%p pop(%d)", this, size);
+00180 #endif
+00181 
+00182 #ifdef NL_DEBUG
+00183         // clear the message to be sure user doesn't use it anymore
+00184         memset (_Tail, '-', size + sizeof (TFifoSize));
+00185 #endif
+00186 
+00187         _Tail += size + sizeof (TFifoSize);
+00188 
+00189         if (_Tail == _Head) _Empty = true;
+00190 
+00191 #if DEBUG_FIFO
+00192         display ();
+00193 #endif
+00194 }
+00195 
+00196 uint8 CBufFIFO::frontLast ()
+00197 {
+00198         uint8   *tail = _Tail;
+00199         
+00200         if (empty ())
+00201         {
+00202                 nlwarning("Try to get the front of an empty fifo!");
+00203                 return 0;
+00204         }
+00205 
+00206         if (_Rewinder != NULL && tail == _Rewinder)
+00207         {
+00208 #if DEBUG_FIFO
+00209                 nldebug("%p front rewind!", this);
+00210 #endif
+00211 
+00212                 // need to rewind
+00213                 tail = _Buffer;
+00214         }
+00215 
+00216         TFifoSize size = *(TFifoSize *)tail;
+00217 
+00218 #if DEBUG_FIFO
+00219         nldebug("%p frontLast() returns %d ", this, size, *(tail+sizeof(TFifoSize)+size-1));
+00220 #endif
+00221 
+00222         return *(tail+sizeof(TFifoSize)+size-1);
+00223 }
+00224 
+00225 
+00226 void CBufFIFO::front (vector<uint8> &buffer)
+00227 {
+00228         uint8 *tmpbuffer;
+00229         uint32 size;
+00230 
+00231         buffer.clear ();
+00232 
+00233         front (tmpbuffer, size);
+00234         
+00235         buffer.resize (size);
+00236 
+00237         CFastMem::memcpy (&(buffer[0]), tmpbuffer, size);
+00238 
+00239 /*      TTicks before = CTime::getPerformanceTime ();
+00240 
+00241         uint8   *tail = _Tail;
+00242         
+00243         buffer.clear ();
+00244 
+00245         if (empty ())
+00246         {
+00247                 nlwarning("Try to get the front of an empty fifo!");
+00248                 return;
+00249         }
+00250 
+00251         _Fronted++;
+00252         
+00253         if (_Rewinder != NULL && tail == _Rewinder)
+00254         {
+00255 #if DEBUG_FIFO
+00256                 nldebug("%p front rewind!", this);
+00257 #endif
+00258 
+00259                 // need to rewind
+00260                 tail = _Buffer;
+00261         }
+00262 
+00263         TFifoSize size = *(TFifoSize *)tail;
+00264 
+00265 #if DEBUG_FIFO
+00266         nldebug("%p front(%d)", this, size);
+00267 #endif
+00268 
+00269         tail += sizeof (TFifoSize);
+00270 
+00271         buffer.resize (size);
+00272 
+00273         CFastMem::memcpy (&(buffer[0]), tail, size);
+00274 
+00275         // stat code
+00276         TTicks after = CTime::getPerformanceTime ();
+00277         _FrontedTime += after - before;
+00278 
+00279 #if DEBUG_FIFO
+00280         display ();
+00281 #endif
+00282 */}
+00283 
+00284 
+00285 void CBufFIFO::front (NLMISC::CMemStream &buffer)
+00286 {
+00287         uint8 *tmpbuffer;
+00288         uint32 size;
+00289 
+00290         buffer.clear ();
+00291 
+00292         front (tmpbuffer, size);
+00293 
+00294         buffer.fill (tmpbuffer, size);
+00295         
+00296         /*
+00297         TTicks before = CTime::getPerformanceTime ();
+00298 
+00299         uint8   *tail = _Tail;
+00300         
+00301         buffer.clear ();
+00302 
+00303         if (empty ())
+00304         {
+00305                 nlwarning("Try to get the front of an empty fifo!");
+00306                 return;
+00307         }
+00308 
+00309         _Fronted++;
+00310         
+00311         if (_Rewinder != NULL && tail == _Rewinder)
+00312         {
+00313 #if DEBUG_FIFO
+00314                 nldebug("%p front rewind!", this);
+00315 #endif
+00316 
+00317                 // need to rewind
+00318                 tail = _Buffer;
+00319         }
+00320 
+00321         TFifoSize size = *(TFifoSize *)tail;
+00322 
+00323 #if DEBUG_FIFO
+00324         nldebug("%p front(%d)", this, size);
+00325 #endif
+00326 
+00327         tail += sizeof (TFifoSize);
+00328 
+00329         //buffer.resize (size);
+00330         //CFastMem::memcpy (&(buffer[0]), tail, size);
+00331 
+00332         buffer.fill (tail, size);
+00333 
+00334         // stat code
+00335         TTicks after = CTime::getPerformanceTime ();
+00336         _FrontedTime += after - before;
+00337 
+00338 #if DEBUG_FIFO
+00339         display ();
+00340 #endif*/
+00341 }
+00342 
+00343 void CBufFIFO::front (uint8 *&buffer, uint32 &size)
+00344 {
+00345         TTicks before = CTime::getPerformanceTime ();
+00346 
+00347         uint8   *tail = _Tail;
+00348 
+00349         if (empty ())
+00350         {
+00351                 nlwarning("Try to get the front of an empty fifo!");
+00352                 return;
+00353         }
+00354 
+00355         _Fronted++;
+00356         
+00357         if (_Rewinder != NULL && tail == _Rewinder)
+00358         {
+00359 #if DEBUG_FIFO
+00360                 nldebug("%p front rewind!", this);
+00361 #endif
+00362 
+00363                 // need to rewind
+00364                 tail = _Buffer;
+00365         }
+00366 
+00367         size = *(TFifoSize *)tail;
+00368 
+00369 #if DEBUG_FIFO
+00370         nldebug("%p front(%d)", this, size);
+00371 #endif
+00372 
+00373         tail += sizeof (TFifoSize);
+00374 
+00375         // stat code
+00376         TTicks after = CTime::getPerformanceTime ();
+00377         _FrontedTime += after - before;
+00378 
+00379 #if DEBUG_FIFO
+00380         display ();
+00381 #endif
+00382 
+00383         buffer = tail;
+00384 }
+00385 
+00386 
+00387 
+00388 void CBufFIFO::clear ()
+00389 {
+00390         _Tail = _Head = _Buffer;
+00391         _Rewinder = NULL;
+00392         _Empty = true;
+00393 }
+00394 
+00395 uint32 CBufFIFO::size ()
+00396 {
+00397         if (empty ())
+00398         {
+00399                 return 0;
+00400         }
+00401         else if (_Head == _Tail)
+00402         {
+00403                 // buffer is full
+00404                 if (_Rewinder == NULL)
+00405                         return _BufferSize;
+00406                 else
+00407                         return _Rewinder - _Buffer;
+00408         }
+00409         else if (_Head > _Tail)
+00410         {
+00411                 return _Head - _Tail;
+00412         }
+00413         else if (_Head < _Tail)
+00414         {
+00415                 nlassert (_Rewinder != NULL);
+00416                 return (_Rewinder - _Tail) + (_Head - _Buffer);
+00417         }
+00418         nlstop;
+00419         return 0;
+00420 }
+00421 
+00422 void CBufFIFO::resize (uint32 size)
+00423 {
+00424         TTicks before = CTime::getPerformanceTime();
+00425 
+00426         if (size == 0) size = 100;
+00427 
+00428 #if DEBUG_FIFO
+00429         nldebug("%p resize(%d)", this, size);
+00430 #endif
+00431 
+00432         if (size > _BiggestBuffer) _BiggestBuffer = size;
+00433         if (size < _SmallestBuffer) _SmallestBuffer = size;
+00434 
+00435         _Resized++;
+00436 
+00437         uint32 UsedSize = CBufFIFO::size();
+00438 
+00439         // creer un nouveau tableau et copie l ancien dans le nouveau.
+00440         if (size < _BufferSize && UsedSize > size)
+00441         {
+00442                 // probleme, on a pas assez de place pour caser les datas => on fait pas
+00443                 nlwarning("Can't resize the FIFO because there's not enough room in the new wanted buffer (%d bytes needed at least)", UsedSize);
+00444                 return;
+00445         }
+00446 
+00447         uint8 *NewBuffer = new uint8[size];
+00448         if (NewBuffer == NULL)
+00449         {
+00450                 nlerror("Not enough memory to resize the FIFO to %u bytes", size);
+00451         }
+00452 #ifdef NL_DEBUG
+00453         // clear the message to be sure user doesn't use it anymore
+00454         memset (NewBuffer, '-', size);
+00455 #endif
+00456 
+00457 #if DEBUG_FIFO
+00458         nldebug("%p new %d bytes", this, size);
+00459 #endif
+00460 
+00461         // copy the old buffer to the new one
+00462         // if _Tail == _Head => empty fifo, don't copy anything
+00463         if (!empty())
+00464         {
+00465                 if (_Tail < _Head)
+00466                 {
+00467                         CFastMem::memcpy (NewBuffer, _Tail, UsedSize);
+00468                 }
+00469                 else if (_Tail >= _Head)
+00470                 {
+00471                         nlassert (_Rewinder != NULL);
+00472 
+00473                         uint size1 = _Rewinder - _Tail;
+00474                         CFastMem::memcpy (NewBuffer, _Tail, size1);
+00475                         uint size2 = _Head - _Buffer;
+00476                         CFastMem::memcpy (NewBuffer + size1, _Buffer, size2);
+00477 
+00478                         nlassert (size1+size2==UsedSize);
+00479                 }
+00480         }
+00481 
+00482         // resync the circular pointer
+00483         // Warning: don't invert these 2 lines position or it ll not work
+00484         _Tail = NewBuffer;
+00485         _Head = NewBuffer + UsedSize;
+00486         _Rewinder = NULL;
+00487 
+00488         // delete old buffer if needed
+00489         if (_Buffer != NULL)
+00490         {
+00491                 delete _Buffer;
+00492 #if DEBUG_FIFO
+00493                 nldebug ("delete", this);
+00494 #endif
+00495         }
+00496 
+00497         // affect new buffer
+00498         _Buffer = NewBuffer;
+00499         _BufferSize = size;
+00500 
+00501         TTicks after = CTime::getPerformanceTime();
+00502 
+00503         _ResizedTime += after - before;
+00504 
+00505 #if DEBUG_FIFO
+00506         display ();
+00507 #endif
+00508 }
+00509 
+00510 void CBufFIFO::displayStats ()
+00511 {
+00512         nlinfo ("%p _BiggestBlock: %d", this, _BiggestBlock);
+00513         nlinfo ("%p _SmallestBlock: %d", this, _SmallestBlock);
+00514         nlinfo ("%p _BiggestBuffer: %d", this, _BiggestBuffer);
+00515         nlinfo ("%p _SmallestBuffer: %d", this, _SmallestBuffer);
+00516         nlinfo ("%p _Pushed : %d", this, _Pushed);
+00517         nlinfo ("%p _Fronted: %d", this, _Fronted);
+00518         nlinfo ("%p _Resized: %d", this, _Resized);
+00519         nlinfo ("%p _PushedTime: %"NL_I64"d %f", this, _PushedTime, (double)(sint64)_PushedTime / (double)_Pushed);
+00520         nlinfo ("%p _FrontedTime: %"NL_I64"d %f", this, _FrontedTime, (double)(sint64)_FrontedTime / (double)_Fronted);
+00521         nlinfo ("%p _ResizedTime: %"NL_I64"d %f", this, _ResizedTime, (double)(sint64)_ResizedTime / (double)_Resized);
+00522 }
+00523 
+00524 void CBufFIFO::display ()
+00525 {
+00526         int size = 64;
+00527         int gran = size/30;
+00528 
+00529         char str[1024];
+00530 
+00531         smprintf(str, 1024, "%p %p (%5d %5d) %p %p %p ", this, _Buffer, _BufferSize, CBufFIFO::size(), _Rewinder, _Tail, _Head);
+00532 
+00533         int i;
+00534         for (i = 0; i < (sint32) _BufferSize; i+= gran)
+00535         {
+00536                 uint8 *pos = _Buffer + i;
+00537                 if (_Tail >= pos && _Tail < pos + gran)
+00538                 {
+00539                         if (_Head >= pos && _Head < pos + gran)
+00540                         {
+00541                                 if (_Rewinder != NULL && _Rewinder >= pos && _Rewinder < pos + gran)
+00542                                 {
+00543                                         strncat (str, "*", 1024);
+00544                                 }
+00545                                 else
+00546                                 {
+00547                                         strncat (str, "@", 1024);
+00548                                 }
+00549                         }
+00550                         else
+00551                         {
+00552                                 strncat (str, "T", 1024);
+00553                         }
+00554                 }
+00555                 else if (_Head >= pos && _Head < pos + gran)
+00556                 {
+00557                         strncat (str, "H", 1024);
+00558                 }
+00559                 else if (_Rewinder != NULL && _Rewinder >= pos && _Rewinder < pos + gran)
+00560                 {
+00561                         strncat (str, "R", 1024);
+00562                 }
+00563                 else
+00564                 {
+00565                         if (strlen(str) < 1023)
+00566                         {
+00567                                 uint32 p = strlen(str);
+00568                                 if (isprint(*pos))
+00569                                         str[p] = *pos;
+00570                                 else
+00571                                         str[p] = '$';
+00572 
+00573                                 str[p+1] = '\0';
+00574                         }
+00575                 }
+00576         }
+00577 
+00578         for (; i < size; i+= gran)
+00579         {
+00580                 strncat (str, " ", 1024);
+00581         }
+00582 #ifdef NL_DEBUG
+00583         strncat (str, "\n", 1024);
+00584 #else
+00585         strncat (str, "\r", 1024);
+00586 #endif
+00587         DebugLog->display (str);
+00588 }
+00589 
+00590 bool CBufFIFO::canFit (uint32 size)
+00591 {
+00592         if (_Tail == _Head)
+00593         {
+00594                 if (empty())
+00595                 {
+00596                         // is the buffer large enough?
+00597                         if (_BufferSize >= size)
+00598                         {
+00599                                 // reset the pointer
+00600 #if DEBUG_FIFO
+00601                                 nldebug("%p reset tail and head", this);
+00602 #endif
+00603                                 _Head = _Tail = _Buffer;
+00604                                 return true;
+00605                         }
+00606                         else
+00607                         {
+00608                                 // buffer not big enough
+00609 #if DEBUG_FIFO
+00610                                 nldebug("%p buffer full buffersize<size", this);
+00611 #endif
+00612                                 return false;
+00613                         }
+00614                 }
+00615                 else
+00616                 {
+00617                         // buffer full
+00618 #if DEBUG_FIFO
+00619                         nldebug("%p buffer full h=t", this);
+00620 #endif
+00621                         return false;
+00622                 }
+00623         }
+00624         else if (_Tail < _Head)
+00625         {
+00626                 if (_Buffer + _BufferSize - _Head >= (sint32) size)
+00627                 {
+00628                         // can fit after _Head
+00629 #if DEBUG_FIFO
+00630                         nldebug("%p fit after", this);
+00631 #endif
+00632                         return true;
+00633                 }
+00634                 else if (_Tail - _Buffer >= (sint32) size)
+00635                 {
+00636                         // can fit at the beginning
+00637 #if DEBUG_FIFO
+00638                         nldebug("%p fit at beginning", this);
+00639 #endif
+00640                         _Rewinder = _Head;
+00641 #if DEBUG_FIFO
+00642                         nldebug("%p set the rewinder", this);
+00643 #endif
+00644                         _Head = _Buffer;
+00645                         return true;
+00646                 }
+00647                 else
+00648                 {
+00649                         // can't fit
+00650 #if DEBUG_FIFO
+00651                         nldebug("%p no room t<h", this);
+00652 #endif
+00653                         return false;
+00654                 }
+00655         }
+00656         else // the last case is : if (_Tail > _Head)
+00657         {
+00658                 if (_Tail - _Head >= (sint32) size)
+00659                 {
+00660 #if DEBUG_FIFO
+00661                         nldebug("%p fit t>h", this);
+00662 #endif
+00663                         return true;
+00664                 }
+00665                 else
+00666                 {
+00667 #if DEBUG_FIFO
+00668                         nldebug("%p no room t>h", this);
+00669 #endif
+00670                         return false;
+00671                 }
+00672         }
+00673         nlstop;
+00674 }
+00675 
+00676 
+00677 } // NLMISC
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1