1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "WebBrowserPersistSerializeChild.h"
8 
9 #include <algorithm>
10 
11 #include "nsThreadUtils.h"
12 
13 namespace mozilla {
14 
NS_IMPL_ISUPPORTS(WebBrowserPersistSerializeChild,nsIWebBrowserPersistWriteCompletion,nsIWebBrowserPersistURIMap,nsIOutputStream)15 NS_IMPL_ISUPPORTS(WebBrowserPersistSerializeChild,
16                   nsIWebBrowserPersistWriteCompletion,
17                   nsIWebBrowserPersistURIMap, nsIOutputStream)
18 
19 WebBrowserPersistSerializeChild::WebBrowserPersistSerializeChild(
20     const WebBrowserPersistURIMap& aMap)
21     : mMap(aMap) {}
22 
23 WebBrowserPersistSerializeChild::~WebBrowserPersistSerializeChild() = default;
24 
25 NS_IMETHODIMP
OnFinish(nsIWebBrowserPersistDocument * aDocument,nsIOutputStream * aStream,const nsACString & aContentType,nsresult aStatus)26 WebBrowserPersistSerializeChild::OnFinish(
27     nsIWebBrowserPersistDocument* aDocument, nsIOutputStream* aStream,
28     const nsACString& aContentType, nsresult aStatus) {
29   MOZ_ASSERT(aStream == this);
30   nsCString contentType(aContentType);
31   Send__delete__(this, contentType, aStatus);
32   return NS_OK;
33 }
34 
35 NS_IMETHODIMP
GetNumMappedURIs(uint32_t * aNum)36 WebBrowserPersistSerializeChild::GetNumMappedURIs(uint32_t* aNum) {
37   *aNum = static_cast<uint32_t>(mMap.mapURIs().Length());
38   return NS_OK;
39 }
40 
41 NS_IMETHODIMP
GetURIMapping(uint32_t aIndex,nsACString & aMapFrom,nsACString & aMapTo)42 WebBrowserPersistSerializeChild::GetURIMapping(uint32_t aIndex,
43                                                nsACString& aMapFrom,
44                                                nsACString& aMapTo) {
45   if (aIndex >= mMap.mapURIs().Length()) {
46     return NS_ERROR_INVALID_ARG;
47   }
48   aMapFrom = mMap.mapURIs()[aIndex].mapFrom();
49   aMapTo = mMap.mapURIs()[aIndex].mapTo();
50   return NS_OK;
51 }
52 
53 NS_IMETHODIMP
GetTargetBaseURI(nsACString & aURI)54 WebBrowserPersistSerializeChild::GetTargetBaseURI(nsACString& aURI) {
55   aURI = mMap.targetBaseURI();
56   return NS_OK;
57 }
58 
59 NS_IMETHODIMP
Close()60 WebBrowserPersistSerializeChild::Close() {
61   NS_WARNING("WebBrowserPersistSerializeChild::Close()");
62   return NS_ERROR_NOT_IMPLEMENTED;
63 }
64 
65 NS_IMETHODIMP
Flush()66 WebBrowserPersistSerializeChild::Flush() {
67   NS_WARNING("WebBrowserPersistSerializeChild::Flush()");
68   return NS_ERROR_NOT_IMPLEMENTED;
69 }
70 
71 NS_IMETHODIMP
Write(const char * aBuf,uint32_t aCount,uint32_t * aWritten)72 WebBrowserPersistSerializeChild::Write(const char* aBuf, uint32_t aCount,
73                                        uint32_t* aWritten) {
74   // Normally an nsIOutputStream would have to be thread-safe, but
75   // nsDocumentEncoder currently doesn't call this off the main
76   // thread (which also means it's difficult to test the
77   // thread-safety code this class doesn't yet have).
78   //
79   // This is *not* an NS_ERROR_NOT_IMPLEMENTED, because at this
80   // point we've probably already misused the non-thread-safe
81   // refcounting.
82   MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Fix this class to be thread-safe.");
83 
84   // Limit the message size to 64k because large messages are
85   // potentially bad for the latency of other messages on the same channel.
86   static const uint32_t kMaxWrite = 65536;
87 
88   // Work around bug 1181433 by sending multiple messages if
89   // necessary to write the entire aCount bytes, even though
90   // nsIOutputStream.idl says we're allowed to do a short write.
91   const char* buf = aBuf;
92   uint32_t count = aCount;
93   *aWritten = 0;
94   while (count > 0) {
95     uint32_t toWrite = std::min(kMaxWrite, count);
96     nsTArray<uint8_t> arrayBuf;
97     // It would be nice if this extra copy could be avoided.
98     arrayBuf.AppendElements(buf, toWrite);
99     SendWriteData(std::move(arrayBuf));
100     *aWritten += toWrite;
101     buf += toWrite;
102     count -= toWrite;
103   }
104   return NS_OK;
105 }
106 
107 NS_IMETHODIMP
WriteFrom(nsIInputStream * aFrom,uint32_t aCount,uint32_t * aWritten)108 WebBrowserPersistSerializeChild::WriteFrom(nsIInputStream* aFrom,
109                                            uint32_t aCount,
110                                            uint32_t* aWritten) {
111   NS_WARNING("WebBrowserPersistSerializeChild::WriteFrom()");
112   return NS_ERROR_NOT_IMPLEMENTED;
113 }
114 
115 NS_IMETHODIMP
WriteSegments(nsReadSegmentFun aFun,void * aCtx,uint32_t aCount,uint32_t * aWritten)116 WebBrowserPersistSerializeChild::WriteSegments(nsReadSegmentFun aFun,
117                                                void* aCtx, uint32_t aCount,
118                                                uint32_t* aWritten) {
119   NS_WARNING("WebBrowserPersistSerializeChild::WriteSegments()");
120   return NS_ERROR_NOT_IMPLEMENTED;
121 }
122 
123 NS_IMETHODIMP
IsNonBlocking(bool * aNonBlocking)124 WebBrowserPersistSerializeChild::IsNonBlocking(bool* aNonBlocking) {
125   // Writes will never fail with NS_BASE_STREAM_WOULD_BLOCK, so:
126   *aNonBlocking = false;
127   return NS_OK;
128 }
129 
130 }  // namespace mozilla
131