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