Merge pull request #1785 from stweil/serialize

Use new serialization API
This commit is contained in:
zdenop 2018-07-18 18:17:53 +02:00 committed by GitHub
commit 790e115d1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 112 additions and 154 deletions

View File

@ -150,37 +150,33 @@ void FontSetDeleteCallback(FontSet fs) {
/*---------------------------------------------------------------------------*/
// Callbacks used by UnicityTable to read/write FontInfo/FontSet structures.
bool read_info(TFile* f, FontInfo* fi) {
int32_t size;
if (f->FReadEndian(&size, sizeof(size), 1) != 1) return false;
uint32_t size;
if (!f->DeSerialize(&size)) return false;
char* font_name = new char[size + 1];
fi->name = font_name;
if (f->FRead(font_name, sizeof(*font_name), size) != size) return false;
if (!f->DeSerialize(font_name, size)) return false;
font_name[size] = '\0';
if (f->FReadEndian(&fi->properties, sizeof(fi->properties), 1) != 1)
return false;
return true;
return f->DeSerialize(&fi->properties);
}
bool write_info(FILE* f, const FontInfo& fi) {
int32_t size = strlen(fi.name);
if (fwrite(&size, sizeof(size), 1, f) != 1) return false;
if (static_cast<int>(fwrite(fi.name, sizeof(*fi.name), size, f)) != size)
return false;
if (fwrite(&fi.properties, sizeof(fi.properties), 1, f) != 1) return false;
return true;
return tesseract::Serialize(f, &size) &&
tesseract::Serialize(f, &fi.name[0], size) &&
tesseract::Serialize(f, &fi.properties);
}
bool read_spacing_info(TFile* f, FontInfo* fi) {
int32_t vec_size, kern_size;
if (f->FReadEndian(&vec_size, sizeof(vec_size), 1) != 1) return false;
if (!f->DeSerialize(&vec_size)) return false;
ASSERT_HOST(vec_size >= 0);
if (vec_size == 0) return true;
fi->init_spacing(vec_size);
for (int i = 0; i < vec_size; ++i) {
FontSpacingInfo *fs = new FontSpacingInfo();
if (f->FReadEndian(&fs->x_gap_before, sizeof(fs->x_gap_before), 1) != 1 ||
f->FReadEndian(&fs->x_gap_after, sizeof(fs->x_gap_after), 1) != 1 ||
f->FReadEndian(&kern_size, sizeof(kern_size), 1) != 1) {
if (!f->DeSerialize(&fs->x_gap_before) ||
!f->DeSerialize(&fs->x_gap_after) ||
!f->DeSerialize(&kern_size)) {
delete fs;
return false;
}
@ -200,22 +196,21 @@ bool read_spacing_info(TFile* f, FontInfo* fi) {
bool write_spacing_info(FILE* f, const FontInfo& fi) {
int32_t vec_size = (fi.spacing_vec == nullptr) ? 0 : fi.spacing_vec->size();
if (fwrite(&vec_size, sizeof(vec_size), 1, f) != 1) return false;
if (!tesseract::Serialize(f, &vec_size)) return false;
int16_t x_gap_invalid = -1;
for (int i = 0; i < vec_size; ++i) {
FontSpacingInfo *fs = fi.spacing_vec->get(i);
int32_t kern_size = (fs == nullptr) ? -1 : fs->kerned_x_gaps.size();
if (fs == nullptr) {
// Valid to have the identical fwrites. Writing invalid x-gaps.
if (fwrite(&(x_gap_invalid), sizeof(x_gap_invalid), 1, f) != 1 ||
fwrite(&(x_gap_invalid), sizeof(x_gap_invalid), 1, f) != 1 ||
fwrite(&kern_size, sizeof(kern_size), 1, f) != 1) {
// Writing two invalid x-gaps.
if (!tesseract::Serialize(f, &x_gap_invalid, 2) ||
!tesseract::Serialize(f, &kern_size)) {
return false;
}
} else {
if (fwrite(&(fs->x_gap_before), sizeof(fs->x_gap_before), 1, f) != 1 ||
fwrite(&(fs->x_gap_after), sizeof(fs->x_gap_after), 1, f) != 1 ||
fwrite(&kern_size, sizeof(kern_size), 1, f) != 1) {
if (!tesseract::Serialize(f, &fs->x_gap_before) ||
!tesseract::Serialize(f, &fs->x_gap_after) ||
!tesseract::Serialize(f, &kern_size)) {
return false;
}
}
@ -228,19 +223,14 @@ bool write_spacing_info(FILE* f, const FontInfo& fi) {
}
bool read_set(TFile* f, FontSet* fs) {
if (f->FReadEndian(&fs->size, sizeof(fs->size), 1) != 1) return false;
if (!f->DeSerialize(&fs->size)) return false;
fs->configs = new int[fs->size];
if (f->FReadEndian(fs->configs, sizeof(fs->configs[0]), fs->size) != fs->size)
return false;
return true;
return f->DeSerialize(&fs->configs[0], fs->size);
}
bool write_set(FILE* f, const FontSet& fs) {
if (fwrite(&fs.size, sizeof(fs.size), 1, f) != 1) return false;
for (int i = 0; i < fs.size; ++i) {
if (fwrite(&fs.configs[i], sizeof(fs.configs[i]), 1, f) != 1) return false;
}
return true;
return tesseract::Serialize(f, &fs.size) &&
tesseract::Serialize(f, &fs.configs[0], fs.size);
}
} // namespace tesseract.

View File

@ -84,19 +84,17 @@ void WordFeature::Draw(const GenericVector<WordFeature>& features,
// Writes to the given file. Returns false in case of error.
bool WordFeature::Serialize(FILE* fp) const {
if (fwrite(&x_, sizeof(x_), 1, fp) != 1) return false;
if (fwrite(&y_, sizeof(y_), 1, fp) != 1) return false;
if (fwrite(&dir_, sizeof(dir_), 1, fp) != 1) return false;
return true;
return tesseract::Serialize(fp, &x_) &&
tesseract::Serialize(fp, &y_) &&
tesseract::Serialize(fp, &dir_);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool WordFeature::DeSerialize(bool swap, FILE* fp) {
if (fread(&x_, sizeof(x_), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &x_)) return false;
if (swap) ReverseN(&x_, sizeof(x_));
if (fread(&y_, sizeof(y_), 1, fp) != 1) return false;
if (fread(&dir_, sizeof(dir_), 1, fp) != 1) return false;
return true;
return tesseract::DeSerialize(fp, &y_) &&
tesseract::DeSerialize(fp, &dir_);
}
void FloatWordFeature::FromWordFeatures(
@ -167,7 +165,7 @@ ImageData* ImageData::Build(const char* name, int page_number, const char* lang,
// Writes to the given file. Returns false in case of error.
bool ImageData::Serialize(TFile* fp) const {
if (!imagefilename_.Serialize(fp)) return false;
if (fp->FWrite(&page_number_, sizeof(page_number_), 1) != 1) return false;
if (!fp->Serialize(&page_number_)) return false;
if (!image_data_.Serialize(fp)) return false;
if (!language_.Serialize(fp)) return false;
if (!transcription_.Serialize(fp)) return false;
@ -175,16 +173,14 @@ bool ImageData::Serialize(TFile* fp) const {
if (!boxes_.Serialize(fp)) return false;
if (!box_texts_.SerializeClasses(fp)) return false;
int8_t vertical = vertical_text_;
if (fp->FWrite(&vertical, sizeof(vertical), 1) != 1) return false;
return true;
return fp->Serialize(&vertical);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool ImageData::DeSerialize(TFile* fp) {
if (!imagefilename_.DeSerialize(fp)) return false;
if (fp->FReadEndian(&page_number_, sizeof(page_number_), 1) != 1)
return false;
if (!fp->DeSerialize(&page_number_)) return false;
if (!image_data_.DeSerialize(fp)) return false;
if (!language_.DeSerialize(fp)) return false;
if (!transcription_.DeSerialize(fp)) return false;
@ -192,7 +188,7 @@ bool ImageData::DeSerialize(TFile* fp) {
if (!boxes_.DeSerialize(fp)) return false;
if (!box_texts_.DeSerializeClasses(fp)) return false;
int8_t vertical = 0;
if (fp->FRead(&vertical, sizeof(vertical), 1) != 1) return false;
if (!fp->DeSerialize(&vertical)) return false;
vertical_text_ = vertical != 0;
return true;
}
@ -201,14 +197,14 @@ bool ImageData::DeSerialize(TFile* fp) {
bool ImageData::SkipDeSerialize(TFile* fp) {
if (!STRING::SkipDeSerialize(fp)) return false;
int32_t page_number;
if (fp->FRead(&page_number, sizeof(page_number), 1) != 1) return false;
if (!fp->DeSerialize(&page_number)) return false;
if (!GenericVector<char>::SkipDeSerialize(fp)) return false;
if (!STRING::SkipDeSerialize(fp)) return false;
if (!STRING::SkipDeSerialize(fp)) return false;
if (!GenericVector<TBOX>::SkipDeSerialize(fp)) return false;
if (!GenericVector<STRING>::SkipDeSerializeClasses(fp)) return false;
int8_t vertical = 0;
return fp->FRead(&vertical, sizeof(vertical), 1) == 1;
return fp->DeSerialize(&vertical);
}
// Saves the given Pix as a PNG-encoded string and destroys it.

View File

@ -30,7 +30,7 @@
#include <algorithm> // for max, min
#include <cmath> // for sqrt, fabs, isfinite
#include <cstdint> // for int32_t
#include <cstdio> // for fread, fwrite, FILE
#include <cstdio> // for FILE
#include <cstring> // for memcpy
#include "errcode.h" // for ASSERT_HOST
#include "helpers.h" // for ReverseN, ClipToRange
@ -143,17 +143,16 @@ class GENERIC_2D_ARRAY {
// Only works with bitwise-serializeable types!
bool Serialize(FILE* fp) const {
if (!SerializeSize(fp)) return false;
if (fwrite(&empty_, sizeof(empty_), 1, fp) != 1) return false;
if (!tesseract::Serialize(fp, &empty_)) return false;
int size = num_elements();
if (fwrite(array_, sizeof(*array_), size, fp) != size) return false;
return true;
return tesseract::Serialize(fp, &array_[0], size);
}
bool Serialize(tesseract::TFile* fp) const {
if (!SerializeSize(fp)) return false;
if (fp->FWrite(&empty_, sizeof(empty_), 1) != 1) return false;
if (!fp->Serialize(&empty_)) return false;
int size = num_elements();
if (fp->FWrite(array_, sizeof(*array_), size) != size) return false;
return true;
return fp->Serialize(&array_[0], size);
}
// Reads from the given file. Returns false in case of error.
@ -161,22 +160,21 @@ class GENERIC_2D_ARRAY {
// If swap is true, assumes a big/little-endian swap is needed.
bool DeSerialize(bool swap, FILE* fp) {
if (!DeSerializeSize(swap, fp)) return false;
if (fread(&empty_, sizeof(empty_), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &empty_)) return false;
if (swap) ReverseN(&empty_, sizeof(empty_));
int size = num_elements();
if (fread(array_, sizeof(*array_), size, fp) != size) return false;
if (!tesseract::DeSerialize(fp, &array_[0], size)) return false;
if (swap) {
for (int i = 0; i < size; ++i)
ReverseN(&array_[i], sizeof(array_[i]));
}
return true;
}
bool DeSerialize(tesseract::TFile* fp) {
if (!DeSerializeSize(fp)) return false;
if (fp->FReadEndian(&empty_, sizeof(empty_), 1) != 1) return false;
int size = num_elements();
if (fp->FReadEndian(array_, sizeof(*array_), size) != size) return false;
return true;
return DeSerializeSize(fp) &&
fp->DeSerialize(&empty_) &&
fp->DeSerialize(&array_[0], num_elements());
}
// Writes to the given file. Returns false in case of error.
@ -466,25 +464,23 @@ class GENERIC_2D_ARRAY {
protected:
// Factored helper to serialize the size.
bool SerializeSize(FILE* fp) const {
int32_t size = dim1_;
if (fwrite(&size, sizeof(size), 1, fp) != 1) return false;
uint32_t size = dim1_;
if (!tesseract::Serialize(fp, &size)) return false;
size = dim2_;
if (fwrite(&size, sizeof(size), 1, fp) != 1) return false;
return true;
return tesseract::Serialize(fp, &size);
}
bool SerializeSize(tesseract::TFile* fp) const {
int32_t size = dim1_;
if (fp->FWrite(&size, sizeof(size), 1) != 1) return false;
uint32_t size = dim1_;
if (!fp->Serialize(&size)) return false;
size = dim2_;
if (fp->FWrite(&size, sizeof(size), 1) != 1) return false;
return true;
return fp->Serialize(&size);
}
// Factored helper to deserialize the size.
// If swap is true, assumes a big/little-endian swap is needed.
bool DeSerializeSize(bool swap, FILE* fp) {
int32_t size1, size2;
if (fread(&size1, sizeof(size1), 1, fp) != 1) return false;
if (fread(&size2, sizeof(size2), 1, fp) != 1) return false;
uint32_t size1, size2;
if (!tesseract::DeSerialize(fp, &size1)) return false;
if (!tesseract::DeSerialize(fp, &size2)) return false;
if (swap) {
ReverseN(&size1, sizeof(size1));
ReverseN(&size2, sizeof(size2));
@ -497,8 +493,8 @@ class GENERIC_2D_ARRAY {
}
bool DeSerializeSize(tesseract::TFile* fp) {
int32_t size1, size2;
if (fp->FReadEndian(&size1, sizeof(size1), 1) != 1) return false;
if (fp->FReadEndian(&size2, sizeof(size2), 1) != 1) return false;
if (!fp->DeSerialize(&size1)) return false;
if (!fp->DeSerialize(&size2)) return false;
// Arbitrarily limit the number of elements to protect against bad data.
if (size1 > UINT16_MAX) return false;
if (size2 > UINT16_MAX) return false;

View File

@ -61,15 +61,14 @@ static int sign(int x) {
// Writes to the given file. Returns false in case of error.
bool ICOORD::Serialize(FILE* fp) const {
if (fwrite(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
if (fwrite(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
return true;
return tesseract::Serialize(fp, &xcoord) &&
tesseract::Serialize(fp, &ycoord);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool ICOORD::DeSerialize(bool swap, FILE* fp) {
if (fread(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
if (fread(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &xcoord)) return false;
if (!tesseract::DeSerialize(fp, &ycoord)) return false;
if (swap) {
ReverseN(&xcoord, sizeof(xcoord));
ReverseN(&ycoord, sizeof(ycoord));

View File

@ -20,10 +20,10 @@
///////////////////////////////////////////////////////////////////////
#include "bitvector.h"
#include <algorithm>
#include <cstring>
#include "helpers.h"
#include <algorithm>
#include "serialis.h" // for tesseract::Serialize
namespace tesseract {
@ -137,25 +137,22 @@ void BitVector::Init(int length) {
// Writes to the given file. Returns false in case of error.
bool BitVector::Serialize(FILE* fp) const {
if (fwrite(&bit_size_, sizeof(bit_size_), 1, fp) != 1) return false;
if (!tesseract::Serialize(fp, &bit_size_)) return false;
int wordlen = WordLength();
if (static_cast<int>(fwrite(array_, sizeof(*array_), wordlen, fp)) != wordlen)
return false;
return true;
return tesseract::Serialize(fp, &array_[0], wordlen);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool BitVector::DeSerialize(bool swap, FILE* fp) {
uint32_t new_bit_size;
if (fread(&new_bit_size, sizeof(new_bit_size), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &new_bit_size)) return false;
if (swap) {
ReverseN(&new_bit_size, sizeof(new_bit_size));
}
Alloc(new_bit_size);
int wordlen = WordLength();
if (static_cast<int>(fread(array_, sizeof(*array_), wordlen, fp)) != wordlen)
return false;
if (!tesseract::DeSerialize(fp, &array_[0], wordlen)) return false;
if (swap) {
for (int i = 0; i < wordlen; ++i)
ReverseN(&array_[i], sizeof(array_[i]));

View File

@ -41,24 +41,20 @@ void IndexMap::CopyFrom(const IndexMapBiDi& src) {
// Writes to the given file. Returns false in case of error.
bool IndexMap::Serialize(FILE* fp) const {
int32_t sparse_size = sparse_size_;
if (fwrite(&sparse_size, sizeof(sparse_size), 1, fp) != 1) return false;
if (!compact_map_.Serialize(fp)) return false;
return true;
return tesseract::Serialize(fp, &sparse_size_) && compact_map_.Serialize(fp);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool IndexMap::DeSerialize(bool swap, FILE* fp) {
uint32_t sparse_size;
if (fread(&sparse_size, sizeof(sparse_size), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &sparse_size)) return false;
if (swap)
ReverseN(&sparse_size, sizeof(sparse_size));
// Arbitrarily limit the number of elements to protect against bad data.
if (sparse_size > UINT16_MAX) return false;
sparse_size_ = sparse_size;
if (!compact_map_.DeSerialize(swap, fp)) return false;
return true;
return compact_map_.DeSerialize(swap, fp);
}

View File

@ -74,7 +74,7 @@ class IndexMap {
protected:
// The sparse space covers integers in the range [0, sparse_size_-1].
int sparse_size_;
int32_t sparse_size_;
// The compact space covers integers in the range [0, compact_map_.size()-1].
// Each element contains the corresponding sparse index.
GenericVector<int32_t> compact_map_;

View File

@ -146,45 +146,42 @@ STRING::~STRING() {
// TODO(rays) Change all callers to use TFile and remove the old functions.
// Writes to the given file. Returns false in case of error.
bool STRING::Serialize(FILE* fp) const {
int32_t len = length();
if (fwrite(&len, sizeof(len), 1, fp) != 1) return false;
if (static_cast<int>(fwrite(GetCStr(), 1, len, fp)) != len) return false;
return true;
uint32_t len = length();
return tesseract::Serialize(fp, &len) &&
tesseract::Serialize(fp, GetCStr(), len);
}
// Writes to the given file. Returns false in case of error.
bool STRING::Serialize(TFile* fp) const {
int32_t len = length();
if (fp->FWrite(&len, sizeof(len), 1) != 1) return false;
if (fp->FWrite(GetCStr(), 1, len) != len) return false;
return true;
uint32_t len = length();
return fp->Serialize(&len) &&
fp->Serialize(GetCStr(), len);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool STRING::DeSerialize(bool swap, FILE* fp) {
uint32_t len;
if (fread(&len, sizeof(len), 1, fp) != 1) return false;
if (!tesseract::DeSerialize(fp, &len)) return false;
if (swap)
ReverseN(&len, sizeof(len));
// Arbitrarily limit the number of characters to protect against bad data.
if (len > UINT16_MAX) return false;
truncate_at(len);
return fread(GetCStr(), 1, len, fp) == len;
return tesseract::DeSerialize(fp, GetCStr(), len);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool STRING::DeSerialize(TFile* fp) {
int32_t len;
if (fp->FReadEndian(&len, sizeof(len), 1) != 1) return false;
uint32_t len;
if (!fp->DeSerialize(&len)) return false;
truncate_at(len);
if (fp->FRead(GetCStr(), 1, len) != len) return false;
return true;
return fp->DeSerialize(GetCStr(), len);
}
// As DeSerialize, but only seeks past the data - hence a static method.
bool STRING::SkipDeSerialize(tesseract::TFile* fp) {
int32_t len;
if (fp->FReadEndian(&len, sizeof(len), 1) != 1) return false;
return fp->FRead(nullptr, 1, len) == len;
bool STRING::SkipDeSerialize(TFile* fp) {
uint32_t len;
if (!fp->DeSerialize(&len)) return false;
return fp->Skip(len);
}
bool STRING::contains(const char c) const {

View File

@ -69,17 +69,15 @@ bool TessdataManager::LoadMemBuffer(const char *name, const char *data,
data_file_name_ = name;
TFile fp;
fp.Open(data, size);
int32_t num_entries = TESSDATA_NUM_ENTRIES;
if (fp.FRead(&num_entries, sizeof(num_entries), 1) != 1) return false;
swap_ = num_entries > kMaxNumTessdataEntries || num_entries < 0;
uint32_t num_entries;
if (!fp.DeSerialize(&num_entries)) return false;
swap_ = num_entries > kMaxNumTessdataEntries;
fp.set_swap(swap_);
if (swap_) ReverseN(&num_entries, sizeof(num_entries));
if (num_entries > kMaxNumTessdataEntries || num_entries < 0) return false;
if (num_entries > kMaxNumTessdataEntries) return false;
GenericVector<int64_t> offset_table;
offset_table.resize_no_init(num_entries);
if (fp.FReadEndian(&offset_table[0], sizeof(offset_table[0]), num_entries) !=
num_entries)
return false;
if (!fp.DeSerialize(&offset_table[0], num_entries)) return false;
for (int i = 0; i < num_entries && i < TESSDATA_NUM_ENTRIES; ++i) {
if (offset_table[i] >= 0) {
int64_t entry_size = size - offset_table[i];
@ -87,7 +85,7 @@ bool TessdataManager::LoadMemBuffer(const char *name, const char *data,
while (j < num_entries && offset_table[j] == -1) ++j;
if (j < num_entries) entry_size = offset_table[j] - offset_table[i];
entries_[i].resize_no_init(entry_size);
if (fp.FRead(&entries_[i][0], 1, entry_size) != entry_size) return false;
if (!fp.DeSerialize(&entries_[i][0], entry_size)) return false;
}
}
if (entries_[TESSDATA_VERSION].empty()) {
@ -135,11 +133,11 @@ void TessdataManager::Serialize(GenericVector<char> *data) const {
int32_t num_entries = TESSDATA_NUM_ENTRIES;
TFile fp;
fp.OpenWrite(data);
fp.FWrite(&num_entries, sizeof(num_entries), 1);
fp.FWrite(offset_table, sizeof(offset_table), 1);
fp.Serialize(&num_entries);
fp.Serialize(&offset_table[0], countof(offset_table));
for (int i = 0; i < TESSDATA_NUM_ENTRIES; ++i) {
if (!entries_[i].empty()) {
fp.FWrite(&entries_[i][0], entries_[i].size(), 1);
fp.Serialize(&entries_[i][0], entries_[i].size());
}
}
}

View File

@ -59,21 +59,15 @@ class RecodedCharID {
// Writes to the given file. Returns false in case of error.
bool Serialize(TFile* fp) const {
if (fp->FWrite(&self_normalized_, sizeof(self_normalized_), 1) != 1)
return false;
if (fp->FWrite(&length_, sizeof(length_), 1) != 1) return false;
if (fp->FWrite(code_, sizeof(code_[0]), length_) != length_) return false;
return true;
return fp->Serialize(&self_normalized_) &&
fp->Serialize(&length_) &&
fp->Serialize(&code_[0], length_);
}
// Reads from the given file. Returns false in case of error.
// If swap is true, assumes a big/little-endian swap is needed.
bool DeSerialize(TFile* fp) {
if (fp->FRead(&self_normalized_, sizeof(self_normalized_), 1) != 1)
return false;
if (fp->FReadEndian(&length_, sizeof(length_), 1) != 1) return false;
if (fp->FReadEndian(code_, sizeof(code_[0]), length_) != length_)
return false;
return true;
return fp->DeSerialize(&self_normalized_) &&
fp->DeSerialize(&length_) &&
fp->DeSerialize(&code_[0], length_);
}
bool operator==(const RecodedCharID& other) const {
if (length_ != other.length_) return false;

View File

@ -354,15 +354,13 @@ class UNICHARSET {
// Returns true if the operation is successful.
bool save_to_file(FILE *file) const {
STRING str;
if (!save_to_string(&str)) return false;
if (fwrite(&str[0], str.length(), 1, file) != 1) return false;
return true;
return save_to_string(&str) &&
tesseract::Serialize(file, &str[0], str.length());
}
bool save_to_file(tesseract::TFile *file) const {
STRING str;
if (!save_to_string(&str)) return false;
if (file->FWrite(&str[0], str.length(), 1) != 1) return false;
return true;
return save_to_string(&str) && file->Serialize(&str[0], str.length());
}
// Saves the content of the UNICHARSET to the given STRING.

View File

@ -70,7 +70,8 @@ MasterTrainer::~MasterTrainer() {
// enough data to get the samples back and display them.
// Writes to the given file. Returns false in case of error.
bool MasterTrainer::Serialize(FILE* fp) const {
if (fwrite(&norm_mode_, sizeof(norm_mode_), 1, fp) != 1) return false;
uint32_t value = norm_mode_;
if (!tesseract::Serialize(fp, &value)) return false;
if (!unicharset_.save_to_file(fp)) return false;
if (!feature_space_.Serialize(fp)) return false;
if (!samples_.Serialize(fp)) return false;

View File

@ -67,14 +67,12 @@ int UnicharRating::FirstResultWithUnichar(
// Writes to the given file. Returns false in case of error.
bool UnicharAndFonts::Serialize(FILE* fp) const {
if (fwrite(&unichar_id, sizeof(unichar_id), 1, fp) != 1) return false;
return font_ids.Serialize(fp);
return tesseract::Serialize(fp, &unichar_id) && font_ids.Serialize(fp);
}
// Reads from the given file. Returns false in case of error.
bool UnicharAndFonts::DeSerialize(TFile* fp) {
if (fp->FReadEndian(&unichar_id, sizeof(unichar_id), 1) != 1) return false;
return font_ids.DeSerialize(fp);
return fp->DeSerialize(&unichar_id) && font_ids.DeSerialize(fp);
}
// Sort function to sort a pair of UnicharAndFonts by unichar_id.
@ -87,15 +85,13 @@ int UnicharAndFonts::SortByUnicharId(const void* v1, const void* v2) {
// Writes to the given file. Returns false in case of error.
bool Shape::Serialize(FILE* fp) const {
uint8_t sorted = unichars_sorted_;
if (fwrite(&sorted, sizeof(sorted), 1, fp) != 1)
return false;
return unichars_.SerializeClasses(fp);
return tesseract::Serialize(fp, &sorted) && unichars_.SerializeClasses(fp);
}
// Reads from the given file. Returns false in case of error.
bool Shape::DeSerialize(TFile* fp) {
uint8_t sorted;
if (fp->FRead(&sorted, sizeof(sorted), 1) != 1) return false;
if (!fp->DeSerialize(&sorted)) return false;
unichars_sorted_ = sorted != 0;
return unichars_.DeSerializeClasses(fp);
}