Tesseract 3.01
/data/source/tesseract-ocr/ccutil/genericvector.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines