Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * fvfile_block.cpp - FireVision file block 00004 * 00005 * Created: Fri Mar 28 11:52:45 2008 00006 * Copyright 2008 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <fvutils/fileformat/fvfile_block.h> 00025 00026 #include <cstdlib> 00027 #include <cstring> 00028 00029 00030 namespace firevision { 00031 #if 0 /* just to make Emacs auto-indent happy */ 00032 } 00033 #endif 00034 00035 /** @class FireVisionDataFileBlock <fvutils/fileformat/fvfile_block.h> 00036 * FireVision File Format data block. 00037 * This class describes one data block inside a FVFF file. 00038 * @author Tim Niemueller 00039 */ 00040 00041 /** @var void * FireVisionDataFileBlock::_data 00042 * Pointer to the internal data segment. 00043 * Never free or modify the pointer, but only deal with the data it points to. 00044 */ 00045 /** @var size_t FireVisionDataFileBlock::_data_size 00046 * Size of _data in bytes. 00047 */ 00048 /** @var void * FireVisionDataFileBlock::_spec_header 00049 * Pointer to the content specific block header. 00050 * Never free or modify the pointer, but only deal with the data it points to. 00051 */ 00052 00053 /** Constructor. 00054 * @param type block type, content specific 00055 * @param data_size size of the data segment 00056 * @param spec_header content-specific header 00057 * @param spec_header_size size of spec_header in bytes 00058 */ 00059 FireVisionDataFileBlock::FireVisionDataFileBlock(unsigned int type, size_t data_size, 00060 void *spec_header, size_t spec_header_size) 00061 { 00062 constructor(type, data_size, spec_header, spec_header_size); 00063 } 00064 00065 00066 /** Constructor. 00067 * @param type block type, content specific 00068 * @param data_size size of the data segment 00069 * @param spec_header_size a specific header of the given size is created internally 00070 */ 00071 FireVisionDataFileBlock::FireVisionDataFileBlock(unsigned int type, size_t data_size, 00072 size_t spec_header_size) 00073 { 00074 constructor(type, data_size, NULL, spec_header_size); 00075 } 00076 00077 00078 /** Constructor. 00079 * Specific header is assumed to be unused. 00080 * @param type block type, content specific 00081 * @param data_size size of the data segment 00082 */ 00083 FireVisionDataFileBlock::FireVisionDataFileBlock(unsigned int type, size_t data_size) 00084 { 00085 constructor(type, data_size, NULL, 0); 00086 } 00087 00088 00089 /** Shallow copy constructor. 00090 * This creates a shallow copy of the given block. "Shallow" means that the data is not 00091 * copied but referenced. This instance is only valid as long as the original instance 00092 * still exists. 00093 * @param block block to copy 00094 */ 00095 FireVisionDataFileBlock::FireVisionDataFileBlock(FireVisionDataFileBlock *block) 00096 { 00097 _data_size = block->_data_size; 00098 __spec_header_size = block->__spec_header_size; 00099 __block_size = block->__block_size; 00100 __block_memptr = block->__block_memptr; 00101 __block_header = (fvff_block_header_t *)__block_memptr; 00102 _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t); 00103 _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + __spec_header_size; 00104 __block_owner = false; 00105 } 00106 00107 00108 /** Internal constructor. 00109 * @param type block type, content specific 00110 * @param data_size size of the data segment 00111 * @param spec_header content-specific header 00112 * @param spec_header_size size of spec_header in bytes 00113 */ 00114 void 00115 FireVisionDataFileBlock::constructor(unsigned int type, size_t data_size, 00116 void *spec_header, size_t spec_header_size) 00117 { 00118 _data_size = data_size; 00119 __spec_header_size = spec_header_size; 00120 __block_size = _data_size + sizeof(fvff_block_header_t) + spec_header_size; 00121 00122 __block_memptr = calloc(1, __block_size); 00123 __block_owner = true; 00124 __block_header = (fvff_block_header_t *)__block_memptr; 00125 _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t); 00126 _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + spec_header_size; 00127 00128 if ( (spec_header != NULL) && (spec_header_size > 0) ) { 00129 memcpy((char *)__block_memptr + sizeof(fvff_block_header_t), spec_header, spec_header_size); 00130 } 00131 00132 __block_header->type = type; 00133 __block_header->size = _data_size; 00134 __block_header->spec_head_size = spec_header_size; 00135 } 00136 00137 00138 /** Set content-specific header. 00139 * If necessary this re-creates internal buffers. To avoid this use the three-parameter 00140 * ctor to have it account for the expected header size. 00141 * @param spec_header content-specific header 00142 * @param spec_header_size size of spec_header in bytes 00143 */ 00144 void 00145 FireVisionDataFileBlock::set_spec_header(void *spec_header, size_t spec_header_size) 00146 { 00147 if( spec_header_size != __spec_header_size ) { 00148 // we need to re-create the memory and copy old data 00149 __spec_header_size = spec_header_size; 00150 __block_size = _data_size + sizeof(fvff_block_header_t) + spec_header_size; 00151 00152 void *newblock = calloc(1, __block_size); 00153 00154 memcpy(newblock, __block_memptr, sizeof(fvff_block_header_t)); 00155 memcpy((char *)newblock + sizeof(fvff_block_header_t) + spec_header_size, _data, _data_size); 00156 00157 free(__block_memptr); 00158 __block_memptr = newblock; 00159 __block_header = (fvff_block_header_t *)__block_memptr; 00160 _spec_header = (char *)__block_memptr + sizeof(fvff_block_header_t); 00161 _data = (char *)__block_memptr + sizeof(fvff_block_header_t) + spec_header_size; 00162 00163 __block_header->spec_head_size = spec_header_size; 00164 } 00165 00166 if ( (spec_header != NULL) && (spec_header_size > 0) ) { 00167 memcpy((char *)__block_memptr + sizeof(fvff_block_header_t), spec_header, spec_header_size); 00168 } 00169 } 00170 00171 00172 /** Destructor. */ 00173 FireVisionDataFileBlock::~FireVisionDataFileBlock() 00174 { 00175 if ( __block_owner) { 00176 free(__block_memptr); 00177 } 00178 } 00179 00180 00181 /** Get block type. 00182 * @return block type ID, content specific 00183 */ 00184 unsigned int 00185 FireVisionDataFileBlock::type() const 00186 { 00187 return __block_header->type; 00188 } 00189 00190 00191 /** Pointer to the whole block. 00192 * @return pointer to whole block, including headers 00193 */ 00194 void * 00195 FireVisionDataFileBlock::block_memptr() const 00196 { 00197 return __block_memptr; 00198 } 00199 00200 00201 /** Size of blocks. 00202 * @return size of blocks in bytes. 00203 */ 00204 size_t 00205 FireVisionDataFileBlock::block_size() const 00206 { 00207 return __block_size; 00208 } 00209 00210 00211 /** Get data pointer. 00212 * @return pointer to the data segment of the block 00213 */ 00214 void * 00215 FireVisionDataFileBlock::data_ptr() const 00216 { 00217 return _data; 00218 } 00219 00220 00221 /** Size of data chunk. 00222 * @return size of data in bytes. 00223 */ 00224 size_t 00225 FireVisionDataFileBlock::data_size() const 00226 { 00227 return _data_size; 00228 } 00229 00230 } // end namespace firevision