<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: excel.cxx,v $
 *
 *  $Revision: 1.24 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 11:47:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// ============================================================================

#ifndef _SFXDOCFILE_HXX
#include <sfx2/docfile.hxx>
#endif
#ifndef _SFXAPP_HXX
#include <sfx2/app.hxx>
#endif
#ifndef _SVSTOR_HXX
#include <sot/storage.hxx>
#endif
#ifndef _SOT_EXCHANGE_HXX
#include <sot/exchange.hxx>
#endif
#ifndef _GLOBNAME_HXX
#include <tools/globname.hxx>
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#ifndef _SFXSTRITEM_HXX
#include <svtools/stritem.hxx>
#endif

#ifndef SC_FILTER_HXX
#include "filter.hxx"
#endif

#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_XLDUMPER_HXX
#include "xldumper.hxx"
#endif
#ifndef SC_XISTREAM_HXX
#include "xistream.hxx"
#endif

#include "scerrors.hxx"
#include "root.hxx"
#include "imp_op.hxx"
#include "excimp8.hxx"
#include "exp_op.hxx"

FltError ScImportExcel( SfxMedium& r, ScDocument* p )
{
    return ScImportExcel( r, p, EIF_AUTO );
}

FltError ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
{
    // check the passed Calc document
    DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
    if( !pDocument ) return eERR_INTERN;        // should not happen

#if SCF_INCL_DUMPER
    {
        ::scf::dump::xls::Dumper aDumper( rMedium, pDocument->GetDocumentShell() );
        aDumper.Dump();
        if( !aDumper.IsImportEnabled() )
            return ERRCODE_ABORT;
    }
#endif

    /*  Import all BIFF versions regardless on eFormat, needed for import of
        external cells (file type detection returns Excel4.0). */
    if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
    {
        DBG_ERRORFILE( "::ScImportExcel - wrong file format specification" );
        return eERR_FORMAT;
    }

    // check the input stream from medium
    SvStream* pMedStrm = rMedium.GetInStream();
    DBG_ASSERT( pMedStrm, "::ScImportExcel - medium without input stream" );
    if( !pMedStrm ) return eERR_OPEN;           // should not happen

    SvStream* pBookStrm = 0;            // The "Book"/"Workbook" stream containing main data.
    XclBiff eBiff = EXC_BIFF_UNKNOWN;   // The BIFF version of the main stream.

    // try to open an OLE storage
    SotStorageRef xRootStrg;
    SotStorageStreamRef xStrgStrm;
    if( SotStorage::IsStorageFile( pMedStrm ) )
    {
        xRootStrg = new SotStorage( pMedStrm, FALSE );
        if( xRootStrg->GetError() )
            xRootStrg = 0;
    }

    // try to open "Book" or "Workbook" stream in OLE storage
    if( xRootStrg.Is() )
    {
        // try to open the "Book" stream
        SotStorageStreamRef xBookStrm5 = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
        XclBiff eBookStrm5Biff = xBookStrm5.Is() ?  XclImpStream::DetectBiffVersion( *xBookStrm5 ) : EXC_BIFF_UNKNOWN;

        // try to open the "Workbook" stream
        SotStorageStreamRef xBookStrm8 = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
        XclBiff eBookStrm8Biff = xBookStrm8.Is() ?  XclImpStream::DetectBiffVersion( *xBookStrm8 ) : EXC_BIFF_UNKNOWN;

        // decide which stream to use
        if( (eBookStrm8Biff != EXC_BIFF_UNKNOWN) && ((eBookStrm5Biff == EXC_BIFF_UNKNOWN) || (eBookStrm8Biff > eBookStrm5Biff)) )
        {
            /*  Only "Workbook" stream exists; or both streams exist,
                and "Workbook" has higher BIFF version than "Book" stream. */
            xStrgStrm = xBookStrm8;
            eBiff = eBookStrm8Biff;
        }
        else if( eBookStrm5Biff != EXC_BIFF_UNKNOWN )
        {
            /*  Only "Book" stream exists; or both streams exist,
                and "Book" has higher BIFF version than "Workbook" stream. */
            xStrgStrm = xBookStrm5;
            eBiff = eBookStrm5Biff;
        }

        pBookStrm = xStrgStrm;
    }

    // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
    if( !pBookStrm )
    {
        eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
        if( eBiff != EXC_BIFF_UNKNOWN )
            pBookStrm = pMedStrm;
    }

    // try to import the file
    FltError eRet = eERR_UNKN_BIFF;
    if( pBookStrm )
    {
        pBookStrm->SetBufferSize( 0x8000 );     // still needed?

        XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
        ::std::auto_ptr< ImportExcel > xFilter;
        switch( eBiff )
        {
            case EXC_BIFF2:
            case EXC_BIFF3:
            case EXC_BIFF4:
            case EXC_BIFF5:
                xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
            break;
            case EXC_BIFF8:
                xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
            break;
            default:    DBG_ERROR_BIFF();
        }

        eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
    }

    return eRet;
}

FltError ScExportExcel234( SvStream &aStream, ScDocument *pDoc,
    ExportFormatExcel eFormat, CharSet eNach )
{
    FltError                eRet = eERR_NI;
    return eRet;
}

FltError ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
    const BOOL bBiff8, CharSet eNach )
{
    // check the passed Calc document
    DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
    if( !pDocument ) return eERR_INTERN;        // should not happen

    // check the output stream from medium
    SvStream* pMedStrm = rMedium.GetOutStream();
    DBG_ASSERT( pMedStrm, "::ScExportExcel5 - medium without output stream" );
    if( !pMedStrm ) return eERR_OPEN;           // should not happen

    // try to open an OLE storage
    SotStorageRef xRootStrg = new SotStorage( pMedStrm, FALSE );
    if( xRootStrg->GetError() ) return eERR_OPEN;

    // create BIFF dependent strings
    String aStrmName, aClipName, aClassName;
    if( bBiff8 )
    {
        aStrmName = EXC_STREAM_WORKBOOK;
        aClipName = CREATE_STRING( "Biff8" );
        aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
    }
    else
    {
        aStrmName = EXC_STREAM_BOOK;
        aClipName = CREATE_STRING( "Biff5" );
        aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
    }

    // open the "Book"/"Workbook" stream
    SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
    if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;

    xStrgStrm->SetBufferSize( 0x8000 );     // still needed?

    FltError eRet = eERR_UNKN_BIFF;
    XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
    if ( bBiff8 )
    {
        ExportBiff8 aFilter( aExpData, *xStrgStrm );
        eRet = aFilter.Write();
    }
    else
    {
        ExportBiff5 aFilter( aExpData, *xStrgStrm );
        eRet = aFilter.Write();
    }

    if( eRet == eERR_RNGOVRFLW )
        eRet = SCWARN_EXPORT_MAXROW;

    SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
    sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
    xRootStrg->SetClass( aGlobName, nClip, aClassName );

    xStrgStrm->Commit();
    xRootStrg->Commit();

    return eRet;
}

<commit_msg>INTEGRATION: CWS calcwarnings (1.24.108); FILE MERGED 2006/12/01 14:42:22 dr 1.24.108.1: #i69284# remove compiler warnings for wntmsci10<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: excel.cxx,v $
 *
 *  $Revision: 1.25 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 12:21:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// ============================================================================

#ifndef _SFXDOCFILE_HXX
#include <sfx2/docfile.hxx>
#endif
#ifndef _SFXAPP_HXX
#include <sfx2/app.hxx>
#endif
#ifndef _SVSTOR_HXX
#include <sot/storage.hxx>
#endif
#ifndef _SOT_EXCHANGE_HXX
#include <sot/exchange.hxx>
#endif
#ifndef _GLOBNAME_HXX
#include <tools/globname.hxx>
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#ifndef _SFXSTRITEM_HXX
#include <svtools/stritem.hxx>
#endif

#ifndef SC_FILTER_HXX
#include "filter.hxx"
#endif

#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_XLDUMPER_HXX
#include "xldumper.hxx"
#endif
#ifndef SC_XISTREAM_HXX
#include "xistream.hxx"
#endif

#include "scerrors.hxx"
#include "root.hxx"
#include "imp_op.hxx"
#include "excimp8.hxx"
#include "exp_op.hxx"

FltError ScImportExcel( SfxMedium& r, ScDocument* p )
{
    return ScImportExcel( r, p, EIF_AUTO );
}

