VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
glinebuffer.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file glinebuffer.h
19 ///
20 
21 #ifndef G_LINE_BUFFER_H
22 #define G_LINE_BUFFER_H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gexception.h"
27 #include <string>
28 
29 namespace GNet
30 {
31  class LineBuffer ;
32  class LineBufferIterator ;
33 }
34 
35 /// \class GNet::LineBuffer
36 /// A class which does line buffering. Raw data is added, and newline-delimited
37 /// lines are extracted via an iterator.
38 ///
39 /// Usage:
40 /// \code
41 /// {
42 /// GNet::LineBuffer buffer ;
43 /// buffer.add("abc") ;
44 /// buffer.add("def\nABC\nDE") ;
45 /// buffer.add("F\n") ;
46 /// GNet::LineBufferIterator iter( buffer ) ;
47 /// while( iter.more() )
48 /// cout << iter.line() << endl ;
49 /// }
50 /// \endcode
51 ///
53 {
54 public:
55  G_EXCEPTION( Error , "line buffer error" ) ;
56 
57  LineBuffer() ;
58  ///< Default constructor for a line buffer that auto-detects either
59  ///< CR or CR-LF line endings based on the first line.
60 
61  explicit LineBuffer( const std::string & eol , bool do_throw_on_overflow = false ) ;
62  ///< Constructor. The default is to not throw on overflow because
63  ///< the very large overflow limit is only intended to be protection
64  ///< against a rogue client or a denial-of-service attack.
65 
66  void add( const std::string & segment ) ;
67  ///< Adds a data segment.
68 
69  void add( const char * p , std::string::size_type n ) ;
70  ///< Adds a data segment.
71 
72  const std::string & eol() const ;
73  ///< Returns the line-ending.
74 
75  void expect( size_t n ) ;
76  ///< The next 'n' bytes added and/or extracted are treated as a
77  ///< complete line. This is useful for binary chunks of known
78  ///< size surrounded by text, as in http.
79 
80 private:
81  friend class LineBufferIterator ;
82  LineBuffer( const LineBuffer & ) ;
83  void operator=( const LineBuffer & ) ;
84  size_t lock( LineBufferIterator * ) ;
85  void unlock( LineBufferIterator * , size_t , size_t ) ;
86  bool check( size_t ) const ;
87  void detect() ;
88 
89 private:
90  LineBufferIterator * m_iterator ;
91  bool m_auto ;
92  std::string m_eol ;
93  bool m_throw_on_overflow ;
94  std::string m_store ;
95  size_t m_expect ;
96 } ;
97 
98 /// \class GNet::LineBufferIterator
99 /// An iterator class for GNet::LineBuffer that extracts complete lines.
100 /// Iteration and add()ing should not be mixed.
101 ///
103 {
104 public:
105  explicit LineBufferIterator( LineBuffer & ) ;
106  ///< Constructor.
107 
109  ///< Destructor.
110 
111  bool more() ;
112  ///< Returns true if there is a line() to be had.
113 
114  const std::string & line() const ;
115  ///< Returns the current line.
116  ///< Precondition: more()
117 
118  std::string::const_iterator begin() const ;
119  ///< Returns a begin iterator for the current line.
120  ///< Precondition: more()
121 
122  std::string::const_iterator end() const ;
123  ///< Returns an end iterator for the current line.
124  ///< Precondition: more()
125 
126 private:
127  friend class LineBuffer ;
129  void operator=( const LineBufferIterator & ) ;
130  void expect( size_t ) ;
131 
132 private:
133  LineBuffer & m_buffer ;
134  size_t m_expect ;
135  std::string::size_type m_pos ;
136  std::string::size_type m_eol_size ;
137  std::string::const_iterator m_line_begin ;
138  std::string::const_iterator m_line_end ;
139  mutable std::string m_line ;
140  mutable bool m_line_valid ;
141 } ;
142 
143 #endif
const std::string & eol() const
Returns the line-ending.
void add(const std::string &segment)
Adds a data segment.
Definition: glinebuffer.cpp:79
void expect(size_t n)
The next 'n' bytes added and/or extracted are treated as a complete line.
Definition: glinebuffer.cpp:84
std::string::const_iterator end() const
Returns an end iterator for the current line.
An iterator class for GNet::LineBuffer that extracts complete lines.
Definition: glinebuffer.h:102
LineBuffer()
Default constructor for a line buffer that auto-detects either CR or CR-LF line endings based on the ...
Definition: glinebuffer.cpp:30
LineBufferIterator(LineBuffer &)
Constructor.
~LineBufferIterator()
Destructor.
std::string::const_iterator begin() const
Returns a begin iterator for the current line.
const std::string & line() const
Returns the current line.
A class which does line buffering.
Definition: glinebuffer.h:52
bool more()
Returns true if there is a line() to be had.