1/*
2 * Copyright (c) 2000-2002,2004,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// url - URL object with decomposition
27//
28#include "url.h"
29#include <CoreFoundation/CFURL.h>
30#include <CoreFoundation/CFString.h>
31#include <errno.h>
32
33
34namespace Security {
35namespace Network {
36
37
38//
39// Turn a CFStringRef into an STL string and release the incoming CFStringRef
40//
41static string mkstr(CFStringRef str)
42{
43    if (!str)
44        return "";
45    char buffer[2048];
46    if (CFStringGetCString(str, buffer, sizeof(buffer), kCFStringEncodingUTF8))
47        return buffer;
48    else
49        UnixError::throwMe(EINVAL);
50}
51
52
53//
54// Construction
55//
56URL::URL()
57{
58    ref = NULL;
59}
60
61URL::URL(const char *s)
62{
63    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)s, strlen(s), kCFStringEncodingUTF8, NULL);
64    if (!ref)
65        UnixError::throwMe(EINVAL);
66}
67
68URL::URL(const char *s, const URL &base)
69{
70    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)s, strlen(s), kCFStringEncodingUTF8, base.ref);
71    if (!ref)
72        UnixError::throwMe(EINVAL);
73}
74
75URL::~URL()
76{
77    if (ref)
78        CFRelease(ref);
79}
80
81
82//
83// Extraction: These methods produce UTF8 strings
84//
85URL::operator string() const
86{
87    return mkstr(CFURLGetString(ref));
88}
89
90string URL::scheme() const
91{
92    return mkstr(CFURLCopyScheme(ref));
93}
94
95string URL::host() const
96{
97    return mkstr(CFURLCopyHostName(ref));
98}
99
100IPPort URL::port(IPPort defaultPort) const
101{
102    SInt32 port = CFURLGetPortNumber(ref);
103    return (port == -1) ? defaultPort : port;
104}
105
106string URL::username() const
107{
108    return mkstr(CFURLCopyUserName(ref));
109}
110
111string URL::password() const
112{
113    return mkstr(CFURLCopyPassword(ref));
114}
115
116string URL::path() const
117{
118    Boolean isAbsolute;
119    return "/" + mkstr(CFURLCopyStrictPath(ref, &isAbsolute));
120}
121
122string URL::resourceSpec() const
123{
124    return mkstr(CFURLCopyResourceSpecifier(ref));
125}
126
127string URL::fullPath() const
128{
129    return path() + resourceSpec();
130}
131
132string URL::basename() const
133{
134    return mkstr(CFURLCopyLastPathComponent(ref));
135}
136
137string URL::extension() const
138{
139    return mkstr(CFURLCopyPathExtension(ref));
140}
141
142void URL::recreateURL(const char* url)
143{
144    if(ref)
145        CFRelease(ref);
146    ref = CFURLCreateWithBytes(NULL, (const UInt8 *)url, strlen(url), kCFStringEncodingUTF8, NULL);
147}
148
149}	// end namespace Network
150}	// end namespace Security
151