GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: URLAccessCFBinInputStream.cpp 936316 2010-04-21 14:19:58Z borisk $ 00020 */ 00021 00022 #include <cstdlib> 00023 #include <cstring> 00024 00025 #include <xercesc/util/XMLNetAccessor.hpp> 00026 #include <xercesc/util/NetAccessors/MacOSURLAccessCF/URLAccessCFBinInputStream.hpp> 00027 #include <xercesc/util/XMLString.hpp> 00028 #include <xercesc/util/XMLExceptMsgs.hpp> 00029 #include <xercesc/util/Janitor.hpp> 00030 00031 XERCES_CPP_NAMESPACE_BEGIN 00032 00033 URLAccessCFBinInputStream::URLAccessCFBinInputStream(const XMLURL& urlSource) 00034 : mBytesProcessed(0), 00035 mDataRef(NULL) 00036 { 00037 // Figure out what we're dealing with 00038 const XMLCh* urlText = urlSource.getURLText(); 00039 unsigned int urlLength = XMLString::stringLen(urlText); 00040 00041 // Create a CFString from the path 00042 CFStringRef stringRef = NULL; 00043 if (urlText) 00044 { 00045 stringRef = CFStringCreateWithCharacters( 00046 kCFAllocatorDefault, 00047 urlText, 00048 urlLength 00049 ); 00050 } 00051 00052 // Create a URLRef from the CFString 00053 CFURLRef urlRef = NULL; 00054 if (stringRef) 00055 { 00056 urlRef = CFURLCreateWithString( 00057 kCFAllocatorDefault, 00058 stringRef, 00059 NULL // CFURLRef baseURL 00060 ); 00061 } 00062 00063 // Fetch the data 00064 mDataRef = NULL; 00065 SInt32 errorCode = 0; 00066 Boolean success = false; 00067 if (stringRef) 00068 { 00069 success = CFURLCreateDataAndPropertiesFromResource( 00070 kCFAllocatorDefault, 00071 urlRef, 00072 &mDataRef, 00073 NULL, // CFDictionaryRef *properties, 00074 NULL, // CFArrayRef desiredProperties, 00075 &errorCode 00076 ); 00077 } 00078 00079 // Cleanup temporary stuff 00080 if (stringRef) 00081 CFRelease(stringRef); 00082 if (urlRef) 00083 CFRelease(urlRef); 00084 00085 // Check for an error in fetching the data 00086 if (!success || errorCode) 00087 { 00088 // Dispose any potential dataRef 00089 if (mDataRef) 00090 { 00091 CFRelease(mDataRef); 00092 mDataRef = NULL; 00093 } 00094 00095 // Do a best attempt at mapping some errors 00096 switch (errorCode) 00097 { 00098 case kCFURLUnknownSchemeError: 00099 ThrowXML(MalformedURLException, XMLExcepts::URL_UnsupportedProto); 00100 break; 00101 00102 case kCFURLRemoteHostUnavailableError: 00103 { 00104 if (urlSource.getHost()) 00105 ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_TargetResolution, urlSource.getHost()); 00106 else 00107 ThrowXML1(NetAccessorException, XMLExcepts::File_CouldNotOpenFile, urlText); 00108 break; 00109 } 00110 00111 case kCFURLUnknownError: 00112 ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, urlText); 00113 break; 00114 00115 case kCFURLResourceNotFoundError: 00116 case kCFURLResourceAccessViolationError: 00117 case kCFURLTimeoutError: 00118 ThrowXML1(NetAccessorException, XMLExcepts::File_CouldNotOpenFile, urlText); 00119 break; 00120 00121 case kCFURLImproperArgumentsError: 00122 case kCFURLUnknownPropertyKeyError: 00123 case kCFURLPropertyKeyUnavailableError: 00124 default: 00125 ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_InternalError, urlText); 00126 break; 00127 } 00128 } 00129 } 00130 00131 00132 URLAccessCFBinInputStream::~URLAccessCFBinInputStream() 00133 { 00134 // Release any dataRef 00135 if (mDataRef) 00136 CFRelease(mDataRef); 00137 } 00138 00139 00140 // 00141 // We've already read the data into a dataRef. 00142 // Just spoon it out to the caller as they ask for it. 00143 // 00144 XMLSize_t 00145 URLAccessCFBinInputStream::readBytes(XMLByte* const toFill 00146 , const XMLSize_t maxToRead) 00147 { 00148 // If we don't have a dataRef, we can't return any data 00149 if (!mDataRef) 00150 return 0; 00151 00152 // Get the length of the data we've fetched 00153 CFIndex dataLength = CFDataGetLength(mDataRef); 00154 00155 // Calculate how much to return based on how much 00156 // we've already returned, and how much the user wants 00157 CFIndex n = dataLength - mBytesProcessed; // Amount remaining 00158 CFIndex desired = maxToRead & 0x7fffffff; // CFIndex is signed 00159 if (n > desired) // Amount desired 00160 n = desired; 00161 00162 // Read the appropriate bytes into the user buffer 00163 CFRange range = CFRangeMake(mBytesProcessed, n); 00164 CFDataGetBytes(mDataRef, range, reinterpret_cast<UInt8*>(toFill)); 00165 00166 // Update bytes processed 00167 mBytesProcessed += n; 00168 00169 // Return the number of bytes delivered 00170 return n; 00171 } 00172 00173 const XMLCh* URLAccessCFBinInputStream::getContentType() const 00174 { 00175 // TODO 00176 // 00177 return 0; 00178 } 00179 00180 XERCES_CPP_NAMESPACE_END