1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 //                          xdrIOBuffer.h
4 //------------------------------------------------------------------------------
5 //  Copyright (c) 2000,2005 by Vladislav Grinchenko
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Library General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //------------------------------------------------------------------------------
12 //  Created: 04/03/2000
13 //------------------------------------------------------------------------------
14 
15 #ifndef XDR_IO_BUFFER_H
16 #define XDR_IO_BUFFER_H
17 
18 #include "assa/Assure.h"
19 #include "assa/Socket.h"
20 #include "assa/IPv4Socket.h"
21 
22 #include <string>
23 
24 namespace ASSA {
25 
26 /** @file xdrIOBuffer.h
27  *
28  * This class allows to read XDR-encoded data from Socket stream asynchronously
29  * and then read from it as if from a stream of intermixed strings, integers
30  * and floats. Data are XDR-decoded on a fly.
31  *
32  * Testing xdrIOBuffer object in conditional statement will produce
33  * false if:
34  *
35  *     - Not entire buffer has been read yet.
36  *     - Socket stream exceptional condition occured.
37  *
38  * Thus, data accumulation and data decoding functions are separated.
39  *
40  * Initially, buffer is in waiting state. In this state,
41  * xdrIOBuffer object waits for bytes from the Socket stream.
42  *
43  * When buffer object becomes full, the state is switched to
44  * xmitted. Now, an application code can read data
45  * from the buffer. The data will be XDR-decoded.
46  *
47  * xdrIOBuffer object yields TRUE in conditional statements only
48  * in xmitted state. In other words, buffer is TRUE if
49  * it is full, and FALSE otherwise.
50  *
51  * xdrIOBuffer can be used only once. You cannot "rewind", and therefore
52  * reuse it.
53  */
54 
55 class xdrIOBuffer
56 {
57 public:
58 	/** @enum state_t
59 	 */
60 	enum state_t {
61 		waiting,
62 		xmitted,
63 		parsed,
64 		error
65 	};
66 
67 	/** Constructor.
68 	 */
69 	xdrIOBuffer (u_int len_);
70 
71 	/** Destructor.
72          */
73 	~xdrIOBuffer ();
74 
75 	/** Copy constructor
76 	 */
77 	xdrIOBuffer (const xdrIOBuffer& rhs_);
78 
79 	/** Assign operator.
80 	 */
81 	xdrIOBuffer& operator= (const xdrIOBuffer& rhs_);
82 
83 	/** Read raw data from Socket nonblocking and
84 	 *  store into internal buffer.
85 	 */
86 	friend Socket& operator>>(Socket& src_, xdrIOBuffer& dest_);
87 
88 	/** Read and XDR-decode STL string from the buffer.
89 	 */
90 	xdrIOBuffer& operator>>(std::string&);
91 
92 	/** Read and XDR-decode an integer from the buffer.
93 	 */
94 	xdrIOBuffer& operator>>(int&);
95 
96 	/** Read and XDR-decode a float from the buffer.
97 	 */
98 	xdrIOBuffer& operator>>(float&);
99 
100 	/** Convertion to void* (for testing where bool is required).
101 	 */
102 	operator void*() const;
103 
104 	/** Give verbal interpretation of object's state.
105 	 */
106 	string get_state () const;
107 
108 	/** Return number of bytes in xdrIOBuffer. In <b>waiting</b>
109 	    state it's bytes transmitted so far. In <b>xmitted</b> state,
110 	    number of bytes left to decode.
111 	 */
112 	int size () const;
113 
114 	/** Return buffer (maximum expected/allowable) size.
115 	 */
116 	int buffer_size () const;
117 
118 	/** Return pointer to the first byte of xdrIOBuffer.
119 	 */
120 	const char* str () const;
121 
122 	/** Clear up the internal buffer and reset state to
123 		<b>waiting</b>.
124 	*/
125 	void reset ();
126 
127 	/** Dump object's internal state to the log file
128 	 */
129 	void dump () const;
130 
131 protected:
132 	/// Copy object from argument
133 	void copy (const xdrIOBuffer&);
134 
135 private:
136 	/// Buffer
137 	char* m_buf;
138 
139 	/// Buffer size and maximum expected size
140 	int m_sz;
141 
142 	/// Pointer for next I/O operation into the buffer
143 	char* m_ptr;
144 
145 	/// Object state
146 	state_t m_state;
147 };
148 
149 inline
150 xdrIOBuffer::
xdrIOBuffer(const xdrIOBuffer & rhs_)151 xdrIOBuffer (const xdrIOBuffer& rhs_)
152 {
153 	trace_with_mask("xdrIOBuffer::xdrIOBuffer(xdrIOBuffer&)", XDRBUFTRACE);
154 
155 	copy (rhs_);
156 }
157 
158 inline
159 xdrIOBuffer::
160 operator void*() const
161 {
162 	trace_with_mask("xdrIOBuffer::opt void*()", XDRBUFTRACE);
163 
164 	return (m_state == waiting || m_state == parsed)
165 		? (void *)0	// bad state
166 		: (void *)(-1); // good state
167 }
168 
169 inline int
170 xdrIOBuffer::
size()171 size () const
172 {
173 	return (m_ptr - m_buf);
174 }
175 
176 inline int
177 xdrIOBuffer::
buffer_size()178 buffer_size () const
179 {
180 	return (m_sz);
181 }
182 
183 inline const char*
184 xdrIOBuffer::
str()185 str () const
186 {
187 	return ((const char*) m_buf);
188 }
189 
190 } // end namespace ASSA
191 
192 #endif /* XDR_IO_BUFFER_H */
193