/*************************************************************************** chathistorywriter.h - chat logs writer ------------------- begin : Tue Jul 13 2010 copyright : (C) 2010 by Valerio Pilo email : valerio@kmess.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHATHISTORYWRITER_H #define CHATHISTORYWRITER_H #include <QFile> #include <QtCore/QObject> /** * Maximum log file size, 4MB. */ const long MAX_LOG_FILE_SIZE = 4L * 1024L * 1024L; // Forward declarations class ChatMessage; class ChatMessageStyle; class Conversation; /** * Class to incrementally save a chat log in XML format to file. * * Every time a message arrives or is sent, it is parsed into XML and stored here. * * low level description: * As soon as a chat is opened, the xml log saving system choses a file name where * to store the log. * A quint64 pointer keeps track of the position in the file where to add new data. * When writing anything to the file, if the pointer is 0 a file header gets added; * then, if it is the first write of the chat, a first conversation tag is added with * the time of the first message and the pointer is set to the end of that data; then * the new data is written; finally, the XML conversation and messsageRoot closing tags * are also added. To ensure integrity, the file is flushed on every write. * * medium level description: * When someone sends a message, we store its XML into a cache, and also flush it into * the file, writing from the file pointer position. * When another message needs to be stored, we store its XML too into a cache, then flush * to the logfile a messagegroup tags pair, containing all previously stored XML messages, * and finally we check if it's applicable for message grouping: * - if it is, do nothing (we'll continue stacking up messages for the group) * - If it is not, empty the cache and set the pointer to the end of the written * messageGroup tags. We'll start with a new message or group. * As soon as the chat is closed, the file is already filled up and we can just close it. * * high level description: * a class (keeping the logging state) is instantiated. a startLogging( handle ) method is * called as soon as the chat is opened. * When a message arrives, a logMessage( ChatMessage* ) method is called. * When the chat is closed, an endLogging() method is called. * * @author Valerio Pilo <valerio@kmess.org> */ 00072 class ChatHistoryWriter : public QObject { Q_OBJECT friend class ChatHistoryManager; private: // Private constructor // Constructor ChatHistoryWriter( const QString& account, const QString& handle ); public: // Public destructor // Destructor virtual ~ChatHistoryWriter(); public: // Public methods // Return whether the writer is capable of writing new messages bool isReady() const; // Write a message to file void logMessage( const ChatMessage& message ); private: // Private methods // Write the cache contents to the file void writeCache(); private: // Private properties // Conversation data, used for chat history manager data caching Conversation* conversation_; // Handle of the initial contact of the chat being logged QString handle_; // Whether at least one message was written to the file bool isFirstMessage_; // Whether the log file was created just for the chat being logged bool isNewLogFile_; // The last received message, to avoid storing duplicates (not using the cache since it gets cleared often) ChatMessage* lastMessage_; // Log file where to save the chat QFile logFile_; // List of messages currently being processed QList<ChatMessage> messageCache_; // The chat style converter, used to turn chat messages into XML ChatMessageStyle* messageStyle_; // Last appending position within the file qint64 pointer_; }; #endif // CHATHISTORYWRITER_H