KISSCPP
a C++ library for rapid application development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
persisted_queue.hpp
Go to the documentation of this file.
1 // File : persisted_queue.hpp
2 // Author: Dirk J. Botha <bothadj@gmail.com>
3 //
4 // This file is part of kisscpp library.
5 //
6 // The kisscpp library is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // The kisscpp library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with the kisscpp library. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef _PERSISTED_QUEUE_HPP_
20 #define _PERSISTED_QUEUE_HPP_
21 
22 #include <sstream>
23 #include <string>
24 #include <fstream>
25 #include <deque>
26 #include <algorithm>
27 #include <cerrno>
28 #include <ctime>
29 
30 #include <boost/noncopyable.hpp>
31 #include <boost/shared_ptr.hpp>
32 #include <boost/regex.hpp>
33 #include <boost/archive/iterators/base64_from_binary.hpp>
34 #include <boost/archive/iterators/binary_from_base64.hpp>
35 #include <boost/archive/iterators/transform_width.hpp>
36 #include <boost/archive/iterators/remove_whitespace.hpp>
37 #include <boost/filesystem/operations.hpp>
38 #include <boost/filesystem/path.hpp>
39 #include <boost/filesystem/exception.hpp>
40 
41 #include "logstream.hpp"
42 
43 //--------------------------------------------------------------------------------
44 using namespace boost::archive::iterators;
45 
46 namespace kisscpp
47 {
48 
49 //--------------------------------------------------------------------------------
50 template <class T>
52 {
53  public:
54  typedef transform_width< binary_from_base64<remove_whitespace<std::string::const_iterator> > , 8, 6 > BinaryType;
55  typedef base64_from_binary<transform_width<std::string::const_iterator,6,8> > Base64Type;
56 
59 
60  virtual boost::shared_ptr<std::string> encode(const boost::shared_ptr<T> obj2encode) = 0;
61  virtual boost::shared_ptr<T> decode(const std::string& str2decode) = 0;
62 
63  protected:
64  boost::shared_ptr<std::string> encodeToBase64String(const std::string& s)
65  {
66  LogStream log(__PRETTY_FUNCTION__);
67  unsigned int writePaddChars = (3 - s.length() % 3) % 3;
68  boost::shared_ptr<std::string> base64;
69 
70  base64.reset(new std::string(Base64Type(s.begin()),Base64Type(s.end())));
71 
72  base64->append(writePaddChars,'=');
73 
74  return base64;
75  }
76 
77  boost::shared_ptr<std::string> decodeFromBase64(const std::string& s)
78  {
79  LogStream log(__PRETTY_FUNCTION__);
80  unsigned int paddChars = count(s.begin(), s.end(), '=');
81  std::string is = s;
82  boost::shared_ptr<std::string> result;
83 
84  log << manip::debug_normal << "base 64 string to decode : " << s << endl;
85 
86  if(is[is.size()-1] == '=') is[is.size()-1] = 'A';
87  if(is[is.size()-2] == '=') is[is.size()-2] = 'A';
88 
89  result.reset(new std::string(BinaryType(is.begin()), BinaryType(is.end()))); // decode
90 
91  result->erase(result->end()-paddChars,result->end()); // erase padding '\0' characters
92 
93  log << manip::debug_normal << "decoded base 64 string: " << result->c_str() << endl;
94 
95  return result;
96  }
97 
98  private:
99 };
100 
101 //--------------------------------------------------------------------------------
102 // These define statements exist for code readabililty purposes
103 // Normally they should be typedef statements, but this is a templitized class.
104 // There are probably better ways of dealing with this, but I'm rather pushed for
105 // time right now, and this is cleanest, most convenient solution available to me.
106 #define QueuedObjectPointerType boost::shared_ptr<_qoT >
107 #define QueueType std::deque<QueuedObjectPointerType >
108 #define QueueTypePtr boost::shared_ptr<QueueType >
109 #define QueueTypeIterator typename std::deque<boost::shared_ptr<_qoT > >::iterator
110 #define value_type QueueType::value_type
111 
112 //--------------------------------------------------------------------------------
113 template <class _qoT, class _sT>
114 class PersistedQueue : public boost::noncopyable
115 {
116  public:
117  PersistedQueue(const std::string& queueName,
118  const std::string& queueWorkingDir,
119  const unsigned maxItemsPerPage);
121  ~PersistedQueue();
122 
123  void push_back (QueuedObjectPointerType p);
124  void push_front(QueuedObjectPointerType p);
125  QueuedObjectPointerType pop_front ();
126 
127  QueuedObjectPointerType front();
128  void clear();
129  bool empty();
130  size_t size();
131 
132  protected:
133 
134  private:
135  void setWorkingDirectory (std::string wdir);
136  void persistToFile (std::string seq, QueueTypePtr p);
137  QueueTypePtr loadFromFile (const std::string& path2File);
138  void load ();
139  void loadFirstAndLastPage ();
140  void loadPersistedFileNames();
141  void loadOrphanedQueueFiles();
142  void makeStateFilePath ();
143  bool stateFileExists ();
144  void loadStateFile ();
145  void writeFirstAndLastPage ();
146  void writeStateFile ();
147  std::string seqNumber ();
148 
149  std::string _queueName;
150  boost::filesystem::path _workingDirectory;
151  boost::filesystem::path _stateFilePath;
152  unsigned _maxItemsPerPage;
153  boost::regex _queueFileRegex;
154 
155  std::deque<std::string> persistedFileNames;
156 
157  QueueTypePtr firstPage;
158  QueueTypePtr lastPage;
159  QueueTypePtr swapPage;
160 
161  _sT biCoder;
162 };
163 
164 #include "persisted_queue.tpp"
165 
166 }
167 
168 #endif
169 
Definition: persisted_queue.hpp:114
Base64BiCoder()
Definition: persisted_queue.hpp:57
Definition: persisted_queue.hpp:51
transform_width< binary_from_base64< remove_whitespace< std::string::const_iterator > >, 8, 6 > BinaryType
Definition: persisted_queue.hpp:54
#define QueuedObjectPointerType
Definition: persisted_queue.hpp:106
bool empty()
Definition: persisted_queue.hpp:128
base64_from_binary< transform_width< std::string::const_iterator, 6, 8 > > Base64Type
Definition: persisted_queue.hpp:55
~Base64BiCoder()
Definition: persisted_queue.hpp:58
LogStream & debug_normal(LogStream &s, const bool permanent=false)
Definition: logstream.hpp:353
Definition: logstream.hpp:145
boost::shared_ptr< std::string > decodeFromBase64(const std::string &s)
Definition: persisted_queue.hpp:77
#define QueueTypePtr
Definition: persisted_queue.hpp:108
LogStream & endl(LogStream &s)
Definition: logstream.hpp:328