3 * Library to deal with pinyin.
5 * Copyright (C) 2011 Peng Wu <alexepico@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #ifndef PHRASE_LOGGER_H
24 #define PHRASE_LOGGER_H
27 #include "novel_types.h"
28 #include "memory_chunk.h"
32 * Logger Record type: add/remove/modify
34 * Modify Header: header/null token/len/old data chunk/new data chunk
36 * Add Record: add/token/len/data chunk
37 * Remove Record: remove/token/len/data chunk
38 * Modify Record: modify/token/old len/new len/old data chunk/new data chunk
55 * The logger of phrase index changes.
58 class PhraseIndexLogger{
60 MemoryChunk * m_chunk;
72 * PhraseIndexLogger::PhraseIndexLogger:
74 * The constructor of the PhraseIndexLogger.
77 PhraseIndexLogger():m_offset(0){
78 m_chunk = new MemoryChunk;
82 * PhraseIndexLogger::~PhraseIndexLogger:
84 * The destructor of the PhraseIndexLogger.
92 * PhraseIndexLogger::load:
93 * @chunk: the memory chunk of the logs.
94 * @returns: whether the load operation is successful.
96 * Load the logs from the memory chunk.
99 bool load(MemoryChunk * chunk) {
106 * PhraseIndexLogger::store:
107 * @new_chunk: the new memory chunk to store the logs.
108 * @returns: whether the store operation is successful.
110 * Store the logs to the new memory chunk.
113 bool store(MemoryChunk * new_chunk){
114 new_chunk->set_content(0, m_chunk->begin(), m_chunk->size());
119 * PhraseIndexLogger::has_next_record:
120 * @returns: whether this logger has next record.
122 * Whether this logger has next record.
125 bool has_next_record(){
126 return m_offset < m_chunk->size();
130 * PhraseIndexLogger::rewind:
131 * @returns: whether the rewind operation is successful.
133 * Rewind this logger to the begin of logs.
142 * PhraseIndexLogger::next_record:
143 * @log_type: the type of this log record.
144 * @token: the token of this log record.
145 * @oldone: the original content of the phrase item.
146 * @newone: the new content of the phrase item.
148 * Read the next log record.
150 * Prolog: has_next_record() returned true.
153 bool next_record(LOG_TYPE & log_type, phrase_token_t & token,
154 MemoryChunk * oldone, MemoryChunk * newone){
155 size_t offset = m_offset;
156 m_chunk->get_content(offset, &log_type, sizeof(LOG_TYPE));
157 offset += sizeof(LOG_TYPE);
158 m_chunk->get_content(offset, &token, sizeof(phrase_token_t));
159 offset += sizeof(phrase_token_t);
161 oldone->set_size(0); newone->set_size(0);
164 case LOG_ADD_RECORD:{
166 m_chunk->get_content(offset, &len, sizeof(guint16));
167 offset += sizeof(guint16);
168 newone->set_content(0, ((char *)m_chunk->begin()) + offset, len);
172 case LOG_REMOVE_RECORD:{
174 m_chunk->get_content(offset, &len, sizeof(guint16));
175 offset += sizeof(guint16);
176 oldone->set_content(0, ((char *)m_chunk->begin()) + offset, len);
180 case LOG_MODIFY_RECORD:{
181 guint16 oldlen = 0, newlen = 0;
182 m_chunk->get_content(offset, &oldlen, sizeof(guint16));
183 offset += sizeof(guint16);
184 m_chunk->get_content(offset, &newlen, sizeof(guint16));
185 offset += sizeof(guint16);
186 oldone->set_content(0, ((char *)m_chunk->begin()) + offset,
189 newone->set_content(0, ((char *)m_chunk->begin()) + offset, newlen);
193 case LOG_MODIFY_HEADER:{
194 assert(token == null_token);
196 m_chunk->get_content(offset, &len, sizeof(guint16));
197 offset += sizeof(guint16);
198 oldone->set_content(0, ((char *)m_chunk->begin()) + offset,
201 newone->set_content(0, ((char *)m_chunk->begin()) + offset,
215 * PhraseIndexLogger::append_record:
216 * @log_type: the type of this log record.
217 * @token: the token of this log record.
218 * @oldone: the original content of the phrase item.
219 * @newone: the new content of the phrase item.
221 * Append one log record to the logger.
224 bool append_record(LOG_TYPE log_type, phrase_token_t token,
225 MemoryChunk * oldone, MemoryChunk * newone){
229 chunk.set_content(offset, &log_type, sizeof(LOG_TYPE));
230 offset += sizeof(LOG_TYPE);
231 chunk.set_content(offset, &token, sizeof(phrase_token_t));
232 offset += sizeof(phrase_token_t);
235 case LOG_ADD_RECORD:{
236 assert( NULL == oldone );
237 assert( NULL != newone );
238 /* use newone chunk */
239 guint16 len = newone->size();
240 chunk.set_content(offset, &len, sizeof(guint16));
241 offset += sizeof(guint16);
242 chunk.set_content(offset, newone->begin(), newone->size());
243 offset += newone->size();
246 case LOG_REMOVE_RECORD:{
247 assert(NULL != oldone);
248 assert(NULL == newone);
249 /* use oldone chunk */
250 guint16 len = oldone->size();
251 chunk.set_content(offset, &len, sizeof(guint16));
252 offset += sizeof(guint16);
253 chunk.set_content(offset, oldone->begin(), oldone->size());
254 offset += oldone->size();
257 case LOG_MODIFY_RECORD:{
258 assert(NULL != oldone);
259 assert(NULL != newone);
260 guint16 oldlen = oldone->size();
261 guint16 newlen = newone->size();
262 chunk.set_content(offset, &oldlen, sizeof(guint16));
263 offset += sizeof(guint16);
264 chunk.set_content(offset, &newlen, sizeof(guint16));
265 offset += sizeof(guint16);
266 chunk.set_content(offset, oldone->begin(), oldone->size());
268 chunk.set_content(offset, newone->begin(), newone->size());
272 case LOG_MODIFY_HEADER:{
273 assert(NULL != oldone);
274 assert(NULL != newone);
275 assert(null_token == token);
276 guint16 oldlen = oldone->size();
277 guint16 newlen = newone->size();
278 assert(oldlen == newlen);
279 chunk.set_content(offset, &oldlen, sizeof(guint16));
280 offset += sizeof(guint16);
281 chunk.set_content(offset, oldone->begin(), oldone->size());
283 chunk.set_content(offset, newone->begin(), newone->size());
291 /* store log record. */
292 m_chunk->set_content(m_chunk->size(), chunk.begin(), chunk.size());