/src/tesseract/src/ccutil/serialis.h
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************** |
2 | | * File: serialis.h (Formerly serialmac.h) |
3 | | * Description: Inline routines and macros for serialisation functions |
4 | | * Author: Phil Cheatle |
5 | | * |
6 | | * (C) Copyright 1990, Hewlett-Packard Ltd. |
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 SERIALIS_H |
20 | | #define SERIALIS_H |
21 | | |
22 | | #include <tesseract/baseapi.h> // FileReader |
23 | | #include <cstdint> // uint8_t |
24 | | #include <cstdio> |
25 | | #include <cstdlib> |
26 | | #include <cstring> |
27 | | #include <type_traits> |
28 | | #include <vector> // std::vector |
29 | | |
30 | | namespace tesseract { |
31 | | |
32 | | // Return number of elements of an array. |
33 | | template <typename T, size_t N> |
34 | 0 | constexpr size_t countof(T const (&)[N]) noexcept { |
35 | 0 | return N; |
36 | 0 | } Unexecuted instantiation: unsigned long tesseract::countof<double, 7ul>(double const (&) [7ul]) Unexecuted instantiation: unsigned long tesseract::countof<long, 24ul>(long const (&) [24ul]) |
37 | | |
38 | | // Function to write a std::vector<char> to a whole file. |
39 | | // Returns false on failure. |
40 | | using FileWriter = bool (*)(const std::vector<char> &data, const char *filename); |
41 | | |
42 | | TESS_API |
43 | | bool LoadDataFromFile(const char *filename, std::vector<char> *data); |
44 | | TESS_API |
45 | | bool SaveDataToFile(const std::vector<char> &data, const char *filename); |
46 | | |
47 | | // Deserialize data from file. |
48 | | template <typename T> |
49 | 0 | bool DeSerialize(FILE *fp, T *data, size_t n = 1) { |
50 | 0 | return fread(data, sizeof(T), n, fp) == n; |
51 | 0 | } Unexecuted instantiation: bool tesseract::DeSerialize<short>(_IO_FILE*, short*, unsigned long) Unexecuted instantiation: bool tesseract::DeSerialize<unsigned int>(_IO_FILE*, unsigned int*, unsigned long) |
52 | | |
53 | | // Serialize data to file. |
54 | | template <typename T> |
55 | 0 | bool Serialize(FILE *fp, const T *data, size_t n = 1) { |
56 | 0 | return fwrite(data, sizeof(T), n, fp) == n; |
57 | 0 | } Unexecuted instantiation: bool tesseract::Serialize<char>(_IO_FILE*, char const*, unsigned long) Unexecuted instantiation: bool tesseract::Serialize<short>(_IO_FILE*, short const*, unsigned long) Unexecuted instantiation: bool tesseract::Serialize<int>(_IO_FILE*, int const*, unsigned long) Unexecuted instantiation: bool tesseract::Serialize<unsigned char>(_IO_FILE*, unsigned char const*, unsigned long) Unexecuted instantiation: bool tesseract::Serialize<unsigned int>(_IO_FILE*, unsigned int const*, unsigned long) |
58 | | |
59 | | // Simple file class. |
60 | | // Allows for portable file input from memory and from foreign file systems. |
61 | | class TESS_API TFile { |
62 | | public: |
63 | | TFile(); |
64 | | ~TFile(); |
65 | | |
66 | | // All the Open methods load the whole file into memory for reading. |
67 | | // Opens a file with a supplied reader, or nullptr to use the default. |
68 | | // Note that mixed read/write is not supported. |
69 | | bool Open(const char *filename, FileReader reader); |
70 | | // From an existing memory buffer. |
71 | | bool Open(const char *data, size_t size); |
72 | | // From an open file and an end offset. |
73 | | bool Open(FILE *fp, int64_t end_offset); |
74 | | // Sets the value of the swap flag, so that FReadEndian does the right thing. |
75 | 72 | void set_swap(bool value) { |
76 | 72 | swap_ = value; |
77 | 72 | } |
78 | | |
79 | | // Deserialize data. |
80 | | bool DeSerializeSize(int32_t *data); |
81 | | bool DeSerializeSkip(size_t size = 1); |
82 | | bool DeSerialize(std::string &data); |
83 | | bool DeSerialize(std::vector<char> &data); |
84 | | //bool DeSerialize(std::vector<std::string> &data); |
85 | | template <typename T> |
86 | 151k | bool DeSerialize(T *data, size_t count = 1) { |
87 | 151k | return FReadEndian(data, sizeof(T), count) == count; |
88 | 151k | } bool tesseract::TFile::DeSerialize<int>(int*, unsigned long) Line | Count | Source | 86 | 46.1k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 46.1k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 46.1k | } |
bool tesseract::TFile::DeSerialize<signed char>(signed char*, unsigned long) Line | Count | Source | 86 | 748 | bool DeSerialize(T *data, size_t count = 1) { | 87 | 748 | return FReadEndian(data, sizeof(T), count) == count; | 88 | 748 | } |
bool tesseract::TFile::DeSerialize<unsigned int>(unsigned int*, unsigned long) Line | Count | Source | 86 | 32.2k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 32.2k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 32.2k | } |
bool tesseract::TFile::DeSerialize<unsigned char>(unsigned char*, unsigned long) Line | Count | Source | 86 | 28.2k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 28.2k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 28.2k | } |
bool tesseract::TFile::DeSerialize<short>(short*, unsigned long) Line | Count | Source | 86 | 28.9k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 28.9k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 28.9k | } |
bool tesseract::TFile::DeSerialize<unsigned short>(unsigned short*, unsigned long) Line | Count | Source | 86 | 4 | bool DeSerialize(T *data, size_t count = 1) { | 87 | 4 | return FReadEndian(data, sizeof(T), count) == count; | 88 | 4 | } |
bool tesseract::TFile::DeSerialize<char>(char*, unsigned long) Line | Count | Source | 86 | 1.88k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 1.88k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 1.88k | } |
bool tesseract::TFile::DeSerialize<long>(long*, unsigned long) Line | Count | Source | 86 | 4 | bool DeSerialize(T *data, size_t count = 1) { | 87 | 4 | return FReadEndian(data, sizeof(T), count) == count; | 88 | 4 | } |
bool tesseract::TFile::DeSerialize<float>(float*, unsigned long) Line | Count | Source | 86 | 28 | bool DeSerialize(T *data, size_t count = 1) { | 87 | 28 | return FReadEndian(data, sizeof(T), count) == count; | 88 | 28 | } |
bool tesseract::TFile::DeSerialize<double>(double*, unsigned long) Line | Count | Source | 86 | 12.7k | bool DeSerialize(T *data, size_t count = 1) { | 87 | 12.7k | return FReadEndian(data, sizeof(T), count) == count; | 88 | 12.7k | } |
bool tesseract::TFile::DeSerialize<unsigned long>(unsigned long*, unsigned long) Line | Count | Source | 86 | 32 | bool DeSerialize(T *data, size_t count = 1) { | 87 | 32 | return FReadEndian(data, sizeof(T), count) == count; | 88 | 32 | } |
|
89 | | template <typename T> |
90 | 28.6k | bool DeSerialize(std::vector<T> &data) { |
91 | 28.6k | uint32_t size; |
92 | 28.6k | if (!DeSerialize(&size)) { |
93 | 0 | return false; |
94 | 28.6k | } else if (size == 0) { |
95 | 4 | data.clear(); |
96 | 28.6k | } else if (size > 50000000) { |
97 | | // Arbitrarily limit the number of elements to protect against bad data. |
98 | 0 | return false; |
99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { |
100 | | // Deserialize a string. |
101 | | // TODO: optimize. |
102 | 0 | data.resize(size); |
103 | 0 | for (auto &item : data) { |
104 | 0 | if (!DeSerialize(item)) { |
105 | 0 | return false; |
106 | 0 | } |
107 | 0 | } |
108 | 14.0k | } else if constexpr (std::is_class<T>::value) { |
109 | | // Deserialize a tesseract class. |
110 | | // TODO: optimize. |
111 | 14.0k | data.resize(size); |
112 | 14.5k | for (auto &item : data) { |
113 | 14.5k | if (!item.DeSerialize(this)) { |
114 | 0 | return false; |
115 | 0 | } |
116 | 14.5k | } |
117 | 14.0k | } else if constexpr (std::is_pointer<T>::value) { |
118 | | // Deserialize pointers. |
119 | | // TODO: optimize. |
120 | 4 | data.resize(size); |
121 | 14.0k | for (uint32_t i = 0; i < size; i++) { |
122 | 14.0k | uint8_t non_null; |
123 | 14.0k | if (!DeSerialize(&non_null)) { |
124 | 0 | return false; |
125 | 0 | } |
126 | 14.0k | if (non_null) { |
127 | 14.0k | typedef typename std::remove_pointer<T>::type ST; |
128 | 14.0k | auto item = new ST; |
129 | 14.0k | if (!item->DeSerialize(this)) { |
130 | 0 | delete item; |
131 | 0 | return false; |
132 | 0 | } |
133 | 14.0k | data[i] = item; |
134 | 14.0k | } |
135 | 14.0k | } |
136 | 14.5k | } else { |
137 | | // Deserialize a non-class. |
138 | | // TODO: optimize. |
139 | 14.5k | data.resize(size); |
140 | 14.5k | return DeSerialize(&data[0], size); |
141 | 14.5k | } |
142 | 28.6k | return true; |
143 | 28.6k | } Unexecuted instantiation: bool tesseract::TFile::DeSerialize<tesseract::TBOX>(std::__1::vector<tesseract::TBOX, std::__1::allocator<tesseract::TBOX> >&) Unexecuted instantiation: bool tesseract::TFile::DeSerialize<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&) bool tesseract::TFile::DeSerialize<unsigned short>(std::__1::vector<unsigned short, std::__1::allocator<unsigned short> >&) Line | Count | Source | 90 | 4 | bool DeSerialize(std::vector<T> &data) { | 91 | 4 | uint32_t size; | 92 | 4 | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 4 | } else if (size == 0) { | 95 | 0 | data.clear(); | 96 | 4 | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | | data.resize(size); | 112 | | for (auto &item : data) { | 113 | | if (!item.DeSerialize(this)) { | 114 | | return false; | 115 | | } | 116 | | } | 117 | | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | | data.resize(size); | 121 | | for (uint32_t i = 0; i < size; i++) { | 122 | | uint8_t non_null; | 123 | | if (!DeSerialize(&non_null)) { | 124 | | return false; | 125 | | } | 126 | | if (non_null) { | 127 | | typedef typename std::remove_pointer<T>::type ST; | 128 | | auto item = new ST; | 129 | | if (!item->DeSerialize(this)) { | 130 | | delete item; | 131 | | return false; | 132 | | } | 133 | | data[i] = item; | 134 | | } | 135 | | } | 136 | 4 | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | 4 | data.resize(size); | 140 | 4 | return DeSerialize(&data[0], size); | 141 | 4 | } | 142 | 4 | return true; | 143 | 4 | } |
bool tesseract::TFile::DeSerialize<int>(std::__1::vector<int, std::__1::allocator<int> >&) Line | Count | Source | 90 | 14.5k | bool DeSerialize(std::vector<T> &data) { | 91 | 14.5k | uint32_t size; | 92 | 14.5k | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 14.5k | } else if (size == 0) { | 95 | 4 | data.clear(); | 96 | 14.5k | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | | data.resize(size); | 112 | | for (auto &item : data) { | 113 | | if (!item.DeSerialize(this)) { | 114 | | return false; | 115 | | } | 116 | | } | 117 | | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | | data.resize(size); | 121 | | for (uint32_t i = 0; i < size; i++) { | 122 | | uint8_t non_null; | 123 | | if (!DeSerialize(&non_null)) { | 124 | | return false; | 125 | | } | 126 | | if (non_null) { | 127 | | typedef typename std::remove_pointer<T>::type ST; | 128 | | auto item = new ST; | 129 | | if (!item->DeSerialize(this)) { | 130 | | delete item; | 131 | | return false; | 132 | | } | 133 | | data[i] = item; | 134 | | } | 135 | | } | 136 | 14.5k | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | 14.5k | data.resize(size); | 140 | 14.5k | return DeSerialize(&data[0], size); | 141 | 14.5k | } | 142 | 14.5k | return true; | 143 | 14.5k | } |
bool tesseract::TFile::DeSerialize<tesseract::UnicharAndFonts>(std::__1::vector<tesseract::UnicharAndFonts, std::__1::allocator<tesseract::UnicharAndFonts> >&) Line | Count | Source | 90 | 14.0k | bool DeSerialize(std::vector<T> &data) { | 91 | 14.0k | uint32_t size; | 92 | 14.0k | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 14.0k | } else if (size == 0) { | 95 | 0 | data.clear(); | 96 | 14.0k | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | 14.0k | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | 14.0k | data.resize(size); | 112 | 14.0k | for (auto &item : data) { | 113 | 14.0k | if (!item.DeSerialize(this)) { | 114 | 0 | return false; | 115 | 0 | } | 116 | 14.0k | } | 117 | | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | | data.resize(size); | 121 | | for (uint32_t i = 0; i < size; i++) { | 122 | | uint8_t non_null; | 123 | | if (!DeSerialize(&non_null)) { | 124 | | return false; | 125 | | } | 126 | | if (non_null) { | 127 | | typedef typename std::remove_pointer<T>::type ST; | 128 | | auto item = new ST; | 129 | | if (!item->DeSerialize(this)) { | 130 | | delete item; | 131 | | return false; | 132 | | } | 133 | | data[i] = item; | 134 | | } | 135 | | } | 136 | | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | | data.resize(size); | 140 | | return DeSerialize(&data[0], size); | 141 | | } | 142 | 14.0k | return true; | 143 | 14.0k | } |
bool tesseract::TFile::DeSerialize<tesseract::Shape*>(std::__1::vector<tesseract::Shape*, std::__1::allocator<tesseract::Shape*> >&) Line | Count | Source | 90 | 4 | bool DeSerialize(std::vector<T> &data) { | 91 | 4 | uint32_t size; | 92 | 4 | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 4 | } else if (size == 0) { | 95 | 0 | data.clear(); | 96 | 4 | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | | data.resize(size); | 112 | | for (auto &item : data) { | 113 | | if (!item.DeSerialize(this)) { | 114 | | return false; | 115 | | } | 116 | | } | 117 | 4 | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | 4 | data.resize(size); | 121 | 14.0k | for (uint32_t i = 0; i < size; i++) { | 122 | 14.0k | uint8_t non_null; | 123 | 14.0k | if (!DeSerialize(&non_null)) { | 124 | 0 | return false; | 125 | 0 | } | 126 | 14.0k | if (non_null) { | 127 | 14.0k | typedef typename std::remove_pointer<T>::type ST; | 128 | 14.0k | auto item = new ST; | 129 | 14.0k | if (!item->DeSerialize(this)) { | 130 | 0 | delete item; | 131 | 0 | return false; | 132 | 0 | } | 133 | 14.0k | data[i] = item; | 134 | 14.0k | } | 135 | 14.0k | } | 136 | | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | | data.resize(size); | 140 | | return DeSerialize(&data[0], size); | 141 | | } | 142 | 4 | return true; | 143 | 4 | } |
bool tesseract::TFile::DeSerialize<float>(std::__1::vector<float, std::__1::allocator<float> >&) Line | Count | Source | 90 | 16 | bool DeSerialize(std::vector<T> &data) { | 91 | 16 | uint32_t size; | 92 | 16 | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 16 | } else if (size == 0) { | 95 | 0 | data.clear(); | 96 | 16 | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | | data.resize(size); | 112 | | for (auto &item : data) { | 113 | | if (!item.DeSerialize(this)) { | 114 | | return false; | 115 | | } | 116 | | } | 117 | | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | | data.resize(size); | 121 | | for (uint32_t i = 0; i < size; i++) { | 122 | | uint8_t non_null; | 123 | | if (!DeSerialize(&non_null)) { | 124 | | return false; | 125 | | } | 126 | | if (non_null) { | 127 | | typedef typename std::remove_pointer<T>::type ST; | 128 | | auto item = new ST; | 129 | | if (!item->DeSerialize(this)) { | 130 | | delete item; | 131 | | return false; | 132 | | } | 133 | | data[i] = item; | 134 | | } | 135 | | } | 136 | 16 | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | 16 | data.resize(size); | 140 | 16 | return DeSerialize(&data[0], size); | 141 | 16 | } | 142 | 16 | return true; | 143 | 16 | } |
Unexecuted instantiation: bool tesseract::TFile::DeSerialize<short>(std::__1::vector<short, std::__1::allocator<short> >&) bool tesseract::TFile::DeSerialize<tesseract::RecodedCharID>(std::__1::vector<tesseract::RecodedCharID, std::__1::allocator<tesseract::RecodedCharID> >&) Line | Count | Source | 90 | 4 | bool DeSerialize(std::vector<T> &data) { | 91 | 4 | uint32_t size; | 92 | 4 | if (!DeSerialize(&size)) { | 93 | 0 | return false; | 94 | 4 | } else if (size == 0) { | 95 | 0 | data.clear(); | 96 | 4 | } else if (size > 50000000) { | 97 | | // Arbitrarily limit the number of elements to protect against bad data. | 98 | 0 | return false; | 99 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { | 100 | | // Deserialize a string. | 101 | | // TODO: optimize. | 102 | | data.resize(size); | 103 | | for (auto &item : data) { | 104 | | if (!DeSerialize(item)) { | 105 | | return false; | 106 | | } | 107 | | } | 108 | 4 | } else if constexpr (std::is_class<T>::value) { | 109 | | // Deserialize a tesseract class. | 110 | | // TODO: optimize. | 111 | 4 | data.resize(size); | 112 | 448 | for (auto &item : data) { | 113 | 448 | if (!item.DeSerialize(this)) { | 114 | 0 | return false; | 115 | 0 | } | 116 | 448 | } | 117 | | } else if constexpr (std::is_pointer<T>::value) { | 118 | | // Deserialize pointers. | 119 | | // TODO: optimize. | 120 | | data.resize(size); | 121 | | for (uint32_t i = 0; i < size; i++) { | 122 | | uint8_t non_null; | 123 | | if (!DeSerialize(&non_null)) { | 124 | | return false; | 125 | | } | 126 | | if (non_null) { | 127 | | typedef typename std::remove_pointer<T>::type ST; | 128 | | auto item = new ST; | 129 | | if (!item->DeSerialize(this)) { | 130 | | delete item; | 131 | | return false; | 132 | | } | 133 | | data[i] = item; | 134 | | } | 135 | | } | 136 | | } else { | 137 | | // Deserialize a non-class. | 138 | | // TODO: optimize. | 139 | | data.resize(size); | 140 | | return DeSerialize(&data[0], size); | 141 | | } | 142 | 4 | return true; | 143 | 4 | } |
|
144 | | |
145 | | // Serialize data. |
146 | | bool Serialize(const std::string &data); |
147 | | bool Serialize(const std::vector<char> &data); |
148 | | template <typename T> |
149 | 0 | bool Serialize(const T *data, size_t count = 1) { |
150 | 0 | return FWrite(data, sizeof(T), count) == count; |
151 | 0 | } Unexecuted instantiation: bool tesseract::TFile::Serialize<char>(char const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<int>(int const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<signed char>(signed char const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<unsigned int>(unsigned int const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<unsigned char>(unsigned char const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<short>(short const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<long>(long const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<float>(float const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<double>(double const*, unsigned long) Unexecuted instantiation: bool tesseract::TFile::Serialize<unsigned long>(unsigned long const*, unsigned long) |
152 | | template <typename T> |
153 | 0 | bool Serialize(const std::vector<T> &data) { |
154 | | // Serialize number of elements first. |
155 | 0 | uint32_t size = data.size(); |
156 | 0 | if (!Serialize(&size)) { |
157 | 0 | return false; |
158 | 0 | } else if constexpr (std::is_same<T, std::string>::value) { |
159 | | // Serialize strings. |
160 | 0 | for (auto &&string : data) { |
161 | 0 | if (!Serialize(string)) { |
162 | 0 | return false; |
163 | 0 | } |
164 | 0 | } |
165 | 0 | } else if constexpr (std::is_class<T>::value) { |
166 | | // Serialize a tesseract class. |
167 | 0 | for (auto &item : data) { |
168 | 0 | if (!item.Serialize(this)) { |
169 | 0 | return false; |
170 | 0 | } |
171 | 0 | } |
172 | 0 | } else if constexpr (std::is_pointer<T>::value) { |
173 | | // Serialize pointers. |
174 | 0 | for (auto &item : data) { |
175 | 0 | uint8_t non_null = (item != nullptr); |
176 | 0 | if (!Serialize(&non_null)) { |
177 | 0 | return false; |
178 | 0 | } |
179 | 0 | if (non_null) { |
180 | 0 | if (!item->Serialize(this)) { |
181 | 0 | return false; |
182 | 0 | } |
183 | 0 | } |
184 | 0 | } |
185 | 0 | } else if (size > 0) { |
186 | | // Serialize a non-class. |
187 | 0 | return Serialize(&data[0], size); |
188 | 0 | } |
189 | 0 | return true; |
190 | 0 | } Unexecuted instantiation: bool tesseract::TFile::Serialize<tesseract::TBOX>(std::__1::vector<tesseract::TBOX, std::__1::allocator<tesseract::TBOX> > const&) Unexecuted instantiation: bool tesseract::TFile::Serialize<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) Unexecuted instantiation: bool tesseract::TFile::Serialize<tesseract::ImageData*>(std::__1::vector<tesseract::ImageData*, std::__1::allocator<tesseract::ImageData*> > const&) Unexecuted instantiation: bool tesseract::TFile::Serialize<float>(std::__1::vector<float, std::__1::allocator<float> > const&) Unexecuted instantiation: bool tesseract::TFile::Serialize<tesseract::RecodedCharID>(std::__1::vector<tesseract::RecodedCharID, std::__1::allocator<tesseract::RecodedCharID> > const&) |
191 | | |
192 | | // Skip data. |
193 | | bool Skip(size_t count); |
194 | | |
195 | | // Reads a line like fgets. Returns nullptr on EOF, otherwise buffer. |
196 | | // Reads at most buffer_size bytes, including '\0' terminator, even if |
197 | | // the line is longer. Does nothing if buffer_size <= 0. |
198 | | char *FGets(char *buffer, int buffer_size); |
199 | | // Replicates fread, followed by a swap of the bytes if needed, returning the |
200 | | // number of items read. If swap_ is true then the count items will each have |
201 | | // size bytes reversed. |
202 | | size_t FReadEndian(void *buffer, size_t size, size_t count); |
203 | | // Replicates fread, returning the number of items read. |
204 | | size_t FRead(void *buffer, size_t size, size_t count); |
205 | | // Resets the TFile as if it has been Opened, but nothing read. |
206 | | // Only allowed while reading! |
207 | | void Rewind(); |
208 | | |
209 | | // Open for writing. Either supply a non-nullptr data with OpenWrite before |
210 | | // calling FWrite, (no close required), or supply a nullptr data to OpenWrite |
211 | | // and call CloseWrite to write to a file after the FWrites. |
212 | | void OpenWrite(std::vector<char> *data); |
213 | | bool CloseWrite(const char *filename, FileWriter writer); |
214 | | |
215 | | // Replicates fwrite, returning the number of items written. |
216 | | // To use fprintf, use snprintf and FWrite. |
217 | | size_t FWrite(const void *buffer, size_t size, size_t count); |
218 | | |
219 | | private: |
220 | | // The buffered data from the file. |
221 | | std::vector<char> *data_ = nullptr; |
222 | | // The number of bytes used so far. |
223 | | unsigned offset_ = 0; |
224 | | // True if the data_ pointer is owned by *this. |
225 | | bool data_is_owned_ = false; |
226 | | // True if the TFile is open for writing. |
227 | | bool is_writing_ = false; |
228 | | // True if bytes need to be swapped in FReadEndian. |
229 | | bool swap_ = false; |
230 | | }; |
231 | | |
232 | | } // namespace tesseract. |
233 | | |
234 | | #endif |