]>
Commit | Line | Data |
---|---|---|
a90939db JF |
1 | /* |
2 | * Copyright (C) 2007 Apple Inc. All rights reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
7 | * 1. Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | |
9 | * 2. Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | |
12 | * | |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 | */ | |
25 | ||
26 | #include "config.h" | |
27 | #include "KURL.h" | |
28 | #include "ResourceError.h" | |
29 | ||
30 | #if USE(CFNETWORK) | |
31 | ||
32 | // FIXME: Once <rdar://problem/5050881> is fixed in open source we | |
33 | // can remove this extern "C" | |
34 | extern "C" { | |
35 | #include <CFNetwork/CFNetworkErrors.h> | |
36 | } | |
37 | ||
38 | #include <CoreFoundation/CFError.h> | |
39 | #include <WTF/RetainPtr.h> | |
40 | ||
41 | namespace WebCore { | |
42 | ||
43 | const CFStringRef failingURLStringKey = CFSTR("NSErrorFailingURLStringKey"); | |
44 | const CFStringRef failingURLKey = CFSTR("NSErrorFailingURLKey"); | |
45 | ||
46 | // FIXME: Once <rdar://problem/5050841> is fixed we can remove this constructor. | |
47 | ResourceError::ResourceError(CFStreamError error) | |
48 | : m_dataIsUpToDate(true) | |
49 | { | |
50 | m_isNull = false; | |
51 | m_errorCode = error.error; | |
52 | ||
53 | switch(error.domain) { | |
54 | case kCFStreamErrorDomainCustom: | |
55 | m_domain ="NSCustomErrorDomain"; | |
56 | break; | |
57 | case kCFStreamErrorDomainPOSIX: | |
58 | m_domain = "NSPOSIXErrorDomain"; | |
59 | break; | |
60 | case kCFStreamErrorDomainMacOSStatus: | |
61 | m_domain = "NSOSStatusErrorDomain"; | |
62 | break; | |
63 | } | |
64 | } | |
65 | ||
66 | void ResourceError::platformLazyInit() | |
67 | { | |
68 | if (m_dataIsUpToDate) | |
69 | return; | |
70 | ||
71 | if (!m_platformError) | |
72 | return; | |
73 | ||
74 | CFStringRef domain = CFErrorGetDomain(m_platformError.get()); | |
75 | if (domain == kCFErrorDomainMach || domain == kCFErrorDomainCocoa) | |
76 | m_domain ="NSCustomErrorDomain"; | |
77 | else if (domain == kCFErrorDomainCFNetwork) | |
78 | m_domain = "CFURLErrorDomain"; | |
79 | else if (domain == kCFErrorDomainPOSIX) | |
80 | m_domain = "NSPOSIXErrorDomain"; | |
81 | else if (domain == kCFErrorDomainOSStatus) | |
82 | m_domain = "NSOSStatusErrorDomain"; | |
83 | else if (domain == kCFErrorDomainWinSock) | |
84 | m_domain = "kCFErrorDomainWinSock"; | |
85 | ||
86 | m_errorCode = CFErrorGetCode(m_platformError.get()); | |
87 | ||
88 | RetainPtr<CFDictionaryRef> userInfo(AdoptCF, CFErrorCopyUserInfo(m_platformError.get())); | |
89 | if (userInfo.get()) { | |
90 | CFStringRef failingURLString = (CFStringRef) CFDictionaryGetValue(userInfo.get(), failingURLStringKey); | |
91 | if (failingURLString) | |
92 | m_failingURL = String(failingURLString); | |
93 | else { | |
94 | CFURLRef failingURL = (CFURLRef) CFDictionaryGetValue(userInfo.get(), failingURLKey); | |
95 | if (failingURL) { | |
96 | RetainPtr<CFURLRef> absoluteURLRef(AdoptCF, CFURLCopyAbsoluteURL(failingURL)); | |
97 | if (absoluteURLRef.get()) { | |
98 | failingURLString = CFURLGetString(absoluteURLRef.get()); | |
99 | m_failingURL = String(failingURLString); | |
100 | } | |
101 | } | |
102 | } | |
103 | m_localizedDescription = (CFStringRef) CFDictionaryGetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey); | |
104 | } | |
105 | ||
106 | m_dataIsUpToDate = true; | |
107 | } | |
108 | ||
109 | bool ResourceError::platformCompare(const ResourceError& a, const ResourceError& b) | |
110 | { | |
111 | return (CFErrorRef)a == (CFErrorRef)b; | |
112 | } | |
113 | ||
114 | ResourceError::operator CFErrorRef() const | |
115 | { | |
116 | if (m_isNull) { | |
117 | ASSERT(!m_platformError); | |
118 | return nil; | |
119 | } | |
120 | ||
121 | if (!m_platformError) { | |
122 | RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); | |
123 | ||
124 | if (!m_localizedDescription.isEmpty()) { | |
125 | RetainPtr<CFStringRef> localizedDescriptionString(AdoptCF, m_localizedDescription.createCFString()); | |
126 | CFDictionarySetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey, localizedDescriptionString.get()); | |
127 | } | |
128 | ||
129 | if (!m_failingURL.isEmpty()) { | |
130 | RetainPtr<CFStringRef> failingURLString(AdoptCF, m_failingURL.createCFString()); | |
131 | CFDictionarySetValue(userInfo.get(), failingURLStringKey, failingURLString.get()); | |
132 | RetainPtr<CFURLRef> url(AdoptCF, KURL(m_failingURL).createCFURL()); | |
133 | CFDictionarySetValue(userInfo.get(), failingURLKey, url.get()); | |
134 | } | |
135 | ||
136 | RetainPtr<CFStringRef> domainString(AdoptCF, m_domain.createCFString()); | |
137 | m_platformError.adoptCF(CFErrorCreate(0, domainString.get(), m_errorCode, userInfo.get())); | |
138 | } | |
139 | ||
140 | return m_platformError.get(); | |
141 | } | |
142 | ||
143 | ResourceError::operator CFStreamError() const | |
144 | { | |
145 | lazyInit(); | |
146 | ||
147 | CFStreamError result; | |
148 | result.error = m_errorCode; | |
149 | ||
150 | if (m_domain == "NSCustomErrorDomain") | |
151 | result.domain = kCFStreamErrorDomainCustom; | |
152 | else if (m_domain == "NSPOSIXErrorDomain") | |
153 | result.domain = kCFStreamErrorDomainPOSIX; | |
154 | else if (m_domain == "NSOSStatusErrorDomain") | |
155 | result.domain = kCFStreamErrorDomainMacOSStatus; | |
156 | else | |
157 | ASSERT_NOT_REACHED(); | |
158 | ||
159 | return result; | |
160 | } | |
161 | ||
162 | } // namespace WebCore | |
163 | ||
164 | #endif // USE(CFNETWORK) |