netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsWyciwyg.h"
     7 #include "base/compiler_specific.h"
     9 #include "mozilla/net/ChannelEventQueue.h"
    10 #include "WyciwygChannelChild.h"
    11 #include "mozilla/dom/TabChild.h"
    13 #include "nsCharsetSource.h"
    14 #include "nsStringStream.h"
    15 #include "nsNetUtil.h"
    16 #include "nsISerializable.h"
    17 #include "nsSerializationHelper.h"
    18 #include "nsIProgressEventSink.h"
    19 #include "mozilla/ipc/URIUtils.h"
    20 #include "SerializedLoadContext.h"
    22 using namespace mozilla::ipc;
    24 namespace mozilla {
    25 namespace net {
    27 NS_IMPL_ISUPPORTS(WyciwygChannelChild,
    28                   nsIRequest,
    29                   nsIChannel,
    30                   nsIWyciwygChannel,
    31                   nsIPrivateBrowsingChannel)
    34 WyciwygChannelChild::WyciwygChannelChild()
    35   : mStatus(NS_OK)
    36   , mIsPending(false)
    37   , mCanceled(false)
    38   , mLoadFlags(LOAD_NORMAL)
    39   , mContentLength(-1)
    40   , mCharsetSource(kCharsetUninitialized)
    41   , mState(WCC_NEW)
    42   , mIPCOpen(false)
    43   , mSentAppData(false)
    44 {
    45   LOG(("Creating WyciwygChannelChild @%x\n", this));
    46   mEventQ = new ChannelEventQueue(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this));
    47 }
    49 WyciwygChannelChild::~WyciwygChannelChild()
    50 {
    51   LOG(("Destroying WyciwygChannelChild @%x\n", this));
    52 }
    54 void
    55 WyciwygChannelChild::AddIPDLReference()
    56 {
    57   NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
    58   mIPCOpen = true;
    59   AddRef();
    60 }
    62 void
    63 WyciwygChannelChild::ReleaseIPDLReference()
    64 {
    65   NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
    66   mIPCOpen = false;
    67   Release();
    68 }
    70 nsresult
    71 WyciwygChannelChild::Init(nsIURI* uri)
    72 {
    73   NS_ENSURE_ARG_POINTER(uri);
    75   mState = WCC_INIT;
    77   mURI = uri;
    78   mOriginalURI = uri;
    80   URIParams serializedUri;
    81   SerializeURI(uri, serializedUri);
    83   SendInit(serializedUri);
    84   return NS_OK;
    85 }
    87 //-----------------------------------------------------------------------------
    88 // WyciwygChannelChild::PWyciwygChannelChild
    89 //-----------------------------------------------------------------------------
    91 class WyciwygStartRequestEvent : public ChannelEvent
    92 {
    93 public:
    94   WyciwygStartRequestEvent(WyciwygChannelChild* child,
    95                            const nsresult& statusCode,
    96                            const int64_t& contentLength,
    97                            const int32_t& source,
    98                            const nsCString& charset,
    99                            const nsCString& securityInfo)
   100   : mChild(child), mStatusCode(statusCode), mContentLength(contentLength),
   101     mSource(source), mCharset(charset), mSecurityInfo(securityInfo) {}
   102   void Run() { mChild->OnStartRequest(mStatusCode, mContentLength, mSource,
   103                                      mCharset, mSecurityInfo); }
   104 private:
   105   WyciwygChannelChild* mChild;
   106   nsresult mStatusCode;
   107   int64_t mContentLength;
   108   int32_t mSource;
   109   nsCString mCharset;
   110   nsCString mSecurityInfo;
   111 };
   113 bool
   114 WyciwygChannelChild::RecvOnStartRequest(const nsresult& statusCode,
   115                                         const int64_t& contentLength,
   116                                         const int32_t& source,
   117                                         const nsCString& charset,
   118                                         const nsCString& securityInfo)
   119 {
   120   if (mEventQ->ShouldEnqueue()) {
   121     mEventQ->Enqueue(new WyciwygStartRequestEvent(this, statusCode,
   122                                                  contentLength, source,
   123                                                  charset, securityInfo));
   124   } else {
   125     OnStartRequest(statusCode, contentLength, source, charset, securityInfo);
   126   }
   127   return true;
   128 }
   130 void
   131 WyciwygChannelChild::OnStartRequest(const nsresult& statusCode,
   132                                     const int64_t& contentLength,
   133                                     const int32_t& source,
   134                                     const nsCString& charset,
   135                                     const nsCString& securityInfo)
   136 {
   137   LOG(("WyciwygChannelChild::RecvOnStartRequest [this=%p]\n", this));
   139   mState = WCC_ONSTART;
   141   mStatus = statusCode;
   142   mContentLength = contentLength;
   143   mCharsetSource = source;
   144   mCharset = charset;
   146   if (!securityInfo.IsEmpty()) {
   147     NS_DeserializeObject(securityInfo, getter_AddRefs(mSecurityInfo));
   148   }
   150   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   152   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
   153   if (NS_FAILED(rv))
   154     Cancel(rv);
   155 }
   157 class WyciwygDataAvailableEvent : public ChannelEvent
   158 {
   159 public:
   160   WyciwygDataAvailableEvent(WyciwygChannelChild* child,
   161                             const nsCString& data,
   162                             const uint64_t& offset)
   163   : mChild(child), mData(data), mOffset(offset) {}
   164   void Run() { mChild->OnDataAvailable(mData, mOffset); }
   165 private:
   166   WyciwygChannelChild* mChild;
   167   nsCString mData;
   168   uint64_t mOffset;
   169 };
   171 bool
   172 WyciwygChannelChild::RecvOnDataAvailable(const nsCString& data,
   173                                          const uint64_t& offset)
   174 {
   175   if (mEventQ->ShouldEnqueue()) {
   176     mEventQ->Enqueue(new WyciwygDataAvailableEvent(this, data, offset));
   177   } else {
   178     OnDataAvailable(data, offset);
   179   }
   180   return true;
   181 }
   183 void
   184 WyciwygChannelChild::OnDataAvailable(const nsCString& data,
   185                                      const uint64_t& offset)
   186 {
   187   LOG(("WyciwygChannelChild::RecvOnDataAvailable [this=%p]\n", this));
   189   if (mCanceled)
   190     return;
   192   mState = WCC_ONDATA;
   194   // NOTE: the OnDataAvailable contract requires the client to read all the data
   195   // in the inputstream.  This code relies on that ('data' will go away after
   196   // this function).  Apparently the previous, non-e10s behavior was to actually
   197   // support only reading part of the data, allowing later calls to read the
   198   // rest.
   199   nsCOMPtr<nsIInputStream> stringStream;
   200   nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream),
   201                                       data.get(),
   202                                       data.Length(),
   203                                       NS_ASSIGNMENT_DEPEND);
   204   if (NS_FAILED(rv)) {
   205     Cancel(rv);
   206     return;
   207   }
   209   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   211   rv = mListener->OnDataAvailable(this, mListenerContext,
   212                                   stringStream, offset, data.Length());
   213   if (NS_FAILED(rv))
   214     Cancel(rv);
   216   if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
   217     mProgressSink->OnProgress(this, nullptr, offset + data.Length(),
   218                               uint64_t(mContentLength));
   219 }
   221 class WyciwygStopRequestEvent : public ChannelEvent
   222 {
   223 public:
   224   WyciwygStopRequestEvent(WyciwygChannelChild* child,
   225                           const nsresult& statusCode)
   226   : mChild(child), mStatusCode(statusCode) {}
   227   void Run() { mChild->OnStopRequest(mStatusCode); }
   228 private:
   229   WyciwygChannelChild* mChild;
   230   nsresult mStatusCode;
   231 };
   233 bool
   234 WyciwygChannelChild::RecvOnStopRequest(const nsresult& statusCode)
   235 {
   236   if (mEventQ->ShouldEnqueue()) {
   237     mEventQ->Enqueue(new WyciwygStopRequestEvent(this, statusCode));
   238   } else {
   239     OnStopRequest(statusCode);
   240   }
   241   return true;
   242 }
   244 void
   245 WyciwygChannelChild::OnStopRequest(const nsresult& statusCode)
   246 {
   247   LOG(("WyciwygChannelChild::RecvOnStopRequest [this=%p status=%u]\n",
   248            this, statusCode));
   250   { // We need to ensure that all IPDL message dispatching occurs
   251     // before we delete the protocol below
   252     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   254     mState = WCC_ONSTOP;
   256     mIsPending = false;
   258     if (!mCanceled)
   259       mStatus = statusCode;
   261     mListener->OnStopRequest(this, mListenerContext, statusCode);
   263     mListener = 0;
   264     mListenerContext = 0;
   266     if (mLoadGroup)
   267       mLoadGroup->RemoveRequest(this, nullptr, mStatus);
   269     mCallbacks = 0;
   270     mProgressSink = 0;
   271   }
   273   if (mIPCOpen)
   274     PWyciwygChannelChild::Send__delete__(this);
   275 }
   277 class WyciwygCancelEvent : public ChannelEvent
   278 {
   279  public:
   280   WyciwygCancelEvent(WyciwygChannelChild* child, const nsresult& status)
   281   : mChild(child)
   282   , mStatus(status) {}
   284   void Run() { mChild->CancelEarly(mStatus); }
   285  private:
   286   WyciwygChannelChild* mChild;
   287   nsresult mStatus;
   288 };
   290 bool
   291 WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
   292 {
   293   if (mEventQ->ShouldEnqueue()) {
   294     mEventQ->Enqueue(new WyciwygCancelEvent(this, statusCode));
   295   } else {
   296     CancelEarly(statusCode);
   297   }
   298   return true;
   299 }
   301 void WyciwygChannelChild::CancelEarly(const nsresult& statusCode)
   302 {
   303   LOG(("WyciwygChannelChild::CancelEarly [this=%p]\n", this));
   305   if (mCanceled)
   306     return;
   308   mCanceled = true;
   309   mStatus = statusCode;
   311   mIsPending = false;
   312   if (mLoadGroup)
   313     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
   315   if (mListener) {
   316     mListener->OnStartRequest(this, mListenerContext);
   317     mListener->OnStopRequest(this, mListenerContext, mStatus);
   318   }
   319   mListener = nullptr;
   320   mListenerContext = nullptr;
   322   if (mIPCOpen)
   323     PWyciwygChannelChild::Send__delete__(this);
   324 }
   326 //-----------------------------------------------------------------------------
   327 // nsIRequest
   328 //-----------------------------------------------------------------------------
   330 /* readonly attribute AUTF8String name; */
   331 NS_IMETHODIMP
   332 WyciwygChannelChild::GetName(nsACString & aName)
   333 {
   334   return mURI->GetSpec(aName);
   335 }
   337 /* boolean isPending (); */
   338 NS_IMETHODIMP
   339 WyciwygChannelChild::IsPending(bool *aIsPending)
   340 {
   341   *aIsPending = mIsPending;
   342   return NS_OK;
   343 }
   345 /* readonly attribute nsresult status; */
   346 NS_IMETHODIMP
   347 WyciwygChannelChild::GetStatus(nsresult *aStatus)
   348 {
   349   *aStatus = mStatus;
   350   return NS_OK;
   351 }
   353 /* void cancel (in nsresult aStatus); */
   354 NS_IMETHODIMP
   355 WyciwygChannelChild::Cancel(nsresult aStatus)
   356 {
   357   if (mCanceled)
   358     return NS_OK;
   360   mCanceled = true;
   361   mStatus = aStatus;
   362   if (mIPCOpen)
   363     SendCancel(aStatus);
   364   return NS_OK;
   365 }
   367 /* void suspend (); */
   368 NS_IMETHODIMP
   369 WyciwygChannelChild::Suspend()
   370 {
   371   return NS_ERROR_NOT_IMPLEMENTED;
   372 }
   374 /* void resume (); */
   375 NS_IMETHODIMP
   376 WyciwygChannelChild::Resume()
   377 {
   378   return NS_ERROR_NOT_IMPLEMENTED;
   379 }
   381 /* attribute nsILoadGroup loadGroup; */
   382 NS_IMETHODIMP
   383 WyciwygChannelChild::GetLoadGroup(nsILoadGroup * *aLoadGroup)
   384 {
   385   *aLoadGroup = mLoadGroup;
   386   NS_IF_ADDREF(*aLoadGroup);
   387   return NS_OK;
   388 }
   389 NS_IMETHODIMP
   390 WyciwygChannelChild::SetLoadGroup(nsILoadGroup * aLoadGroup)
   391 {
   392   if (!CanSetLoadGroup(aLoadGroup)) {
   393     return NS_ERROR_FAILURE;
   394   }
   396   mLoadGroup = aLoadGroup;
   397   NS_QueryNotificationCallbacks(mCallbacks,
   398                                 mLoadGroup,
   399                                 NS_GET_IID(nsIProgressEventSink),
   400                                 getter_AddRefs(mProgressSink));
   401   return NS_OK;
   402 }
   404 /* attribute nsLoadFlags loadFlags; */
   405 NS_IMETHODIMP
   406 WyciwygChannelChild::GetLoadFlags(nsLoadFlags *aLoadFlags)
   407 {
   408   *aLoadFlags = mLoadFlags;
   409   return NS_OK;
   410 }
   411 NS_IMETHODIMP
   412 WyciwygChannelChild::SetLoadFlags(nsLoadFlags aLoadFlags)
   413 {
   414   mLoadFlags = aLoadFlags;
   415   return NS_OK;
   416 }
   419 //-----------------------------------------------------------------------------
   420 // nsIChannel
   421 //-----------------------------------------------------------------------------
   423 /* attribute nsIURI originalURI; */
   424 NS_IMETHODIMP
   425 WyciwygChannelChild::GetOriginalURI(nsIURI * *aOriginalURI)
   426 {
   427   *aOriginalURI = mOriginalURI;
   428   NS_ADDREF(*aOriginalURI);
   429   return NS_OK;
   430 }
   431 NS_IMETHODIMP
   432 WyciwygChannelChild::SetOriginalURI(nsIURI * aOriginalURI)
   433 {
   434   NS_ENSURE_TRUE(mState == WCC_INIT, NS_ERROR_UNEXPECTED);
   436   NS_ENSURE_ARG_POINTER(aOriginalURI);
   437   mOriginalURI = aOriginalURI;
   438   return NS_OK;
   439 }
   441 /* readonly attribute nsIURI URI; */
   442 NS_IMETHODIMP
   443 WyciwygChannelChild::GetURI(nsIURI * *aURI)
   444 {
   445   *aURI = mURI;
   446   NS_IF_ADDREF(*aURI);
   447   return NS_OK;
   448 }
   450 /* attribute nsISupports owner; */
   451 NS_IMETHODIMP
   452 WyciwygChannelChild::GetOwner(nsISupports * *aOwner)
   453 {
   454   NS_PRECONDITION(mOwner, "Must have a principal!");
   455   NS_ENSURE_STATE(mOwner);
   457   NS_ADDREF(*aOwner = mOwner);
   458   return NS_OK;
   459 }
   460 NS_IMETHODIMP
   461 WyciwygChannelChild::SetOwner(nsISupports * aOwner)
   462 {
   463   mOwner = aOwner;
   464   return NS_OK;
   465 }
   467 /* attribute nsIInterfaceRequestor notificationCallbacks; */
   468 NS_IMETHODIMP
   469 WyciwygChannelChild::GetNotificationCallbacks(nsIInterfaceRequestor * *aCallbacks)
   470 {
   471   *aCallbacks = mCallbacks;
   472   NS_IF_ADDREF(*aCallbacks);
   473   return NS_OK;
   474 }
   475 NS_IMETHODIMP
   476 WyciwygChannelChild::SetNotificationCallbacks(nsIInterfaceRequestor * aCallbacks)
   477 {
   478   if (!CanSetCallbacks(aCallbacks)) {
   479     return NS_ERROR_FAILURE;
   480   }
   482   mCallbacks = aCallbacks;
   483   NS_QueryNotificationCallbacks(mCallbacks,
   484                                 mLoadGroup,
   485                                 NS_GET_IID(nsIProgressEventSink),
   486                                 getter_AddRefs(mProgressSink));
   487   return NS_OK;
   488 }
   490 /* readonly attribute nsISupports securityInfo; */
   491 NS_IMETHODIMP
   492 WyciwygChannelChild::GetSecurityInfo(nsISupports * *aSecurityInfo)
   493 {
   494   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
   496   return NS_OK;
   497 }
   499 /* attribute ACString contentType; */
   500 NS_IMETHODIMP
   501 WyciwygChannelChild::GetContentType(nsACString & aContentType)
   502 {
   503   aContentType.AssignLiteral(WYCIWYG_TYPE);
   504   return NS_OK;
   505 }
   506 NS_IMETHODIMP
   507 WyciwygChannelChild::SetContentType(const nsACString & aContentType)
   508 {
   509   return NS_ERROR_NOT_IMPLEMENTED;
   510 }
   512 /* attribute ACString contentCharset; */
   513 NS_IMETHODIMP
   514 WyciwygChannelChild::GetContentCharset(nsACString & aContentCharset)
   515 {
   516   aContentCharset.Assign("UTF-16");
   517   return NS_OK;
   518 }
   519 NS_IMETHODIMP
   520 WyciwygChannelChild::SetContentCharset(const nsACString & aContentCharset)
   521 {
   522   return NS_ERROR_NOT_IMPLEMENTED;
   523 }
   525 NS_IMETHODIMP
   526 WyciwygChannelChild::GetContentDisposition(uint32_t *aContentDisposition)
   527 {
   528   return NS_ERROR_NOT_AVAILABLE;
   529 }
   531 NS_IMETHODIMP
   532 WyciwygChannelChild::SetContentDisposition(uint32_t aContentDisposition)
   533 {
   534   return NS_ERROR_NOT_AVAILABLE;
   535 }
   537 NS_IMETHODIMP
   538 WyciwygChannelChild::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
   539 {
   540   return NS_ERROR_NOT_AVAILABLE;
   541 }
   543 NS_IMETHODIMP
   544 WyciwygChannelChild::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
   545 {
   546   return NS_ERROR_NOT_AVAILABLE;
   547 }
   549 NS_IMETHODIMP
   550 WyciwygChannelChild::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
   551 {
   552   return NS_ERROR_NOT_AVAILABLE;
   553 }
   555 /* attribute int64_t contentLength; */
   556 NS_IMETHODIMP
   557 WyciwygChannelChild::GetContentLength(int64_t *aContentLength)
   558 {
   559   return NS_ERROR_NOT_IMPLEMENTED;
   560 }
   561 NS_IMETHODIMP
   562 WyciwygChannelChild::SetContentLength(int64_t aContentLength)
   563 {
   564   return NS_ERROR_NOT_IMPLEMENTED;
   565 }
   567 /* nsIInputStream open (); */
   568 NS_IMETHODIMP
   569 WyciwygChannelChild::Open(nsIInputStream **_retval)
   570 {
   571   return NS_ERROR_NOT_IMPLEMENTED;
   572 }
   574 static mozilla::dom::TabChild*
   575 GetTabChild(nsIChannel* aChannel)
   576 {
   577   nsCOMPtr<nsITabChild> iTabChild;
   578   NS_QueryNotificationCallbacks(aChannel, iTabChild);
   579   return iTabChild ? static_cast<mozilla::dom::TabChild*>(iTabChild.get()) : nullptr;
   580 }
   582 /* void asyncOpen (in nsIStreamListener aListener, in nsISupports aContext); */
   583 NS_IMETHODIMP
   584 WyciwygChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
   585 {
   586   LOG(("WyciwygChannelChild::AsyncOpen [this=%p]\n", this));
   588   // The only places creating wyciwyg: channels should be
   589   // HTMLDocument::OpenCommon and session history.  Both should be setting an
   590   // owner.
   591   NS_PRECONDITION(mOwner, "Must have a principal");
   592   NS_ENSURE_STATE(mOwner);
   594   NS_ENSURE_ARG_POINTER(aListener);
   595   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
   597   mListener = aListener;
   598   mListenerContext = aContext;
   599   mIsPending = true;
   601   if (mLoadGroup)
   602     mLoadGroup->AddRequest(this, nullptr);
   604   URIParams originalURI;
   605   SerializeURI(mOriginalURI, originalURI);
   607   mozilla::dom::TabChild* tabChild = GetTabChild(this);
   608   if (MissingRequiredTabChild(tabChild, "wyciwyg")) {
   609     return NS_ERROR_ILLEGAL_VALUE;
   610   }
   612   SendAsyncOpen(originalURI, mLoadFlags, IPC::SerializedLoadContext(this), tabChild);
   614   mSentAppData = true;
   615   mState = WCC_OPENED;
   617   return NS_OK;
   618 }
   620 //-----------------------------------------------------------------------------
   621 // nsIWyciwygChannel
   622 //-----------------------------------------------------------------------------
   624 /* void writeToCacheEntry (in AString aData); */
   625 NS_IMETHODIMP
   626 WyciwygChannelChild::WriteToCacheEntry(const nsAString & aData)
   627 {
   628   NS_ENSURE_TRUE((mState == WCC_INIT) ||
   629                  (mState == WCC_ONWRITE), NS_ERROR_UNEXPECTED);
   631   if (!mSentAppData) {
   632     mozilla::dom::TabChild* tabChild = GetTabChild(this);
   633     SendAppData(IPC::SerializedLoadContext(this), tabChild);
   634     mSentAppData = true;
   635   }
   637   SendWriteToCacheEntry(PromiseFlatString(aData));
   638   mState = WCC_ONWRITE;
   639   return NS_OK;
   640 }
   642 /* void closeCacheEntry (in nsresult reason); */
   643 NS_IMETHODIMP
   644 WyciwygChannelChild::CloseCacheEntry(nsresult reason)
   645 {
   646   NS_ENSURE_TRUE(mState == WCC_ONWRITE, NS_ERROR_UNEXPECTED);
   648   SendCloseCacheEntry(reason);
   649   mState = WCC_ONCLOSED;
   651   if (mIPCOpen)
   652     PWyciwygChannelChild::Send__delete__(this);
   654   return NS_OK;
   655 }
   657 /* void setSecurityInfo (in nsISupports aSecurityInfo); */
   658 NS_IMETHODIMP
   659 WyciwygChannelChild::SetSecurityInfo(nsISupports *aSecurityInfo)
   660 {
   661   mSecurityInfo = aSecurityInfo;
   663   if (mSecurityInfo) {
   664     nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mSecurityInfo);
   665     if (serializable) {
   666       nsCString secInfoStr;
   667       NS_SerializeToString(serializable, secInfoStr);
   668       SendSetSecurityInfo(secInfoStr);
   669     }
   670     else {
   671       NS_WARNING("Can't serialize security info");
   672     }
   673   }
   675   return NS_OK;
   676 }
   678 /* void setCharsetAndSource (in long aSource, in ACString aCharset); */
   679 NS_IMETHODIMP
   680 WyciwygChannelChild::SetCharsetAndSource(int32_t aSource, const nsACString & aCharset)
   681 {
   682   // mState == WCC_ONSTART when reading from the channel
   683   // mState == WCC_INIT when writing to the cache
   684   NS_ENSURE_TRUE((mState == WCC_ONSTART) ||
   685                  (mState == WCC_INIT), NS_ERROR_UNEXPECTED);
   687   mCharsetSource = aSource;
   688   mCharset = aCharset;
   690   // TODO ensure that nsWyciwygChannel in the parent has still the cache entry
   691   SendSetCharsetAndSource(mCharsetSource, mCharset);
   692   return NS_OK;
   693 }
   695 /* ACString getCharsetAndSource (out long aSource); */
   696 NS_IMETHODIMP
   697 WyciwygChannelChild::GetCharsetAndSource(int32_t *aSource, nsACString & _retval)
   698 {
   699   NS_ENSURE_TRUE((mState == WCC_ONSTART) ||
   700                  (mState == WCC_ONDATA) ||
   701                  (mState == WCC_ONSTOP), NS_ERROR_NOT_AVAILABLE);
   703   if (mCharsetSource == kCharsetUninitialized)
   704     return NS_ERROR_NOT_AVAILABLE;
   706   *aSource = mCharsetSource;
   707   _retval = mCharset;
   708   return NS_OK;
   709 }
   711 //------------------------------------------------------------------------------
   712 }} // mozilla::net

mercurial