URLAccessBinInputStream.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:8k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  *
  56.  * Written by James D. Berry 7/20/00
  57.  * Critical Path Software, Inc.
  58.  */
  59. /*
  60.  * $Id: URLAccessBinInputStream.cpp,v 1.5 2003/05/17 05:54:18 knoaman Exp $
  61.  */
  62. #include <xercesc/util/XMLNetAccessor.hpp>
  63. #include <xercesc/util/NetAccessors/MacOSURLAccess/URLAccessBinInputStream.hpp>
  64. #include <xercesc/util/XMLString.hpp>
  65. #include <xercesc/util/XMLExceptMsgs.hpp>
  66. #include <xercesc/util/Janitor.hpp>
  67. #include <cstdlib>
  68. #include <cstring>
  69. XERCES_CPP_NAMESPACE_BEGIN
  70. URLAccessBinInputStream::URLAccessBinInputStream(const XMLURL& urlSource)
  71.       : mBytesProcessed(0),
  72.         mURLReference(NULL),
  73.         mBuffer(NULL),
  74.         mBufPos(NULL),
  75.         mBufAvailable(0)
  76. {
  77. OSStatus status = noErr;
  78. // Get the full URL from the source
  79.     char*               url = XMLString::transcode(urlSource.getURLText(), urlSource.getMemoryManager());
  80.     ArrayJanitor<char>  janBuf(url, urlSource.getMemoryManager());
  81. // Create a URL reference from the URL
  82. status = URLNewReference(url, &mURLReference);
  83. // Begin the transfer
  84. if (status == noErr)
  85. status = URLOpen(
  86. mURLReference,
  87. NULL, // FSSpec* (not reading to file)
  88. 0,  // URLOpenFlags
  89. NULL, // URLNotifyUPP
  90. 0, // URLEventMask
  91. 0); // userContext
  92. // If we failed, we throw
  93. switch (status)
  94. {
  95. case noErr:
  96. break;
  97. case kURLInvalidURLError:
  98.          ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  99. break;
  100. case kURLUnsupportedSchemeError:
  101.          ThrowXML(MalformedURLException, XMLExcepts::URL_UnsupportedProto);
  102. break;
  103. default:
  104.          ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ConnSocket, urlSource.getURLText());
  105.          break;
  106. }
  107. }
  108. URLAccessBinInputStream::~URLAccessBinInputStream()
  109. {
  110. OSStatus status = noErr;
  111. // Release any buffer we've still got a hold of
  112. if (status == noErr && mBuffer)
  113. {
  114. status = URLReleaseBuffer(mURLReference, mBuffer);
  115. mBuffer = NULL;
  116. }
  117. // Get the current state
  118. URLState state = 0;
  119. if (status == noErr)
  120. status = URLGetCurrentState(mURLReference, &state);
  121. // Abort if we're not completed
  122. if (status == noErr && state != kURLNullState && state != kURLCompletedState)
  123. status = URLAbort(mURLReference);
  124. // Loop til we reach a terminal state.
  125. // This may be unneeded by URLAccess, but the docs are
  126. // not very good.
  127. while (
  128. status == noErr
  129.  && state != kURLNullState
  130.  && state != kURLErrorOccurredState
  131.  && state != kURLCompletedState
  132.   )
  133. {
  134. status = URLIdle();
  135. if (status == noErr)
  136. status = URLGetCurrentState(mURLReference, &state);
  137. }
  138. // Dispose the reference
  139. status = URLDisposeReference(mURLReference);
  140. }
  141. //
  142. // Call URLAccess to fullfill the read request. Since it
  143. // passes us back buffers full of data, our object maintains
  144. // a partial buffer across calls.
  145. //
  146. unsigned int
  147. URLAccessBinInputStream::readBytes(XMLByte* const    toFill
  148.                                     , const unsigned int    maxToRead)
  149. {
  150. OSStatus status = noErr;
  151. XMLByte* writePos = toFill;
  152. std::size_t bytesDesired = maxToRead;
  153. URLState state = kURLNullState;
  154. while ( // while...
  155. status == noErr // there's been no error
  156.  && bytesDesired > 0 // more data is wanted
  157.  && (status = URLGetCurrentState(mURLReference, &state)) == noErr // we can get the state
  158.  && (state != kURLErrorOccurredState) // no error has occurred in the transaction
  159.  && (mBuffer || state != kURLCompletedState) // we have data still buffered or the request isn't complete
  160.  && (mBuffer || bytesDesired == maxToRead) // we have data still buffered or we've supplied absolutely none
  161.   )
  162. {
  163. // Give time to URLAccess
  164. status = URLIdle();
  165. // If we've got buffered data, use it
  166. if (status == noErr && mBuffer)
  167. {
  168. // Supply as much as we can from the buffer
  169. std::size_t n = mBufAvailable;
  170. if (n > bytesDesired)
  171. n = bytesDesired;
  172. // If we've got data, copy it over and update our pointers
  173. if (n > 0)
  174. {
  175. std::memcpy(writePos, mBufPos, n);
  176. writePos += n;
  177. bytesDesired -= n;
  178. mBufPos += n;
  179. mBufAvailable -= n;
  180. mBytesProcessed += n;
  181. }
  182. // If we exhausted the buffer, release it
  183. if (mBufAvailable == 0)
  184. {
  185. status = URLReleaseBuffer(mURLReference, mBuffer);
  186. mBuffer = NULL;
  187. }
  188. }
  189. // If the buffer is exhausted, get a new one
  190. if (status == noErr && !mBuffer)
  191. {
  192. status = URLGetBuffer(mURLReference, &mBuffer, &mBufAvailable);
  193. if (status == noErr)
  194. mBufPos = reinterpret_cast<char*>(mBuffer);
  195. }
  196. }
  197. // Throw on any error
  198. if (status != noErr || state == kURLErrorOccurredState)
  199.     ThrowXML(NetAccessorException, XMLExcepts::NetAcc_ReadSocket);
  200. // Return number of bytes delivered
  201. return maxToRead - bytesDesired;
  202. }
  203. XERCES_CPP_NAMESPACE_END