FltError ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
{
    // check the passed Calc document
    DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
    if( !pDocument ) return eERR_INTERN;        // should not happen

#if SCF_INCL_DUMPER
    {
        ::scf::dump::xls::Dumper aDumper( rMedium, pDocument->GetDocumentShell() );
        aDumper.Dump();
        if( !aDumper.IsImportEnabled() )
            return ERRCODE_ABORT;
    }
#endif

    /*  Import all BIFF versions regardless on eFormat, needed for import of
        external cells (file type detection returns Excel4.0). */
    if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
    {
        DBG_ERRORFILE( "::ScImportExcel - wrong file format specification" );
        return eERR_FORMAT;
    }

    // check the input stream from medium
    SvStream* pMedStrm = rMedium.GetInStream();
    DBG_ASSERT( pMedStrm, "::ScImportExcel - medium without input stream" );
    if( !pMedStrm ) return eERR_OPEN;           // should not happen

    SvStream* pBookStrm = 0;            // The "Book"/"Workbook" stream containing main data.
    XclBiff eBiff = EXC_BIFF_UNKNOWN;   // The BIFF version of the main stream.

    // try to open an OLE storage
    SotStorageRef xRootStrg;
    SotStorageStreamRef xStrgStrm;
    if( SotStorage::IsStorageFile( pMedStrm ) )
    {
        xRootStrg = new SotStorage( pMedStrm, FALSE );
        if( xRootStrg->GetError() )
            xRootStrg = 0;
    }

    // try to open "Book" or "Workbook" stream in OLE storage
    if( xRootStrg.Is() )
    {
        // try to open the "Book" stream
        SotStorageStreamRef xBookStrm5 = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
        XclBiff eBookStrm5Biff = xBookStrm5.Is() ?  XclImpStream::DetectBiffVersion( *xBookStrm5 ) : EXC_BIFF_UNKNOWN;

        // try to open the "Workbook" stream
        SotStorageStreamRef xBookStrm8 = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
        XclBiff eBookStrm8Biff = xBookStrm8.Is() ?  XclImpStream::DetectBiffVersion( *xBookStrm8 ) : EXC_BIFF_UNKNOWN;

        // decide which stream to use
        if( (eBookStrm8Biff != EXC_BIFF_UNKNOWN) && ((eBookStrm5Biff == EXC_BIFF_UNKNOWN) || (eBookStrm8Biff > eBookStrm5Biff)) )
        {
            /*  Only "Workbook" stream exists; or both streams exist,
                and "Workbook" has higher BIFF version than "Book" stream. */
            xStrgStrm = xBookStrm8;
            eBiff = eBookStrm8Biff;
        }
        else if( eBookStrm5Biff != EXC_BIFF_UNKNOWN )
        {
            /*  Only "Book" stream exists; or both streams exist,
                and "Book" has higher BIFF version than "Workbook" stream. */
            xStrgStrm = xBookStrm5;
            eBiff = eBookStrm5Biff;
        }

        pBookStrm = xStrgStrm;
    }

    // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
    if( !pBookStrm )
    {
        eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
        if( eBiff != EXC_BIFF_UNKNOWN )
            pBookStrm = pMedStrm;
    }

    // try to import the file
    FltError eRet = eERR_UNKN_BIFF;
    if( pBookStrm )
    {
        pBookStrm->SetBufferSize( 0x8000 );     // still needed?

        XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
        ::std::auto_ptr< ImportExcel > xFilter;
        switch( eBiff )
        {
            case EXC_BIFF2:
            case EXC_BIFF3:
            case EXC_BIFF4:
            case EXC_BIFF5:
                xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
            break;
            case EXC_BIFF8:
                xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
            break;
            default:    DBG_ERROR_BIFF();
        }

        eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
    }

    return eRet;
}

FltError ScExportExcel234( SvStream& /*aStream*/, ScDocument* /*pDoc*/,
    ExportFormatExcel /*eFormat*/, CharSet /*eNach*/ )
{
    FltError                eRet = eERR_NI;
    return eRet;
}

FltError ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
    const BOOL bBiff8, CharSet eNach )
{
    // check the passed Calc document
    DBG_ASSERT( pDocument, "::ScImportExcel - no document" );
    if( !pDocument ) return eERR_INTERN;        // should not happen

    // check the output stream from medium
    SvStream* pMedStrm = rMedium.GetOutStream();
    DBG_ASSERT( pMedStrm, "::ScExportExcel5 - medium without output stream" );
    if( !pMedStrm ) return eERR_OPEN;           // should not happen

    // try to open an OLE storage
    SotStorageRef xRootStrg = new SotStorage( pMedStrm, FALSE );
    if( xRootStrg->GetError() ) return eERR_OPEN;

    // create BIFF dependent strings
    String aStrmName, aClipName, aClassName;
    if( bBiff8 )
    {
        aStrmName = EXC_STREAM_WORKBOOK;
        aClipName = CREATE_STRING( "Biff8" );
        aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
    }
    else
    {
        aStrmName = EXC_STREAM_BOOK;
        aClipName = CREATE_STRING( "Biff5" );
        aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
    }

    // open the "Book"/"Workbook" stream
    SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
    if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;

    xStrgStrm->SetBufferSize( 0x8000 );     // still needed?

    FltError eRet = eERR_UNKN_BIFF;
    XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
    if ( bBiff8 )
    {
        ExportBiff8 aFilter( aExpData, *xStrgStrm );
        eRet = aFilter.Write();
    }
    else
    {
        ExportBiff5 aFilter( aExpData, *xStrgStrm );
        eRet = aFilter.Write();
    }

    if( eRet == eERR_RNGOVRFLW )
        eRet = SCWARN_EXPORT_MAXROW;

    SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
    sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
    xRootStrg->SetClass( aGlobName, nClip, aClassName );

    xStrgStrm->Commit();
    xRootStrg->Commit();

    return eRet;
}

<|endoftext|>


<commit_before>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "simdindexjoin.h"

#include <annis/operators/operator.h>     // for Operator
#include <annis/util/comparefunctions.h>  // for checkAnnotationEqual
#include <algorithm>                      // for move
#include <future>                         // for future, async, launch, laun...
#include <list>                           // for list
#include "annis/iterators.h"              // for AnnoIt, Iterator
#include "annis/types.h"                  // for Match, Annotation, nodeid_t
#include "annis/util/threadpool.h"        // for ThreadPool

#include <Vc/Vc>

using namespace annis;

SIMDIndexJoin::SIMDIndexJoin(std::shared_ptr<Iterator> lhs, size_t lhsIdx,
                             std::shared_ptr<Operator> op,
                             const AnnoStorage<nodeid_t>& annos,
                             Annotation rhsAnnoToFind)
  : lhs(lhs), lhsIdx(lhsIdx), op(op), annos(annos), rhsAnnoToFind(rhsAnnoToFind)
{
}

bool SIMDIndexJoin::next(std::vector<Match> &tuple)
{
  tuple.clear();

  do
  {
    while(!matchBuffer.empty())
    {
      const MatchPair& m = matchBuffer.front();

      tuple.reserve(m.lhs.size()+1);
      tuple.insert(tuple.begin(), m.lhs.begin(), m.lhs.end());
      tuple.push_back({m.rhs, rhsAnnoToFind});

      matchBuffer.pop_front();
      return true;

    }
  } while (nextMatchBuffer());

  return false;
}

void SIMDIndexJoin::reset()
{
  if(lhs)
  {
    lhs->reset();
  }

  matchBuffer.clear();
}

bool SIMDIndexJoin::nextMatchBuffer()
{
  std::vector<Match> currentLHS;

  Vc::uint32_v valueTemplate(rhsAnnoToFind.val);

  while(matchBuffer.empty() && lhs->next(currentLHS))
  {
    std::unique_ptr<AnnoIt> reachableNodesIt = op->retrieveMatches(currentLHS[lhsIdx]);
    if(reachableNodesIt)
    {
      const bool annoDefDifferent = rhsAnnoToFind.ns != currentLHS[lhsIdx].anno.ns
          || rhsAnnoToFind.name != currentLHS[lhsIdx].anno.name;

      constexpr size_t SIMD_VECTOR_SIZE = Vc::uint32_v::size();

      Vc::uint32_v vAnnoVals;
      Vc::Mask<uint32_t> maskFoundAnnos;

      // use an aligned memory allocator to make SIMD faster

      uint32_t annoVals[SIMD_VECTOR_SIZE];
      uint32_t reachableNodes[SIMD_VECTOR_SIZE];

      Match m;
      bool foundRHS = false;
      do
      {
        foundRHS = false;

        // fill each element of the vector
        for(size_t i=0; i < SIMD_VECTOR_SIZE; i++)
        {
          if(reachableNodesIt->next(m))
          {
            std::vector<Annotation> foundAnnos = annos.getAnnotations(m.node, rhsAnnoToFind.ns, rhsAnnoToFind.name);
            annoVals[i] = (foundAnnos.empty() ? 0 : foundAnnos[0].val);
            reachableNodes[i] = (m.node);

            foundRHS = true;
          }
          else
          {
            annoVals[i] = 0;
            reachableNodes[i] = 0;
          }
        }

        // transform the data to SIMD
        vAnnoVals.load(annoVals, Vc::Aligned);

        // search for values that are the same as a SIMD instruction
        maskFoundAnnos = (vAnnoVals == valueTemplate);
        if(Vc::any_of(maskFoundAnnos))
        {
          for(size_t foundIdx=static_cast<size_t>(maskFoundAnnos.firstOne()); foundIdx < maskFoundAnnos.size(); foundIdx++)
          {
            if(maskFoundAnnos[foundIdx])
            {
              if(annoDefDifferent || op->isReflexive() || currentLHS[lhsIdx].node != reachableNodes[foundIdx])
              {
                matchBuffer.push_back({currentLHS, reachableNodes[foundIdx]});
              }
            }
          }
        }

      } while(foundRHS);
    } // end if reachable nodes iterator valide
  } // end while LHS valid and nothing found yet

  return !matchBuffer.empty();
}

