Fix windows build.
[WebKit-https.git] / Source / WebCore / platform / network / cf / ResourceErrorCF.cpp
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 "ResourceError.h"
28
29 #if USE(CFNETWORK)
30
31 #include "KURL.h"
32 #include <CoreFoundation/CFError.h>
33 #include <CFNetwork/CFNetworkErrors.h>
34 #include <WTF/RetainPtr.h>
35
36 namespace WebCore {
37
38 ResourceError::ResourceError(CFErrorRef cfError)
39     : m_dataIsUpToDate(false)
40     , m_platformError(cfError)
41 {
42     m_isNull = !cfError;
43 }
44
45 const CFStringRef failingURLStringKey = CFSTR("NSErrorFailingURLStringKey");
46 const CFStringRef failingURLKey = CFSTR("NSErrorFailingURLKey");
47
48 void ResourceError::platformLazyInit()
49 {
50     if (m_dataIsUpToDate)
51         return;
52
53     if (!m_platformError)
54         return;
55
56     CFStringRef domain = CFErrorGetDomain(m_platformError.get());
57     if (domain == kCFErrorDomainMach || domain == kCFErrorDomainCocoa)
58         m_domain ="NSCustomErrorDomain";
59     else if (domain == kCFErrorDomainCFNetwork)
60         m_domain = "CFURLErrorDomain";
61     else if (domain == kCFErrorDomainPOSIX)
62         m_domain = "NSPOSIXErrorDomain";
63     else if (domain == kCFErrorDomainOSStatus)
64         m_domain = "NSOSStatusErrorDomain";
65     else if (domain == kCFErrorDomainWinSock)
66         m_domain = "kCFErrorDomainWinSock";
67
68     m_errorCode = CFErrorGetCode(m_platformError.get());
69
70     RetainPtr<CFDictionaryRef> userInfo(AdoptCF, CFErrorCopyUserInfo(m_platformError.get()));
71     if (userInfo.get()) {
72         CFStringRef failingURLString = (CFStringRef) CFDictionaryGetValue(userInfo.get(), failingURLStringKey);
73         if (failingURLString)
74             m_failingURL = String(failingURLString);
75         else {
76             CFURLRef failingURL = (CFURLRef) CFDictionaryGetValue(userInfo.get(), failingURLKey);
77             if (failingURL) {
78                 RetainPtr<CFURLRef> absoluteURLRef(AdoptCF, CFURLCopyAbsoluteURL(failingURL));
79                 if (absoluteURLRef.get()) {
80                     failingURLString = CFURLGetString(absoluteURLRef.get());
81                     m_failingURL = String(failingURLString);
82                 }
83             }
84         }
85         m_localizedDescription = (CFStringRef) CFDictionaryGetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey);
86     }
87
88     m_dataIsUpToDate = true;
89 }
90
91 bool ResourceError::platformCompare(const ResourceError& a, const ResourceError& b)
92 {
93     return a.cfError() == b.cfError();
94 }
95
96 CFErrorRef ResourceError::cfError() const
97 {
98     if (m_isNull) {
99         ASSERT(!m_platformError);
100         return 0;
101     }
102
103     if (!m_platformError) {
104         RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
105
106         if (!m_localizedDescription.isEmpty()) {
107             RetainPtr<CFStringRef> localizedDescriptionString(AdoptCF, m_localizedDescription.createCFString());
108             CFDictionarySetValue(userInfo.get(), kCFErrorLocalizedDescriptionKey, localizedDescriptionString.get());
109         }
110
111         if (!m_failingURL.isEmpty()) {
112             RetainPtr<CFStringRef> failingURLString(AdoptCF, m_failingURL.createCFString());
113             CFDictionarySetValue(userInfo.get(), failingURLStringKey, failingURLString.get());
114             RetainPtr<CFURLRef> url(AdoptCF, KURL(ParsedURLString, m_failingURL).createCFURL());
115             CFDictionarySetValue(userInfo.get(), failingURLKey, url.get());
116         }
117
118         RetainPtr<CFStringRef> domainString(AdoptCF, m_domain.createCFString());
119         m_platformError.adoptCF(CFErrorCreate(0, domainString.get(), m_errorCode, userInfo.get()));
120     }
121
122     return m_platformError.get();
123 }
124
125 ResourceError::operator CFErrorRef() const
126 {
127     return cfError();
128 }
129
130 // FIXME: Once <rdar://problem/5050841> is fixed we can remove this constructor.
131 ResourceError::ResourceError(CFStreamError error)
132     : m_dataIsUpToDate(true)
133 {
134     m_isNull = false;
135     m_errorCode = error.error;
136
137     switch(error.domain) {
138     case kCFStreamErrorDomainCustom:
139         m_domain ="NSCustomErrorDomain";
140         break;
141     case kCFStreamErrorDomainPOSIX:
142         m_domain = "NSPOSIXErrorDomain";
143         break;
144     case kCFStreamErrorDomainMacOSStatus:
145         m_domain = "NSOSStatusErrorDomain";
146         break;
147     }
148 }
149
150 CFStreamError ResourceError::cfStreamError() const
151 {
152     lazyInit();
153
154     CFStreamError result;
155     result.error = m_errorCode;
156
157     if (m_domain == "NSCustomErrorDomain")
158         result.domain = kCFStreamErrorDomainCustom;
159     else if (m_domain == "NSPOSIXErrorDomain")
160         result.domain = kCFStreamErrorDomainPOSIX;
161     else if (m_domain == "NSOSStatusErrorDomain")
162         result.domain = kCFStreamErrorDomainMacOSStatus;
163     else
164         ASSERT_NOT_REACHED();
165
166     return result;
167 }
168
169 ResourceError::operator CFStreamError() const
170 {
171     return cfStreamError();
172 }
173
174 } // namespace WebCore
175
176 #endif // USE(CFNETWORK)