Coverage Report

Created: 2025-12-31 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tesseract/src/ccutil/genericvector.h
Line
Count
Source
1
///////////////////////////////////////////////////////////////////////
2
// File:        genericvector.h
3
// Description: Generic vector class
4
// Author:      Daria Antonova
5
//
6
// (C) Copyright 2007, Google Inc.
7
// Licensed under the Apache License, Version 2.0 (the "License");
8
// you may not use this file except in compliance with the License.
9
// You may obtain a copy of the License at
10
// http://www.apache.org/licenses/LICENSE-2.0
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
///////////////////////////////////////////////////////////////////////
18
//
19
#ifndef TESSERACT_CCUTIL_GENERICVECTOR_H_
20
#define TESSERACT_CCUTIL_GENERICVECTOR_H_
21
22
#include "helpers.h"
23
#include "serialis.h"
24
25
#include <algorithm>
26
#include <cassert>
27
#include <climits> // for LONG_MAX
28
#include <cstdint> // for uint32_t
29
#include <cstdio>
30
#include <cstdlib>
31
#include <functional> // for std::function
32
33
namespace tesseract {
34
35
// Use PointerVector<T> below in preference to GenericVector<T*>, as that
36
// provides automatic deletion of pointers, [De]Serialize that works, and
37
// sort that works.
38
template <typename T>
39
class GenericVector {
40
public:
41
887k
  GenericVector() {
42
887k
    init(kDefaultVectorSize);
43
887k
  }
tesseract::GenericVector<tesseract::WERD_RES*>::GenericVector()
Line
Count
Source
41
887k
  GenericVector() {
42
887k
    init(kDefaultVectorSize);
43
887k
  }
tesseract::GenericVector<tesseract::FontInfo>::GenericVector()
Line
Count
Source
41
8
  GenericVector() {
42
8
    init(kDefaultVectorSize);
43
8
  }
tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::GenericVector()
Line
Count
Source
41
4
  GenericVector() {
42
4
    init(kDefaultVectorSize);
43
4
  }
Unexecuted instantiation: tesseract::GenericVector<int>::GenericVector()
44
45
  // Copy
46
766k
  GenericVector(const GenericVector &other) {
47
766k
    this->init(other.size());
48
766k
    this->operator+=(other);
49
766k
  }
50
  GenericVector<T> &operator+=(const GenericVector &other);
51
  GenericVector<T> &operator=(const GenericVector &other);
52
53
  ~GenericVector();
54
55
  // Reserve some memory.
56
  void reserve(int size);
57
  // Double the size of the internal array.
58
  void double_the_size();
59
60
  // Resizes to size and sets all values to t.
61
  void init_to_size(int size, const T &t);
62
  void resize(int size, const T &t);
63
  // Resizes to size without any initialization.
64
0
  void resize_no_init(int size) {
65
0
    reserve(size);
66
0
    size_used_ = size;
67
0
  }
68
69
  // Return the size used.
70
95.6M
  unsigned size() const {
71
95.6M
    return size_used_;
72
95.6M
  }
tesseract::GenericVector<tesseract::FontInfo>::size() const
Line
Count
Source
70
88.5M
  unsigned size() const {
71
88.5M
    return size_used_;
72
88.5M
  }
Unexecuted instantiation: tesseract::GenericVector<char>::size() const
tesseract::GenericVector<tesseract::WERD_RES*>::size() const
Line
Count
Source
70
7.11M
  unsigned size() const {
71
7.11M
    return size_used_;
72
7.11M
  }
Unexecuted instantiation: tesseract::GenericVector<int>::size() const
73
  // Workaround to avoid g++ -Wsign-compare warnings.
74
0
  size_t unsigned_size() const {
75
0
    static_assert(sizeof(size_used_) <= sizeof(size_t), "Wow! sizeof(size_t) < sizeof(int32_t)!!");
76
0
    assert(0 <= size_used_);
77
0
    return static_cast<size_t>(size_used_);
78
0
  }
Unexecuted instantiation: tesseract::GenericVector<tesseract::FontInfo>::unsigned_size() const
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::unsigned_size() const
79
  int size_reserved() const {
80
    return size_reserved_;
81
  }
82
83
  // Return true if empty.
84
674k
  bool empty() const {
85
674k
    return size_used_ == 0;
86
674k
  }
87
88
  // Return the object from an index.
89
669M
  T &at(int index) const {
90
669M
    assert(index >= 0 && index < size_used_);
91
669M
    return data_[index];
92
669M
  }
tesseract::GenericVector<tesseract::FontInfo>::at(int) const
Line
Count
Source
89
67.1M
  T &at(int index) const {
90
    assert(index >= 0 && index < size_used_);
91
67.1M
    return data_[index];
92
67.1M
  }
tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::at(int) const
Line
Count
Source
89
602M
  T &at(int index) const {
90
    assert(index >= 0 && index < size_used_);
91
602M
    return data_[index];
92
602M
  }
Unexecuted instantiation: tesseract::GenericVector<tesseract::WERD_RES*>::at(int) const
93
94
  T &back() const;
95
  T &operator[](int index) const;
96
  // Returns the last object and removes it.
97
  T pop_back();
98
99
  // Return the index of the T object.
100
  int get_index(const T &object) const;
101
102
  // Push an element in the end of the array
103
  int push_back(T object);
104
  void operator+=(const T &t);
105
106
  // Set the value at the given index
107
  void set(const T &t, int index);
108
109
  // Insert t at the given index, push other elements to the right.
110
  void insert(const T &t, int index);
111
112
  // Removes an element at the given index and
113
  // shifts the remaining elements to the left.
114
  void remove(int index);
115
116
  // Truncates the array to the given size by removing the end.
117
  // If the current size is less, the array is not expanded.
118
347k
  void truncate(int size) {
119
347k
    if (size < size_used_) {
120
0
      size_used_ = size;
121
0
    }
122
347k
  }
tesseract::GenericVector<tesseract::WERD_RES*>::truncate(int)
Line
Count
Source
118
347k
  void truncate(int size) {
119
347k
    if (size < size_used_) {
120
0
      size_used_ = size;
121
0
    }
122
347k
  }
Unexecuted instantiation: tesseract::GenericVector<tesseract::FontInfo>::truncate(int)
123
124
  // Add a callback to be called to delete the elements when the array took
125
  // their ownership.
126
4
  void set_clear_callback(const std::function<void(T)> &cb) {
127
4
    clear_cb_ = cb;
128
4
  }
129
130
  // Clear the array, calling the clear callback function if any.
131
  // All the owned callbacks are also deleted.
132
  // If you don't want the callbacks to be deleted, before calling clear, set
133
  // the callback to nullptr.
134
  void clear();
135
136
  // Delete objects pointed to by data_[i]
137
  void delete_data_pointers();
138
139
  // This method clears the current object, then, does a shallow copy of
140
  // its argument, and finally invalidates its argument.
141
  // Callbacks are moved to the current object;
142
  void move(GenericVector<T> *from);
143
144
  // Read/Write the array to a file. This does _NOT_ read/write the callbacks.
145
  // The callback given must be permanent since they will be called more than
146
  // once. The given callback will be deleted at the end.
147
  // If the callbacks are nullptr, then the data is simply read/written using
148
  // fread (and swapping)/fwrite.
149
  // Returns false on error or if the callback returns false.
150
  // DEPRECATED. Use [De]Serialize[Classes] instead.
151
  bool write(FILE *f, const std::function<bool(FILE *, const T &)> &cb) const;
152
  bool read(TFile *f, const std::function<bool(TFile *, T *)> &cb);
153
  // Writes a vector of simple types to the given file. Assumes that bitwise
154
  // read/write of T will work. Returns false in case of error.
155
  // TODO(rays) Change all callers to use TFile and remove deprecated methods.
156
  bool Serialize(FILE *fp) const;
157
  bool Serialize(TFile *fp) const;
158
  // Reads a vector of simple types from the given file. Assumes that bitwise
159
  // read/write will work with ReverseN according to sizeof(T).
160
  // Returns false in case of error.
161
  // If swap is true, assumes a big/little-endian swap is needed.
162
  // TFile is assumed to know about swapping.
163
  bool DeSerialize(bool swap, FILE *fp);
164
  bool DeSerialize(TFile *fp);
165
  // Writes a vector of classes to the given file. Assumes the existence of
166
  // bool T::Serialize(FILE* fp) const that returns false in case of error.
167
  // Returns false in case of error.
168
  bool SerializeClasses(FILE *fp) const;
169
  // Reads a vector of classes from the given file. Assumes the existence of
170
  // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
171
  // error. Also needs T::T() and T::T(constT&), as init_to_size is used in
172
  // this function. Returns false in case of error.
173
  // If swap is true, assumes a big/little-endian swap is needed.
174
  bool DeSerializeClasses(TFile *fp);
175
176
  // Reverses the elements of the vector.
177
  void reverse() {
178
    for (int i = 0; i < size_used_ / 2; ++i) {
179
      std::swap(data_[i], data_[size_used_ - 1 - i]);
180
    }
181
  }
182
183
  // Sorts the members of this vector using the less than comparator (cmp_lt),
184
  // which compares the values. Useful for GenericVectors to primitive types.
185
  // Will not work so great for pointers (unless you just want to sort some
186
  // pointers). You need to provide a specialization to sort_cmp to use
187
  // your type.
188
  void sort();
189
190
  // Sort the array into the order defined by the qsort function comparator.
191
  // The comparator function is as defined by qsort, ie. it receives pointers
192
  // to two Ts and returns negative if the first element is to appear earlier
193
  // in the result and positive if it is to appear later, with 0 for equal.
194
  void sort(int (*comparator)(const void *, const void *)) {
195
    qsort(data_, size_used_, sizeof(*data_), comparator);
196
  }
197
198
  // Swaps the elements with the given indices.
199
  void swap(int index1, int index2) {
200
    if (index1 != index2) {
201
      T tmp = data_[index1];
202
      data_[index1] = data_[index2];
203
      data_[index2] = tmp;
204
    }
205
  }
206
  // Returns true if all elements of *this are within the given range.
207
  // Only uses operator<
208
  /*bool WithinBounds(const T& rangemin, const T& rangemax) const {
209
  for (int i = 0; i < size_used_; ++i) {
210
    if (data_[i] < rangemin || rangemax < data_[i]) {
211
      return false;
212
    }
213
  }
214
  return true;
215
}*/
216
217
protected:
218
  // Init the object, allocating size memory.
219
  void init(int size);
220
221
  // We are assuming that the object generally placed in the
222
  // vector are small enough that for efficiency it makes sense
223
  // to start with a larger initial size.
224
  static const int kDefaultVectorSize = 4;
225
  int32_t size_used_{};
226
  int32_t size_reserved_{};
227
  T *data_;
228
  std::function<void(T)> clear_cb_;
229
};
230
231
// The default FileReader loads the whole file into the vector of char,
232
// returning false on error.
233
0
inline bool LoadDataFromFile(const char *filename, GenericVector<char> *data) {
234
0
  bool result = false;
235
0
  FILE *fp = fopen(filename, "rb");
236
0
  if (fp != nullptr) {
237
0
    fseek(fp, 0, SEEK_END);
238
0
    auto size = std::ftell(fp);
239
0
    fseek(fp, 0, SEEK_SET);
240
0
    // Trying to open a directory on Linux sets size to LONG_MAX. Catch it here.
241
0
    if (size > 0 && size < LONG_MAX) {
242
0
      // reserve an extra byte in case caller wants to append a '\0' character
243
0
      data->reserve(size + 1);
244
0
      data->resize_no_init(size);
245
0
      result = static_cast<long>(fread(&(*data)[0], 1, size, fp)) == size;
246
0
    }
247
0
    fclose(fp);
248
0
  }
249
0
  return result;
250
0
}
251
252
// The default FileWriter writes the vector of char to the filename file,
253
// returning false on error.
254
0
inline bool SaveDataToFile(const GenericVector<char> &data, const char *filename) {
255
0
  FILE *fp = fopen(filename, "wb");
256
0
  if (fp == nullptr) {
257
0
    return false;
258
0
  }
259
0
  bool result = fwrite(&data[0], 1, data.size(), fp) == data.size();
260
0
  fclose(fp);
261
0
  return result;
262
0
}
263
264
// Used by sort()
265
// return < 0 if t1 < t2
266
// return 0 if t1 == t2
267
// return > 0 if t1 > t2
268
template <typename T>
269
int sort_cmp(const void *t1, const void *t2) {
270
  const T *a = static_cast<const T *>(t1);
271
  const T *b = static_cast<const T *>(t2);
272
  if (*a < *b) {
273
    return -1;
274
  }
275
  if (*b < *a) {
276
    return 1;
277
  }
278
  return 0;
279
}
280
281
// Used by PointerVector::sort()
282
// return < 0 if t1 < t2
283
// return 0 if t1 == t2
284
// return > 0 if t1 > t2
285
template <typename T>
286
int sort_ptr_cmp(const void *t1, const void *t2) {
287
  const T *a = *static_cast<T *const *>(t1);
288
  const T *b = *static_cast<T *const *>(t2);
289
  if (*a < *b) {
290
    return -1;
291
  }
292
  if (*b < *a) {
293
    return 1;
294
  }
295
  return 0;
296
}
297
298
// Subclass for a vector of pointers. Use in preference to GenericVector<T*>
299
// as it provides automatic deletion and correct serialization, with the
300
// corollary that all copy operations are deep copies of the pointed-to objects.
301
template <typename T>
302
class PointerVector : public GenericVector<T *> {
303
public:
304
887k
  PointerVector() : GenericVector<T *>() {}
305
  explicit PointerVector(int size) : GenericVector<T *>(size) {}
306
1.65M
  ~PointerVector() {
307
    // Clear must be called here, even though it is called again by the base,
308
    // as the base will call the wrong clear.
309
1.65M
    clear();
310
1.65M
  }
311
  // Copy must be deep, as the pointers will be automatically deleted on
312
  // destruction.
313
766k
  PointerVector(const PointerVector &other) : GenericVector<T *>(other) {
314
766k
    this->init(other.size());
315
766k
    this->operator+=(other);
316
766k
  }
317
766k
  PointerVector<T> &operator+=(const PointerVector &other) {
318
766k
    this->reserve(this->size_used_ + other.size_used_);
319
766k
    for (unsigned i = 0; i < other.size(); ++i) {
320
0
      this->push_back(new T(*other.data_[i]));
321
0
    }
322
766k
    return *this;
323
766k
  }
324
325
  PointerVector<T> &operator=(const PointerVector &other) {
326
    if (&other != this) {
327
      this->truncate(0);
328
      this->operator+=(other);
329
    }
330
    return *this;
331
  }
332
333
  // Removes an element at the given index and
334
  // shifts the remaining elements to the left.
335
  void remove(int index) {
336
    delete GenericVector<T *>::data_[index];
337
    GenericVector<T *>::remove(index);
338
  }
339
340
  // Truncates the array to the given size by removing the end.
341
  // If the current size is less, the array is not expanded.
342
347k
  void truncate(int size) {
343
347k
    for (int i = size; i < GenericVector<T *>::size_used_; ++i) {
344
0
      delete GenericVector<T *>::data_[i];
345
0
    }
346
347k
    GenericVector<T *>::truncate(size);
347
347k
  }
348
349
  // Clear the array, calling the clear callback function if any.
350
  // All the owned callbacks are also deleted.
351
  // If you don't want the callbacks to be deleted, before calling clear, set
352
  // the callback to nullptr.
353
1.97M
  void clear() {
354
1.97M
    GenericVector<T *>::delete_data_pointers();
355
1.97M
    GenericVector<T *>::clear();
356
1.97M
  }
357
358
  // Writes a vector of (pointers to) classes to the given file. Assumes the
359
  // existence of bool T::Serialize(FILE*) const that returns false in case of
360
  // error. There is no Serialize for simple types, as you would have a
361
  // normal GenericVector of those.
362
  // Returns false in case of error.
363
  bool Serialize(FILE *fp) const {
364
    int32_t used = GenericVector<T *>::size_used_;
365
    if (fwrite(&used, sizeof(used), 1, fp) != 1) {
366
      return false;
367
    }
368
    for (int i = 0; i < used; ++i) {
369
      int8_t non_null = GenericVector<T *>::data_[i] != nullptr;
370
      if (fwrite(&non_null, sizeof(non_null), 1, fp) != 1) {
371
        return false;
372
      }
373
      if (non_null && !GenericVector<T *>::data_[i]->Serialize(fp)) {
374
        return false;
375
      }
376
    }
377
    return true;
378
  }
379
  bool Serialize(TFile *fp) const {
380
    int32_t used = GenericVector<T *>::size_used_;
381
    if (fp->FWrite(&used, sizeof(used), 1) != 1) {
382
      return false;
383
    }
384
    for (int i = 0; i < used; ++i) {
385
      int8_t non_null = GenericVector<T *>::data_[i] != nullptr;
386
      if (fp->FWrite(&non_null, sizeof(non_null), 1) != 1) {
387
        return false;
388
      }
389
      if (non_null && !GenericVector<T *>::data_[i]->Serialize(fp)) {
390
        return false;
391
      }
392
    }
393
    return true;
394
  }
395
  // Reads a vector of (pointers to) classes to the given file. Assumes the
396
  // existence of bool T::DeSerialize(bool, Tfile*) const that returns false in
397
  // case of error. There is no Serialize for simple types, as you would have a
398
  // normal GenericVector of those.
399
  // If swap is true, assumes a big/little-endian swap is needed.
400
  // Also needs T::T(), as new T is used in this function.
401
  // Returns false in case of error.
402
  bool DeSerialize(bool swap, FILE *fp) {
403
    uint32_t reserved;
404
    if (fread(&reserved, sizeof(reserved), 1, fp) != 1) {
405
      return false;
406
    }
407
    if (swap) {
408
      Reverse32(&reserved);
409
    }
410
    // Arbitrarily limit the number of elements to protect against bad data.
411
    assert(reserved <= UINT16_MAX);
412
    if (reserved > UINT16_MAX) {
413
      return false;
414
    }
415
    GenericVector<T *>::reserve(reserved);
416
    truncate(0);
417
    for (uint32_t i = 0; i < reserved; ++i) {
418
      int8_t non_null;
419
      if (fread(&non_null, sizeof(non_null), 1, fp) != 1) {
420
        return false;
421
      }
422
      T *item = nullptr;
423
      if (non_null != 0) {
424
        item = new T;
425
        if (!item->DeSerialize(swap, fp)) {
426
          delete item;
427
          return false;
428
        }
429
        this->push_back(item);
430
      } else {
431
        // Null elements should keep their place in the vector.
432
        this->push_back(nullptr);
433
      }
434
    }
435
    return true;
436
  }
437
438
  // Sorts the items pointed to by the members of this vector using
439
  // t::operator<().
440
  void sort() {
441
    this->GenericVector<T *>::sort(&sort_ptr_cmp<T>);
442
  }
443
};
444
445
template <typename T>
446
2.42M
void GenericVector<T>::init(int size) {
447
2.42M
  size_used_ = 0;
448
2.42M
  if (size <= 0) {
449
1.53M
    data_ = nullptr;
450
1.53M
    size_reserved_ = 0;
451
1.53M
  } else {
452
887k
    if (size < kDefaultVectorSize) {
453
0
      size = kDefaultVectorSize;
454
0
    }
455
887k
    data_ = new T[size];
456
887k
    size_reserved_ = size;
457
887k
  }
458
2.42M
  clear_cb_ = nullptr;
459
2.42M
}
tesseract::GenericVector<tesseract::WERD_RES*>::init(int)
Line
Count
Source
446
2.42M
void GenericVector<T>::init(int size) {
447
2.42M
  size_used_ = 0;
448
2.42M
  if (size <= 0) {
449
1.53M
    data_ = nullptr;
450
1.53M
    size_reserved_ = 0;
451
1.53M
  } else {
452
887k
    if (size < kDefaultVectorSize) {
453
0
      size = kDefaultVectorSize;
454
0
    }
455
887k
    data_ = new T[size];
456
887k
    size_reserved_ = size;
457
887k
  }
458
2.42M
  clear_cb_ = nullptr;
459
2.42M
}
tesseract::GenericVector<tesseract::FontInfo>::init(int)
Line
Count
Source
446
8
void GenericVector<T>::init(int size) {
447
8
  size_used_ = 0;
448
8
  if (size <= 0) {
449
0
    data_ = nullptr;
450
0
    size_reserved_ = 0;
451
8
  } else {
452
8
    if (size < kDefaultVectorSize) {
453
0
      size = kDefaultVectorSize;
454
0
    }
455
8
    data_ = new T[size];
456
8
    size_reserved_ = size;
457
8
  }
458
8
  clear_cb_ = nullptr;
459
8
}
tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::init(int)
Line
Count
Source
446
4
void GenericVector<T>::init(int size) {
447
4
  size_used_ = 0;
448
4
  if (size <= 0) {
449
0
    data_ = nullptr;
450
0
    size_reserved_ = 0;
451
4
  } else {
452
4
    if (size < kDefaultVectorSize) {
453
0
      size = kDefaultVectorSize;
454
0
    }
455
4
    data_ = new T[size];
456
4
    size_reserved_ = size;
457
4
  }
458
4
  clear_cb_ = nullptr;
459
4
}
Unexecuted instantiation: tesseract::GenericVector<int>::init(int)
460
461
template <typename T>
462
1.65M
GenericVector<T>::~GenericVector() {
463
1.65M
  clear();
464
1.65M
}
tesseract::GenericVector<tesseract::WERD_RES*>::~GenericVector()
Line
Count
Source
462
1.65M
GenericVector<T>::~GenericVector() {
463
1.65M
  clear();
464
1.65M
}
tesseract::GenericVector<tesseract::FontInfo>::~GenericVector()
Line
Count
Source
462
4
GenericVector<T>::~GenericVector() {
463
4
  clear();
464
4
}
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::~GenericVector()
Unexecuted instantiation: tesseract::GenericVector<int>::~GenericVector()
465
466
// Reserve some memory. If the internal array contains elements, they are
467
// copied.
468
template <typename T>
469
1.95M
void GenericVector<T>::reserve(int size) {
470
1.95M
  if (size_reserved_ >= size || size <= 0) {
471
1.53M
    return;
472
1.53M
  }
473
419k
  if (size < kDefaultVectorSize) {
474
0
    size = kDefaultVectorSize;
475
0
  }
476
419k
  T *new_array = new T[size];
477
432k
  for (int i = 0; i < size_used_; ++i) {
478
12.8k
    new_array[i] = data_[i];
479
12.8k
  }
480
419k
  delete[] data_;
481
419k
  data_ = new_array;
482
419k
  size_reserved_ = size;
483
419k
}
Unexecuted instantiation: tesseract::GenericVector<char>::reserve(int)
tesseract::GenericVector<tesseract::WERD_RES*>::reserve(int)
Line
Count
Source
469
1.95M
void GenericVector<T>::reserve(int size) {
470
1.95M
  if (size_reserved_ >= size || size <= 0) {
471
1.53M
    return;
472
1.53M
  }
473
419k
  if (size < kDefaultVectorSize) {
474
0
    size = kDefaultVectorSize;
475
0
  }
476
419k
  T *new_array = new T[size];
477
430k
  for (int i = 0; i < size_used_; ++i) {
478
10.7k
    new_array[i] = data_[i];
479
10.7k
  }
480
419k
  delete[] data_;
481
419k
  data_ = new_array;
482
419k
  size_reserved_ = size;
483
419k
}
tesseract::GenericVector<tesseract::FontInfo>::reserve(int)
Line
Count
Source
469
36
void GenericVector<T>::reserve(int size) {
470
36
  if (size_reserved_ >= size || size <= 0) {
471
4
    return;
472
4
  }
473
32
  if (size < kDefaultVectorSize) {
474
0
    size = kDefaultVectorSize;
475
0
  }
476
32
  T *new_array = new T[size];
477
2.06k
  for (int i = 0; i < size_used_; ++i) {
478
2.03k
    new_array[i] = data_[i];
479
2.03k
  }
480
32
  delete[] data_;
481
32
  data_ = new_array;
482
32
  size_reserved_ = size;
483
32
}
tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::reserve(int)
Line
Count
Source
469
4
void GenericVector<T>::reserve(int size) {
470
4
  if (size_reserved_ >= size || size <= 0) {
471
0
    return;
472
0
  }
473
4
  if (size < kDefaultVectorSize) {
474
0
    size = kDefaultVectorSize;
475
0
  }
476
4
  T *new_array = new T[size];
477
4
  for (int i = 0; i < size_used_; ++i) {
478
0
    new_array[i] = data_[i];
479
0
  }
480
4
  delete[] data_;
481
4
  data_ = new_array;
482
4
  size_reserved_ = size;
483
4
}
484
485
template <typename T>
486
419k
void GenericVector<T>::double_the_size() {
487
419k
  if (size_reserved_ == 0) {
488
417k
    reserve(kDefaultVectorSize);
489
417k
  } else {
490
2.22k
    reserve(2 * size_reserved_);
491
2.22k
  }
492
419k
}
tesseract::GenericVector<tesseract::WERD_RES*>::double_the_size()
Line
Count
Source
486
419k
void GenericVector<T>::double_the_size() {
487
419k
  if (size_reserved_ == 0) {
488
417k
    reserve(kDefaultVectorSize);
489
417k
  } else {
490
2.19k
    reserve(2 * size_reserved_);
491
2.19k
  }
492
419k
}
tesseract::GenericVector<tesseract::FontInfo>::double_the_size()
Line
Count
Source
486
28
void GenericVector<T>::double_the_size() {
487
28
  if (size_reserved_ == 0) {
488
0
    reserve(kDefaultVectorSize);
489
28
  } else {
490
28
    reserve(2 * size_reserved_);
491
28
  }
492
28
}
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::double_the_size()
493
494
// Resizes to size and sets all values to t.
495
template <typename T>
496
0
void GenericVector<T>::init_to_size(int size, const T &t) {
497
0
  reserve(size);
498
0
  size_used_ = size;
499
0
  for (int i = 0; i < size; ++i) {
500
0
    data_[i] = t;
501
0
  }
502
0
}
503
504
template <typename T>
505
void GenericVector<T>::resize(int size, const T &t) {
506
  init_to_size(size, t);
507
}
508
509
template <typename T>
510
2.90M
T &GenericVector<T>::operator[](int index) const {
511
2.90M
  assert(index >= 0 && index < size_used_);
512
2.90M
  return data_[index];
513
2.90M
}
Unexecuted instantiation: tesseract::GenericVector<char>::operator[](int) const
tesseract::GenericVector<tesseract::WERD_RES*>::operator[](int) const
Line
Count
Source
510
2.90M
T &GenericVector<T>::operator[](int index) const {
511
  assert(index >= 0 && index < size_used_);
512
2.90M
  return data_[index];
513
2.90M
}
Unexecuted instantiation: tesseract::GenericVector<int>::operator[](int) const
514
515
template <typename T>
516
231k
T &GenericVector<T>::back() const {
517
231k
  assert(size_used_ > 0);
518
231k
  return data_[size_used_ - 1];
519
231k
}
520
// Returns the last object and removes it.
521
template <typename T>
522
T GenericVector<T>::pop_back() {
523
  assert(size_used_ > 0);
524
  return data_[--size_used_];
525
}
526
527
// Return the object from an index.
528
template <typename T>
529
void GenericVector<T>::set(const T &t, int index) {
530
  assert(index >= 0 && index < size_used_);
531
  data_[index] = t;
532
}
533
534
// Shifts the rest of the elements to the right to make
535
// space for the new elements and inserts the given element
536
// at the specified index.
537
template <typename T>
538
void GenericVector<T>::insert(const T &t, int index) {
539
  assert(index >= 0 && index <= size_used_);
540
  if (size_reserved_ == size_used_) {
541
    double_the_size();
542
  }
543
  for (int i = size_used_; i > index; --i) {
544
    data_[i] = data_[i - 1];
545
  }
546
  data_[index] = t;
547
  size_used_++;
548
}
549
550
// Removes an element at the given index and
551
// shifts the remaining elements to the left.
552
template <typename T>
553
void GenericVector<T>::remove(int index) {
554
  assert(index >= 0 && index < size_used_);
555
  for (int i = index; i < size_used_ - 1; ++i) {
556
    data_[i] = data_[i + 1];
557
  }
558
  size_used_--;
559
}
560
561
// Return the index of the T object.
562
template <typename T>
563
4.66k
int GenericVector<T>::get_index(const T &object) const {
564
797k
  for (int i = 0; i < size_used_; ++i) {
565
795k
    if (object == data_[i]) {
566
2.95k
      return i;
567
2.95k
    }
568
795k
  }
569
1.70k
  return -1;
570
4.66k
}
tesseract::GenericVector<tesseract::FontInfo>::get_index(tesseract::FontInfo const&) const
Line
Count
Source
563
4.66k
int GenericVector<T>::get_index(const T &object) const {
564
797k
  for (int i = 0; i < size_used_; ++i) {
565
795k
    if (object == data_[i]) {
566
2.95k
      return i;
567
2.95k
    }
568
795k
  }
569
1.70k
  return -1;
570
4.66k
}
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::get_index(std::__1::vector<int, std::__1::allocator<int> > const&) const
571
572
// Add an element in the array
573
template <typename T>
574
655k
int GenericVector<T>::push_back(T object) {
575
655k
  int index = 0;
576
655k
  if (size_used_ == size_reserved_) {
577
419k
    double_the_size();
578
419k
  }
579
655k
  index = size_used_++;
580
655k
  data_[index] = std::move(object);
581
655k
  return index;
582
655k
}
tesseract::GenericVector<tesseract::WERD_RES*>::push_back(tesseract::WERD_RES*)
Line
Count
Source
574
653k
int GenericVector<T>::push_back(T object) {
575
653k
  int index = 0;
576
653k
  if (size_used_ == size_reserved_) {
577
419k
    double_the_size();
578
419k
  }
579
653k
  index = size_used_++;
580
653k
  data_[index] = std::move(object);
581
653k
  return index;
582
653k
}
tesseract::GenericVector<tesseract::FontInfo>::push_back(tesseract::FontInfo)
Line
Count
Source
574
1.70k
int GenericVector<T>::push_back(T object) {
575
1.70k
  int index = 0;
576
1.70k
  if (size_used_ == size_reserved_) {
577
28
    double_the_size();
578
28
  }
579
1.70k
  index = size_used_++;
580
1.70k
  data_[index] = std::move(object);
581
1.70k
  return index;
582
1.70k
}
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::push_back(std::__1::vector<int, std::__1::allocator<int> >)
583
584
template <typename T>
585
0
void GenericVector<T>::operator+=(const T &t) {
586
0
  push_back(t);
587
0
}
588
589
template <typename T>
590
766k
GenericVector<T> &GenericVector<T>::operator+=(const GenericVector &other) {
591
766k
  this->reserve(size_used_ + other.size_used_);
592
766k
  for (unsigned i = 0; i < other.size(); ++i) {
593
0
    this->operator+=(other.data_[i]);
594
0
  }
595
766k
  return *this;
596
766k
}
597
598
template <typename T>
599
GenericVector<T> &GenericVector<T>::operator=(const GenericVector &other) {
600
  if (&other != this) {
601
    this->truncate(0);
602
    this->operator+=(other);
603
  }
604
  return *this;
605
}
606
607
// Clear the array, calling the callback function if any.
608
template <typename T>
609
3.63M
void GenericVector<T>::clear() {
610
3.63M
  if (size_reserved_ > 0 && clear_cb_ != nullptr) {
611
0
    for (int i = 0; i < size_used_; ++i) {
612
0
      clear_cb_(data_[i]);
613
0
    }
614
0
  }
615
3.63M
  delete[] data_;
616
3.63M
  data_ = nullptr;
617
3.63M
  size_used_ = 0;
618
3.63M
  size_reserved_ = 0;
619
3.63M
  clear_cb_ = nullptr;
620
3.63M
}
tesseract::GenericVector<tesseract::WERD_RES*>::clear()
Line
Count
Source
609
3.63M
void GenericVector<T>::clear() {
610
3.63M
  if (size_reserved_ > 0 && clear_cb_ != nullptr) {
611
0
    for (int i = 0; i < size_used_; ++i) {
612
0
      clear_cb_(data_[i]);
613
0
    }
614
0
  }
615
3.63M
  delete[] data_;
616
3.63M
  data_ = nullptr;
617
3.63M
  size_used_ = 0;
618
3.63M
  size_reserved_ = 0;
619
3.63M
  clear_cb_ = nullptr;
620
3.63M
}
tesseract::GenericVector<tesseract::FontInfo>::clear()
Line
Count
Source
609
8
void GenericVector<T>::clear() {
610
8
  if (size_reserved_ > 0 && clear_cb_ != nullptr) {
611
0
    for (int i = 0; i < size_used_; ++i) {
612
0
      clear_cb_(data_[i]);
613
0
    }
614
0
  }
615
8
  delete[] data_;
616
8
  data_ = nullptr;
617
8
  size_used_ = 0;
618
8
  size_reserved_ = 0;
619
8
  clear_cb_ = nullptr;
620
8
}
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::clear()
Unexecuted instantiation: tesseract::GenericVector<int>::clear()
621
622
template <typename T>
623
1.97M
void GenericVector<T>::delete_data_pointers() {
624
2.63M
  for (int i = 0; i < size_used_; ++i) {
625
653k
    delete data_[i];
626
653k
  }
627
1.97M
}
628
629
template <typename T>
630
0
bool GenericVector<T>::write(FILE *f, const std::function<bool(FILE *, const T &)> &cb) const {
631
0
  if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) {
632
0
    return false;
633
0
  }
634
0
  if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) {
635
0
    return false;
636
0
  }
