Remove dynamic exceptions
[anna.git] / include / anna / core / DataBlock.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_core_DataBlock_hpp
10 #define anna_core_DataBlock_hpp
11
12 #include <anna/core/RuntimeException.hpp>
13 #include <anna/config/defines.hpp>
14
15 namespace anna {
16
17 /**
18    Optimizacion de acceso a la memoria dinamica.
19
20    Incrementa el rendimiento al acceder y reservar de memoria dinamica mediante la reutilizacion controlada.
21
22    Para optimizar el acceso no se ha establecido ningun tipo de proteccion para ejecucion MT.
23 */
24 class DataBlock {
25 public:
26   /**
27     Constructor.
28
29     @param deepCopy Modo de copia de esta instancia. Si activamos el modo de copia profunda al asignar
30     cualquier otro bloque de memoria a este, se reserva (si fuese necesario) la memoria para ubicar el
31     buffer y despues realizara una copia byte a byte.
32   */
33   explicit DataBlock(const bool deepCopy = false)  :
34     a_buffer(NULL),
35     a_size(0),
36     a_deepCopy(deepCopy),
37     a_maxSize(0) {}
38
39   /**
40     Constructor.
41
42     @param buffer Bloque de memoria con el que inicializar el buffer de esta instancia.
43     @param size Numero de bytes del bloque de memoria recibido.
44     @param deepCopy Modo de copia de esta instancia. Si activamos el modo de copia profunda al asignar
45     cualquier otro bloque de memoria a este, se reserva la memoria para ubicar el buffer y despues
46     realizara una copia byte a byte.
47   */
48   DataBlock(const char* buffer, const int size, const bool deepCopy = false) noexcept(false);
49
50   /**
51     Constructor copia.
52     El modo de copia sera el mismo que el establecido por la instancia de la que copiar.
53
54     @param other Bloque de memoria con el que instanciar esta instancia.
55   */
56   DataBlock(const DataBlock& other) noexcept(false);
57
58   /**
59      Destructor.
60   */
61   virtual ~DataBlock();
62
63   // Accesores
64   /**
65      Éste metodo solo debe usarse en aplicaciones mono-thread o en situaciones en las que estemos seguros
66      que esta bloque de datos no puede verse afectado por otro thread.
67
68      @return Tamaño de la memoria reservada por esta instancia.
69   */
70   int getMaxSize() const { return a_maxSize; }
71
72   /**
73      Éste metodo solo debe usarse en aplicaciones mono-thread o en situaciones en las que estemos seguros
74      que esta bloque de datos no puede verse afectado por otro thread.
75
76      @return Tamaño del bloque de memoria contenido actualmente.
77   */
78   int getSize() const { return a_size; }
79
80   /**
81      Éste metodo solo debe usarse en aplicaciones mono-thread o en situaciones en las que estemos seguros
82      que esta bloque de datos no puede verse afectado por otro thread.
83
84      @return El contenido del bloque de memoria.
85   */
86   const char* getData() const { return a_buffer; }
87
88   /**
89      Devuelve informacion acerca del estado de ocupacion de este bloque de memoria.
90
91     @return \em true si el bloque de memoria esta vacio o \em false en otro caso.
92   */
93   bool isEmpty() const { return (a_size == 0) ? true : false; }
94
95   /**
96      Devuelve informacion acerca de la configuracion de reserva de memoria de este bloque.
97
98      @return @em true si el bloque de memoria tiene activado el sistema de copia profunda o @em false en otro caso.
99   */
100   bool deepCopy() const { return a_deepCopy; }
101
102   /**
103      Establece el numero de bytes que tiene asociado a este bloque de datos.
104      \param size numero de bytes que tiene asociado a este bloque de datos.
105      \warning El DataBlock delega la gestion de la memoria a la clase heredada.
106   */
107   void setSize(const int size) noexcept(false);
108
109   /**
110     Anade el caracter recibido al bloque de memoria. Para poder usar este operador el bloque de
111     memoria destino debe tener activado el modo de copia profunda. Si la memoria reservada no es
112     suficiente  reservara automaticamente la cantidad de memoria necesaria.
113
114     @param c Caracter a añadir a este bloque de memoria.
115
116     @returns Una referencia a si mismo.
117   */
118   DataBlock& operator += (const char c) noexcept(false) {
119     append(&c, sizeof(c));
120     return *this;
121   }
122
123   /**
124     Anhade el bloque de memoria recibido. Para poder usar este operador el bloque de memoria
125     destino debe tener activado el modo de copia profunda. Si la memoria reservada no es
126     suficiente reservara automaticamente la cantidad de memoria necesaria.
127
128     @param right Bloque de memoria a añadir a este bloque de memoria.
129
130     @returns Una referencia a si mismo.
131   */
132   DataBlock& operator += (const DataBlock& right) noexcept(false) {
133     if(this != &right)
134       append(right.a_buffer, right.a_size);
135
136     return *this;
137   }
138
139   /**
140     Anade la cadena recibida al bloque de memoria. Para poder usar este operador el bloque de
141     memoria destino debe tener activado el modo de copia profunda. Si la memoria reservada no es
142     suficiente  reservara automaticamente la cantidad de memoria necesaria.
143
144     \param str Cadena a añadir a este bloque de memoria.
145
146     @returns Una referencia a si mismo.
147   */
148   DataBlock& operator += (const std::string& str) noexcept(false) {
149     append(str.c_str(), str.length());
150     return *this;
151   }
152
153   /**
154      Devuelve la posicion i-esima del bloque de datos.
155      \param pos Posicion a la que acceder.
156      \return La posicion i-esima del bloque de datos.
157   */
158   const char operator [](const int pos) const noexcept(false);
159
160   /**
161      Devuelve la posicion i-esima del bloque de datos.
162      \param pos Posicion a la que acceder.
163      \return La posicion i-esima del bloque de datos.
164   */
165   char& operator [](const int pos) noexcept(false);
166
167   /**
168      Anade el bloque de memoria recibido. Para poder usar este operador el bloque de memoria
169      destino debe tener activado el modo de copia profunda. Si la memoria reservada no es
170      suficiente reservara automaticamente la cantidad de memoria necesaria.
171
172      \param data Direccion donde comienza el bloque de datos.
173      \param len Longitud del bloque de datos.
174   */
175   void append(const char* data, const int len) noexcept(false);
176
177   /**
178      Anade el bloque de memoria recibido. Para poder usar este operador el bloque de memoria
179      destino debe tener activado el modo de copia profunda. Si la memoria reservada no es
180      suficiente reservara automaticamente la cantidad de memoria necesaria.
181
182      \param other Bloque de memoria a añadir.
183   */
184   void append(const DataBlock& other) noexcept(false) { append(other.a_buffer, other.a_size); }
185
186   /**
187     Copia el contenido del bloque recibido como parámetro.
188     @param right Bloque de memoria del que copiar.
189     @returns Una referencia a si mismo.
190   */
191   void assign(const DataBlock& right) noexcept(false) { *this = right; }
192
193   /**
194     Copia o direcciona el contenido del bloque recibido como parámetro.
195     \param buffer Dirección de memoria a direcionar.
196     \param size Tamaño de la memoria.
197     @returns Una referencia a si mismo.
198   */
199   void assign(const char* buffer, const int size) noexcept(false);
200
201   /**
202     operador copia. El modo de copiar vendra definido por el modo copia con el que hayamos
203     iniciado la instancia destino.
204     @param right Bloque de memoria del que copiar.
205     @returns Una referencia a si mismo.
206   */
207   DataBlock& operator = (const DataBlock& right) noexcept(false);
208
209   /**
210     Operador de inicializacion. El bloque destino debera tener activado el sistema de
211     copia profunda.
212     @param c Caracter con el que vamos a inicializar el contenido del bloque.
213     @returns Una referencia a si mismo.
214   */
215   DataBlock& operator = (const char c) noexcept(false) { clear(); (*this) += c; return *this; }
216
217   /**
218     Operador de inicializacion. El bloque destino debera tener activado el sistema de
219     copia profunda.
220     @param str Cadena con el que vamos a inicializar el contenido del bloque.
221     @returns Una referencia a si mismo.
222   */
223   DataBlock& operator = (const std::string& str) noexcept(false) { clear(); (*this) += str; return *this; }
224
225   // Metodos
226   /**
227      Reserva el numero de bytes indicado por el parametro recibido. Si la cantidad de memoria preasignada es mayor
228      que la solicitada no se realiza ninguna llamada al sistema operativo.
229
230      @param nbytes Numero de bytes a reservar.
231   */
232   void allocate(const int nbytes) noexcept(false);
233
234   /**
235     La reserva de memoria actual pasa a ser memoria pre-asignada, asi libera el bloque
236     de memoria reservado hasta el momento, pero de forma que si posteriormente vuelve a
237     ser necesario puede reutilizarlo sin tener que volver a realizar una llamada al
238     sistema para obtener memoria dinamica.
239   */
240   void clear() noexcept(false) { a_size = 0; }
241
242   /**
243      Elimina del bloque de memoria unos determinados bytes.
244
245      @param pos Posicion del bloque donde empezar a eliminar.
246      @param nbytes Numero de bytes a descartar a partir de la posicion indicada.
247   */
248   void remove(const int pos, const int nbytes) noexcept(false);
249
250   /**
251      Elimina del bloque de memoria los n primeros bytes.
252      @param nbytes Numero de bytes a descartar a partir de la posicion indicada.
253   */
254   void remove(const int nbytes) noexcept(false);
255
256   /**
257    * Muestra el contenido de este buffer en forma de buffer hexadecimal vs bytes.
258    */
259   std::string asString(const int characterByLine = 24) const ;
260
261 protected:
262   /**
263      Inicializa el contenido de este bloque de datos. Si fue instancia con copia
264      profunda copia el contenido del buffer, en otro caso solo se queda con el
265      valor de la referencia de memoria a la que apunta.
266
267      @param buffer Bloque de memoria con el que inicializar el buffer de esta instancia.
268      @param size Numero de bytes del bloque de memoria recibido.
269   */
270   void initialize(const char* buffer, const int size) noexcept(false);
271
272   /**
273      Establece el espacio de memoria asociado a este bloque de datos.
274      \param buffer Nuevo buffer de datos asociado a este bloque.
275      \warning El DataBlock delega la gestion de la memoria a la clase heredada.
276   */
277   void setBuffer(const char* buffer) { a_buffer = (char*) buffer; }
278
279   /**
280      Establece el numero de bytes que tiene reservados este bloque de datos.
281      \param maxSize numero de bytes que tiene reservados este bloque de datos.
282      \warning El DataBlock delega la gestion de la memoria a la clase heredada.
283   */
284   void setMaxSize(const int maxSize) { a_maxSize = maxSize; }
285
286 private:
287   char* a_buffer;
288   int a_size;
289   bool a_deepCopy;
290   int a_maxSize;
291
292   void extend(const int nbytes) noexcept(false);
293 };
294
295 } //namespace anna
296
297 #endif
298