messageheader.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_MESSAGEHEADER_H
31 #define TNT_MESSAGEHEADER_H
32 
33 #include <istream>
34 #include <string>
35 #include <cstring>
36 #include <utility>
37 
38 namespace tnt
39 {
42  {
43  public:
44  static const unsigned MAXHEADERSIZE = 4096;
45 
46  private:
47  char rawdata[MAXHEADERSIZE]; // key_1\0value_1\0key_2\0value_2\0...key_n\0value_n\0\0
48  unsigned endOffset;
49  char* getEnd() { return rawdata + endOffset; }
50 
51  public:
52  class Parser;
53  friend class Parser;
54 
55  typedef std::pair<const char*, const char*> value_type;
56 
58  : public std::iterator<std::forward_iterator_tag, value_type>
59  {
60  friend class Messageheader;
61 
62  value_type current_value;
63 
64  void fixup()
65  {
66  if (*current_value.first)
67  current_value.second = current_value.first + std::strlen(current_value.first) + 1;
68  else
69  current_value.first = current_value.second = 0;
70  }
71 
72  void moveForward()
73  {
74  current_value.first = current_value.second + std::strlen(current_value.second) + 1;
75  fixup();
76  }
77 
78  public:
80  : current_value(static_cast<const char*>(0), static_cast<const char*>(0))
81  { }
82 
83  explicit const_iterator(const char* p)
84  : current_value(p, p)
85  {
86  fixup();
87  }
88 
89  bool operator== (const const_iterator& it) const
90  { return current_value.first == it.current_value.first; }
91 
92  bool operator!= (const const_iterator& it) const
93  { return current_value.first != it.current_value.first; }
94 
96  {
97  moveForward();
98  return *this;
99  }
100 
102  {
103  const_iterator ret = *this;
104  moveForward();
105  return ret;
106  }
107 
108  const value_type& operator* () const { return current_value; }
109  const value_type* operator-> () const { return &current_value; }
110  };
111 
112  protected:
114  {
115  OK,
118  };
119 
120  virtual return_type onField(const char* name, const char* value);
121 
122  public:
124  { clear(); }
125 
126  virtual ~Messageheader() { }
127 
129  { return const_iterator(rawdata); }
131  { return const_iterator(); }
132 
133  const_iterator find(const char* key) const;
134  const_iterator find(const std::string& key) const
135  { return find(key.c_str()); }
136 
137  bool hasHeader(const char* key) const
138  { return find(key) != end(); }
139  bool hasHeader(const std::string& key) const
140  { return hasHeader(key.c_str()); }
141 
142  bool compareHeader(const char* key, const char* value) const;
143  bool compareHeader(const std::string& key, const std::string& value) const
144  { return compareHeader(key.c_str(), value.c_str()); }
145 
146  void removeHeader(const char* key);
147  void removeHeader(const std::string& key)
148  { removeHeader(key.c_str()); }
149 
150  void clear();
151 
152  void setHeader(const char* key, const char* value, bool replace);
153 
154  void setHeader(const std::string& key, const std::string& value, bool replace)
155  { setHeader(key.c_str(), value.c_str(), replace); }
156  };
157 
158  std::istream& operator>> (std::istream& in, Messageheader& data);
159 
160 }
161 
162 #endif // TNT_MESSAGEHEADER_H
163