637
0
  if (cb != nullptr) {
638
0
    for (int i = 0; i < size_used_; ++i) {
639
0
      if (!cb(f, data_[i])) {
640
0
        return false;
641
0
      }
642
0
    }
643
0
  } else {
644
0
    if (fwrite(data_, sizeof(T), size_used_, f) != unsigned_size()) {
645
0
      return false;
646
0
    }
647
0
  }
648
0
  return true;
649
0
}
Unexecuted instantiation: tesseract::GenericVector<tesseract::FontInfo>::write(_IO_FILE*, std::__1::function<bool (_IO_FILE*, tesseract::FontInfo const&)> const&) const
Unexecuted instantiation: tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::write(_IO_FILE*, std::__1::function<bool (_IO_FILE*, std::__1::vector<int, std::__1::allocator<int> > const&)> const&) const
650
651
template <typename T>
652
12
bool GenericVector<T>::read(TFile *f, const std::function<bool(TFile *, T *)> &cb) {
653
12
  int32_t reserved;
654
12
  if (f->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
655
0
    return false;
656
0
  }
657
12
  reserve(reserved);
658
12
  if (f->FReadEndian(&size_used_, sizeof(size_used_), 1) != 1) {
659
0
    return false;
660
0
  }
661
12
  if (cb != nullptr) {
662
3.87k
    for (int i = 0; i < size_used_; ++i) {
663
3.86k
      if (!cb(f, data_ + i)) {
664
0
        return false;
665
0
      }
666
3.86k
    }
667
12
  } else {
668
0
    if (f->FReadEndian(data_, sizeof(T), size_used_) != static_cast<unsigned>(size_used_)) {
669
0
      return false;
670
0
    }
671
0
  }
672
12
  return true;
673
12
}
tesseract::GenericVector<tesseract::FontInfo>::read(tesseract::TFile*, std::__1::function<bool (tesseract::TFile*, tesseract::FontInfo*)> const&)
Line
Count
Source
652
8
bool GenericVector<T>::read(TFile *f, const std::function<bool(TFile *, T *)> &cb) {
653
8
  int32_t reserved;
654
8
  if (f->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
655
0
    return false;
656
0
  }
657
8
  reserve(reserved);
658
8
  if (f->FReadEndian(&size_used_, sizeof(size_used_), 1) != 1) {
659
0
    return false;
660
0
  }
661
8
  if (cb != nullptr) {
662
3.42k
    for (int i = 0; i < size_used_; ++i) {
663
3.41k
      if (!cb(f, data_ + i)) {
664
0
        return false;
665
0
      }
666
3.41k
    }
667
8
  } else {
668
0
    if (f->FReadEndian(data_, sizeof(T), size_used_) != static_cast<unsigned>(size_used_)) {
669
0
      return false;
670
0
    }
671
0
  }
672
8
  return true;
673
8
}
tesseract::GenericVector<std::__1::vector<int, std::__1::allocator<int> > >::read(tesseract::TFile*, std::__1::function<bool (tesseract::TFile*, std::__1::vector<int, std::__1::allocator<int> >*)> const&)
Line
Count
Source
652
4
bool GenericVector<T>::read(TFile *f, const std::function<bool(TFile *, T *)> &cb) {
653
4
  int32_t reserved;
654
4
  if (f->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
655
0
    return false;
656
0
  }
657
4
  reserve(reserved);
658
4
  if (f->FReadEndian(&size_used_, sizeof(size_used_), 1) != 1) {
659
0
    return false;
660
0
  }
661
4
  if (cb != nullptr) {
662
448
    for (int i = 0; i < size_used_; ++i) {
663
444
      if (!cb(f, data_ + i)) {
664
0
        return false;
665
0
      }
666
444
    }
667
4
  } else {
668
0
    if (f->FReadEndian(data_, sizeof(T), size_used_) != static_cast<unsigned>(size_used_)) {
669
0
      return false;
670
0
    }
671
0
  }
672
4
  return true;
673
4
}
674
675
// Writes a vector of simple types to the given file. Assumes that bitwise
676
// read/write of T will work. Returns false in case of error.
677
template <typename T>
678
bool GenericVector<T>::Serialize(FILE *fp) const {
679
  if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) {
680
    return false;
681
  }
