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;
74 * PhraseIndexLogger::PhraseIndexLogger:
76 * The constructor of the PhraseIndexLogger.
79 PhraseIndexLogger():m_offset(0), m_error(false){
80 m_chunk = new MemoryChunk;
84 * PhraseIndexLogger::~PhraseIndexLogger:
86 * The destructor of the PhraseIndexLogger.
94 * PhraseIndexLogger::load:
95 * @chunk: the memory chunk of the logs.
96 * @returns: whether the load operation is successful.
98 * Load the logs from the memory chunk.
101 bool load(MemoryChunk * chunk) {
108 * PhraseIndexLogger::store:
109 * @new_chunk: the new memory chunk to store the logs.
110 * @returns: whether the store operation is successful.
112 * Store the logs to the new memory chunk.
115 bool store(MemoryChunk * new_chunk){
116 new_chunk->set_content(0, m_chunk->begin(), m_chunk->size());
121 * PhraseIndexLogger::has_next_record:
122 * @returns: whether this logger has next record.
124 * Whether this logger has next record.
127 bool has_next_record(){
131 return m_offset < m_chunk->size();
135 * PhraseIndexLogger::rewind:
136 * @returns: whether the rewind operation is successful.
138 * Rewind this logger to the begin of logs.
147 * PhraseIndexLogger::next_record:
148 * @log_type: the type of this log record.
149 * @token: the token of this log record.
150 * @oldone: the original content of the phrase item.
151 * @newone: the new content of the phrase item.
153 * Read the next log record.
155 * Prolog: has_next_record() returned true.
158 bool next_record(LOG_TYPE & log_type, phrase_token_t & token,
159 MemoryChunk * oldone, MemoryChunk * newone){
160 size_t offset = m_offset;
161 m_chunk->get_content(offset, &log_type, sizeof(LOG_TYPE));
162 offset += sizeof(LOG_TYPE);
163 m_chunk->get_content(offset, &token, sizeof(phrase_token_t));
164 offset += sizeof(phrase_token_t);
166 oldone->set_size(0); newone->set_size(0);
169 case LOG_ADD_RECORD:{
171 m_chunk->get_content(offset, &len, sizeof(guint16));
172 offset += sizeof(guint16);
173 newone->set_content(0, ((char *)m_chunk->begin()) + offset, len);
177 case LOG_REMOVE_RECORD:{
179 m_chunk->get_content(offset, &len, sizeof(guint16));
180 offset += sizeof(guint16);
181 oldone->set_content(0, ((char *)m_chunk->begin()) + offset, len);
185 case LOG_MODIFY_RECORD:{
186 guint16 oldlen = 0, newlen = 0;
187 m_chunk->get_content(offset, &oldlen, sizeof(guint16));
188 offset += sizeof(guint16);
189 m_chunk->get_content(offset, &newlen, sizeof(guint16));
190 offset += sizeof(guint16);
191 oldone->set_content(0, ((char *)m_chunk->begin()) + offset,
194 newone->set_content(0, ((char *)m_chunk->begin()) + offset, newlen);
198 case LOG_MODIFY_HEADER:{
199 assert(token == null_token);
201 m_chunk->get_content(offset, &len, sizeof(guint16));
202 offset += sizeof(guint16);
203 oldone->set_content(0, ((char *)m_chunk->begin()) + offset,
206 newone->set_content(0, ((char *)m_chunk->begin()) + offset,
221 * PhraseIndexLogger::append_record:
222 * @log_type: the type of this log record.
223 * @token: the token of this log record.
224 * @oldone: the original content of the phrase item.
225 * @newone: the new content of the phrase item.
227 * Append one log record to the logger.
230 bool append_record(LOG_TYPE log_type, phrase_token_t token,
231 MemoryChunk * oldone, MemoryChunk * newone){
235 chunk.set_content(offset, &log_type, sizeof(LOG_TYPE));
236 offset += sizeof(LOG_TYPE);
237 chunk.set_content(offset, &token, sizeof(phrase_token_t));
238 offset += sizeof(phrase_token_t);
241 case LOG_ADD_RECORD:{
242 assert( NULL == oldone );
243 assert( NULL != newone );
244 /* use newone chunk */
245 guint16 len = newone->size();
246 chunk.set_content(offset, &len, sizeof(guint16));
247 offset += sizeof(guint16);
248 chunk.set_content(offset, newone->begin(), newone->size());
249 offset += newone->size();
252 case LOG_REMOVE_RECORD:{
253 assert(NULL != oldone);
254 assert(NULL == newone);
255 /* use oldone chunk */
256 guint16 len = oldone->size();
257 chunk.set_content(offset, &len, sizeof(guint16));
258 offset += sizeof(guint16);
259 chunk.set_content(offset, oldone->begin(), oldone->size());
260 offset += oldone->size();
263 case LOG_MODIFY_RECORD:{
264 assert(NULL != oldone);
265 assert(NULL != newone);
266 guint16 oldlen = oldone->size();
267 guint16 newlen = newone->size();
268 chunk.set_content(offset, &oldlen, sizeof(guint16));
269 offset += sizeof(guint16);
270 chunk.set_content(offset, &newlen, sizeof(guint16));
271 offset += sizeof(guint16);
272 chunk.set_content(offset, oldone->begin(), oldone->size());
274 chunk.set_content(offset, newone->begin(), newone->size());
278 case LOG_MODIFY_HEADER:{
279 assert(NULL != oldone);
280 assert(NULL != newone);
281 assert(null_token == token);
282 guint16 oldlen = oldone->size();
283 guint16 newlen = newone->size();
284 assert(oldlen == newlen);
285 chunk.set_content(offset, &oldlen, sizeof(guint16));
286 offset += sizeof(guint16);
287 chunk.set_content(offset, oldone->begin(), oldone->size());
289 chunk.set_content(offset, newone->begin(), newone->size());
297 /* store log record. */
298 m_chunk->set_content(m_chunk->size(), chunk.begin(), chunk.size());