SIMDIndexJoin::~SIMDIndexJoin()
{
}
<commit_msg>Some smaller performance improvements.<commit_after>/*
   Copyright 2017 Thomas Krause <thomaskrause@posteo.de>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "simdindexjoin.h"

#include <annis/operators/operator.h>     // for Operator
#include <annis/util/comparefunctions.h>  // for checkAnnotationEqual
#include <algorithm>                      // for move
#include <future>                         // for future, async, launch, laun...
#include <list>                           // for list
#include "annis/iterators.h"              // for AnnoIt, Iterator
#include "annis/types.h"                  // for Match, Annotation, nodeid_t
#include "annis/util/threadpool.h"        // for ThreadPool

#include <Vc/Vc>

using namespace annis;

SIMDIndexJoin::SIMDIndexJoin(std::shared_ptr<Iterator> lhs, size_t lhsIdx,
                             std::shared_ptr<Operator> op,
                             const AnnoStorage<nodeid_t>& annos,
                             Annotation rhsAnnoToFind)
  : lhs(lhs), lhsIdx(lhsIdx), op(op), annos(annos), rhsAnnoToFind(rhsAnnoToFind)
{
}

bool SIMDIndexJoin::next(std::vector<Match> &tuple)
{
  tuple.clear();

  do
  {
    while(!matchBuffer.empty())
    {
      const MatchPair& m = matchBuffer.front();

      tuple.reserve(m.lhs.size()+1);
      tuple.insert(tuple.begin(), m.lhs.begin(), m.lhs.end());
      tuple.push_back({m.rhs, rhsAnnoToFind});

      matchBuffer.pop_front();
      return true;

    }
  } while (nextMatchBuffer());

  return false;
}

void SIMDIndexJoin::reset()
{
  if(lhs)
  {
    lhs->reset();
  }

  matchBuffer.clear();
}

bool SIMDIndexJoin::nextMatchBuffer()
{
  std::vector<Match> currentLHS;

  Vc::uint32_v valueTemplate(rhsAnnoToFind.val);

  while(matchBuffer.empty() && lhs->next(currentLHS))
  {
    std::unique_ptr<AnnoIt> reachableNodesIt = op->retrieveMatches(currentLHS[lhsIdx]);
    if(reachableNodesIt)
    {
      const bool annoDefDifferent = rhsAnnoToFind.ns != currentLHS[lhsIdx].anno.ns
          || rhsAnnoToFind.name != currentLHS[lhsIdx].anno.name;

      constexpr size_t SIMD_VECTOR_SIZE = Vc::uint32_v::size();

      Vc::uint32_v vAnnoVals;
      Vc::Mask<uint32_t> maskFoundAnnos;

      // use an aligned memory allocator to make SIMD faster

      uint32_t annoVals[SIMD_VECTOR_SIZE];
      uint32_t reachableNodes[SIMD_VECTOR_SIZE];

      bool foundRHS = false;
      do
      {
        foundRHS = false;

        // fill each element of the vector
        for(size_t i=0; i < SIMD_VECTOR_SIZE; i++)
        {
          Match m;
          if(reachableNodesIt->next(m))
          {
            std::vector<Annotation> foundAnnos = annos.getAnnotations(m.node, rhsAnnoToFind.ns, rhsAnnoToFind.name);
            annoVals[i] = (foundAnnos.empty() ? 0 : foundAnnos[0].val);
            reachableNodes[i] = (m.node);

            foundRHS = true;
          }
          else
          {
            annoVals[i] = 0;
          }
        }

        // transform the data to SIMD
        vAnnoVals.load(annoVals, Vc::Aligned);

        // search for values that are the same as a SIMD instruction
        maskFoundAnnos = (vAnnoVals == valueTemplate);
        if(Vc::any_of(maskFoundAnnos))
        {
          for(size_t foundIdx : Vc::where(maskFoundAnnos))
          {
            if(annoDefDifferent || op->isReflexive() || currentLHS[lhsIdx].node != reachableNodes[foundIdx])
            {
              matchBuffer.push_back({currentLHS, reachableNodes[foundIdx]});
            }
          }
        }

      } while(foundRHS);
    } // end if reachable nodes iterator valide
  } // end while LHS valid and nothing found yet

  return !matchBuffer.empty();
}

SIMDIndexJoin::~SIMDIndexJoin()
{
}
<|endoftext|>


<commit_before>#include "RidgeEdgeModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Algorithms/ModelBasedSegmentation/Shape.hpp"
#include <boost/shared_array.hpp>

namespace fast {

RidgeEdgeModel::RidgeEdgeModel() {
	mMinimumDepth = 0;
	mLineLength = 0;
	mLineSampleSpacing = 0;
	mIntensityDifferenceThreshold = 20;
	mSizes.push_back(1);
}

typedef struct DetectedEdge {
    int edgeIndex;
    float uncertainty;
} DetectedEdge;

inline DetectedEdge findEdge(
        std::vector<float> intensityProfile, const float intensityThreshold, std::vector<int> sizes) {
    // Pre calculate partial sum
    const int line_length = intensityProfile.size();
    boost::shared_array<float> sum_k(new float[line_length]());
    float totalSum = 0.0f;
    for(int k = 0; k < line_length; ++k) {
        if(k == 0) {
            sum_k[k] = intensityProfile[0];
        }else{
            sum_k[k] = sum_k[k-1] + intensityProfile[k];
        }
        totalSum += intensityProfile[k];
    }

    float bestScore = std::numeric_limits<float>::max();
    int bestK = -1;
    float bestHeightDifference = 0;
	for(int size : sizes) {
		for(int k = 1; k < line_length - size; ++k) {
			float score = 0.0f;
			// A 1
			float average1 = sum_k[k] / k;
			for(int t = 0; t <= k; ++t) {
				score += fabs(average1 - intensityProfile[t]);
			}

			// A 2
			float average2 = (sum_k[k+size] - sum_k[k]) / (size);
			for(int t = k+1; t <= k+size; ++t) {
				score += fabs(average2 - intensityProfile[t]);
			}

			// A 3
			float average3 = (sum_k[line_length-1] - sum_k[k+size]) / (line_length - k - size);
			for(int t = k + size + 1; t < line_length; ++t) {
				score += fabs(average3 - intensityProfile[t]);
			}
			if(score < bestScore) {
				bestScore = score;
				bestK = k;
				float weight1 = (float)(k) / (line_length - size);
				float weight2 = (float)(line_length - k - size) / (line_length - size);
                bestHeightDifference = average2 - (average1*weight1 + average2*weight2);
			}
		}
	}

    DetectedEdge edge;

    if(bestHeightDifference < intensityThreshold) {
        edge.edgeIndex = -1;
    } else {
        edge.edgeIndex = bestK;
        edge.uncertainty = 1.0f/fabs(bestHeightDifference);
    }

    return edge;
}

inline bool isInBounds(Image::pointer image, const Vector4f& position) {
    return position(0) >= 0 && position(1) >= 0 && position(2) >= 0 &&
        position(0) < image->getWidth() && position(1) < image->getHeight() && position(2) < image->getDepth();
}

inline float getValue(void* pixelPointer, Image::pointer image, const Vector4f& position) {

    uint index = (int)position(0)+(int)position(1)*image->getWidth()+(int)position(2)*image->getWidth()*image->getHeight();
    float value;
    switch(image->getDataType()) {
        // This macro creates a case statement for each data type and sets FAST_TYPE to the correct C++ data type
        fastSwitchTypeMacro(value = ((FAST_TYPE*)pixelPointer)[index]);
    }
    return value;
}

std::vector<Measurement> RidgeEdgeModel::getMeasurements(SharedPointer<Image> image, SharedPointer<Shape> shape) {
	if(mLineLength == 0 || mLineSampleSpacing == 0)
		throw Exception("Line length and sample spacing must be given to the RidgeEdgeModel");

	std::vector<Measurement> measurements;
	Mesh::pointer predictedMesh = shape->getMesh();
	MeshAccess::pointer predictedMeshAccess = predictedMesh->getMeshAccess(ACCESS_READ);
	std::vector<MeshVertex> points = predictedMeshAccess->getVertices();

	ImageAccess::pointer access = image->getImageAccess(ACCESS_READ);

	// Convert sizes to pixels, also make sure it is dividible by 2
	std::vector<int> sizesInSteps;
	for(float size : mSizes) {
		// Convert from mm to steps (approx)
		int steps = round(size / mLineSampleSpacing);
		// Make divisible by 2 for convienience
		if(steps % 2 != 0) {
			steps++;
		}
		sizesInSteps.push_back(steps);
		reportInfo() << "Added step size: " << steps << reportEnd();
	}

	// For each point on the shape do a line search in the direction of the normal
	// Return set of displacements and uncertainties
	if(image->getDimensions() == 3) {
		AffineTransformation::pointer transformMatrix = SceneGraph::getAffineTransformationFromData(image);
		transformMatrix->scale(image->getSpacing());
		Matrix4f inverseTransformMatrix = transformMatrix->matrix().inverse();

		// Get model scene graph transform
		AffineTransformation::pointer modelTransformation = SceneGraph::getAffineTransformationFromData(shape->getMesh());
		MatrixXf modelTransformMatrix = modelTransformation->affine();

		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
				// Apply model transform
				// TODO the line search normal*d should propably be applied after this transform, so that we know that is correct units?
				position = modelTransformMatrix*position.homogeneous();
				const Vector4f longPosition(position(0), position(1), position(2), 1);
				// Apply image inverse transform to get image voxel position
				const Vector4f positionInt = inverseTransformMatrix*longPosition;
				try {
					const float value = access->getScalar(positionInt.cast<int>());
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile, mIntensityDifferenceThreshold, sizesInSteps);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector3f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	} else {
		Vector3f spacing = image->getSpacing();
		// For 2D images
		// For 2D, we probably want to ignore scene graph, and only use spacing.
		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
				const Vector2i pixelPosition(round(position.x() / spacing.x()), round(position.y() / spacing.y()));
				if(position.y() < mMinimumDepth)
					continue;
				try {
					const float value = access->getScalar(pixelPosition);
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile, mIntensityDifferenceThreshold, sizesInSteps);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector2f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	}

	return measurements;
}

void RidgeEdgeModel::setRidgeSizes(std::vector<float> sizes) {
	mSizes = sizes;
}

void RidgeEdgeModel::setLineLength(float length) {
	if(length <= 0)
		throw Exception("Length must be > 0");
	mLineLength = length;
}

void RidgeEdgeModel::setLineSampleSpacing(float spacing) {
	if(spacing <= 0)
		throw Exception("Sample spacing must be > 0");
	mLineSampleSpacing = spacing;
}

void RidgeEdgeModel::setIntensityDifferenceThreshold(float threshold) {
	if(threshold <= 0)
		throw Exception("Intensity difference threshold must be > 0");
	mIntensityDifferenceThreshold = threshold;
}

void RidgeEdgeModel::setMinimumDepth(float depth) {
	if(depth < 0)
		throw Exception("Minimum depth must be > 0 in RidgeEdgeModel");
	mMinimumDepth = depth;
}

}
<commit_msg>fixed some calculations in new ridge edge model<commit_after>#include "RidgeEdgeModel.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/Algorithms/ModelBasedSegmentation/Shape.hpp"
#include <boost/shared_array.hpp>

namespace fast {

RidgeEdgeModel::RidgeEdgeModel() {
	mMinimumDepth = 0;
	mLineLength = 0;
	mLineSampleSpacing = 0;
	mIntensityDifferenceThreshold = 20;
    std::vector<float> sizes = {1, 1.5, 2, 2.5, 3, 3.5, 4};
	mSizes = sizes;
}

typedef struct DetectedEdge {
    int edgeIndex;
    float uncertainty;
} DetectedEdge;

inline DetectedEdge findEdge(
        std::vector<float> intensityProfile, const float intensityThreshold, std::vector<int> sizes) {
    // Pre calculate partial sum
    const int line_length = intensityProfile.size();
    boost::shared_array<float> sum_k(new float[line_length]());
    float totalSum = 0.0f;
    for(int k = 0; k < line_length; ++k) {
        if(k == 0) {
            sum_k[k] = intensityProfile[0];
        }else{
            sum_k[k] = sum_k[k-1] + intensityProfile[k];
        }
        totalSum += intensityProfile[k];
    }

    float bestScore = std::numeric_limits<float>::max();
    int bestK = -1;
    float bestHeightDifference = 0;
	for(int size : sizes) {
		for(int k = 1; k < line_length - size; ++k) {
			float score = 0.0f;
			// A 1
			float average1 = sum_k[k] / (k+1);
			for(int t = 0; t <= k; ++t) {
				score += fabs(average1 - intensityProfile[t]);
			}

			// A 2
			float average2 = (sum_k[k+size] - sum_k[k]) / (size);
			for(int t = k+1; t <= k+size; ++t) {
				score += fabs(average2 - intensityProfile[t]);
			}

			// A 3
			float average3 = (sum_k[line_length-1] - sum_k[k+size]) / (line_length - 1 - k - size);
			for(int t = k + size + 1; t < line_length; ++t) {
				score += fabs(average3 - intensityProfile[t]);
			}
			if(score < bestScore) {
				bestScore = score;
				bestK = k;
				float weight1 = (float)(k) / (line_length - size);
				float weight2 = (float)(line_length - k - size) / (line_length - size);
                bestHeightDifference = average2 - (average1*weight1 + average2*weight2);
			}
		}
	}

    DetectedEdge edge;

    if(bestHeightDifference < intensityThreshold) {
        edge.edgeIndex = -1;
    } else {
        edge.edgeIndex = bestK;
        edge.uncertainty = 1.0f/fabs(bestHeightDifference);
    }

    return edge;
}

inline bool isInBounds(Image::pointer image, const Vector4f& position) {
    return position(0) >= 0 && position(1) >= 0 && position(2) >= 0 &&
        position(0) < image->getWidth() && position(1) < image->getHeight() && position(2) < image->getDepth();
}

inline float getValue(void* pixelPointer, Image::pointer image, const Vector4f& position) {

    uint index = (int)position(0)+(int)position(1)*image->getWidth()+(int)position(2)*image->getWidth()*image->getHeight();
    float value;
    switch(image->getDataType()) {
        // This macro creates a case statement for each data type and sets FAST_TYPE to the correct C++ data type
        fastSwitchTypeMacro(value = ((FAST_TYPE*)pixelPointer)[index]);
    }
    return value;
}

std::vector<Measurement> RidgeEdgeModel::getMeasurements(SharedPointer<Image> image, SharedPointer<Shape> shape) {
	if(mLineLength == 0 || mLineSampleSpacing == 0)
		throw Exception("Line length and sample spacing must be given to the RidgeEdgeModel");

	std::vector<Measurement> measurements;
	Mesh::pointer predictedMesh = shape->getMesh();
	MeshAccess::pointer predictedMeshAccess = predictedMesh->getMeshAccess(ACCESS_READ);
	std::vector<MeshVertex> points = predictedMeshAccess->getVertices();

	ImageAccess::pointer access = image->getImageAccess(ACCESS_READ);

	// Convert sizes to pixels, also make sure it is dividible by 2
	std::vector<int> sizesInSteps;
	for(float size : mSizes) {
		// Convert from mm to steps (approx)
		int steps = round(size / mLineSampleSpacing);
		// Make divisible by 2 for convienience
		if(steps % 2 != 0 && steps == 0) {
			steps++;
		}
		sizesInSteps.push_back(steps);
	}

	// For each point on the shape do a line search in the direction of the normal
	// Return set of displacements and uncertainties
	if(image->getDimensions() == 3) {
		AffineTransformation::pointer transformMatrix = SceneGraph::getAffineTransformationFromData(image);
		transformMatrix->scale(image->getSpacing());
		Matrix4f inverseTransformMatrix = transformMatrix->matrix().inverse();

		// Get model scene graph transform
		AffineTransformation::pointer modelTransformation = SceneGraph::getAffineTransformationFromData(shape->getMesh());
		MatrixXf modelTransformMatrix = modelTransformation->affine();

		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
				// Apply model transform
				// TODO the line search normal*d should propably be applied after this transform, so that we know that is correct units?
				position = modelTransformMatrix*position.homogeneous();
				const Vector4f longPosition(position(0), position(1), position(2), 1);
				// Apply image inverse transform to get image voxel position
				const Vector4f positionInt = inverseTransformMatrix*longPosition;
				try {
					const float value = access->getScalar(positionInt.cast<int>());
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile, mIntensityDifferenceThreshold, sizesInSteps);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector3f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector3f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	} else {
		Vector3f spacing = image->getSpacing();
		// For 2D images
		// For 2D, we probably want to ignore scene graph, and only use spacing.
		// Do edge detection for each vertex
		int counter = 0;
		for(int i = 0; i < points.size(); ++i) {
			std::vector<float> intensityProfile;
			unsigned int startPos = 0;
			bool startFound = false;
			for(float d = -mLineLength/2; d < mLineLength/2; d += mLineSampleSpacing) {
				Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
				const Vector2i pixelPosition(round(position.x() / spacing.x()), round(position.y() / spacing.y()));
				if(position.y() < mMinimumDepth)
					continue;
				try {
					const float value = access->getScalar(pixelPosition);
					if(value > 0) {
						intensityProfile.push_back(value);
						startFound = true;
					} else if(!startFound) {
						startPos++;
					}
				} catch(Exception &e) {
					if(!startFound) {
						startPos++;
					}
				}
			}
			Measurement m;
			m.uncertainty = 1;
			m.displacement = 0;
			if(startFound){
				DetectedEdge edge = findEdge(intensityProfile, mIntensityDifferenceThreshold, sizesInSteps);
				if(edge.edgeIndex != -1) {
					float d = -mLineLength/2.0f + (startPos + edge.edgeIndex)*mLineSampleSpacing;
					const Vector2f position = points[i].getPosition() + points[i].getNormal()*d;
					m.uncertainty = edge.uncertainty;
					const Vector2f normal = points[i].getNormal();
					m.displacement = normal.dot(position-points[i].getPosition());
					counter++;
				}
			}
			measurements.push_back(m);
		}
	}

	return measurements;
}

void RidgeEdgeModel::setRidgeSizes(std::vector<float> sizes) {
	mSizes = sizes;
}

void RidgeEdgeModel::setLineLength(float length) {
	if(length <= 0)
		throw Exception("Length must be > 0");
	mLineLength = length;
}

void RidgeEdgeModel::setLineSampleSpacing(float spacing) {
	if(spacing <= 0)
		throw Exception("Sample spacing must be > 0");
	mLineSampleSpacing = spacing;
}

void RidgeEdgeModel::setIntensityDifferenceThreshold(float threshold) {
	if(threshold <= 0)
		throw Exception("Intensity difference threshold must be > 0");
	mIntensityDifferenceThreshold = threshold;
}

void RidgeEdgeModel::setMinimumDepth(float depth) {
	if(depth < 0)
		throw Exception("Minimum depth must be > 0 in RidgeEdgeModel");
	mMinimumDepth = depth;
}

}
<|endoftext|>


<commit_before>#include <iostream>
#include "chain.h"
using namespace std;

int main (int argc, char *argv[]){

	if(argc < 2)
	{
		cout << "Enter the file name as input" <<endl;
		return 0;
	}

	//Creates new chain
	chain *mychain = new chain(100);

	int multOf = 5;

	// Read the file with filename stored in argv[1]. Store the numbers in mychain.

	mychain->readAndStoreFromFile(argv[1]);

	//Print mychain
	cout<<"\n\n The list is : "<<endl;
	mychain->output();

	// Delete all entries from mychain which contain element that is multiple of variable multOf

	mychain->eraseModuloValue(multOf);

	//Print mychain
	cout<<"\n\n The list after removal of elements with multiple of 5 is : "<<endl;
	mychain->output();

	//Reorder mychain such that all odd numbers precede all even numbers.
	//Note that the original ordering between odd (even) numbers should remain intact.
	//Example: 3 4 5 1 2 will become 3 5 1 4 2. But, 5 1 3 4 2 is not valid.
	mychain->oddAndEvenOrdering();

	//Print mychain
	cout<<"\n\n The list after odd and even ordering is : "<<endl;
	mychain->output();

	cout<<"\n\n cats: "<<endl;
	//Reverse the mychain
	mychain->reverse();

	//Print mychain
	cout<<"\n\n The reversed list is : "<<endl;
	mychain->output();

}
<commit_msg>Update main.cpp<commit_after>#include <iostream>
#include "chain.h"
using namespace std;

int main (int argc, char *argv[]){

	if(argc < 2)
	{
		cout << "Enter the file name as input" <<endl;
		return 0;
	}

	//Creates new chain
	chain *mychain = new chain(100);

	int multOf = 5;

	// Read the file with filename stored in argv[1]. Store the numbers in mychain.

	mychain->readAndStoreFromFile(argv[1]);

	//Print mychain
	cout<<"\n\n The list is : "<<endl;
	mychain->output();

	// Delete all entries from mychain which contain element that is multiple of variable multOf

	mychain->eraseModuloValue(multOf);

	//Print mychain
	cout<<"\n\n The list after removal of elements with multiple of 5 is : "<<endl;
	mychain->output();

	//Reorder mychain such that all odd numbers precede all even numbers.
	//Note that the original ordering between odd (even) numbers should remain intact.
	//Example: 3 4 5 1 2 will become 3 5 1 4 2. But, 5 1 3 4 2 is not valid.
	mychain->oddAndEvenOrdering();

	//Print mychain
	cout<<"\n\n The list after odd and even ordering is : "<<endl;
	mychain->output();

	//Reverse the mychain
	mychain->reverse();

	//Print mychain
	cout<<"\n\n The reversed list is : "<<endl;
	mychain->output();

}
<|endoftext|>


<commit_before>#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <cstdint>
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>

#ifdef __cplusplus
extern "C" {
#endif
#include "benchmark.h"
#include "numbersfromtextfiles.h"
#ifdef __cplusplus
}
#endif

#ifdef MEMTRACKED
#include "memtrackingallocator.h"
#else
size_t memory_usage;
#endif

void initializeMemUsageCounter()  {
    memory_usage = 0;
}

uint64_t getMemUsageInBytes()  {
    return memory_usage;
}

#ifdef MEMTRACKED
typedef std::vector<uint32_t,MemoryCountingAllocator<uint32_t> >  vector;
#else
typedef std::vector<uint32_t>  vector;
#endif

static vector  fast_logicalor(size_t n, const vector **inputs) {
	  class StdVectorPtr {

	  public:
	    StdVectorPtr(const vector *p, bool o) : ptr(p), own(o) {}
	    const vector *ptr;
	    bool own; // whether to clean

	    bool operator<(const StdVectorPtr &o) const {
	      return o.ptr->size() < ptr->size(); // backward on purpose
	    }
	  };

	  if (n == 0) {
		return vector();
	  }
	  if (n == 1) {
	    return vector(*inputs[0]);
	  }
	  std::priority_queue<StdVectorPtr> pq;
	  for (size_t i = 0; i < n; i++) {
	    // could use emplace
	    pq.push(StdVectorPtr(inputs[i], false));
	  }
	  while (pq.size() > 2) {

	    StdVectorPtr x1 = pq.top();
	    pq.pop();

	    StdVectorPtr x2 = pq.top();
	    pq.pop();
	    vector * buffer = new vector();
      std::set_union(x1.ptr->begin(), x1.ptr->end(),x2.ptr->begin(), x2.ptr->end(),std::back_inserter(*buffer));
	    if (x1.own) {
	      delete x1.ptr;
	    }
	    if (x2.own) {
	      delete x2.ptr;
	    }
	    pq.push(StdVectorPtr(buffer, true));
	  }
	  StdVectorPtr x1 = pq.top();
	  pq.pop();

	  StdVectorPtr x2 = pq.top();
	  pq.pop();

	  vector  container;
    std::set_union(x1.ptr->begin(), x1.ptr->end(),x2.ptr->begin(), x2.ptr->end(),std::back_inserter(container));

	  if (x1.own) {
	    delete x1.ptr;
	  }
	  if (x2.own) {
	    delete x2.ptr;
	  }
	  return container;
	}

/**
 * Once you have collected all the integers, build the bitmaps.
 */
