LCOV - app.info - xpcom/io/nsStringStream.cpp

LCOV - code coverage report
| Current view: | directory - xpcom/io - nsStringStream.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 161 | 108 | 67.1 %
| Date: | 2012-04-21 | Functions: | 31 | 23 | 74.2 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
           2                 : /* vim:set ts=4 sts=4 sw=4 cin et: */
           3                 : /* ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is mozilla.org code.
          17                 :  *
          18                 :  * The Initial Developer of the Original Code is
          19                 :  * Netscape Communications Corporation.
          20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          21                 :  * the Initial Developer. All Rights Reserved.
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   mcmullen@netscape.com (original author)
          25                 :  *   warren@netscape.com
          26                 :  *   alecf@netscape.com
          27                 :  *   scc@mozilla.org
          28                 :  *   david.gardiner@unisa.edu.au
          29                 :  *   fur@netscape.com
          30                 :  *   norris@netscape.com
          31                 :  *   pinkerton@netscape.com
          32                 :  *   davidm@netscape.com
          33                 :  *   sfraser@netscape.com
          34                 :  *   darin@netscape.com
          35                 :  *   bzbarsky@mit.edu
          36                 :  *
          37                 :  * Alternatively, the contents of this file may be used under the terms of
          38                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          39                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          40                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          41                 :  * of those above. If you wish to allow use of your version of this file only
          42                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          43                 :  * use your version of this file under the terms of the MPL, indicate your
          44                 :  * decision by deleting the provisions above and replace them with the notice
          45                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          46                 :  * the provisions above, a recipient may use your version of this file under
          47                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          48                 :  *
          49                 :  * ***** END LICENSE BLOCK ***** */
          50                 :
          51                 : /**
          52                 :  * Based on original code from nsIStringStream.cpp
          53                 :  */
          54                 :
          55                 : #include "IPC/IPCMessageUtils.h"
          56                 :
          57                 : #include "nsStringStream.h"
          58                 : #include "nsStreamUtils.h"
          59                 : #include "nsReadableUtils.h"
          60                 : #include "nsISeekableStream.h"
          61                 : #include "nsISupportsPrimitives.h"
          62                 : #include "nsCRT.h"
          63                 : #include "prerror.h"
          64                 : #include "plstr.h"
          65                 : #include "nsIClassInfoImpl.h"
          66                 : #include "nsIIPCSerializable.h"
          67                 :
          68                 : //-----------------------------------------------------------------------------
          69                 : // nsIStringInputStream implementation
          70                 : //-----------------------------------------------------------------------------
          71                 :
          72                 : class nsStringInputStream : public nsIStringInputStream
          73                 :                           , public nsISeekableStream
          74                 :                           , public nsISupportsCString
          75                 :                           , public nsIIPCSerializable
          76                 : {
          77                 : public:
          78                 :     NS_DECL_ISUPPORTS
          79                 :     NS_DECL_NSIINPUTSTREAM
          80                 :     NS_DECL_NSISTRINGINPUTSTREAM
          81                 :     NS_DECL_NSISEEKABLESTREAM
          82                 :     NS_DECL_NSISUPPORTSPRIMITIVE
          83                 :     NS_DECL_NSISUPPORTSCSTRING
          84                 :     NS_DECL_NSIIPCSERIALIZABLE
          85                 :
          86          202112 :     nsStringInputStream()
          87          202112 :     {
          88          202112 :         Clear();
          89          202112 :     }
          90                 :
          91                 : private:
          92          202100 :     ~nsStringInputStream()
          93          202100 :     {}
          94                 :
          95          793591 :     PRUint32 Length() const
          96                 :     {
          97          793591 :         return mData.Length();
          98                 :     }
          99                 :
         100          398946 :     PRUint32 LengthRemaining() const
         101                 :     {
         102          398946 :         return Length() - mOffset;
         103                 :     }
         104                 :
         105          202413 :     void Clear()
         106                 :     {
         107          202413 :         mData.SetIsVoid(true);
         108          202413 :     }
         109                 :
         110          398948 :     bool Closed()
         111                 :     {
         112          398948 :         return mData.IsVoid();
         113                 :     }
         114                 :
         115                 :     nsDependentCSubstring mData;
         116                 :     PRUint32 mOffset;
         117                 : };
         118                 :
         119                 : // This class needs to support threadsafe refcounting since people often
         120                 : // allocate a string stream, and then read it from a background thread.
         121          615580 : NS_IMPL_THREADSAFE_ADDREF(nsStringInputStream)
         122          817668 : NS_IMPL_THREADSAFE_RELEASE(nsStringInputStream)
         123                 :
         124                 : NS_IMPL_CLASSINFO(nsStringInputStream, NULL, nsIClassInfo::THREADSAFE,
         125                 :                   NS_STRINGINPUTSTREAM_CID)
         126          422963 : NS_IMPL_QUERY_INTERFACE5_CI(nsStringInputStream,
         127                 :                             nsIStringInputStream,
         128                 :                             nsIInputStream,
         129                 :                             nsISupportsCString,
         130                 :                             nsISeekableStream,
         131            1859 :                             nsIIPCSerializable)
         132             789 : NS_IMPL_CI_INTERFACE_GETTER5(nsStringInputStream,
         133                 :                              nsIStringInputStream,
         134                 :                              nsIInputStream,
         135                 :                              nsISupportsCString,
         136                 :                              nsISeekableStream,
         137             789 :                              nsIIPCSerializable)
         138                 :
         139                 : /////////
         140                 : // nsISupportsCString implementation
         141                 : /////////
         142                 :
         143                 : NS_IMETHODIMP
         144               0 : nsStringInputStream::GetType(PRUint16 *type)
         145                 : {
         146               0 :     *type = TYPE_CSTRING;
         147               0 :     return NS_OK;
         148                 : }
         149                 :
         150                 : NS_IMETHODIMP
         151               0 : nsStringInputStream::GetData(nsACString &data)
         152                 : {
         153                 :     // The stream doesn't have any data when it is closed.  We could fake it
         154                 :     // and return an empty string here, but it seems better to keep this return
         155                 :     // value consistent with the behavior of the other 'getter' methods.
         156               0 :     NS_ENSURE_TRUE(!Closed(), NS_BASE_STREAM_CLOSED);
         157                 :
         158               0 :     data.Assign(mData);
         159               0 :     return NS_OK;
         160                 : }
         161                 :
         162                 : NS_IMETHODIMP
         163            1119 : nsStringInputStream::SetData(const nsACString &data)
         164                 : {
         165            1119 :     mData.Assign(data);
         166            1119 :     mOffset = 0;
         167            1119 :     return NS_OK;
         168                 : }
         169                 :
         170                 : NS_IMETHODIMP
         171               0 : nsStringInputStream::ToString(char **result)
         172                 : {
         173                 :     // NOTE: This method may result in data loss, so we do not implement it.
         174               0 :     return NS_ERROR_NOT_IMPLEMENTED;
         175                 : }
         176                 :
         177                 : /////////
         178                 : // nsIStringInputStream implementation
         179                 : /////////
         180                 :
         181                 : NS_IMETHODIMP
         182             709 : nsStringInputStream::SetData(const char *data, PRInt32 dataLen)
         183                 : {
         184             709 :     NS_ENSURE_ARG_POINTER(data);
         185             709 :     mData.Assign(data, dataLen);
         186             709 :     mOffset = 0;
         187             709 :     return NS_OK;
         188                 : }
         189                 :
         190                 : NS_IMETHODIMP
         191             944 : nsStringInputStream::AdoptData(char *data, PRInt32 dataLen)
         192                 : {
         193             944 :     NS_ENSURE_ARG_POINTER(data);
         194             944 :     mData.Adopt(data, dataLen);
         195             944 :     mOffset = 0;
         196             944 :     return NS_OK;
         197                 : }
         198                 :
         199                 : NS_IMETHODIMP
         200          203888 : nsStringInputStream::ShareData(const char *data, PRInt32 dataLen)
         201                 : {
         202          203888 :     NS_ENSURE_ARG_POINTER(data);
         203                 :
         204          203888 :     if (dataLen < 0)
         205               2 :         dataLen = strlen(data);
         206                 :
         207          203888 :     mData.Rebind(data, dataLen);
         208          203888 :     mOffset = 0;
         209          203888 :     return NS_OK;
         210                 : }
         211                 :
         212                 : /////////
         213                 : // nsIInputStream implementation
         214                 : /////////
         215                 :
         216                 : NS_IMETHODIMP
         217             301 : nsStringInputStream::Close()
         218                 : {
         219             301 :     Clear();
         220             301 :     return NS_OK;
         221                 : }
         222                 :
         223                 : NS_IMETHODIMP
         224            4303 : nsStringInputStream::Available(PRUint32 *aLength)
         225                 : {
         226            4303 :     NS_ASSERTION(aLength, "null ptr");
         227                 :
         228            4303 :     if (Closed())
         229               0 :         return NS_BASE_STREAM_CLOSED;
         230                 :
         231            4303 :     *aLength = LengthRemaining();
         232            4303 :     return NS_OK;
         233                 : }
         234                 :
         235                 : NS_IMETHODIMP
         236          386286 : nsStringInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount)
         237                 : {
         238          386286 :     NS_ASSERTION(aBuf, "null ptr");
         239          386286 :     return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aReadCount);
         240                 : }
         241                 :
         242                 : NS_IMETHODIMP
         243          394643 : nsStringInputStream::ReadSegments(nsWriteSegmentFun writer, void *closure,
         244                 :                                   PRUint32 aCount, PRUint32 *result)
         245                 : {
         246          394643 :     NS_ASSERTION(result, "null ptr");
         247          394643 :     NS_ASSERTION(Length() >= mOffset, "bad stream state");
         248                 :
         249          394643 :     if (Closed())
         250               0 :         return NS_BASE_STREAM_CLOSED;
         251                 :
         252                 :     // We may be at end-of-file
         253          394643 :     PRUint32 maxCount = LengthRemaining();
         254          394643 :     if (maxCount == 0) {
         255            8997 :         *result = 0;
         256            8997 :         return NS_OK;
         257                 :     }
         258                 :
         259          385646 :     if (aCount > maxCount)
         260            9127 :         aCount = maxCount;
         261          385646 :     nsresult rv = writer(this, closure, mData.BeginReading() + mOffset, 0, aCount, result);
         262          385646 :     if (NS_SUCCEEDED(rv)) {
         263          383896 :         NS_ASSERTION(*result <= aCount,
         264                 :                      "writer should not write more than we asked it to write");
         265          383896 :         mOffset += *result;
         266                 :     }
         267                 :
         268                 :     // errors returned from the writer end here!
         269          385646 :     return NS_OK;
         270                 : }
         271                 :
         272                 : NS_IMETHODIMP
         273               1 : nsStringInputStream::IsNonBlocking(bool *aNonBlocking)
         274                 : {
         275               1 :     *aNonBlocking = true;
         276               1 :     return NS_OK;
         277                 : }
         278                 :
         279                 : /////////
         280                 : // nsISeekableStream implementation
         281                 : /////////
         282                 :
         283                 : NS_IMETHODIMP
         284               2 : nsStringInputStream::Seek(PRInt32 whence, PRInt64 offset)
         285                 : {
         286               2 :     if (Closed())
         287               0 :         return NS_BASE_STREAM_CLOSED;
         288                 :
         289                 :     // Compute new stream position.  The given offset may be a negative value.
         290                 :
         291               2 :     PRInt64 newPos = offset;
         292               2 :     switch (whence) {
         293                 :     case NS_SEEK_SET:
         294               2 :         break;
         295                 :     case NS_SEEK_CUR:
         296               0 :         newPos += mOffset;
         297               0 :         break;
         298                 :     case NS_SEEK_END:
         299               0 :         newPos += Length();
         300               0 :         break;
         301                 :     default:
         302               0 :         NS_ERROR("invalid whence");
         303               0 :         return NS_ERROR_INVALID_ARG;
         304                 :     }
         305                 :
         306               2 :     NS_ENSURE_ARG(newPos >= 0);
         307               2 :     NS_ENSURE_ARG(newPos <= Length());
         308                 :
         309               2 :     mOffset = (PRUint32)newPos;
         310               2 :     return NS_OK;
         311                 : }
         312                 :
         313                 : NS_IMETHODIMP
         314               0 : nsStringInputStream::Tell(PRInt64* outWhere)
         315                 : {
         316               0 :     if (Closed())
         317               0 :         return NS_BASE_STREAM_CLOSED;
         318                 :
         319               0 :     *outWhere = mOffset;
         320               0 :     return NS_OK;
         321                 : }
         322                 :
         323                 : NS_IMETHODIMP
         324               0 : nsStringInputStream::SetEOF()
         325                 : {
         326               0 :     if (Closed())
         327               0 :         return NS_BASE_STREAM_CLOSED;
         328                 :
         329               0 :     mOffset = Length();
         330               0 :     return NS_OK;
         331                 : }
         332                 :
         333                 : /////////
         334                 : // nsIIPCSerializable implementation
         335                 : /////////
         336                 :
         337                 : bool
         338               0 : nsStringInputStream::Read(const IPC::Message *aMsg, void **aIter)
         339                 : {
         340                 :     using IPC::ReadParam;
         341                 :
         342               0 :     nsCString value;
         343                 :
         344               0 :     if (!ReadParam(aMsg, aIter, &value))
         345               0 :         return false;
         346                 :
         347               0 :     nsresult rv = SetData(value);
         348               0 :     if (NS_FAILED(rv))
         349               0 :         return false;
         350                 :
         351               0 :     return true;
         352                 : }
         353                 :
         354                 : void
         355               0 : nsStringInputStream::Write(IPC::Message *aMsg)
         356                 : {
         357                 :     using IPC::WriteParam;
         358                 :
         359               0 :     WriteParam(aMsg, static_cast<const nsCString&>(PromiseFlatCString(mData)));
         360               0 : }
         361                 :
         362                 : nsresult
         363            3827 : NS_NewByteInputStream(nsIInputStream** aStreamResult,
         364                 :                       const char* aStringToRead, PRInt32 aLength,
         365                 :                       nsAssignmentType aAssignment)
         366                 : {
         367            3827 :     NS_PRECONDITION(aStreamResult, "null out ptr");
         368                 :
         369            3827 :     nsStringInputStream* stream = new nsStringInputStream();
         370            3827 :     if (! stream)
         371               0 :         return NS_ERROR_OUT_OF_MEMORY;
         372                 :
         373            3827 :     NS_ADDREF(stream);
         374                 :
         375                 :     nsresult rv;
         376            3827 :     switch (aAssignment) {
         377                 :     case NS_ASSIGNMENT_COPY:
         378               0 :         rv = stream->SetData(aStringToRead, aLength);
         379               0 :         break;
         380                 :     case NS_ASSIGNMENT_DEPEND:
         381            3827 :         rv = stream->ShareData(aStringToRead, aLength);
         382            3827 :         break;
         383                 :     case NS_ASSIGNMENT_ADOPT:
         384               0 :         rv = stream->AdoptData(const_cast<char*>(aStringToRead), aLength);
         385               0 :         break;
         386                 :     default:
         387               0 :         NS_ERROR("invalid assignment type");
         388               0 :         rv = NS_ERROR_INVALID_ARG;
         389                 :     }
         390                 :
         391            3827 :     if (NS_FAILED(rv)) {
         392               0 :         NS_RELEASE(stream);
         393               0 :         return rv;
         394                 :     }
         395                 :
         396            3827 :     *aStreamResult = stream;
         397            3827 :     return NS_OK;
         398                 : }
         399                 :
         400                 : nsresult
         401               0 : NS_NewStringInputStream(nsIInputStream** aStreamResult,
         402                 :                         const nsAString& aStringToRead)
         403                 : {
         404               0 :     NS_LossyConvertUTF16toASCII data(aStringToRead); // truncates high-order bytes
         405               0 :     return NS_NewCStringInputStream(aStreamResult, data);
         406                 : }
         407                 :
         408                 : nsresult
         409             273 : NS_NewCStringInputStream(nsIInputStream** aStreamResult,
         410                 :                          const nsACString& aStringToRead)
         411                 : {
         412             273 :     NS_PRECONDITION(aStreamResult, "null out ptr");
         413                 :
         414             273 :     nsStringInputStream* stream = new nsStringInputStream();
         415             273 :     if (! stream)
         416               0 :         return NS_ERROR_OUT_OF_MEMORY;
         417                 :
         418             273 :     NS_ADDREF(stream);
         419                 :
         420             273 :     stream->SetData(aStringToRead);
         421                 :
         422             273 :     *aStreamResult = stream;
         423             273 :     return NS_OK;
         424                 : }
         425                 :
         426                 : // factory method for constructing a nsStringInputStream object
         427                 : nsresult
         428          198012 : nsStringInputStreamConstructor(nsISupports *outer, REFNSIID iid, void **result)
         429                 : {
         430          198012 :     *result = nsnull;
         431                 :
         432          198012 :     NS_ENSURE_TRUE(!outer, NS_ERROR_NO_AGGREGATION);
         433                 :
         434          198012 :     nsStringInputStream *inst = new nsStringInputStream();
         435          198012 :     if (!inst)
         436               0 :         return NS_ERROR_OUT_OF_MEMORY;
         437                 :
         438          198012 :     NS_ADDREF(inst);
         439          198012 :     nsresult rv = inst->QueryInterface(iid, result);
         440          198012 :     NS_RELEASE(inst);
         441                 :
         442          198012 :     return rv;
         443                 : }

Generated by: LCOV version 1.7