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

#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XENCRYPTIONPROTECTEDSOURCE_HPP_
#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_XSIMPLEFILEACCESS_HPP_
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#include <comphelper/fileformat.h>
#include <comphelper/storagehelper.hxx>
#include <comphelper/processfactory.hxx>

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

namespace comphelper {

// ----------------------------------------------------------------------
uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
                            const uno::Reference< lang::XMultiServiceFactory >& xSF )
        throw ( uno::Exception )
{
    uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
    if ( !xFactory.is() )
        throw uno::RuntimeException();

    uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
                    xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
                    uno::UNO_QUERY );

    if ( !xStorageFactory.is() )
        throw uno::RuntimeException();

    return xStorageFactory;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
    throw ( uno::Exception )
{
    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
            const ::rtl::OUString& aURL,
            sal_Int32 nStorageMode,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
    throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= aURL;
    aArgs[1] <<= nStorageMode;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
            const uno::Reference < io::XInputStream >& xStream,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
        throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= xStream;
    aArgs[1] <<= embed::ElementModes::READ;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
            const uno::Reference < io::XStream >& xStream,
            sal_Int32 nStorageMode,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
        throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= xStream;
    aArgs[1] <<= nStorageMode;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
void OStorageHelper::CopyInputToOutput(
            const uno::Reference< io::XInputStream >& xInput,
            const uno::Reference< io::XOutputStream >& xOutput )
    throw ( uno::Exception )
{
    static const sal_Int32 nConstBufferSize = 32000;

    sal_Int32 nRead;
    uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );

    do
    {
        nRead = xInput->readBytes ( aSequence, nConstBufferSize );
        if ( nRead < nConstBufferSize )
        {
            uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
            xOutput->writeBytes ( aTempBuf );
        }
        else
            xOutput->writeBytes ( aSequence );
    }
    while ( nRead == nConstBufferSize );
}

// ----------------------------------------------------------------------
uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
            const ::rtl::OUString& aURL,
            const uno::Reference< lang::XMultiServiceFactory >& xSF )
    throw ( uno::Exception )
{
    uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
    if ( !xFactory.is() )
        throw uno::RuntimeException();

    uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess(
            xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
            uno::UNO_QUERY );

    if ( !xTempAccess.is() )
        throw uno::RuntimeException();

    uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL );
    if ( !xInputStream.is() )
        throw uno::RuntimeException();

    return xInputStream;
}

// ----------------------------------------------------------------------
void OStorageHelper::SetCommonStoragePassword(
            const uno::Reference< embed::XStorage >& xStorage,
            const ::rtl::OUString& aPass )
    throw ( uno::Exception )
{
    uno::Reference< embed::XEncryptionProtectedSource > xEncrSet( xStorage, uno::UNO_QUERY );
    if ( !xEncrSet.is() )
        throw io::IOException(); // TODO

    xEncrSet->setEncryptionPassword( aPass );
}

// ----------------------------------------------------------------------
sal_Int32 OStorageHelper::GetXStorageFormat(
            const uno::Reference< embed::XStorage >& xStorage )
        throw ( uno::Exception )
{
    uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );

    ::rtl::OUString aMediaType;
    xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;

    sal_Int32 nResult = 0;

    // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
    if ( aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer.web" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer.global" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.draw" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.impress" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.calc" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.chart" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.math" ) ) )
    {
        nResult = SOFFICE_FILEFORMAT_60;
    }
    else if ( aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text-web" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text-global" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.drawing" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.presentation" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.spreadsheet" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.chart" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.formula" ) ) )
    {
        nResult = SOFFICE_FILEFORMAT_8;
    }
    else
        throw uno::Exception();

    return nResult;
}

}

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

#ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
#include <com/sun/star/embed/ElementModes.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XENCRYPTIONPROTECTEDSOURCE_HPP_
#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
#endif

#ifndef _COM_SUN_STAR_UCB_XSIMPLEFILEACCESS_HPP_
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_ILLEGALTYPEEXCEPTION_HPP_
#include <com/sun/star/beans/IllegalTypeException.hpp>
#endif

#include <comphelper/fileformat.h>
#include <comphelper/storagehelper.hxx>
#include <comphelper/processfactory.hxx>

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

namespace comphelper {

// ----------------------------------------------------------------------
uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
                            const uno::Reference< lang::XMultiServiceFactory >& xSF )
        throw ( uno::Exception )
{
    uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
    if ( !xFactory.is() )
        throw uno::RuntimeException();

    uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
                    xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
                    uno::UNO_QUERY );

    if ( !xStorageFactory.is() )
        throw uno::RuntimeException();

    return xStorageFactory;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
    throw ( uno::Exception )
{
    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
            const ::rtl::OUString& aURL,
            sal_Int32 nStorageMode,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
    throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= aURL;
    aArgs[1] <<= nStorageMode;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
            const uno::Reference < io::XInputStream >& xStream,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
        throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= xStream;
    aArgs[1] <<= embed::ElementModes::READ;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
            const uno::Reference < io::XStream >& xStream,
            sal_Int32 nStorageMode,
            const uno::Reference< lang::XMultiServiceFactory >& xFactory )
        throw ( uno::Exception )
{
    uno::Sequence< uno::Any > aArgs( 2 );
    aArgs[0] <<= xStream;
    aArgs[1] <<= nStorageMode;

    uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ),
                                                    uno::UNO_QUERY );
    if ( !xTempStorage.is() )
        throw uno::RuntimeException();

    return xTempStorage;
}

// ----------------------------------------------------------------------
void OStorageHelper::CopyInputToOutput(
            const uno::Reference< io::XInputStream >& xInput,
            const uno::Reference< io::XOutputStream >& xOutput )
    throw ( uno::Exception )
{
    static const sal_Int32 nConstBufferSize = 32000;

    sal_Int32 nRead;
    uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );

    do
    {
        nRead = xInput->readBytes ( aSequence, nConstBufferSize );
        if ( nRead < nConstBufferSize )
        {
            uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
            xOutput->writeBytes ( aTempBuf );
        }
        else
            xOutput->writeBytes ( aSequence );
    }
    while ( nRead == nConstBufferSize );
}

// ----------------------------------------------------------------------
uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
            const ::rtl::OUString& aURL,
            const uno::Reference< lang::XMultiServiceFactory >& xSF )
    throw ( uno::Exception )
{
    uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory();
    if ( !xFactory.is() )
        throw uno::RuntimeException();

    uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess(
            xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
            uno::UNO_QUERY );

    if ( !xTempAccess.is() )
        throw uno::RuntimeException();

    uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL );
    if ( !xInputStream.is() )
        throw uno::RuntimeException();

    return xInputStream;
}

// ----------------------------------------------------------------------
void OStorageHelper::SetCommonStoragePassword(
            const uno::Reference< embed::XStorage >& xStorage,
            const ::rtl::OUString& aPass )
    throw ( uno::Exception )
{
    uno::Reference< embed::XEncryptionProtectedSource > xEncrSet( xStorage, uno::UNO_QUERY );
    if ( !xEncrSet.is() )
        throw io::IOException(); // TODO

    xEncrSet->setEncryptionPassword( aPass );
}

// ----------------------------------------------------------------------
sal_Int32 OStorageHelper::GetXStorageFormat(
            const uno::Reference< embed::XStorage >& xStorage )
        throw ( uno::Exception )
{
    uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );

    ::rtl::OUString aMediaType;
    xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType;

    sal_Int32 nResult = 0;

    // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
    if ( aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer.web" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.writer.global" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.draw" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.impress" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.calc" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.chart" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/vnd.sun.xml.math" ) ) )
    {
        nResult = SOFFICE_FILEFORMAT_60;
    }
    else if ( aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text-web" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.text-global" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.drawing" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.presentation" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.spreadsheet" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.chart" ) )
      || aMediaType.equalsIgnoreAsciiCase( ::rtl::OUString::createFromAscii( "application/x-vnd.oasis.openoffice.formula" ) ) )
    {
        nResult = SOFFICE_FILEFORMAT_8;
    }
    else
    {
        // the mediatype is not known
        throw beans::IllegalTypeException();
    }

    return nResult;
}

}

<|endoftext|>


<commit_before>// Copyright 2017 The Crashpad Authors. 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 "util/net/http_transport.h"

#include <curl/curl.h>
#include <string.h>
#include <sys/utsname.h>

#include <algorithm>
#include <limits>

#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/scoped_generic.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "package.h"
#include "util/net/http_body.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {

namespace {

std::string UserAgent() {
  std::string user_agent = base::StringPrintf(
      "%s/%s %s", PACKAGE_NAME, PACKAGE_VERSION, curl_version());

  utsname os;
  if (uname(&os) != 0) {
    PLOG(WARNING) << "uname";
  } else {
    // Match the architecture name that would be used by the kernel, so that the
    // strcmp() below can omit the kernel’s architecture name if it’s the same
    // as the user process’ architecture. On Linux, these names are normally
    // defined in each architecture’s Makefile as UTS_MACHINE, but can be
    // overridden in architecture-specific configuration as COMPAT_UTS_MACHINE.
    // See linux-4.4.52/arch/*/Makefile and
    // linux-4.4.52/arch/*/include/asm/compat.h. In turn, on some systems, these
    // names are further overridden or refined in early kernel startup code by
    // modifying the string returned by linux-4.4.52/include/linux/utsname.h
    // init_utsname() as noted.
#if defined(ARCH_CPU_X86)
    // linux-4.4.52/arch/x86/kernel/cpu/bugs.c check_bugs() sets the first digit
    // to 4, 5, or 6, but no higher. Assume 6.
    const char arch[] = "i686";
#elif defined(ARCH_CPU_X86_64)
    const char arch[] = "x86_64";
#elif defined(ARCH_CPU_ARMEL)
    // linux-4.4.52/arch/arm/kernel/setup.c setup_processor() bases the string
    // on the ARM processor name and a character identifying little- or
    // big-endian. The processor name comes from a definition in
    // arch/arm/mm/proc-*.S. Assume armv7, little-endian.
    const char arch[] = "armv7l";
#elif defined(ARCH_CPU_ARM64)
    // ARM64 uses aarch64 or aarch64_be as directed by ELF_PLATFORM. See
    // linux-4.4.52/arch/arm64/kernel/setup.c setup_arch(). Assume
    // little-endian.
    const char arch[] = "aarch64";
#elif defined(ARCH_CPU_MIPSEL)
    const char arch[] = "mips";
#elif defined(ARCH_CPU_MIPS64EL)
    const char arch[] = "mips64";
#else
#error Port
#endif

    user_agent.append(
        base::StringPrintf(" %s/%s (%s", os.sysname, os.release, arch));
    if (strcmp(arch, os.machine) != 0) {
      user_agent.append(base::StringPrintf("; %s", os.machine));
    }
    user_agent.append(1, ')');
  }

  return user_agent;
}

std::string CurlErrorMessage(CURLcode curl_err, const std::string& base) {
  return base::StringPrintf(
      "%s: %s (%d)", base.c_str(), curl_easy_strerror(curl_err), curl_err);
}

struct ScopedCURLTraits {
  static CURL* InvalidValue() { return nullptr; }
  static void Free(CURL* curl) {
    if (curl) {
      curl_easy_cleanup(curl);
    }
  }
};
using ScopedCURL = base::ScopedGeneric<CURL*, ScopedCURLTraits>;

class CurlSList {
 public:
  CurlSList() : list_(nullptr) {}
  ~CurlSList() {
    if (list_) {
      curl_slist_free_all(list_);
    }
  }

  curl_slist* get() const { return list_; }

  bool Append(const char* data) {
    curl_slist* list = curl_slist_append(list_, data);
    if (!list_) {
      list_ = list;
    }
    return list != nullptr;
  }

 private:
  curl_slist* list_;

  DISALLOW_COPY_AND_ASSIGN(CurlSList);
};

class ScopedClearString {
 public:
  explicit ScopedClearString(std::string* string) : string_(string) {}

  ~ScopedClearString() {
    if (string_) {
      string_->clear();
    }
  }

  void Disarm() { string_ = nullptr; }

 private:
  std::string* string_;

  DISALLOW_COPY_AND_ASSIGN(ScopedClearString);
};

class HTTPTransportLibcurl final : public HTTPTransport {
 public:
  HTTPTransportLibcurl();
  ~HTTPTransportLibcurl() override;

  // HTTPTransport:
  bool ExecuteSynchronously(std::string* response_body) override;

 private:
  static size_t ReadRequestBody(char* buffer,
                                size_t size,
                                size_t nitems,
                                void* userdata);
  static size_t WriteResponseBody(char* buffer,
                                  size_t size,
                                  size_t nitems,
                                  void* userdata);

  DISALLOW_COPY_AND_ASSIGN(HTTPTransportLibcurl);
};

HTTPTransportLibcurl::HTTPTransportLibcurl() : HTTPTransport() {}

HTTPTransportLibcurl::~HTTPTransportLibcurl() {}

bool HTTPTransportLibcurl::ExecuteSynchronously(std::string* response_body) {
  DCHECK(body_stream());

  response_body->clear();

  // curl_easy_init() will do this on the first call if it hasn’t been done yet,
  // but not in a thread-safe way as is done here.
  static CURLcode curl_global_init_err = []() {
    return curl_global_init(CURL_GLOBAL_DEFAULT);
  }();
  if (curl_global_init_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_global_init_err, "curl_global_init");
    return false;
  }

  CurlSList curl_headers;
  ScopedCURL curl(curl_easy_init());
  if (!curl.get()) {
    LOG(ERROR) << "curl_easy_init";
    return false;
  }

// These macros wrap the repetitive “try something, log an error and return
// false on failure” pattern. Macros are convenient because the log messages
// will point to the correct line number, which can help pinpoint a problem when
// there are as many calls to these functions as there are here.
#define TRY_CURL_EASY_SETOPT(curl, option, parameter)                    \
  do {                                                                   \
    CURLcode curl_err = curl_easy_setopt((curl), (option), (parameter)); \
    if (curl_err != CURLE_OK) {                                          \
      LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_setopt");      \
      return false;                                                      \
    }                                                                    \
  } while (false)
#define TRY_CURL_SLIST_APPEND(slist, data) \
  do {                                     \
    if (!(slist).Append(data)) {           \
      LOG(ERROR) << "curl_slist_append";   \
      return false;                        \
    }                                      \
  } while (false)

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_USERAGENT, UserAgent().c_str());

  // Accept and automatically decode any encoding that libcurl understands.
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_ACCEPT_ENCODING, "");

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_URL, url().c_str());

  const int kMillisecondsPerSecond = 1E3;
  TRY_CURL_EASY_SETOPT(curl.get(),
                       CURLOPT_TIMEOUT_MS,
                       static_cast<long>(timeout() * kMillisecondsPerSecond));

  // If the request body size is known ahead of time, a Content-Length header
  // field will be present. Store that to use as CURLOPT_POSTFIELDSIZE_LARGE,
  // which will both set the Content-Length field in the request header and
  // inform libcurl of the request body size. Otherwise, use Transfer-Encoding:
  // chunked, which does not require advance knowledge of the request body size.
  bool chunked = true;
  size_t content_length;
  for (const auto& pair : headers()) {
    if (pair.first == kContentLength) {
      chunked = !base::StringToSizeT(pair.second, &content_length);
      DCHECK(!chunked);
    } else {
      TRY_CURL_SLIST_APPEND(curl_headers,
                            (pair.first + ": " + pair.second).c_str());
    }
  }

  if (method() == "POST") {
    TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_POST, 1l);

    // By default when sending a POST request, libcurl includes an “Expect:
    // 100-continue” header field. Althogh this header is specified in HTTP/1.1
    // (RFC 2616 §8.2.3, RFC 7231 §5.1.1), even collection servers that claim to
    // speak HTTP/1.1 may not respond to it. When sending this header field,
    // libcurl will wait for one second for the server to respond with a “100
    // Continue” status before continuing to transmit the request body. This
    // delay is avoided by telling libcurl not to send this header field at all.
    // The drawback is that certain HTTP error statuses may not be received
    // until after substantial amounts of data have been sent to the server.
    TRY_CURL_SLIST_APPEND(curl_headers, "Expect:");

    if (chunked) {
      TRY_CURL_SLIST_APPEND(curl_headers, "Transfer-Encoding: chunked");
    } else {
      curl_off_t content_length_curl;
      if (!AssignIfInRange(&content_length_curl, content_length)) {
        LOG(ERROR) << base::StringPrintf("Content-Length %zu too large",
                                         content_length);
        return false;
      }
      TRY_CURL_EASY_SETOPT(
          curl.get(), CURLOPT_POSTFIELDSIZE_LARGE, content_length_curl);
    }
  } else if (method() != "GET") {
    // Untested.
    TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_CUSTOMREQUEST, method().c_str());
  }

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_HTTPHEADER, curl_headers.get());

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_READFUNCTION, ReadRequestBody);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_READDATA, this);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_WRITEFUNCTION, WriteResponseBody);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_WRITEDATA, response_body);

