1 /*
2 * This file is part of StarDict.
3 *
4 * StarDict is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * StarDict is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with StarDict. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
21
22 #include <algorithm>
23 #include <errno.h>
24 #include <cstring>
25 #include "lib_common_dict.h"
26
clear(void)27 void article_data_t::clear(void)
28 {
29 key.clear();
30 synonyms.clear();
31 definitions.clear();
32 }
33
34 /* Return value:
35 * EXIT_FAILURE - key already exists
36 * EXIT_SUCCESS - key added
37 * */
add_key(const std::string & new_key)38 int article_data_t::add_key(const std::string& new_key)
39 {
40 if(new_key.empty())
41 return EXIT_FAILURE;
42 if(key == new_key)
43 return EXIT_FAILURE;
44 if(std::find(synonyms.begin(), synonyms.end(), new_key) != synonyms.end())
45 return EXIT_FAILURE;
46 if(key.empty()) {
47 key = new_key;
48 return EXIT_SUCCESS;
49 }
50 synonyms.push_back(new_key);
51 return EXIT_SUCCESS;
52 }
53
54 /* Return value:
55 * EXIT_FAILURE - key or synonym already exists
56 * EXIT_SUCCESS - synonym added
57 * */
add_synonym(const std::string & new_synonym)58 int article_data_t::add_synonym(const std::string& new_synonym)
59 {
60 if(new_synonym.empty())
61 return EXIT_FAILURE;
62 if(key == new_synonym)
63 return EXIT_FAILURE;
64 if(std::find(synonyms.begin(), synonyms.end(), new_synonym) != synonyms.end())
65 return EXIT_FAILURE;
66 synonyms.push_back(new_synonym);
67 return EXIT_SUCCESS;
68 }
69
70 /* Return value:
71 * EXIT_FAILURE or EXIT_SUCCESS */
add_definition(const article_def_t & def)72 int article_data_t::add_definition(const article_def_t& def)
73 {
74 definitions.push_back(def);
75 return EXIT_SUCCESS;
76 }
77
common_dict_t(void)78 common_dict_t::common_dict_t(void)
79 :
80 lot_of_memory(false)
81 {
82
83 }
84
85 /* clean articles
86 * prepare a new file to write data */
reset(void)87 int common_dict_t::reset(void)
88 {
89 articles.clear();
90 // First close the previous temporary file, otherwise we'll cannot remove it.
91 contents_file.reset(NULL);
92 contents_file_name.clear();
93 data_store.clear();
94 if(!lot_of_memory) {
95 contents_file_name = contents_file_creator.create_temp_file();
96 if(contents_file_name.empty())
97 return EXIT_FAILURE;
98 // open file for reading and writing
99 contents_file.reset(g_fopen(contents_file_name.c_str(), "wb+"));
100 if(!contents_file) {
101 g_critical(create_temp_file_err, contents_file_name.c_str());
102 return EXIT_FAILURE;
103 }
104 }
105 dict_info.clear();
106 return EXIT_SUCCESS;
107 }
108
109 /* write data to contents file.
110 * set offset to the beginning of the record in the file */
write_data(const char * data,size_t size,size_t & offset)111 int common_dict_t::write_data(const char* data, size_t size, size_t& offset)
112 {
113 if(!data || size == 0) {
114 g_critical(incorrect_arg_err);
115 return EXIT_FAILURE;
116 }
117 if(lot_of_memory) {
118 offset = data_store.size();
119 data_store.resize(data_store.size()+size);
120 memcpy(&data_store[offset], data, size);
121 } else {
122 if(fseek(get_impl(contents_file), 0, SEEK_END)) {
123 std::string error(g_strerror(errno));
124 g_critical(read_file_err, contents_file_name.c_str(), error.c_str());
125 return EXIT_FAILURE;
126 }
127 offset = ftell(get_impl(contents_file));
128 if(1 != fwrite(data, size, 1, get_impl(contents_file))) {
129 g_critical(write_file_err, contents_file_name.c_str());
130 return EXIT_FAILURE;
131 }
132 }
133 return EXIT_SUCCESS;
134 }
135
136 /* read data from contents file
137 * offset - offset of the first byte in the file,
138 * size - size of the data in bytes
139 * data - where to save data, must point to a buffer of enough size */
read_data(char * data,size_t size,size_t offset)140 int common_dict_t::read_data(char* data, size_t size, size_t offset)
141 {
142 if(!data || size == 0) {
143 g_critical(incorrect_arg_err);
144 return EXIT_FAILURE;
145 }
146 if(lot_of_memory) {
147 if(offset+size > data_store.size())
148 return EXIT_FAILURE;
149 memcpy(data, &data_store[offset], size);
150 } else {
151 if(fseek(get_impl(contents_file), offset, SEEK_SET)) {
152 std::string error(g_strerror(errno));
153 g_critical(read_file_err, contents_file_name.c_str(), error.c_str());
154 return EXIT_FAILURE;
155 }
156 if(1 != fread(data, size, 1, get_impl(contents_file))) {
157 std::string error(g_strerror(errno));
158 g_critical(read_file_err, contents_file_name.c_str(), error.c_str());
159 return EXIT_FAILURE;
160 }
161 }
162 return EXIT_SUCCESS;
163 }
164
add_article(const article_data_t & article)165 int common_dict_t::add_article(const article_data_t& article)
166 {
167 articles.push_back(article);
168 return EXIT_SUCCESS;
169 }
170