URLAccessBinInputStream.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:7k
源码类别:

xml/soap/webservice

开发平台:

C/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.2 2000/10/09 19:14:48 jberry Exp $
  61.  */
  62. #include <util/XMLNetAccessor.hpp>
  63. #include <util/NetAccessors/MacOSURLAccess/URLAccessBinInputStream.hpp>
  64. #include <util/XMLString.hpp>
  65. #include <util/XMLExceptMsgs.hpp>
  66. #include <util/Janitor.hpp>
  67. #include <cstdlib>
  68. #include <cstring>
  69. URLAccessBinInputStream::URLAccessBinInputStream(const XMLURL& urlSource)
  70.       : mBytesProcessed(0),
  71.         mURLReference(NULL),
  72.         mBuffer(NULL),
  73.         mBufPos(NULL),
  74.         mBufAvailable(0)
  75. {
  76. OSStatus status = noErr;
  77. // Get the full URL from the source
  78.     char*               url = XMLString::transcode(urlSource.getURLText());
  79.     ArrayJanitor<char>  janBuf(url);
  80. // Create a URL reference from the URL
  81. status = URLNewReference(url, &mURLReference);
  82. // Begin the transfer
  83. if (status == noErr)
  84. status = URLOpen(
  85. mURLReference,
  86. NULL, // FSSpec* (not reading to file)
  87. 0,  // URLOpenFlags
  88. NULL, // URLNotifyUPP
  89. 0, // URLEventMask
  90. 0); // userContext
  91. // If we failed, we throw
  92. switch (status)
  93. {
  94. case noErr:
  95. break;
  96. case kURLInvalidURLError:
  97.          ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  98. break;
  99. case kURLUnsupportedSchemeError:
  100.          ThrowXML(MalformedURLException, XMLExcepts::URL_UnsupportedProto);
  101. break;
  102. default:
  103.          ThrowXML(NetAccessorException, XMLExcepts::NetAcc_ConnSocket);
  104.          break;
  105. }
  106. }
  107. URLAccessBinInputStream::~URLAccessBinInputStream()
  108. {
  109. OSStatus status = noErr;
  110. // Release any buffer we've still got a hold of
  111. if (status == noErr && mBuffer)
  112. {
  113. status = URLReleaseBuffer(mURLReference, mBuffer);
  114. mBuffer = NULL;
  115. }
  116. // Get the current state
  117. URLState state = 0;
  118. if (status == noErr)
  119. status = URLGetCurrentState(mURLReference, &state);
  120. // Abort if we're not completed
  121. if (status == noErr && state != kURLNullState && state != kURLCompletedState)
  122. status = URLAbort(mURLReference);
  123. // Loop til we reach a terminal state.
  124. // This may be unneeded by URLAccess, but the docs are
  125. // not very good.
  126. while (
  127. status == noErr
  128.  && state != kURLNullState
  129.  && state != kURLErrorOccurredState
  130.  && state != kURLCompletedState
  131.   )
  132. {
  133. status = URLIdle();
  134. if (status == noErr)
  135. status = URLGetCurrentState(mURLReference, &state);
  136. }
  137. // Dispose the reference
  138. status = URLDisposeReference(mURLReference);
  139. }
  140. //
  141. // Call URLAccess to fullfill the read request. Since it
  142. // passes us back buffers full of data, our object maintains
  143. // a partial buffer across calls.
  144. //
  145. unsigned int
  146. URLAccessBinInputStream::readBytes(XMLByte* const    toFill
  147.                                     , const unsigned int    maxToRead)
  148. {
  149. OSStatus status = noErr;
  150. XMLByte* writePos = toFill;
  151. std::size_t bytesDesired = maxToRead;
  152. URLState state = kURLNullState;
  153. while ( // while...
  154. status == noErr // there's been no error
  155.  && bytesDesired > 0 // more data is wanted
  156.  && (status = URLGetCurrentState(mURLReference, &state)) == noErr // we can get the state
  157.  && (state != kURLErrorOccurredState) // no error has occurred in the transaction
  158.  && (mBuffer || state != kURLCompletedState) // we have data still buffered or the request isn't complete
  159.  && (mBuffer || bytesDesired == maxToRead) // we have data still buffered or we've supplied absolutely none
  160.   )
  161. {
  162. // Give time to URLAccess
  163. status = URLIdle();
  164. // If we've got buffered data, use it
  165. if (status == noErr && mBuffer)
  166. {
  167. // Supply as much as we can from the buffer
  168. std::size_t n = mBufAvailable;
  169. if (n > bytesDesired)
  170. n = bytesDesired;
  171. // If we've got data, copy it over and update our pointers
  172. if (n > 0)
  173. {
  174. std::memcpy(writePos, mBufPos, n);
  175. writePos += n;
  176. bytesDesired -= n;
  177. mBufPos += n;
  178. mBufAvailable -= n;
  179. mBytesProcessed += n;
  180. }
  181. // If we exhausted the buffer, release it
  182. if (mBufAvailable == 0)
  183. {
  184. status = URLReleaseBuffer(mURLReference, mBuffer);
  185. mBuffer = NULL;
  186. }
  187. }
  188. // If the buffer is exhausted, get a new one
  189. if (status == noErr && !mBuffer)
  190. {
  191. status = URLGetBuffer(mURLReference, &mBuffer, &mBufAvailable);
  192. if (status == noErr)
  193. mBufPos = reinterpret_cast<char*>(mBuffer);
  194. }
  195. }
  196. // Throw on any error
  197. if (status != noErr || state == kURLErrorOccurredState)
  198.     ThrowXML(NetAccessorException, XMLExcepts::NetAcc_ReadSocket);
  199. // Return number of bytes delivered
  200. return maxToRead - bytesDesired;
  201. }