#undef TRY_CURL_EASY_SETOPT
#undef TRY_CURL_SLIST_APPEND

  // If a partial response body is received and then a failure occurs, ensure
  // that response_body is cleared.
  ScopedClearString clear_response_body(response_body);

  // Do it.
  CURLcode curl_err = curl_easy_perform(curl.get());
  if (curl_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_perform");
    return false;
  }

  long status;
  curl_err = curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &status);
  if (curl_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_getinfo");
    return false;
  }

  if (status != 200) {
    LOG(ERROR) << base::StringPrintf("HTTP status %ld", status);
    return false;
  }

  // The response body is complete. Don’t clear it.
  clear_response_body.Disarm();

  return true;
}

// static
size_t HTTPTransportLibcurl::ReadRequestBody(char* buffer,
                                             size_t size,
                                             size_t nitems,
                                             void* userdata) {
  HTTPTransportLibcurl* self =
      reinterpret_cast<HTTPTransportLibcurl*>(userdata);

  // This libcurl callback mimics the silly stdio-style fread() interface: size
  // and nitems have been separated and must be multiplied.
  base::CheckedNumeric<size_t> checked_len = base::CheckMul(size, nitems);
  size_t len = checked_len.ValueOrDefault(std::numeric_limits<size_t>::max());

  // Limit the read to what can be expressed in a FileOperationResult.
  len = std::min(
      len,
      static_cast<size_t>(std::numeric_limits<FileOperationResult>::max()));

  FileOperationResult bytes_read = self->body_stream()->GetBytesBuffer(
      reinterpret_cast<uint8_t*>(buffer), len);
  if (bytes_read < 0) {
    return CURL_READFUNC_ABORT;
  }

  return bytes_read;
}

// static
size_t HTTPTransportLibcurl::WriteResponseBody(char* buffer,
                                               size_t size,
                                               size_t nitems,
                                               void* userdata) {
  std::string* response_body = reinterpret_cast<std::string*>(userdata);

  // This libcurl callback mimics the silly stdio-style fread() interface: size
  // and nitems have been separated and must be multiplied.
  base::CheckedNumeric<size_t> checked_len = base::CheckMul(size, nitems);
  size_t len = checked_len.ValueOrDefault(std::numeric_limits<size_t>::max());

  response_body->append(buffer, len);
  return len;
}

}  // namespace

// static
std::unique_ptr<HTTPTransport> HTTPTransport::Create() {
  return std::unique_ptr<HTTPTransport>(new HTTPTransportLibcurl());
}

}  // namespace crashpad
<commit_msg>linux: Don’t make assumptions about the CPU revision<commit_after>// Copyright 2017 The Crashpad Authors. 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 "util/net/http_transport.h"

#include <curl/curl.h>
#include <string.h>
#include <sys/utsname.h>

#include <algorithm>
#include <limits>

#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/scoped_generic.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "package.h"
#include "util/net/http_body.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {

namespace {

std::string UserAgent() {
  std::string user_agent = base::StringPrintf(
      "%s/%s %s", PACKAGE_NAME, PACKAGE_VERSION, curl_version());

  utsname os;
  if (uname(&os) != 0) {
    PLOG(WARNING) << "uname";
  } else {
    // Match the architecture name that would be used by the kernel, so that the
    // strcmp() below can omit the kernel’s architecture name if it’s the same
    // as the user process’ architecture. On Linux, these names are normally
    // defined in each architecture’s Makefile as UTS_MACHINE, but can be
    // overridden in architecture-specific configuration as COMPAT_UTS_MACHINE.
    // See linux-4.9.17/arch/*/Makefile and
    // linux-4.9.17/arch/*/include/asm/compat.h. In turn, on some systems, these
    // names are further overridden or refined in early kernel startup code by
    // modifying the string returned by linux-4.9.17/include/linux/utsname.h
    // init_utsname() as noted.
#if defined(ARCH_CPU_X86)
    // linux-4.9.17/arch/x86/kernel/cpu/bugs.c check_bugs() sets the first digit
    // to 4, 5, or 6, but no higher.
#if defined(__i686__)
    const char arch[] = "i686";
#elif defined(__i586__)
    const char arch[] = "i586";
#elif defined(__i486__)
    const char arch[] = "i486";
#else
    const char arch[] = "i386";
#endif
#elif defined(ARCH_CPU_X86_64)
    const char arch[] = "x86_64";
#elif defined(ARCH_CPU_ARMEL)
    // linux-4.9.17/arch/arm/kernel/setup.c setup_processor() bases the string
    // on the ARM processor name and a character identifying little- or
    // big-endian. The processor name comes from a definition in
    // arch/arm/mm/proc-*.S.
#if defined(__ARM_ARCH_4T__)
    const char arch[] = "armv4t"
#elif defined(__ARM_ARCH_5TEJ__)
    const char arch[] = "armv5tej"
#elif defined(__ARM_ARCH_5TE__)
    const char arch[] = "armv5te"
#elif defined(__ARM_ARCH_5T__)
    const char arch[] = "armv5t"
#elif defined(__ARM_ARCH_7M__)
    const char arch[] = "armv7m"
#else
    // Most ARM architectures fall into here, including all profile variants of
    // armv6, armv7, armv8, with one exception, armv7m, handled above.
    // xstr(__ARM_ARCH) will be the architecture revision number, such as 6, 7,
    // or 8.
#define xstr(s) str(s)
#define str(s) #s
    const char arch[] = "armv" xstr(__ARM_ARCH)
#undef str
#undef xstr
#endif
#if defined(ARCH_CPU_LITTLE_ENDIAN)
        "l";
#elif defined(ARCH_CPU_BIG_ENDIAN)
        "b";
#endif
#elif defined(ARCH_CPU_ARM64)
    // ARM64 uses aarch64 or aarch64_be as directed by ELF_PLATFORM. See
    // linux-4.9.17/arch/arm64/kernel/setup.c setup_arch().
#if defined(ARCH_CPU_LITTLE_ENDIAN)
    const char arch[] = "aarch64";
#elif defined(ARCH_CPU_BIG_ENDIAN)
    const char arch[] = "aarch64_be";
#endif
#elif defined(ARCH_CPU_MIPSEL)
    const char arch[] = "mips";
#elif defined(ARCH_CPU_MIPS64EL)
    const char arch[] = "mips64";
#else
#error Port
#endif

    user_agent.append(
        base::StringPrintf(" %s/%s (%s", os.sysname, os.release, arch));
    if (strcmp(arch, os.machine) != 0) {
      user_agent.append(base::StringPrintf("; %s", os.machine));
    }
    user_agent.append(1, ')');
  }

  return user_agent;
}

std::string CurlErrorMessage(CURLcode curl_err, const std::string& base) {
  return base::StringPrintf(
      "%s: %s (%d)", base.c_str(), curl_easy_strerror(curl_err), curl_err);
}

struct ScopedCURLTraits {
  static CURL* InvalidValue() { return nullptr; }
  static void Free(CURL* curl) {
    if (curl) {
      curl_easy_cleanup(curl);
    }
  }
};
using ScopedCURL = base::ScopedGeneric<CURL*, ScopedCURLTraits>;

class CurlSList {
 public:
  CurlSList() : list_(nullptr) {}
  ~CurlSList() {
    if (list_) {
      curl_slist_free_all(list_);
    }
  }

  curl_slist* get() const { return list_; }

  bool Append(const char* data) {
    curl_slist* list = curl_slist_append(list_, data);
    if (!list_) {
      list_ = list;
    }
    return list != nullptr;
  }

 private:
  curl_slist* list_;

  DISALLOW_COPY_AND_ASSIGN(CurlSList);
};

class ScopedClearString {
 public:
  explicit ScopedClearString(std::string* string) : string_(string) {}

  ~ScopedClearString() {
    if (string_) {
      string_->clear();
    }
  }

  void Disarm() { string_ = nullptr; }

 private:
  std::string* string_;

  DISALLOW_COPY_AND_ASSIGN(ScopedClearString);
};

class HTTPTransportLibcurl final : public HTTPTransport {
 public:
  HTTPTransportLibcurl();
  ~HTTPTransportLibcurl() override;

  // HTTPTransport:
  bool ExecuteSynchronously(std::string* response_body) override;

 private:
  static size_t ReadRequestBody(char* buffer,
                                size_t size,
                                size_t nitems,
                                void* userdata);
  static size_t WriteResponseBody(char* buffer,
                                  size_t size,
                                  size_t nitems,
                                  void* userdata);

  DISALLOW_COPY_AND_ASSIGN(HTTPTransportLibcurl);
};

HTTPTransportLibcurl::HTTPTransportLibcurl() : HTTPTransport() {}

HTTPTransportLibcurl::~HTTPTransportLibcurl() {}

bool HTTPTransportLibcurl::ExecuteSynchronously(std::string* response_body) {
  DCHECK(body_stream());

  response_body->clear();

  // curl_easy_init() will do this on the first call if it hasn’t been done yet,
  // but not in a thread-safe way as is done here.
  static CURLcode curl_global_init_err = []() {
    return curl_global_init(CURL_GLOBAL_DEFAULT);
  }();
  if (curl_global_init_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_global_init_err, "curl_global_init");
    return false;
  }

