Back to index

lightning-sunbird  0.9+nobinonly
nsDOMException.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsCOMPtr.h"
00040 #include "nsCRT.h"
00041 #include "nsDOMClassInfo.h"
00042 #include "nsDOMError.h"
00043 #include "nsDOMException.h"
00044 #include "nsIDOMDOMException.h"
00045 #include "nsIDOMRangeException.h"
00046 #ifdef MOZ_SVG
00047 #include "nsIDOMSVGException.h"
00048 #endif
00049 #include "nsString.h"
00050 #include "prprf.h"
00051 
00052 #define DOM_MSG_DEF(val, message) {(val), #val, message},
00053 
00054 #define IMPL_INTERNAL_DOM_EXCEPTION_HEAD(classname, ifname)                  \
00055 class classname : public nsBaseDOMException,                                 \
00056                   public ifname                                              \
00057 {                                                                            \
00058 public:                                                                      \
00059   classname();                                                               \
00060   virtual ~classname();                                                      \
00061                                                                              \
00062   NS_DECL_ISUPPORTS_INHERITED
00063 
00064 #define IMPL_INTERNAL_DOM_EXCEPTION_TAIL(classname, ifname, domname, module, \
00065                                          mapping_function)                   \
00066 };                                                                           \
00067                                                                              \
00068 classname::classname() {}                                                    \
00069 classname::~classname() {}                                                   \
00070                                                                              \
00071 NS_IMPL_ADDREF_INHERITED(classname, nsBaseDOMException)                      \
00072 NS_IMPL_RELEASE_INHERITED(classname, nsBaseDOMException)                     \
00073 NS_CLASSINFO_MAP_BEGIN(domname)                                              \
00074   NS_CLASSINFO_MAP_ENTRY(nsIException)                                       \
00075   NS_CLASSINFO_MAP_ENTRY(ifname)                                             \
00076 NS_CLASSINFO_MAP_END                                                         \
00077 NS_INTERFACE_MAP_BEGIN(classname)                                            \
00078   NS_INTERFACE_MAP_ENTRY(ifname)                                             \
00079   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(domname)                              \
00080 NS_INTERFACE_MAP_END_INHERITING(nsBaseDOMException)                          \
00081                                                                              \
00082 nsresult                                                                     \
00083 NS_New##domname(nsresult aNSResult, nsIException* aDefaultException,         \
00084                 nsIException** aException)                                   \
00085 {                                                                            \
00086   if (!(NS_ERROR_GET_MODULE(aNSResult) == module)) {                         \
00087     NS_WARNING("Trying to create an exception for the wrong error module."); \
00088     return NS_ERROR_FAILURE;                                                 \
00089   }                                                                          \
00090   const char* name;                                                          \
00091   const char* message;                                                       \
00092   mapping_function(aNSResult, &name, &message);                              \
00093   classname* inst = new classname();                                         \
00094   NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);                              \
00095   inst->Init(aNSResult, name, message, aDefaultException);                   \
00096   *aException = inst;                                                        \
00097   NS_ADDREF(*aException);                                                    \
00098   return NS_OK;                                                              \
00099 }
00100 
00101 static struct ResultStruct
00102 {
00103   nsresult mNSResult;
00104   const char* mName;
00105   const char* mMessage;
00106 } gDOMErrorMsgMap[] = {
00107 #include "domerr.msg"
00108   {0, nsnull, nsnull}   // sentinel to mark end of array
00109 };
00110 
00111 #undef DOM_MSG_DEF
00112 
00113 static void
00114 NSResultToNameAndMessage(nsresult aNSResult,
00115                          const char** aName,
00116                          const char** aMessage)
00117 {
00118   ResultStruct* result_struct = gDOMErrorMsgMap;
00119 
00120   while (result_struct->mName) {
00121     if (aNSResult == result_struct->mNSResult) {
00122       *aName = result_struct->mName;
00123       *aMessage = result_struct->mMessage;
00124       return;
00125     }
00126 
00127     ++result_struct;
00128   }
00129 
00130   NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
00131 
00132   return;
00133 }
00134 
00135 IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsDOMException, nsIDOMDOMException)
00136   NS_DECL_NSIDOMDOMEXCEPTION
00137 IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsDOMException, nsIDOMDOMException,
00138                                  DOMException, NS_ERROR_MODULE_DOM,
00139                                  NSResultToNameAndMessage)
00140 
00141 NS_IMETHODIMP
00142 nsDOMException::GetCode(PRUint32* aCode)
00143 {
00144   NS_ENSURE_ARG_POINTER(aCode);
00145   nsresult result;
00146   GetResult(&result);
00147   *aCode = NS_ERROR_GET_CODE(result);
00148 
00149   return NS_OK;
00150 }
00151 
00152 IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsRangeException, nsIDOMRangeException)
00153   NS_DECL_NSIDOMRANGEEXCEPTION
00154 IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsRangeException, nsIDOMRangeException,
00155                                  RangeException, NS_ERROR_MODULE_DOM_RANGE,
00156                                  NSResultToNameAndMessage)
00157 
00158 NS_IMETHODIMP
00159 nsRangeException::GetCode(PRUint16* aCode)
00160 {
00161   NS_ENSURE_ARG_POINTER(aCode);
00162   nsresult result;
00163   GetResult(&result);
00164   *aCode = NS_ERROR_GET_CODE(result);
00165 
00166   return NS_OK;
00167 }
00168 
00169 #ifdef MOZ_SVG
00170 IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsSVGException, nsIDOMSVGException)
00171   NS_DECL_NSIDOMSVGEXCEPTION
00172 IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsSVGException, nsIDOMSVGException,
00173                                  SVGException, NS_ERROR_MODULE_SVG,
00174                                  NSResultToNameAndMessage)
00175 
00176 NS_IMETHODIMP
00177 nsSVGException::GetCode(PRUint16* aCode)
00178 {
00179   NS_ENSURE_ARG_POINTER(aCode);
00180   nsresult result;
00181   GetResult(&result);
00182   *aCode = NS_ERROR_GET_CODE(result);
00183 
00184   return NS_OK;
00185 }
00186 #endif // MOZ_SVG
00187 
00188 
00189 nsBaseDOMException::nsBaseDOMException()
00190 {
00191 }
00192 
00193 nsBaseDOMException::~nsBaseDOMException()
00194 {
00195 }
00196 
00197 NS_IMPL_ISUPPORTS2(nsBaseDOMException, nsIException, nsIBaseDOMException)
00198 
00199 NS_IMETHODIMP
00200 nsBaseDOMException::GetMessage(char **aMessage)
00201 {
00202   if (mMessage) {
00203     *aMessage = nsCRT::strdup(mMessage);
00204   } else {
00205     *aMessage = nsnull;
00206   }
00207 
00208   return NS_OK;
00209 }
00210 
00211 NS_IMETHODIMP
00212 nsBaseDOMException::GetResult(PRUint32* aResult)
00213 {
00214   NS_ENSURE_ARG_POINTER(aResult);
00215 
00216   *aResult = mResult;
00217 
00218   return NS_OK;
00219 }
00220 
00221 NS_IMETHODIMP
00222 nsBaseDOMException::GetName(char **aName)
00223 {
00224   NS_ENSURE_ARG_POINTER(aName);
00225 
00226   if (mName) {
00227     *aName = nsCRT::strdup(mName);
00228   } else {
00229     *aName = nsnull;
00230   }
00231 
00232   return NS_OK;
00233 }
00234 
00235 NS_IMETHODIMP
00236 nsBaseDOMException::GetFilename(char **aFilename)
00237 {
00238   if (mInner) {
00239     return mInner->GetFilename(aFilename);
00240   }
00241 
00242   NS_ENSURE_ARG_POINTER(aFilename);
00243 
00244   *aFilename = nsnull;
00245 
00246   return NS_OK;
00247 }
00248 
00249 NS_IMETHODIMP
00250 nsBaseDOMException::GetLineNumber(PRUint32 *aLineNumber)
00251 {
00252   if (mInner) {
00253     return mInner->GetLineNumber(aLineNumber);
00254   }
00255 
00256   NS_ENSURE_ARG_POINTER(aLineNumber);
00257 
00258   *aLineNumber = 0;
00259 
00260   return NS_OK;
00261 }
00262 
00263 NS_IMETHODIMP
00264 nsBaseDOMException::GetColumnNumber(PRUint32 *aColumnNumber)
00265 {
00266   if (mInner) {
00267     return mInner->GetColumnNumber(aColumnNumber);
00268   }
00269 
00270   NS_ENSURE_ARG_POINTER(aColumnNumber);
00271 
00272   *aColumnNumber = 0;
00273 
00274   return NS_OK;
00275 }
00276 
00277 NS_IMETHODIMP
00278 nsBaseDOMException::GetLocation(nsIStackFrame **aLocation)
00279 {
00280   if (mInner) {
00281     return mInner->GetLocation(aLocation);
00282   }
00283 
00284   NS_ENSURE_ARG_POINTER(aLocation);
00285 
00286   *aLocation = nsnull;
00287 
00288   return NS_OK;
00289 }
00290 
00291 NS_IMETHODIMP
00292 nsBaseDOMException::GetInner(nsIException **aInner)
00293 {
00294   NS_ENSURE_ARG_POINTER(aInner);
00295 
00296   *aInner = nsnull;
00297 
00298   return NS_OK;
00299 }
00300 
00301 NS_IMETHODIMP
00302 nsBaseDOMException::GetData(nsISupports **aData)
00303 {
00304   if (mInner) {
00305     return mInner->GetData(aData);
00306   }
00307 
00308   NS_ENSURE_ARG_POINTER(aData);
00309 
00310   *aData = nsnull;
00311 
00312   return NS_OK;
00313 }
00314 
00315 NS_IMETHODIMP
00316 nsBaseDOMException::ToString(char **aReturn)
00317 {
00318   *aReturn = nsnull;
00319 
00320   static const char defaultMsg[] = "<no message>";
00321   static const char defaultLocation[] = "<unknown>";
00322   static const char defaultName[] = "<unknown>";
00323   static const char format[] =
00324     "[Exception... \"%s\"  code: \"%d\" nsresult: \"0x%x (%s)\"  location: \"%s\"]";
00325 
00326   nsCAutoString location;
00327 
00328   if (mInner) {
00329     nsXPIDLCString filename;
00330 
00331     mInner->GetFilename(getter_Copies(filename));
00332 
00333     if (!filename.IsEmpty()) {
00334       PRUint32 line_nr = 0;
00335 
00336       mInner->GetLineNumber(&line_nr);
00337 
00338       char *temp = PR_smprintf("%s Line: %d", filename.get(), line_nr);
00339       if (temp) {
00340         location.Assign(temp);
00341         PR_smprintf_free(temp);
00342       }
00343     }
00344   }
00345 
00346   if (location.IsEmpty()) {
00347     location = defaultLocation;
00348   }
00349 
00350   const char* msg = mMessage ? mMessage : defaultMsg;
00351   const char* resultName = mName ? mName : defaultName;
00352   PRUint32 code = NS_ERROR_GET_CODE(mResult);
00353 
00354   *aReturn = PR_smprintf(format, msg, code, mResult, resultName,
00355                          location.get());
00356 
00357   return *aReturn ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
00358 }
00359 
00360 NS_IMETHODIMP
00361 nsBaseDOMException::Init(nsresult aNSResult, const char* aName,
00362                          const char* aMessage,
00363                          nsIException* aDefaultException)
00364 {
00365   mResult = aNSResult;
00366   mName = aName;
00367   mMessage = aMessage;
00368   mInner = aDefaultException;
00369   return NS_OK;
00370 }