1 // Socket.h - a virtual IO channel, for Gnash
2 //
3 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 //   Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU 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 // This program 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 General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 
20 
21 #ifndef GNASH_SOCKET_H
22 #define GNASH_SOCKET_H
23 
24 #include "dsodefs.h"
25 #include <cstdint>
26 #include "IOChannel.h"
27 
28 namespace gnash {
29     class URL;
30 }
31 
32 namespace gnash {
33 
34 /// A simple IOChannel subclass for reading and writing sockets.
35 //
36 /// The Socket class will give you years of satisfaction provided you observe
37 /// the following points:
38 /// 1. A socket is active only when both connected() and not bad().
39 /// 2. The only accurate way of determining an error is to check bad().
40 /// 3. read() and write() should not be called until connected() is true.
41 class DSOEXPORT Socket : public IOChannel
42 {
43 public:
44 
45     /// Create a non-connected socket.
46     Socket();
47 
~Socket()48     virtual ~Socket() {}
49 
50     /// Initiate a connection
51     //
52     /// A return of true does not mean the connection has succeeded, only that
53     /// it did not fail. The connection attempt is only complete when
54     /// connected() returns true.
55     //
56     /// @return         false if the connection fails. In this case, the
57     ///                 Socket is still in a closed state and is ready for
58     ///                 a new connection attempt. Otherwise true.
59     bool connect(const std::string& hostname, std::uint16_t port);
60 
61     /// Close the Socket.
62     //
63     /// A closed Socket is in a state where another connection attempt can
64     /// be made. Any errors are reset.
65     void close();
66 
67     /// Whether a connection attempt is complete.
68     //
69     /// This is true as soon as the socket is ready for reading and writing.
70     /// But beware! This function may still return true if the Socket is
71     /// in error condition. Always check bad() if you care about this.
72     bool connected() const;
73 
74     /// True if the Socket is in an error condition.
75     //
76     /// An error condition is fatal and can only be reset when the Socket
77     /// is closed. Any read or write failure other than EAGAIN or EWOULDBLOCK
78     /// causes a fatal error.
bad()79     virtual bool bad() const {
80         return _error;
81     }
82 
83     /// Read exactly the given number of bytes from the Socket or none at all.
84     //
85     virtual std::streamsize read(void* dst, std::streamsize num);
86 
87     /// Read up to the given number of bytes from the Socket.
88     virtual std::streamsize readNonBlocking(void* dst, std::streamsize num);
89 
90     /// Write the given number of bytes to the stream
91     //
92     /// If you call write() before connected() is true, it may put the Socket
93     /// into an error condition.
94     //
95     /// Calling write() when the Socket is bad has no effect.
96     virtual std::streamsize write(const void* src, std::streamsize num);
97 
98     /// Return current stream position
99     //
100     /// Meaningless for a Socket.
101     virtual std::streampos tell() const;
102 
103     /// Seek to the specified position
104     //
105     /// Meaningless for a Socket.
106     virtual bool seek(std::streampos p);
107 
108     /// Seek to the end of the stream
109     //
110     /// Not Socket.
111     virtual void go_to_end();
112 
113     /// Return true if the end of the stream has been reached.
114     //
115     /// EOF is when remote end closed the connection and
116     /// we have no more cached data to read
117     ///
118     virtual bool eof() const;
119 
120 private:
121 
122     /// Fill the cache.
123     void fillCache();
124 
125     mutable bool _connected;
126 
127     /// A cache for received data.
128     char _cache[16384];
129 
130     /// The socket ID.
131     int _socket;
132 
133     /// Unprocessed bytes.
134     int _size;
135 
136     /// Current read position in cache.
137     size_t _pos;
138 
139     mutable bool _error;
140 };
141 
142 } // namespace gnash
143 
144 #endif // GNASH_IOCHANNEL_H
145 
146 // Local Variables:
147 // mode: C++
148 // indent-tabs-mode: nil
149 // End:
150