1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ArchiveReader.h"
8 #include "ArchiveRequest.h"
9 #include "ArchiveEvent.h"
10 #include "ArchiveZipEvent.h"
13 #include "nsNetUtil.h"
15 #include "mozilla/dom/ArchiveReaderBinding.h"
16 #include "mozilla/dom/BindingDeclarations.h"
17 #include "mozilla/Preferences.h"
18 #include "mozilla/dom/EncodingUtils.h"
20 using namespace mozilla
;
21 using namespace mozilla::dom
;
22 USING_ARCHIVEREADER_NAMESPACE
24 /* static */ already_AddRefed
<ArchiveReader
>
25 ArchiveReader::Constructor(const GlobalObject
& aGlobal
,
27 const ArchiveReaderOptions
& aOptions
,
32 nsCOMPtr
<nsPIDOMWindow
> window
= do_QueryInterface(aGlobal
.GetAsSupports());
34 aError
.Throw(NS_ERROR_UNEXPECTED
);
38 nsAutoCString encoding
;
39 if (!EncodingUtils::FindEncodingForLabelNoReplacement(aOptions
.mEncoding
,
41 aError
.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED
, &aOptions
.mEncoding
);
45 nsRefPtr
<ArchiveReader
> reader
=
46 new ArchiveReader(aBlob
, window
, encoding
);
47 return reader
.forget();
50 ArchiveReader::ArchiveReader(nsIDOMBlob
* aBlob
, nsPIDOMWindow
* aWindow
,
51 const nsACString
& aEncoding
)
54 , mStatus(NOT_STARTED
)
55 , mEncoding(aEncoding
)
63 ArchiveReader::~ArchiveReader()
67 /* virtual */ JSObject
*
68 ArchiveReader::WrapObject(JSContext
* aCx
)
70 return ArchiveReaderBinding::Wrap(aCx
, this);
74 ArchiveReader::RegisterRequest(ArchiveRequest
* aRequest
)
77 // Append to the list and let's start to work:
79 mRequests
.AppendElement(aRequest
);
82 // Just append to the list:
84 mRequests
.AppendElement(aRequest
);
89 RequestReady(aRequest
);
93 NS_ASSERTION(false, "unexpected mStatus value");
97 // This returns the input stream
99 ArchiveReader::GetInputStream(nsIInputStream
** aInputStream
)
101 // Getting the input stream
102 mBlob
->GetInternalStream(aInputStream
);
103 NS_ENSURE_TRUE(*aInputStream
, NS_ERROR_UNEXPECTED
);
108 ArchiveReader::GetSize(uint64_t* aSize
)
110 nsresult rv
= mBlob
->GetSize(aSize
);
111 NS_ENSURE_SUCCESS(rv
, rv
);
115 // Here we open the archive:
117 ArchiveReader::OpenArchive()
123 nsCOMPtr
<nsIEventTarget
> target
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID
);
124 NS_ASSERTION(target
, "Must have stream transport service");
126 // Here a Event to make everything async:
127 nsRefPtr
<ArchiveReaderEvent
> event
;
129 /* FIXME: If we want to support more than 1 format we should check the content type here: */
130 event
= new ArchiveReaderZipEvent(this, mEncoding
);
131 rv
= target
->Dispatch(event
, NS_DISPATCH_NORMAL
);
132 NS_ENSURE_SUCCESS(rv
, rv
);
134 // In order to be sure that this object exists when the event finishes its task,
135 // we increase the refcount here:
141 // Data received from the dispatched event:
143 ArchiveReader::Ready(nsTArray
<nsCOMPtr
<nsIDOMFile
> >& aFileList
,
148 // Let's store the values:
149 mData
.fileList
= aFileList
;
150 mData
.status
= aStatus
;
152 // Propagate the results:
153 for (uint32_t index
= 0; index
< mRequests
.Length(); ++index
) {
154 nsRefPtr
<ArchiveRequest
> request
= mRequests
[index
];
155 RequestReady(request
);
160 // The async operation is concluded, we can decrease the reference:
165 ArchiveReader::RequestReady(ArchiveRequest
* aRequest
)
167 // The request will do the rest:
168 aRequest
->ReaderReady(mData
.fileList
, mData
.status
);
171 already_AddRefed
<ArchiveRequest
>
172 ArchiveReader::GetFilenames()
174 nsRefPtr
<ArchiveRequest
> request
= GenerateArchiveRequest();
175 request
->OpGetFilenames();
177 return request
.forget();
180 already_AddRefed
<ArchiveRequest
>
181 ArchiveReader::GetFile(const nsAString
& filename
)
183 nsRefPtr
<ArchiveRequest
> request
= GenerateArchiveRequest();
184 request
->OpGetFile(filename
);
186 return request
.forget();
189 already_AddRefed
<ArchiveRequest
>
190 ArchiveReader::GetFiles()
192 nsRefPtr
<ArchiveRequest
> request
= GenerateArchiveRequest();
193 request
->OpGetFiles();
195 return request
.forget();
198 already_AddRefed
<ArchiveRequest
>
199 ArchiveReader::GenerateArchiveRequest()
201 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
202 return ArchiveRequest::Create(mWindow
, this);
205 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ArchiveReader
,
211 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ArchiveReader
)
212 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
213 NS_INTERFACE_MAP_ENTRY(nsISupports
)
216 NS_IMPL_CYCLE_COLLECTING_ADDREF(ArchiveReader
)
217 NS_IMPL_CYCLE_COLLECTING_RELEASE(ArchiveReader
)