LCOV - code coverage report
Current view: top level - libreoffice/tools/source/ref - errinf.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 70 189 37.0 %
Date: 2012-12-27 Functions: 11 53 20.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <limits.h>
      21             : #include <tools/shl.hxx>
      22             : #include <tools/debug.hxx>
      23             : #include <tools/errinf.hxx>
      24             : #include <tools/string.hxx>
      25             : #include <rtl/strbuf.hxx>
      26             : 
      27             : class ErrorHandler;
      28             : 
      29             : namespace {
      30             : typedef void (* DisplayFnPtr)();
      31             : }
      32             : 
      33             : struct EDcrData
      34             : {
      35             : public:
      36             :     ErrorHandler               *pFirstHdl;
      37             :     ErrorContext               *pFirstCtx;
      38             :     DisplayFnPtr               pDsp;
      39             :     sal_Bool                   bIsWindowDsp;
      40             : 
      41             :     DynamicErrorInfo            *ppDcr[ERRCODE_DYNAMIC_COUNT];
      42             :     sal_uInt16                  nNextDcr;
      43             :                                 EDcrData();
      44             : 
      45             : static  EDcrData                *GetData();
      46             : };
      47             : 
      48             : class EDcr_Impl
      49             : {
      50             :     sal_uIntPtr                 lErrId;
      51             :     sal_uInt16                  nMask;
      52             : 
      53             :     void                        RegisterEDcr(DynamicErrorInfo *);
      54             :     void                        UnRegisterEDcr(DynamicErrorInfo *);
      55             :     static ErrorInfo           *GetDynamicErrorInfo(sal_uIntPtr lId);
      56             : 
      57             : friend class DynamicErrorInfo;
      58             : friend class ErrorInfo;
      59             : };
      60             : 
      61          31 : EDcrData::EDcrData()
      62             : {
      63         992 :     for(sal_uInt16 n=0;n<ERRCODE_DYNAMIC_COUNT;n++)
      64         961 :         ppDcr[n]=0;
      65          31 :     nNextDcr=0;
      66          31 :     pFirstHdl=0;
      67          31 :     pDsp=0;
      68          31 :     pFirstCtx=0;
      69          31 : }
      70             : 
      71         874 : EDcrData *EDcrData::GetData()
      72             : {
      73             : #ifdef BOOTSTRAP
      74             :     return 0x0;
      75             : #else
      76         874 :     EDcrData **ppDat=(EDcrData **)GetAppData(SHL_ERR);
      77         874 :     if(!*ppDat)
      78             :     {
      79          31 :         return (*ppDat=new EDcrData);
      80             :     }
      81             :     else
      82         843 :         return *ppDat;
      83             : #endif
      84             : }
      85             : 
      86           1 : void EDcr_Impl::RegisterEDcr(DynamicErrorInfo *pDcr)
      87             : {
      88             :     // Register dynamic identifier
      89           1 :     EDcrData* pData=EDcrData::GetData();
      90             :     lErrId= (((sal_uIntPtr)pData->nNextDcr + 1) << ERRCODE_DYNAMIC_SHIFT) +
      91           1 :         pDcr->GetErrorCode();
      92           1 :     DynamicErrorInfo **ppDcr=pData->ppDcr;
      93           1 :     sal_uInt16 nNext=pData->nNextDcr;
      94             : 
      95           1 :     if(ppDcr[nNext])
      96             :     {
      97           0 :         delete ppDcr[nNext];
      98             :     }
      99           1 :     ppDcr[nNext]=pDcr;
     100           1 :     if(++pData->nNextDcr>=ERRCODE_DYNAMIC_COUNT)
     101           0 :         pData->nNextDcr=0;
     102           1 : }
     103             : 
     104           0 : void EDcr_Impl::UnRegisterEDcr(DynamicErrorInfo *pDcr)
     105             : {
     106             : 
     107           0 :     EDcrData* pData=EDcrData::GetData();
     108           0 :     DynamicErrorInfo **ppDcr=pData->ppDcr;
     109             :     sal_uIntPtr lIdx=(
     110           0 :         ((sal_uIntPtr)(*pDcr) & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
     111             :     DBG_ASSERT(ppDcr[lIdx]==pDcr,"ErrHdl: Error nicht gefunden");
     112           0 :     if(ppDcr[lIdx]==pDcr)
     113           0 :         ppDcr[lIdx]=0;
     114           0 : }
     115             : 
     116           0 : TYPEINIT0(ErrorInfo);
     117           0 : TYPEINIT1(DynamicErrorInfo, ErrorInfo);
     118           0 : TYPEINIT1(StringErrorInfo, DynamicErrorInfo);
     119           0 : TYPEINIT1(TwoStringErrorInfo, DynamicErrorInfo);
     120           0 : TYPEINIT1(MessageInfo, DynamicErrorInfo);
     121             : 
     122           0 : ErrorInfo *ErrorInfo::GetErrorInfo(sal_uIntPtr lId)
     123             : {
     124           0 :     if(lId & ERRCODE_DYNAMIC_MASK)
     125           0 :         return EDcr_Impl::GetDynamicErrorInfo(lId);
     126             :     else
     127           0 :         return new ErrorInfo(lId);
     128             : }
     129             : 
     130           1 : DynamicErrorInfo::operator sal_uIntPtr() const
     131             : {
     132           1 :     return pImpl->lErrId;
     133             : }
     134             : 
     135           1 : DynamicErrorInfo::DynamicErrorInfo(sal_uIntPtr lArgUserId, sal_uInt16 nMask)
     136           1 : : ErrorInfo(lArgUserId)
     137             : {
     138           1 :     pImpl=new EDcr_Impl;
     139           1 :     pImpl->RegisterEDcr(this);
     140           1 :     pImpl->nMask=nMask;
     141           1 : }
     142             : 
     143           0 : DynamicErrorInfo::~DynamicErrorInfo()
     144             : {
     145           0 :     pImpl->UnRegisterEDcr(this);
     146           0 :     delete pImpl;
     147           0 : }
     148             : 
     149           0 : ErrorInfo* EDcr_Impl::GetDynamicErrorInfo(sal_uIntPtr lId)
     150             : {
     151           0 :     sal_uIntPtr lIdx=((lId & ERRCODE_DYNAMIC_MASK)>>ERRCODE_DYNAMIC_SHIFT)-1;
     152           0 :     DynamicErrorInfo* pDcr=EDcrData::GetData()->ppDcr[lIdx];
     153           0 :     if(pDcr && (sal_uIntPtr)(*pDcr)==lId)
     154           0 :         return pDcr;
     155             :     else
     156           0 :         return new ErrorInfo(lId & ~ERRCODE_DYNAMIC_MASK);
     157             : }
     158             : 
     159           0 : sal_uInt16 DynamicErrorInfo::GetDialogMask() const
     160             : {
     161           0 :     return pImpl->nMask;
     162             : }
     163             : 
     164           0 : StringErrorInfo::StringErrorInfo(
     165             :     sal_uIntPtr UserId, const OUString& aStringP,  sal_uInt16 nFlags)
     166           0 : : DynamicErrorInfo(UserId, nFlags), aString(aStringP)
     167             : {
     168           0 : }
     169             : 
     170             : class ErrHdl_Impl
     171             : {
     172             : public:
     173             :     ErrorHandler        *pNext;
     174             :     static sal_Bool         CreateString(const ErrorHandler *pStart,
     175             :                                      const ErrorInfo*, OUString&, sal_uInt16&);
     176             : };
     177             : 
     178           0 : static void aDspFunc(const OUString &rErr, const OUString &rAction)
     179             : {
     180           0 :     rtl::OStringBuffer aErr(RTL_CONSTASCII_STRINGPARAM("Aktion: "));
     181           0 :     aErr.append(rtl::OUStringToOString(rAction, RTL_TEXTENCODING_ASCII_US));
     182           0 :     aErr.append(RTL_CONSTASCII_STRINGPARAM(" Fehler: "));
     183           0 :     aErr.append(rtl::OUStringToOString(rErr, RTL_TEXTENCODING_ASCII_US));
     184           0 :     OSL_FAIL(aErr.getStr());
     185           0 : }
     186             : 
     187         243 : ErrorContext::ErrorContext(Window *pWinP)
     188             : {
     189         243 :     EDcrData *pData=EDcrData::GetData();
     190         243 :     ErrorContext *&pHdl=pData->pFirstCtx;
     191         243 :     pWin=pWinP;
     192         243 :     pNext=pHdl;
     193         243 :     pHdl=this;
     194         243 : }
     195             : 
     196         243 : ErrorContext::~ErrorContext()
     197             : {
     198         243 :     ErrorContext **ppCtx=&(EDcrData::GetData()->pFirstCtx);
     199         486 :     while(*ppCtx && *ppCtx!=this)
     200           0 :         ppCtx=&((*ppCtx)->pNext);
     201         243 :     if(*ppCtx)
     202         243 :         *ppCtx=(*ppCtx)->pNext;
     203         243 : }
     204             : 
     205           0 : ErrorContext *ErrorContext::GetContext()
     206             : {
     207           0 :     return EDcrData::GetData()->pFirstCtx;
     208             : }
     209             : 
     210          93 : ErrorHandler::ErrorHandler()
     211             : {
     212          93 :     pImpl=new ErrHdl_Impl;
     213          93 :     EDcrData *pData=EDcrData::GetData();
     214          93 :     ErrorHandler *&pHdl=pData->pFirstHdl;
     215          93 :     pImpl->pNext=pHdl;
     216          93 :     pHdl=this;
     217          93 :     if(!pData->pDsp)
     218           1 :         RegisterDisplay(&aDspFunc);
     219          93 : }
     220             : 
     221          18 : ErrorHandler::~ErrorHandler()
     222             : {
     223          18 :     ErrorHandler **ppHdl=&(EDcrData::GetData()->pFirstHdl);
     224          54 :     while(*ppHdl && *ppHdl!=this)
     225          18 :         ppHdl=&((*ppHdl)->pImpl->pNext);
     226          18 :     if(*ppHdl)
     227          18 :         *ppHdl=(*ppHdl)->pImpl->pNext;
     228          18 :     delete pImpl;
     229          18 : }
     230             : 
     231          93 : void ErrorHandler::RegisterDisplay(WindowDisplayErrorFunc *aDsp)
     232             : {
     233          93 :     EDcrData *pData=EDcrData::GetData();
     234          93 :     pData->bIsWindowDsp=sal_True;
     235          93 :     pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
     236          93 : }
     237             : 
     238         183 : void ErrorHandler::RegisterDisplay(BasicDisplayErrorFunc *aDsp)
     239             : {
     240         183 :     EDcrData *pData=EDcrData::GetData();
     241         183 :     pData->bIsWindowDsp=sal_False;
     242         183 :     pData->pDsp = reinterpret_cast< DisplayFnPtr >(aDsp);
     243         183 : }
     244             : 
     245             : /** Handles an error.
     246             : 
     247             :     If nFlags is not set, the DynamicErrorInfo flags or the
     248             :     resource flags will be used.
     249             :     Thus:
     250             : 
     251             :     1. nFlags,
     252             :     2. Resource Flags
     253             :     3. Dynamic Flags
     254             :     4. Default ERRCODE_BUTTON_OK, ERRCODE_MSG_ERROR
     255             : 
     256             :     @param lId               error id
     257             :     @param nFlags            error flags.
     258             :     @param bJustCreateString ???
     259             :     @param rError            ???
     260             : 
     261             :     @return ???
     262             : */
     263           0 : sal_uInt16 ErrorHandler::HandleError_Impl(
     264             :     sal_uIntPtr lId, sal_uInt16 nFlags, sal_Bool bJustCreateString, OUString & rError)
     265             : {
     266           0 :     OUString aErr;
     267           0 :     OUString aAction;
     268           0 :     if(!lId || lId == ERRCODE_ABORT)
     269           0 :         return 0;
     270           0 :     EDcrData *pData=EDcrData::GetData();
     271           0 :     ErrorInfo *pInfo=ErrorInfo::GetErrorInfo(lId);
     272           0 :     ErrorContext *pCtx=ErrorContext::GetContext();
     273           0 :     if(pCtx)
     274           0 :         pCtx->GetString(pInfo->GetErrorCode(), aAction);
     275           0 :     Window *pParent=0;
     276             :     // Remove parent from context
     277           0 :     for(;pCtx;pCtx=pCtx->pNext)
     278           0 :         if(pCtx->GetParent())
     279             :         {
     280           0 :             pParent=pCtx->GetParent();
     281           0 :             break;
     282             :         }
     283             : 
     284           0 :     sal_Bool bWarning = ((lId & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
     285           0 :     sal_uInt16 nErrFlags = ERRCODE_BUTTON_DEF_OK | ERRCODE_BUTTON_OK;
     286           0 :     if (bWarning)
     287           0 :         nErrFlags |= ERRCODE_MSG_WARNING;
     288             :     else
     289           0 :         nErrFlags |= ERRCODE_MSG_ERROR;
     290             : 
     291           0 :     DynamicErrorInfo* pDynPtr=PTR_CAST(DynamicErrorInfo,pInfo);
     292           0 :     if(pDynPtr)
     293             :     {
     294           0 :         sal_uInt16 nDynFlags = pDynPtr->GetDialogMask();
     295           0 :         if( nDynFlags )
     296           0 :             nErrFlags = nDynFlags;
     297             :     }
     298             : 
     299           0 :     if(ErrHdl_Impl::CreateString(pData->pFirstHdl,pInfo,aErr,nErrFlags))
     300             :     {
     301           0 :         if (bJustCreateString)
     302             :         {
     303           0 :             rError = aErr;
     304           0 :             return 1;
     305             :         }
     306             :         else
     307             :         {
     308           0 :             if(!pData->pDsp)
     309             :             {
     310           0 :                 rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM("Action: "));
     311           0 :                 aStr.append(rtl::OUStringToOString(aAction, RTL_TEXTENCODING_ASCII_US));
     312           0 :                 aStr.append(RTL_CONSTASCII_STRINGPARAM("\nFehler: "));
     313           0 :                 aStr.append(rtl::OUStringToOString(aErr, RTL_TEXTENCODING_ASCII_US));
     314           0 :                 OSL_FAIL(aStr.getStr());
     315             :             }
     316             :             else
     317             :             {
     318           0 :                 delete pInfo;
     319           0 :                 if(!pData->bIsWindowDsp)
     320             :                 {
     321           0 :                     (*(BasicDisplayErrorFunc*)pData->pDsp)(aErr,aAction);
     322           0 :                     return 0;
     323             :                 }
     324             :                 else
     325             :                 {
     326           0 :                     if (nFlags != USHRT_MAX)
     327           0 :                         nErrFlags = nFlags;
     328             :                     return (*(WindowDisplayErrorFunc*)pData->pDsp)(
     329           0 :                         pParent, nErrFlags, aErr, aAction);
     330             :                 }
     331             :             }
     332             :         }
     333             :     }
     334             :     OSL_FAIL("Error nicht behandelt");
     335             :     // Error 1 is General Error in the Sfx
     336           0 :     if(pInfo->GetErrorCode()!=1)
     337             :     {
     338           0 :         HandleError_Impl(1, USHRT_MAX, bJustCreateString, rError);
     339             :     }
     340             :     else
     341             :     {
     342             :         OSL_FAIL("Error 1 nicht gehandeled");
     343             :     }
     344           0 :     delete pInfo;
     345           0 :     return 0;
     346             : }
     347             : 
     348             : // static
     349           0 : sal_Bool ErrorHandler::GetErrorString(sal_uIntPtr lId, OUString& rStr)
     350             : {
     351           0 :     return (sal_Bool)HandleError_Impl( lId, USHRT_MAX, sal_True, rStr );
     352             : }
     353             : 
     354             : /** Handles an error.
     355             : 
     356             :     @see ErrorHandler::HandleError_Impl
     357             : */
     358           0 : sal_uInt16 ErrorHandler::HandleError(sal_uIntPtr lId, sal_uInt16 nFlags)
     359             : {
     360           0 :     OUString aDummy;
     361           0 :     return HandleError_Impl( lId, nFlags, sal_False, aDummy );
     362             : }
     363             : 
     364           0 : sal_Bool ErrHdl_Impl::CreateString( const ErrorHandler *pStart,
     365             :                                     const ErrorInfo* pInfo, OUString& pStr,
     366             :                                     sal_uInt16 &rFlags)
     367             : {
     368           0 :     for(const ErrorHandler *pHdl=pStart;pHdl;pHdl=pHdl->pImpl->pNext)
     369             :     {
     370           0 :         if(pHdl->CreateString( pInfo, pStr, rFlags))
     371           0 :             return sal_True;
     372             :     }
     373           0 :     return sal_False;
     374             : }
     375             : 
     376           0 : sal_Bool SimpleErrorHandler::CreateString(
     377             :     const ErrorInfo *pInfo, OUString &rStr, sal_uInt16 &) const
     378             : {
     379           0 :     sal_uIntPtr nId = pInfo->GetErrorCode();
     380           0 :     rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM("Id "));
     381           0 :     aStr.append(static_cast<sal_Int32>(nId));
     382             :     aStr.append(RTL_CONSTASCII_STRINGPARAM(
     383           0 :         " only handled by SimpleErrorHandler"));
     384           0 :     aStr.append(RTL_CONSTASCII_STRINGPARAM("\nErrorCode: "));
     385             :     aStr.append(static_cast<sal_Int32>(
     386           0 :         nId & ((1L <<  ERRCODE_CLASS_SHIFT)  - 1 )));
     387           0 :     aStr.append(RTL_CONSTASCII_STRINGPARAM("\nErrorClass: "));
     388             :     aStr.append(static_cast<sal_Int32>(
     389           0 :         (nId & ERRCODE_CLASS_MASK) >> ERRCODE_CLASS_SHIFT));
     390           0 :     aStr.append(RTL_CONSTASCII_STRINGPARAM("\nErrorArea: "));
     391             :     aStr.append(static_cast<sal_Int32>((nId & ERRCODE_ERROR_MASK &
     392           0 :             ~((1 << ERRCODE_AREA_SHIFT ) -1 ) ) >> ERRCODE_AREA_SHIFT));
     393           0 :     DynamicErrorInfo *pDyn=PTR_CAST(DynamicErrorInfo,pInfo);
     394           0 :     if(pDyn)
     395             :     {
     396           0 :         aStr.append(RTL_CONSTASCII_STRINGPARAM("\nDId "));
     397           0 :         aStr.append(static_cast<sal_Int32>(*pDyn));
     398             :     }
     399             :     rStr = rtl::OStringToOUString(aStr.makeStringAndClear(),
     400           0 :         RTL_TEXTENCODING_ASCII_US);
     401           0 :     return sal_True;
     402             : }
     403             : 
     404           0 : SimpleErrorHandler::SimpleErrorHandler()
     405           0 :  : ErrorHandler()
     406             : {
     407           0 : }
     408             : 
     409             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10