static std::vector<vector > create_all_bitmaps(size_t *howmany,
        uint32_t **numbers, size_t count) {
    if (numbers == NULL) return std::vector<vector >();
    std::vector<vector > answer(count);

    for (size_t i = 0; i < count; i++) {
        vector & bm = answer[i];
        uint32_t * mynumbers = numbers[i];
        for(size_t j = 0; j < howmany[i] ; ++j) {
            bm.push_back(mynumbers[j]);
        }
        bm.shrink_to_fit();
    }
    return answer;
}

static void printusage(char *command) {
    printf(
        " Try %s directory \n where directory could be "
        "benchmarks/realdata/census1881\n",
        command);
    ;
    printf("the -v flag turns on verbose mode");

}

int main(int argc, char **argv) {
    int c;
    const char *extension = ".txt";
    bool verbose = false;
    uint64_t data[6];
    initializeMemUsageCounter();
    while ((c = getopt(argc, argv, "ve:h")) != -1) switch (c) {
        case 'e':
            extension = optarg;
            break;
        case 'v':
            verbose = true;
            break;
        case 'h':
            printusage(argv[0]);
            return 0;
        default:
            abort();
        }
    if (optind >= argc) {
        printusage(argv[0]);
        return -1;
    }
    char *dirname = argv[optind];
    size_t count;

    size_t *howmany = NULL;
    uint32_t **numbers =
        read_all_integer_files(dirname, extension, &howmany, &count);
    if (numbers == NULL) {
        printf(
            "I could not find or load any data file with extension %s in "
            "directory %s.\n",
            extension, dirname);
        return -1;
    }
    uint32_t maxvalue = 0;
    for (size_t i = 0; i < count; i++) {
      if( howmany[i] > 0 ) {
        if(maxvalue < numbers[i][howmany[i]-1]) {
           maxvalue = numbers[i][howmany[i]-1];
         }
      }
    }
    uint64_t totalcard = 0;
    for (size_t i = 0; i < count; i++) {
      totalcard += howmany[i];
    }
    uint64_t successivecard = 0;
    for (size_t i = 1; i < count; i++) {
       successivecard += howmany[i-1] + howmany[i];
    }
    uint64_t cycles_start = 0, cycles_final = 0;

    RDTSC_START(cycles_start);
    std::vector<vector> bitmaps = create_all_bitmaps(howmany, numbers, count);
    RDTSC_FINAL(cycles_final);
    if (bitmaps.empty()) return -1;
    if(verbose) printf("Loaded %d bitmaps from directory %s \n", (int)count, dirname);
    uint64_t totalsize = getMemUsageInBytes();
    data[0] = totalsize;

    if(verbose) printf("Total size in bytes =  %" PRIu64 " \n", totalsize);

    uint64_t successive_and = 0;
    uint64_t successive_or = 0;
    uint64_t total_or = 0;

    RDTSC_START(cycles_start);
    for (int i = 0; i < (int)count - 1; ++i) {
        vector v;
        std::set_intersection(bitmaps[i].begin(), bitmaps[i].end(),bitmaps[i+1].begin(), bitmaps[i+1].end(),std::back_inserter(v));
        successive_and += v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[1] = cycles_final - cycles_start;
    if(verbose) printf("Successive intersections on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    for (int i = 0; i < (int)count - 1; ++i) {
        vector v;
        std::set_union(bitmaps[i].begin(), bitmaps[i].end(),bitmaps[i+1].begin(), bitmaps[i+1].end(),std::back_inserter(v));
        successive_or += v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[2] = cycles_final - cycles_start;
    if(verbose) printf("Successive unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    if(count>1) {
        vector v;
        std::set_union(bitmaps[0].begin(), bitmaps[0].end(),bitmaps[1].begin(), bitmaps[1].end(),std::back_inserter(v));
        for (int i = 2; i < (int)count ; ++i) {
            vector newv;
            std::set_union(v.begin(), v.end(),bitmaps[i].begin(), bitmaps[i].end(),std::back_inserter(newv));
            v.swap(newv);
        }
        total_or = v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[3] = cycles_final - cycles_start;
    if(verbose) printf("Total naive unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);
    RDTSC_START(cycles_start);
    if(count>1) {
        const vector  ** allofthem = new const vector* [count];
        for(int i = 0 ; i < (int) count; ++i) allofthem[i] = & bitmaps[i];
        vector totalorbitmap = fast_logicalor(count, allofthem);
        total_or = totalorbitmap.size();
        delete[] allofthem;
    }
    RDTSC_FINAL(cycles_final);
    data[4] = cycles_final - cycles_start;
    if(verbose) printf("Total heap unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    uint64_t quartcount = 0;
    for (size_t i = 0; i < count ; ++i) {
      auto X1 = std::find(bitmaps[i].begin(),bitmaps[i].end(),maxvalue/4 );
      if(X1 != bitmaps[i].end())
      	quartcount ++;
      auto X2 = std::find(bitmaps[i].begin(),bitmaps[i].end(),maxvalue/2 );
      if(X2 != bitmaps[i].end())
      	quartcount ++;
      auto X3 = std::find(bitmaps[i].begin(),bitmaps[i].end(),3*maxvalue/4 );
      if(X3 != bitmaps[i].end())
      	quartcount ++;
    }
    RDTSC_FINAL(cycles_final);
    data[5] = cycles_final - cycles_start;

    if(verbose) printf("Quartile queries on %zu bitmaps took %" PRIu64 " cycles\n", count,
           cycles_final - cycles_start);

    if(verbose) printf("Collected stats  %" PRIu64 "  %" PRIu64 "  %" PRIu64 " %" PRIu64 "\n",successive_and,successive_or,total_or,quartcount);

    printf(" %20.2f %20.2f %20.2f %20.2f %20.2f %20.2f \n",
      data[0]*8.0/totalcard,
      data[1]*1.0/successivecard,
      data[2]*1.0/successivecard,
      data[3]*1.0/totalcard,
      data[4]*1.0/totalcard,
      data[5]*1.0/(3*count)
    );

    for (int i = 0; i < (int)count; ++i) {
        free(numbers[i]);
        numbers[i] = NULL;  // paranoid
    }
    free(howmany);
    free(numbers);

    return 0;
}
<commit_msg>Switching to binary search.<commit_after>#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <cstdint>
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>

#ifdef __cplusplus
extern "C" {
#endif
#include "benchmark.h"
#include "numbersfromtextfiles.h"
#ifdef __cplusplus
}
#endif

#ifdef MEMTRACKED
#include "memtrackingallocator.h"
#else
size_t memory_usage;
#endif

void initializeMemUsageCounter()  {
    memory_usage = 0;
}

uint64_t getMemUsageInBytes()  {
    return memory_usage;
}

#ifdef MEMTRACKED
typedef std::vector<uint32_t,MemoryCountingAllocator<uint32_t> >  vector;
#else
typedef std::vector<uint32_t>  vector;
#endif

static vector  fast_logicalor(size_t n, const vector **inputs) {
	  class StdVectorPtr {

	  public:
	    StdVectorPtr(const vector *p, bool o) : ptr(p), own(o) {}
	    const vector *ptr;
	    bool own; // whether to clean

	    bool operator<(const StdVectorPtr &o) const {
	      return o.ptr->size() < ptr->size(); // backward on purpose
	    }
	  };

	  if (n == 0) {
		return vector();
	  }
	  if (n == 1) {
	    return vector(*inputs[0]);
	  }
	  std::priority_queue<StdVectorPtr> pq;
	  for (size_t i = 0; i < n; i++) {
	    // could use emplace
	    pq.push(StdVectorPtr(inputs[i], false));
	  }
	  while (pq.size() > 2) {

	    StdVectorPtr x1 = pq.top();
	    pq.pop();

	    StdVectorPtr x2 = pq.top();
	    pq.pop();
	    vector * buffer = new vector();
      std::set_union(x1.ptr->begin(), x1.ptr->end(),x2.ptr->begin(), x2.ptr->end(),std::back_inserter(*buffer));
	    if (x1.own) {
	      delete x1.ptr;
	    }
	    if (x2.own) {
	      delete x2.ptr;
	    }
	    pq.push(StdVectorPtr(buffer, true));
	  }
	  StdVectorPtr x1 = pq.top();
	  pq.pop();

	  StdVectorPtr x2 = pq.top();
	  pq.pop();

	  vector  container;
    std::set_union(x1.ptr->begin(), x1.ptr->end(),x2.ptr->begin(), x2.ptr->end(),std::back_inserter(container));

	  if (x1.own) {
	    delete x1.ptr;
	  }
	  if (x2.own) {
	    delete x2.ptr;
	  }
	  return container;
	}

/**
 * Once you have collected all the integers, build the bitmaps.
 */
static std::vector<vector > create_all_bitmaps(size_t *howmany,
        uint32_t **numbers, size_t count) {
    if (numbers == NULL) return std::vector<vector >();
    std::vector<vector > answer(count);

    for (size_t i = 0; i < count; i++) {
        vector & bm = answer[i];
        uint32_t * mynumbers = numbers[i];
        for(size_t j = 0; j < howmany[i] ; ++j) {
            bm.push_back(mynumbers[j]);
        }
        bm.shrink_to_fit();
    }
    return answer;
}

static void printusage(char *command) {
    printf(
        " Try %s directory \n where directory could be "
        "benchmarks/realdata/census1881\n",
        command);
    ;
    printf("the -v flag turns on verbose mode");

}

int main(int argc, char **argv) {
    int c;
    const char *extension = ".txt";
    bool verbose = false;
    uint64_t data[6];
    initializeMemUsageCounter();
    while ((c = getopt(argc, argv, "ve:h")) != -1) switch (c) {
        case 'e':
            extension = optarg;
            break;
        case 'v':
            verbose = true;
            break;
        case 'h':
            printusage(argv[0]);
            return 0;
        default:
            abort();
        }
    if (optind >= argc) {
        printusage(argv[0]);
        return -1;
    }
    char *dirname = argv[optind];
    size_t count;

    size_t *howmany = NULL;
    uint32_t **numbers =
        read_all_integer_files(dirname, extension, &howmany, &count);
    if (numbers == NULL) {
        printf(
            "I could not find or load any data file with extension %s in "
            "directory %s.\n",
            extension, dirname);
        return -1;
    }
    uint32_t maxvalue = 0;
    for (size_t i = 0; i < count; i++) {
      if( howmany[i] > 0 ) {
        if(maxvalue < numbers[i][howmany[i]-1]) {
           maxvalue = numbers[i][howmany[i]-1];
         }
      }
    }
    uint64_t totalcard = 0;
    for (size_t i = 0; i < count; i++) {
      totalcard += howmany[i];
    }
    uint64_t successivecard = 0;
    for (size_t i = 1; i < count; i++) {
       successivecard += howmany[i-1] + howmany[i];
    }
    uint64_t cycles_start = 0, cycles_final = 0;

    RDTSC_START(cycles_start);
    std::vector<vector> bitmaps = create_all_bitmaps(howmany, numbers, count);
    RDTSC_FINAL(cycles_final);
    if (bitmaps.empty()) return -1;
    if(verbose) printf("Loaded %d bitmaps from directory %s \n", (int)count, dirname);
    uint64_t totalsize = getMemUsageInBytes();
    data[0] = totalsize;

    if(verbose) printf("Total size in bytes =  %" PRIu64 " \n", totalsize);

    uint64_t successive_and = 0;
    uint64_t successive_or = 0;
    uint64_t total_or = 0;

    RDTSC_START(cycles_start);
    for (int i = 0; i < (int)count - 1; ++i) {
        vector v;
        std::set_intersection(bitmaps[i].begin(), bitmaps[i].end(),bitmaps[i+1].begin(), bitmaps[i+1].end(),std::back_inserter(v));
        successive_and += v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[1] = cycles_final - cycles_start;
    if(verbose) printf("Successive intersections on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    for (int i = 0; i < (int)count - 1; ++i) {
        vector v;
        std::set_union(bitmaps[i].begin(), bitmaps[i].end(),bitmaps[i+1].begin(), bitmaps[i+1].end(),std::back_inserter(v));
        successive_or += v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[2] = cycles_final - cycles_start;
    if(verbose) printf("Successive unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    if(count>1) {
        vector v;
        std::set_union(bitmaps[0].begin(), bitmaps[0].end(),bitmaps[1].begin(), bitmaps[1].end(),std::back_inserter(v));
        for (int i = 2; i < (int)count ; ++i) {
            vector newv;
            std::set_union(v.begin(), v.end(),bitmaps[i].begin(), bitmaps[i].end(),std::back_inserter(newv));
            v.swap(newv);
        }
        total_or = v.size();
    }
    RDTSC_FINAL(cycles_final);
    data[3] = cycles_final - cycles_start;
    if(verbose) printf("Total naive unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);
    RDTSC_START(cycles_start);
    if(count>1) {
        const vector  ** allofthem = new const vector* [count];
        for(int i = 0 ; i < (int) count; ++i) allofthem[i] = & bitmaps[i];
        vector totalorbitmap = fast_logicalor(count, allofthem);
        total_or = totalorbitmap.size();
        delete[] allofthem;
    }
    RDTSC_FINAL(cycles_final);
    data[4] = cycles_final - cycles_start;
    if(verbose) printf("Total heap unions on %zu bitmaps took %" PRIu64 " cycles\n", count,
                           cycles_final - cycles_start);

    RDTSC_START(cycles_start);
    uint64_t quartcount = 0;
    for (size_t i = 0; i < count ; ++i) {
      if ( std::binary_search(bitmaps[i].begin(),bitmaps[i].end(),maxvalue/4 ) )
      	quartcount ++;
      if ( std::binary_search(bitmaps[i].begin(),bitmaps[i].end(),maxvalue/2 ) )
      	quartcount ++;
      if ( std::binary_search(bitmaps[i].begin(),bitmaps[i].end(),3*maxvalue/4 ) )
      	quartcount ++;
    }
    RDTSC_FINAL(cycles_final);
    data[5] = cycles_final - cycles_start;

    if(verbose) printf("Quartile queries on %zu bitmaps took %" PRIu64 " cycles\n", count,
           cycles_final - cycles_start);

    if(verbose) printf("Collected stats  %" PRIu64 "  %" PRIu64 "  %" PRIu64 " %" PRIu64 "\n",successive_and,successive_or,total_or,quartcount);

    printf(" %20.2f %20.2f %20.2f %20.2f %20.2f %20.2f \n",
      data[0]*8.0/totalcard,
      data[1]*1.0/successivecard,
      data[2]*1.0/successivecard,
      data[3]*1.0/totalcard,
      data[4]*1.0/totalcard,
      data[5]*1.0/(3*count)
    );

    for (int i = 0; i < (int)count; ++i) {
        free(numbers[i]);
        numbers[i] = NULL;  // paranoid
    }
    free(howmany);
    free(numbers);

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: defltuno.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: sab $ $Date: 2001-03-29 15:38:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#include <svtools/smplhint.hxx>
#include <svtools/itemprop.hxx>
#include <svx/unomid.hxx>

#include <com/sun/star/beans/PropertyAttribute.hpp>

#include "scitems.hxx"
#include "defltuno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
#include "docpool.hxx"
#include "unoguard.hxx"
#include "unonames.hxx"
#include "docoptio.hxx"

using namespace ::com::sun::star;

//------------------------------------------------------------------------

const SfxItemPropertyMap* lcl_GetDocDefaultsMap()
{
    static SfxItemPropertyMap aDocDefaultsMap_Impl[] =
    {
        {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_STANDARDDEC),              0,      &getCppuType((sal_Int16*)0),        0, 0 },
        {MAP_CHAR_LEN(SC_UNO_TABSTOPDIS),               0,      &getCppuType((sal_Int32*)0),        0, 0 },
        {0,0,0,0}
    };
    return aDocDefaultsMap_Impl;
}

//------------------------------------------------------------------------

SC_SIMPLE_SERVICE_INFO( ScDocDefaultsObj, "ScDocDefaultsObj", "com.sun.star.sheet.Defaults" )

//------------------------------------------------------------------------

ScDocDefaultsObj::ScDocDefaultsObj(ScDocShell* pDocSh) :
    pDocShell( pDocSh )
{
    pDocShell->GetDocument()->AddUnoObject(*this);
}

ScDocDefaultsObj::~ScDocDefaultsObj()
{
    if (pDocShell)
        pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScDocDefaultsObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;       // document gone
    }
}

void ScDocDefaultsObj::ItemsChanged()
{
    if (pDocShell)
    {
        //! if not in XML import, adjust row heights

        pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
    }
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocDefaultsObj::getPropertySetInfo()
                                                        throw(uno::RuntimeException)
{
    ScUnoGuard aGuard;
    static uno::Reference<beans::XPropertySetInfo> aRef =
        new SfxItemPropertySetInfo( lcl_GetDocDefaultsMap() );
    return aRef;
}

void SAL_CALL ScDocDefaultsObj::setPropertyValue(
                        const rtl::OUString& aPropertyName, const uno::Any& aValue )
                throw(beans::UnknownPropertyException, beans::PropertyVetoException,
                        lang::IllegalArgumentException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();
    if(!pMap->nWID)
    {
        if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                ScDocOptions aDocOpt(pDoc->GetDocOptions());
                sal_Int16 nValue;
                if (aValue >>= nValue)
                {
                    aDocOpt.SetStdPrecision(static_cast<sal_uInt8> (nValue));
                    pDoc->SetDocOptions(aDocOpt);
                }
            }
            else
                throw uno::RuntimeException();
        }
        else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                ScDocOptions aDocOpt(pDoc->GetDocOptions());
                sal_Int32 nValue;
                if (aValue >>= nValue)
                {
                    aDocOpt.SetTabDistance(static_cast<sal_uInt8> (nValue));
                    pDoc->SetDocOptions(aDocOpt);
                }
            }
            else
                throw uno::RuntimeException();
        }
    }
    else
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        SfxPoolItem* pNewItem = pPool->GetDefaultItem(pMap->nWID).Clone();

        if( !pNewItem->PutValue( aValue, pMap->nMemberId ) )
            throw lang::IllegalArgumentException();

        pPool->SetPoolDefaultItem( *pNewItem );
        delete pNewItem;    // copied in SetPoolDefaultItem

        ItemsChanged();
    }
}

uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aPropertyName )
                throw(beans::UnknownPropertyException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    //  use pool default if set

    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    uno::Any aRet;
    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    if (!pMap->nWID)
    {
        if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
                aRet <<= static_cast<sal_Int16> (aDocOpt.GetStdPrecision());
            }
            else
                throw uno::RuntimeException();
        }
        else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
                aRet <<= static_cast<sal_Int32> (aDocOpt.GetTabDistance());
            }
            else
                throw uno::RuntimeException();
        }
    }
    else
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        const SfxPoolItem& rItem = pPool->GetDefaultItem( pMap->nWID );
        rItem.QueryValue( aRet, pMap->nMemberId );
    }
    return aRet;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj )

// XPropertyState

beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const rtl::OUString& aPropertyName )
                                throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;

    USHORT nWID = pMap->nWID;
    if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID )
    {
        //  static default for font is system-dependent,
        //  so font default is always treated as "direct value".

        eRet = beans::PropertyState_DIRECT_VALUE;
    }
    else
    {
        //  check if pool default is set

        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        if ( pPool->GetPoolDefaultItem( nWID ) != NULL )
            eRet = beans::PropertyState_DIRECT_VALUE;
    }

    return eRet;
}

uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates(
                            const uno::Sequence<rtl::OUString>& aPropertyNames )
                    throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    //  the simple way: call getPropertyState

    ScUnoGuard aGuard;
    const rtl::OUString* pNames = aPropertyNames.getConstArray();
    uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
    beans::PropertyState* pStates = aRet.getArray();
    for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
        pStates[i] = getPropertyState(pNames[i]);
    return aRet;
}

void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
                            throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    if (pMap->nWID)
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        pPool->ResetPoolDefaultItem( pMap->nWID );

        ItemsChanged();
    }
}

uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const rtl::OUString& aPropertyName )
                            throw(beans::UnknownPropertyException, lang::WrappedTargetException,
                                    uno::RuntimeException)
{
    //  always use static default

    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    uno::Any aRet;
    if (pMap->nWID)
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        const SfxPoolItem* pItem = pPool->GetItem( pMap->nWID, SFX_ITEMS_STATICDEFAULT );
        if (pItem)
            pItem->QueryValue( aRet, pMap->nMemberId );
    }
    return aRet;
}