682
  if (fwrite(data_, sizeof(*data_), size_used_, fp) != unsigned_size()) {
683
    return false;
684
  }
685
  return true;
686
}
687
template <typename T>
688
bool GenericVector<T>::Serialize(TFile *fp) const {
689
  if (fp->FWrite(&size_used_, sizeof(size_used_), 1) != 1) {
690
    return false;
691
  }
692
  if (fp->FWrite(data_, sizeof(*data_), size_used_) != size_used_) {
693
    return false;
694
  }
695
  return true;
696
}
697
698
// Reads a vector of simple types from the given file. Assumes that bitwise
699
// read/write will work with ReverseN according to sizeof(T).
700
// Returns false in case of error.
701
// If swap is true, assumes a big/little-endian swap is needed.
702
template <typename T>
703
bool GenericVector<T>::DeSerialize(bool swap, FILE *fp) {
704
  uint32_t reserved;
705
  if (fread(&reserved, sizeof(reserved), 1, fp) != 1) {
706
    return false;
707
  }
708
  if (swap) {
709
    Reverse32(&reserved);
710
  }
711
  // Arbitrarily limit the number of elements to protect against bad data.
712
  assert(reserved <= UINT16_MAX);
713
  if (reserved > UINT16_MAX) {
714
    return false;
715
  }
716
  reserve(reserved);
717
  size_used_ = reserved;
718
  if (fread(data_, sizeof(T), size_used_, fp) != unsigned_size()) {
719
    return false;
720
  }
721
  if (swap) {
722
    for (int i = 0; i < size_used_; ++i) {
723
      ReverseN(&data_[i], sizeof(data_[i]));
724
    }
725
  }
726
  return true;
727
}
728
template <typename T>
729
bool GenericVector<T>::DeSerialize(TFile *fp) {
730
  uint32_t reserved;
731
  if (fp->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
732
    return false;
733
  }
734
  // Arbitrarily limit the number of elements to protect against bad data.
735
  const uint32_t limit = 50000000;
736
  assert(reserved <= limit);
737
  if (reserved > limit) {
738
    return false;
739
  }
740
  reserve(reserved);
741
  size_used_ = reserved;
742
  return fp->FReadEndian(data_, sizeof(T), size_used_) == size_used_;
743
}
744
745
// Writes a vector of classes to the given file. Assumes the existence of
746
// bool T::Serialize(FILE* fp) const that returns false in case of error.
747
// Returns false in case of error.
748
template <typename T>
749
0
bool GenericVector<T>::SerializeClasses(FILE *fp) const {
750
0
  if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) {
751
0
    return false;
752
0
  }
