/tags/rel-0-1-0/FreeSpeech/data-flow/include/RotatingBuffer.h

# · C++ Header · 140 lines · 87 code · 22 blank · 31 comment · 10 complexity · 36bac89eb36f5bc49d739f7006319bbb MD5 · raw file

  1. // Copyright (C) 1999 Jean-Marc Valin
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2, or (at your option)
  6. // any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful, but
  9. // WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. // General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this file. If not, write to the Free Software Foundation,
  15. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. #ifndef ROTATING_BUFFER_H
  17. #define ROTATING_BUFFER_H
  18. #include "Object.h"
  19. #include "ObjectRef.h"
  20. #include "Exception.h"
  21. #include <typeinfo>
  22. #include "Buffer.h"
  23. #include <vector>
  24. /**A rotating buffer implementation.
  25. This buffer keeps the last N lines (frames) it has*/
  26. class RotatingBuffer : public Buffer {
  27. protected:
  28. ///Pointer to raw float
  29. mutable vector<ObjectRef> data ;
  30. ///The number N of lines kept
  31. int bufferLength ;
  32. public:
  33. ///Constructor, requires the vector length (vLength) and the buffer length (bLength)
  34. RotatingBuffer(int bLength)
  35. : data(bLength)
  36. , bufferLength (bLength)
  37. {
  38. for (int i=0;i<bLength;i++)
  39. data[i]=ObjectRef(new Object(Object::nil));
  40. }
  41. ///Copy constructor (not implemented, do we need one?)
  42. RotatingBuffer(const RotatingBuffer&);
  43. ///Indexing operator, also sets the indexed frame as being the current frame
  44. ObjectRef operator[] (int ind) const;
  45. ///Indexing operator, also sets the indexed frame as being the current frame
  46. ObjectRef & operator[] (int ind) ;
  47. ///Print
  48. virtual void printOn(ostream &out = cout) const;
  49. };
  50. class RotatingBufferException : public BaseException {
  51. public:
  52. ///The constructor with the parameters
  53. RotatingBufferException(const RotatingBuffer *_buffer, string _message, int _element)
  54. : buffer (_buffer)
  55. , message(_message)
  56. , element(_element)
  57. {}
  58. ///The print method
  59. virtual void print(ostream &out = cerr)
  60. {
  61. out<< typeid(RotatingBuffer).name() << " error: "<< message << ".\nElement " << element << endl;
  62. out << "Buffer is: \n";
  63. out << *buffer;
  64. }
  65. protected:
  66. ///the buffer that generated the error
  67. const RotatingBuffer *buffer;
  68. ///the error message
  69. string message;
  70. //The element for which the error occured
  71. int element;
  72. };
  73. inline ObjectRef & RotatingBuffer::operator[] (int ind)
  74. {
  75. if (ind > currentPos)
  76. {
  77. for (int i=currentPos+1;i<=ind;i++)
  78. data[ind % bufferLength] = Object::nilObject;
  79. currentPos = ind;
  80. }
  81. if (ind < 0 || ind <= currentPos-bufferLength)
  82. {
  83. //cerr << "ind = " << ind << endl;
  84. throw new RotatingBufferException (this, "trying to access non-existing element",ind);
  85. }
  86. return data[ind % bufferLength];
  87. }
  88. inline ObjectRef RotatingBuffer::operator[] (int ind) const
  89. {
  90. if (ind > currentPos)
  91. {
  92. for (int i=currentPos+1;i<=ind;i++)
  93. data[ind % bufferLength] = Object::nilObject;
  94. currentPos = ind;
  95. }
  96. if (ind < 0 || ind <= currentPos-bufferLength)
  97. {
  98. throw new RotatingBufferException (this, "trying to access non-existing element",ind);
  99. }
  100. return data[ind % bufferLength];
  101. }
  102. inline void RotatingBuffer::printOn(ostream &out) const
  103. {
  104. int i;
  105. //cerr << "printing... currentPos = " << currentPos << " bufferLength = " << bufferLength << endl;
  106. out << "<RotatingBuffer" << endl;
  107. for (i=max(0,currentPos-bufferLength+1);i<=currentPos;i++)
  108. {
  109. out << "< " << i << " < ";
  110. out << *((*this)[i]);
  111. out << " > > ";
  112. out << endl;
  113. }
  114. out << " > " << endl;
  115. }
  116. inline RotatingBuffer::RotatingBuffer(const RotatingBuffer&)
  117. {throw new RotatingBufferException(NULL,"use an ObjectRef instead",0);}
  118. #endif