|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
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 "nsRDFXMLParser.h" |
|
8 |
|
9 #include "nsIComponentManager.h" |
|
10 #include "nsIParser.h" |
|
11 #include "nsCharsetSource.h" |
|
12 #include "nsIRDFContentSink.h" |
|
13 #include "nsParserCIID.h" |
|
14 #include "nsStringStream.h" |
|
15 #include "nsNetUtil.h" |
|
16 |
|
17 static NS_DEFINE_CID(kParserCID, NS_PARSER_CID); |
|
18 |
|
19 NS_IMPL_ISUPPORTS(nsRDFXMLParser, nsIRDFXMLParser) |
|
20 |
|
21 nsresult |
|
22 nsRDFXMLParser::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) |
|
23 { |
|
24 if (aOuter) |
|
25 return NS_ERROR_NO_AGGREGATION; |
|
26 |
|
27 nsRDFXMLParser* result = new nsRDFXMLParser(); |
|
28 if (! result) |
|
29 return NS_ERROR_OUT_OF_MEMORY; |
|
30 |
|
31 nsresult rv; |
|
32 NS_ADDREF(result); |
|
33 rv = result->QueryInterface(aIID, aResult); |
|
34 NS_RELEASE(result); |
|
35 return rv; |
|
36 } |
|
37 |
|
38 nsRDFXMLParser::nsRDFXMLParser() |
|
39 { |
|
40 MOZ_COUNT_CTOR(nsRDFXMLParser); |
|
41 } |
|
42 |
|
43 nsRDFXMLParser::~nsRDFXMLParser() |
|
44 { |
|
45 MOZ_COUNT_DTOR(nsRDFXMLParser); |
|
46 } |
|
47 |
|
48 NS_IMETHODIMP |
|
49 nsRDFXMLParser::ParseAsync(nsIRDFDataSource* aSink, nsIURI* aBaseURI, nsIStreamListener** aResult) |
|
50 { |
|
51 nsresult rv; |
|
52 |
|
53 nsCOMPtr<nsIRDFContentSink> sink = |
|
54 do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); |
|
55 |
|
56 if (NS_FAILED(rv)) return rv; |
|
57 |
|
58 rv = sink->Init(aBaseURI); |
|
59 if (NS_FAILED(rv)) return rv; |
|
60 |
|
61 // We set the content sink's data source directly to our in-memory |
|
62 // store. This allows the initial content to be generated "directly". |
|
63 rv = sink->SetDataSource(aSink); |
|
64 if (NS_FAILED(rv)) return rv; |
|
65 |
|
66 nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv); |
|
67 if (NS_FAILED(rv)) return rv; |
|
68 |
|
69 parser->SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"), |
|
70 kCharsetFromDocTypeDefault); |
|
71 parser->SetContentSink(sink); |
|
72 |
|
73 rv = parser->Parse(aBaseURI); |
|
74 if (NS_FAILED(rv)) return rv; |
|
75 |
|
76 return CallQueryInterface(parser, aResult); |
|
77 } |
|
78 |
|
79 NS_IMETHODIMP |
|
80 nsRDFXMLParser::ParseString(nsIRDFDataSource* aSink, nsIURI* aBaseURI, const nsACString& aString) |
|
81 { |
|
82 nsresult rv; |
|
83 |
|
84 nsCOMPtr<nsIRDFContentSink> sink = |
|
85 do_CreateInstance("@mozilla.org/rdf/content-sink;1", &rv); |
|
86 |
|
87 if (NS_FAILED(rv)) return rv; |
|
88 |
|
89 rv = sink->Init(aBaseURI); |
|
90 if (NS_FAILED(rv)) return rv; |
|
91 |
|
92 // We set the content sink's data source directly to our in-memory |
|
93 // store. This allows the initial content to be generated "directly". |
|
94 rv = sink->SetDataSource(aSink); |
|
95 if (NS_FAILED(rv)) return rv; |
|
96 |
|
97 nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv); |
|
98 if (NS_FAILED(rv)) return rv; |
|
99 |
|
100 parser->SetDocumentCharset(NS_LITERAL_CSTRING("UTF-8"), |
|
101 kCharsetFromOtherComponent); |
|
102 parser->SetContentSink(sink); |
|
103 |
|
104 rv = parser->Parse(aBaseURI); |
|
105 if (NS_FAILED(rv)) return rv; |
|
106 |
|
107 nsCOMPtr<nsIStreamListener> listener = |
|
108 do_QueryInterface(parser); |
|
109 |
|
110 if (! listener) |
|
111 return NS_ERROR_FAILURE; |
|
112 |
|
113 nsCOMPtr<nsIInputStream> stream; |
|
114 rv = NS_NewCStringInputStream(getter_AddRefs(stream), aString); |
|
115 if (NS_FAILED(rv)) return rv; |
|
116 |
|
117 nsCOMPtr<nsIChannel> channel; |
|
118 rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aBaseURI, stream, |
|
119 NS_LITERAL_CSTRING("text/xml")); |
|
120 if (NS_FAILED(rv)) return rv; |
|
121 |
|
122 listener->OnStartRequest(channel, nullptr); |
|
123 listener->OnDataAvailable(channel, nullptr, stream, 0, aString.Length()); |
|
124 listener->OnStopRequest(channel, nullptr, NS_OK); |
|
125 |
|
126 return NS_OK; |
|
127 } |