00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _Data_Block_
00023 #define _Data_Block_
00024
00025 #include "endian.hh"
00026
00027 #include <iostream>
00028 #include <vector>
00029
00037 namespace PIRL
00038 {
00039
00040
00041
00137 class Data_Block
00138 {
00139 public:
00140
00141
00142
00144 typedef unsigned int Index;
00145
00147 typedef std::vector<Index> Value_List;
00148
00150 typedef void (*Copier)
00151 (
00152 unsigned char* destination,
00153 int destination_amount,
00154 const unsigned char* source,
00155 int source_amount
00156 );
00157
00158
00159
00160
00162 static const char* const
00163 ID;
00164
00173 enum Data_Order
00174 {
00175 MSB,
00176 LSB
00177 };
00178
00180 static const Index
00181 NO_INDEX;
00182
00191 enum Array_Index_Counts
00192 {
00193 ELEMENT_INDEX,
00194 INDEX_COUNT
00195 };
00197 #define INDEX_COUNTS INDEX_COUNT
00198
00207 enum Array_Offset_Counts
00208 {
00209 ELEMENT_OFFSET,
00210 OFFSET_COUNT
00211 };
00213 #define OFFSET_COUNTS OFFSET_COUNT
00214
00220 #ifndef DATA_BLOCK_LIMITS_CHECK
00221 #define DATA_BLOCK_LIMITS_CHECK false
00222 #endif
00223
00224
00225
00226
00235 Data_Block ();
00236
00269 Data_Block
00270 (
00271 void* const data,
00272 const Index* offsets,
00273 Index total_elements = 0,
00274 const Index* array_counts = NULL,
00275 bool native_order = true
00276 );
00277
00299 Data_Block
00300 (
00301 void* const data,
00302 const Value_List& offsets,
00303 const Value_List& array_counts,
00304 bool native_order = true
00305 );
00306
00322 Data_Block
00323 (
00324 void* const data,
00325 const Value_List& offsets,
00326 bool native_order = true
00327 );
00328
00368 Data_Block
00369 (
00370 void* const data,
00371 const Index* offsets,
00372 Index total_elements,
00373 const Index* array_counts,
00374 Data_Order data_order
00375 );
00376
00397 Data_Block
00398 (
00399 void* const data,
00400 const Value_List& offsets,
00401 const Value_List& array_counts,
00402 Data_Order data_order
00403 );
00404
00424 Data_Block
00425 (
00426 void* const data,
00427 const Index* offsets,
00428 Index total_elements,
00429 Data_Order data_order
00430 );
00431
00451 Data_Block
00452 (
00453 void* const data,
00454 const Index* offsets,
00455 Data_Order data_order
00456 );
00457
00471 Data_Block
00472 (
00473 void* const data,
00474 const Value_List& offsets,
00475 Data_Order data_order
00476 );
00477
00503 Data_Block
00504 (
00505 void* const data,
00506 const Index* offsets,
00507 const Index indexed_counts[][2],
00508 Data_Order data_order
00509 );
00510
00511
00512
00513
00523 Data_Block (const Data_Block& data_block);
00524
00535 Data_Block& operator= (const Data_Block& data_block);
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 virtual ~Data_Block ();
00549
00550
00551
00552
00553
00554
00555
00560 bool native () const
00561 {return Native;}
00562
00569 Data_Block& native (bool native_order);
00570
00576 static Data_Order native_order ()
00577 {return host_is_high_endian () ? MSB : LSB;}
00578
00584 Data_Order data_order () const;
00585
00592 Data_Block& data_order (Data_Order order);
00593
00594
00595
00596
00601 unsigned char* data () const
00602 {return Block;}
00603
00612 virtual Data_Block& data (void* const block);
00613
00623 Index size () const
00624 {return (Counts.size () ? Offsets[Counts.size ()] : 0);}
00625
00626
00627
00628
00634 Value_List element_offsets_list () const
00635 {return Offsets;}
00636
00650 Index* element_offsets ()
00651 {return &Offsets[0];}
00652
00674 bool element_offsets (const Value_List& offsets);
00675
00722 bool element_offsets (const Index* offsets, Index total_elements = NO_INDEX);
00723
00741 bool element_sizes (const Value_List& sizes);
00742
00765 bool element_sizes (const Index* sizes, Index total_elements = NO_INDEX);
00766
00773 Index offset_of (Index element) const;
00774
00796 bool offset_of (Index element, Index offset);
00797
00818 bool insert_element (Index offset, Index size, Index array_count = 1);
00819
00828 Data_Block& delete_element (Index element);
00829
00840 Data_Block& shift_offsets (int amount);
00841
00842
00843
00844
00850 Index elements () const
00851 {return Counts.size ();}
00852
00859 Index size_of (Index element) const;
00860
00878 bool size_of (Index element, Index size);
00879
00891 Index value_size_of (Index element) const;
00892
00906 Data_Block& value_size_of (Index element, Index size);
00907
00914 Index index_of (Index offset) const;
00915
00916
00917
00918
00923 Value_List array_counts_list () const
00924 {return Counts;}
00925
00938 Index* array_counts ()
00939 {return &Counts[0];}
00940
00953 Data_Block& array_counts (const Value_List& counts, Index begin = 0);
00954
00976 Data_Block& array_counts
00977 (const Index* counts, Index begin = 0, Index end = NO_INDEX);
00978
01000 Data_Block& array_indexed_counts
01001 (const Index indexed_counts[][2], Index total_counts = NO_INDEX);
01002
01028 Data_Block& array_offset_counts
01029 (const Index offset_counts[][2], Index total_counts = NO_INDEX);
01030
01040 Index count_of (Index element) const;
01041
01054 Data_Block& count_of (Index element, Index count);
01055
01072 bool reset_counts (bool unconditional = true,
01073 Index begin = 0, Index end = NO_INDEX);
01074
01075
01076
01077
01078
01079
01080
01084 Copier
01085 Get;
01086
01090 Copier
01091 Put;
01092
01119 template<typename T, bool limits_check>
01120 const Data_Block&
01121 get (T& value, const Index element, const Index index = 0) const
01122 {
01123 if (Block)
01124 {
01125 if (limits_check)
01126 limits_checker (element, index, true, false);
01127 unsigned int
01128 amount = (Offsets[element + 1] - Offsets[element]) / Counts[element];
01129 Get
01130 (
01131 reinterpret_cast<unsigned char*>(&value),
01132 sizeof (T),
01133 Block + Offsets[element] + (amount * index),
01134 amount
01135 );
01136 }
01137 return *this;
01138 }
01139
01154 template<typename T>
01155 const Data_Block&
01156 get (T& value, const Index element, const Index index = 0) const
01157 {return get<T, DATA_BLOCK_LIMITS_CHECK> (value, element, index);}
01158
01171 template<typename T, bool limits_check>
01172 T get (const Index element, const Index index = 0) const
01173 {
01174 T value;
01175 get<T, limits_check> (value, element, index);
01176 return value;
01177 }
01178
01192 template<typename T>
01193 T get (const Index element, const Index index = 0) const
01194 {return get<T, DATA_BLOCK_LIMITS_CHECK> (element, index);}
01195
01196
01224 template<typename T, bool limits_check>
01225 Data_Block& put (T& value, const Index element, const Index index = 0)
01226 {
01227 if (Block)
01228 {
01229 if (limits_check)
01230 limits_checker (element, index, false, false);
01231 unsigned int
01232 amount = (Offsets[element + 1] - Offsets[element]) / Counts[element];
01233 Put
01234 (
01235 Block + Offsets[element] + (amount * index),
01236 amount,
01237 reinterpret_cast<const unsigned char*>(&value),
01238 sizeof (T)
01239 );
01240 }
01241 return *this;
01242 }
01243
01258 template<typename T>
01259 Data_Block& put (T& value, const Index element, const Index index = 0)
01260 {return put<T, DATA_BLOCK_LIMITS_CHECK> (value, element, index);}
01261
01282 template<typename T, bool limits_check>
01283 const Data_Block& get (T* array, const Index element, Index count = 0) const
01284 {
01285 if (Block)
01286 {
01287 if (limits_check)
01288 limits_checker (element, count, true, true);
01289 unsigned int
01290 amount = (Offsets[element + 1] - Offsets[element]) / Counts[element];
01291 if (! count || count > Counts[element])
01292 count = Counts[element];
01293 unsigned char*
01294 data = Block + Offsets[element];
01295
01296
01297 while (count--)
01298 {
01299 Get (reinterpret_cast<unsigned char*>(array), sizeof (T), data, amount);
01300 data += amount;
01301 array++;
01302 }
01303 }
01304 return *this;
01305 }
01306
01324 template<typename T>
01325 const Data_Block& get (T* array, const Index element, Index count = 0) const
01326 {return get<T, DATA_BLOCK_LIMITS_CHECK> (array, element, count);}
01327
01328
01349 template<typename T, bool limits_check>
01350 Data_Block& put (T* array, const Index element, Index count = 0)
01351 {
01352 if (Block)
01353 {
01354 if (limits_check)
01355 limits_checker (element, count, false, true);
01356 unsigned int
01357 amount = (Offsets[element + 1] - Offsets[element]) / Counts[element];
01358 if (! count || count > Counts[element])
01359 count = Counts[element];
01360 unsigned char*
01361 data = Block + Offsets[element];
01362
01363
01364 while (count--)
01365 {
01366 Put (data, amount,
01367 reinterpret_cast<const unsigned char*>(array), sizeof (T));
01368 data += amount;
01369 array++;
01370 }
01371 }
01372 return *this;
01373 }
01374
01392 template<typename T>
01393 Data_Block& put (T* array, const Index element, Index count = 0)
01394 {return put<T, DATA_BLOCK_LIMITS_CHECK> (array, element, count);}
01395
01401 std::istream& input (std::istream& stream);
01402
01408 std::ostream& output (std::ostream& stream) const;
01409
01410
01411
01412
01413
01414
01415 std::ostream& print (std::ostream& stream = std::cout) const;
01416
01417
01418
01419
01432 static Value_List& sizes_to_offsets (Value_List& sizes);
01433
01456 static Index* sizes_to_offsets (Index* sizes, Index total_elements = NO_INDEX);
01457
01472 static Value_List& offsets_to_sizes (Value_List& offsets);
01473
01496 static Index* offsets_to_sizes
01497 (Index* offsets, Index total_elements = NO_INDEX);
01498
01499
01500
01501
01502 protected:
01503
01505 static void
01506 get_forwards
01507 (
01508 unsigned char* host,
01509 int host_amount,
01510 const unsigned char* data,
01511 int data_amount
01512 );
01513
01515 static void
01516 get_backwards
01517 (
01518 unsigned char* host,
01519 int host_amount,
01520 const unsigned char* data,
01521 int data_amount
01522 );
01523
01525 static void
01526 put_forwards
01527 (
01528 unsigned char* data,
01529 int data_amount,
01530 const unsigned char* host,
01531 int host_amount
01532 );
01533
01535 static void
01536 put_backwards
01537 (
01538 unsigned char* data,
01539 int data_amount,
01540 const unsigned char* host,
01541 int host_amount
01542 );
01543
01545 void limits_checker
01546 (
01547 const Index element,
01548 const Index index,
01549 bool getter,
01550 bool array
01551 ) const;
01552
01553
01554 private:
01555
01557 unsigned char*
01558 Block;
01559
01567 Value_List
01568 Offsets;
01569
01576 Value_List
01577 Counts;
01578
01580 bool
01581 Native;
01582
01583 };
01584
01585
01586
01587
01595 std::ostream& operator<<
01596 (std::ostream& stream, const Data_Block& data_block);
01597
01605 std::istream& operator>>=
01606 (std::istream& stream, Data_Block& data_block);
01607
01615 std::ostream& operator<<=
01616 (std::ostream& stream, const Data_Block& data_block);
01617
01618 }
01619 #endif