1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "nsINIParserImpl.h"
8
9 #include "nsINIParser.h"
10 #include "nsStringEnumerator.h"
11 #include "nsTArray.h"
12 #include "mozilla/Attributes.h"
13
14 class nsINIParserImpl final : public nsIINIParser, public nsIINIParserWriter {
15 ~nsINIParserImpl() = default;
16
17 public:
18 NS_DECL_ISUPPORTS
19 NS_DECL_NSIINIPARSER
20 NS_DECL_NSIINIPARSERWRITER
21
Init(nsIFile * aINIFile)22 nsresult Init(nsIFile* aINIFile) { return mParser.Init(aINIFile); }
23
24 private:
25 nsINIParser mParser;
26 bool ContainsNull(const nsACString& aStr);
27 };
28
NS_IMPL_ISUPPORTS(nsINIParserFactory,nsIINIParserFactory,nsIFactory)29 NS_IMPL_ISUPPORTS(nsINIParserFactory, nsIINIParserFactory, nsIFactory)
30
31 NS_IMETHODIMP
32 nsINIParserFactory::CreateINIParser(nsIFile* aINIFile, nsIINIParser** aResult) {
33 *aResult = nullptr;
34
35 RefPtr<nsINIParserImpl> p(new nsINIParserImpl());
36
37 if (aINIFile) {
38 nsresult rv = p->Init(aINIFile);
39 if (NS_FAILED(rv)) {
40 return rv;
41 }
42 }
43
44 p.forget(aResult);
45 return NS_OK;
46 }
47
48 NS_IMETHODIMP
CreateInstance(nsISupports * aOuter,REFNSIID aIID,void ** aResult)49 nsINIParserFactory::CreateInstance(nsISupports* aOuter, REFNSIID aIID,
50 void** aResult) {
51 if (NS_WARN_IF(aOuter)) {
52 return NS_ERROR_NO_AGGREGATION;
53 }
54
55 // We are our own singleton.
56 return QueryInterface(aIID, aResult);
57 }
58
59 NS_IMETHODIMP
LockFactory(bool aLock)60 nsINIParserFactory::LockFactory(bool aLock) { return NS_OK; }
61
NS_IMPL_ISUPPORTS(nsINIParserImpl,nsIINIParser,nsIINIParserWriter)62 NS_IMPL_ISUPPORTS(nsINIParserImpl, nsIINIParser, nsIINIParserWriter)
63
64 bool nsINIParserImpl::ContainsNull(const nsACString& aStr) {
65 return aStr.CountChar('\0') > 0;
66 }
67
SectionCB(const char * aSection,void * aClosure)68 static bool SectionCB(const char* aSection, void* aClosure) {
69 nsTArray<nsCString>* strings = static_cast<nsTArray<nsCString>*>(aClosure);
70 strings->AppendElement()->Assign(aSection);
71 return true;
72 }
73
74 NS_IMETHODIMP
GetSections(nsIUTF8StringEnumerator ** aResult)75 nsINIParserImpl::GetSections(nsIUTF8StringEnumerator** aResult) {
76 nsTArray<nsCString>* strings = new nsTArray<nsCString>;
77
78 nsresult rv = mParser.GetSections(SectionCB, strings);
79 if (NS_SUCCEEDED(rv)) {
80 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, strings);
81 }
82
83 if (NS_FAILED(rv)) {
84 delete strings;
85 }
86
87 return rv;
88 }
89
KeyCB(const char * aKey,const char * aValue,void * aClosure)90 static bool KeyCB(const char* aKey, const char* aValue, void* aClosure) {
91 nsTArray<nsCString>* strings = static_cast<nsTArray<nsCString>*>(aClosure);
92 strings->AppendElement()->Assign(aKey);
93 return true;
94 }
95
96 NS_IMETHODIMP
GetKeys(const nsACString & aSection,nsIUTF8StringEnumerator ** aResult)97 nsINIParserImpl::GetKeys(const nsACString& aSection,
98 nsIUTF8StringEnumerator** aResult) {
99 if (ContainsNull(aSection)) {
100 return NS_ERROR_INVALID_ARG;
101 }
102
103 nsTArray<nsCString>* strings = new nsTArray<nsCString>;
104
105 nsresult rv =
106 mParser.GetStrings(PromiseFlatCString(aSection).get(), KeyCB, strings);
107 if (NS_SUCCEEDED(rv)) {
108 rv = NS_NewAdoptingUTF8StringEnumerator(aResult, strings);
109 }
110
111 if (NS_FAILED(rv)) {
112 delete strings;
113 }
114
115 return rv;
116 }
117
118 NS_IMETHODIMP
GetString(const nsACString & aSection,const nsACString & aKey,nsACString & aResult)119 nsINIParserImpl::GetString(const nsACString& aSection, const nsACString& aKey,
120 nsACString& aResult) {
121 if (ContainsNull(aSection) || ContainsNull(aKey)) {
122 return NS_ERROR_INVALID_ARG;
123 }
124
125 return mParser.GetString(PromiseFlatCString(aSection).get(),
126 PromiseFlatCString(aKey).get(), aResult);
127 }
128
129 NS_IMETHODIMP
SetString(const nsACString & aSection,const nsACString & aKey,const nsACString & aValue)130 nsINIParserImpl::SetString(const nsACString& aSection, const nsACString& aKey,
131 const nsACString& aValue) {
132 if (ContainsNull(aSection) || ContainsNull(aKey) || ContainsNull(aValue)) {
133 return NS_ERROR_INVALID_ARG;
134 }
135
136 return mParser.SetString(PromiseFlatCString(aSection).get(),
137 PromiseFlatCString(aKey).get(),
138 PromiseFlatCString(aValue).get());
139 }
140
141 NS_IMETHODIMP
WriteFile(nsIFile * aINIFile)142 nsINIParserImpl::WriteFile(nsIFile* aINIFile) {
143 return mParser.WriteToFile(aINIFile);
144 }
145