зеркало из https://github.com/mozilla/gecko-dev.git
265 строки
5.9 KiB
C++
265 строки
5.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "nsArrayEnumerator.h"
|
|
#include "nsIObjectInputStream.h"
|
|
#include "nsIObjectOutputStream.h"
|
|
#include "nsSupportsArray.h"
|
|
#include "nsSupportsArrayEnumerator.h"
|
|
|
|
// Disable deprecation warnings generated by nsISupportsArray and associated
|
|
// classes.
|
|
#if defined(__GNUC__)
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
#elif defined(_MSC_VER)
|
|
#pragma warning (push)
|
|
#pragma warning (disable : 4996)
|
|
#endif
|
|
|
|
nsresult
|
|
nsQueryElementAt::operator()(const nsIID& aIID, void** aResult) const
|
|
{
|
|
nsresult status =
|
|
mCollection ? mCollection->QueryElementAt(mIndex, aIID, aResult) :
|
|
NS_ERROR_NULL_POINTER;
|
|
|
|
if (mErrorPtr) {
|
|
*mErrorPtr = status;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
nsSupportsArray::nsSupportsArray()
|
|
{
|
|
}
|
|
|
|
nsSupportsArray::~nsSupportsArray()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
nsresult
|
|
nsSupportsArray::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
|
{
|
|
if (aOuter) {
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
}
|
|
|
|
nsCOMPtr<nsISupportsArray> it = new nsSupportsArray();
|
|
|
|
return it->QueryInterface(aIID, aResult);
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(nsSupportsArray, nsIArray, nsISupportsArray, nsICollection,
|
|
nsISerializable)
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::Read(nsIObjectInputStream* aStream)
|
|
{
|
|
nsresult rv;
|
|
|
|
uint32_t newArraySize;
|
|
rv = aStream->Read32(&newArraySize);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
uint32_t count;
|
|
rv = aStream->Read32(&count);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
NS_ASSERTION(count <= newArraySize, "overlarge mCount!");
|
|
if (count > newArraySize) {
|
|
count = newArraySize;
|
|
}
|
|
|
|
// Don't clear out our array until we know we have enough space for the new
|
|
// one and have successfully copied everything out of the stream.
|
|
nsCOMArray<nsISupports> tmp;
|
|
tmp.SetCapacity(newArraySize);
|
|
tmp.SetCount(count);
|
|
|
|
auto elems = tmp.Elements();
|
|
for (uint32_t i = 0; i < count; i++) {
|
|
rv = aStream->ReadObject(true, &elems[i]);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
// Now clear out existing refs and replace with the new array.
|
|
mArray.Clear();
|
|
mArray.SwapElements(tmp);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::Write(nsIObjectOutputStream* aStream)
|
|
{
|
|
nsresult rv;
|
|
|
|
rv = aStream->Write32(mArray.Capacity());
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = aStream->Write32(mArray.Length());
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
for (size_t i = 0; i < mArray.Length(); i++) {
|
|
rv = aStream->WriteObject(mArray[i], true);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::GetElementAt(uint32_t aIndex, nsISupports** aOutPtr)
|
|
{
|
|
nsCOMPtr<nsISupports> elm = mArray.SafeElementAt(aIndex);
|
|
elm.forget(aOutPtr);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP_(int32_t)
|
|
nsSupportsArray::IndexOf(const nsISupports* aPossibleElement)
|
|
{
|
|
// nsCOMArray takes a non-const param, but it just passes through to
|
|
// nsTArray which takes a const param.
|
|
return mArray.IndexOf(const_cast<nsISupports*>(aPossibleElement));
|
|
}
|
|
|
|
NS_IMETHODIMP_(bool)
|
|
nsSupportsArray::InsertElementAt(nsISupports* aElement, uint32_t aIndex)
|
|
{
|
|
return mArray.InsertObjectAt(aElement, aIndex);
|
|
}
|
|
|
|
NS_IMETHODIMP_(bool)
|
|
nsSupportsArray::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex)
|
|
{
|
|
// nsCOMArray::ReplaceObjectAt will grow the array if necessary. Instead
|
|
// we do the bounds check and only replace if it's in range.
|
|
if (aIndex < mArray.Length()) {
|
|
mArray.ReplaceElementAt(aIndex, aElement);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
NS_IMETHODIMP_(bool)
|
|
nsSupportsArray::RemoveElementAt(uint32_t aIndex)
|
|
{
|
|
return mArray.RemoveObjectAt(aIndex);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::RemoveElement(nsISupports* aElement)
|
|
{
|
|
return mArray.RemoveObject(aElement) ? NS_OK : NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::Clear(void)
|
|
{
|
|
mArray.Clear();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::DeprecatedEnumerate(nsIEnumerator** aResult)
|
|
{
|
|
RefPtr<nsSupportsArrayEnumerator> e = new nsSupportsArrayEnumerator(this);
|
|
e.forget(aResult);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::Clone(nsISupportsArray** aResult)
|
|
{
|
|
nsCOMPtr<nsISupportsArray> newArray;
|
|
nsresult rv = NS_NewISupportsArray(getter_AddRefs(newArray));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
for (size_t i = 0; i < mArray.Length(); i++) {
|
|
// AppendElement does an odd cast of bool to nsresult, we just cast back
|
|
// here.
|
|
if (!(bool)newArray->AppendElement(mArray[i])) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
newArray.forget(aResult);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
|
|
{
|
|
nsresult rv;
|
|
rv = nsSupportsArray::Create(nullptr, NS_GET_IID(nsISupportsArray),
|
|
(void**)aInstancePtrResult);
|
|
return rv;
|
|
}
|
|
|
|
/**
|
|
* nsIArray adapters.
|
|
*/
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::GetLength(uint32_t* aLength) {
|
|
return Count(aLength);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::QueryElementAt(uint32_t aIndex, const nsIID& aIID, void** aResult)
|
|
{
|
|
nsISupports* element = mArray.SafeElementAt(aIndex);
|
|
if (element) {
|
|
return element->QueryInterface(aIID, aResult);
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::IndexOf(uint32_t aStartIndex, nsISupports* aElement, uint32_t* aResult)
|
|
{
|
|
int32_t idx = mArray.IndexOf(aElement, aStartIndex);
|
|
if (idx < 0) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
*aResult = static_cast<uint32_t>(idx);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSupportsArray::Enumerate(nsISimpleEnumerator** aResult)
|
|
{
|
|
return NS_NewArrayEnumerator(aResult, this);
|
|
}
|
|
|
|
#if defined(__GNUC__)
|
|
#pragma GCC diagnostic pop
|
|
#elif defined(_MSC_VER)
|
|
#pragma warning (pop)
|
|
#endif
|
|
|