753
0
  for (int i = 0; i < size_used_; ++i) {
754
0
    if (!data_[i].Serialize(fp)) {
755
0
      return false;
756
0
    }
757
0
  }
758
0
  return true;
759
0
}
760
761
// Reads a vector of classes from the given file. Assumes the existence of
762
// bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
763
// error. Also needs T::T() and T::T(constT&), as init_to_size is used in
764
// this function. Returns false in case of error.
765
// If swap is true, assumes a big/little-endian swap is needed.
766
template <typename T>
767
0
bool GenericVector<T>::DeSerializeClasses(TFile *fp) {
768
0
  int32_t reserved;
769
0
  if (fp->FReadEndian(&reserved, sizeof(reserved), 1) != 1) {
770
0
    return false;
771
0
  }
772
0
  T empty;
773
0
  init_to_size(reserved, empty);
774
0
  for (int i = 0; i < reserved; ++i) {
775
0
    if (!data_[i].DeSerialize(fp)) {
776
0
      return false;
777
0
    }
778
0
  }
779
0
  return true;
780
0
}
781
782
// This method clear the current object, then, does a shallow copy of
783
// its argument, and finally invalidates its argument.
784
template <typename T>
785
void GenericVector<T>::move(GenericVector<T> *from) {
786
  this->clear();
787
  this->data_ = from->data_;
788
  this->size_reserved_ = from->size_reserved_;
789
  this->size_used_ = from->size_used_;
790
  this->clear_cb_ = from->clear_cb_;
791
  from->data_ = nullptr;
792
  from->clear_cb_ = nullptr;
793
  from->size_used_ = 0;
794
  from->size_reserved_ = 0;
795
}
796
797
template <typename T>
798
void GenericVector<T>::sort() {
799
  sort(&sort_cmp<T>);
800
}
801
802
} // namespace tesseract
803
804
#endif // TESSERACT_CCUTIL_GENERICVECTOR_H_