transport: sqlite channel status and load flags
[abstract.git] / transport / sqlite / src / aaSqliteChannel.cpp
blob855abfcf8cd9ca65eecb881ed86252e7e7b25385
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
3 /*
4 * Copyright (C) 2008 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "xpcom-config.h"
24 #include "nsCOMPtr.h"
25 #include "nsAutoPtr.h"
26 #include "nsServiceManagerUtils.h"
27 #include "nsStringAPI.h"
28 #include "nsNetCID.h"
29 #include "nsIStreamListener.h"
30 #include "nsIURL.h"
31 #include "nsIFileURL.h"
32 #include "nsINetUtil.h"
33 #include "nsComponentManagerUtils.h"
34 #include "nsNetUtil.h"
36 /* Unfrozen API */
37 #include "nsThreadUtils.h"
38 #include "nsIRunnable.h"
39 #include "nsIThread.h"
41 /* Project includes */
43 #include "aaSqliteChannel.h"
44 #include "aaSqlitePump.h"
46 aaSqliteChannel::aaSqliteChannel(nsIURI *aURI)
47 : mURI(aURI)
48 , mContentType("text/dbxml")
49 , mStarted(PR_FALSE)
50 , mHadStart(PR_FALSE)
51 , mLoadFlags(0)
52 , mStatus(NS_OK)
55 NS_IMPL_THREADSAFE_ISUPPORTS4(aaSqliteChannel,
56 nsIRequest,
57 nsIChannel,
58 nsIStreamListener,
59 nsIRequestObserver)
61 /* nsIRequest */
62 NS_IMETHODIMP
63 aaSqliteChannel::GetName(nsACString & aName)
65 return NS_ERROR_NOT_IMPLEMENTED;
68 NS_IMETHODIMP
69 aaSqliteChannel::IsPending(PRBool *_retval NS_OUTPARAM)
71 NS_ENSURE_ARG_POINTER(_retval);
72 *_retval = !!mObserver;
73 return NS_OK;
76 NS_IMETHODIMP
77 aaSqliteChannel::GetStatus(nsresult *aStatus)
79 NS_ENSURE_ARG_POINTER(aStatus);
80 *aStatus = mStatus;
81 return NS_OK;
84 NS_IMETHODIMP
85 aaSqliteChannel::Cancel(nsresult aStatus)
87 return NS_ERROR_NOT_IMPLEMENTED;
90 NS_IMETHODIMP
91 aaSqliteChannel::Suspend()
93 return NS_ERROR_NOT_IMPLEMENTED;
96 NS_IMETHODIMP
97 aaSqliteChannel::Resume()
99 return NS_ERROR_NOT_IMPLEMENTED;
102 NS_IMETHODIMP
103 aaSqliteChannel::GetLoadGroup(nsILoadGroup * *aLoadGroup)
105 NS_ENSURE_ARG_POINTER(aLoadGroup);
106 NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
107 return NS_OK;
109 NS_IMETHODIMP
110 aaSqliteChannel::SetLoadGroup(nsILoadGroup * aLoadGroup)
112 mLoadGroup = aLoadGroup;
113 return NS_OK;
116 NS_IMETHODIMP
117 aaSqliteChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
119 NS_ENSURE_ARG_POINTER(aLoadFlags);
120 *aLoadFlags = mLoadFlags;
121 return NS_OK;
123 NS_IMETHODIMP
124 aaSqliteChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
126 mLoadFlags = aLoadFlags;
127 return NS_OK;
130 /* nsIChannel */
131 NS_IMETHODIMP
132 aaSqliteChannel::GetOriginalURI(nsIURI * *aOriginalURI)
134 NS_ENSURE_ARG_POINTER(aOriginalURI);
135 NS_IF_ADDREF(*aOriginalURI = mURI);
136 return NS_OK;
138 NS_IMETHODIMP
139 aaSqliteChannel::SetOriginalURI(nsIURI * aOriginalURI)
141 return NS_ERROR_NOT_IMPLEMENTED;
144 NS_IMETHODIMP
145 aaSqliteChannel::GetURI(nsIURI * *aURI)
147 NS_ENSURE_ARG_POINTER(aURI);
148 NS_IF_ADDREF(*aURI = mURI);
149 return NS_OK;
152 NS_IMETHODIMP
153 aaSqliteChannel::GetOwner(nsISupports * *aOwner)
155 NS_ENSURE_ARG_POINTER(aOwner);
156 NS_IF_ADDREF(*aOwner = mOwner);
157 return NS_OK;
159 NS_IMETHODIMP
160 aaSqliteChannel::SetOwner(nsISupports * aOwner)
162 mOwner = aOwner;
163 return NS_OK;
166 NS_IMETHODIMP
167 aaSqliteChannel::GetNotificationCallbacks(nsIInterfaceRequestor *
168 *aNotificationCallbacks)
170 return NS_ERROR_NOT_IMPLEMENTED;
172 NS_IMETHODIMP
173 aaSqliteChannel::SetNotificationCallbacks(nsIInterfaceRequestor *
174 aNotificationCallbacks)
176 return NS_ERROR_NOT_IMPLEMENTED;
179 NS_IMETHODIMP
180 aaSqliteChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
182 return NS_ERROR_NOT_IMPLEMENTED;
185 NS_IMETHODIMP
186 aaSqliteChannel::GetContentType(nsACString & aContentType)
188 aContentType.Assign(mContentType);
189 return NS_OK;
191 NS_IMETHODIMP
192 aaSqliteChannel::SetContentType(const nsACString & aContentType)
194 nsresult rv = NS_OK;
195 if(NS_UNLIKELY(mStarted && !mHadStart))
196 return NS_ERROR_UNEXPECTED;
198 if (mHadStart)
200 nsCAutoString contentCharset;
201 rv = NS_ParseContentType(aContentType, mContentType, contentCharset);
202 NS_ENSURE_SUCCESS(rv, rv);
205 return NS_OK;
208 NS_IMETHODIMP
209 aaSqliteChannel::GetContentCharset(nsACString & aContentCharset)
211 return NS_ERROR_NOT_IMPLEMENTED;
213 NS_IMETHODIMP
214 aaSqliteChannel::SetContentCharset(const nsACString & aContentCharset)
216 return NS_ERROR_NOT_IMPLEMENTED;
219 NS_IMETHODIMP
220 aaSqliteChannel::GetContentLength(PRInt32 *aContentLength)
222 return NS_ERROR_NOT_IMPLEMENTED;
224 NS_IMETHODIMP
225 aaSqliteChannel::SetContentLength(PRInt32 aContentLength)
227 return NS_ERROR_NOT_IMPLEMENTED;
230 NS_IMETHODIMP
231 aaSqliteChannel::Open(nsIInputStream **_retval NS_OUTPARAM)
233 return NS_ERROR_NOT_IMPLEMENTED;
236 NS_IMETHODIMP
237 aaSqliteChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
239 NS_ENSURE_ARG_POINTER(aListener);
240 NS_ENSURE_STATE(mURI);
241 nsresult rv;
243 if (NS_UNLIKELY(mStarted)) return NS_ERROR_ALREADY_OPENED;
245 nsCOMPtr<nsIEventTarget> worker =
246 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
247 NS_ENSURE_SUCCESS(rv, rv);
249 mObserver = aListener;
251 nsCOMPtr<nsIURL> url = do_QueryInterface(mURI, &rv);
252 NS_ENSURE_SUCCESS(rv, rv);
254 nsCAutoString query;
255 rv = url->GetQuery(query);
256 NS_ENSURE_SUCCESS(rv, rv);
258 NS_ENSURE_TRUE(StringBeginsWith(query, NS_LITERAL_CSTRING("sql=")),
259 NS_ERROR_INVALID_ARG);
260 const nsACString& sqlQuery = Substring(query, 4);
262 nsCOMPtr<nsINetUtil> netUtil = do_CreateInstance(NS_NETUTIL_CONTRACTID, &rv);
263 NS_ENSURE_SUCCESS(rv, rv);
265 nsCAutoString sql;
266 rv = netUtil->UnescapeString(sqlQuery, nsINetUtil::ESCAPE_XALPHAS, sql);
267 NS_ENSURE_SUCCESS(rv, rv);
269 nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(mURI, &rv);
270 NS_ENSURE_SUCCESS(rv, rv);
272 nsCOMPtr<nsIFile> db;
273 rv = fileURL->GetFile(getter_AddRefs(db));
274 NS_ENSURE_SUCCESS(rv, rv);
276 nsRefPtr<aaSqlitePump> pump = new aaSqlitePump(db, sql.get(), this);
277 NS_ENSURE_TRUE(pump, NS_ERROR_OUT_OF_MEMORY);
279 rv = worker->Dispatch(pump, NS_DISPATCH_NORMAL);
280 NS_ENSURE_SUCCESS(rv, rv);
282 mStarted = PR_TRUE;
284 if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull);
285 return NS_OK;
288 NS_IMETHODIMP
289 aaSqliteChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
291 NS_ENSURE_STATE(mObserver && !mHadStart);
292 mHadStart = PR_TRUE;
293 return mObserver->OnStartRequest(aRequest, aContext);
296 NS_IMETHODIMP
297 aaSqliteChannel::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
298 nsresult aStatusCode)
300 NS_ENSURE_STATE(mObserver && mHadStart);
301 nsresult rv = NS_OK;
302 rv = mObserver->OnStopRequest(aRequest, aContext, aStatusCode);
303 if (mLoadGroup) mLoadGroup->RemoveRequest(this, nsnull, aStatusCode);
304 mObserver = nsnull;
305 return rv;
308 NS_IMETHODIMP
309 aaSqliteChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
310 nsIInputStream *aInputStream, PRUint32 aOffset, PRUint32 aCount)
312 NS_ENSURE_STATE(mObserver && mHadStart);
313 return mObserver->OnDataAvailable(aRequest, aContext, aInputStream,
314 aOffset, aCount);