tesseract  5.0.0-alpha-619-ge9db
tfile_test.cc
Go to the documentation of this file.
1 // (C) Copyright 2017, Google Inc.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 // http://www.apache.org/licenses/LICENSE-2.0
6 // Unless required by applicable law or agreed to in writing, software
7 // distributed under the License is distributed on an "AS IS" BASIS,
8 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 // See the License for the specific language governing permissions and
10 // limitations under the License.
11 
13 #include <tesseract/serialis.h>
14 
15 #include "include_gunit.h"
16 
17 using tesseract::TFile;
18 
19 namespace {
20 
21 // Tests TFile and GenericVector serialization by serializing and
22 // writing/reading.
23 
24 class TfileTest : public ::testing::Test {
25  protected:
26  void SetUp() {
27  std::locale::global(std::locale(""));
28  }
29 
30  TfileTest() {}
31 
32  // Some data to serialize.
33  class MathData {
34  public:
35  MathData() : num_squares_(0), num_triangles_(0) {}
36  void Setup() {
37  // Setup some data.
38  for (int s = 0; s < 42; ++s) squares_.push_back(s * s);
39  num_squares_ = squares_.size();
40  for (int t = 0; t < 52; ++t) triangles_.push_back(t * (t + 1) / 2);
41  num_triangles_ = triangles_.size();
42  }
43  void ExpectEq(const MathData& other) {
44  // Check the data.
45  EXPECT_EQ(num_squares_, other.num_squares_);
46  for (int s = 0; s < squares_.size(); ++s)
47  EXPECT_EQ(squares_[s], other.squares_[s]);
48  EXPECT_EQ(num_triangles_, other.num_triangles_);
49  for (int s = 0; s < triangles_.size(); ++s)
50  EXPECT_EQ(triangles_[s], other.triangles_[s]);
51  }
52  bool Serialize(TFile* fp) {
53  if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
54  if (!squares_.Serialize(fp)) return false;
55  if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
56  return false;
57  if (!triangles_.Serialize(fp)) return false;
58  return true;
59  }
60  bool DeSerialize(TFile* fp) {
61  if (fp->FReadEndian(&num_squares_, sizeof(num_squares_), 1) != 1)
62  return false;
63  if (!squares_.DeSerialize(fp)) return false;
64  if (fp->FReadEndian(&num_triangles_, sizeof(num_triangles_), 1) != 1)
65  return false;
66  if (!triangles_.DeSerialize(fp)) return false;
67  return true;
68  }
69  bool SerializeBigEndian(TFile* fp) {
70  ReverseN(&num_squares_, sizeof(num_squares_));
71  if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
72  // Write an additional reversed size before the vector, which will get
73  // used as its size on reading.
74  if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
75  for (int i = 0; i < squares_.size(); ++i)
76  ReverseN(&squares_[i], sizeof(squares_[i]));
77  if (!squares_.Serialize(fp)) return false;
78  ReverseN(&num_triangles_, sizeof(num_triangles_));
79  if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
80  return false;
81  if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
82  return false;
83  for (int i = 0; i < triangles_.size(); ++i)
84  ReverseN(&triangles_[i], sizeof(triangles_[i]));
85  return triangles_.Serialize(fp);
86  }
87  bool DeSerializeBigEndian(TFile* fp) {
88  if (fp->FReadEndian(&num_squares_, sizeof(num_squares_), 1) != 1)
89  return false;
90  if (!squares_.DeSerialize(fp)) return false;
91  // The first element is the size that was written, so we will delete it
92  // and read the last element separately.
93  int last_element;
94  if (fp->FReadEndian(&last_element, sizeof(last_element), 1) != 1)
95  return false;
96  squares_.remove(0);
97  squares_.push_back(last_element);
98  if (fp->FReadEndian(&num_triangles_, sizeof(num_triangles_), 1) != 1)
99  return false;
100  if (!triangles_.DeSerialize(fp)) return false;
101  if (fp->FReadEndian(&last_element, sizeof(last_element), 1) != 1)
102  return false;
103  triangles_.remove(0);
104  triangles_.push_back(last_element);
105  return true;
106  }
107 
108  private:
109  GenericVector<int> squares_;
110  int num_squares_;
111  GenericVector<int> triangles_;
112  int num_triangles_;
113  };
114 };
115 
116 TEST_F(TfileTest, Serialize) {
117  // This test verifies that Tfile can serialize a class.
118  MathData m1;
119  m1.Setup();
120  GenericVector<char> data;
121  TFile fpw;
122  fpw.OpenWrite(&data);
123  EXPECT_TRUE(m1.Serialize(&fpw));
124  TFile fpr;
125  EXPECT_TRUE(fpr.Open(&data[0], data.size()));
126  MathData m2;
127  EXPECT_TRUE(m2.DeSerialize(&fpr));
128  m1.ExpectEq(m2);
129  MathData m3;
130  EXPECT_FALSE(m3.DeSerialize(&fpr));
131  fpr.Rewind();
132  EXPECT_TRUE(m3.DeSerialize(&fpr));
133  m1.ExpectEq(m3);
134 }
135 
136 TEST_F(TfileTest, FGets) {
137  // This test verifies that Tfile can interleave FGets with binary data.
138  MathData m1;
139  std::string line_str = "This is a textline with a newline\n";
140  m1.Setup();
141  GenericVector<char> data;
142  TFile fpw;
143  fpw.OpenWrite(&data);
144  EXPECT_TRUE(m1.Serialize(&fpw));
145  EXPECT_EQ(1, fpw.FWrite(line_str.data(), line_str.size(), 1));
146  EXPECT_TRUE(m1.Serialize(&fpw));
147  // Now get back the 2 copies of m1 with the line in between.
148  TFile fpr;
149  EXPECT_TRUE(fpr.Open(&data[0], data.size()));
150  MathData m2;
151  EXPECT_TRUE(m2.DeSerialize(&fpr));
152  m1.ExpectEq(m2);
153  const int kBufsize = 1024;
154  char buffer[kBufsize + 1];
155  EXPECT_EQ(buffer, fpr.FGets(buffer, kBufsize));
156  EXPECT_STREQ(line_str.c_str(), buffer);
157  MathData m3;
158  EXPECT_TRUE(m3.DeSerialize(&fpr));
159  m1.ExpectEq(m3);
160 }
161 
162 TEST_F(TfileTest, BigEndian) {
163  // This test verifies that Tfile can auto-reverse big-endian data.
164  MathData m1;
165  m1.Setup();
166  GenericVector<char> data;
167  TFile fpw;
168  fpw.OpenWrite(&data);
169  EXPECT_TRUE(m1.SerializeBigEndian(&fpw));
170  TFile fpr;
171  EXPECT_TRUE(fpr.Open(&data[0], data.size()));
172  fpr.set_swap(true);
173  MathData m2;
174  EXPECT_TRUE(m2.DeSerializeBigEndian(&fpr));
175  // That serialize was destructive, so test against a fresh MathData.
176  MathData m3;
177  m3.Setup();
178  m3.ExpectEq(m2);
179 }
180 
181 } // namespace
string
std::string string
Definition: equationdetect_test.cc:21
tesseract::TFile::FReadEndian
int FReadEndian(void *buffer, size_t size, int count)
Definition: serialis.cpp:273
include_gunit.h
tesseract::TEST_F
TEST_F(EquationFinderTest, IdentifySpecialText)
Definition: equationdetect_test.cc:181
genericvector.h
tesseract::TFile
Definition: serialis.h:75
GenericVector< int >
serialis.h
ReverseN
void ReverseN(void *ptr, int num_bytes)
Definition: helpers.h:183
tesseract::TFile::FWrite
int FWrite(const void *buffer, size_t size, int count)
Definition: serialis.cpp:332
tesseract::DeSerialize
bool DeSerialize(FILE *fp, char *data, size_t n=1)
Definition: serialis.cpp:41
GenericVector::size
int size() const
Definition: genericvector.h:71
tesseract::TFile::OpenWrite
void OpenWrite(GenericVector< char > *data)
Definition: serialis.cpp:309
tesseract::Serialize
bool Serialize(FILE *fp, const char *data, size_t n=1)
Definition: serialis.cpp:73