  CurlSList curl_headers;
  ScopedCURL curl(curl_easy_init());
  if (!curl.get()) {
    LOG(ERROR) << "curl_easy_init";
    return false;
  }

// These macros wrap the repetitive “try something, log an error and return
// false on failure” pattern. Macros are convenient because the log messages
// will point to the correct line number, which can help pinpoint a problem when
// there are as many calls to these functions as there are here.
#define TRY_CURL_EASY_SETOPT(curl, option, parameter)                    \
  do {                                                                   \
    CURLcode curl_err = curl_easy_setopt((curl), (option), (parameter)); \
    if (curl_err != CURLE_OK) {                                          \
      LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_setopt");      \
      return false;                                                      \
    }                                                                    \
  } while (false)
#define TRY_CURL_SLIST_APPEND(slist, data) \
  do {                                     \
    if (!(slist).Append(data)) {           \
      LOG(ERROR) << "curl_slist_append";   \
      return false;                        \
    }                                      \
  } while (false)

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_USERAGENT, UserAgent().c_str());

  // Accept and automatically decode any encoding that libcurl understands.
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_ACCEPT_ENCODING, "");

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_URL, url().c_str());

  const int kMillisecondsPerSecond = 1E3;
  TRY_CURL_EASY_SETOPT(curl.get(),
                       CURLOPT_TIMEOUT_MS,
                       static_cast<long>(timeout() * kMillisecondsPerSecond));

  // If the request body size is known ahead of time, a Content-Length header
  // field will be present. Store that to use as CURLOPT_POSTFIELDSIZE_LARGE,
  // which will both set the Content-Length field in the request header and
  // inform libcurl of the request body size. Otherwise, use Transfer-Encoding:
  // chunked, which does not require advance knowledge of the request body size.
  bool chunked = true;
  size_t content_length;
  for (const auto& pair : headers()) {
    if (pair.first == kContentLength) {
      chunked = !base::StringToSizeT(pair.second, &content_length);
      DCHECK(!chunked);
    } else {
      TRY_CURL_SLIST_APPEND(curl_headers,
                            (pair.first + ": " + pair.second).c_str());
    }
  }

  if (method() == "POST") {
    TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_POST, 1l);

    // By default when sending a POST request, libcurl includes an “Expect:
    // 100-continue” header field. Althogh this header is specified in HTTP/1.1
    // (RFC 2616 §8.2.3, RFC 7231 §5.1.1), even collection servers that claim to
    // speak HTTP/1.1 may not respond to it. When sending this header field,
    // libcurl will wait for one second for the server to respond with a “100
    // Continue” status before continuing to transmit the request body. This
    // delay is avoided by telling libcurl not to send this header field at all.
    // The drawback is that certain HTTP error statuses may not be received
    // until after substantial amounts of data have been sent to the server.
    TRY_CURL_SLIST_APPEND(curl_headers, "Expect:");

    if (chunked) {
      TRY_CURL_SLIST_APPEND(curl_headers, "Transfer-Encoding: chunked");
    } else {
      curl_off_t content_length_curl;
      if (!AssignIfInRange(&content_length_curl, content_length)) {
        LOG(ERROR) << base::StringPrintf("Content-Length %zu too large",
                                         content_length);
        return false;
      }
      TRY_CURL_EASY_SETOPT(
          curl.get(), CURLOPT_POSTFIELDSIZE_LARGE, content_length_curl);
    }
  } else if (method() != "GET") {
    // Untested.
    TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_CUSTOMREQUEST, method().c_str());
  }

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_HTTPHEADER, curl_headers.get());

  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_READFUNCTION, ReadRequestBody);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_READDATA, this);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_WRITEFUNCTION, WriteResponseBody);
  TRY_CURL_EASY_SETOPT(curl.get(), CURLOPT_WRITEDATA, response_body);

#undef TRY_CURL_EASY_SETOPT
#undef TRY_CURL_SLIST_APPEND

  // If a partial response body is received and then a failure occurs, ensure
  // that response_body is cleared.
  ScopedClearString clear_response_body(response_body);

  // Do it.
  CURLcode curl_err = curl_easy_perform(curl.get());
  if (curl_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_perform");
    return false;
  }

  long status;
  curl_err = curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &status);
  if (curl_err != CURLE_OK) {
    LOG(ERROR) << CurlErrorMessage(curl_err, "curl_easy_getinfo");
    return false;
  }

  if (status != 200) {
    LOG(ERROR) << base::StringPrintf("HTTP status %ld", status);
    return false;
  }

  // The response body is complete. Don’t clear it.
  clear_response_body.Disarm();

  return true;
}

// static
size_t HTTPTransportLibcurl::ReadRequestBody(char* buffer,
                                             size_t size,
                                             size_t nitems,
                                             void* userdata) {
  HTTPTransportLibcurl* self =
      reinterpret_cast<HTTPTransportLibcurl*>(userdata);

  // This libcurl callback mimics the silly stdio-style fread() interface: size
  // and nitems have been separated and must be multiplied.
  base::CheckedNumeric<size_t> checked_len = base::CheckMul(size, nitems);
  size_t len = checked_len.ValueOrDefault(std::numeric_limits<size_t>::max());

  // Limit the read to what can be expressed in a FileOperationResult.
  len = std::min(
      len,
      static_cast<size_t>(std::numeric_limits<FileOperationResult>::max()));

  FileOperationResult bytes_read = self->body_stream()->GetBytesBuffer(
      reinterpret_cast<uint8_t*>(buffer), len);
  if (bytes_read < 0) {
    return CURL_READFUNC_ABORT;
  }

  return bytes_read;
}

// static
size_t HTTPTransportLibcurl::WriteResponseBody(char* buffer,
                                               size_t size,
                                               size_t nitems,
                                               void* userdata) {
  std::string* response_body = reinterpret_cast<std::string*>(userdata);

  // This libcurl callback mimics the silly stdio-style fread() interface: size
  // and nitems have been separated and must be multiplied.
  base::CheckedNumeric<size_t> checked_len = base::CheckMul(size, nitems);
  size_t len = checked_len.ValueOrDefault(std::numeric_limits<size_t>::max());

  response_body->append(buffer, len);
  return len;
}

}  // namespace

// static
std::unique_ptr<HTTPTransport> HTTPTransport::Create() {
  return std::unique_ptr<HTTPTransport>(new HTTPTransportLibcurl());
}

}  // namespace crashpad
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: timestamp.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 04:25:38 $
 *
 *  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
 *
 ************************************************************************/

#include <stdio.h>

#include "timestamp.hxx"
#include <osl/diagnose.h>

namespace configmgr
{
    const sal_uInt32 maxTimeValueSeconds    = 0xFF000000ul; // catches accidetally added values as well
    const sal_uInt32 maxTimeValueNanos      = 999999999ul;
    const sal_uInt32 minTimeValueSeconds    = 0ul;
    const sal_uInt32 minTimeValueNanos      = 0ul;
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::never()
    {
        const ::TimeValue maxTimeValue = { maxTimeValueSeconds, maxTimeValueNanos };

        return TimeStamp( maxTimeValue );
    }
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::always()
    {
        const ::TimeValue minTimeValue = { minTimeValueSeconds, minTimeValueNanos };

        return TimeStamp( minTimeValue );
    }
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::getCurrentTime()
    {
        TimeStamp aResult;
        if (! ::osl_getSystemTime( &aResult.m_aTime ) )
            return never();
        return aResult;
    }
// -------------------------------------------------------------------------
} // namespace configmgr

<commit_msg>INTEGRATION: CWS pchfix02 (1.2.60); FILE MERGED 2006/09/01 17:20:47 kaib 1.2.60.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: timestamp.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 15:26:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include <stdio.h>

#include "timestamp.hxx"
#include <osl/diagnose.h>

namespace configmgr
{
    const sal_uInt32 maxTimeValueSeconds    = 0xFF000000ul; // catches accidetally added values as well
    const sal_uInt32 maxTimeValueNanos      = 999999999ul;
    const sal_uInt32 minTimeValueSeconds    = 0ul;
    const sal_uInt32 minTimeValueNanos      = 0ul;
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::never()
    {
        const ::TimeValue maxTimeValue = { maxTimeValueSeconds, maxTimeValueNanos };

        return TimeStamp( maxTimeValue );
    }
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::always()
    {
        const ::TimeValue minTimeValue = { minTimeValueSeconds, minTimeValueNanos };

        return TimeStamp( minTimeValue );
    }
// -------------------------------------------------------------------------
    TimeStamp TimeStamp::getCurrentTime()
    {
        TimeStamp aResult;
        if (! ::osl_getSystemTime( &aResult.m_aTime ) )
            return never();
        return aResult;
    }
// -------------------------------------------------------------------------
} // namespace configmgr

