summaryrefslogtreecommitdiff
path: root/i/chuck/src/data/data_buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'i/chuck/src/data/data_buffer.cc')
-rw-r--r--i/chuck/src/data/data_buffer.cc130
1 files changed, 130 insertions, 0 deletions
diff --git a/i/chuck/src/data/data_buffer.cc b/i/chuck/src/data/data_buffer.cc
new file mode 100644
index 0000000..c0d8cef
--- /dev/null
+++ b/i/chuck/src/data/data_buffer.cc
@@ -0,0 +1,130 @@
+// data_buffer.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Dufour Jérémy
+//
+// Robot APB Team/Efrei 2004.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "data_buffer.hh"
+
+#include <cstring> // std::memcpy
+#include <stdexcept> // std::runtime_error
+#include <algorithm> // std::swap
+
+static const unsigned min_size = 10;
+
+/// Constructeur par defaut
+DataBuffer::DataBuffer (void)
+ : size_ (min_size), headPos_ (0), tailPos_ (0), type_ (NoType)
+{
+ buffer_ = new uint8_t [size_];
+}
+
+/// Constructeur par recopie.
+DataBuffer::DataBuffer (const DataBuffer &d)
+ : headPos_ (0), type_ (NoType)
+{
+ unsigned sizeUse = d.tailPos_ - d.headPos_;
+ size_ = tailPos_ = sizeUse;
+ type_ = d.type_;
+ buffer_ = new uint8_t [size_];
+ std::memcpy (buffer_, &d.buffer_[headPos_], sizeUse);
+}
+
+/// Constructeur avec données.
+DataBuffer::DataBuffer (uint8_t *data, unsigned size, unsigned sizeAllocated,
+ dataType_e type)
+ : size_ (sizeAllocated), headPos_ (0), tailPos_ (size), type_ (type)
+{
+ if (!data || size > sizeAllocated)
+ throw std::invalid_argument ("Paramêtres invalides");
+ buffer_ = new uint8_t [size_];
+ std::memcpy (buffer_, data, tailPos_);
+}
+
+/// Surcharge de l'opérateur d'affectation
+DataBuffer &
+DataBuffer::operator= (const DataBuffer &d)
+{
+ DataBuffer b (d);
+ b.swap (*this);
+ return *this;
+}
+
+/// Lit des données. Même convention que le read de la libc, mais lance
+/// une exception en cas d'erreur.
+unsigned
+DataBuffer::read (uint8_t *buf, unsigned size)
+{
+ if (!buf)
+ throw std::invalid_argument ("Paramêtres invalides");
+ unsigned sizeTmp = tailPos_ - headPos_;
+ // On regarde combien de données peuvent être lues
+ if (size < sizeTmp)
+ sizeTmp = size;
+ std::memcpy (buf, &buffer_[headPos_], sizeTmp);
+ headPos_ += sizeTmp;
+ // Si il n'y a plus de données dans le buffer, on recommence de puis 0
+ if (headPos_ == tailPos_)
+ headPos_ = tailPos_ = 0;
+ return sizeTmp;
+}
+
+/// Écrit des données. Même convention que le write de la libc, mais lance
+/// une exception en cas d'erreur.
+void
+DataBuffer::write (const uint8_t *buf, unsigned size)
+{
+ // Vérification des paramêtres
+ if (!buf)
+ throw std::invalid_argument ("Parametres invalides");
+ // Agrandissement du buffer
+ grow (size);
+ // Ecriture des données
+ std::memcpy (&buffer_[tailPos_], buf, size);
+ tailPos_ += size;
+}
+
+/// Augmente la taille du buffer pour correspondre à size.
+void
+DataBuffer::grow (const unsigned size)
+{
+ // Taille restant non utilisé dans le buffer
+ unsigned tailleLibre = size_ - tailPos_;
+ // Si la taille du buffer n'est pas suffisante
+ if (tailleLibre < size)
+ {
+ // On augmente de deux fois la taille
+ DataBuffer d (&buffer_[headPos_], tailPos_ - headPos_,
+ 2 * size + size_, type_);
+ d.swap (*this);
+ }
+}
+
+/// Echange les buffers.
+void
+DataBuffer::swap (DataBuffer &d)
+{
+ std::swap (buffer_, d.buffer_);
+ std::swap (size_, d.size_);
+ std::swap (headPos_, d.headPos_);
+ std::swap (tailPos_, d.tailPos_);
+ std::swap (type_, d.type_);
+}