source: trunk/src/network/qhostaddress.cpp@ 7

Last change on this file since 7 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 10.4 KB
Line 
1/****************************************************************************
2** $Id: qhostaddress.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QHostAddress class.
5**
6** Created : 979899
7**
8** Copyright (C) 1997-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qhostaddress.h"
39#include "qstringlist.h"
40
41#ifndef QT_NO_NETWORK
42class QHostAddressPrivate
43{
44public:
45 QHostAddressPrivate( Q_UINT32 a_=0 ) : a(a_), isIp4(TRUE)
46 {
47 }
48 QHostAddressPrivate( Q_UINT8 *a_ );
49 QHostAddressPrivate(const Q_IPV6ADDR &a_);
50 ~QHostAddressPrivate()
51 {
52 }
53
54 QHostAddressPrivate & operator=( const QHostAddressPrivate &from )
55 {
56 a = from.a;
57 isIp4 = from.isIp4;
58 a6 = from.a6;
59 return *this;
60 }
61
62private:
63 Q_UINT32 a; // ip 4 address
64 Q_IPV6ADDR a6; // ip 6 address
65 bool isIp4;
66
67 friend class QHostAddress;
68};
69
70QHostAddressPrivate::QHostAddressPrivate(Q_UINT8 *a_) : a(0), isIp4(FALSE)
71{
72 for ( int i=0; i<16; i++ ) {
73 a6.c[i] = a_[i];
74 }
75}
76
77QHostAddressPrivate::QHostAddressPrivate(const Q_IPV6ADDR &a_) : a(0), isIp4(FALSE)
78{
79 a6 = a_;
80}
81
82/*!
83 \class QHostAddress qhostaddress.h
84 \brief The QHostAddress class provides an IP address.
85\if defined(commercial)
86 It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
87\endif
88
89 \ingroup io
90 \module network
91
92 This class contains an IP address in a platform and protocol
93 independent manner. It stores both IPv4 and IPv6 addresses in a
94 way that you can easily access on any platform.
95
96 QHostAddress is normally used with the classes QSocket,
97 QServerSocket and QSocketDevice to set up a server or to connect
98 to a host.
99
100 Host addresses may be set with setAddress() and retrieved with
101 ip4Addr() or toString().
102
103 \sa QSocket, QServerSocket, QSocketDevice
104*/
105
106
107/*!
108 Creates a host address object with the IP address 0.0.0.0.
109*/
110QHostAddress::QHostAddress()
111 : d( new QHostAddressPrivate )
112{
113}
114
115
116/*!
117 Creates a host address object for the IPv4 address \a ip4Addr.
118*/
119QHostAddress::QHostAddress( Q_UINT32 ip4Addr )
120 : d( new QHostAddressPrivate( ip4Addr ) )
121{
122}
123
124
125/*!
126 Creates a host address object with the specified IPv6 address.
127
128 \a ip6Addr must be a 16 byte array in network byte order
129 (high-order byte first).
130*/
131QHostAddress::QHostAddress( Q_UINT8 *ip6Addr )
132 : d( new QHostAddressPrivate( ip6Addr ) )
133{
134}
135
136/*!
137 Creates a host address object with the IPv6 address, \a ip6Addr.
138*/
139QHostAddress::QHostAddress(const Q_IPV6ADDR &ip6Addr)
140 : d(new QHostAddressPrivate(ip6Addr))
141{
142}
143
144// ### DOC: Can only make this public if we specify precisely the
145// format of the address string.
146/*!
147 \internal
148*/
149QHostAddress::QHostAddress(const QString &address)
150 : d( new QHostAddressPrivate )
151{
152 setAddress( address );
153}
154
155/*!
156 Creates a copy of \a address.
157*/
158QHostAddress::QHostAddress( const QHostAddress &address )
159 : d( new QHostAddressPrivate )
160{
161 *d = *(address.d);
162}
163
164
165/*!
166 Destroys the host address object.
167*/
168QHostAddress::~QHostAddress()
169{
170 delete d;
171}
172
173
174/*!
175 Assigns another host address object \a address to this object and
176 returns a reference to this object.
177*/
178QHostAddress & QHostAddress::operator=( const QHostAddress & address )
179{
180 *d = *(address.d);
181 return *this;
182}
183
184
185/*!
186 Set the IPv4 address specified by \a ip4Addr.
187*/
188void QHostAddress::setAddress( Q_UINT32 ip4Addr )
189{
190 delete d;
191 d = new QHostAddressPrivate( ip4Addr );
192}
193
194
195/*!
196 \overload
197
198 Set the IPv6 address specified by \a ip6Addr.
199
200 \a ip6Addr must be a 16 byte array in network byte order
201 (high-order byte first).
202*/
203void QHostAddress::setAddress( Q_UINT8 *ip6Addr )
204{
205 delete d;
206 d = new QHostAddressPrivate( ip6Addr );
207}
208
209#ifndef QT_NO_STRINGLIST
210static bool parseIp4(const QString& address, Q_UINT32 *addr)
211{
212 QStringList ipv4 = QStringList::split(".", address, FALSE);
213 if (ipv4.count() == 4) {
214 int i = 0;
215 bool ok = TRUE;
216 while(ok && i < 4) {
217 uint byteValue = ipv4[i].toUInt(&ok);
218 if (byteValue > 255)
219 ok = FALSE;
220 if (ok)
221 *addr = (*addr << 8) + byteValue;
222 ++i;
223 }
224 if (ok)
225 return TRUE;
226 }
227 return FALSE;
228}
229
230/*!
231 \overload
232
233 Sets the IPv4 or IPv6 address specified by the string
234 representation \a address (e.g. "127.0.0.1"). Returns TRUE and
235 sets the address if the address was successfully parsed; otherwise
236 returns FALSE and leaves the address unchanged.
237*/
238bool QHostAddress::setAddress(const QString& address)
239{
240 QString a = address.simplifyWhiteSpace();
241
242 // try ipv4
243 Q_UINT32 maybeIp4 = 0;
244 if (parseIp4(address, &maybeIp4)) {
245 setAddress(maybeIp4);
246 return TRUE;
247 }
248
249 // try ipv6
250 QStringList ipv6 = QStringList::split(":", a, TRUE);
251 int count = ipv6.count();
252 if (count < 3)
253 return FALSE; // there must be at least two ":"
254 if (count > 8)
255 return FALSE; // maximum of seven ":" exceeded
256 Q_UINT8 maybeIp6[16];
257 int mc = 16;
258 int fillCount = 9 - count;
259 for (int i=count-1; i>=0; --i) {
260 if ( mc <= 0 )
261 return FALSE;
262
263 if (ipv6[i].isEmpty()) {
264 if (i==count-1) {
265 // special case: ":" is last character
266 if (!ipv6[i-1].isEmpty())
267 return FALSE;
268 maybeIp6[--mc] = 0;
269 maybeIp6[--mc] = 0;
270 } else if (i==0) {
271 // special case: ":" is first character
272 if (!ipv6[i+1].isEmpty())
273 return FALSE;
274 maybeIp6[--mc] = 0;
275 maybeIp6[--mc] = 0;
276 } else {
277 for (int j=0; j<fillCount; ++j) {
278 if ( mc <= 0 )
279 return FALSE;
280 maybeIp6[--mc] = 0;
281 maybeIp6[--mc] = 0;
282 }
283 }
284 } else {
285 bool ok = FALSE;
286 uint byteValue = ipv6[i].toUInt(&ok, 16);
287 if (ok && byteValue <= 0xffff) {
288 maybeIp6[--mc] = byteValue & 0xff;
289 maybeIp6[--mc] = (byteValue >> 8) & 0xff;
290 } else {
291 if (i == count-1) {
292 // parse the ipv4 part of a mixed type
293 if (!parseIp4(ipv6[i], &maybeIp4))
294 return FALSE;
295 maybeIp6[--mc] = maybeIp4 & 0xff;
296 maybeIp6[--mc] = (maybeIp4 >> 8) & 0xff;
297 maybeIp6[--mc] = (maybeIp4 >> 16) & 0xff;
298 maybeIp6[--mc] = (maybeIp4 >> 24) & 0xff;
299 --fillCount;
300 } else {
301 return FALSE;
302 }
303 }
304 }
305 }
306 if (mc == 0) {
307 setAddress(maybeIp6);
308 return TRUE;
309 }
310
311 return FALSE;
312}
313#endif
314
315/*!
316 \obsolete
317
318 Use isIPv4Address() instead.
319*/
320bool QHostAddress::isIp4Addr() const
321{
322 return isIPv4Address();
323}
324
325/*!
326 Returns TRUE if the host address represents an IPv4 address;
327 otherwise returns FALSE.
328*/
329bool QHostAddress::isIPv4Address() const
330{
331 return d->isIp4;
332}
333
334/*!
335 \obsolete
336
337 Use toIPv4Address() instead.
338*/
339Q_UINT32 QHostAddress::ip4Addr() const
340{
341 return toIPv4Address();
342}
343
344/*!
345 Returns the IPv4 address as a number.
346
347 For example, if the address is 127.0.0.1, the returned value is
348 2130706433 (i.e. 0x7f000001).
349
350 This value is only valid when isIp4Addr() returns TRUE.
351
352 \sa toString()
353*/
354Q_UINT32 QHostAddress::toIPv4Address() const
355{
356 return d->a;
357}
358
359/*!
360 Returns TRUE if the host address represents an IPv6 address;
361 otherwise returns FALSE.
362*/
363bool QHostAddress::isIPv6Address() const
364{
365 return !d->isIp4;
366}
367
368/*!
369 Returns the IPv6 address as a Q_IPV6ADDR structure. The structure
370 consists of 16 unsigned characters.
371
372 \code
373 Q_IPV6ADDR addr = hostAddr.ip6Addr();
374 // addr.c[] contains 16 unsigned characters
375
376 for (int i = 0; i < 16; ++i) {
377 // process addr.c[i]
378 }
379 \endcode
380
381 This value is only valid when isIPv6Address() returns TRUE.
382
383 \sa toString()
384*/
385Q_IPV6ADDR QHostAddress::toIPv6Address() const
386{
387 return d->a6;
388}
389
390#ifndef QT_NO_SPRINTF
391/*!
392 Returns the address as a string.
393
394 For example, if the address is the IPv4 address 127.0.0.1, the
395 returned string is "127.0.0.1".
396
397 \sa ip4Addr()
398*/
399QString QHostAddress::toString() const
400{
401 if ( d->isIp4 ) {
402 Q_UINT32 i = ip4Addr();
403 QString s;
404 s.sprintf( "%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
405 (i >> 8) & 0xff, i & 0xff );
406 return s;
407 } else {
408 Q_UINT16 ugle[8];
409 for ( int i=0; i<8; i++ ) {
410 ugle[i] = ( (Q_UINT16)( d->a6.c[2*i] ) << 8 ) |
411 ( (Q_UINT16)( d->a6.c[2*i+1] ) );
412 }
413 QString s;
414 s.sprintf( "%X:%X:%X:%X:%X:%X:%X:%X",
415 ugle[0], ugle[1], ugle[2], ugle[3],
416 ugle[4], ugle[5], ugle[6], ugle[7] );
417 return s;
418 }
419}
420#endif
421
422
423/*!
424 Returns TRUE if this host address is the same as \a other;
425 otherwise returns FALSE.
426*/
427bool QHostAddress::operator==( const QHostAddress & other ) const
428{
429 return d->a == other.d->a;
430}
431
432
433/*!
434 Returns TRUE if this host address is null (INADDR_ANY or in6addr_any). The
435 default constructor creates a null address, and that address isn't valid
436 for any particular host or interface.
437*/
438bool QHostAddress::isNull() const
439{
440 if ( d->isIp4 )
441 return d->a == 0;
442 int i = 0;
443 while( i < 16 ) {
444 if ( d->a6.c[i++] != 0 )
445 return FALSE;
446 }
447 return TRUE;
448}
449
450#endif //QT_NO_NETWORK
Note: See TracBrowser for help on using the repository browser.