<commit_msg>#80363#; have to convert Twips and Hmm; cast with a sal_uInt16 and not a sal_uInt8<commit_after>/*************************************************************************
 *
 *  $RCSfile: defltuno.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: sab $ $Date: 2001-04-12 11:55:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#include <svtools/smplhint.hxx>
#include <svtools/itemprop.hxx>
#include <svx/unomid.hxx>

#include <com/sun/star/beans/PropertyAttribute.hpp>

#include "scitems.hxx"
#include "defltuno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
#include "docpool.hxx"
#include "unoguard.hxx"
#include "unonames.hxx"
#include "docoptio.hxx"

#ifndef _TOOLS_SOLMATH_HXX
#include <tools/solmath.hxx>
#endif

using namespace ::com::sun::star;

//------------------------------------------------------------------------

const SfxItemPropertyMap* lcl_GetDocDefaultsMap()
{
    static SfxItemPropertyMap aDocDefaultsMap_Impl[] =
    {
        {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_CHAR_SET },
        {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_FAMILY },
        {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_FAMILY_NAME },
        {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),        0, MID_FONT_PITCH },
        {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),    0, MID_FONT_STYLE_NAME },
        {MAP_CHAR_LEN(SC_UNO_STANDARDDEC),              0,      &getCppuType((sal_Int16*)0),        0, 0 },
        {MAP_CHAR_LEN(SC_UNO_TABSTOPDIS),               0,      &getCppuType((sal_Int32*)0),        0, 0 },
        {0,0,0,0}
    };
    return aDocDefaultsMap_Impl;
}

inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
inline long HMMToTwips(long nHMM)   { return (nHMM * 72 + 63) / 127; }
inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; }

//------------------------------------------------------------------------

SC_SIMPLE_SERVICE_INFO( ScDocDefaultsObj, "ScDocDefaultsObj", "com.sun.star.sheet.Defaults" )

//------------------------------------------------------------------------

ScDocDefaultsObj::ScDocDefaultsObj(ScDocShell* pDocSh) :
    pDocShell( pDocSh )
{
    pDocShell->GetDocument()->AddUnoObject(*this);
}

ScDocDefaultsObj::~ScDocDefaultsObj()
{
    if (pDocShell)
        pDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScDocDefaultsObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;       // document gone
    }
}

void ScDocDefaultsObj::ItemsChanged()
{
    if (pDocShell)
    {
        //! if not in XML import, adjust row heights

        pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
    }
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDocDefaultsObj::getPropertySetInfo()
                                                        throw(uno::RuntimeException)
{
    ScUnoGuard aGuard;
    static uno::Reference<beans::XPropertySetInfo> aRef =
        new SfxItemPropertySetInfo( lcl_GetDocDefaultsMap() );
    return aRef;
}

void SAL_CALL ScDocDefaultsObj::setPropertyValue(
                        const rtl::OUString& aPropertyName, const uno::Any& aValue )
                throw(beans::UnknownPropertyException, beans::PropertyVetoException,
                        lang::IllegalArgumentException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();
    if(!pMap->nWID)
    {
        if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                ScDocOptions aDocOpt(pDoc->GetDocOptions());
                sal_Int16 nValue;
                if (aValue >>= nValue)
                {
                    aDocOpt.SetStdPrecision(static_cast<sal_uInt8> (nValue));
                    pDoc->SetDocOptions(aDocOpt);
                }
            }
            else
                throw uno::RuntimeException();
        }
        else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                ScDocOptions aDocOpt(pDoc->GetDocOptions());
                sal_Int32 nValue;
                if (aValue >>= nValue)
                {
                    aDocOpt.SetTabDistance(static_cast<sal_uInt16>(HMMToTwips(nValue)));
                    pDoc->SetDocOptions(aDocOpt);
                }
            }
            else
                throw uno::RuntimeException();
        }
    }
    else
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        SfxPoolItem* pNewItem = pPool->GetDefaultItem(pMap->nWID).Clone();

        if( !pNewItem->PutValue( aValue, pMap->nMemberId ) )
            throw lang::IllegalArgumentException();

        pPool->SetPoolDefaultItem( *pNewItem );
        delete pNewItem;    // copied in SetPoolDefaultItem

        ItemsChanged();
    }
}

uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aPropertyName )
                throw(beans::UnknownPropertyException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    //  use pool default if set

    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    uno::Any aRet;
    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    if (!pMap->nWID)
    {
        if(aPropertyName.compareToAscii(SC_UNO_STANDARDDEC) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
                aRet <<= static_cast<sal_Int16> (aDocOpt.GetStdPrecision());
            }
            else
                throw uno::RuntimeException();
        }
        else if (aPropertyName.compareToAscii(SC_UNO_TABSTOPDIS) == 0)
        {
            ScDocument* pDoc = pDocShell->GetDocument();
            if (pDoc)
            {
                const ScDocOptions& aDocOpt = pDoc->GetDocOptions();
                sal_Int32 nValue (TwipsToEvenHMM(aDocOpt.GetTabDistance()));
                aRet <<= nValue;
            }
            else
                throw uno::RuntimeException();
        }
    }
    else
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        const SfxPoolItem& rItem = pPool->GetDefaultItem( pMap->nWID );
        rItem.QueryValue( aRet, pMap->nMemberId );
    }
    return aRet;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDocDefaultsObj )

// XPropertyState

beans::PropertyState SAL_CALL ScDocDefaultsObj::getPropertyState( const rtl::OUString& aPropertyName )
                                throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    beans::PropertyState eRet = beans::PropertyState_DEFAULT_VALUE;

    USHORT nWID = pMap->nWID;
    if ( nWID == ATTR_FONT || nWID == ATTR_CJK_FONT || nWID == ATTR_CTL_FONT || !nWID )
    {
        //  static default for font is system-dependent,
        //  so font default is always treated as "direct value".

        eRet = beans::PropertyState_DIRECT_VALUE;
    }
    else
    {
        //  check if pool default is set

        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        if ( pPool->GetPoolDefaultItem( nWID ) != NULL )
            eRet = beans::PropertyState_DIRECT_VALUE;
    }

    return eRet;
}

uno::Sequence<beans::PropertyState> SAL_CALL ScDocDefaultsObj::getPropertyStates(
                            const uno::Sequence<rtl::OUString>& aPropertyNames )
                    throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    //  the simple way: call getPropertyState

    ScUnoGuard aGuard;
    const rtl::OUString* pNames = aPropertyNames.getConstArray();
    uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
    beans::PropertyState* pStates = aRet.getArray();
    for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
        pStates[i] = getPropertyState(pNames[i]);
    return aRet;
}

void SAL_CALL ScDocDefaultsObj::setPropertyToDefault( const rtl::OUString& aPropertyName )
                            throw(beans::UnknownPropertyException, uno::RuntimeException)
{
    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    if (pMap->nWID)
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        pPool->ResetPoolDefaultItem( pMap->nWID );

        ItemsChanged();
    }
}

uno::Any SAL_CALL ScDocDefaultsObj::getPropertyDefault( const rtl::OUString& aPropertyName )
                            throw(beans::UnknownPropertyException, lang::WrappedTargetException,
                                    uno::RuntimeException)
{
    //  always use static default

    ScUnoGuard aGuard;

    if ( !pDocShell )
        throw uno::RuntimeException();

    const SfxItemPropertyMap* pMap =
            SfxItemPropertyMap::GetByName( lcl_GetDocDefaultsMap(), aPropertyName );
    if ( !pMap )
        throw beans::UnknownPropertyException();

    uno::Any aRet;
    if (pMap->nWID)
    {
        ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
        const SfxPoolItem* pItem = pPool->GetItem( pMap->nWID, SFX_ITEMS_STATICDEFAULT );
        if (pItem)
            pItem->QueryValue( aRet, pMap->nMemberId );
    }
    return aRet;
}

<|endoftext|>