GNU CommonC++
socket.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 //
17 // As a special exception, you may use this file as part of a free software
18 // library without restriction. Specifically, if other files instantiate
19 // templates or use macros or inline functions from this file, or you compile
20 // this file and link it with other files to produce an executable, this
21 // file does not by itself cause the resulting executable to be covered by
22 // the GNU General Public License. This exception does not however
23 // invalidate any other reasons why the executable file might be covered by
24 // the GNU General Public License.
25 //
26 // This exception applies only to the code released under the name GNU
27 // Common C++. If you copy code from other releases into a copy of GNU
28 // Common C++, as the General Public License permits, the exception does
29 // not apply to the code that you add in this way. To avoid misleading
30 // anyone as to the status of such modified files, you must delete
31 // this exception notice from them.
32 //
33 // If you write modifications of your own for GNU Common C++, it is your choice
34 // whether to permit this exception to apply to your modifications.
35 // If you do not wish that, delete this exception notice.
36 //
37 
43 #ifndef CCXX_SOCKET_H_
44 #define CCXX_SOCKET_H_
45 
46 #ifndef CCXX_ADDRESS_H_
47 #include <cc++/address.h>
48 #endif
49 
50 #if defined(WIN32) && !defined(__CYGWIN32__)
51 #include <io.h>
52 #define _IOLEN64 (unsigned)
53 #define _IORET64 (int)
54 #define TIMEOUT_INF ~((timeout_t) 0)
55 typedef int socklen_t;
56 #else
57 #define INVALID_SOCKET -1
58 typedef int SOCKET;
59 #endif
60 
61 #ifndef _IOLEN64
62 #define _IOLEN64
63 #endif
64 
65 #ifndef _IORET64
66 #define _IORET64
67 #endif
68 
69 #ifndef MSG_DONTWAIT
70 #define MSG_DONTWAIT 0
71 #endif
72 
73 #ifndef MSG_NOSIGNAL
74 #define MSG_NOSIGNAL 0
75 #endif
76 
77 #ifdef CCXX_NAMESPACES
78 namespace ost {
79 #endif
80 
84 typedef unsigned short tpport_t;
85 
104 {
105 public:
106  enum Family {
107 #ifdef CCXX_IPV6
108  IPV6 = AF_INET6,
109 #endif
110  IPV4 = AF_INET
111  };
112 
113  typedef enum Family Family;
114 
115  enum Error {
116  errSuccess = 0,
144  errInvalidValue
145  };
146 
147  typedef enum Error Error;
148 
149  enum Tos {
150  tosLowDelay = 0,
154  tosInvalid
155  };
156  typedef enum Tos Tos;
157 
158  enum Pending {
161  pendingError
162  };
163  typedef enum Pending Pending;
164 
165 protected:
166  enum State {
172  STREAM
173  };
174  typedef enum State State;
175 
176 private:
177  // used by exception handlers....
178  mutable Error errid;
179  mutable const char *errstr;
180  mutable long syserr;
181 
182  void setSocket(void);
183  friend SOCKET dupSocket(SOCKET s,Socket::State state);
184 
185 protected:
186  static Mutex mutex;
187 
188  mutable struct {
189  bool thrown: 1;
190  bool broadcast: 1;
191  bool route: 1;
192  bool keepalive: 1;
193  bool loopback: 1;
194  bool multicast: 1;
195  bool completion: 1;
196  bool linger: 1;
197  unsigned ttl: 8;
198  } flags;
199 
205  SOCKET volatile so;
206  State volatile state;
207 
216  Error error(Error error, char *err = NULL, long systemError = 0) const;
217 
224  inline void error(char *err) const
225  {error(errExtended, err);};
226 
233  inline void setError(bool enable)
234  {flags.thrown = !enable;};
235 
241  void endSocket(void);
242 
248  Error connectError(void);
249 
253  Error sendLimit(int limit = 2048);
254 
258  Error receiveLimit(int limit = 1);
259 
266  Error sendTimeout(timeout_t timer);
267 
274  Error receiveTimeout(timeout_t timer);
275 
283  Error sendBuffer(unsigned size);
284 
292  Error receiveBuffer(unsigned size);
293 
301  Error bufferSize(unsigned size);
302 
311  Error setBroadcast(bool enable);
312 
324  Error setMulticastByFamily(bool enable, Family family = IPV4);
325 
334  Error setLoopbackByFamily(bool enable, Family family = IPV4);
335 
343  Error setTimeToLiveByFamily(unsigned char ttl, Family fam = IPV4);
344 
351  Error join(const IPV4Multicast &ia);
352 #ifdef CCXX_IPV6
353  Error join(const IPV6Multicast &ia);
354 #endif
355 
362  Error drop(const IPV4Multicast &ia);
363 #ifdef CCXX_IPV6
364  Error drop(const IPV6Multicast &ia);
365 #endif
366 
374  Error setRouting(bool enable);
375 
376 
383  Error setNoDelay(bool enable);
384 
396  Socket(int domain, int type, int protocol = 0);
397 
405  Socket(SOCKET fd);
406 
410  Socket();
411 
419  Socket(const Socket &source);
420 
430  ssize_t readLine(char *buf, size_t len, timeout_t timeout = 0);
431 
443  virtual ssize_t readData(void * buf,size_t len,char separator=0,timeout_t t=0);
444 
453  virtual ssize_t writeData(const void* buf,size_t len,timeout_t t=0);
454 
455 public:
463  virtual ~Socket();
464 
471  static bool check(Family fam);
472 
476  Socket &operator=(const Socket &from);
477 
487  IPV4Host getIPV4Sender(tpport_t *port = NULL) const;
488 
489  inline IPV4Host getSender(tpport_t *port = NULL) const
490  {return getIPV4Sender(port);}
491 
492 #ifdef CCXX_IPV6
493  IPV6Host getIPV6Sender(tpport_t *port = NULL) const;
494 #endif
495 
505  IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
506 
507  inline IPV4Host getPeer(tpport_t *port = NULL) const
508  {return getIPV4Peer(port);}
509 
510 #ifdef CCXX_IPV6
511  IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
512 #endif
513 
521  IPV4Host getIPV4Local(tpport_t *port = NULL) const;
522 
523  inline IPV4Host getLocal(tpport_t *port = NULL) const
524  {return getIPV4Local(port);}
525 
526 #ifdef CCXX_IPV6
527  IPV6Host getIPV6Local(tpport_t *port = NULL) const;
528 #endif
529 
557  IPV4Host getIPV4NAT(tpport_t *port = NULL) const;
558 
559  inline IPV4Host getNAT(tpport_t *port) const
560  {return getIPV4NAT(port);}
561 
562 #ifdef CCXX_IPV6
563  IPV6Host getIPV6NAT(tpport_t *port = NULL) const;
564 #endif
565 
576  void setCompletion(bool immediate);
577 
583  Error setLinger(bool linger);
584 
592  Error setKeepAlive(bool enable);
593 
602  Error setTypeOfService(Tos service);
603 
612  bool isConnected(void) const;
613 
621  bool isActive(void) const;
622 
627  bool operator!() const;
628 
635  inline bool isBroadcast(void) const
636  {return flags.broadcast;};
637 
643  inline bool isRouted(void) const
644  {return flags.route;};
645 
652  inline Error getErrorNumber(void) const {return errid;}
653 
660  inline const char *getErrorString(void) const {return errstr;}
661 
662  inline long getSystemError(void) const {return syserr;}
663 
664  const char *getSystemErrorString(void) const;
665 
675  virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
676 };
677 
710 class __EXPORT UDPSocket : public Socket
711 {
712 private:
713  inline Error setKeepAlive(bool enable)
714  {return Socket::setKeepAlive(enable);};
715 
716 protected:
717 #ifdef CCXX_IPV6
718  union {
719  struct sockaddr_in6 ipv6;
720  struct sockaddr_in ipv4;
721  } peer;
722 #else
723  union {
724  struct sockaddr_in ipv4;
725  } peer;
726 #endif
727 
728  Family family;
729 
730 public:
734  UDPSocket(Family family = IPV4);
735 
739  UDPSocket(const char *name, Family family = IPV4);
740 
750  UDPSocket(const IPV4Address &bind, tpport_t port);
751 #ifdef CCXX_IPV6
752  UDPSocket(const IPV6Address &bind, tpport_t port);
753 #endif
754 
758  virtual ~UDPSocket();
759 
763  inline Error setLoopback(bool enable)
764  {return Socket::setLoopbackByFamily(enable, family);}
765 
769  inline Error setMulticast(bool enable)
770  {return Socket::setMulticastByFamily(enable, family);}
771 
775  inline Error setTimeToLive(char ttl)
776  {return Socket::setTimeToLiveByFamily(ttl, family);}
777 
785  void setPeer(const IPV4Host &host, tpport_t port);
786  void connect(const IPV4Host &host, tpport_t port);
787 #ifdef CCXX_IPV6
788  void setPeer(const IPV6Host &host, tpport_t port);
789  void connect(const IPV6Host &host, tpport_t port);
790 #endif
791 
799  Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex);
800 
809  Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex);
810 
811 
819  ssize_t send(const void *buf, size_t len);
820 
829  ssize_t receive(void *buf, size_t len, bool reply = false);
830 
839  IPV4Host getIPV4Peer(tpport_t *port = NULL) const;
840  inline IPV4Host getPeer(tpport_t *port = NULL) const
841  {return getIPV4Peer(port);}
842 
843 #ifdef CCXX_IPV6
844  IPV6Host getIPV6Peer(tpport_t *port = NULL) const;
845 #endif
846 
854  inline ssize_t peek(void *buf, size_t len)
855  {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
856 
860  void setPeer(const char *service);
861  void connect(const char *service);
862 
867  Error disconnect(void);
868 };
869 
870 
880 {
881 private:
882  void setPeer(const IPV4Host &ia, tpport_t port);
883 
884  Error setBroadcast(bool enable)
885  {return Socket::setBroadcast(enable);};
886 
887 public:
894  UDPBroadcast(const IPV4Address &ia, tpport_t port);
895 
902  void setPeer(const IPV4Broadcast &subnet, tpport_t port);
903 };
904 
913 class __EXPORT UDPTransmit : protected UDPSocket
914 {
915 private:
923  Error cConnect(const IPV4Address &ia, tpport_t port);
924 
925 protected:
929  UDPTransmit(Family family = IPV4);
930 
942  UDPTransmit(const IPV4Address &bind, tpport_t port = 5005);
943 #ifdef CCXX_IPV6
944  UDPTransmit(const IPV6Address &bind, tpport_t port = 5005);
945 #endif
946 
956  Error connect(const IPV4Host &host, tpport_t port);
957 #ifdef CCXX_IPV6
958  Error connect(const IPV6Address &host, tpport_t port);
959 #endif
960 
970  Error connect(const IPV4Broadcast &subnet, tpport_t port);
971 
979  Error connect(const IPV4Multicast &mgroup, tpport_t port);
980 #ifdef CCXX_IPV6
981  Error connect(const IPV6Multicast &mgroup, tpport_t port);
982 #endif
983 
991  inline ssize_t send(const void *buf, size_t len)
992  {return _IORET64 ::send(so, (const char *)buf, _IOLEN64 len, MSG_NOSIGNAL);}
993 
997  inline void endTransmitter(void)
998  {Socket::endSocket();}
999 
1000  /*
1001  * Get transmitter socket.
1002  *
1003  * @return transmitter.
1004  */
1005  inline SOCKET getTransmitter(void)
1006  {return so;};
1007 
1008  inline Error setMulticast(bool enable)
1009  {return Socket::setMulticastByFamily(enable, family);}
1010 
1011  inline Error setTimeToLive(unsigned char ttl)
1012  {return Socket::setTimeToLiveByFamily(ttl, family);};
1013 
1014 public:
1024  inline ssize_t transmit(const char *buffer, size_t len)
1025  {return _IORET64 ::send(so, buffer, _IOLEN64 len, MSG_DONTWAIT|MSG_NOSIGNAL);}
1026 
1033  inline bool isOutputReady(unsigned long timeout = 0l)
1034  {return Socket::isPending(Socket::pendingOutput, timeout);};
1035 
1036 
1037  inline Error setRouting(bool enable)
1038  {return Socket::setRouting(enable);};
1039 
1040  inline Error setTypeOfService(Tos tos)
1041  {return Socket::setTypeOfService(tos);};
1042 
1043  inline Error setBroadcast(bool enable)
1044  {return Socket::setBroadcast(enable);};
1045 };
1046 
1055 class __EXPORT UDPReceive : protected UDPSocket
1056 {
1057 protected:
1068  UDPReceive(const IPV4Address &bind, tpport_t port);
1069 #ifdef CCXX_IPV6
1070  UDPReceive(const IPV6Address &bind, tpport_t port);
1071 #endif
1072 
1082  Error connect(const IPV4Host &host, tpport_t port);
1083 #ifdef CCXX_IPV6
1084  Error connect(const IPV6Host &host, tpport_t port);
1085 #endif
1086 
1093  bool isPendingReceive(timeout_t timeout)
1094  {return Socket::isPending(Socket::pendingInput, timeout);};
1095 
1099  inline void endReceiver(void)
1100  {Socket::endSocket();}
1101 
1102  inline SOCKET getReceiver(void) const
1103  {return so;};
1104 
1105  inline Error setRouting(bool enable)
1106  {return Socket::setRouting(enable);}
1107 
1108  inline Error setMulticast(bool enable)
1109  {return Socket::setMulticastByFamily(enable, family);}
1110 
1111  inline Error join(const IPV4Multicast &ia)
1112  {return Socket::join(ia);}
1113 
1114 #ifdef CCXX_IPV6
1115  inline Error join(const IPV6Multicast &ia)
1116  {return Socket::join(ia);}
1117 #endif
1118 
1119  inline Error drop(const IPV4Multicast &ia)
1120  {return Socket::drop(ia);}
1121 
1122 #ifdef CCXX_IPV6
1123  inline Error drop(const IPV6Multicast &ia)
1124  {return Socket::drop(ia);}
1125 #endif
1126 
1127 public:
1135  inline ssize_t receive(void *buf, size_t len)
1136  {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, 0);};
1137 
1144  inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
1145  {return Socket::isPending(Socket::pendingInput, timeout);};
1146 };
1147 
1159 {
1160 public:
1168  UDPDuplex(const IPV4Address &bind, tpport_t port);
1169 #ifdef CCXX_IPV6
1170  UDPDuplex(const IPV6Address &bind, tpport_t port);
1171 #endif
1172 
1182  Error connect(const IPV4Host &host, tpport_t port);
1183 #ifdef CCXX_IPV6
1184  Error connect(const IPV6Host &host, tpport_t port);
1185 #endif
1186 
1193  Error disconnect(void);
1194 };
1195 
1196 
1221 class __EXPORT TCPSocket : protected Socket
1222 {
1223 protected:
1224  int segsize;
1225  void setSegmentSize(unsigned mss);
1226 
1227 public:
1239  virtual bool onAccept(const IPV4Host &ia, tpport_t port);
1240 
1244  inline SOCKET getSocket(void)
1245  {return so;};
1246 
1250  inline int getSegmentSize(void)
1251  {return segsize;};
1252 
1265  TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
1266 
1277  TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536);
1278 
1287  inline IPV4Host getRequest(tpport_t *port = NULL) const
1288  {return Socket::getIPV4Sender(port);}
1289 
1293  void reject(void);
1294 
1298  inline IPV4Host getLocal(tpport_t *port = NULL) const
1299  {return Socket::getIPV4Local(port);}
1300 
1306  inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
1307  {return Socket::isPending(Socket::pendingInput, timeout);}
1308 
1312  virtual ~TCPSocket();
1313 };
1314 
1315 #ifdef CCXX_IPV6
1316 
1340 class __EXPORT TCPV6Socket : protected Socket
1341 {
1342 private:
1343  int segsize;
1344  void setSegmentSize(unsigned mss);
1345 
1346 public:
1358  virtual bool onAccept(const IPV6Host &ia, tpport_t port);
1359 
1363  inline SOCKET getSocket(void)
1364  {return so;};
1365 
1366  inline int getSegmentSize(void)
1367  {return segsize;};
1368 
1381  TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536);
1382 
1393  TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536);
1394 
1403  inline IPV6Host getRequest(tpport_t *port = NULL) const
1404  {return Socket::getIPV6Sender(port);}
1405 
1409  void reject(void);
1410 
1414  inline IPV6Host getLocal(tpport_t *port = NULL) const
1415  {return Socket::getIPV6Local(port);}
1416 
1422  inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */
1423  {return Socket::isPending(Socket::pendingInput, timeout);}
1424 
1428  virtual ~TCPV6Socket();
1429 };
1430 
1431 #endif
1432 
1433 /*
1434 :\projects\libraries\cplusplus\commonc++\win32\socket.h(357) : warning C4275: non dll-interface class 'streambuf' used as base for dll-interface class 'TCPStream'
1435  c:\program files\microsoft visual studio\vc98\include\streamb.h(69) : see declaration of 'streambuf'
1436 c:\projects\libraries\cplusplus\commonc++\win32\socket.h(358) : warning C4275: non dll-interface class 'iostream' used as base for dll-interface class 'TCPStream'
1437  c:\program files\microsoft visual studio\vc98\include\iostream.h(66) : see declaration of 'iostream'
1438 */
1439 
1440 #ifdef _MSC_VER
1441 #pragma warning(disable:4275) // disable C4275 warning
1442 #endif
1443 
1457 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream
1458 {
1459 private:
1460  int doallocate();
1461 
1462  void segmentBuffering(unsigned mss);
1463 
1464  friend TCPStream& crlf(TCPStream&);
1465  friend TCPStream& lfcr(TCPStream&);
1466 
1467 protected:
1469  size_t bufsize;
1470  Family family;
1471  char *gbuf, *pbuf;
1472 
1473 public:
1478  TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0);
1479 
1483  void disconnect(void);
1484 
1488  int getSegmentSize(void);
1489 
1490 protected:
1497  void allocate(size_t size);
1498 
1503  void endStream(void);
1504 
1511  int underflow();
1512 
1521  int uflow();
1522 
1530  int overflow(int ch);
1531 
1540  void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536);
1541 #ifdef CCXX_IPV6
1542  void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536);
1543 #endif
1544 
1552  void connect(const char *name, unsigned mss = 536);
1553 
1561  std::iostream *tcp(void)
1562  {return ((std::iostream *)this);};
1563 
1564 public:
1574  TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0);
1575 #ifdef CCXX_IPV6
1576  TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0);
1577 #endif
1578 
1584  void connect(TCPSocket &server);
1585 #ifdef CCXX_IPV6
1586  void connect(TCPV6Socket &server);
1587 #endif
1588 
1599  TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
1600 #ifdef CCXX_IPV6
1601  TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0);
1602 #endif
1603 
1613  TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0);
1614 
1620  inline void setTimeout(timeout_t timer)
1621  {timeout = timer;};
1622 
1629  TCPStream(const TCPStream &source);
1630 
1635  virtual ~TCPStream();
1636 
1643  int sync(void);
1644 
1645 #ifdef HAVE_SNPRINTF
1646 
1652  size_t printf(const char *format, ...);
1653 #endif
1654 
1662  bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
1663 
1671  inline ssize_t peek(void *buf, size_t len)
1672  {return _IORET64 ::recv(so, (char *)buf, _IOLEN64 len, MSG_PEEK);};
1673 
1679  inline size_t getBufferSize(void) const
1680  {return bufsize;};
1681 };
1682 
1693 class __EXPORT TCPSession : public Thread, public TCPStream
1694 {
1695 private:
1696  TCPSession(const TCPSession &rhs); // not defined
1697 protected:
1710  int waitConnection(timeout_t timeout = TIMEOUT_INF);
1711 
1718  void initial(void);
1719 
1720 public:
1731  TCPSession(const IPV4Host &host,
1732  tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
1733 #ifdef CCXX_IPV6
1734  TCPSession(const IPV6Host &host,
1735  tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0);
1736 #endif
1737 
1747  TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0);
1748 #ifdef CCXX_IPV6
1749  TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0);
1750 #endif
1751 
1755  virtual ~TCPSession();
1756 };
1757 
1758 #if defined(WIN32)
1759 
1769 class init_WSA
1770 {
1771 public:
1772  init_WSA();
1773  ~init_WSA();
1774 };
1775 
1776 #endif // WIN32
1777 
1779 
1792 {
1793 private:
1794 
1795  IPV4Host getSender(tpport_t *port) const;
1796 
1797 protected:
1802  SimpleTCPStream();
1803 
1808  void endStream(void);
1809 
1818  void Connect(const IPV4Host &host, tpport_t port, size_t size);
1819 
1820 
1821 public:
1830  SimpleTCPStream(TCPSocket &server, size_t size = 512);
1831 
1840  SimpleTCPStream(const IPV4Host &host, tpport_t port, size_t size = 512);
1841 
1847  SimpleTCPStream(const SimpleTCPStream &source);
1848 
1853  virtual ~SimpleTCPStream();
1854 
1866  bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
1867 
1868  void flush() {}
1869 
1881  ssize_t read(char *bytes, size_t length, timeout_t timeout = 0);
1882 
1894  ssize_t write(const char *bytes, size_t length, timeout_t timeout = 0);
1895 
1909  ssize_t peek(char *bytes, size_t length, timeout_t timeout = 0);
1910 
1911 };
1912 
1913 #ifdef COMMON_STD_EXCEPTION
1914 class __EXPORT SockException : public IOException
1915 {
1916 private:
1917  Socket::Error _socketError;
1918 
1919 public:
1920  SockException(const String &str, Socket::Error socketError, long systemError = 0) :
1921  IOException(str, systemError), _socketError(socketError) {};
1922 
1923  inline Socket::Error getSocketError() const
1924  { return _socketError; }
1925 };
1926 #endif
1927 
1928 #ifdef CCXX_NAMESPACES
1929 }
1930 #endif
1931 
1932 #endif
1933