<|endoftext|>


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

#include <taskpanelist.hxx>
#include <functional>
#include <algorithm>

// can't have static linkage because SUNPRO 5.2 complains
Point ImplTaskPaneListGetPos( const Window *w )
{
    Point pos;
    if( w->ImplIsDockingWindow() )
    {
        pos = ((DockingWindow*)w)->GetPosPixel();
        Window *pF = ((DockingWindow*)w)->GetFloatingWindow();
        if( pF )
            pos = pF->OutputToAbsoluteScreenPixel( pF->ScreenToOutputPixel( pos ) );
        else
            pos = w->OutputToAbsoluteScreenPixel( pos );
    }
    else
        pos = w->OutputToAbsoluteScreenPixel( w->GetPosPixel() );

    return pos;
}

// compares window pos left-to-right
struct LTRSort : public ::std::binary_function< const Window*, const Window*, bool >
{
    bool operator()( const Window* w1, const Window* w2 ) const
    {
        Point pos1(ImplTaskPaneListGetPos( w1 ));
        Point pos2(ImplTaskPaneListGetPos( w2 ));

        if( pos1.X() == pos2.X() )
            return ( pos1.Y() < pos2.Y() );
        else
            return ( pos1.X() < pos2.X() );
    }
};
struct LTRSortBackward : public ::std::binary_function< const Window*, const Window*, bool >
{
    bool operator()( const Window* w2, const Window* w1 ) const
    {
        Point pos1(ImplTaskPaneListGetPos( w1 ));
        Point pos2(ImplTaskPaneListGetPos( w2 ));

        if( pos1.X() == pos2.X() )
            return ( pos1.Y() < pos2.Y() );
        else
            return ( pos1.X() < pos2.X() );
    }
};

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

static void ImplTaskPaneListGrabFocus( Window *pWindow )
{
    // put focus in child of floating windows which is typically a toolbar
    // that can deal with the focus
    if( pWindow->ImplIsFloatingWindow() && pWindow->GetWindow( WINDOW_FIRSTCHILD ) )
        pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
    pWindow->GrabFocus();
}

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

TaskPaneList::TaskPaneList()
{
}

TaskPaneList::~TaskPaneList()
{
}

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

void TaskPaneList::AddWindow( Window *pWindow )
{
    bool bDockingWindow=false;
    bool bToolbox=false;
    bool bDialog=false;
    bool bUnknown=false;

    if( pWindow )
    {
        if( pWindow->GetType() == RSC_DOCKINGWINDOW )
            bDockingWindow = true;
        else if( pWindow->GetType() == RSC_TOOLBOX )
            bToolbox = true;
        else if( pWindow->IsDialog() )
            bDialog = true;
        else
            bUnknown = true;

        ::std::vector< Window* >::iterator p;
        p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );

        // avoid duplicates
        if( p == mTaskPanes.end() ) // not found
            mTaskPanes.push_back( pWindow );
    }
}

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

void TaskPaneList::RemoveWindow( Window *pWindow )
{
    ::std::vector< Window* >::iterator p;
    p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
    if( p != mTaskPanes.end() )
        mTaskPanes.erase( p );
}

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

BOOL TaskPaneList::HandleKeyEvent( KeyEvent aKeyEvent )
{

    // F6 cycles through everything and works always
    // Ctrl-TAB cycles through Menubar, Toolbars and Floatingwindows only and is
    // only active if one of those items has the focus
    BOOL bF6 = FALSE;
    BOOL bSplitterOnly = FALSE;
    BOOL bFocusInList = FALSE;
    KeyCode aKeyCode = aKeyEvent.GetKeyCode();
    BOOL bForward = !aKeyCode.IsShift();
    if( ( (aKeyCode.IsMod1() || aKeyCode.IsMod2()) && aKeyCode.GetCode() == KEY_TAB )  // Ctrl-TAB or Alt-TAB
        || ( bF6 = ( aKeyCode.GetCode()) == KEY_F6 )    // F6
        )
    {
        bSplitterOnly = bF6 && aKeyCode.IsMod1() && aKeyCode.IsShift();

        // is the focus in the list ?
        ::std::vector< Window* >::iterator p = mTaskPanes.begin();
        while( p != mTaskPanes.end() )
        {
            Window *pWin = *p;
            if( pWin->HasChildPathFocus( TRUE ) )
            {
                bFocusInList = TRUE;

                // Ctrl-TAB does not work in Dialogs
                if( !bF6 && pWin->IsDialog() )
                    return FALSE;

                // Ctrl-F6 goes directly to the document
                if( !pWin->IsDialog() && bF6 && aKeyCode.IsMod1() && !aKeyCode.IsShift() )
                {
                    pWin->GrabFocusToDocument();
                    return TRUE;
                }

                // activate next task pane
                Window *pNextWin = NULL;

                if( bSplitterOnly )
                    pNextWin = FindNextSplitter( *p, TRUE );
                else
                    pNextWin = bF6 ?  FindNextFloat( *p, bForward ) : FindNextPane( *p, bForward );
                if( pNextWin != pWin )
                {
                    ImplGetSVData()->maWinData.mbNoSaveFocus = TRUE;
                    ImplTaskPaneListGrabFocus( pNextWin );
                    ImplGetSVData()->maWinData.mbNoSaveFocus = FALSE;
                }
                else
                {
                    // forward key if no splitter found
                    if( bSplitterOnly )
                        return FALSE;

                    // we did not find another taskpane, so
                    // put focus back into document
                    pWin->GrabFocusToDocument();
                }

                return TRUE;
            }
            else
                p++;
        }

        // the focus is not in the list: activate first float if F6 was pressed
        if( !bFocusInList && bF6 )
        {
            Window *pWin;
            if( bSplitterOnly )
                pWin = FindNextSplitter( NULL, TRUE );
            else
                pWin = FindNextFloat( NULL, bForward );
            if( pWin )
            {
                ImplTaskPaneListGrabFocus( pWin );
                return TRUE;
            }
        }
    }

    return FALSE;
}

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

