Tesseract 3.01
|
00001 00002 // File: genericvector.h 00003 // Description: Generic vector class 00004 // Author: Daria Antonova 00005 // Created: Mon Jun 23 11:26:43 PDT 2008 00006 // 00007 // (C) Copyright 2007, Google Inc. 00008 // Licensed under the Apache License, Version 2.0 (the "License"); 00009 // you may not use this file except in compliance with the License. 00010 // You may obtain a copy of the License at 00011 // http://www.apache.org/licenses/LICENSE-2.0 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // 00019 // 00020 #ifndef TESSERACT_CCUTIL_GENERICVECTOR_H_ 00021 #define TESSERACT_CCUTIL_GENERICVECTOR_H_ 00022 00023 #include <stdio.h> 00024 #include <stdlib.h> 00025 00026 #include "tesscallback.h" 00027 #include "errcode.h" 00028 #include "helpers.h" 00029 #include "ndminx.h" 00030 00031 // Use PointerVector<T> below in preference to GenericVector<T*>, as that 00032 // provides automatic deletion of pointers, [De]Serialize that works, and 00033 // sort that works. 00034 template <typename T> 00035 class GenericVector { 00036 public: 00037 GenericVector() { this->init(kDefaultVectorSize); } 00038 explicit GenericVector(int size) { this->init(size); } 00039 00040 // Copy 00041 GenericVector(const GenericVector& other) { 00042 this->init(other.size()); 00043 this->operator+=(other); 00044 } 00045 GenericVector<T> &operator+=(const GenericVector& other); 00046 GenericVector<T> &operator=(const GenericVector& other); 00047 00048 virtual ~GenericVector(); 00049 00050 // Reserve some memory. 00051 void reserve(int size); 00052 // Double the size of the internal array. 00053 void double_the_size(); 00054 00055 // Resizes to size and sets all values to t. 00056 void init_to_size(int size, T t); 00057 00058 // Return the size used. 00059 int size() const { 00060 return size_used_; 00061 } 00062 00063 int length() const { 00064 return size_used_; 00065 } 00066 00067 // Return true if empty. 00068 bool empty() const { 00069 return size_used_ == 0; 00070 } 00071 00072 // Return the object from an index. 00073 T &get(int index) const; 00074 T &operator[](int index) const; 00075 00076 // Return the index of the T object. 00077 // This method NEEDS a compare_callback to be passed to 00078 // set_compare_callback. 00079 int get_index(T object) const; 00080 00081 // Return true if T is in the array 00082 bool contains(T object) const; 00083 00084 // Return true if the index is valid 00085 T contains_index(int index) const; 00086 00087 // Push an element in the end of the array 00088 int push_back(T object); 00089 void operator+=(T t); 00090 00091 // Push an element in the front of the array 00092 // Note: This function is O(n) 00093 int push_front(T object); 00094 00095 // Set the value at the given index 00096 void set(T t, int index); 00097 00098 // Insert t at the given index, push other elements to the right. 00099 void insert(T t, int index); 00100 00101 // Removes an element at the given index and 00102 // shifts the remaining elements to the left. 00103 virtual void remove(int index); 00104 00105 // Truncates the array to the given size by removing the end. 00106 // If the current size is less, the array is not expanded. 00107 virtual void truncate(int size) { 00108 if (size < size_used_) 00109 size_used_ = size; 00110 } 00111 00112 // Add a callback to be called to delete the elements when the array took 00113 // their ownership. 00114 void set_clear_callback(TessCallback1<T>* cb); 00115 00116 // Add a callback to be called to compare the elements when needed (contains, 00117 // get_id, ...) 00118 void set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb); 00119 00120 // Clear the array, calling the clear callback function if any. 00121 // All the owned callbacks are also deleted. 00122 // If you don't want the callbacks to be deleted, before calling clear, set 00123 // the callback to NULL. 00124 virtual void clear(); 00125 00126 // Delete objects pointed to by data_[i] 00127 void delete_data_pointers(); 00128 00129 // This method clears the current object, then, does a shallow copy of 00130 // its argument, and finally invalidate its argument. 00131 // Callbacks are moved to the current object; 00132 void move(GenericVector<T>* from); 00133 00134 // Read/Write the array to a file. This does _NOT_ read/write the callbacks. 00135 // The callback given must be permanent since they will be called more than 00136 // once. The given callback will be deleted at the end. 00137 // If the callbacks are NULL, then the data is simply read/written using 00138 // fread (and swapping)/fwrite. 00139 // Returns false on error or if the callback returns false. 00140 // DEPRECATED. Use [De]Serialize[Classes] instead. 00141 bool write(FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const; 00142 bool read(FILE* f, TessResultCallback3<bool, FILE*, T*, bool>* cb, bool swap); 00143 // Writes a vector of simple types to the given file. Assumes that bitwise 00144 // read/write of T will work. Returns false in case of error. 00145 virtual bool Serialize(FILE* fp) const; 00146 // Reads a vector of simple types from the given file. Assumes that bitwise 00147 // read/write will work with ReverseN according to sizeof(T). 00148 // Returns false in case of error. 00149 // If swap is true, assumes a big/little-endian swap is needed. 00150 virtual bool DeSerialize(bool swap, FILE* fp); 00151 // Writes a vector of classes to the given file. Assumes the existence of 00152 // bool T::Serialize(FILE* fp) const that returns false in case of error. 00153 // Returns false in case of error. 00154 bool SerializeClasses(FILE* fp) const; 00155 // Reads a vector of classes from the given file. Assumes the existence of 00156 // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of 00157 // error. Also needs T::T() and T::T(constT&), as init_to_size is used in 00158 // this function. Returns false in case of error. 00159 // If swap is true, assumes a big/little-endian swap is needed. 00160 bool DeSerializeClasses(bool swap, FILE* fp); 00161 00162 // Allocates a new array of double the current_size, copies over the 00163 // information from data to the new location, deletes data and returns 00164 // the pointed to the new larger array. 00165 // This function uses memcpy to copy the data, instead of invoking 00166 // operator=() for each element like double_the_size() does. 00167 static T *double_the_size_memcpy(int current_size, T *data) { 00168 T *data_new = new T[current_size * 2]; 00169 memcpy(data_new, data, sizeof(T) * current_size); 00170 delete[] data; 00171 return data_new; 00172 } 00173 00174 // Sorts the members of this vector using the less than comparator (cmp_lt), 00175 // which compares the values. Useful for GenericVectors to primitive types. 00176 // Will not work so great for pointers (unless you just want to sort some 00177 // pointers). You need to provide a specialization to sort_cmp to use 00178 // your type. 00179 void sort(); 00180 00181 // Sort the array into the order defined by the qsort function comparator. 00182 // The comparator function is as defined by qsort, ie. it receives pointers 00183 // to two Ts and returns negative if the first element is to appear earlier 00184 // in the result and positive if it is to appear later, with 0 for equal. 00185 void sort(int (*comparator)(const void*, const void*)) { 00186 qsort(data_, size_used_, sizeof(*data_), comparator); 00187 } 00188 00189 // Searches the array (assuming sorted in ascending order, using sort()) for 00190 // an element equal to target and returns true if it is present. 00191 // Use binary_search to get the index of target, or its nearest candidate. 00192 bool bool_binary_search(const T& target) const { 00193 int index = binary_search(target); 00194 if (index >= size_used_) 00195 return false; 00196 return data_[index] == target; 00197 } 00198 // Searches the array (assuming sorted in ascending order, using sort()) for 00199 // an element equal to target and returns the index of the best candidate. 00200 // The return value is the largest index i such that data_[i] <= target or 0. 00201 int binary_search(const T& target) const { 00202 int bottom = 0; 00203 int top = size_used_; 00204 do { 00205 int middle = (bottom + top) / 2; 00206 if (data_[middle] > target) 00207 top = middle; 00208 else 00209 bottom = middle; 00210 } 00211 while (top - bottom > 1); 00212 return bottom; 00213 } 00214 00215 // Compact the vector by deleting elements using operator!= on basic types. 00216 // The vector must be sorted. 00217 void compact_sorted() { 00218 if (size_used_ == 0) 00219 return; 00220 00221 // First element is in no matter what, hence the i = 1. 00222 int last_write = 0; 00223 for (int i = 1; i < size_used_; ++i) { 00224 // Finds next unique item and writes it. 00225 if (data_[last_write] != data_[i]) 00226 data_[++last_write] = data_[i]; 00227 } 00228 // last_write is the index of a valid data cell, so add 1. 00229 size_used_ = last_write + 1; 00230 } 00231 00232 // Compact the vector by deleting elements for which delete_cb returns 00233 // true. delete_cb is a permanent callback and will be deleted. 00234 void compact(TessResultCallback1<bool, int>* delete_cb) { 00235 int new_size = 0; 00236 int old_index = 0; 00237 // Until the callback returns true, the elements stay the same. 00238 while (old_index < size_used_ && !delete_cb->Run(old_index++)) 00239 ++new_size; 00240 // Now just copy anything else that gets false from delete_cb. 00241 for (; old_index < size_used_; ++old_index) { 00242 if (!delete_cb->Run(old_index)) { 00243 data_[new_size++] = data_[old_index]; 00244 } 00245 } 00246 size_used_ = new_size; 00247 delete delete_cb; 00248 } 00249 00250 T dot_product(const GenericVector<T>& other) const { 00251 T result = static_cast<T>(0); 00252 for (int i = MIN(size_used_, other.size_used_) - 1; i >= 0; --i) 00253 result += data_[i] * other.data_[i]; 00254 return result; 00255 } 00256 00257 protected: 00258 00259 // Init the object, allocating size memory. 00260 void init(int size); 00261 00262 // We are assuming that the object generally placed in thie 00263 // vector are small enough that for efficiency it makes sence 00264 // to start with a larger initial size. 00265 static const int kDefaultVectorSize = 4; 00266 inT32 size_used_; 00267 inT32 size_reserved_; 00268 T* data_; 00269 TessCallback1<T>* clear_cb_; 00270 // Mutable because Run method is not const 00271 mutable TessResultCallback2<bool, T const &, T const &>* compare_cb_; 00272 }; 00273 00274 namespace tesseract { 00275 00276 template <typename T> 00277 bool cmp_eq(T const & t1, T const & t2) { 00278 return t1 == t2; 00279 } 00280 00281 // Used by sort() 00282 // return < 0 if t1 < t2 00283 // return 0 if t1 == t2 00284 // return > 0 if t1 > t2 00285 template <typename T> 00286 int sort_cmp(const void* t1, const void* t2) { 00287 const T* a = static_cast<const T *> (t1); 00288 const T* b = static_cast<const T *> (t2); 00289 if (*a < *b) { 00290 return -1; 00291 } else if (*b < *a) { 00292 return 1; 00293 } else { 00294 return 0; 00295 } 00296 } 00297 00298 // Used by PointerVector::sort() 00299 // return < 0 if t1 < t2 00300 // return 0 if t1 == t2 00301 // return > 0 if t1 > t2 00302 template <typename T> 00303 int sort_ptr_cmp(const void* t1, const void* t2) { 00304 const T* a = *reinterpret_cast<T * const *>(t1); 00305 const T* b = *reinterpret_cast<T * const *>(t2); 00306 if (*a < *b) { 00307 return -1; 00308 } else if (*b < *a) { 00309 return 1; 00310 } else { 00311 return 0; 00312 } 00313 } 00314 00315 // Subclass for a vector of pointers. Use in preference to GenericVector<T*> 00316 // as it provides automatic deletion and correct serialization, with the 00317 // corollary that all copy operations are deep copies of the pointed-to objects. 00318 template<typename T> 00319 class PointerVector : public GenericVector<T*> { 00320 public: 00321 PointerVector() : GenericVector<T*>() { } 00322 explicit PointerVector(int size) : GenericVector<T*>(size) { } 00323 virtual ~PointerVector() { 00324 // Clear must be called here, even though it is called again by the base, 00325 // as the base will call the wrong clear. 00326 clear(); 00327 } 00328 // Copy must be deep, as the pointers will be automatically deleted on 00329 // destruction. 00330 PointerVector(const PointerVector& other) { 00331 init(other.size()); 00332 this->operator+=(other); 00333 } 00334 PointerVector<T>& operator+=(const PointerVector& other) { 00335 reserve(this->size_used_ + other.size_used_); 00336 for (int i = 0; i < other.size(); ++i) { 00337 push_back(new T(*other.data_[i])); 00338 } 00339 return *this; 00340 } 00341 00342 PointerVector<T>& operator=(const PointerVector& other) { 00343 this->truncate(0); 00344 this->operator+=(other); 00345 return *this; 00346 } 00347 00348 // Removes an element at the given index and 00349 // shifts the remaining elements to the left. 00350 virtual void remove(int index) { 00351 delete GenericVector<T*>::data_[index]; 00352 GenericVector<T*>::remove(index); 00353 } 00354 00355 // Truncates the array to the given size by removing the end. 00356 // If the current size is less, the array is not expanded. 00357 virtual void truncate(int size) { 00358 for (int i = size; i < GenericVector<T*>::size_used_; ++i) 00359 delete GenericVector<T*>::data_[i]; 00360 GenericVector<T*>::truncate(size); 00361 } 00362 00363 // Clear the array, calling the clear callback function if any. 00364 // All the owned callbacks are also deleted. 00365 // If you don't want the callbacks to be deleted, before calling clear, set 00366 // the callback to NULL. 00367 virtual void clear() { 00368 GenericVector<T*>::delete_data_pointers(); 00369 GenericVector<T*>::clear(); 00370 } 00371 00372 // Writes a vector of simple types to the given file. Assumes that bitwise 00373 // read/write of T will work. Returns false in case of error. 00374 virtual bool Serialize(FILE* fp) const { 00375 inT32 used = GenericVector<T*>::size_used_; 00376 if (fwrite(&used, sizeof(used), 1, fp) != 1) return false; 00377 for (int i = 0; i < used; ++i) { 00378 inT8 non_null = GenericVector<T*>::data_[i] != NULL; 00379 if (fwrite(&non_null, sizeof(non_null), 1, fp) != 1) return false; 00380 if (non_null && !GenericVector<T*>::data_[i]->Serialize(fp)) return false; 00381 } 00382 return true; 00383 } 00384 // Reads a vector of simple types from the given file. Assumes that bitwise 00385 // read/write will work with ReverseN according to sizeof(T). 00386 // Also needs T::T(), as new T is used in this function. 00387 // Returns false in case of error. 00388 // If swap is true, assumes a big/little-endian swap is needed. 00389 virtual bool DeSerialize(bool swap, FILE* fp) { 00390 inT32 reserved; 00391 if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false; 00392 if (swap) Reverse32(&reserved); 00393 GenericVector<T*>::reserve(reserved); 00394 for (int i = 0; i < reserved; ++i) { 00395 inT8 non_null; 00396 if (fread(&non_null, sizeof(non_null), 1, fp) != 1) return false; 00397 T* item = NULL; 00398 if (non_null) { 00399 item = new T; 00400 if (!item->DeSerialize(swap, fp)) return false; 00401 } 00402 push_back(item); 00403 } 00404 return true; 00405 } 00406 00407 // Sorts the items pointed to by the members of this vector using 00408 // t::operator<(). 00409 void sort() { 00410 sort(&sort_ptr_cmp<T>); 00411 } 00412 }; 00413 00414 } // namespace tesseract 00415 00416 // A useful vector that uses operator== to do comparisons. 00417 template <typename T> 00418 class GenericVectorEqEq : public GenericVector<T> { 00419 public: 00420 GenericVectorEqEq() { 00421 GenericVector<T>::set_compare_callback( 00422 NewPermanentTessCallback(tesseract::cmp_eq<T>)); 00423 } 00424 GenericVectorEqEq(int size) : GenericVector<T>(size) { 00425 GenericVector<T>::set_compare_callback( 00426 NewPermanentTessCallback(tesseract::cmp_eq<T>)); 00427 } 00428 }; 00429 00430 template <typename T> 00431 void GenericVector<T>::init(int size) { 00432 size_used_ = 0; 00433 size_reserved_ = 0; 00434 data_ = 0; 00435 clear_cb_ = 0; 00436 compare_cb_ = 0; 00437 reserve(size); 00438 } 00439 00440 template <typename T> 00441 GenericVector<T>::~GenericVector() { 00442 clear(); 00443 } 00444 00445 // Reserve some memory. If the internal array contains elements, they are 00446 // copied. 00447 template <typename T> 00448 void GenericVector<T>::reserve(int size) { 00449 if (size_reserved_ >= size || size <= 0) 00450 return; 00451 T* new_array = new T[size]; 00452 for (int i = 0; i < size_used_; ++i) 00453 new_array[i] = data_[i]; 00454 if (data_ != NULL) delete[] data_; 00455 data_ = new_array; 00456 size_reserved_ = size; 00457 } 00458 00459 template <typename T> 00460 void GenericVector<T>::double_the_size() { 00461 if (size_reserved_ == 0) { 00462 reserve(kDefaultVectorSize); 00463 } 00464 else { 00465 reserve(2 * size_reserved_); 00466 } 00467 } 00468 00469 // Resizes to size and sets all values to t. 00470 template <typename T> 00471 void GenericVector<T>::init_to_size(int size, T t) { 00472 reserve(size); 00473 size_used_ = size; 00474 for (int i = 0; i < size; ++i) 00475 data_[i] = t; 00476 } 00477 00478 00479 // Return the object from an index. 00480 template <typename T> 00481 T &GenericVector<T>::get(int index) const { 00482 ASSERT_HOST(index >= 0 && index < size_used_); 00483 return data_[index]; 00484 } 00485 00486 template <typename T> 00487 T &GenericVector<T>::operator[](int index) const { 00488 return data_[index]; 00489 } 00490 00491 // Return the object from an index. 00492 template <typename T> 00493 void GenericVector<T>::set(T t, int index) { 00494 ASSERT_HOST(index >= 0 && index < size_used_); 00495 data_[index] = t; 00496 } 00497 00498 // Shifts the rest of the elements to the right to make 00499 // space for the new elements and inserts the given element 00500 // at the specified index. 00501 template <typename T> 00502 void GenericVector<T>::insert(T t, int index) { 00503 ASSERT_HOST(index >= 0 && index < size_used_); 00504 if (size_reserved_ == size_used_) 00505 double_the_size(); 00506 for (int i = size_used_; i > index; --i) { 00507 data_[i] = data_[i-1]; 00508 } 00509 data_[index] = t; 00510 size_used_++; 00511 } 00512 00513 // Removes an element at the given index and 00514 // shifts the remaining elements to the left. 00515 template <typename T> 00516 void GenericVector<T>::remove(int index) { 00517 ASSERT_HOST(index >= 0 && index < size_used_); 00518 for (int i = index; i < size_used_ - 1; ++i) { 00519 data_[i] = data_[i+1]; 00520 } 00521 size_used_--; 00522 } 00523 00524 // Return true if the index is valindex 00525 template <typename T> 00526 T GenericVector<T>::contains_index(int index) const { 00527 return index >= 0 && index < size_used_; 00528 } 00529 00530 // Return the index of the T object. 00531 template <typename T> 00532 int GenericVector<T>::get_index(T object) const { 00533 for (int i = 0; i < size_used_; ++i) { 00534 ASSERT_HOST(compare_cb_ != NULL); 00535 if (compare_cb_->Run(object, data_[i])) 00536 return i; 00537 } 00538 return -1; 00539 } 00540 00541 // Return true if T is in the array 00542 template <typename T> 00543 bool GenericVector<T>::contains(T object) const { 00544 return get_index(object) != -1; 00545 } 00546 00547 // Add an element in the array 00548 template <typename T> 00549 int GenericVector<T>::push_back(T object) { 00550 int index = 0; 00551 if (size_used_ == size_reserved_) 00552 double_the_size(); 00553 index = size_used_++; 00554 data_[index] = object; 00555 return index; 00556 } 00557 00558 // Add an element in the array (front) 00559 template <typename T> 00560 int GenericVector<T>::push_front(T object) { 00561 if (size_used_ == size_reserved_) 00562 double_the_size(); 00563 for (int i = size_used_; i > 0; --i) 00564 data_[i] = data_[i-1]; 00565 data_[0] = object; 00566 ++size_used_; 00567 return 0; 00568 } 00569 00570 template <typename T> 00571 void GenericVector<T>::operator+=(T t) { 00572 push_back(t); 00573 } 00574 00575 template <typename T> 00576 GenericVector<T> &GenericVector<T>::operator+=(const GenericVector& other) { 00577 this->reserve(size_used_ + other.size_used_); 00578 for (int i = 0; i < other.size(); ++i) { 00579 this->operator+=(other.data_[i]); 00580 } 00581 return *this; 00582 } 00583 00584 template <typename T> 00585 GenericVector<T> &GenericVector<T>::operator=(const GenericVector& other) { 00586 this->truncate(0); 00587 this->operator+=(other); 00588 return *this; 00589 } 00590 00591 // Add a callback to be called to delete the elements when the array took 00592 // their ownership. 00593 template <typename T> 00594 void GenericVector<T>::set_clear_callback(TessCallback1<T>* cb) { 00595 clear_cb_ = cb; 00596 } 00597 00598 // Add a callback to be called to delete the elements when the array took 00599 // their ownership. 00600 template <typename T> 00601 void GenericVector<T>::set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb) { 00602 compare_cb_ = cb; 00603 } 00604 00605 // Clear the array, calling the callback function if any. 00606 template <typename T> 00607 void GenericVector<T>::clear() { 00608 if (size_reserved_ > 0) { 00609 if (clear_cb_ != NULL) 00610 for (int i = 0; i < size_used_; ++i) 00611 clear_cb_->Run(data_[i]); 00612 delete[] data_; 00613 data_ = NULL; 00614 size_used_ = 0; 00615 size_reserved_ = 0; 00616 } 00617 if (clear_cb_ != NULL) { 00618 delete clear_cb_; 00619 clear_cb_ = NULL; 00620 } 00621 if (compare_cb_ != NULL) { 00622 delete compare_cb_; 00623 compare_cb_ = NULL; 00624 } 00625 } 00626 00627 template <typename T> 00628 void GenericVector<T>::delete_data_pointers() { 00629 for (int i = 0; i < size_used_; ++i) 00630 if (data_[i]) { 00631 delete data_[i]; 00632 } 00633 } 00634 00635 00636 template <typename T> 00637 bool GenericVector<T>::write( 00638 FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const { 00639 if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) return false; 00640 if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) return false; 00641 if (cb != NULL) { 00642 for (int i = 0; i < size_used_; ++i) { 00643 if (!cb->Run(f, data_[i])) { 00644 delete cb; 00645 return false; 00646 } 00647 } 00648 delete cb; 00649 } else { 00650 if (fwrite(data_, sizeof(T), size_used_, f) != size_used_) return false; 00651 } 00652 return true; 00653 } 00654 00655 template <typename T> 00656 bool GenericVector<T>::read(FILE* f, 00657 TessResultCallback3<bool, FILE*, T*, bool>* cb, 00658 bool swap) { 00659 inT32 reserved; 00660 if (fread(&reserved, sizeof(reserved), 1, f) != 1) return false; 00661 if (swap) Reverse32(&reserved); 00662 reserve(reserved); 00663 if (fread(&size_used_, sizeof(size_used_), 1, f) != 1) return false; 00664 if (swap) Reverse32(&size_used_); 00665 if (cb != NULL) { 00666 for (int i = 0; i < size_used_; ++i) { 00667 if (!cb->Run(f, data_ + i, swap)) { 00668 delete cb; 00669 return false; 00670 } 00671 } 00672 delete cb; 00673 } else { 00674 if (fread(data_, sizeof(T), size_used_, f) != size_used_) return false; 00675 if (swap) { 00676 for (int i = 0; i < size_used_; ++i) 00677 ReverseN(&data_[i], sizeof(T)); 00678 } 00679 } 00680 return true; 00681 } 00682 00683 // Writes a vector of simple types to the given file. Assumes that bitwise 00684 // read/write of T will work. Returns false in case of error. 00685 template <typename T> 00686 bool GenericVector<T>::Serialize(FILE* fp) const { 00687 if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false; 00688 if (fwrite(data_, sizeof(*data_), size_used_, fp) != size_used_) return false; 00689 return true; 00690 } 00691 00692 // Reads a vector of simple types from the given file. Assumes that bitwise 00693 // read/write will work with ReverseN according to sizeof(T). 00694 // Returns false in case of error. 00695 // If swap is true, assumes a big/little-endian swap is needed. 00696 template <typename T> 00697 bool GenericVector<T>::DeSerialize(bool swap, FILE* fp) { 00698 inT32 reserved; 00699 if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false; 00700 if (swap) Reverse32(&reserved); 00701 reserve(reserved); 00702 size_used_ = reserved; 00703 if (fread(data_, sizeof(T), size_used_, fp) != size_used_) return false; 00704 if (swap) { 00705 for (int i = 0; i < size_used_; ++i) 00706 ReverseN(&data_[i], sizeof(data_[i])); 00707 } 00708 return true; 00709 } 00710 00711 // Writes a vector of classes to the given file. Assumes the existence of 00712 // bool T::Serialize(FILE* fp) const that returns false in case of error. 00713 // Returns false in case of error. 00714 template <typename T> 00715 bool GenericVector<T>::SerializeClasses(FILE* fp) const { 00716 if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false; 00717 for (int i = 0; i < size_used_; ++i) { 00718 if (!data_[i].Serialize(fp)) return false; 00719 } 00720 return true; 00721 } 00722 00723 // Reads a vector of classes from the given file. Assumes the existence of 00724 // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of 00725 // error. Alse needs T::T() and T::T(constT&), as init_to_size is used in 00726 // this function. Returns false in case of error. 00727 // If swap is true, assumes a big/little-endian swap is needed. 00728 template <typename T> 00729 bool GenericVector<T>::DeSerializeClasses(bool swap, FILE* fp) { 00730 uinT32 reserved; 00731 if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false; 00732 if (swap) Reverse32(&reserved); 00733 T empty; 00734 init_to_size(reserved, empty); 00735 for (int i = 0; i < reserved; ++i) { 00736 if (!data_[i].DeSerialize(swap, fp)) return false; 00737 } 00738 return true; 00739 } 00740 00741 // This method clear the current object, then, does a shallow copy of 00742 // its argument, and finally invalindate its argument. 00743 template <typename T> 00744 void GenericVector<T>::move(GenericVector<T>* from) { 00745 this->clear(); 00746 this->data_ = from->data_; 00747 this->size_reserved_ = from->size_reserved_; 00748 this->size_used_ = from->size_used_; 00749 this->compare_cb_ = from->compare_cb_; 00750 this->clear_cb_ = from->clear_cb_; 00751 from->data_ = NULL; 00752 from->clear_cb_ = NULL; 00753 from->compare_cb_ = NULL; 00754 from->size_used_ = 0; 00755 from->size_reserved_ = 0; 00756 } 00757 00758 template <typename T> 00759 void GenericVector<T>::sort() { 00760 sort(&tesseract::sort_cmp<T>); 00761 } 00762 00763 #endif // TESSERACT_CCUTIL_GENERICVECTOR_H_