Fawkes API  Fawkes Development Version
fvfile_block.cpp
1 
2 /***************************************************************************
3  * fvfile_block.cpp - FireVision file block
4  *
5  * Created: Fri Mar 28 11:52:45 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <fvutils/fileformat/fvfile_block.h>
25 
26 #include <cstdlib>
27 #include <cstring>
28 
29 
30 namespace firevision {
31 #if 0 /* just to make Emacs auto-indent happy */
32 }
33 #endif
34 
35 /** @class FireVisionDataFileBlock <fvutils/fileformat/fvfile_block.h>
36  * FireVision File Format data block.
37  * This class describes one data block inside a FVFF file.
38  * @author Tim Niemueller
39  */
40 
41 /** @var void * FireVisionDataFileBlock::_data
42  * Pointer to the internal data segment.
43  * Never free or modify the pointer, but only deal with the data it points to.
44  */
45 /** @var size_t FireVisionDataFileBlock::_data_size
46  * Size of _data in bytes.
47  */
48 /** @var void * FireVisionDataFileBlock::_spec_header
49  * Pointer to the content specific block header.
50  * Never free or modify the pointer, but only deal with the data it points to.
51  */
52 
53 /** Constructor.
54  * @param type block type, content specific
55  * @param data_size size of the data segment
56  * @param spec_header content-specific header
57  * @param spec_header_size size of spec_header in bytes
58  */
59 FireVisionDataFileBlock::FireVisionDataFileBlock(unsigned int type, size_t data_size,
60  void *spec_header, size_t spec_header_size)
61 {
62  constructor(type, data_size, spec_header, spec_header_size);
63 }
64 
65 
66 /** Constructor.
67  * @param type block type, content specific
68  * @param data_size size of the data segment
69  * @param spec_header_size a specific header of the given size is created internally
70  */
72  size_t spec_header_size)
73 {
74  constructor(type, data_size, NULL, spec_header_size);
75 }
76 
77 
78 /** Constructor.
79  * Specific header is assumed to be unused.
80  * @param type block type, content specific
81  * @param data_size size of the data segment
82  */
84 {
85  constructor(type, data_size, NULL, 0);
86 }
87 
88 
89 /** Shallow copy constructor.
90  * This creates a shallow copy of the given block. "Shallow" means that the data is not
91  * copied but referenced. This instance is only valid as long as the original instance
92  * still exists.
93  * @param block block to copy
94  */
96 {
97  _data_size = block->_data_size;
98  __spec_header_size = block->__spec_header_size;
99  __block_size = block->__block_size;
100  __block_memptr = block->__block_memptr;
101  __block_header = (fvff_block_header_t *)__block_memptr;
102  _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t);
103  _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + __spec_header_size;
104  __block_owner = false;
105 }
106 
107 
108 /** Internal constructor.
109  * @param type block type, content specific
110  * @param data_size size of the data segment
111  * @param spec_header content-specific header
112  * @param spec_header_size size of spec_header in bytes
113  */
114 void
115 FireVisionDataFileBlock::constructor(unsigned int type, size_t data_size,
116  void *spec_header, size_t spec_header_size)
117 {
119  __spec_header_size = spec_header_size;
120  __block_size = _data_size + sizeof(fvff_block_header_t) + spec_header_size;
121 
122  __block_memptr = calloc(1, __block_size);
123  __block_owner = true;
124  __block_header = (fvff_block_header_t *)__block_memptr;
125  _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t);
126  _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + spec_header_size;
127 
128  if ( (spec_header != NULL) && (spec_header_size > 0) ) {
129  memcpy((char *)__block_memptr + sizeof(fvff_block_header_t), spec_header, spec_header_size);
130  }
131 
132  __block_header->type = type;
133  __block_header->size = _data_size;
134  __block_header->spec_head_size = spec_header_size;
135 }
136 
137 
138 /** Set content-specific header.
139  * If necessary this re-creates internal buffers. To avoid this use the three-parameter
140  * ctor to have it account for the expected header size.
141  * @param spec_header content-specific header
142  * @param spec_header_size size of spec_header in bytes
143  */
144 void
145 FireVisionDataFileBlock::set_spec_header(void *spec_header, size_t spec_header_size)
146 {
147  if( spec_header_size != __spec_header_size ) {
148  // we need to re-create the memory and copy old data
149  __spec_header_size = spec_header_size;
150  __block_size = _data_size + sizeof(fvff_block_header_t) + spec_header_size;
151 
152  void *newblock = calloc(1, __block_size);
153 
154  memcpy(newblock, __block_memptr, sizeof(fvff_block_header_t));
155  memcpy((char *)newblock + sizeof(fvff_block_header_t) + spec_header_size, _data, _data_size);
156 
157  free(__block_memptr);
158  __block_memptr = newblock;
159  __block_header = (fvff_block_header_t *)__block_memptr;
160  _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t);
161  _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + spec_header_size;
162 
163  __block_header->spec_head_size = spec_header_size;
164  }
165 
166  if ( (spec_header != NULL) && (spec_header_size > 0) ) {
167  memcpy((char *)__block_memptr + sizeof(fvff_block_header_t), spec_header, spec_header_size);
168  }
169 }
170 
171 
172 /** Destructor. */
174 {
175  if ( __block_owner) {
176  free(__block_memptr);
177  }
178 }
179 
180 
181 /** Get block type.
182  * @return block type ID, content specific
183  */
184 unsigned int
186 {
187  return __block_header->type;
188 }
189 
190 
191 /** Pointer to the whole block.
192  * @return pointer to whole block, including headers
193  */
194 void *
196 {
197  return __block_memptr;
198 }
199 
200 
201 /** Size of blocks.
202  * @return size of blocks in bytes.
203  */
204 size_t
206 {
207  return __block_size;
208 }
209 
210 
211 /** Get data pointer.
212  * @return pointer to the data segment of the block
213  */
214 void *
216 {
217  return _data;
218 }
219 
220 
221 /** Size of data chunk.
222  * @return size of data in bytes.
223  */
224 size_t
226 {
227  return _data_size;
228 }
229 
230 } // end namespace firevision
unsigned int type() const
Get block type.
uint32_t size
size in bytes of this block, does not include any headers
Definition: fvff.h:78
void * _data
Pointer to the internal data segment.
Definition: fvfile_block.h:55
void * block_memptr() const
Pointer to the whole block.
FireVision File Format data block.
Definition: fvfile_block.h:35
void set_spec_header(void *spec_header, size_t spec_header_size)
Set content-specific header.
void * _spec_header
Pointer to the content specific block header.
Definition: fvfile_block.h:57
void * data_ptr() const
Get data pointer.
virtual ~FireVisionDataFileBlock()
Destructor.
uint32_t spec_head_size
the size of the following content specific block header
Definition: fvff.h:79
size_t block_size() const
Size of blocks.
size_t _data_size
Size of _data in bytes.
Definition: fvfile_block.h:56
uint32_t type
The type of the block, content-specific.
Definition: fvff.h:77
size_t data_size() const
Size of data chunk.
FireVisionDataFileBlock(unsigned int type, size_t data_size, void *spec_header, size_t spec_header_size)
Constructor.