mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 18:55:30 +00:00
204fe23163
In order to implement profile-per-install we need a mutable INI parser in early startup. The current one is implemented in JavaScript and thus not available. This makes the current read-only C++ INI parser mutable and removes the JavaScript implementation. It turns out that the two different implementations of nsIINIParserFactory and nsIINIParser behaved slightly differently but only in ways that the single test cared about so I've adjusted things a little to make it work. The existing C++ implementation did not do validity checks on arguments, this adds that making empty sections and values illegal. Differential Revision: https://phabricator.services.mozilla.com/D3851 --HG-- rename : xpcom/tests/unit/test_iniProcessor.js => xpcom/tests/unit/test_iniParser.js extra : source : 524941c8ed0e048ee51be1bd11082b41428ef490 extra : amend_source : 2de6cef5be97448a41733bedda29d6af34aed27a
182 lines
4.3 KiB
C++
182 lines
4.3 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 "nsINIParserImpl.h"
|
|
|
|
#include "nsINIParser.h"
|
|
#include "nsStringEnumerator.h"
|
|
#include "nsTArray.h"
|
|
#include "mozilla/Attributes.h"
|
|
|
|
class nsINIParserImpl final
|
|
: public nsIINIParser
|
|
, public nsIINIParserWriter
|
|
{
|
|
~nsINIParserImpl() {}
|
|
|
|
public:
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIINIPARSER
|
|
NS_DECL_NSIINIPARSERWRITER
|
|
|
|
nsresult Init(nsIFile* aINIFile) { return mParser.Init(aINIFile); }
|
|
|
|
private:
|
|
nsINIParser mParser;
|
|
bool ContainsNull(const nsACString& aStr);
|
|
};
|
|
|
|
NS_IMPL_ISUPPORTS(nsINIParserFactory,
|
|
nsIINIParserFactory,
|
|
nsIFactory)
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserFactory::CreateINIParser(nsIFile* aINIFile,
|
|
nsIINIParser** aResult)
|
|
{
|
|
*aResult = nullptr;
|
|
|
|
RefPtr<nsINIParserImpl> p(new nsINIParserImpl());
|
|
if (!p) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if (aINIFile) {
|
|
nsresult rv = p->Init(aINIFile);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
p.forget(aResult);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserFactory::CreateInstance(nsISupports* aOuter,
|
|
REFNSIID aIID,
|
|
void** aResult)
|
|
{
|
|
if (NS_WARN_IF(aOuter)) {
|
|
return NS_ERROR_NO_AGGREGATION;
|
|
}
|
|
|
|
// We are our own singleton.
|
|
return QueryInterface(aIID, aResult);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserFactory::LockFactory(bool aLock)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(nsINIParserImpl,
|
|
nsIINIParser,
|
|
nsIINIParserWriter)
|
|
|
|
bool
|
|
nsINIParserImpl::ContainsNull(const nsACString& aStr) {
|
|
return aStr.CountChar('\0') > 0;
|
|
}
|
|
|
|
static bool
|
|
SectionCB(const char* aSection, void* aClosure)
|
|
{
|
|
nsTArray<nsCString>* strings = static_cast<nsTArray<nsCString>*>(aClosure);
|
|
strings->AppendElement()->Assign(aSection);
|
|
return true;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserImpl::GetSections(nsIUTF8StringEnumerator** aResult)
|
|
{
|
|
nsTArray<nsCString>* strings = new nsTArray<nsCString>;
|
|
if (!strings) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
nsresult rv = mParser.GetSections(SectionCB, strings);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = NS_NewAdoptingUTF8StringEnumerator(aResult, strings);
|
|
}
|
|
|
|
if (NS_FAILED(rv)) {
|
|
delete strings;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
static bool
|
|
KeyCB(const char* aKey, const char* aValue, void* aClosure)
|
|
{
|
|
nsTArray<nsCString>* strings = static_cast<nsTArray<nsCString>*>(aClosure);
|
|
strings->AppendElement()->Assign(aKey);
|
|
return true;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserImpl::GetKeys(const nsACString& aSection,
|
|
nsIUTF8StringEnumerator** aResult)
|
|
{
|
|
if (ContainsNull(aSection)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
nsTArray<nsCString>* strings = new nsTArray<nsCString>;
|
|
if (!strings) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
nsresult rv = mParser.GetStrings(PromiseFlatCString(aSection).get(),
|
|
KeyCB, strings);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
rv = NS_NewAdoptingUTF8StringEnumerator(aResult, strings);
|
|
}
|
|
|
|
if (NS_FAILED(rv)) {
|
|
delete strings;
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserImpl::GetString(const nsACString& aSection,
|
|
const nsACString& aKey,
|
|
nsACString& aResult)
|
|
{
|
|
if (ContainsNull(aSection) || ContainsNull(aKey)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
return mParser.GetString(PromiseFlatCString(aSection).get(),
|
|
PromiseFlatCString(aKey).get(),
|
|
aResult);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserImpl::SetString(const nsACString& aSection,
|
|
const nsACString& aKey,
|
|
const nsACString& aValue)
|
|
{
|
|
if (ContainsNull(aSection) || ContainsNull(aKey) || ContainsNull(aValue)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
return mParser.SetString(PromiseFlatCString(aSection).get(),
|
|
PromiseFlatCString(aKey).get(),
|
|
PromiseFlatCString(aValue).get());
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsINIParserImpl::WriteFile(nsIFile* aINIFile)
|
|
{
|
|
return mParser.WriteToFile(aINIFile);
|
|
}
|