summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tesseract/unittest/tfile_test.cc')
-rw-r--r--tesseract/unittest/tfile_test.cc179
1 files changed, 179 insertions, 0 deletions
diff --git a/tesseract/unittest/tfile_test.cc b/tesseract/unittest/tfile_test.cc
new file mode 100644
index 00000000..166405ff
--- /dev/null
+++ b/tesseract/unittest/tfile_test.cc
@@ -0,0 +1,179 @@
+// (C) Copyright 2017, Google Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "genericvector.h"
+#include "serialis.h"
+
+#include "include_gunit.h"
+
+namespace tesseract {
+
+// Tests TFile and std::vector serialization by serializing and
+// writing/reading.
+
+class TfileTest : public ::testing::Test {
+ protected:
+ void SetUp() {
+ std::locale::global(std::locale(""));
+ }
+
+ TfileTest() {}
+
+ // Some data to serialize.
+ class MathData {
+ public:
+ MathData() : num_squares_(0), num_triangles_(0) {}
+ void Setup() {
+ // Setup some data.
+ for (int s = 0; s < 42; ++s) squares_.push_back(s * s);
+ num_squares_ = squares_.size();
+ for (int t = 0; t < 52; ++t) triangles_.push_back(t * (t + 1) / 2);
+ num_triangles_ = triangles_.size();
+ }
+ void ExpectEq(const MathData& other) {
+ // Check the data.
+ EXPECT_EQ(num_squares_, other.num_squares_);
+ for (int s = 0; s < squares_.size(); ++s)
+ EXPECT_EQ(squares_[s], other.squares_[s]);
+ EXPECT_EQ(num_triangles_, other.num_triangles_);
+ for (int s = 0; s < triangles_.size(); ++s)
+ EXPECT_EQ(triangles_[s], other.triangles_[s]);
+ }
+ bool Serialize(TFile* fp) {
+ if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
+ if (!squares_.Serialize(fp)) return false;
+ if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
+ return false;
+ if (!triangles_.Serialize(fp)) return false;
+ return true;
+ }
+ bool DeSerialize(TFile* fp) {
+ if (fp->FReadEndian(&num_squares_, sizeof(num_squares_), 1) != 1)
+ return false;
+ if (!squares_.DeSerialize(fp)) return false;
+ if (fp->FReadEndian(&num_triangles_, sizeof(num_triangles_), 1) != 1)
+ return false;
+ if (!triangles_.DeSerialize(fp)) return false;
+ return true;
+ }
+ bool SerializeBigEndian(TFile* fp) {
+ ReverseN(&num_squares_, sizeof(num_squares_));
+ if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
+ // Write an additional reversed size before the vector, which will get
+ // used as its size on reading.
+ if (fp->FWrite(&num_squares_, sizeof(num_squares_), 1) != 1) return false;
+ for (int i = 0; i < squares_.size(); ++i)
+ ReverseN(&squares_[i], sizeof(squares_[i]));
+ if (!squares_.Serialize(fp)) return false;
+ ReverseN(&num_triangles_, sizeof(num_triangles_));
+ if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
+ return false;
+ if (fp->FWrite(&num_triangles_, sizeof(num_triangles_), 1) != 1)
+ return false;
+ for (int i = 0; i < triangles_.size(); ++i)
+ ReverseN(&triangles_[i], sizeof(triangles_[i]));
+ return triangles_.Serialize(fp);
+ }
+ bool DeSerializeBigEndian(TFile* fp) {
+ if (fp->FReadEndian(&num_squares_, sizeof(num_squares_), 1) != 1)
+ return false;
+ if (!squares_.DeSerialize(fp)) return false;
+ // The first element is the size that was written, so we will delete it
+ // and read the last element separately.
+ int last_element;
+ if (fp->FReadEndian(&last_element, sizeof(last_element), 1) != 1)
+ return false;
+ squares_.remove(0);
+ squares_.push_back(last_element);
+ if (fp->FReadEndian(&num_triangles_, sizeof(num_triangles_), 1) != 1)
+ return false;
+ if (!triangles_.DeSerialize(fp)) return false;
+ if (fp->FReadEndian(&last_element, sizeof(last_element), 1) != 1)
+ return false;
+ triangles_.remove(0);
+ triangles_.push_back(last_element);
+ return true;
+ }
+
+ private:
+ GenericVector<int> squares_;
+ int num_squares_;
+ GenericVector<int> triangles_;
+ int num_triangles_;
+ };
+};
+
+TEST_F(TfileTest, Serialize) {
+ // This test verifies that Tfile can serialize a class.
+ MathData m1;
+ m1.Setup();
+ std::vector<char> data;
+ TFile fpw;
+ fpw.OpenWrite(&data);
+ EXPECT_TRUE(m1.Serialize(&fpw));
+ TFile fpr;
+ EXPECT_TRUE(fpr.Open(&data[0], data.size()));
+ MathData m2;
+ EXPECT_TRUE(m2.DeSerialize(&fpr));
+ m1.ExpectEq(m2);
+ MathData m3;
+ EXPECT_FALSE(m3.DeSerialize(&fpr));
+ fpr.Rewind();
+ EXPECT_TRUE(m3.DeSerialize(&fpr));
+ m1.ExpectEq(m3);
+}
+
+TEST_F(TfileTest, FGets) {
+ // This test verifies that Tfile can interleave FGets with binary data.
+ MathData m1;
+ std::string line_str = "This is a textline with a newline\n";
+ m1.Setup();
+ std::vector<char> data;
+ TFile fpw;
+ fpw.OpenWrite(&data);
+ EXPECT_TRUE(m1.Serialize(&fpw));
+ EXPECT_EQ(1, fpw.FWrite(line_str.data(), line_str.size(), 1));
+ EXPECT_TRUE(m1.Serialize(&fpw));
+ // Now get back the 2 copies of m1 with the line in between.
+ TFile fpr;
+ EXPECT_TRUE(fpr.Open(&data[0], data.size()));
+ MathData m2;
+ EXPECT_TRUE(m2.DeSerialize(&fpr));
+ m1.ExpectEq(m2);
+ const int kBufsize = 1024;
+ char buffer[kBufsize + 1];
+ EXPECT_EQ(buffer, fpr.FGets(buffer, kBufsize));
+ EXPECT_STREQ(line_str.c_str(), buffer);
+ MathData m3;
+ EXPECT_TRUE(m3.DeSerialize(&fpr));
+ m1.ExpectEq(m3);
+}
+
+TEST_F(TfileTest, BigEndian) {
+ // This test verifies that Tfile can auto-reverse big-endian data.
+ MathData m1;
+ m1.Setup();
+ std::vector<char> data;
+ TFile fpw;
+ fpw.OpenWrite(&data);
+ EXPECT_TRUE(m1.SerializeBigEndian(&fpw));
+ TFile fpr;
+ EXPECT_TRUE(fpr.Open(&data[0], data.size()));
+ fpr.set_swap(true);
+ MathData m2;
+ EXPECT_TRUE(m2.DeSerializeBigEndian(&fpr));
+ // That serialize was destructive, so test against a fresh MathData.
+ MathData m3;
+ m3.Setup();
+ m3.ExpectEq(m2);
+}
+
+} // namespace