//  returns next valid pane
Window* TaskPaneList::FindNextPane( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( *p == pWindow )
        {
            unsigned n = mTaskPanes.size();
            while( --n )
            {
                if( ++p == mTaskPanes.end() )
                    p = mTaskPanes.begin();
                if( (*p)->IsReallyVisible() && !(*p)->IsDialog() && !(*p)->ImplIsSplitter() )
                {
                    pWindow = *p;
                    break;
                }
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

// returns next splitter
Window* TaskPaneList::FindNextSplitter( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( !pWindow || *p == pWindow )
        {
            unsigned n = mTaskPanes.size();
            while( --n )
            {
                if( pWindow )   // increment before test
                    ++p;
                if( p == mTaskPanes.end() )
                    p = mTaskPanes.begin();
                if( (*p)->ImplIsSplitter() && (*p)->IsReallyVisible() && !(*p)->IsDialog() && (*p)->GetParent()->HasChildPathFocus() )
                {
                    pWindow = *p;
                    break;
                }
                if( !pWindow )  // increment after test, otherwise first element is skipped
                    ++p;
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

// returns first valid item (regardless of type) if pWindow==0, otherwise returns next valid float
Window* TaskPaneList::FindNextFloat( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( !pWindow || *p == pWindow )
        {
            while( p != mTaskPanes.end() )
            {
                if( pWindow )   // increment before test
                    ++p;
                if( p == mTaskPanes.end() )
                    break; // do not wrap, send focus back to document at end of list
                if( (*p)->IsReallyVisible() && !(*p)->ImplIsSplitter() )
                {
                    pWindow = *p;
                    break;
                }
                if( !pWindow )  // increment after test, otherwise first element is skipped
                    ++p;
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

<commit_msg>INTEGRATION: CWS dba17 (1.15.200); FILE MERGED 2004/09/27 11:55:40 fs 1.15.200.1: AddWindow: ensure that if two windows have an parent/child relation, the child is inserted *before* the parent. Done during #i33573#, but in real the fix for #98916#, whose original fix indirectly caused #i33573#<commit_after>/*************************************************************************
 *
 *  $RCSfile: taskpanelist.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-10-22 12:14:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SV_SVDATA_HXX
#include <svdata.hxx>
#endif
#ifndef _TOOLS_RCID_H
#include <tools/rcid.h>
#endif
#ifndef _SV_DOCKWIN_HXX
#include <dockwin.hxx>
#endif

#include <taskpanelist.hxx>
#include <functional>
#include <algorithm>

// can't have static linkage because SUNPRO 5.2 complains
Point ImplTaskPaneListGetPos( const Window *w )
{
    Point pos;
    if( w->ImplIsDockingWindow() )
    {
        pos = ((DockingWindow*)w)->GetPosPixel();
        Window *pF = ((DockingWindow*)w)->GetFloatingWindow();
        if( pF )
            pos = pF->OutputToAbsoluteScreenPixel( pF->ScreenToOutputPixel( pos ) );
        else
            pos = w->OutputToAbsoluteScreenPixel( pos );
    }
    else
        pos = w->OutputToAbsoluteScreenPixel( w->GetPosPixel() );

    return pos;
}

// compares window pos left-to-right
struct LTRSort : public ::std::binary_function< const Window*, const Window*, bool >
{
    bool operator()( const Window* w1, const Window* w2 ) const
    {
        Point pos1(ImplTaskPaneListGetPos( w1 ));
        Point pos2(ImplTaskPaneListGetPos( w2 ));

        if( pos1.X() == pos2.X() )
            return ( pos1.Y() < pos2.Y() );
        else
            return ( pos1.X() < pos2.X() );
    }
};
struct LTRSortBackward : public ::std::binary_function< const Window*, const Window*, bool >
{
    bool operator()( const Window* w2, const Window* w1 ) const
    {
        Point pos1(ImplTaskPaneListGetPos( w1 ));
        Point pos2(ImplTaskPaneListGetPos( w2 ));

        if( pos1.X() == pos2.X() )
            return ( pos1.Y() < pos2.Y() );
        else
            return ( pos1.X() < pos2.X() );
    }
};

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

static void ImplTaskPaneListGrabFocus( Window *pWindow )
{
    // put focus in child of floating windows which is typically a toolbar
    // that can deal with the focus
    if( pWindow->ImplIsFloatingWindow() && pWindow->GetWindow( WINDOW_FIRSTCHILD ) )
        pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
    pWindow->GrabFocus();
}

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

TaskPaneList::TaskPaneList()
{
}

TaskPaneList::~TaskPaneList()
{
}

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

void TaskPaneList::AddWindow( Window *pWindow )
{
#if OSL_DEBUG_LEVEL > 0
    bool bDockingWindow=false;
    bool bToolbox=false;
    bool bDialog=false;
    bool bUnknown=false;
#endif

    if( pWindow )
    {
#if OSL_DEBUG_LEVEL > 0
        if( pWindow->GetType() == RSC_DOCKINGWINDOW )
            bDockingWindow = true;
        else if( pWindow->GetType() == RSC_TOOLBOX )
            bToolbox = true;
        else if( pWindow->IsDialog() )
            bDialog = true;
        else
            bUnknown = true;
#endif

        ::std::vector< Window* >::iterator insertionPos = mTaskPanes.end();
        for ( ::std::vector< Window* >::iterator p = mTaskPanes.begin();
              p != mTaskPanes.end();
              ++p
            )
        {
            if ( *p == pWindow )
                // avoid duplicates
                return;

            // If the new window is the child of an existing pane window, or vice versa,
            // ensure that in our pane list, *first* the child window appears, *then*
            // the ancestor window.
            // This is necessary for HandleKeyEvent: There, the list is traveled from the
            // beginning, until the first window is found which has the ChildPathFocus. Now
            // if this would be the ancestor window of another pane window, this would fudge
            // the result
            // 2004-09-27 - fs@openoffice.org, while fixing #i33573#, which included replacing
            // the original fix for #98916# with this one here.
            if ( pWindow->IsWindowOrChild( *p ) )
            {
                insertionPos = p + 1;
                break;
            }
            if ( (*p)->IsWindowOrChild( pWindow ) )
            {
                insertionPos = p;
                break;
            }
        }

        mTaskPanes.insert( insertionPos, pWindow );
    }
}

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

void TaskPaneList::RemoveWindow( Window *pWindow )
{
    ::std::vector< Window* >::iterator p;
    p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
    if( p != mTaskPanes.end() )
        mTaskPanes.erase( p );
}

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

BOOL TaskPaneList::HandleKeyEvent( KeyEvent aKeyEvent )
{

    // F6 cycles through everything and works always
    // Ctrl-TAB cycles through Menubar, Toolbars and Floatingwindows only and is
    // only active if one of those items has the focus
    BOOL bF6 = FALSE;
    BOOL bSplitterOnly = FALSE;
    BOOL bFocusInList = FALSE;
    KeyCode aKeyCode = aKeyEvent.GetKeyCode();
    BOOL bForward = !aKeyCode.IsShift();
    if( ( (aKeyCode.IsMod1() || aKeyCode.IsMod2()) && aKeyCode.GetCode() == KEY_TAB )  // Ctrl-TAB or Alt-TAB
        || ( bF6 = ( aKeyCode.GetCode()) == KEY_F6 )    // F6
        )
    {
        bSplitterOnly = bF6 && aKeyCode.IsMod1() && aKeyCode.IsShift();

        // is the focus in the list ?
        ::std::vector< Window* >::iterator p = mTaskPanes.begin();
        while( p != mTaskPanes.end() )
        {
            Window *pWin = *p;
            if( pWin->HasChildPathFocus( TRUE ) )
            {
                bFocusInList = TRUE;

                // Ctrl-TAB does not work in Dialogs
                if( !bF6 && pWin->IsDialog() )
                    return FALSE;

                // Ctrl-F6 goes directly to the document
                if( !pWin->IsDialog() && bF6 && aKeyCode.IsMod1() && !aKeyCode.IsShift() )
                {
                    pWin->GrabFocusToDocument();
                    return TRUE;
                }

                // activate next task pane
                Window *pNextWin = NULL;

                if( bSplitterOnly )
                    pNextWin = FindNextSplitter( *p, TRUE );
                else
                    pNextWin = bF6 ?  FindNextFloat( *p, bForward ) : FindNextPane( *p, bForward );
                if( pNextWin != pWin )
                {
                    ImplGetSVData()->maWinData.mbNoSaveFocus = TRUE;
                    ImplTaskPaneListGrabFocus( pNextWin );
                    ImplGetSVData()->maWinData.mbNoSaveFocus = FALSE;
                }
                else
                {
                    // forward key if no splitter found
                    if( bSplitterOnly )
                        return FALSE;

                    // we did not find another taskpane, so
                    // put focus back into document
                    pWin->GrabFocusToDocument();
                }

                return TRUE;
            }
            else
                p++;
        }

        // the focus is not in the list: activate first float if F6 was pressed
        if( !bFocusInList && bF6 )
        {
            Window *pWin;
            if( bSplitterOnly )
                pWin = FindNextSplitter( NULL, TRUE );
            else
                pWin = FindNextFloat( NULL, bForward );
            if( pWin )
            {
                ImplTaskPaneListGrabFocus( pWin );
                return TRUE;
            }
        }
    }

    return FALSE;
}

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

//  returns next valid pane
Window* TaskPaneList::FindNextPane( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( *p == pWindow )
        {
            unsigned n = mTaskPanes.size();
            while( --n )
            {
                if( ++p == mTaskPanes.end() )
                    p = mTaskPanes.begin();
                if( (*p)->IsReallyVisible() && !(*p)->IsDialog() && !(*p)->ImplIsSplitter() )
                {
                    pWindow = *p;
                    break;
                }
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

// returns next splitter
Window* TaskPaneList::FindNextSplitter( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( !pWindow || *p == pWindow )
        {
            unsigned n = mTaskPanes.size();
            while( --n )
            {
                if( pWindow )   // increment before test
                    ++p;
                if( p == mTaskPanes.end() )
                    p = mTaskPanes.begin();
                if( (*p)->ImplIsSplitter() && (*p)->IsReallyVisible() && !(*p)->IsDialog() && (*p)->GetParent()->HasChildPathFocus() )
                {
                    pWindow = *p;
                    break;
                }
                if( !pWindow )  // increment after test, otherwise first element is skipped
                    ++p;
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

// returns first valid item (regardless of type) if pWindow==0, otherwise returns next valid float
Window* TaskPaneList::FindNextFloat( Window *pWindow, BOOL bForward )
{
    if( bForward )
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
    else
        ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );

    ::std::vector< Window* >::iterator p = mTaskPanes.begin();
    while( p != mTaskPanes.end() )
    {
        if( !pWindow || *p == pWindow )
        {
            while( p != mTaskPanes.end() )
            {
                if( pWindow )   // increment before test
                    ++p;
                if( p == mTaskPanes.end() )
                    break; // do not wrap, send focus back to document at end of list
                if( (*p)->IsReallyVisible() && !(*p)->ImplIsSplitter() )
                {
                    pWindow = *p;
                    break;
                }
                if( !pWindow )  // increment after test, otherwise first element is skipped
                    ++p;
            }
            break;
        }
        else
            ++p;
    }

    return pWindow;
}

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

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_path.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

void SimulateRendererCrash(Browser* browser) {
  browser->OpenURL(GURL(chrome::kAboutCrashURL), GURL(), CURRENT_TAB,
                   PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::TAB_CONTENTS_DISCONNECTED);
}

}  // namespace

class CrashRecoveryBrowserTest : public InProcessBrowserTest {
};

// http://crbug.com/29331 - Causes an OS crash dialog in release mode, needs to
// be fixed before it can be enabled to not cause the bots issues.
#if defined(OS_MACOSX)
#define MAYBE_Reload DISABLED_Reload
#define MAYBE_LoadInNewTab DISABLED_LoadInNewTab
#elif defined(OS_WIN)
// http://crbug.com/57158 - Times out sometimes on windows.
#define MAYBE_LoadInNewTab DISABLED_LoadInNewTab
// http://crbug.com/57183 - Failing on windows.
#define MAYBE_Reload FAILS_Reload
#else
#define MAYBE_Reload Reload
#define MAYBE_LoadInNewTab LoadInNewTab
#endif

// Test that reload works after a crash.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, MAYBE_Reload) {
  // The title of the active tab should change each time this URL is loaded.
  GURL url(
      "data:text/html,<script>document.title=new Date().valueOf()</script>");
  ui_test_utils::NavigateToURL(browser(), url);

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_NE(title_before_crash, title_after_crash);
}

// Tests that loading a crashed page in a new tab correctly updates the title.
// There was an earlier bug (1270510) in process-per-site in which the max page
// ID of the RenderProcessHost was stale, so the NavigationEntry in the new tab
// was not committed.  This prevents regression of that bug.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, MAYBE_LoadInNewTab) {
  const FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html");

  ui_test_utils::NavigateToURL(browser(),
      ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
                                FilePath(kTitle2File)));

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_EQ(title_before_crash, title_after_crash);
}
<commit_msg>Fix CrashRecoveryBrowserTest.MAYBE_Reload on Windows. TBR=satish,phajdan.jr BUG=57183,57158 TEST=none<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_path.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

void SimulateRendererCrash(Browser* browser) {
  browser->OpenURL(GURL(chrome::kAboutCrashURL), GURL(), CURRENT_TAB,
                   PageTransition::TYPED);
  ui_test_utils::WaitForNotification(
      NotificationType::TAB_CONTENTS_DISCONNECTED);
}

}  // namespace

class CrashRecoveryBrowserTest : public InProcessBrowserTest {
};

// http://crbug.com/29331 - Causes an OS crash dialog in release mode, needs to
// be fixed before it can be enabled to not cause the bots issues.
#if defined(OS_MACOSX)
#define MAYBE_Reload DISABLED_Reload
#define MAYBE_LoadInNewTab DISABLED_LoadInNewTab
#elif defined(OS_WIN)
// http://crbug.com/57158 - Times out sometimes on windows.
#define MAYBE_LoadInNewTab DISABLED_LoadInNewTab
#define MAYBE_Reload Reload
#else
#define MAYBE_Reload Reload
#define MAYBE_LoadInNewTab LoadInNewTab
#endif

// Test that reload works after a crash.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, MAYBE_Reload) {
  // The title of the active tab should change each time this URL is loaded.
  GURL url(
      "data:text/html,<script>document.title=new Date().valueOf()</script>");
  ui_test_utils::NavigateToURL(browser(), url);

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_NE(title_before_crash, title_after_crash);
}

// Tests that loading a crashed page in a new tab correctly updates the title.
// There was an earlier bug (1270510) in process-per-site in which the max page
// ID of the RenderProcessHost was stale, so the NavigationEntry in the new tab
// was not committed.  This prevents regression of that bug.
IN_PROC_BROWSER_TEST_F(CrashRecoveryBrowserTest, MAYBE_LoadInNewTab) {
  const FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html");

  ui_test_utils::NavigateToURL(browser(),
      ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
                                FilePath(kTitle2File)));

  string16 title_before_crash;
  string16 title_after_crash;

  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_before_crash));
  SimulateRendererCrash(browser());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(),
                                                &title_after_crash));
  EXPECT_EQ(title_before_crash, title_after_crash);
}
<|endoftext|>


<commit_before><commit_msg>Chromecast: Checks if default codec type is supported<commit_after><|endoftext|>


<commit_before>// This is a personal academic project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* Weapon stuff
*
* License: Mozilla Public License Version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/ OR See accompanying file LICENSE)
* Authors:
*  - Dan Printzell
*/
#include <hydra/component/weaponcomponent.hpp>
#include <hydra/component/rigidbodycomponent.hpp>
#include <hydra/component/cameracomponent.hpp>
#include <btBulletDynamicsCommon.h>
#include <hydra/engine.hpp>

#include <imgui/imgui.h>
#include <glm/gtc/type_ptr.hpp>

using namespace Hydra::World;
using namespace Hydra::Component;

using world = Hydra::World::World;

WeaponComponent::~WeaponComponent() { }

bool WeaponComponent::reload(float delta) {
	if (this->currammo > 0) {

		this->reloadTime += delta;
		//WTF IS THIS
		this->currmagammo = (reloadTime / maxReloadTime) * maxmagammo;
		//WTF IS THIS END
		if (reloadTime >= this->maxReloadTime) {
			reloadTime = 0;
			// ADD AGAIN AFTER REMOVING WTF IS THIS
			//this->currammo += currmagammo;
			if (currammo >= maxmagammo) {
				this->currmagammo = maxmagammo;
				this->currammo -= maxmagammo;
			}
			else {
				this->currmagammo = currammo;
				currammo = 0;
			}
			return false;
		}
		return true;
	}
	return false;
}

void WeaponComponent::resetReload() {
	this->reloadTime = 0;
}

//TODO: (Re)move? to system?
bool WeaponComponent::shoot(glm::vec3 position, glm::vec3 direction, glm::quat bulletOrientation, float velocity) {
	if (fireRateTimer > 0)
		return false;
	// maxmagammo == 0 = sv_infinite_ammo 1
	if (maxmagammo != 0) {
		if (currmagammo == 0) {
			return false;
		}
		currmagammo -= this->ammoPerShot;
	}

	if (bulletSpread == 0.0f) {
		auto bullet = world::newEntity("Bullet", world::rootID);
		bullet->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/SmallCargo.mATTIC");

		auto b = bullet->addComponent<Hydra::Component::BulletComponent>();
		b->direction = direction;
		b->velocity = velocity;
		b->bulletType = bulletType;

		auto t = bullet->addComponent<Hydra::Component::TransformComponent>();
		t->position = position;
		t->scale = glm::vec3(bulletSize);
		t->rotation = bulletOrientation;

		auto bulletPhysWorld = static_cast<Hydra::System::BulletPhysicsSystem*>(IEngine::getInstance()->getState()->getPhysicsSystem());

		auto rbc = bullet->addComponent<Hydra::Component::RigidBodyComponent>();

		rbc->createBox(glm::vec3(0.5f) * t->scale, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE, 0.0095f);
		auto rigidBody = static_cast<btRigidBody*>(rbc->getRigidBody());
		bulletPhysWorld->enable(rbc.get());
		rigidBody->setActivationState(DISABLE_DEACTIVATION);
		rigidBody->applyCentralForce(btVector3(b->direction.x, b->direction.y, b->direction.z) * 300);
		rigidBody->setGravity(btVector3(0, 0, 0));
	} else {
		for (int i = 0; i < bulletsPerShot; i++) {
			auto bullet = world::newEntity("Bullet", world::rootID);
			bullet->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/SmallCargo.mATTIC");

			float phi = ((float)rand() / (float)(RAND_MAX)) * (2.0f*3.14f);
			float distance = ((float)rand() / (float)(RAND_MAX)) * bulletSpread;
			float theta = ((float)rand() / (float)(RAND_MAX)) * 3.14f;

			glm::vec3 bulletDirection = direction;
			bulletDirection.x += distance * sin(theta) * cos(phi);
			bulletDirection.y += distance * sin(theta) * sin(phi);
			bulletDirection.z += distance * cos(theta);
			bulletDirection = glm::normalize(bulletDirection);

			auto b = bullet->addComponent<Hydra::Component::BulletComponent>();
			b->direction = bulletDirection;
			b->velocity = velocity;
			b->bulletType = bulletType;

			auto t = bullet->addComponent<Hydra::Component::TransformComponent>();
			t->position = position;
			t->scale = glm::vec3(bulletSize);
			t->rotation = bulletOrientation;

			auto bulletPhysWorld = static_cast<Hydra::System::BulletPhysicsSystem*>(IEngine::getInstance()->getState()->getPhysicsSystem());

			auto rbc = bullet->addComponent<Hydra::Component::RigidBodyComponent>();
			rbc->createBox(glm::vec3(0.5f) * t->scale, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE, 0.0095f);
			auto rigidBody = static_cast<btRigidBody*>(rbc->getRigidBody());
			bulletPhysWorld->enable(rbc.get());
			rigidBody->setActivationState(DISABLE_DEACTIVATION);
			rigidBody->applyCentralForce(btVector3(b->direction.x, b->direction.y, b->direction.z) * 300);
			rigidBody->setGravity(btVector3(0,0,0));
		}
	}
	fireRateTimer = 1.0f/(fireRateRPM / 60.0f);
	return true;
}

void WeaponComponent::serialize(nlohmann::json& json) const {
	json["fireRateRPM"] = fireRateRPM;
	json["ignoreParent"] = bulletSize;
	json["ignoreParent"] = bulletSpread;
	json["ignoreParent"] = bulletsPerShot;
}

void WeaponComponent::deserialize(nlohmann::json& json) {
	fireRateRPM = json.value<int>("fireRateRPM", 0);
	bulletSize = json.value<float>("bulletSize", 0);
	bulletSpread = json.value<float>("bulletSpread", 0);
	bulletsPerShot = json.value<int>("bulletsPerShot", 0);
}

void WeaponComponent::registerUI() {
	ImGui::DragFloat("Fire Rate RPM", &fireRateRPM);
	ImGui::DragFloat("Bullet Size", &bulletSize, 0.001f);
	ImGui::DragFloat("Bullet Spread", &bulletSpread, 0.001f);
	ImGui::InputInt("Bullets Per Shot", &bulletsPerShot);
	ImGui::InputInt("Magazine", &this->currmagammo);
	ImGui::InputInt("Max Ammo", &this->maxammo);
	ImGui::InputInt("Ammo", &this->currammo);
	ImGui::InputInt("Max Magazine", &this->maxmagammo);
}
<commit_msg>shitty shitty skott<commit_after>// This is a personal academic project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* Weapon stuff
*
* License: Mozilla Public License Version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/ OR See accompanying file LICENSE)
* Authors:
*  - Dan Printzell
*/
#include <hydra/component/weaponcomponent.hpp>
#include <hydra/component/rigidbodycomponent.hpp>
#include <hydra/component/cameracomponent.hpp>
#include <btBulletDynamicsCommon.h>
#include <hydra/engine.hpp>

#include <imgui/imgui.h>
#include <glm/gtc/type_ptr.hpp>

using namespace Hydra::World;
using namespace Hydra::Component;

using world = Hydra::World::World;

WeaponComponent::~WeaponComponent() { }

bool WeaponComponent::reload(float delta) {
	if (this->currmagammo == this->maxmagammo)
		return false;
	if (this->currammo <= 0)
		return false;

	this->reloadTime += delta;
	//WTF IS THIS
	this->currmagammo = (reloadTime / maxReloadTime) * maxmagammo;
	//WTF IS THIS END
	if (reloadTime >= this->maxReloadTime) {
		reloadTime = 0;
		// ADD AGAIN AFTER REMOVING WTF IS THIS
		//this->currammo += currmagammo;
		if (currammo >= maxmagammo) {
			this->currmagammo = maxmagammo;
			this->currammo -= maxmagammo;
		} else {
			this->currmagammo = currammo;
			currammo = 0;
		}
		return false;
	}
	return true;
}

void WeaponComponent::resetReload() {
	this->reloadTime = 0;
}

//TODO: (Re)move? to system?
bool WeaponComponent::shoot(glm::vec3 position, glm::vec3 direction, glm::quat bulletOrientation, float velocity) {
	if (fireRateTimer > 0)
		return false;
	// maxmagammo == 0 = sv_infinite_ammo 1
	if (maxmagammo != 0) {
		if (currmagammo == 0) {
			return false;
		}
		currmagammo -= this->ammoPerShot;
	}

	if (bulletSpread == 0.0f) {
		auto bullet = world::newEntity("Bullet", world::rootID);
		bullet->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/SmallCargo.mATTIC");

		auto b = bullet->addComponent<Hydra::Component::BulletComponent>();
		b->direction = direction;
		b->velocity = velocity;
		b->bulletType = bulletType;

		auto t = bullet->addComponent<Hydra::Component::TransformComponent>();
		t->position = position;
		t->scale = glm::vec3(bulletSize);
		t->rotation = bulletOrientation;

		auto bulletPhysWorld = static_cast<Hydra::System::BulletPhysicsSystem*>(IEngine::getInstance()->getState()->getPhysicsSystem());

		auto rbc = bullet->addComponent<Hydra::Component::RigidBodyComponent>();

		rbc->createBox(glm::vec3(0.5f) * t->scale, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE, 0.0095f);
		auto rigidBody = static_cast<btRigidBody*>(rbc->getRigidBody());
		bulletPhysWorld->enable(rbc.get());
		rigidBody->setActivationState(DISABLE_DEACTIVATION);
		rigidBody->applyCentralForce(btVector3(b->direction.x, b->direction.y, b->direction.z) * 300);
		rigidBody->setGravity(btVector3(0, 0, 0));
	} else {
		for (int i = 0; i < bulletsPerShot; i++) {
			auto bullet = world::newEntity("Bullet", world::rootID);
			bullet->addComponent<Hydra::Component::MeshComponent>()->loadMesh("assets/objects/SmallCargo.mATTIC");

			float phi = ((float)rand() / (float)(RAND_MAX)) * (2.0f*3.14f);
			float distance = ((float)rand() / (float)(RAND_MAX)) * bulletSpread;
			float theta = ((float)rand() / (float)(RAND_MAX)) * 3.14f;

			glm::vec3 bulletDirection = direction;
			bulletDirection.x += distance * sin(theta) * cos(phi);
			bulletDirection.y += distance * sin(theta) * sin(phi);
			bulletDirection.z += distance * cos(theta);
			bulletDirection = glm::normalize(bulletDirection);

			auto b = bullet->addComponent<Hydra::Component::BulletComponent>();
			b->direction = bulletDirection;
			b->velocity = velocity;
			b->bulletType = bulletType;

			auto t = bullet->addComponent<Hydra::Component::TransformComponent>();
			t->position = position;
			t->scale = glm::vec3(bulletSize);
			t->rotation = bulletOrientation;

			auto bulletPhysWorld = static_cast<Hydra::System::BulletPhysicsSystem*>(IEngine::getInstance()->getState()->getPhysicsSystem());

			auto rbc = bullet->addComponent<Hydra::Component::RigidBodyComponent>();
			rbc->createBox(glm::vec3(0.5f) * t->scale, Hydra::System::BulletPhysicsSystem::CollisionTypes::COLL_PLAYER_PROJECTILE, 0.0095f);
			auto rigidBody = static_cast<btRigidBody*>(rbc->getRigidBody());
			bulletPhysWorld->enable(rbc.get());
			rigidBody->setActivationState(DISABLE_DEACTIVATION);
			rigidBody->applyCentralForce(btVector3(b->direction.x, b->direction.y, b->direction.z) * 300);
			rigidBody->setGravity(btVector3(0,0,0));
		}
	}
	fireRateTimer = 1.0f/(fireRateRPM / 60.0f);
	return true;
}

void WeaponComponent::serialize(nlohmann::json& json) const {
	json["fireRateRPM"] = fireRateRPM;
	json["ignoreParent"] = bulletSize;
	json["ignoreParent"] = bulletSpread;
	json["ignoreParent"] = bulletsPerShot;
}

void WeaponComponent::deserialize(nlohmann::json& json) {
	fireRateRPM = json.value<int>("fireRateRPM", 0);
	bulletSize = json.value<float>("bulletSize", 0);
	bulletSpread = json.value<float>("bulletSpread", 0);
	bulletsPerShot = json.value<int>("bulletsPerShot", 0);
}

void WeaponComponent::registerUI() {
	ImGui::DragFloat("Fire Rate RPM", &fireRateRPM);
	ImGui::DragFloat("Bullet Size", &bulletSize, 0.001f);
	ImGui::DragFloat("Bullet Spread", &bulletSpread, 0.001f);
	ImGui::InputInt("Bullets Per Shot", &bulletsPerShot);
	ImGui::InputInt("Magazine", &this->currmagammo);
	ImGui::InputInt("Max Ammo", &this->maxammo);
	ImGui::InputInt("Ammo", &this->currammo);
	ImGui::InputInt("Max Magazine", &this->maxmagammo);
}
<|endoftext|>