<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: tokenuno.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_TOKENUNO_HXX
#define SC_TOKENUNO_HXX

#include <svtools/lstner.hxx>
#include <com/sun/star/sheet/FormulaToken.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sheet/XFormulaParser.hpp>
#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
#ifndef __com_sun_star_sheet_FormulaOpCodeMapEntry_idl__
#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
#endif
#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase2.hxx>
#include "address.hxx"
#include "compiler.hxx"

class ScTokenArray;
class ScDocShell;

class ScTokenConversion
{
public:
    static bool ConvertToTokenArray(
                        ScTokenArray& rTokenArray,
                        const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence );
    static bool ConvertToTokenSequence(
                        com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence,
                        const ScTokenArray& rTokenArray );
};

class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
                            ::com::sun::star::sheet::XFormulaParser,
                            ::com::sun::star::beans::XPropertySet,
                            ::com::sun::star::lang::XServiceInfo >,
                        public SfxListener
{
private:
    ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::FormulaOpCodeMapEntry > maOpCodeMapping;
    ScCompiler::OpCodeMapPtr    mxOpCodeMap;
    ScDocShell*         mpDocShell;
    ScAddress           maRefPos;
    bool                mbEnglish;
    bool                mbR1C1;
    bool                mbComp3D;
    bool                mbIgnoreSpaces;

    void                    SetCompilerFlags( ScCompiler& rCompiler ) const;

public:
                            ScFormulaParserObj(ScDocShell* pDocSh);
    virtual                 ~ScFormulaParserObj();

    virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

                            // XFormulaParser
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL parseFormula(
                                    const ::rtl::OUString& aFormula )
                                throw (::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL printFormula( const ::com::sun::star::uno::Sequence<
                                    ::com::sun::star::sheet::FormulaToken >& aTokens )
                                throw (::com::sun::star::uno::RuntimeException);

                            // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
                            SAL_CALL getPropertySetInfo()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   setPropertyValue( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Any& aValue )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::beans::PropertyVetoException,
                                    ::com::sun::star::lang::IllegalArgumentException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue(
                                    const ::rtl::OUString& PropertyName )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   addPropertyChangeListener( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XPropertyChangeListener >& xListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   removePropertyChangeListener( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XPropertyChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   addVetoableChangeListener( const ::rtl::OUString& PropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XVetoableChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   removeVetoableChangeListener( const ::rtl::OUString& PropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XVetoableChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);

                            // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
                                throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
                                throw(::com::sun::star::uno::RuntimeException);
};

class ScFormulaOpCodeMapperObj : public ::cppu::WeakImplHelper2<
                            ::com::sun::star::sheet::XFormulaOpCodeMapper,
                            ::com::sun::star::lang::XServiceInfo >
{
public:
                            ScFormulaOpCodeMapperObj();
    virtual                 ~ScFormulaOpCodeMapperObj();

                            // XFormulaOpCodeMapper
                            // Attributes
    virtual ::sal_Int32 SAL_CALL getOpCodeExternal() throw (::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL getOpCodeUnknown() throw (::com::sun::star::uno::RuntimeException);
                            // Methods
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL getMappings(
                                    const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames,
                                    sal_Int32 nLanguage )
                                throw ( ::com::sun::star::lang::IllegalArgumentException,
                                        ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaOpCodeMapEntry > SAL_CALL getAvailableMappings(
                                    sal_Int32 nLanguage, sal_Int32 nGroups )
                                throw ( ::com::sun::star::lang::IllegalArgumentException,
                                        ::com::sun::star::uno::RuntimeException);

                            // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
                                throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
                                throw(::com::sun::star::uno::RuntimeException);

};

#endif

<commit_msg>INTEGRATION: CWS xmlfilter04 (1.2.54); FILE MERGED 2008/03/07 02:06:04 kohei 1.2.54.1: remove the two boolean properties from ScFormulaParserObj and put the new formula convention property.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: tokenuno.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_TOKENUNO_HXX
#define SC_TOKENUNO_HXX

#include <svtools/lstner.hxx>
#include <com/sun/star/sheet/FormulaToken.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sheet/XFormulaParser.hpp>
#include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
#ifndef __com_sun_star_sheet_FormulaOpCodeMapEntry_idl__
#include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
#endif
#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase2.hxx>
#include "address.hxx"
#include "compiler.hxx"

class ScTokenArray;
class ScDocShell;

class ScTokenConversion
{
public:
    static bool ConvertToTokenArray(
                        ScTokenArray& rTokenArray,
                        const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence );
    static bool ConvertToTokenSequence(
                        com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence,
                        const ScTokenArray& rTokenArray );
};

class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
                            ::com::sun::star::sheet::XFormulaParser,
                            ::com::sun::star::beans::XPropertySet,
                            ::com::sun::star::lang::XServiceInfo >,
                        public SfxListener
{
private:
    ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::FormulaOpCodeMapEntry > maOpCodeMapping;
    ScCompiler::OpCodeMapPtr    mxOpCodeMap;
    ScDocShell*         mpDocShell;
    ScAddress           maRefPos;
    sal_Int16           mnConv;
    bool                mbEnglish;
    bool                mbIgnoreSpaces;

    void                    SetCompilerFlags( ScCompiler& rCompiler ) const;

public:
                            ScFormulaParserObj(ScDocShell* pDocSh);
    virtual                 ~ScFormulaParserObj();

    virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

                            // XFormulaParser
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL parseFormula(
                                    const ::rtl::OUString& aFormula )
                                throw (::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL printFormula( const ::com::sun::star::uno::Sequence<
                                    ::com::sun::star::sheet::FormulaToken >& aTokens )
                                throw (::com::sun::star::uno::RuntimeException);

                            // XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
                            SAL_CALL getPropertySetInfo()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   setPropertyValue( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Any& aValue )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::beans::PropertyVetoException,
                                    ::com::sun::star::lang::IllegalArgumentException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue(
                                    const ::rtl::OUString& PropertyName )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   addPropertyChangeListener( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XPropertyChangeListener >& xListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   removePropertyChangeListener( const ::rtl::OUString& aPropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XPropertyChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   addVetoableChangeListener( const ::rtl::OUString& PropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XVetoableChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL   removeVetoableChangeListener( const ::rtl::OUString& PropertyName,
                                    const ::com::sun::star::uno::Reference<
                                        ::com::sun::star::beans::XVetoableChangeListener >& aListener )
                                throw(::com::sun::star::beans::UnknownPropertyException,
                                    ::com::sun::star::lang::WrappedTargetException,
                                    ::com::sun::star::uno::RuntimeException);

                            // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
                                throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
                                throw(::com::sun::star::uno::RuntimeException);
};

class ScFormulaOpCodeMapperObj : public ::cppu::WeakImplHelper2<
                            ::com::sun::star::sheet::XFormulaOpCodeMapper,
                            ::com::sun::star::lang::XServiceInfo >
{
public:
                            ScFormulaOpCodeMapperObj();
    virtual                 ~ScFormulaOpCodeMapperObj();

                            // XFormulaOpCodeMapper
                            // Attributes
    virtual ::sal_Int32 SAL_CALL getOpCodeExternal() throw (::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL getOpCodeUnknown() throw (::com::sun::star::uno::RuntimeException);
                            // Methods
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaToken > SAL_CALL getMappings(
                                    const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames,
                                    sal_Int32 nLanguage )
                                throw ( ::com::sun::star::lang::IllegalArgumentException,
                                        ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::FormulaOpCodeMapEntry > SAL_CALL getAvailableMappings(
                                    sal_Int32 nLanguage, sal_Int32 nGroups )
                                throw ( ::com::sun::star::lang::IllegalArgumentException,
                                        ::com::sun::star::uno::RuntimeException);

                            // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
                                throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
                                throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
                                throw(::com::sun::star::uno::RuntimeException);

};

#endif

<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 <algorithm>
#include <cstdio>
#include <cstring>

#ifdef _WIN32
#define NOMINMAX
#include <windows.h>
#elif __MACH__
#include <mach/mach.h>
#include <mach/mach_time.h>
#else
#include <time.h>
#endif
#include "highway_tree_hash.h"
#include "scalar_highway_tree_hash.h"
#include "scalar_sip_tree_hash.h"
#include "sip_hash.h"
#include "sip_tree_hash.h"
#include "sse41_highway_tree_hash.h"
#include "vec2.h"

namespace highwayhash {
namespace {

uint64 TimerTicks() {
#ifdef _WIN32
  LARGE_INTEGER counter;
  (void)QueryPerformanceCounter(&counter);
  return counter.QuadPart;
#elif __MACH__
  return mach_absolute_time();
#else
  timespec t;
  clock_gettime(CLOCK_REALTIME, &t);
  return static_cast<uint64>(t.tv_sec) * 1000000000 + t.tv_nsec;
#endif
}

double ToSeconds(uint64 elapsed) {
  const double elapsed_d = static_cast<double>(elapsed);

#ifdef _WIN32
  LARGE_INTEGER frequency;
  (void)QueryPerformanceFrequency(&frequency);
  return elapsed_d / frequency.QuadPart;
#elif __MACH__
  // On OSX/iOS platform the elapsed time is cpu time unit
  // We have to query the time base information to convert it back
  // See https://developer.apple.com/library/mac/qa/qa1398/_index.html
  static mach_timebase_info_data_t    sTimebaseInfo;
  if (sTimebaseInfo.denom == 0) {
    (void) mach_timebase_info(&sTimebaseInfo);
  }
  return elapsed_d * sTimebaseInfo.numer / sTimebaseInfo.denom / 1000000000;
#else
  return elapsed_d / 1000000000;  // ns
#endif
}

/*
Known-good SipHash-2-4 output from D. Bernstein.
key = 00 01 02 ...
and
in = (empty string)
in = 00 (1 byte)
in = 00 01 (2 bytes)
in = 00 01 02 (3 bytes)
...
in = 00 01 02 ... 3e (63 bytes)
*/
static const unsigned char vectors[64 * 8] = {
    0x31, 0x0E, 0x0E, 0xDD, 0x47, 0xDB, 0x6F, 0x72, 0xFD, 0x67, 0xDC, 0x93,
    0xC5, 0x39, 0xF8, 0x74, 0x5A, 0x4F, 0xA9, 0xD9, 0x09, 0x80, 0x6C, 0x0D,
    0x2D, 0x7E, 0xFB, 0xD7, 0x96, 0x66, 0x67, 0x85, 0xB7, 0x87, 0x71, 0x27,
    0xE0, 0x94, 0x27, 0xCF, 0x8D, 0xA6, 0x99, 0xCD, 0x64, 0x55, 0x76, 0x18,
    0xCE, 0xE3, 0xFE, 0x58, 0x6E, 0x46, 0xC9, 0xCB, 0x37, 0xD1, 0x01, 0x8B,
    0xF5, 0x00, 0x02, 0xAB, 0x62, 0x24, 0x93, 0x9A, 0x79, 0xF5, 0xF5, 0x93,
    0xB0, 0xE4, 0xA9, 0x0B, 0xDF, 0x82, 0x00, 0x9E, 0xF3, 0xB9, 0xDD, 0x94,
    0xC5, 0xBB, 0x5D, 0x7A, 0xA7, 0xAD, 0x6B, 0x22, 0x46, 0x2F, 0xB3, 0xF4,
    0xFB, 0xE5, 0x0E, 0x86, 0xBC, 0x8F, 0x1E, 0x75, 0x90, 0x3D, 0x84, 0xC0,
    0x27, 0x56, 0xEA, 0x14, 0xEE, 0xF2, 0x7A, 0x8E, 0x90, 0xCA, 0x23, 0xF7,
    0xE5, 0x45, 0xBE, 0x49, 0x61, 0xCA, 0x29, 0xA1, 0xDB, 0x9B, 0xC2, 0x57,
    0x7F, 0xCC, 0x2A, 0x3F, 0x94, 0x47, 0xBE, 0x2C, 0xF5, 0xE9, 0x9A, 0x69,
    0x9C, 0xD3, 0x8D, 0x96, 0xF0, 0xB3, 0xC1, 0x4B, 0xBD, 0x61, 0x79, 0xA7,
    0x1D, 0xC9, 0x6D, 0xBB, 0x98, 0xEE, 0xA2, 0x1A, 0xF2, 0x5C, 0xD6, 0xBE,
    0xC7, 0x67, 0x3B, 0x2E, 0xB0, 0xCB, 0xF2, 0xD0, 0x88, 0x3E, 0xA3, 0xE3,
    0x95, 0x67, 0x53, 0x93, 0xC8, 0xCE, 0x5C, 0xCD, 0x8C, 0x03, 0x0C, 0xA8,
    0x94, 0xAF, 0x49, 0xF6, 0xC6, 0x50, 0xAD, 0xB8, 0xEA, 0xB8, 0x85, 0x8A,
    0xDE, 0x92, 0xE1, 0xBC, 0xF3, 0x15, 0xBB, 0x5B, 0xB8, 0x35, 0xD8, 0x17,
    0xAD, 0xCF, 0x6B, 0x07, 0x63, 0x61, 0x2E, 0x2F, 0xA5, 0xC9, 0x1D, 0xA7,
    0xAC, 0xAA, 0x4D, 0xDE, 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xA2, 0xA6,
    0x28, 0xEF, 0x49, 0x5C, 0x53, 0xA3, 0x87, 0xAD, 0x42, 0xC3, 0x41, 0xD8,
    0xFA, 0x92, 0xD8, 0x32, 0xCE, 0x7C, 0xF2, 0x72, 0x2F, 0x51, 0x27, 0x71,
    0xE3, 0x78, 0x59, 0xF9, 0x46, 0x23, 0xF3, 0xA7, 0x38, 0x12, 0x05, 0xBB,
    0x1A, 0xB0, 0xE0, 0x12, 0xAE, 0x97, 0xA1, 0x0F, 0xD4, 0x34, 0xE0, 0x15,
    0xB4, 0xA3, 0x15, 0x08, 0xBE, 0xFF, 0x4D, 0x31, 0x81, 0x39, 0x62, 0x29,
    0xF0, 0x90, 0x79, 0x02, 0x4D, 0x0C, 0xF4, 0x9E, 0xE5, 0xD4, 0xDC, 0xCA,
    0x5C, 0x73, 0x33, 0x6A, 0x76, 0xD8, 0xBF, 0x9A, 0xD0, 0xA7, 0x04, 0x53,
    0x6B, 0xA9, 0x3E, 0x0E, 0x92, 0x59, 0x58, 0xFC, 0xD6, 0x42, 0x0C, 0xAD,
    0xA9, 0x15, 0xC2, 0x9B, 0xC8, 0x06, 0x73, 0x18, 0x95, 0x2B, 0x79, 0xF3,
    0xBC, 0x0A, 0xA6, 0xD4, 0xF2, 0x1D, 0xF2, 0xE4, 0x1D, 0x45, 0x35, 0xF9,
    0x87, 0x57, 0x75, 0x19, 0x04, 0x8F, 0x53, 0xA9, 0x10, 0xA5, 0x6C, 0xF5,
    0xDF, 0xCD, 0x9A, 0xDB, 0xEB, 0x75, 0x09, 0x5C, 0xCD, 0x98, 0x6C, 0xD0,
    0x51, 0xA9, 0xCB, 0x9E, 0xCB, 0xA3, 0x12, 0xE6, 0x96, 0xAF, 0xAD, 0xFC,
    0x2C, 0xE6, 0x66, 0xC7, 0x72, 0xFE, 0x52, 0x97, 0x5A, 0x43, 0x64, 0xEE,
    0x5A, 0x16, 0x45, 0xB2, 0x76, 0xD5, 0x92, 0xA1, 0xB2, 0x74, 0xCB, 0x8E,
    0xBF, 0x87, 0x87, 0x0A, 0x6F, 0x9B, 0xB4, 0x20, 0x3D, 0xE7, 0xB3, 0x81,
    0xEA, 0xEC, 0xB2, 0xA3, 0x0B, 0x22, 0xA8, 0x7F, 0x99, 0x24, 0xA4, 0x3C,
    0xC1, 0x31, 0x57, 0x24, 0xBD, 0x83, 0x8D, 0x3A, 0xAF, 0xBF, 0x8D, 0xB7,
    0x0B, 0x1A, 0x2A, 0x32, 0x65, 0xD5, 0x1A, 0xEA, 0x13, 0x50, 0x79, 0xA3,
    0x23, 0x1C, 0xE6, 0x60, 0x93, 0x2B, 0x28, 0x46, 0xE4, 0xD7, 0x06, 0x66,
    0xE1, 0x91, 0x5F, 0x5C, 0xB1, 0xEC, 0xA4, 0x6C, 0xF3, 0x25, 0x96, 0x5C,
    0xA1, 0x6D, 0x62, 0x9F, 0x57, 0x5F, 0xF2, 0x8E, 0x60, 0x38, 0x1B, 0xE5,
    0x72, 0x45, 0x06, 0xEB, 0x4C, 0x32, 0x8A, 0x95};

static void VerifySipHash() {
  const int kMaxSize = 64;
  char in[kMaxSize];
  bool ok = true;

  const uint64 key[2] = {0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL};

  for (int size = 0; size < kMaxSize; ++size) {
    in[size] = static_cast<char>(size);
    const uint64 hash = highwayhash::SipHash(key, in, size);

    char out[8];
    memcpy(out, &hash, sizeof(hash));

    if (memcmp(out, vectors + size * 8, 8)) {
      printf("Failed for length %d\n", size);
      ok = false;
    }
  }

  if (!ok) {
    exit(1);
  }
  printf("Verified SipHash.\n");
}

template <class Function1, class Function2>
static void VerifyEqual(const char* caption, const Function1& hash_function1,
                        const Function2& hash_function2) {
  const int kMaxSize = 128;
  char in[kMaxSize] = {0};

  const uint64 key[4] = {0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL,
                         0x1716151413121110ULL, 0x1F1E1D1C1B1A1918ULL};

  for (int size = 0; size < kMaxSize; ++size) {
    in[size] = static_cast<char>(size);
    const uint64 hash = hash_function1(key, in, size);
    const uint64 hash2 = hash_function2(key, in, size);
    if (hash != hash2) {
      printf("Failed for length %d %llx %llx\n", size, hash, hash2);
      exit(1);
    }
  }
  printf("Verified %s.\n", caption);
}

template <class Function>
static void BenchmarkFunc(const char* caption, const Function& hash_function) {
  const int kSize = 1024;
  char in[kSize];
  for (int i = 0; i < kSize; ++i) {
    in[i] = static_cast<char>(i);
  }

  // hash_function accepts a decayed pointer.
  const uint64 key[4] = {0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL,
                         0x1716151413121110ULL, 0x1F1E1D1C1B1A1918ULL};

  uint64 sum = 1;
  uint64 minTicks = 99999999999;
  const int kLoops = 50000;
  for (int rep = 0; rep < 25; ++rep) {
    const uint64 t0 = TimerTicks();
    COMPILER_FENCE;
    for (int loop = 0; loop < kLoops; ++loop) {
      sum <<= 1;
      const uint64 hash = hash_function(key, in, kSize);
      sum ^= hash;
    }
    const uint64 t1 = TimerTicks();
    COMPILER_FENCE;
    minTicks = std::min(minTicks, t1 - t0);
  }
  const double minSec = ToSeconds(minTicks);
  const double cyclesPerByte = 3.5E9 * minSec / (kLoops * kSize);
  const double GBps = kLoops * kSize / minSec * 1E-9;
  printf("%21s %d sum=%llu\tGBps=%5.2f  c/b=%.2f\n", caption, kSize, sum, GBps,
         cyclesPerByte);
}

template <class State>
static void BenchmarkState(const char* caption) {
  const int kSize = 1024;
  char in[kSize];
  for (int i = 0; i < kSize; ++i) {
    in[i] = static_cast<char>(i);
  }

  const uint64 all_keys[4] = {0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL,
                              0x1716151413121110ULL, 0x1F1E1D1C1B1A1918ULL};
  typename State::Key key;
  memcpy(&key, all_keys, sizeof(key));

  uint64 sum = 1;
  uint64 minTicks = 99999999999;
  const int kLoops = 50000;
  for (int rep = 0; rep < 25; ++rep) {
    const uint64 t0 = TimerTicks();
    COMPILER_FENCE;
    for (int loop = 0; loop < kLoops; ++loop) {
      const uint64 hash = highwayhash::ComputeHash<State>(key, in, kSize);
      sum <<= 1;
      sum ^= hash;
    }
    const uint64 t1 = TimerTicks();
    COMPILER_FENCE;
    minTicks = std::min(minTicks, t1 - t0);
  }
  const double minSec = ToSeconds(minTicks);
  const double cyclesPerByte = 3.5E9 * minSec / (kLoops * kSize);
  const double GBps = kLoops * kSize / minSec * 1E-9;
  printf("%21s %d sum=%llu\tGBps=%5.2f  c/b=%.2f\n", caption, kSize, sum, GBps,
         cyclesPerByte);
}

template <class State>
static void BenchmarkUpdate(const char* caption) {
  const int kSize = 1024;
  char in[kSize];
  for (int i = 0; i < kSize; ++i) {
    in[i] = static_cast<char>(i);
  }

  const uint64 all_keys[4] = {0x0706050403020100ULL, 0x0F0E0D0C0B0A0908ULL,
                              0x1716151413121110ULL, 0x1F1E1D1C1B1A1918ULL};
  typename State::Key key;
  memcpy(&key, all_keys, sizeof(key));

  uint64 sum = 1;
  uint64 minTicks = 99999999999;
  const int kLoops = 500;
  const int kItems = 100;
  for (int rep = 0; rep < 25; ++rep) {
    const uint64 t0 = TimerTicks();
    COMPILER_FENCE;
    for (int loop = 0; loop < kLoops; ++loop) {
      State state(key);
      for (int item = 0; item < kItems; ++item) {
        highwayhash::UpdateState(in, kSize, &state);
      }
      const uint64 hash = state.Finalize();
      sum <<= 1;
      sum ^= hash;
    }
    const uint64 t1 = TimerTicks();
    COMPILER_FENCE;
    minTicks = std::min(minTicks, t1 - t0);
  }
  const double minSec = ToSeconds(minTicks);
  const double cyclesPerByte = 3.5E9 * minSec / (kLoops * kItems * kSize);
  const double GBps = kLoops * kItems * kSize / minSec * 1E-9;
  printf("%21s %d sum=%llu\tGBps=%5.2f  c/b=%.2f\n", caption, kSize, sum, GBps,
         cyclesPerByte);
}

void RunTests() {
  BenchmarkState<SipHashState>("SipHash");
  BenchmarkUpdate<SipHashState>("Update: SipHash");
  printf("\n");
  BenchmarkFunc("ScalarSipTreeHash", ScalarSipTreeHash);
#ifdef __AVX2__
  BenchmarkFunc("SipTreeHash", SipTreeHash);
#endif
  printf("\n");
  BenchmarkFunc("ScalarHighwayTreeHash", ScalarHighwayTreeHash);
#ifdef __SSE4_1__
  BenchmarkFunc("SSE41HighwayTreeHash", SSE41HighwayTreeHash);
#endif
#ifdef __AVX2__
  BenchmarkState<HighwayTreeHashState>("HighwayTreeHash");
  BenchmarkUpdate<HighwayTreeHashState>("Update: HighwayTree");
#endif
  printf("\n");
  VerifySipHash();
#ifdef __AVX2__
  VerifyEqual("ScalarSipTreeHash", ScalarSipTreeHash, SipTreeHash);
  VerifyEqual("ScalarHighwayTreeHash", ScalarHighwayTreeHash, HighwayTreeHash);
#endif
}

}  // namespace
}  // namespace highwayhash

int main(int argc, char* argv[]) {
  highwayhash::RunTests();
  return 0;
}
<commit_msg>Remove redundant sip_hash_main (moved to highwayhash/)<commit_after><|endoftext|>


<commit_before>#include "sermanwindow.h"
#include "ui_sermanwindow.h"
#include <QDir>
#include <QFileInfo>
#include <QKeyEvent>
#include <QStandardPaths>
#include <iostream>
#include <thread>

using namespace std;

SermanWindow::SermanWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow),
      remote(new Communicator(this)) {
  ui->setupUi(this);
  ui->logEdit->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
  ui->logEdit->setVisible(true);
  ui->cmdLineEdit->installEventFilter(this);

  commandHistory = History(QDir::homePath().toStdString());
  commandHistory.readFromDisc();
  watcher.addPath(QStandardPaths::locate(QStandardPaths::HomeLocation,
                                         FileLoader::fileName));

  QObject::connect(&watcher, &QFileSystemWatcher::fileChanged, this,
                   &SermanWindow::on_hotload);

  auto filesettings = settings.loadSettings();
  if (filesettings.hostName != "") {
    remote->setPort(filesettings.port);
    cout << "|" << filesettings.hostName.toStdString() << "|" << endl;
    QHostInfo::lookupHost(filesettings.hostName, this,
                          SLOT(on_newHostname(QHostInfo)));
  }
}

SermanWindow::~SermanWindow() {
  delete remote;
  delete ui;
}

void SermanWindow::on_sendButton_clicked() {
  commandHistory.addToHistory(ui->cmdLineEdit->text().toStdString());

  cout << ui->cmdLineEdit->text().toStdString() << endl;
  remote->sendCommand(ui->cmdLineEdit->text() + "\n");

  auto retVal = ui->cmdLineEdit->text();
  auto scrollBar = ui->logEdit->verticalScrollBar();
  scrollBar->setValue(scrollBar->maximumHeight());
  ui->logEdit->append(retVal);
  ui->cmdLineEdit->clear();
}

void SermanWindow::on_newHostname(QHostInfo ipnumber) {
  auto addresses = ipnumber.addresses();
  if (addresses.size() > 0) {
    cout << "on_newHostname:" << addresses[0].toString().toStdString() << endl;
    cout << "port: " << remote->getPort() << std::endl;
    remote->setAddress(addresses[0]);
  }
}

void SermanWindow::on_hotload(const QString &path) {

  if (path.contains(FileLoader::fileName)) {
    auto filesettings = settings.loadSettings();
    if (filesettings.hostName != "") {
      remote->setPort(filesettings.port);
      cout << "|" << filesettings.hostName.toStdString() << "|" << endl;
      QHostInfo::lookupHost(filesettings.hostName, this,
                            SLOT(on_newHostname(QHostInfo)));
    }
  } else {
    std::cout << path.toStdString() << std::endl;
  }

  // apperently this code is needed on linux since some editors delete the file
  // and make a new one instead of change it.
  QFileInfo checkFile(path);
  while (!checkFile.exists())
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  watcher.addPath(path);
}

bool SermanWindow::eventFilter(QObject *dist, QEvent *event) {
  if (event->type() == QEvent::KeyPress) {
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

    if (keyEvent->key() == Qt::Key_Up) {
      ui->cmdLineEdit->setText(
          QString(commandHistory.getFromHistory().c_str()));
      commandHistory.stepBackHistory();

      return true;
    }

    if (keyEvent->key() == Qt::Key_Down) {
      ui->cmdLineEdit->setText(
          QString(commandHistory.getFromHistory().c_str()));
      commandHistory.stepForwardHistory();
      // cout << "down arrow" << endl;
      return true;
    }

    if (keyEvent->key() == Qt::Key_Return) {
      on_sendButton_clicked();
      return true;
    }
    if ((keyEvent->key() == Qt::Key_D) &&
        (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
      for (auto line : commandHistory.dumpHistory()) {
        std::cout << line << std::endl;
      }
    }
    if ((keyEvent->key() == Qt::Key_R) &&
        (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
      if (!searchMode) {
        auto found = commandHistory.find(ui->cmdLineEdit->text().toStdString());
        if (found.size() > 0) {
          ui->cmdLineEdit->setText(QString(found[0].c_str()));
        }
        searchMode = true;
        std::cout << "searching" << std::endl;
        statusBar()->showMessage("Searching");
      } else {
        auto line = commandHistory.stepForwardSearch();
        ui->cmdLineEdit->setText(QString(line.c_str()));
      }
    }
    if (((keyEvent->key() == Qt::Key_G) &&
         (QApplication::keyboardModifiers() & Qt::ControlModifier)) ||
        (keyEvent->key() == Qt::Key_Escape)) {
      searchMode = false;
      std::cout << "search mode off" << std::endl;
      statusBar()->clearMessage();
    }
  }

  return QObject::eventFilter(dist, event);
}

void SermanWindow::on_actionConnect_triggered() { remote->connect(); }

void SermanWindow::on_actionDisconnect_triggered() { remote->disconnect(); }

void SermanWindow::gotRemoteData() {
  auto retVal = remote->getRemoteData();
  auto scrollBar = ui->logEdit->verticalScrollBar();
  scrollBar->setValue(scrollBar->maximumHeight());
  ui->logEdit->append(retVal);
}

void SermanWindow::on_actionCleanup_triggered() {}

void SermanWindow::on_actionClear_Terminal_triggered() { ui->logEdit->clear(); }
<commit_msg>Added search<commit_after>#include "sermanwindow.h"
#include "ui_sermanwindow.h"
#include <QDir>
#include <QFileInfo>
#include <QInputDialog>
#include <QKeyEvent>
#include <QStandardPaths>
#include <iostream>
#include <thread>

using namespace std;

SermanWindow::SermanWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow),
      remote(new Communicator(this)) {
  ui->setupUi(this);
  ui->logEdit->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
  ui->logEdit->setVisible(true);
  ui->cmdLineEdit->installEventFilter(this);

  commandHistory = History(QDir::homePath().toStdString());
  commandHistory.readFromDisc();
  watcher.addPath(QStandardPaths::locate(QStandardPaths::HomeLocation,
                                         FileLoader::fileName));

  QObject::connect(&watcher, &QFileSystemWatcher::fileChanged, this,
                   &SermanWindow::on_hotload);

  auto filesettings = settings.loadSettings();
  if (filesettings.hostName != "") {
    remote->setPort(filesettings.port);
    cout << "|" << filesettings.hostName.toStdString() << "|" << endl;
    QHostInfo::lookupHost(filesettings.hostName, this,
                          SLOT(on_newHostname(QHostInfo)));
  }
}

SermanWindow::~SermanWindow() {
  delete remote;
  delete ui;
}

void SermanWindow::on_sendButton_clicked() {
  commandHistory.addToHistory(ui->cmdLineEdit->text().toStdString());

  cout << ui->cmdLineEdit->text().toStdString() << endl;
  remote->sendCommand(ui->cmdLineEdit->text() + "\n");

  auto retVal = ui->cmdLineEdit->text();
  auto scrollBar = ui->logEdit->verticalScrollBar();
  scrollBar->setValue(scrollBar->maximumHeight());
  ui->logEdit->append(retVal);
  ui->cmdLineEdit->clear();
}

void SermanWindow::on_newHostname(QHostInfo ipnumber) {
  auto addresses = ipnumber.addresses();
  if (addresses.size() > 0) {
    cout << "on_newHostname:" << addresses[0].toString().toStdString() << endl;
    cout << "port: " << remote->getPort() << std::endl;
    remote->setAddress(addresses[0]);
  }
}

void SermanWindow::on_hotload(const QString &path) {

  if (path.contains(FileLoader::fileName)) {
    auto filesettings = settings.loadSettings();
    if (filesettings.hostName != "") {
      remote->setPort(filesettings.port);
      cout << "|" << filesettings.hostName.toStdString() << "|" << endl;
      QHostInfo::lookupHost(filesettings.hostName, this,
                            SLOT(on_newHostname(QHostInfo)));
    }
  } else {
    std::cout << path.toStdString() << std::endl;
  }

  // apperently this code is needed on linux since some editors delete the file
  // and make a new one instead of change it.
  QFileInfo checkFile(path);
  while (!checkFile.exists())
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
  watcher.addPath(path);
}

bool SermanWindow::eventFilter(QObject *dist, QEvent *event) {
  if (event->type() == QEvent::KeyPress) {
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

    if (keyEvent->key() == Qt::Key_Up) {
      ui->cmdLineEdit->setText(
          QString(commandHistory.getFromHistory().c_str()));
      commandHistory.stepBackHistory();

      return true;
    }

    if (keyEvent->key() == Qt::Key_Down) {
      ui->cmdLineEdit->setText(
          QString(commandHistory.getFromHistory().c_str()));
      commandHistory.stepForwardHistory();
      // cout << "down arrow" << endl;
      return true;
    }

    if (keyEvent->key() == Qt::Key_Return) {
      on_sendButton_clicked();
      return true;
    }
    if ((keyEvent->key() == Qt::Key_D) &&
        (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
      for (auto line : commandHistory.dumpHistory()) {
        std::cout << line << std::endl;
      }
    }
    if ((keyEvent->key() == Qt::Key_R) &&
        (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
      if (!searchMode) {
        auto found = commandHistory.find(ui->cmdLineEdit->text().toStdString());
        if (found.size() > 0) {
          ui->cmdLineEdit->setText(QString(found[0].c_str()));
        }
        searchMode = true;
        std::cout << "searching" << std::endl;
        statusBar()->showMessage("Searching");
      } else {
        auto line = commandHistory.stepForwardSearch();
        ui->cmdLineEdit->setText(QString(line.c_str()));
      }
    }
    if ((keyEvent->key() == Qt::Key_F) &&
        (QApplication::keyboardModifiers() & Qt::ControlModifier)) {
      bool ok;
      QString text = QInputDialog::getText(this, tr("Find"), tr("search text"),
                                           QLineEdit::Normal, "", &ok);
      if (ok && !text.isEmpty()) {
      }
    }
    if (((keyEvent->key() == Qt::Key_G) &&
         (QApplication::keyboardModifiers() & Qt::ControlModifier)) ||
        (keyEvent->key() == Qt::Key_Escape)) {
      searchMode = false;
      std::cout << "search mode off" << std::endl;
      statusBar()->clearMessage();
    }
  }

  return QObject::eventFilter(dist, event);
}

void SermanWindow::on_actionConnect_triggered() { remote->connect(); }

void SermanWindow::on_actionDisconnect_triggered() { remote->disconnect(); }

void SermanWindow::gotRemoteData() {
  auto retVal = remote->getRemoteData();
  auto scrollBar = ui->logEdit->verticalScrollBar();
  scrollBar->setValue(scrollBar->maximumHeight());
  ui->logEdit->append(retVal);
}

void SermanWindow::on_actionCleanup_triggered() {}

void SermanWindow::on_actionClear_Terminal_triggered() { ui->logEdit->clear(); }
<|endoftext|>


<commit_before>/** \file    create_literary_remains_records.cc
 *  \author  Dr. Johannes Ruscheinski
 *
 *  A tool for creating literary remains MARC records from Beacon files.
 */

/*
    Copyright (C) 2019, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <unordered_map>
#include <unordered_set>
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "TimeUtil.h"
#include "util.h"

namespace {

// use marc reader/writer to copy instead of using FileUtil::Copy
// so we don't lose file handler (FIFO compatibility)
void CopyMarc(MARC::Reader * const reader, MARC::Writer * const writer) {
    while (auto record = reader->read())
        writer->write(record);
}

struct LiteraryRemainsInfo {
    std::string author_name_;
    std::string url_;
    std::string source_name_;
    std::string dates_;
public:
    LiteraryRemainsInfo() = default;
    LiteraryRemainsInfo(const LiteraryRemainsInfo &other) = default;
    LiteraryRemainsInfo(const std::string &author_name, const std::string &url, const std::string &source_name, const std::string &dates)
        : author_name_(author_name), url_(url), source_name_(source_name), dates_(dates) { }

    LiteraryRemainsInfo &operator=(const LiteraryRemainsInfo &rhs) = default;
};

void LoadAuthorGNDNumbers(
    const std::string &filename,
    std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> * const gnd_numbers_to_literary_remains_infos_map)
{
    auto reader(MARC::Reader::Factory(filename));

    unsigned total_count(0), references_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        auto beacon_field(record.findTag("BEA"));
        if (beacon_field == record.end())
            continue;

        const auto _100_field(record.findTag("100"));
        if (_100_field == record.end() or not _100_field->hasSubfield('a'))
            continue;

        std::string gnd_number;
        if (not MARC::GetGNDCode(record, &gnd_number))
            continue;

        const auto numeration(_100_field->getFirstSubfieldWithCode('c'));
        const auto titles_and_other_words_associated_with_a_name(_100_field->getFirstSubfieldWithCode('c'));
        const auto name_and_numeration(_100_field->getFirstSubfieldWithCode('a') + (numeration.empty() ? "" : " " + numeration));
        const auto author_name(not titles_and_other_words_associated_with_a_name.empty()
                                   ? name_and_numeration + " (" + titles_and_other_words_associated_with_a_name + ")"
                                   : name_and_numeration);

        const auto dates(_100_field->getFirstSubfieldWithCode('d'));

        std::vector<LiteraryRemainsInfo> literary_remains_infos;
        while (beacon_field != record.end() and beacon_field->getTag() == "BEA") {
            literary_remains_infos.emplace_back(author_name, beacon_field->getFirstSubfieldWithCode('u'),
                                                beacon_field->getFirstSubfieldWithCode('a'), dates);
            ++beacon_field;
        }
        (*gnd_numbers_to_literary_remains_infos_map)[gnd_number] = literary_remains_infos;
        references_count += literary_remains_infos.size();
    }

    LOG_INFO("Loaded " + std::to_string(references_count) + " literary remains references from \"" + filename
             + "\" which contained a total of " + std::to_string(total_count) + " records.");
}

std::string NormaliseAuthorName(std::string author_name) {
    const auto comma_pos(author_name.find(','));
    if (comma_pos == std::string::npos)
        return author_name;

    std::string auxillary_info;
    const auto open_paren_pos(author_name.find('('));
    if (open_paren_pos != std::string::npos) {
        if (comma_pos > open_paren_pos)
            return author_name;

        auxillary_info = " " + author_name.substr(open_paren_pos);
        author_name.resize(open_paren_pos);
    }

    return StringUtil::TrimWhite(author_name.substr(comma_pos + 1)) + " " + StringUtil::TrimWhite(author_name.substr(0, comma_pos))
           + auxillary_info;
}

void AppendLiteraryRemainsRecords(
    MARC::Writer * const writer,
    const std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> &gnd_numbers_to_literary_remains_infos_map)
{
    unsigned creation_count(0);
    for (const auto &gnd_numbers_and_literary_remains_infos : gnd_numbers_to_literary_remains_infos_map) {
        MARC::Record new_record(MARC::Record::TypeOfRecord::MIXED_MATERIALS, MARC::Record::BibliographicLevel::COLLECTION,
                                "LR" + gnd_numbers_and_literary_remains_infos.first);
        const std::string &author_name(gnd_numbers_and_literary_remains_infos.second.front().author_name_);
        std::string dates(gnd_numbers_and_literary_remains_infos.second.front().dates_.empty()
                              ? "" : " " + gnd_numbers_and_literary_remains_infos.second.front().dates_);
        new_record.insertField("003", "PipeLineGenerated");
        new_record.insertField("005", TimeUtil::GetCurrentDateAndTime("%Y%m%d%H%M%S") + ".0");
        new_record.insertField("008", "190606s2019    xx |||||      00| ||ger c");
        new_record.insertField("100", { { 'a', author_name }, { '0', "(DE-588)" + gnd_numbers_and_literary_remains_infos.first } });
        new_record.insertField("245", { { 'a', "Nachlass von " + NormaliseAuthorName(author_name) + dates } });

        for (const auto &literary_remains_info : gnd_numbers_and_literary_remains_infos.second)
            new_record.insertField("856",
                                   { { 'u', literary_remains_info.url_ },
                                       { '3', "Nachlassdatenbank (" + literary_remains_info.source_name_ + ")" } });

        writer->write(new_record);
    }

    LOG_INFO("Appended a total of " + std::to_string(creation_count) + " record(s).");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc != 4)
        ::Usage("marc_input marc_output authority_records");

    auto reader(MARC::Reader::Factory(argv[1]));
    auto writer(MARC::Writer::Factory(argv[2]));
    CopyMarc(reader.get(), writer.get());

    std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> gnd_numbers_to_literary_remains_infos_map;
    LoadAuthorGNDNumbers(argv[3], &gnd_numbers_to_literary_remains_infos_map);
    AppendLiteraryRemainsRecords(writer.get(), gnd_numbers_to_literary_remains_infos_map);

    return EXIT_SUCCESS;
}
<commit_msg>Fixed a bug.<commit_after>/** \file    create_literary_remains_records.cc
 *  \author  Dr. Johannes Ruscheinski
 *
 *  A tool for creating literary remains MARC records from Beacon files.
 */

/*
    Copyright (C) 2019, Library of the University of Tübingen

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <unordered_map>
#include <unordered_set>
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "TimeUtil.h"
#include "util.h"

namespace {

// use marc reader/writer to copy instead of using FileUtil::Copy
// so we don't lose file handler (FIFO compatibility)
void CopyMarc(MARC::Reader * const reader, MARC::Writer * const writer) {
    while (auto record = reader->read())
        writer->write(record);
}

struct LiteraryRemainsInfo {
    std::string author_name_;
    std::string url_;
    std::string source_name_;
    std::string dates_;
public:
    LiteraryRemainsInfo() = default;
    LiteraryRemainsInfo(const LiteraryRemainsInfo &other) = default;
    LiteraryRemainsInfo(const std::string &author_name, const std::string &url, const std::string &source_name, const std::string &dates)
        : author_name_(author_name), url_(url), source_name_(source_name), dates_(dates) { }

    LiteraryRemainsInfo &operator=(const LiteraryRemainsInfo &rhs) = default;
};

void LoadAuthorGNDNumbers(
    const std::string &filename,
    std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> * const gnd_numbers_to_literary_remains_infos_map)
{
    auto reader(MARC::Reader::Factory(filename));

    unsigned total_count(0), references_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        auto beacon_field(record.findTag("BEA"));
        if (beacon_field == record.end())
            continue;

        const auto _100_field(record.findTag("100"));
        if (_100_field == record.end() or not _100_field->hasSubfield('a'))
            continue;

        std::string gnd_number;
        if (not MARC::GetGNDCode(record, &gnd_number))
            continue;

        const auto numeration(_100_field->getFirstSubfieldWithCode('b'));
        const auto titles_and_other_words_associated_with_a_name(_100_field->getFirstSubfieldWithCode('c'));
        const auto name_and_numeration(_100_field->getFirstSubfieldWithCode('a') + (numeration.empty() ? "" : " " + numeration));
        const auto author_name(not titles_and_other_words_associated_with_a_name.empty()
                                   ? name_and_numeration + " (" + titles_and_other_words_associated_with_a_name + ")"
                                   : name_and_numeration);

        const auto dates(_100_field->getFirstSubfieldWithCode('d'));

        std::vector<LiteraryRemainsInfo> literary_remains_infos;
        while (beacon_field != record.end() and beacon_field->getTag() == "BEA") {
            literary_remains_infos.emplace_back(author_name, beacon_field->getFirstSubfieldWithCode('u'),
                                                beacon_field->getFirstSubfieldWithCode('a'), dates);
            ++beacon_field;
        }
        (*gnd_numbers_to_literary_remains_infos_map)[gnd_number] = literary_remains_infos;
        references_count += literary_remains_infos.size();
    }

    LOG_INFO("Loaded " + std::to_string(references_count) + " literary remains references from \"" + filename
             + "\" which contained a total of " + std::to_string(total_count) + " records.");
}

std::string NormaliseAuthorName(std::string author_name) {
    const auto comma_pos(author_name.find(','));
    if (comma_pos == std::string::npos)
        return author_name;

    std::string auxillary_info;
    const auto open_paren_pos(author_name.find('('));
    if (open_paren_pos != std::string::npos) {
        if (comma_pos > open_paren_pos)
            return author_name;

        auxillary_info = " " + author_name.substr(open_paren_pos);
        author_name.resize(open_paren_pos);
    }

    return StringUtil::TrimWhite(author_name.substr(comma_pos + 1)) + " " + StringUtil::TrimWhite(author_name.substr(0, comma_pos))
           + auxillary_info;
}

void AppendLiteraryRemainsRecords(
    MARC::Writer * const writer,
    const std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> &gnd_numbers_to_literary_remains_infos_map)
{
    unsigned creation_count(0);
    for (const auto &gnd_numbers_and_literary_remains_infos : gnd_numbers_to_literary_remains_infos_map) {
        MARC::Record new_record(MARC::Record::TypeOfRecord::MIXED_MATERIALS, MARC::Record::BibliographicLevel::COLLECTION,
                                "LR" + gnd_numbers_and_literary_remains_infos.first);
        const std::string &author_name(gnd_numbers_and_literary_remains_infos.second.front().author_name_);
        std::string dates(gnd_numbers_and_literary_remains_infos.second.front().dates_.empty()
                              ? "" : " " + gnd_numbers_and_literary_remains_infos.second.front().dates_);
        new_record.insertField("003", "PipeLineGenerated");
        new_record.insertField("005", TimeUtil::GetCurrentDateAndTime("%Y%m%d%H%M%S") + ".0");
        new_record.insertField("008", "190606s2019    xx |||||      00| ||ger c");
        new_record.insertField("100", { { 'a', author_name }, { '0', "(DE-588)" + gnd_numbers_and_literary_remains_infos.first } });
        new_record.insertField("245", { { 'a', "Nachlass von " + NormaliseAuthorName(author_name) + dates } });

        for (const auto &literary_remains_info : gnd_numbers_and_literary_remains_infos.second)
            new_record.insertField("856",
                                   { { 'u', literary_remains_info.url_ },
                                       { '3', "Nachlassdatenbank (" + literary_remains_info.source_name_ + ")" } });

        writer->write(new_record);
    }

    LOG_INFO("Appended a total of " + std::to_string(creation_count) + " record(s).");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc != 4)
        ::Usage("marc_input marc_output authority_records");

    auto reader(MARC::Reader::Factory(argv[1]));
    auto writer(MARC::Writer::Factory(argv[2]));
    CopyMarc(reader.get(), writer.get());

    std::unordered_map<std::string, std::vector<LiteraryRemainsInfo>> gnd_numbers_to_literary_remains_infos_map;
    LoadAuthorGNDNumbers(argv[3], &gnd_numbers_to_literary_remains_infos_map);
    AppendLiteraryRemainsRecords(writer.get(), gnd_numbers_to_literary_remains_infos_map);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <Salamandre-daemon/ServerBroadcast.hpp>
#include <Salamandre-daemon/ServerFunctions.hpp>
#include <Socket/FuncWrapper.hpp>

#include <Salamandre-stats/stats.hpp>

#include <utils/log.hpp>

#include <chrono>

#include <ifaddrs.h>

namespace salamandre
{
    ServerBroadcast::ServerBroadcast(int port,int server_port,bool local):
        port(port),
        server_port(server_port),
        run(false),
        sock_listen(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP, IPPROTO_UDP),
        sock_send(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP, IPPROTO_UDP)
    {
        sock_listen.connect(port);
        sock_listen.setReusable(true);
        sock_listen.bind();

        if(local)
            sock_send.connect("127.255.255.255", port);
        else
            sock_send.connect("255.255.255.255", port);
        if(!sock_send.setBroadcast(true))
        {
            ::perror("Unable to set enable broadcast: ");
        }

        this->getaddrs();
    }

    void ServerBroadcast::getaddrs()
    {
        struct ifaddrs *ifaddr, *ifa;
        sockaddr_in * address;
        if (::getifaddrs(&ifaddr) != 0) {
            ::perror("Unable to get interface addrs: ");
        }

        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == NULL) {
                continue;
            }

            if (ifa->ifa_addr->sa_family == AF_INET) { // We don't support IPv6, yet
                address = (sockaddr_in*) ifa->ifa_addr;
                this->my_ips.insert(address->sin_addr.s_addr);
                utils::log::info("ServerBroadcast::getaddrs","Adding", inet_ntoa(address->sin_addr), "to my known ip addresses.");
            }
        }
        freeifaddrs(ifaddr);
    }

    void ServerBroadcast::init()
    {
        stats::Stats::init();
    }

    void ServerBroadcast::close()
    {
        stats::Stats::close();
    }

    void ServerBroadcast::start()
    {
        run = true;
        this->thread[0] = std::thread(&ServerBroadcast::start_listener,this);
        this->thread[1] = std::thread(&ServerBroadcast::start_sender,this);
    }

    void ServerBroadcast::wait()
    {
        this->thread[0].join();
        this->thread[1].join();
    }

    void ServerBroadcast::sendThisIsMyInfo()
    {
        sock_send<<(int)salamandre::srv::thisIsMyInfos
            <<server_port;
        sock_send.send();
        sock_send.clear();
    }

    void ServerBroadcast::sendILostMyData(int id_medecin,int id_patient,std::string filename)
    {
        sock_send<<(int)salamandre::srv::iLostMyData
            <<id_medecin
            <<id_patient
            <<filename
            <<server_port;
        sock_send.send();
        sock_send.clear();
    }

    void ServerBroadcast::start_listener()
    {
        while(this->run)
        {
            sock_listen.clear();
            ntw::SocketSerialized from(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP);
            from.connect(port);
            sock_listen.receive(from);
            int id;
            sock_listen>>id;
            utils::log::info("ServerBroadcast::listen","Recv id ",id,"with status",sock_listen.getStatus());

            if(sock_listen.getStatus() == ntw::Status::stop) {
                utils::log::warnning("ServerBroadcast::listen","Whether we received shutdown");
                continue;
            }

            switch(id)
            {
                case salamandre::srv::func::thisIsMyInfos :
                    {
                        int port;
                        sock_listen>>port;
                        funcThisIsMyInfos(from,port);
                    }break;
                case salamandre::srv::func::iLostMyData :
                    {
                        int id_medecin,id_patient,port;
                        std::string filename;
                        sock_listen>>id_medecin>>id_patient>>filename>>port;
                        funcILostMyData(from,id_medecin,id_patient,filename,port);
                    }break;
                default:
                    ///\todo WTF are you doing?
                    break;
            }
        }
    }

    void ServerBroadcast::start_sender()
    {
        const std::chrono::seconds duration(30);
        const std::chrono::milliseconds step(500);

        std::chrono::milliseconds elapsed_time(0);

        sendThisIsMyInfo();

        while(this->run)
        {
            if (elapsed_time > duration)
            {
                sendThisIsMyInfo();
                elapsed_time = std::chrono::milliseconds(0);
            }
            std::this_thread::sleep_for(step);
            elapsed_time += step;
        }
    }

    void ServerBroadcast::stop()
    {
        run = false;
        sock_listen.shutdown();
    }

    void ServerBroadcast::funcThisIsMyInfos(ntw::SocketSerialized& from,int port)
    {
        std::string remote_ip = from.getIp();
        utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Recv info from", remote_ip, " Port",port);
        in_addr_t remote_addr = ::inet_addr(remote_ip.c_str());

        // We don't add messages from ourselves
        if (this->my_ips.find(remote_addr) == this->my_ips.end() || port != this->server_port) {
            utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Adding", remote_ip, "port", port, "to the known nodes.");
            stats::Stats::add_node(remote_ip, port);
        } else {
            utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Not adding", remote_ip, "port", port, ": This is me!");
        }
    }

    void ServerBroadcast::funcILostMyData(ntw::SocketSerialized& from,int id_medecin,int id_patient,std::string filename,int port)
    {
        utils::log::info("ServerBroadcast::funcILostMyData","Recv from:",from.getIp()," id_medecin:",id_medecin," id_patient:",id_patient," filename:",filename," port:",port);
        std::thread t(salamandre::srv::funcILostMyData_BroadcastRecv,id_medecin,id_patient,filename,port,from.getIp());
        t.detach();
    }

}
<commit_msg>warning<commit_after>#include <Salamandre-daemon/ServerBroadcast.hpp>
#include <Salamandre-daemon/ServerFunctions.hpp>
#include <Socket/FuncWrapper.hpp>

#include <Salamandre-stats/stats.hpp>

#include <utils/log.hpp>

#include <chrono>

#include <ifaddrs.h>

namespace salamandre
{
    ServerBroadcast::ServerBroadcast(int port,int server_port,bool local):
        port(port),
        server_port(server_port),
        run(false),
        sock_listen(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP, IPPROTO_UDP),
        sock_send(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP, IPPROTO_UDP)
    {
        sock_listen.connect(port);
        sock_listen.setReusable(true);
        sock_listen.bind();

        if(local)
            sock_send.connect("127.255.255.255", port);
        else
            sock_send.connect("255.255.255.255", port);
        if(!sock_send.setBroadcast(true))
        {
            ::perror("Unable to set enable broadcast: ");
        }

        this->getaddrs();
    }

    void ServerBroadcast::getaddrs()
    {
        struct ifaddrs *ifaddr, *ifa;
        sockaddr_in * address;
        if (::getifaddrs(&ifaddr) != 0)
        {
            ::perror("Unable to get interface addrs: ");
        }

        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
        {
            if (ifa->ifa_addr == NULL)
            {
                continue;
            }

            if (ifa->ifa_addr->sa_family == AF_INET)
            { // We don't support IPv6, yet
                address = (sockaddr_in*) ifa->ifa_addr;
                this->my_ips.insert(address->sin_addr.s_addr);
                utils::log::info("ServerBroadcast::getaddrs","Adding", inet_ntoa(address->sin_addr), "to my known ip addresses.");
            }
        }
        ::freeifaddrs(ifaddr);
    }

    void ServerBroadcast::init()
    {
        stats::Stats::init();
    }

    void ServerBroadcast::close()
    {
        stats::Stats::close();
    }

    void ServerBroadcast::start()
    {
        run = true;
        this->thread[0] = std::thread(&ServerBroadcast::start_listener,this);
        this->thread[1] = std::thread(&ServerBroadcast::start_sender,this);
    }

    void ServerBroadcast::wait()
    {
        this->thread[0].join();
        this->thread[1].join();
    }

    void ServerBroadcast::sendThisIsMyInfo()
    {
        sock_send<<(int)salamandre::srv::thisIsMyInfos
            <<server_port;
        sock_send.send();
        sock_send.clear();
    }

    void ServerBroadcast::sendILostMyData(int id_medecin,int id_patient,std::string filename)
    {
        sock_send<<(int)salamandre::srv::iLostMyData
            <<id_medecin
            <<id_patient
            <<filename
            <<server_port;
        sock_send.send();
        sock_send.clear();
    }

    void ServerBroadcast::start_listener()
    {
        while(this->run)
        {
            sock_listen.clear();
            ntw::SocketSerialized from(ntw::Socket::Domain::IP,ntw::Socket::Type::UDP);
            from.connect(port);
            sock_listen.receive(from);
            int id;
            sock_listen>>id;
            utils::log::info("ServerBroadcast::listen","Recv id ",id,"with status",sock_listen.getStatus());

            if(sock_listen.getStatus() == ntw::Status::stop) {
                utils::log::warning("ServerBroadcast::listen","Whether we received shutdown");
                continue;
            }

            switch(id)
            {
                case salamandre::srv::func::thisIsMyInfos :
                    {
                        int port;
                        sock_listen>>port;
                        funcThisIsMyInfos(from,port);
                    }break;
                case salamandre::srv::func::iLostMyData :
                    {
                        int id_medecin,id_patient,port;
                        std::string filename;
                        sock_listen>>id_medecin>>id_patient>>filename>>port;
                        funcILostMyData(from,id_medecin,id_patient,filename,port);
                    }break;
                default:
                    ///\todo WTF are you doing?
                    break;
            }
        }
    }

    void ServerBroadcast::start_sender()
    {
        const std::chrono::seconds duration(30);
        const std::chrono::milliseconds step(500);

        std::chrono::milliseconds elapsed_time(0);

        sendThisIsMyInfo();

        while(this->run)
        {
            if (elapsed_time > duration)
            {
                sendThisIsMyInfo();
                elapsed_time = std::chrono::milliseconds(0);
            }
            std::this_thread::sleep_for(step);
            elapsed_time += step;
        }
    }

    void ServerBroadcast::stop()
    {
        run = false;
        sock_listen.shutdown();
    }

    void ServerBroadcast::funcThisIsMyInfos(ntw::SocketSerialized& from,int port)
    {
        std::string remote_ip = from.getIp();
        utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Recv info from", remote_ip, " Port",port);
        in_addr_t remote_addr = ::inet_addr(remote_ip.c_str());

        // We don't add messages from ourselves
        if (this->my_ips.find(remote_addr) == this->my_ips.end() || port != this->server_port) {
            utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Adding", remote_ip, "port", port, "to the known nodes.");
            stats::Stats::add_node(remote_ip, port);
        } else {
            utils::log::info("ServerBroadcast::funcThisIsMyInfos", "Not adding", remote_ip, "port", port, ": This is me!");
        }
    }

    void ServerBroadcast::funcILostMyData(ntw::SocketSerialized& from,int id_medecin,int id_patient,std::string filename,int port)
    {
        utils::log::info("ServerBroadcast::funcILostMyData","Recv from:",from.getIp()," id_medecin:",id_medecin," id_patient:",id_patient," filename:",filename," port:",port);
        std::thread t(salamandre::srv::funcILostMyData_BroadcastRecv,id_medecin,id_patient,filename,port,from.getIp());
        t.detach();
    }

}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2009-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_KDTREE_KDTREE_IMPL_FLANN_H_
#define PCL_KDTREE_KDTREE_IMPL_FLANN_H_

#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/console/print.h>

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::setInputCloud (const PointCloudConstPtr &cloud, const IndicesConstPtr &indices)
{
  cleanup ();   // Perform an automatic cleanup of structures

  epsilon_ = 0.0f;   // default error bound value
  dim_ = point_representation_->getNumberOfDimensions (); // Number of dimensions - default is 3 = xyz

  input_   = cloud;
  indices_ = indices;

  // Allocate enough data
  if (!input_)
  {
    PCL_ERROR ("[pcl::KdTreeFLANN::setInputCloud] Invalid input!\n");
    return;
  }
  if (indices != NULL)
  {
    total_nr_points_ = (int) indices_->size ();
    convertCloudToArray (*input_, *indices_);
  }
  else
  {
    total_nr_points_ = (int) input_->points.size ();
    convertCloudToArray (*input_);
  }

  flann_index_ = new FLANNIndex (flann::Matrix<float> (cloud_, index_mapping_.size (), dim_),
                                 flann::KDTreeSingleIndexParams (15)); // max 15 points/leaf
  flann_index_->buildIndex ();
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> int
pcl::KdTreeFLANN<PointT, Dist>::nearestKSearch (const PointT &point, int k,
                                                std::vector<int> &k_indices,
                                                std::vector<float> &k_distances) const
{
  assert (point_representation_->isValid (point) && "Invalid (NaN, Inf) point coordinates given to nearestKSearch!");

  if (k > total_nr_points_)
    k = total_nr_points_;

  k_indices.resize (k);
  k_distances.resize (k);

  std::vector<float> query (dim_);
  point_representation_->vectorize ((PointT)point, query);

  flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k);
  flann::Matrix<float> k_distances_mat (&k_distances[0], 1, k);
  // Wrap the k_indices and k_distances vectors (no data copy)
  flann_index_->knnSearch (flann::Matrix<float> (&query[0], 1, dim_),
                           k_indices_mat, k_distances_mat,
                           k, param_k_);

  // Do mapping to original point cloud
  if (!identity_mapping_)
  {
    for (size_t i = 0; i < (size_t)k; ++i)
    {
      int& neighbor_index = k_indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }

  return (k);
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> int
pcl::KdTreeFLANN<PointT, Dist>::radiusSearch (const PointT &point, double radius, std::vector<int> &k_indices,
                                              std::vector<float> &k_sqr_dists, unsigned int max_nn) const
{
  assert (point_representation_->isValid (point) && "Invalid (NaN, Inf) point coordinates given to radiusSearch!");

  std::vector<float> query (dim_);
  point_representation_->vectorize ((PointT)point, query);

  int neighbors_in_radius = 0;

  // If the user pre-allocated the arrays, we are only going to
  if (k_indices.size () == (size_t)total_nr_points_ && k_sqr_dists.size () == (size_t)total_nr_points_)
  {
    flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size ());
    flann::Matrix<float> k_distances_mat (&k_sqr_dists[0], 1, k_sqr_dists.size ());
    neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                                      k_indices_mat,
                                                      k_distances_mat,
                                                      (float) (radius * radius),
                                                      param_radius_);
  }
  else
  {
    // Has max_nn been set properly?
    if (max_nn == 0 || max_nn > (unsigned int)total_nr_points_)
      max_nn = total_nr_points_;

    static flann::Matrix<int> indices_empty;
    static flann::Matrix<float> dists_empty;
    neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                                      indices_empty,
                                                      dists_empty,
                                                      (float) (radius * radius),
                                                      param_radius_);
    neighbors_in_radius = std::min ((unsigned int)neighbors_in_radius, max_nn);

    k_indices.resize (neighbors_in_radius);
    k_sqr_dists.resize (neighbors_in_radius);
    if(neighbors_in_radius != 0)
    {
      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size ());
      flann::Matrix<float> k_distances_mat (&k_sqr_dists[0], 1, k_sqr_dists.size ());
      flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                  k_indices_mat,
                                  k_distances_mat,
                                  (float) (radius * radius),
                                  param_radius_);
    }
  }

  // Do mapping to original point cloud
  if (!identity_mapping_)
  {
    for (int i = 0; i < neighbors_in_radius; ++i)
    {
      int& neighbor_index = k_indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }

  return (neighbors_in_radius);
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::cleanup ()
{
  if (flann_index_)
    delete flann_index_;

  // Data array cleanup
  if (cloud_)
  {
    free (cloud_);
    cloud_ = NULL;
  }
  index_mapping_.clear ();

  if (indices_)
    indices_.reset ();
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::convertCloudToArray (const PointCloud &cloud)
{
  // No point in doing anything if the array is empty
  if (cloud.points.empty ())
  {
    cloud_ = NULL;
    return;
  }

  int original_no_of_points = (int) cloud.points.size ();

  cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof(float));
  float* cloud_ptr = cloud_;
  index_mapping_.reserve (original_no_of_points);
  identity_mapping_ = true;

  for (int cloud_index = 0; cloud_index < original_no_of_points; ++cloud_index)
  {
    // Check if the point is invalid
    if (!point_representation_->isValid (cloud.points[cloud_index]))
    {
      identity_mapping_ = false;
      continue;
    }

    index_mapping_.push_back (cloud_index);

    point_representation_->vectorize (cloud.points[cloud_index], cloud_ptr);
    cloud_ptr += dim_;
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::convertCloudToArray (const PointCloud &cloud, const std::vector<int> &indices)
{
  // No point in doing anything if the array is empty
  if (cloud.points.empty ())
  {
    cloud_ = NULL;
    return;
  }

  int original_no_of_points = (int) indices.size ();

  cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
  float* cloud_ptr = cloud_;
  index_mapping_.reserve (original_no_of_points);
  // its a subcloud -> false
  // true only identity:
  //     - indices size equals cloud size
  //     - indices only contain values between 0 and cloud.size - 1
  //     - no index is multiple times in the list
  //     => index is complete
  // But we can not guarantee that => identity_mapping_ = false
  identity_mapping_ = false;

  for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
  {
    // Check if the point is invalid
    if (!point_representation_->isValid (cloud.points[*iIt]))
      continue;

    // map from 0 - N -> indices [0] - indices [N]
    index_mapping_.push_back (*iIt);  // If the returned index should be for the indices vector

    point_representation_->vectorize (cloud.points[*iIt], cloud_ptr);
    cloud_ptr += dim_;
  }
}

#define PCL_INSTANTIATE_KdTreeFLANN(T) template class PCL_EXPORTS pcl::KdTreeFLANN<T>;

#endif  //#ifndef _PCL_KDTREE_KDTREE_IMPL_FLANN_H_

<commit_msg>Bug fix<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2009-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef PCL_KDTREE_KDTREE_IMPL_FLANN_H_
#define PCL_KDTREE_KDTREE_IMPL_FLANN_H_

#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/console/print.h>

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::setInputCloud (const PointCloudConstPtr &cloud, const IndicesConstPtr &indices)
{
  cleanup ();   // Perform an automatic cleanup of structures

  epsilon_ = 0.0f;   // default error bound value
  dim_ = point_representation_->getNumberOfDimensions (); // Number of dimensions - default is 3 = xyz

  input_   = cloud;
  indices_ = indices;

  // Allocate enough data
  if (!input_)
  {
    PCL_ERROR ("[pcl::KdTreeFLANN::setInputCloud] Invalid input!\n");
    return;
  }
  if (indices != NULL)
  {
    convertCloudToArray (*input_, *indices_);
  }
  else
  {
    convertCloudToArray (*input_);
  }
  total_nr_points_ = (int) index_mapping_.size ();

  flann_index_ = new FLANNIndex (flann::Matrix<float> (cloud_, index_mapping_.size (), dim_),
                                 flann::KDTreeSingleIndexParams (15)); // max 15 points/leaf
  flann_index_->buildIndex ();
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> int
pcl::KdTreeFLANN<PointT, Dist>::nearestKSearch (const PointT &point, int k,
                                                std::vector<int> &k_indices,
                                                std::vector<float> &k_distances) const
{
  assert (point_representation_->isValid (point) && "Invalid (NaN, Inf) point coordinates given to nearestKSearch!");

  if (k > total_nr_points_)
    k = total_nr_points_;

  k_indices.resize (k);
  k_distances.resize (k);

  std::vector<float> query (dim_);
  point_representation_->vectorize ((PointT)point, query);

  flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k);
  flann::Matrix<float> k_distances_mat (&k_distances[0], 1, k);
  // Wrap the k_indices and k_distances vectors (no data copy)
  flann_index_->knnSearch (flann::Matrix<float> (&query[0], 1, dim_),
                           k_indices_mat, k_distances_mat,
                           k, param_k_);

  // Do mapping to original point cloud
  if (!identity_mapping_)
  {
    for (size_t i = 0; i < (size_t)k; ++i)
    {
      int& neighbor_index = k_indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }

  return (k);
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> int
pcl::KdTreeFLANN<PointT, Dist>::radiusSearch (const PointT &point, double radius, std::vector<int> &k_indices,
                                              std::vector<float> &k_sqr_dists, unsigned int max_nn) const
{
  assert (point_representation_->isValid (point) && "Invalid (NaN, Inf) point coordinates given to radiusSearch!");

  std::vector<float> query (dim_);
  point_representation_->vectorize ((PointT)point, query);

  int neighbors_in_radius = 0;

  // If the user pre-allocated the arrays, we are only going to
  if (k_indices.size () == (size_t)total_nr_points_ && k_sqr_dists.size () == (size_t)total_nr_points_)
  {
    flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size ());
    flann::Matrix<float> k_distances_mat (&k_sqr_dists[0], 1, k_sqr_dists.size ());
    neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                                      k_indices_mat,
                                                      k_distances_mat,
                                                      (float) (radius * radius),
                                                      param_radius_);
  }
  else
  {
    // Has max_nn been set properly?
    if (max_nn == 0 || max_nn > (unsigned int)total_nr_points_)
      max_nn = total_nr_points_;

    static flann::Matrix<int> indices_empty;
    static flann::Matrix<float> dists_empty;
    neighbors_in_radius = flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                                      indices_empty,
                                                      dists_empty,
                                                      (float) (radius * radius),
                                                      param_radius_);
    neighbors_in_radius = std::min ((unsigned int)neighbors_in_radius, max_nn);

    k_indices.resize (neighbors_in_radius);
    k_sqr_dists.resize (neighbors_in_radius);
    if(neighbors_in_radius != 0)
    {
      flann::Matrix<int> k_indices_mat (&k_indices[0], 1, k_indices.size ());
      flann::Matrix<float> k_distances_mat (&k_sqr_dists[0], 1, k_sqr_dists.size ());
      flann_index_->radiusSearch (flann::Matrix<float> (&query[0], 1, dim_),
                                  k_indices_mat,
                                  k_distances_mat,
                                  (float) (radius * radius),
                                  param_radius_);
    }
  }

  // Do mapping to original point cloud
  if (!identity_mapping_)
  {
    for (int i = 0; i < neighbors_in_radius; ++i)
    {
      int& neighbor_index = k_indices[i];
      neighbor_index = index_mapping_[neighbor_index];
    }
  }

  return (neighbors_in_radius);
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::cleanup ()
{
  if (flann_index_)
    delete flann_index_;

  // Data array cleanup
  if (cloud_)
  {
    free (cloud_);
    cloud_ = NULL;
  }
  index_mapping_.clear ();

  if (indices_)
    indices_.reset ();
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::convertCloudToArray (const PointCloud &cloud)
{
  // No point in doing anything if the array is empty
  if (cloud.points.empty ())
  {
    cloud_ = NULL;
    return;
  }

  int original_no_of_points = (int) cloud.points.size ();

  cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof(float));
  float* cloud_ptr = cloud_;
  index_mapping_.reserve (original_no_of_points);
  identity_mapping_ = true;

  for (int cloud_index = 0; cloud_index < original_no_of_points; ++cloud_index)
  {
    // Check if the point is invalid
    if (!point_representation_->isValid (cloud.points[cloud_index]))
    {
      identity_mapping_ = false;
      continue;
    }

    index_mapping_.push_back (cloud_index);

    point_representation_->vectorize (cloud.points[cloud_index], cloud_ptr);
    cloud_ptr += dim_;
  }
}

////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename Dist> void
pcl::KdTreeFLANN<PointT, Dist>::convertCloudToArray (const PointCloud &cloud, const std::vector<int> &indices)
{
  // No point in doing anything if the array is empty
  if (cloud.points.empty ())
  {
    cloud_ = NULL;
    return;
  }

  int original_no_of_points = (int) indices.size ();

  cloud_ = (float*)malloc (original_no_of_points * dim_ * sizeof (float));
  float* cloud_ptr = cloud_;
  index_mapping_.reserve (original_no_of_points);
  // its a subcloud -> false
  // true only identity:
  //     - indices size equals cloud size
  //     - indices only contain values between 0 and cloud.size - 1
  //     - no index is multiple times in the list
  //     => index is complete
  // But we can not guarantee that => identity_mapping_ = false
  identity_mapping_ = false;

  for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
  {
    // Check if the point is invalid
    if (!point_representation_->isValid (cloud.points[*iIt]))
      continue;

    // map from 0 - N -> indices [0] - indices [N]
    index_mapping_.push_back (*iIt);  // If the returned index should be for the indices vector

    point_representation_->vectorize (cloud.points[*iIt], cloud_ptr);
    cloud_ptr += dim_;
  }
}

#define PCL_INSTANTIATE_KdTreeFLANN(T) template class PCL_EXPORTS pcl::KdTreeFLANN<T>;

#endif  //#ifndef _PCL_KDTREE_KDTREE_IMPL_FLANN_H_

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RowSetCacheIterator.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:36:52 $
 *
 *  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
 *
 ************************************************************************/
#ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
#include "RowSetCacheIterator.hxx"
#endif
#ifndef DBACCESS_CORE_API_ROWSETCACHE_HXX
#include "RowSetCache.hxx"
#endif
#ifndef DBACCESS_CORE_API_ROWSETBASE_HXX
#include "RowSetBase.hxx"
#endif

using namespace dbaccess;
ORowSetCacheIterator::ORowSetCacheIterator(const ORowSetCacheIterator& _rRH)
: m_aIter(_rRH.m_aIter)
, m_pCache(_rRH.m_pCache)
,m_pRowSet(_rRH.m_pRowSet)
{
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator::operator ORowSetMatrix::iterator()
{
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetCacheIterator& _rRH)
{
    if(this == &_rRH)
        return *this;

    m_pCache = _rRH.m_pCache;
    m_aIter  = _rRH.m_aIter;
    m_pRowSet = _rRH.m_pRowSet;

    return *this;
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetMatrix::iterator& _rIter)
{
    m_aIter->second.aIterator = _rIter;
    return *this;
}
// -----------------------------------------------------------------------------
ORowSetRow& ORowSetCacheIterator::operator *()
{
    return *m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
const ORowSetRow& ORowSetCacheIterator::operator *() const
{
    if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
    {
        OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
        m_pCache->moveToBookmark(m_aIter->second.aBookmark);
        m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
    }
    return *m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->()
{
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
const ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->() const
{
    if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
    {
        OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
        m_pCache->moveToBookmark(m_aIter->second.aBookmark);
        m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
    }
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator <=(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator <= _rRH;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator !=(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator != _rRH;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator ==(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator == _rRH;
}
// -----------------------------------------------------------------------------
void ORowSetCacheIterator::setBookmark(const ::com::sun::star::uno::Any&    _rBookmark)
{
    m_aIter->second.aBookmark = _rBookmark;
}
// -----------------------------------------------------------------------------
sal_Bool ORowSetCacheIterator::isNull() const
{
    sal_Bool bRet = !m_pCache || !m_pRowSet || m_aIter == m_pCache->m_aCacheIterators.end();
    if ( !bRet )
    {
        ORowSetCacheIterator_Helper aHelper = m_aIter->second;
        bRet = ( m_pRowSet->isInsertRow()
            ?
            m_aIter->second.aIterator == m_pCache->m_pInsertMatrix->end()
            :
            m_aIter->second.aIterator == m_pCache->m_pMatrix->end()
        );
    }
    return  bRet;
}
// -----------------------------------------------------------------------------
::osl::Mutex* ORowSetCacheIterator::getMutex() const
{
    return m_pRowSet ? m_pRowSet->getMutex() : NULL;
}
<commit_msg>INTEGRATION: CWS dba204b (1.14.12); FILE MERGED 2006/07/10 07:59:47 oj 1.14.12.1: #i64770# rotate end as well, and removed some warnings plus extra debug code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: RowSetCacheIterator.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-26 07:46:36 $
 *
 *  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
 *
 ************************************************************************/
#ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
#include "RowSetCacheIterator.hxx"
#endif
#ifndef DBACCESS_CORE_API_ROWSETCACHE_HXX
#include "RowSetCache.hxx"
#endif
#ifndef DBACCESS_CORE_API_ROWSETBASE_HXX
#include "RowSetBase.hxx"
#endif

using namespace dbaccess;
ORowSetCacheIterator::ORowSetCacheIterator(const ORowSetCacheIterator& _rRH)
: m_aIter(_rRH.m_aIter)
, m_pCache(_rRH.m_pCache)
,m_pRowSet(_rRH.m_pRowSet)
{
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator::operator ORowSetMatrix::iterator()
{
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetCacheIterator& _rRH)
{
    if(this == &_rRH)
        return *this;

    m_pCache = _rRH.m_pCache;
    m_aIter  = _rRH.m_aIter;
    m_pRowSet = _rRH.m_pRowSet;

    return *this;
}
// -----------------------------------------------------------------------------
ORowSetCacheIterator& ORowSetCacheIterator::operator =(const ORowSetMatrix::iterator& _rIter)
{
    m_aIter->second.aIterator = _rIter;
    return *this;
}
// -----------------------------------------------------------------------------
ORowSetRow& ORowSetCacheIterator::operator *()
{
    return *m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
const ORowSetRow& ORowSetCacheIterator::operator *() const
{
    if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
    {
        OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
        OSL_VERIFY(m_pCache->moveToBookmark(m_aIter->second.aBookmark));
        m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
    }
    return *m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->()
{
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
const ORowSetMatrix::iterator& ORowSetCacheIterator::operator ->() const
{
    if ( !m_pRowSet->isInsertRow() && m_aIter->second.aIterator == m_pCache->m_pMatrix->end() )
    {
        OSL_ENSURE(m_aIter->second.aBookmark.hasValue(),"bookmark has no value!");
        OSL_VERIFY(m_pCache->moveToBookmark(m_aIter->second.aBookmark));
        m_aIter->second.aIterator = m_pCache->m_aMatrixIter;
    }
    return m_aIter->second.aIterator;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator <=(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator <= _rRH;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator <(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator < _rRH;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator !=(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator != _rRH;
}
// -----------------------------------------------------------------------------
bool ORowSetCacheIterator::operator ==(const ORowSetMatrix::iterator& _rRH) const
{
    return m_aIter->second.aIterator == _rRH;
}
// -----------------------------------------------------------------------------
void ORowSetCacheIterator::setBookmark(const ::com::sun::star::uno::Any&    _rBookmark)
{
    m_aIter->second.aBookmark = _rBookmark;
}
// -----------------------------------------------------------------------------
sal_Bool ORowSetCacheIterator::isNull() const
{
    sal_Bool bRet = !m_pCache || !m_pRowSet || m_aIter == m_pCache->m_aCacheIterators.end();
    if ( !bRet )
    {
        ORowSetCacheIterator_Helper aHelper = m_aIter->second;
        bRet = ( m_pRowSet->isInsertRow()
            ?
            m_aIter->second.aIterator == m_pCache->m_pInsertMatrix->end()
            :
            m_aIter->second.aIterator == m_pCache->m_pMatrix->end()
        );
    }
    return  bRet;
}
// -----------------------------------------------------------------------------
::osl::Mutex* ORowSetCacheIterator::getMutex() const
{
    return m_pRowSet ? m_pRowSet->getMutex() : NULL;
}
<|endoftext|>