cec: fix OS-X compilation. credits: Dustin Cooper
[deb_libcec.git] / src / lib / platform / sockets / socket.h
CommitLineData
abbca718
LOK
1#pragma once
2/*
3 * This file is part of the libCEC(R) library.
4 *
9b53a148 5 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
abbca718
LOK
6 * libCEC(R) is an original work, containing original code.
7 *
8 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 *
10 * This program is dual-licensed; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 *
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
27 *
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
32 */
33
ba65909d
LOK
34#include "../threads/mutex.h"
35#include "../util/StdString.h"
36
37#if defined(__WINDOWS__)
38#include "../windows/os-socket.h"
39#else
40#include "../posix/os-socket.h"
41#endif
42
8637ad53
LOK
43/* Needed on Mac OS/X */
44#ifndef SOL_TCP
45#define SOL_TCP IPPROTO_TCP
46#endif
47
ba65909d 48// Common socket operations
abbca718 49
f00ff009 50namespace PLATFORM
b9187cc6 51{
99666519 52 class ISocket : public PreventCopy
ba65909d 53 {
99666519
LOK
54 public:
55 ISocket(void) {};
56 virtual ~ISocket(void) {}
cb2397e9 57
99666519
LOK
58 virtual bool Open(uint64_t iTimeoutMs = 0) = 0;
59 virtual void Close(void) = 0;
60 virtual void Shutdown(void) = 0;
61 virtual bool IsOpen(void) = 0;
62 virtual ssize_t Write(void* data, size_t len) = 0;
63 virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0;
64 virtual CStdString GetError(void) = 0;
65 virtual int GetErrorNumber(void) = 0;
66 virtual CStdString GetName(void) = 0;
67 };
25701fa6 68
99666519
LOK
69 template <typename _SType>
70 class CCommonSocket : public ISocket
71 {
72 public:
73 CCommonSocket(_SType initialSocketValue, const CStdString &strName) :
74 m_socket(initialSocketValue),
75 m_strName(strName),
76 m_iError(0) {}
25701fa6 77
99666519 78 virtual ~CCommonSocket(void) {}
abbca718 79
99666519
LOK
80 virtual CStdString GetError(void)
81 {
82 CStdString strError;
83 strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError;
84 return strError;
85 }
86
87 virtual int GetErrorNumber(void)
88 {
89 return m_iError;
90 }
91
92 virtual CStdString GetName(void)
93 {
94 CStdString strName;
95 strName = m_strName;
96 return strName;
97 }
98
99 protected:
100 _SType m_socket;
101 CStdString m_strError;
102 CStdString m_strName;
103 int m_iError;
104 CMutex m_mutex;
105 };
106
107 template <typename _Socket>
108 class CProtectedSocket : public ISocket
109 {
110 public:
111 CProtectedSocket(_Socket *socket) :
112 m_socket(socket),
113 m_iUseCount(0) {}
114
115 virtual ~CProtectedSocket(void)
116 {
117 Close();
118 delete m_socket;
119 }
abbca718 120
99666519
LOK
121 virtual bool Open(uint64_t iTimeoutMs = 0)
122 {
123 bool bReturn(false);
124 if (m_socket && WaitReady())
abbca718 125 {
99666519
LOK
126 bReturn = m_socket->Open(iTimeoutMs);
127 MarkReady();
ba65909d 128 }
99666519
LOK
129 return bReturn;
130 }
ba65909d 131
99666519
LOK
132 virtual void Close(void)
133 {
134 if (m_socket && WaitReady())
ba65909d 135 {
99666519
LOK
136 m_socket->Close();
137 MarkReady();
abbca718 138 }
99666519 139 }
abbca718 140
99666519
LOK
141 virtual void Shutdown(void)
142 {
143 if (m_socket && WaitReady())
cb2397e9 144 {
99666519
LOK
145 m_socket->Shutdown();
146 MarkReady();
cb2397e9 147 }
99666519
LOK
148 }
149
150 virtual bool IsOpen(void)
151 {
152 CLockObject lock(m_mutex);
153 return m_socket && m_socket->IsOpen();
154 }
155
156 virtual bool IsBusy(void)
157 {
158 CLockObject lock(m_mutex);
159 return m_socket && m_iUseCount > 0;
160 }
161
162 virtual int GetUseCount(void)
163 {
164 CLockObject lock(m_mutex);
165 return m_iUseCount;
166 }
167
168 virtual ssize_t Write(void* data, size_t len)
169 {
170 if (!m_socket || !WaitReady())
171 return EINVAL;
172
173 ssize_t iReturn = m_socket->Write(data, len);
174 MarkReady();
175
176 return iReturn;
177 }
178
179 virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0)
180 {
181 if (!m_socket || !WaitReady())
182 return EINVAL;
183
184 ssize_t iReturn = m_socket->Read(data, len, iTimeoutMs);
185 MarkReady();
186
187 return iReturn;
188 }
189
190 virtual CStdString GetError(void)
191 {
192 CStdString strError;
193 CLockObject lock(m_mutex);
194 strError = m_socket ? m_socket->GetError() : "";
195 return strError;
196 }
197
198 virtual int GetErrorNumber(void)
199 {
200 CLockObject lock(m_mutex);
201 return m_socket ? m_socket->GetErrorNumber() : EINVAL;
202 }
203
204 virtual CStdString GetName(void)
205 {
206 CStdString strName;
207 CLockObject lock(m_mutex);
208 strName = m_socket ? m_socket->GetName() : "";
209 return strName;
210 }
211
212 private:
213 bool WaitReady(void)
214 {
215 CLockObject lock(m_mutex);
216 if (m_iUseCount > 0)
217 m_condition.Wait(m_mutex);
218
219 if (m_iUseCount > 0)
220 return false;
221
222 ++m_iUseCount;
223 return true;
224 }
225
226 void MarkReady(void)
227 {
228 CLockObject lock(m_mutex);
229 if (m_iUseCount > 0)
230 --m_iUseCount;
231 m_condition.Broadcast();
232 }
cb2397e9 233
99666519
LOK
234 _Socket *m_socket;
235 CMutex m_mutex;
236 CCondition m_condition;
237 int m_iUseCount;
ba65909d 238 };
b9187cc6 239};