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 namespace firevision {
30 
31 /** @class FireVisionDataFileBlock <fvutils/fileformat/fvfile_block.h>
32  * FireVision File Format data block.
33  * This class describes one data block inside a FVFF file.
34  * @author Tim Niemueller
35  */
36 
37 /** @var void * FireVisionDataFileBlock::_data
38  * Pointer to the internal data segment.
39  * Never free or modify the pointer, but only deal with the data it points to.
40  */
41 /** @var size_t FireVisionDataFileBlock::_data_size
42  * Size of _data in bytes.
43  */
44 /** @var void * FireVisionDataFileBlock::_spec_header
45  * Pointer to the content specific block header.
46  * Never free or modify the pointer, but only deal with the data it points to.
47  */
48 
49 /** Constructor.
50  * @param type block type, content specific
51  * @param data_size size of the data segment
52  * @param spec_header content-specific header
53  * @param spec_header_size size of spec_header in bytes
54  */
56  size_t data_size,
57  void * spec_header,
58  size_t spec_header_size)
59 {
60  constructor(type, data_size, spec_header, spec_header_size);
61 }
62 
63 /** Constructor.
64  * @param type block type, content specific
65  * @param data_size size of the data segment
66  * @param spec_header_size a specific header of the given size is created internally
67  */
69  size_t data_size,
70  size_t spec_header_size)
71 {
72  constructor(type, data_size, NULL, spec_header_size);
73 }
74 
75 /** Constructor.
76  * Specific header is assumed to be unused.
77  * @param type block type, content specific
78  * @param data_size size of the data segment
79  */
80 FireVisionDataFileBlock::FireVisionDataFileBlock(unsigned int type, size_t data_size)
81 {
82  constructor(type, data_size, NULL, 0);
83 }
84 
85 /** Shallow copy constructor.
86  * This creates a shallow copy of the given block. "Shallow" means that the data is not
87  * copied but referenced. This instance is only valid as long as the original instance
88  * still exists.
89  * @param block block to copy
90  */
92 {
93  _data_size = block->_data_size;
94  spec_header_size_ = block->spec_header_size_;
95  block_size_ = block->block_size_;
96  block_memptr_ = block->block_memptr_;
97  block_header_ = (fvff_block_header_t *)block_memptr_;
98  _spec_header = (char *)block_memptr_ + sizeof(fvff_block_header_t);
99  _data = (char *)block_memptr_ + sizeof(fvff_block_header_t) + spec_header_size_;
100  block_owner_ = false;
101 }
102 
103 /** Internal constructor.
104  * @param type block type, content specific
105  * @param data_size size of the data segment
106  * @param spec_header content-specific header
107  * @param spec_header_size size of spec_header in bytes
108  */
109 void
110 FireVisionDataFileBlock::constructor(unsigned int type,
111  size_t data_size,
112  void * spec_header,
113  size_t spec_header_size)
114 {
116  spec_header_size_ = spec_header_size;
117  block_size_ = _data_size + sizeof(fvff_block_header_t) + spec_header_size;
118 
119  block_memptr_ = calloc(1, block_size_);
120  block_owner_ = true;
121  block_header_ = (fvff_block_header_t *)block_memptr_;
122  _spec_header = (char *)block_memptr_ + sizeof(fvff_block_header_t);
123  _data = (char *)block_memptr_ + sizeof(fvff_block_header_t) + spec_header_size;
124 
125  if ((spec_header != NULL) && (spec_header_size > 0)) {
126  memcpy((char *)block_memptr_ + sizeof(fvff_block_header_t), spec_header, spec_header_size);
127  }
128 
129  block_header_->type = type;
130  block_header_->size = _data_size;
131  block_header_->spec_head_size = spec_header_size;
132 }
133 
134 /** Set content-specific header.
135  * If necessary this re-creates internal buffers. To avoid this use the three-parameter
136  * ctor to have it account for the expected header size.
137  * @param spec_header content-specific header
138  * @param spec_header_size size of spec_header in bytes
139  */
140 void
141 FireVisionDataFileBlock::set_spec_header(void *spec_header, size_t spec_header_size)
142 {
143  if (spec_header_size != spec_header_size_) {
144  // we need to re-create the memory and copy old data
145  spec_header_size_ = spec_header_size;
146  block_size_ = _data_size + sizeof(fvff_block_header_t) + spec_header_size;
147 
148  void *newblock = calloc(1, block_size_);
149 
150  memcpy(newblock, block_memptr_, sizeof(fvff_block_header_t));
151  memcpy((char *)newblock + sizeof(fvff_block_header_t) + spec_header_size, _data, _data_size);
152 
153  free(block_memptr_);
154  block_memptr_ = newblock;
155  block_header_ = (fvff_block_header_t *)block_memptr_;
156  _spec_header = (char *)block_memptr_ + sizeof(fvff_block_header_t);
157  _data = (char *)block_memptr_ + sizeof(fvff_block_header_t) + spec_header_size;
158 
159  block_header_->spec_head_size = spec_header_size;
160  }
161 
162  if ((spec_header != NULL) && (spec_header_size > 0)) {
163  memcpy((char *)block_memptr_ + sizeof(fvff_block_header_t), spec_header, spec_header_size);
164  }
165 }
166 
167 /** Destructor. */
169 {
170  if (block_owner_) {
171  free(block_memptr_);
172  }
173 }
174 
175 /** Get block type.
176  * @return block type ID, content specific
177  */
178 unsigned int
180 {
181  return block_header_->type;
182 }
183 
184 /** Pointer to the whole block.
185  * @return pointer to whole block, including headers
186  */
187 void *
189 {
190  return block_memptr_;
191 }
192 
193 /** Size of blocks.
194  * @return size of blocks in bytes.
195  */
196 size_t
198 {
199  return block_size_;
200 }
201 
202 /** Get data pointer.
203  * @return pointer to the data segment of the block
204  */
205 void *
207 {
208  return _data;
209 }
210 
211 /** Size of data chunk.
212  * @return size of data in bytes.
213  */
214 size_t
216 {
217  return _data_size;
218 }
219 
220 } // end namespace firevision
FireVision File Format data block.
Definition: fvfile_block.h:34
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.
void * _spec_header
Pointer to the content specific block header.
Definition: fvfile_block.h:56
void * data_ptr() const
Get data pointer.
void * block_memptr() const
Pointer to the whole block.
unsigned int type() const
Get block type.
virtual ~FireVisionDataFileBlock()
Destructor.
void set_spec_header(void *spec_header, size_t spec_header_size)
Set content-specific header.
size_t _data_size
Size of _data in bytes.
Definition: fvfile_block.h:55
void * _data
Pointer to the internal data segment.
Definition: fvfile_block.h:54
size_t block_size() const
Size of blocks.
uint32_t type
The type of the block, content-specific.
Definition: fvff.h:75
uint32_t spec_head_size
the size of the following content specific block header
Definition: fvff.h:77
uint32_t size
size in bytes of this block, does not include any headers
Definition: fvff.h:76