<commit_before>/*************************************************************************
 *
 *  $RCSfile: xlescher.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: obo $ $Date: 2004-10-18 15:20:30 $
 *
 *  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 SC_XLESCHER_HXX
#define SC_XLESCHER_HXX

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _VCL_MAPUNIT_HXX
#include <vcl/mapunit.hxx>
#endif

// Constants and Enumerations =================================================

// misc -----------------------------------------------------------------------

const long EXC_ESCHER_AUTOMARGIN            = 20000;    /// Automatic text margin.

// (0x001C) NOTE --------------------------------------------------------------

const sal_uInt16 EXC_ID_NOTE                = 0x001C;
const sal_uInt16 EXC_NOTE_VISIBLE           = 0x0002;
const sal_uInt16 EXC_NOTE5_MAXLEN           = 2048;

// (0x005D) OBJ ---------------------------------------------------------------

const sal_uInt16 EXC_ID_OBJ                 = 0x005D;

const sal_uInt16 EXC_OBJ_INVALID_ID         = 0x0000;

// sub records
const sal_uInt16 EXC_ID_OBJ_FTEND           = 0x0000;   /// End of OBJ.
const sal_uInt16 EXC_ID_OBJ_FTGMO           = 0x0006;   /// Group marker.
const sal_uInt16 EXC_ID_OBJ_FTCF            = 0x0007;   /// Clipboard format.
const sal_uInt16 EXC_ID_OBJ_FTPIOGRBIT      = 0x0008;   /// Option flags.
const sal_uInt16 EXC_ID_OBJ_FTPICTFMLA      = 0x0009;   /// OLE link formula.
const sal_uInt16 EXC_ID_OBJ_FTCBLS          = 0x000A;   /// Check box/radio button data.
const sal_uInt16 EXC_ID_OBJ_FTSBS           = 0x000C;   /// Scroll bar data.
const sal_uInt16 EXC_ID_OBJ_FTSBSFMLA       = 0x000E;   /// Scroll bar/list box/combo box cell link.
const sal_uInt16 EXC_ID_OBJ_FTGBODATA       = 0x000F;   /// Group box data.
const sal_uInt16 EXC_ID_OBJ_FTLBSDATA       = 0x0013;   /// List box/combo box data.
const sal_uInt16 EXC_ID_OBJ_FTCBLSFMLA      = 0x0014;   /// Check box/radio button cell link.
const sal_uInt16 EXC_ID_OBJ_FTCMO           = 0x0015;   /// Common object settings.
const sal_uInt16 EXC_ID_OBJ_FTUNKNOWN       = 0xFFFF;   /// For internal use only.

// ftCmo: object types
const sal_uInt16 EXC_OBJ_CMO_GROUP          = 0x0000;
const sal_uInt16 EXC_OBJ_CMO_LINE           = 0x0001;
const sal_uInt16 EXC_OBJ_CMO_RECTANGLE      = 0x0002;
const sal_uInt16 EXC_OBJ_CMO_ELLIPSE        = 0x0003;
const sal_uInt16 EXC_OBJ_CMO_ARC            = 0x0004;
const sal_uInt16 EXC_OBJ_CMO_CHART          = 0x0005;
const sal_uInt16 EXC_OBJ_CMO_TEXT           = 0x0006;
const sal_uInt16 EXC_OBJ_CMO_BUTTON         = 0x0007;
const sal_uInt16 EXC_OBJ_CMO_PICTURE        = 0x0008;
const sal_uInt16 EXC_OBJ_CMO_POLYGON        = 0x0009;
const sal_uInt16 EXC_OBJ_CMO_CHECKBOX       = 0x000B;
const sal_uInt16 EXC_OBJ_CMO_OPTIONBUTTON   = 0x000C;
const sal_uInt16 EXC_OBJ_CMO_EDIT           = 0x000D;
const sal_uInt16 EXC_OBJ_CMO_LABEL          = 0x000E;
const sal_uInt16 EXC_OBJ_CMO_DIALOG         = 0x000F;
const sal_uInt16 EXC_OBJ_CMO_SPIN           = 0x0010;
const sal_uInt16 EXC_OBJ_CMO_SCROLLBAR      = 0x0011;
const sal_uInt16 EXC_OBJ_CMO_LISTBOX        = 0x0012;
const sal_uInt16 EXC_OBJ_CMO_GROUPBOX       = 0x0013;
const sal_uInt16 EXC_OBJ_CMO_COMBOBOX       = 0x0014;
const sal_uInt16 EXC_OBJ_CMO_NOTE           = 0x0019;
const sal_uInt16 EXC_OBJ_CMO_DRAWING        = 0x001E;
const sal_uInt16 EXC_OBJ_CMO_UNKNOWN        = 0xFFFF;   /// For internal use only.

// ftCmoGrbit: flags
const sal_uInt16 EXC_OBJ_CMO_PRINTABLE      = 0x0010;   /// Object printable

// ftPioGrbit: flags
const sal_uInt16 EXC_OBJ_PIO_LINKED         = 0x0002;
const sal_uInt16 EXC_OBJ_PIO_SYMBOL         = 0x0008;

// ftCbls: Check box/radio button data
const sal_uInt16 EXC_OBJ_CBLS_STATEMASK     = 0x0003;
const sal_uInt16 EXC_OBJ_CBLS_STATE_UNCHECK = 0x0000;
const sal_uInt16 EXC_OBJ_CBLS_STATE_CHECK   = 0x0001;
const sal_uInt16 EXC_OBJ_CBLS_STATE_TRI     = 0x0002;
const sal_uInt16 EXC_OBJ_CBLS_FLAT          = 0x0001;

// ftGboData: Group box data
const sal_uInt16 EXC_OBJ_GBO_FLAT           = 0x0001;

// ftLbsData: List box data
const sal_uInt16 EXC_OBJ_LBS_SELMASK        = 0x0030;
const sal_uInt16 EXC_OBJ_LBS_SEL_SIMPLE     = 0x0000;   /// Simple selection.
const sal_uInt16 EXC_OBJ_LBS_SEL_MULTI      = 0x0010;   /// Multi selection.
const sal_uInt16 EXC_OBJ_LBS_SEL_EXT        = 0x0020;   /// Extended selection.
const sal_uInt16 EXC_OBJ_LBS_FLAT           = 0x0008;

// ftSbs: Spin button/scrollbar data
const sal_uInt16 EXC_OBJ_SBS_HORIZONTAL     = 0x0001;
const sal_uInt16 EXC_OBJ_SBS_DEFAULTFLAGS   = 0x0001;
const sal_uInt16 EXC_OBJ_SBS_FLAT           = 0x0008;
const sal_Int16 EXC_OBJ_SBS_MINSCROLL       = 0;
const sal_Int16 EXC_OBJ_SBS_MAXSCROLL       = 30000;

/** Value binding mode for cells linked to form controls. */
enum XclCtrlBindMode
{
    xlBindContent,      /// Binds cell to content of control.
    xlBindPosition      /// Binds cell to position in control (i.e. listbox selection index).
};

// (0x00EC) MSODRAWING --------------------------------------------------------

const sal_uInt16 EXC_ID_MSODRAWING          = 0x00EC;

// additional flags not extant in svx headers
const sal_uInt16 EXC_ESC_ANCHOR_POSLOCKED   = 0x0001;
const sal_uInt16 EXC_ESC_ANCHOR_SIZELOCKED  = 0x0002;
const sal_uInt16 EXC_ESC_ANCHOR_LOCKED      = EXC_ESC_ANCHOR_POSLOCKED|EXC_ESC_ANCHOR_SIZELOCKED;

// (0x01B6) TXO ---------------------------------------------------------------

const sal_uInt16 EXC_ID_TXO                 = 0x01B6;

/** Horizontal alignment flags. */
enum XclTxoHorAlign
{
    xlTxoHAlignLeft                         = 0x01,
    xlTxoHAlignCenter                       = 0x02,
    xlTxoHAlignRight                        = 0x03,
    xlTxoHAlignJustify                      = 0x04,
    xlTxoHAlign_Default                     = xlTxoHAlignLeft
};

/** Vertical alignment flags. */
enum XclTxoVerAlign
{
    xlTxoVAlignTop                          = 0x01,
    xlTxoVAlignCenter                       = 0x02,
    xlTxoVAlignBottom                       = 0x03,
    xlTxoVAlignJustify                      = 0x04,
    xlTxoVAlign_Default                     = xlTxoVAlignTop
};

/** Rotation. */
enum XclTxoRotation
{
    xlTxoNoRot                              = 0x0000,       /// Not rotated.
    xlTxoRotStacked                         = 0x0001,       /// characters stacked.
    xlTxoRot90ccw                           = 0x0002,       /// 90 degr. counterclockwise.
    xlTxoRot90cw                            = 0x0003,       /// 90 degr. clockwise.
    xlTxoRot_Default                        = xlTxoNoRot
};

// Structs and classes ========================================================

// Escher client anchor =======================================================

class Rectangle;
class ScDocument;
class SvStream;
class XclImpStream;
class XclExpStream;

/** Represents the position (anchor) of an Escher object in a Calc document. */
struct XclEscherAnchor
{
    sal_uInt16          mnLCol;     /// Left column index.
    sal_uInt16          mnLX;       /// X offset in left column (1/1024 of column width).
    sal_uInt16          mnTRow;     /// Top row index.
    sal_uInt16          mnTY;       /// Y offset in top row (1/256 of row height).
    sal_uInt16          mnRCol;     /// Right column index.
    sal_uInt16          mnRX;       /// X offset in right column (1/1024 of column width).
    sal_uInt16          mnBRow;     /// Bottom row index.
    sal_uInt16          mnBY;       /// Y offset in bottom row (1/256 of row height).
    SCTAB               mnScTab;    /// Calc sheet index.

    explicit            XclEscherAnchor( SCTAB nScTab );

    /** Calculates a rectangle from the contained coordinates. */
    Rectangle           GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const;
    /** Initializes the anchor coordinates from a rectangle. */
    void                SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit );
};

SvStream& operator>>( SvStream& rStrm, XclEscherAnchor& rAnchor );
SvStream& operator<<( SvStream& rStrm, const XclEscherAnchor& rAnchor );

XclImpStream& operator>>( XclImpStream& rStrm, XclEscherAnchor& rAnchor );
XclExpStream& operator<<( XclExpStream& rStrm, const XclEscherAnchor& rAnchor );

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

#endif

<commit_msg>INTEGRATION: CWS dr31 (1.12.88); FILE MERGED 2005/01/06 16:29:59 dr 1.12.88.2: #i39464# autofilter import/export 2004/12/09 09:04:41 dr 1.12.88.1: #i37965# import/export of control<->macro links, code cleanup<commit_after>/*************************************************************************
 *
 *  $RCSfile: xlescher.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-14 12:12:52 $
 *
 *  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 SC_XLESCHER_HXX
#define SC_XLESCHER_HXX

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
#ifndef _VCL_MAPUNIT_HXX
#include <vcl/mapunit.hxx>
#endif

// Constants and Enumerations =================================================

// misc -----------------------------------------------------------------------

const long EXC_ESCHER_AUTOMARGIN            = 20000;    /// Automatic text margin.

// (0x001C) NOTE --------------------------------------------------------------

const sal_uInt16 EXC_ID_NOTE                = 0x001C;
const sal_uInt16 EXC_NOTE_VISIBLE           = 0x0002;
const sal_uInt16 EXC_NOTE5_MAXLEN           = 2048;

// (0x005D) OBJ ---------------------------------------------------------------

const sal_uInt16 EXC_ID_OBJ                 = 0x005D;

const sal_uInt16 EXC_OBJ_INVALID_ID         = 0x0000;

// sub records
const sal_uInt16 EXC_ID_OBJ_FTEND           = 0x0000;   /// End of OBJ.
const sal_uInt16 EXC_ID_OBJ_FTMACRO         = 0x0004;   /// Macro link.
const sal_uInt16 EXC_ID_OBJ_FTGMO           = 0x0006;   /// Group marker.
const sal_uInt16 EXC_ID_OBJ_FTCF            = 0x0007;   /// Clipboard format.
const sal_uInt16 EXC_ID_OBJ_FTPIOGRBIT      = 0x0008;   /// Option flags.
const sal_uInt16 EXC_ID_OBJ_FTPICTFMLA      = 0x0009;   /// OLE link formula.
const sal_uInt16 EXC_ID_OBJ_FTCBLS          = 0x000A;   /// Check box/radio button data.
const sal_uInt16 EXC_ID_OBJ_FTSBS           = 0x000C;   /// Scroll bar data.
const sal_uInt16 EXC_ID_OBJ_FTSBSFMLA       = 0x000E;   /// Scroll bar/list box/combo box cell link.
const sal_uInt16 EXC_ID_OBJ_FTGBODATA       = 0x000F;   /// Group box data.
const sal_uInt16 EXC_ID_OBJ_FTLBSDATA       = 0x0013;   /// List box/combo box data.
const sal_uInt16 EXC_ID_OBJ_FTCBLSFMLA      = 0x0014;   /// Check box/radio button cell link.
const sal_uInt16 EXC_ID_OBJ_FTCMO           = 0x0015;   /// Common object settings.
const sal_uInt16 EXC_ID_OBJ_FTUNKNOWN       = 0xFFFF;   /// For internal use only.

// ftCmo: object types
const sal_uInt16 EXC_OBJ_CMO_GROUP          = 0x0000;
const sal_uInt16 EXC_OBJ_CMO_LINE           = 0x0001;
const sal_uInt16 EXC_OBJ_CMO_RECTANGLE      = 0x0002;
const sal_uInt16 EXC_OBJ_CMO_ELLIPSE        = 0x0003;
const sal_uInt16 EXC_OBJ_CMO_ARC            = 0x0004;
const sal_uInt16 EXC_OBJ_CMO_CHART          = 0x0005;
const sal_uInt16 EXC_OBJ_CMO_TEXT           = 0x0006;
const sal_uInt16 EXC_OBJ_CMO_BUTTON         = 0x0007;
const sal_uInt16 EXC_OBJ_CMO_PICTURE        = 0x0008;
const sal_uInt16 EXC_OBJ_CMO_POLYGON        = 0x0009;
const sal_uInt16 EXC_OBJ_CMO_CHECKBOX       = 0x000B;
const sal_uInt16 EXC_OBJ_CMO_OPTIONBUTTON   = 0x000C;
const sal_uInt16 EXC_OBJ_CMO_EDIT           = 0x000D;
const sal_uInt16 EXC_OBJ_CMO_LABEL          = 0x000E;
const sal_uInt16 EXC_OBJ_CMO_DIALOG         = 0x000F;
const sal_uInt16 EXC_OBJ_CMO_SPIN           = 0x0010;
const sal_uInt16 EXC_OBJ_CMO_SCROLLBAR      = 0x0011;
const sal_uInt16 EXC_OBJ_CMO_LISTBOX        = 0x0012;
const sal_uInt16 EXC_OBJ_CMO_GROUPBOX       = 0x0013;
const sal_uInt16 EXC_OBJ_CMO_COMBOBOX       = 0x0014;
const sal_uInt16 EXC_OBJ_CMO_NOTE           = 0x0019;
const sal_uInt16 EXC_OBJ_CMO_DRAWING        = 0x001E;
const sal_uInt16 EXC_OBJ_CMO_UNKNOWN        = 0xFFFF;   /// For internal use only.

// ftCmoGrbit: flags
const sal_uInt16 EXC_OBJ_CMO_PRINTABLE      = 0x0010;   /// Object printable

// ftPioGrbit: flags
const sal_uInt16 EXC_OBJ_PIO_LINKED         = 0x0002;
const sal_uInt16 EXC_OBJ_PIO_SYMBOL         = 0x0008;

// ftCbls: Check box/radio button data
const sal_uInt16 EXC_OBJ_CBLS_STATEMASK     = 0x0003;
const sal_uInt16 EXC_OBJ_CBLS_STATE_UNCHECK = 0x0000;
const sal_uInt16 EXC_OBJ_CBLS_STATE_CHECK   = 0x0001;
const sal_uInt16 EXC_OBJ_CBLS_STATE_TRI     = 0x0002;
const sal_uInt16 EXC_OBJ_CBLS_FLAT          = 0x0001;

// ftGboData: Group box data
const sal_uInt16 EXC_OBJ_GBO_FLAT           = 0x0001;

// ftLbsData: List box data
const sal_uInt16 EXC_OBJ_LBS_SELMASK        = 0x0030;   /// Mask for selection type.
const sal_uInt16 EXC_OBJ_LBS_SEL_SIMPLE     = 0x0000;   /// Simple selection.
const sal_uInt16 EXC_OBJ_LBS_SEL_MULTI      = 0x0010;   /// Multi selection.
const sal_uInt16 EXC_OBJ_LBS_SEL_EXT        = 0x0020;   /// Extended selection.
const sal_uInt16 EXC_OBJ_LBS_FLAT           = 0x0008;
const sal_uInt16 EXC_OBJ_LBS_COMBOMASK      = 0x0003;   /// Mask for combobox style.
const sal_uInt16 EXC_OBJ_LBS_COMBO_STD      = 0x0000;   /// Standard combo box.
const sal_uInt16 EXC_OBJ_LBS_COMBO_SIMPLE   = 0x0002;   /// Simple dropdown without field.
const sal_uInt16 EXC_OBJ_LBS_FILTERED       = 0x0008;   /// Drowdown style: filtered.

// ftSbs: Spin button/scrollbar data
const sal_uInt16 EXC_OBJ_SBS_HORIZONTAL     = 0x0001;
const sal_uInt16 EXC_OBJ_SBS_DEFAULTFLAGS   = 0x0001;
const sal_uInt16 EXC_OBJ_SBS_FLAT           = 0x0008;
const sal_Int16 EXC_OBJ_SBS_MINSCROLL       = 0;
const sal_Int16 EXC_OBJ_SBS_MAXSCROLL       = 30000;

/** Value binding mode for cells linked to form controls. */
enum XclCtrlBindMode
{
    xlBindContent,      /// Binds cell to content of control.
    xlBindPosition      /// Binds cell to position in control (i.e. listbox selection index).
};

// (0x00EC) MSODRAWING --------------------------------------------------------

const sal_uInt16 EXC_ID_MSODRAWING          = 0x00EC;

// additional flags not extant in svx headers
const sal_uInt16 EXC_ESC_ANCHOR_POSLOCKED   = 0x0001;
const sal_uInt16 EXC_ESC_ANCHOR_SIZELOCKED  = 0x0002;
const sal_uInt16 EXC_ESC_ANCHOR_LOCKED      = EXC_ESC_ANCHOR_POSLOCKED|EXC_ESC_ANCHOR_SIZELOCKED;

// (0x01B6) TXO ---------------------------------------------------------------

const sal_uInt16 EXC_ID_TXO                 = 0x01B6;

/** Horizontal alignment flags. */
enum XclTxoHorAlign
{
    xlTxoHAlignLeft                         = 0x01,
    xlTxoHAlignCenter                       = 0x02,
    xlTxoHAlignRight                        = 0x03,
    xlTxoHAlignJustify                      = 0x04,
    xlTxoHAlign_Default                     = xlTxoHAlignLeft
};

/** Vertical alignment flags. */
enum XclTxoVerAlign
{
    xlTxoVAlignTop                          = 0x01,
    xlTxoVAlignCenter                       = 0x02,
    xlTxoVAlignBottom                       = 0x03,
    xlTxoVAlignJustify                      = 0x04,
    xlTxoVAlign_Default                     = xlTxoVAlignTop
};

/** Rotation. */
enum XclTxoRotation
{
    xlTxoNoRot                              = 0x0000,       /// Not rotated.
    xlTxoRotStacked                         = 0x0001,       /// characters stacked.
    xlTxoRot90ccw                           = 0x0002,       /// 90 degr. counterclockwise.
    xlTxoRot90cw                            = 0x0003,       /// 90 degr. clockwise.
    xlTxoRot_Default                        = xlTxoNoRot
};

// Structs and classes ========================================================

// Escher client anchor =======================================================

class Rectangle;
class ScDocument;
class SvStream;
class XclImpStream;
class XclExpStream;

/** Represents the position (anchor) of an Escher object in a Calc document. */
struct XclEscherAnchor
{
    sal_uInt16          mnLCol;     /// Left column index.
    sal_uInt16          mnLX;       /// X offset in left column (1/1024 of column width).
    sal_uInt16          mnTRow;     /// Top row index.
    sal_uInt16          mnTY;       /// Y offset in top row (1/256 of row height).
    sal_uInt16          mnRCol;     /// Right column index.
    sal_uInt16          mnRX;       /// X offset in right column (1/1024 of column width).
    sal_uInt16          mnBRow;     /// Bottom row index.
    sal_uInt16          mnBY;       /// Y offset in bottom row (1/256 of row height).
    SCTAB               mnScTab;    /// Calc sheet index.

    explicit            XclEscherAnchor( SCTAB nScTab );

    /** Calculates a rectangle from the contained coordinates. */
    Rectangle           GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const;
    /** Initializes the anchor coordinates from a rectangle. */
    void                SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit );
};

SvStream& operator>>( SvStream& rStrm, XclEscherAnchor& rAnchor );
SvStream& operator<<( SvStream& rStrm, const XclEscherAnchor& rAnchor );

XclImpStream& operator>>( XclImpStream& rStrm, XclEscherAnchor& rAnchor );
XclExpStream& operator<<( XclExpStream& rStrm, const XclEscherAnchor& rAnchor );

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

/** Provides static helper functions for textbox (TBX) form controls. */
class XclTbxControlHelper
{
public:
    /** Returns the component service name for the passed control type. */
    static ::rtl::OUString GetServiceName( sal_uInt16 nCtrlType );
    /** Returns a default control name for the passed control type. */
    static ::rtl::OUString GetControlName( sal_uInt16 nCtrlType );

    /** Returns the listener type (interface name) for macro events for the passed control type. */
    static ::rtl::OUString GetListenerType( sal_uInt16 nCtrlType );
    /** Returns the event method (function name) for macro events for the passed control type. */
    static ::rtl::OUString GetEventMethod( sal_uInt16 nCtrlType );
    /** Returns the script type string needed for a script event descriptor. */
    static ::rtl::OUString GetScriptType();

    /** Returns the Calc macro name from an Excel macro name. */
    static ::rtl::OUString GetScMacroName( const String& rXclMacroName );
    /** Returns the Excel macro name from a Calc macro name. */
    static String       GetXclMacroName( const ::rtl::OUString& rScMacroName );
};

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

#endif

<|endoftext|>


<commit_before><commit_msg>Remove array bounds warning (searchlib, take 2)<commit_after><|endoftext|>


<commit_before>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2022 INRIA.
 *
 * 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 "BulletUtils.hpp"

#define DEBUG_STDOUT
#define DEBUG_MESSAGES 1
#include "siconos_debug.h"

#include <BulletCollision/GImpact/btGImpactShape.h>
#include "BulletCollision/CollisionShapes/btConvex2dShape.h"
void display_info_collision_object(const btCollisionObject* collisionObject)
{

  printf("---- collision_object \n");

  const btCollisionShape* collisionShape = collisionObject->getCollisionShape();
  printf("collisionShape : %p\n", collisionShape);
  printf("collisionShape->getShapeType(): %i\n", collisionShape->getShapeType());
  printf("collisionShape->getName(): %s\n", collisionShape->getName());

  if (collisionShape->isPolyhedral())
  {
    printf("isPolyhedral() true \n");
  }
  else
    printf("isPolyhedral() false \n");

  if (collisionShape->getShapeType() == 25)
  {
    printf("GImpactMesh shape type\n");
    btGImpactMeshShape * gimpact_mesh_shape = (btGImpactMeshShape *)collisionShape;
    btStridingMeshInterface * striding_mesh = gimpact_mesh_shape->getMeshInterface();
    btTriangleIndexVertexArray * triangle_mesh = (btTriangleIndexVertexArray *) striding_mesh;
    IndexedMeshArray& mesh_array =  triangle_mesh->getIndexedMeshArray();
    for (int i =0; i < triangle_mesh->getNumSubParts(); i++)
    {
      printf(" mesh_array[%i] : number of triangles = %i\n", i, mesh_array[i].m_numTriangles);
      int * triangleIndexBase = (int*) mesh_array[i].m_triangleIndexBase;
      int k =0;
      for (int t =0; t < mesh_array[i].m_numTriangles; t++)
      {
        printf("              vertex indices  of triangle %i : %i\t %i\t %i\n", t, triangleIndexBase[k], triangleIndexBase[k+1],triangleIndexBase[k+2]);
        k=k+3;
      }
      printf("               : number of vertices = %i\n", mesh_array[i].m_numVertices);
      btScalar * vertexBase = (btScalar*) mesh_array[i].m_vertexBase;
      k =0;
      for (int v =0; v < mesh_array[i].m_numVertices; v++)
      {
        printf("              vertices  %i : %e\t %e\t %e\n", v, vertexBase[k], vertexBase[k+1], vertexBase[k+2]);
        k=k+3;
      }
    }
    printf("gimpact_mesh_shape->getMeshPartCount() = % i \n", gimpact_mesh_shape->getMeshPartCount());
    for (int mesh_part_index=0; mesh_part_index < gimpact_mesh_shape->getMeshPartCount(); mesh_part_index++ )
    {
      btGImpactMeshShapePart* mesh_part =gimpact_mesh_shape->getMeshPart(mesh_part_index);
    }
  }
  if (collisionShape->getShapeType() == CONVEX_2D_SHAPE_PROXYTYPE)
  {
    printf("CONVEX_2D_SHAPE_PROXYTYPE shape type\n");
    btConvex2dShape*  btConvex2d = (btConvex2dShape*)collisionShape;
    btConvexShape * btconvexchild = (btConvexShape *) (btConvex2d->getChildShape());

    printf("btconvexchild->getShapeType(): %i\n", btconvexchild->getShapeType());
    printf("btconvexchild->getName(): %s\n", btconvexchild->getName());

    if(btconvexchild->getShapeType() ==  CONVEX_HULL_SHAPE_PROXYTYPE)
    {
      btConvexHullShape * btch = (btConvexHullShape *) btconvexchild;
      display_info_btConvexHullShape(*btch);
    }
  }
  //getchar();
}

void display_info_manifold(const btPersistentManifold& manifold)
{

  printf("-------- manifold : %p\n",  &manifold);

  const btCollisionObject* body0 = manifold.getBody0();
  printf("-------- m_body0 : %p\n", body0);
  display_info_collision_object(body0);

  const btCollisionObject* body1 = manifold.getBody1();
  printf("-------- m_body1 : %p\n", body1);
  display_info_collision_object(body1);

  printf("Number of contact points (m_cachedPoints) =%i \n", manifold.getNumContacts());
  for (int index =0; index < manifold.getNumContacts(); index++)
  {
    const btManifoldPoint& point =  manifold.getContactPoint(index);
    display_info_contact_point(point);
  }
}
void display_info_contact_point(const btManifoldPoint& cp)
{
  printf("   --------- contact point: %p \n", &cp);
  printf("   m_partId0: %i  m_index0 : %i \n", cp.m_partId0, cp.m_index0);

  btVector3  lpA = cp.m_localPointA;
  printf("   lpA x , y, x : %e\t, %e\t, %e\t \n", lpA.x(), lpA.y(), lpA.z());
  btVector3  lpB = cp.m_localPointB;
  printf("   lpB x , y, x : %e\t, %e\t, %e\t \n", lpB.x(), lpB.y(), lpB.z());

  btVector3  pA = cp.m_positionWorldOnA;
  printf("   pA x , y, x : %e\t, %e\t, %e\t \n", pA.x(), pA.y(), pA.z());
  btVector3  pB = cp.m_positionWorldOnB;
  printf("   pB x , y, x : %e\t, %e\t, %e\t \n", pB.x(), pB.y(), pB.z());

  btVector3  normalOnB =  	cp.m_normalWorldOnB;
  printf("   normalOnB x , y, x : %e\t, %e\t, %e\t \n", normalOnB.x(), normalOnB.y(), normalOnB.z());
  printf("   distance1 = %e\n", cp.m_distance1);
  printf("\n");

}
void display_info_btConvexHullShape(const btConvexHullShape& btch)
{
  int numPoints= btch.getNumPoints();
  printf("   number of points in convex hull shape: %i\n", numPoints);
  int numVertices = btch.getNumVertices();
  int numEdges = btch.getNumVertices();
  int numPlanes = btch.getNumPlanes();
  printf("   number of vertices: %i \t, edge: %i\t, planes: %i\n",numVertices, numEdges, numPlanes );
  const btVector3* points = btch.getPoints();
  for (int p = 0 ; p < numPoints; p++)
  {
    printf("   point # %i x , y, z : %e\t, %e\t, %e\t \n", p,  points[p].x(), points[p].y(), points[p].z());
  }

}
<commit_msg>[mechanics] fix typo case insentitive<commit_after>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2022 INRIA.
 *
 * 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 "BulletUtils.hpp"

#define DEBUG_STDOUT
#define DEBUG_MESSAGES 1
#include "siconos_debug.h"

#include <BulletCollision/Gimpact/btGImpactShape.h>
#include "BulletCollision/CollisionShapes/btConvex2dShape.h"
void display_info_collision_object(const btCollisionObject* collisionObject)
{

  printf("---- collision_object \n");

  const btCollisionShape* collisionShape = collisionObject->getCollisionShape();
  printf("collisionShape : %p\n", collisionShape);
  printf("collisionShape->getShapeType(): %i\n", collisionShape->getShapeType());
  printf("collisionShape->getName(): %s\n", collisionShape->getName());

  if (collisionShape->isPolyhedral())
  {
    printf("isPolyhedral() true \n");
  }
  else
    printf("isPolyhedral() false \n");

  if (collisionShape->getShapeType() == 25)
  {
    printf("GImpactMesh shape type\n");
    btGImpactMeshShape * gimpact_mesh_shape = (btGImpactMeshShape *)collisionShape;
    btStridingMeshInterface * striding_mesh = gimpact_mesh_shape->getMeshInterface();
    btTriangleIndexVertexArray * triangle_mesh = (btTriangleIndexVertexArray *) striding_mesh;
    IndexedMeshArray& mesh_array =  triangle_mesh->getIndexedMeshArray();
    for (int i =0; i < triangle_mesh->getNumSubParts(); i++)
    {
      printf(" mesh_array[%i] : number of triangles = %i\n", i, mesh_array[i].m_numTriangles);
      int * triangleIndexBase = (int*) mesh_array[i].m_triangleIndexBase;
      int k =0;
      for (int t =0; t < mesh_array[i].m_numTriangles; t++)
      {
        printf("              vertex indices  of triangle %i : %i\t %i\t %i\n", t, triangleIndexBase[k], triangleIndexBase[k+1],triangleIndexBase[k+2]);
        k=k+3;
      }
      printf("               : number of vertices = %i\n", mesh_array[i].m_numVertices);
      btScalar * vertexBase = (btScalar*) mesh_array[i].m_vertexBase;
      k =0;
      for (int v =0; v < mesh_array[i].m_numVertices; v++)
      {
        printf("              vertices  %i : %e\t %e\t %e\n", v, vertexBase[k], vertexBase[k+1], vertexBase[k+2]);
        k=k+3;
      }
    }
    printf("gimpact_mesh_shape->getMeshPartCount() = % i \n", gimpact_mesh_shape->getMeshPartCount());
    for (int mesh_part_index=0; mesh_part_index < gimpact_mesh_shape->getMeshPartCount(); mesh_part_index++ )
    {
      btGImpactMeshShapePart* mesh_part =gimpact_mesh_shape->getMeshPart(mesh_part_index);
    }
  }
  if (collisionShape->getShapeType() == CONVEX_2D_SHAPE_PROXYTYPE)
  {
    printf("CONVEX_2D_SHAPE_PROXYTYPE shape type\n");
    btConvex2dShape*  btConvex2d = (btConvex2dShape*)collisionShape;
    btConvexShape * btconvexchild = (btConvexShape *) (btConvex2d->getChildShape());

    printf("btconvexchild->getShapeType(): %i\n", btconvexchild->getShapeType());
    printf("btconvexchild->getName(): %s\n", btconvexchild->getName());

    if(btconvexchild->getShapeType() ==  CONVEX_HULL_SHAPE_PROXYTYPE)
    {
      btConvexHullShape * btch = (btConvexHullShape *) btconvexchild;
      display_info_btConvexHullShape(*btch);
    }
  }
  //getchar();
}

void display_info_manifold(const btPersistentManifold& manifold)
{

  printf("-------- manifold : %p\n",  &manifold);

  const btCollisionObject* body0 = manifold.getBody0();
  printf("-------- m_body0 : %p\n", body0);
  display_info_collision_object(body0);

  const btCollisionObject* body1 = manifold.getBody1();
  printf("-------- m_body1 : %p\n", body1);
  display_info_collision_object(body1);

  printf("Number of contact points (m_cachedPoints) =%i \n", manifold.getNumContacts());
  for (int index =0; index < manifold.getNumContacts(); index++)
  {
    const btManifoldPoint& point =  manifold.getContactPoint(index);
    display_info_contact_point(point);
  }
}
void display_info_contact_point(const btManifoldPoint& cp)
{
  printf("   --------- contact point: %p \n", &cp);
  printf("   m_partId0: %i  m_index0 : %i \n", cp.m_partId0, cp.m_index0);

  btVector3  lpA = cp.m_localPointA;
  printf("   lpA x , y, x : %e\t, %e\t, %e\t \n", lpA.x(), lpA.y(), lpA.z());
  btVector3  lpB = cp.m_localPointB;
  printf("   lpB x , y, x : %e\t, %e\t, %e\t \n", lpB.x(), lpB.y(), lpB.z());

  btVector3  pA = cp.m_positionWorldOnA;
  printf("   pA x , y, x : %e\t, %e\t, %e\t \n", pA.x(), pA.y(), pA.z());
  btVector3  pB = cp.m_positionWorldOnB;
  printf("   pB x , y, x : %e\t, %e\t, %e\t \n", pB.x(), pB.y(), pB.z());

  btVector3  normalOnB =  	cp.m_normalWorldOnB;
  printf("   normalOnB x , y, x : %e\t, %e\t, %e\t \n", normalOnB.x(), normalOnB.y(), normalOnB.z());
  printf("   distance1 = %e\n", cp.m_distance1);
  printf("\n");

}
void display_info_btConvexHullShape(const btConvexHullShape& btch)
{
  int numPoints= btch.getNumPoints();
  printf("   number of points in convex hull shape: %i\n", numPoints);
  int numVertices = btch.getNumVertices();
  int numEdges = btch.getNumVertices();
  int numPlanes = btch.getNumPlanes();
  printf("   number of vertices: %i \t, edge: %i\t, planes: %i\n",numVertices, numEdges, numPlanes );
  const btVector3* points = btch.getPoints();
  for (int p = 0 ; p < numPoints; p++)
  {
    printf("   point # %i x , y, z : %e\t, %e\t, %e\t \n", p,  points[p].x(), points[p].y(), points[p].z());
  }

}
<|endoftext|>


<commit_before>
#include "ksp_plugin/pile_up.hpp"

#include <list>
#include <map>

#include "geometry/identity.hpp"
#include "ksp_plugin/part.hpp"
#include "physics/rigid_motion.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_pile_up {

using base::FindOrDie;
using base::make_not_null_unique;
using geometry::AngularVelocity;
using geometry::BarycentreCalculator;
using geometry::Identity;
using geometry::OrthogonalMap;
using geometry::Position;
using geometry::Velocity;
using physics::DegreesOfFreedom;
using physics::RigidMotion;
using physics::RigidTransformation;

PileUp::PileUp(std::list<not_null<Part*>>&& parts, Instant const& t)
    : parts_(std::move(parts)),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {
  BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
  Vector<Force, Barycentric> total_intrinsic_force;
  for (not_null<Part*> const part : parts_) {
    total_intrinsic_force += part->intrinsic_force();
    calculator.Add(part->degrees_of_freedom(), part->mass());
  }
  mass_ = calculator.weight();
  intrinsic_force_ = total_intrinsic_force;
  DegreesOfFreedom<Barycentric> const barycentre = calculator.Get();
  psychohistory_->Append(t, barycentre);

  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up{
      RigidTransformation<Barycentric, RigidPileUp>{
          barycentre.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()},
      AngularVelocity<Barycentric>{},
      barycentre.velocity()};
  for (not_null<Part*> const part : parts_) {
    actual_part_degrees_of_freedom_.emplace(
        part,
        barycentric_to_pile_up(part->degrees_of_freedom()));
  }
}

void PileUp::set_mass(Mass const& mass) {
  mass_ = mass;
}

void PileUp::set_intrinsic_force(
    Vector<Force, Barycentric> const& intrinsic_force) {
  intrinsic_force_ = intrinsic_force;
}

std::list<not_null<Part*>> const& PileUp::parts() const {
  return parts_;
}

void PileUp::SetPartApparentDegreesOfFreedom(
    not_null<Part*> const part,
    DegreesOfFreedom<ApparentBubble> const& degrees_of_freedom) {
  std::map<not_null<Part*>, DegreesOfFreedom<ApparentBubble>>::iterator it;
  bool inserted;
  std::tie(it, inserted) =
      apparent_part_degrees_of_freedom_.emplace(part, degrees_of_freedom);
  CHECK(inserted) << "Duplicate part " << part << " at "
                  << degrees_of_freedom;
}

void PileUp::DeformPileUpIfNeeded() {
  if (apparent_part_degrees_of_freedom_.empty()) {
    return;
  }
  // A consistency check that |SetPartApparentDegreesOfFreedom| was called for
  // all the parts.
  CHECK_EQ(parts_.size(), apparent_part_degrees_of_freedom_.size());
  for (not_null<Part*> const part : parts_) {
    CHECK_GT(apparent_part_degrees_of_freedom_.count(part), 0);
  }

  // Compute the apparent centre of mass of the parts.
  BarycentreCalculator<DegreesOfFreedom<ApparentBubble>, Mass> calculator;
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& apparent_part_degrees_of_freedom = pair.second;
    calculator.Add(apparent_part_degrees_of_freedom, part->mass());
  }
  auto const apparent_centre_of_mass = calculator.Get();

  // A motion that maps the apparent centre of mass of the parts to the actual
  // centre of mass of the pile-up.
  RigidTransformation<ApparentBubble, RigidPileUp> const
      apparent_bubble_to_pile_up_transformation(
          apparent_centre_of_mass.position(),
          RigidPileUp::origin,
          Identity<ApparentBubble, RigidPileUp>().Forget());
  RigidMotion<ApparentBubble, RigidPileUp> const
      apparent_bubble_to_pile_up_motion(
          apparent_bubble_to_pile_up_transformation,
          AngularVelocity<ApparentBubble>(),
          apparent_centre_of_mass.velocity());

  // Now update the positions of the parts in the pile-up frame.
  actual_part_degrees_of_freedom_.clear();
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& apparent_part_degrees_of_freedom = pair.second;
    actual_part_degrees_of_freedom_.emplace(
        part,
        apparent_bubble_to_pile_up_motion(apparent_part_degrees_of_freedom));
  }
  apparent_part_degrees_of_freedom_.clear();
}

void PileUp::AdvanceTime(
    Ephemeris<Barycentric>& ephemeris,
    Instant const& t,
    Ephemeris<Barycentric>::FixedStepParameters const& fixed_step_parameters,
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        adaptive_step_parameters) {
  CHECK_GE(psychohistory_->Size(), 1);
  CHECK_LE(psychohistory_->Size(), 2);

  // Remove the non-authoritative point.
  psychohistory_->ForgetAfter(last_authoritative().time());
  bool last_point_is_authoritative = true;

  CHECK_EQ(psychohistory_->Size(), 1);
  if (intrinsic_force_ == Vector<Force, Barycentric>{}) {
    ephemeris.FlowWithFixedStep(
        {psychohistory_.get()},
        Ephemeris<Barycentric>::NoIntrinsicAccelerations,
        t,
        fixed_step_parameters);
    if (psychohistory_->last().time() < t) {
      CHECK(ephemeris.FlowWithAdaptiveStep(
                psychohistory_.get(),
                Ephemeris<Barycentric>::NoIntrinsicAcceleration,
                t,
                adaptive_step_parameters,
                Ephemeris<Barycentric>::unlimited_max_ephemeris_steps,
                /*last_point_only=*/true));
      last_point_is_authoritative = false;
    }
  } else {
    auto const a = intrinsic_force_ / mass_;
    auto const intrinsic_acceleration = [a](Instant const& t) { return a; };
    CHECK(ephemeris.FlowWithAdaptiveStep(
              psychohistory_.get(),
              intrinsic_acceleration,
              t,
              adaptive_step_parameters,
              Ephemeris<Barycentric>::unlimited_max_ephemeris_steps,
              /*last_point_only=*/false));
  }
  auto it = psychohistory_->Begin();
  ++it;
  for (; it != psychohistory_->End(); ++it) {
    AppendToPartTails(it,
                      /*authoritative=*/it != psychohistory_->last() ||
                                        last_point_is_authoritative);
  }
  psychohistory_->ForgetBefore(last_point_is_authoritative
                                   ? psychohistory_->last().time()
                                   : (--psychohistory_->last()).time());
  CHECK(last_point_is_authoritative ? psychohistory_->Size() == 1
                                    : psychohistory_->Size() == 2)
      << NAMED(last_point_is_authoritative) << ", "
      << NAMED(psychohistory_->Size());
}

void PileUp::NudgeParts() const {
  // TODO(egg): this is wrong! when we have computed a prolongation, we must use
  // it here...
  auto const actual_centre_of_mass =
      psychohistory_->last().degrees_of_freedom();

  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up{
      RigidTransformation<Barycentric, RigidPileUp>{
          actual_centre_of_mass.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()},
      AngularVelocity<Barycentric>(),
      actual_centre_of_mass.velocity()};
  auto const pile_up_to_barycentric = barycentric_to_pile_up.Inverse();
  for (not_null<Part*> const part : parts_) {
    part->set_degrees_of_freedom(pile_up_to_barycentric(
        FindOrDie(actual_part_degrees_of_freedom_, part)));
  }
}

void PileUp::WriteToMessage(not_null<serialization::PileUp*> message) const {
  for (auto const part : parts_) {
    message->add_part_id(part->part_id());
  }
  mass_.WriteToMessage(message->mutable_mass());
  intrinsic_force_.WriteToMessage(message->mutable_intrinsic_force());
  psychohistory_->WriteToMessage(message->mutable_psychohistory(),
                                 /*forks=*/{});
  for (auto const& pair : actual_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& degrees_of_freedom = pair.second;
    degrees_of_freedom.WriteToMessage(&(
        (*message->mutable_actual_part_degrees_of_freedom())[part->part_id()]));
  }
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& degrees_of_freedom = pair.second;
    degrees_of_freedom.WriteToMessage(&(
        (*message
              ->mutable_apparent_part_degrees_of_freedom())[part->part_id()]));
  }
}

not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
    serialization::PileUp const& message,
    std::function<not_null<Part*>(PartId)> const& part_id_to_part) {
  std::list<not_null<Part*>> parts;
  for (auto const part_id : message.part_id()) {
    parts.push_back(part_id_to_part(part_id));
  }
  not_null<std::unique_ptr<PileUp>> pile_up =
      std::unique_ptr<PileUp>(new PileUp(std::move(parts)));
  pile_up->mass_ = Mass::ReadFromMessage(message.mass());
  pile_up->intrinsic_force_ =
      Vector<Force, Barycentric>::ReadFromMessage(message.intrinsic_force());
  pile_up->psychohistory_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.psychohistory(),
                                                       /*forks=*/{});
  for (auto const& pair : message.actual_part_degrees_of_freedom()) {
    std::uint32_t const part_id = pair.first;
    serialization::Pair const& degrees_of_freedom = pair.second;
    pile_up->actual_part_degrees_of_freedom_.emplace(
        part_id_to_part(part_id),
        DegreesOfFreedom<RigidPileUp>::ReadFromMessage(degrees_of_freedom));
  }
  for (auto const& pair : message.apparent_part_degrees_of_freedom()) {
    std::uint32_t const part_id = pair.first;
    serialization::Pair const& degrees_of_freedom = pair.second;
    pile_up->apparent_part_degrees_of_freedom_.emplace(
        part_id_to_part(part_id),
        DegreesOfFreedom<ApparentBubble>::ReadFromMessage(degrees_of_freedom));
  }
  return pile_up;
}

PileUp::PileUp(std::list<not_null<Part*>>&& parts)
    : parts_(std::move(parts)),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void PileUp::AppendToPartTails(
    DiscreteTrajectory<Barycentric>::Iterator const it,
    bool const authoritative) const {
  auto const& pile_up_dof = it.degrees_of_freedom();
  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up(
      RigidTransformation<Barycentric, RigidPileUp>(
          pile_up_dof.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()),
      AngularVelocity<Barycentric>{},
      pile_up_dof.velocity());
  auto const pile_up_to_barycentric = barycentric_to_pile_up.Inverse();
  for (not_null<Part*> const part : parts_) {
    part->tail().Append(it.time(),
                        pile_up_to_barycentric(
                            FindOrDie(actual_part_degrees_of_freedom_, part)));
    part->set_tail_is_authoritative(authoritative);
  }
}

DiscreteTrajectory<Barycentric>::Iterator PileUp::last_authoritative() const {
  return (psychohistory_->Size() == 1) ? psychohistory_->last()
                                       : --psychohistory_->last();
}

}  // namespace internal_pile_up
}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>maybe fix the bug<commit_after>
#include "ksp_plugin/pile_up.hpp"

#include <list>
#include <map>

#include "geometry/identity.hpp"
#include "ksp_plugin/part.hpp"
#include "physics/rigid_motion.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_pile_up {

using base::FindOrDie;
using base::make_not_null_unique;
using geometry::AngularVelocity;
using geometry::BarycentreCalculator;
using geometry::Identity;
using geometry::OrthogonalMap;
using geometry::Position;
using geometry::Velocity;
using physics::DegreesOfFreedom;
using physics::RigidMotion;
using physics::RigidTransformation;

PileUp::PileUp(std::list<not_null<Part*>>&& parts, Instant const& t)
    : parts_(std::move(parts)),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {
  BarycentreCalculator<DegreesOfFreedom<Barycentric>, Mass> calculator;
  Vector<Force, Barycentric> total_intrinsic_force;
  for (not_null<Part*> const part : parts_) {
    total_intrinsic_force += part->intrinsic_force();
    calculator.Add(part->degrees_of_freedom(), part->mass());
  }
  mass_ = calculator.weight();
  intrinsic_force_ = total_intrinsic_force;
  DegreesOfFreedom<Barycentric> const barycentre = calculator.Get();
  psychohistory_->Append(t, barycentre);

  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up{
      RigidTransformation<Barycentric, RigidPileUp>{
          barycentre.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()},
      AngularVelocity<Barycentric>{},
      barycentre.velocity()};
  for (not_null<Part*> const part : parts_) {
    actual_part_degrees_of_freedom_.emplace(
        part,
        barycentric_to_pile_up(part->degrees_of_freedom()));
  }
}

void PileUp::set_mass(Mass const& mass) {
  mass_ = mass;
}

void PileUp::set_intrinsic_force(
    Vector<Force, Barycentric> const& intrinsic_force) {
  intrinsic_force_ = intrinsic_force;
}

std::list<not_null<Part*>> const& PileUp::parts() const {
  return parts_;
}

void PileUp::SetPartApparentDegreesOfFreedom(
    not_null<Part*> const part,
    DegreesOfFreedom<ApparentBubble> const& degrees_of_freedom) {
  std::map<not_null<Part*>, DegreesOfFreedom<ApparentBubble>>::iterator it;
  bool inserted;
  std::tie(it, inserted) =
      apparent_part_degrees_of_freedom_.emplace(part, degrees_of_freedom);
  CHECK(inserted) << "Duplicate part " << part << " at "
                  << degrees_of_freedom;
}

void PileUp::DeformPileUpIfNeeded() {
  if (apparent_part_degrees_of_freedom_.empty()) {
    return;
  }
  // A consistency check that |SetPartApparentDegreesOfFreedom| was called for
  // all the parts.
  CHECK_EQ(parts_.size(), apparent_part_degrees_of_freedom_.size());
  for (not_null<Part*> const part : parts_) {
    CHECK_GT(apparent_part_degrees_of_freedom_.count(part), 0);
  }

  // Compute the apparent centre of mass of the parts.
  BarycentreCalculator<DegreesOfFreedom<ApparentBubble>, Mass> calculator;
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& apparent_part_degrees_of_freedom = pair.second;
    calculator.Add(apparent_part_degrees_of_freedom, part->mass());
  }
  auto const apparent_centre_of_mass = calculator.Get();

  // A motion that maps the apparent centre of mass of the parts to the actual
  // centre of mass of the pile-up.
  RigidTransformation<ApparentBubble, RigidPileUp> const
      apparent_bubble_to_pile_up_transformation(
          apparent_centre_of_mass.position(),
          RigidPileUp::origin,
          Identity<ApparentBubble, RigidPileUp>().Forget());
  RigidMotion<ApparentBubble, RigidPileUp> const
      apparent_bubble_to_pile_up_motion(
          apparent_bubble_to_pile_up_transformation,
          AngularVelocity<ApparentBubble>(),
          apparent_centre_of_mass.velocity());

  // Now update the positions of the parts in the pile-up frame.
  actual_part_degrees_of_freedom_.clear();
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& apparent_part_degrees_of_freedom = pair.second;
    actual_part_degrees_of_freedom_.emplace(
        part,
        apparent_bubble_to_pile_up_motion(apparent_part_degrees_of_freedom));
  }
  apparent_part_degrees_of_freedom_.clear();
}

void PileUp::AdvanceTime(
    Ephemeris<Barycentric>& ephemeris,
    Instant const& t,
    Ephemeris<Barycentric>::FixedStepParameters const& fixed_step_parameters,
    Ephemeris<Barycentric>::AdaptiveStepParameters const&
        adaptive_step_parameters) {
  CHECK_GE(psychohistory_->Size(), 1);
  CHECK_LE(psychohistory_->Size(), 2);

  bool last_point_is_authoritative = true;

  if (intrinsic_force_ == Vector<Force, Barycentric>{}) {
    // Remove the non-authoritative point.
    psychohistory_->ForgetAfter(last_authoritative().time());
    CHECK_EQ(psychohistory_->Size(), 1);
    ephemeris.FlowWithFixedStep(
        {psychohistory_.get()},
        Ephemeris<Barycentric>::NoIntrinsicAccelerations,
        t,
        fixed_step_parameters);
    if (psychohistory_->last().time() < t) {
      CHECK(ephemeris.FlowWithAdaptiveStep(
                psychohistory_.get(),
                Ephemeris<Barycentric>::NoIntrinsicAcceleration,
                t,
                adaptive_step_parameters,
                Ephemeris<Barycentric>::unlimited_max_ephemeris_steps,
                /*last_point_only=*/true));
      last_point_is_authoritative = false;
    }
  } else {
    // We make the existing last point authoritative, i.e. we do not remove it.
    // If it was already authoritative nothing happen, if it was not, we
    // integrate on top of it, and it gets appended authoritatively to the part
    // tails.
    auto const a = intrinsic_force_ / mass_;
    auto const intrinsic_acceleration = [a](Instant const& t) { return a; };
    CHECK(ephemeris.FlowWithAdaptiveStep(
              psychohistory_.get(),
              intrinsic_acceleration,
              t,
              adaptive_step_parameters,
              Ephemeris<Barycentric>::unlimited_max_ephemeris_steps,
              /*last_point_only=*/false));
  }
  auto it = psychohistory_->Begin();
  ++it;
  for (; it != psychohistory_->End(); ++it) {
    AppendToPartTails(it,
                      /*authoritative=*/it != psychohistory_->last() ||
                                        last_point_is_authoritative);
  }
  psychohistory_->ForgetBefore(last_point_is_authoritative
                                   ? psychohistory_->last().time()
                                   : (--psychohistory_->last()).time());
  CHECK(last_point_is_authoritative ? psychohistory_->Size() == 1
                                    : psychohistory_->Size() == 2)
      << NAMED(last_point_is_authoritative) << ", "
      << NAMED(psychohistory_->Size());
}

void PileUp::NudgeParts() const {
  // TODO(egg): this is wrong! when we have computed a prolongation, we must use
  // it here...
  auto const actual_centre_of_mass =
      psychohistory_->last().degrees_of_freedom();

  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up{
      RigidTransformation<Barycentric, RigidPileUp>{
          actual_centre_of_mass.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()},
      AngularVelocity<Barycentric>(),
      actual_centre_of_mass.velocity()};
  auto const pile_up_to_barycentric = barycentric_to_pile_up.Inverse();
  for (not_null<Part*> const part : parts_) {
    part->set_degrees_of_freedom(pile_up_to_barycentric(
        FindOrDie(actual_part_degrees_of_freedom_, part)));
  }
}

void PileUp::WriteToMessage(not_null<serialization::PileUp*> message) const {
  for (auto const part : parts_) {
    message->add_part_id(part->part_id());
  }
  mass_.WriteToMessage(message->mutable_mass());
  intrinsic_force_.WriteToMessage(message->mutable_intrinsic_force());
  psychohistory_->WriteToMessage(message->mutable_psychohistory(),
                                 /*forks=*/{});
  for (auto const& pair : actual_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& degrees_of_freedom = pair.second;
    degrees_of_freedom.WriteToMessage(&(
        (*message->mutable_actual_part_degrees_of_freedom())[part->part_id()]));
  }
  for (auto const& pair : apparent_part_degrees_of_freedom_) {
    auto const part = pair.first;
    auto const& degrees_of_freedom = pair.second;
    degrees_of_freedom.WriteToMessage(&(
        (*message
              ->mutable_apparent_part_degrees_of_freedom())[part->part_id()]));
  }
}

not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
    serialization::PileUp const& message,
    std::function<not_null<Part*>(PartId)> const& part_id_to_part) {
  std::list<not_null<Part*>> parts;
  for (auto const part_id : message.part_id()) {
    parts.push_back(part_id_to_part(part_id));
  }
  not_null<std::unique_ptr<PileUp>> pile_up =
      std::unique_ptr<PileUp>(new PileUp(std::move(parts)));
  pile_up->mass_ = Mass::ReadFromMessage(message.mass());
  pile_up->intrinsic_force_ =
      Vector<Force, Barycentric>::ReadFromMessage(message.intrinsic_force());
  pile_up->psychohistory_ =
      DiscreteTrajectory<Barycentric>::ReadFromMessage(message.psychohistory(),
                                                       /*forks=*/{});
  for (auto const& pair : message.actual_part_degrees_of_freedom()) {
    std::uint32_t const part_id = pair.first;
    serialization::Pair const& degrees_of_freedom = pair.second;
    pile_up->actual_part_degrees_of_freedom_.emplace(
        part_id_to_part(part_id),
        DegreesOfFreedom<RigidPileUp>::ReadFromMessage(degrees_of_freedom));
  }
  for (auto const& pair : message.apparent_part_degrees_of_freedom()) {
    std::uint32_t const part_id = pair.first;
    serialization::Pair const& degrees_of_freedom = pair.second;
    pile_up->apparent_part_degrees_of_freedom_.emplace(
        part_id_to_part(part_id),
        DegreesOfFreedom<ApparentBubble>::ReadFromMessage(degrees_of_freedom));
  }
  return pile_up;
}

PileUp::PileUp(std::list<not_null<Part*>>&& parts)
    : parts_(std::move(parts)),
      psychohistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()) {}

void PileUp::AppendToPartTails(
    DiscreteTrajectory<Barycentric>::Iterator const it,
    bool const authoritative) const {
  auto const& pile_up_dof = it.degrees_of_freedom();
  RigidMotion<Barycentric, RigidPileUp> const barycentric_to_pile_up(
      RigidTransformation<Barycentric, RigidPileUp>(
          pile_up_dof.position(),
          RigidPileUp::origin,
          Identity<Barycentric, RigidPileUp>().Forget()),
      AngularVelocity<Barycentric>{},
      pile_up_dof.velocity());
  auto const pile_up_to_barycentric = barycentric_to_pile_up.Inverse();
  for (not_null<Part*> const part : parts_) {
    part->tail().Append(it.time(),
                        pile_up_to_barycentric(
                            FindOrDie(actual_part_degrees_of_freedom_, part)));
    part->set_tail_is_authoritative(authoritative);
  }
}

DiscreteTrajectory<Barycentric>::Iterator PileUp::last_authoritative() const {
  return (psychohistory_->Size() == 1) ? psychohistory_->last()
                                       : --psychohistory_->last();
}

}  // namespace internal_pile_up
}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/view/XControlAccess.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <ooo/vba/XControlProvider.hpp>

#include "vbaoleobject.hxx"

using namespace com::sun::star;
using namespace ooo::vba;

sal_Int32 pt2mm( double pt ) //1/100mm
{
    return static_cast<sal_Int32>(pt * 0.352778);
}

double mm2pt( sal_Int32 mm )
{
    return mm * 2.8345;
}

ScVbaOLEObject::ScVbaOLEObject( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
            css::uno::Reference< css::drawing::XControlShape > xControlShape )
: OLEObjectImpl_BASE( xParent, xContext ), m_xControlShape( xControlShape )
{
    //init m_xWindowPeer
    uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl(), css::uno::UNO_QUERY_THROW );
    uno::Reference< container::XChild > xChild( xControlModel, uno::UNO_QUERY_THROW );
    xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
    xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
    css::uno::Reference< css::frame::XModel > xModel( xChild->getParent(), uno::UNO_QUERY_THROW );
    uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
    uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
    m_xControl.set( xControlProvider->createControl(  xControlShape, xModel ) );
}

uno::Reference< uno::XInterface > SAL_CALL
ScVbaOLEObject::getObject() throw (uno::RuntimeException)
{
    return uno::Reference< uno::XInterface >( m_xControl, uno::UNO_QUERY_THROW );
}

sal_Bool SAL_CALL
ScVbaOLEObject::getEnabled() throw (uno::RuntimeException)
{
    return m_xControl->getEnabled();
}

void SAL_CALL
ScVbaOLEObject::setEnabled( sal_Bool _enabled ) throw (uno::RuntimeException)
{
    m_xControl->setEnabled( _enabled );
}

sal_Bool SAL_CALL
ScVbaOLEObject::getVisible() throw (uno::RuntimeException)
{
    OSL_TRACE("OleObject %s returning visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), m_xControl->getVisible() ? "true" : "false" );
    return m_xControl->getVisible();
}

void SAL_CALL
ScVbaOLEObject::setVisible( sal_Bool _visible ) throw (uno::RuntimeException)
{
    OSL_TRACE("OleObject %s set visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), _visible ? "true" : "false" );
    m_xControl->setVisible( _visible );
}

double SAL_CALL
ScVbaOLEObject::getLeft() throw (uno::RuntimeException)
{
    return m_xControl->getLeft();
}

void SAL_CALL
ScVbaOLEObject::setLeft( double _left ) throw (uno::RuntimeException)
{
    m_xControl->setLeft( _left );

}

double SAL_CALL
ScVbaOLEObject::getTop() throw (uno::RuntimeException)
{
    return m_xControl->getTop();
}

void SAL_CALL
ScVbaOLEObject::setTop( double _top ) throw (uno::RuntimeException)
{
    m_xControl->setTop( _top );
}

double SAL_CALL
ScVbaOLEObject::getHeight() throw (uno::RuntimeException)
{
    return m_xControl->getHeight();
}

void SAL_CALL
ScVbaOLEObject::setHeight( double _height ) throw (uno::RuntimeException)
{
    m_xControl->setHeight( _height );
}

double SAL_CALL
ScVbaOLEObject::getWidth() throw (uno::RuntimeException)
{
    return m_xControl->getWidth();
}

void SAL_CALL
ScVbaOLEObject::setWidth( double _width ) throw (uno::RuntimeException)
{
    m_xControl->setWidth( _width );
}
rtl::OUString&
ScVbaOLEObject::getServiceImplName()
{
    static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaOLEObject") );
    return sImplName;
}

uno::Sequence< rtl::OUString >
ScVbaOLEObject::getServiceNames()
{
    static uno::Sequence< rtl::OUString > aServiceNames;
    if ( aServiceNames.getLength() == 0 )
    {
        aServiceNames.realloc( 1 );
        aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.OLEObject" ) );
    }
    return aServiceNames;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>callcatcher: unused methods<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/view/XControlAccess.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <ooo/vba/XControlProvider.hpp>

#include "vbaoleobject.hxx"

using namespace com::sun::star;
using namespace ooo::vba;

ScVbaOLEObject::ScVbaOLEObject( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
            css::uno::Reference< css::drawing::XControlShape > xControlShape )
: OLEObjectImpl_BASE( xParent, xContext ), m_xControlShape( xControlShape )
{
    //init m_xWindowPeer
    uno::Reference< awt::XControlModel > xControlModel( xControlShape->getControl(), css::uno::UNO_QUERY_THROW );
    uno::Reference< container::XChild > xChild( xControlModel, uno::UNO_QUERY_THROW );
    xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
    xChild.set( xChild->getParent(), uno::UNO_QUERY_THROW );
    css::uno::Reference< css::frame::XModel > xModel( xChild->getParent(), uno::UNO_QUERY_THROW );
    uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
    uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
    m_xControl.set( xControlProvider->createControl(  xControlShape, xModel ) );
}

uno::Reference< uno::XInterface > SAL_CALL
ScVbaOLEObject::getObject() throw (uno::RuntimeException)
{
    return uno::Reference< uno::XInterface >( m_xControl, uno::UNO_QUERY_THROW );
}

sal_Bool SAL_CALL
ScVbaOLEObject::getEnabled() throw (uno::RuntimeException)
{
    return m_xControl->getEnabled();
}

void SAL_CALL
ScVbaOLEObject::setEnabled( sal_Bool _enabled ) throw (uno::RuntimeException)
{
    m_xControl->setEnabled( _enabled );
}

sal_Bool SAL_CALL
ScVbaOLEObject::getVisible() throw (uno::RuntimeException)
{
    OSL_TRACE("OleObject %s returning visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), m_xControl->getVisible() ? "true" : "false" );
    return m_xControl->getVisible();
}

void SAL_CALL
ScVbaOLEObject::setVisible( sal_Bool _visible ) throw (uno::RuntimeException)
{
    OSL_TRACE("OleObject %s set visible %s", rtl::OUStringToOString( m_xControl->getName(), RTL_TEXTENCODING_UTF8 ).getStr(), _visible ? "true" : "false" );
    m_xControl->setVisible( _visible );
}

double SAL_CALL
ScVbaOLEObject::getLeft() throw (uno::RuntimeException)
{
    return m_xControl->getLeft();
}

void SAL_CALL
ScVbaOLEObject::setLeft( double _left ) throw (uno::RuntimeException)
{
    m_xControl->setLeft( _left );

}

double SAL_CALL
ScVbaOLEObject::getTop() throw (uno::RuntimeException)
{
    return m_xControl->getTop();
}

void SAL_CALL
ScVbaOLEObject::setTop( double _top ) throw (uno::RuntimeException)
{
    m_xControl->setTop( _top );
}

double SAL_CALL
ScVbaOLEObject::getHeight() throw (uno::RuntimeException)
{
    return m_xControl->getHeight();
}

void SAL_CALL
ScVbaOLEObject::setHeight( double _height ) throw (uno::RuntimeException)
{
    m_xControl->setHeight( _height );
}

double SAL_CALL
ScVbaOLEObject::getWidth() throw (uno::RuntimeException)
{
    return m_xControl->getWidth();
}

void SAL_CALL
ScVbaOLEObject::setWidth( double _width ) throw (uno::RuntimeException)
{
    m_xControl->setWidth( _width );
}
rtl::OUString&
ScVbaOLEObject::getServiceImplName()
{
    static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaOLEObject") );
    return sImplName;
}

uno::Sequence< rtl::OUString >
ScVbaOLEObject::getServiceNames()
{
    static uno::Sequence< rtl::OUString > aServiceNames;
    if ( aServiceNames.getLength() == 0 )
    {
        aServiceNames.realloc( 1 );
        aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.OLEObject" ) );
    }
    return aServiceNames;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*=============================================================================

  Library: XNAT/Core

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 "ctkXnatResourceCatalogXmlParser.h"

#include <QDebug>
#include <QXmlStreamReader>

//----------------------------------------------------------------------------
class ctkXnatResourceCatalogXmlParserPrivate
{
public:

  ctkXnatResourceCatalogXmlParserPrivate()
  {
  }

  QXmlStreamReader xmlReader;
};

ctkXnatResourceCatalogXmlParser::ctkXnatResourceCatalogXmlParser()
  : d_ptr (new ctkXnatResourceCatalogXmlParserPrivate())
{
}
ctkXnatResourceCatalogXmlParser::~ctkXnatResourceCatalogXmlParser()
{
  delete d_ptr;
}

void ctkXnatResourceCatalogXmlParser::setData(const QByteArray &xmlInput)
{
  Q_D(ctkXnatResourceCatalogXmlParser);
  d->xmlReader.addData(xmlInput);
}

void ctkXnatResourceCatalogXmlParser::parseXml(QList<QVariantMap>& result)
{
  Q_D(ctkXnatResourceCatalogXmlParser);

  while (!d->xmlReader.atEnd())
  {
    if (d->xmlReader.name().compare("entry") == 0)
    {
      QVariantMap map;
      QXmlStreamAttributes attributes = d->xmlReader.attributes();

      if( attributes.hasAttribute("name") && attributes.hasAttribute("digest"))
      {
        QString name("");
        name += attributes.value("name");
        QString md5("");
        md5 += attributes.value("digest");
        map[name] = md5;
        result.append(map);
      }
    }
    d->xmlReader.readNext();
  }
  if (d->xmlReader.hasError())
  {
    qWarning()<<"Error parsing XNAT resource catalog xml!";
  }
}
<commit_msg>XNAT: Fix Qt5 build error related to ambiguous call to QStringRef::compare<commit_after>/*=============================================================================

  Library: XNAT/Core

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 "ctkXnatResourceCatalogXmlParser.h"

#include <QDebug>
#include <QXmlStreamReader>

//----------------------------------------------------------------------------
class ctkXnatResourceCatalogXmlParserPrivate
{
public:

  ctkXnatResourceCatalogXmlParserPrivate()
  {
  }

  QXmlStreamReader xmlReader;
};

ctkXnatResourceCatalogXmlParser::ctkXnatResourceCatalogXmlParser()
  : d_ptr (new ctkXnatResourceCatalogXmlParserPrivate())
{
}
ctkXnatResourceCatalogXmlParser::~ctkXnatResourceCatalogXmlParser()
{
  delete d_ptr;
}

void ctkXnatResourceCatalogXmlParser::setData(const QByteArray &xmlInput)
{
  Q_D(ctkXnatResourceCatalogXmlParser);
  d->xmlReader.addData(xmlInput);
}

void ctkXnatResourceCatalogXmlParser::parseXml(QList<QVariantMap>& result)
{
  Q_D(ctkXnatResourceCatalogXmlParser);

  while (!d->xmlReader.atEnd())
  {
    if (d->xmlReader.name().compare(QLatin1String("entry")) == 0)
    {
      QVariantMap map;
      QXmlStreamAttributes attributes = d->xmlReader.attributes();

      if( attributes.hasAttribute("name") && attributes.hasAttribute("digest"))
      {
        QString name("");
        name += attributes.value("name");
        QString md5("");
        md5 += attributes.value("digest");
        map[name] = md5;
        result.append(map);
      }
    }
    d->xmlReader.readNext();
  }
  if (d->xmlReader.hasError())
  {
    qWarning()<<"Error parsing XNAT resource catalog xml!";
  }
}
<|endoftext|>


<commit_before>/*
 * HTTPConnection.cpp
 *****************************************************************************
 * Copyright (C) 2014-2015 - VideoLAN and VLC Authors
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "HTTPConnection.hpp"
#include "ConnectionParams.hpp"
#include "Sockets.hpp"
#include "../adaptive/tools/Helper.h"

#include <cstdio>
#include <sstream>
#include <vlc_stream.h>

using namespace adaptive::http;

AbstractConnection::AbstractConnection(vlc_object_t *p_object_)
{
    p_object = p_object_;
    available = true;
    bytesRead = 0;
    contentLength = 0;
}

AbstractConnection::~AbstractConnection()
{

}

bool AbstractConnection::prepare(const ConnectionParams &params_)
{
    if (!available)
        return false;
    params = params_;
    available = false;
    return true;
}

size_t AbstractConnection::getContentLength() const
{
    return contentLength;
}

HTTPConnection::HTTPConnection(vlc_object_t *p_object_, Socket *socket_, bool persistent)
    : AbstractConnection( p_object_ )
{
    socket = socket_;
    psz_useragent = var_InheritString(p_object_, "http-user-agent");
    queryOk = false;
    retries = 0;
    connectionClose = !persistent;
    chunked = false;
    chunked_eof = false;
    chunkLength = 0;
}

HTTPConnection::~HTTPConnection()
{
    free(psz_useragent);
    delete socket;
}

bool HTTPConnection::canReuse(const ConnectionParams &params_) const
{
    return ( available &&
             params.getHostname() == params_.getHostname() &&
             params.getScheme() == params_.getScheme() &&
             params.getPort() == params_.getPort() );
}

bool HTTPConnection::connect()
{
    return socket->connect(p_object, params.getHostname().c_str(),
                                     params.getPort());
}

bool HTTPConnection::connected() const
{
    return socket->connected();
}

void HTTPConnection::disconnect()
{
    queryOk = false;
    bytesRead = 0;
    contentLength = 0;
    chunked = false;
    chunkLength = 0;
    bytesRange = BytesRange();
    socket->disconnect();
}

int HTTPConnection::request(const std::string &path, const BytesRange &range)
{
    queryOk = false;
    chunked = false;
    chunked_eof = false;
    chunkLength = 0;

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                       range.isValid() ? range.getStartByte() : 0);

    if(!connected() && ( params.getHostname().empty() || !connect() ))
        return VLC_EGENERIC;

    bytesRange = range;
    if(range.isValid() && range.getEndByte() > 0)
        contentLength = range.getEndByte() - range.getStartByte() + 1;

    std::string header = buildRequestHeader(path);
    if(connectionClose)
        header.append("Connection: close\r\n");
    header.append("\r\n");

    if(!send( header ))
    {
        socket->disconnect();
        if(!connectionClose)
        {
            /* server closed connection pipeline after last req. need new */
            connectionClose = true;
            return request(path, range);
        }
        return VLC_EGENERIC;
    }

    int i_ret = parseReply();
    if(i_ret == VLC_SUCCESS)
    {
        queryOk = true;
    }
    else if(i_ret == VLC_EGENERIC)
    {
        socket->disconnect();
        if(!connectionClose)
        {
            connectionClose = true;
            return request(path, range);
        }
    }

    return i_ret;
}

ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
    if( !connected() ||
       (!queryOk && bytesRead == 0) )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    queryOk = false;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = ( chunked ) ? readChunk(p_buffer, len)
                              : socket->read(p_object, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len || /* set EOF */
       contentLength == bytesRead )
    {
        socket->disconnect();
        return ret;
    }

    return ret;
}

bool HTTPConnection::send(const std::string &data)
{
    return send(data.c_str(), data.length());
}

bool HTTPConnection::send(const void *buf, size_t size)
{
    return socket->send(p_object, buf, size);
}

int HTTPConnection::parseReply()
{
    std::string line = readLine();

    if(line.empty())
        return VLC_EGENERIC;

    if (line.compare(0, 9, "HTTP/1.1 ")!=0)
    {
        if(line.compare(0, 9, "HTTP/1.0 ")!=0)
            return VLC_ENOOBJ;
        else
            connectionClose = true;
    }

    std::istringstream ss(line.substr(9));
    ss.imbue(std::locale("C"));
    int replycode;
    ss >> replycode;
    if (replycode != 200 && replycode != 206)
        return VLC_ENOOBJ;

    line = readLine();

    while(!line.empty() && line.compare("\r\n"))
    {
        size_t split = line.find_first_of(':');
        size_t value = split + 1;

        while(line.at(value) == ' ')
            value++;

        onHeader(line.substr(0, split), line.substr(value));
        line = readLine();
    }

    return VLC_SUCCESS;
}

ssize_t HTTPConnection::readChunk(void *p_buffer, size_t len)
{
    size_t copied = 0;

    for( ; copied < len && !chunked_eof; )
    {
        /* adapted from access/http/chunked.c */
        if(chunkLength == 0)
        {
            std::string line = readLine();
            int end;
            if (std::sscanf(line.c_str(), "%zx%n", &chunkLength, &end) < 1
                    || (line[end] != '\0' && line[end] != ';' /* ignore extension(s) */))
                return -1;
        }

        if(chunkLength > 0)
        {
            size_t toread = len - copied;
            if(toread > chunkLength)
                toread = chunkLength;

            ssize_t in = socket->read(p_object, &((uint8_t*)p_buffer)[copied], toread);
            if(in < 0)
            {
                return (copied == 0) ? in : copied;
            }
            else if((size_t)in < toread)
            {
               return copied + in;
            }
            copied += in;
            chunkLength -= in;
        }
        else chunked_eof = true;

        if(chunkLength == 0)
        {
            char crlf[2];
            ssize_t in = socket->read(p_object, &crlf, 2);
            if(in < 2 || memcmp(crlf, "\r\n", 2))
                return (copied == 0) ? -1 : copied;
        }
    }

    return copied;
}

std::string HTTPConnection::readLine()
{
    return socket->readline(p_object);
}

void HTTPConnection::setUsed( bool b )
{
    available = !b;
    if(available)
    {
        if(!connectionClose && contentLength == bytesRead )
        {
            queryOk = false;
            bytesRead = 0;
            contentLength = 0;
            bytesRange = BytesRange();
        }
        else  /* We can't resend request if we haven't finished reading */
            disconnect();
    }
}

void HTTPConnection::onHeader(const std::string &key,
                              const std::string &value)
{
    if(key == "Content-Length")
    {
        std::istringstream ss(value);
        ss.imbue(std::locale("C"));
        size_t length;
        ss >> length;
        contentLength = length;
    }
    else if (key == "Connection" && value =="close")
    {
        connectionClose = true;
    }
    else if (key == "Transfer-Encoding" && value == "chunked")
    {
        chunked = true;
    }
}

std::string HTTPConnection::buildRequestHeader(const std::string &path) const
{
    std::stringstream req;
    req << "GET " << path << " HTTP/1.1\r\n" <<
           "Host: " << params.getHostname() << "\r\n" <<
           "Cache-Control: no-cache" << "\r\n" <<
           "User-Agent: " << std::string(psz_useragent) << "\r\n";
    req << extraRequestHeaders();
    return req.str();
}

std::string HTTPConnection::extraRequestHeaders() const
{
    std::stringstream ss;
    ss.imbue(std::locale("C"));
    if(bytesRange.isValid())
    {
        ss << "Range: bytes=" << bytesRange.getStartByte() << "-";
        if(bytesRange.getEndByte())
            ss << bytesRange.getEndByte();
        ss << "\r\n";
    }
    return ss.str();
}

StreamUrlConnection::StreamUrlConnection(vlc_object_t *p_object)
    : AbstractConnection(p_object)
{
    p_streamurl = NULL;
    bytesRead = 0;
    contentLength = 0;
}

StreamUrlConnection::~StreamUrlConnection()
{
    reset();
}

void StreamUrlConnection::reset()
{
    if(p_streamurl)
        vlc_stream_Delete(p_streamurl);
    p_streamurl = NULL;
    bytesRead = 0;
    contentLength = 0;
    bytesRange = BytesRange();
}

bool StreamUrlConnection::canReuse(const ConnectionParams &) const
{
    return available;
}

int StreamUrlConnection::request(const std::string &path, const BytesRange &range)
{
    reset();

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                      range.isValid() ? range.getStartByte() : 0);

    p_streamurl = vlc_stream_NewURL(p_object, params.getUrl().c_str());
    if(!p_streamurl)
        return VLC_EGENERIC;

    if(range.isValid() && range.getEndByte() > 0)
    {
        if(vlc_stream_Seek(p_streamurl, range.getStartByte()) != VLC_SUCCESS)
        {
            vlc_stream_Delete(p_streamurl);
            return VLC_EGENERIC;
        }
        bytesRange = range;
        contentLength = range.getEndByte() - range.getStartByte() + 1;
    }

    int64_t i_size = stream_Size(p_streamurl);
    if(i_size > -1)
    {
        if(!range.isValid() || contentLength > (size_t) i_size)
            contentLength = (size_t) i_size;
    }
    return VLC_SUCCESS;
}

ssize_t StreamUrlConnection::read(void *p_buffer, size_t len)
{
    if( !p_streamurl )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = vlc_stream_Read(p_streamurl, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len || /* set EOF */
       contentLength == bytesRead )
    {
        reset();
        return ret;
    }

    return ret;
}

void StreamUrlConnection::setUsed( bool b )
{
    available = !b;
    if(available && contentLength == bytesRead)
       reset();
}

ConnectionFactory::ConnectionFactory()
{
}

ConnectionFactory::~ConnectionFactory()
{
}

AbstractConnection * ConnectionFactory::createConnection(vlc_object_t *p_object,
                                                         const ConnectionParams &params)
{
    if((params.getScheme() != "http" && params.getScheme() != "https") || params.getHostname().empty())
        return NULL;

    const int sockettype = (params.getScheme() == "https") ? TLSSocket::TLS : Socket::REGULAR;
    Socket *socket = (sockettype == TLSSocket::TLS) ? new (std::nothrow) TLSSocket()
                                                    : new (std::nothrow) Socket();
    if(!socket)
        return NULL;

    /* disable pipelined tls until we have ticket/resume session support */
    HTTPConnection *conn = new (std::nothrow)
            HTTPConnection(p_object, socket, sockettype != TLSSocket::TLS);
    if(!conn)
    {
        delete socket;
        return NULL;
    }

    return conn;
}

AbstractConnection * StreamUrlConnectionFactory::createConnection(vlc_object_t *p_object,
                                                                  const ConnectionParams &)
{
    return new (std::nothrow) StreamUrlConnection(p_object);
}
<commit_msg>demux: adaptive: output http error messages<commit_after>/*
 * HTTPConnection.cpp
 *****************************************************************************
 * Copyright (C) 2014-2015 - VideoLAN and VLC Authors
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "HTTPConnection.hpp"
#include "ConnectionParams.hpp"
#include "Sockets.hpp"
#include "../adaptive/tools/Helper.h"

#include <cstdio>
#include <sstream>
#include <vlc_stream.h>

using namespace adaptive::http;

AbstractConnection::AbstractConnection(vlc_object_t *p_object_)
{
    p_object = p_object_;
    available = true;
    bytesRead = 0;
    contentLength = 0;
}

AbstractConnection::~AbstractConnection()
{

}

bool AbstractConnection::prepare(const ConnectionParams &params_)
{
    if (!available)
        return false;
    params = params_;
    available = false;
    return true;
}

size_t AbstractConnection::getContentLength() const
{
    return contentLength;
}

HTTPConnection::HTTPConnection(vlc_object_t *p_object_, Socket *socket_, bool persistent)
    : AbstractConnection( p_object_ )
{
    socket = socket_;
    psz_useragent = var_InheritString(p_object_, "http-user-agent");
    queryOk = false;
    retries = 0;
    connectionClose = !persistent;
    chunked = false;
    chunked_eof = false;
    chunkLength = 0;
}

HTTPConnection::~HTTPConnection()
{
    free(psz_useragent);
    delete socket;
}

bool HTTPConnection::canReuse(const ConnectionParams &params_) const
{
    return ( available &&
             params.getHostname() == params_.getHostname() &&
             params.getScheme() == params_.getScheme() &&
             params.getPort() == params_.getPort() );
}

bool HTTPConnection::connect()
{
    return socket->connect(p_object, params.getHostname().c_str(),
                                     params.getPort());
}

bool HTTPConnection::connected() const
{
    return socket->connected();
}

void HTTPConnection::disconnect()
{
    queryOk = false;
    bytesRead = 0;
    contentLength = 0;
    chunked = false;
    chunkLength = 0;
    bytesRange = BytesRange();
    socket->disconnect();
}

int HTTPConnection::request(const std::string &path, const BytesRange &range)
{
    queryOk = false;
    chunked = false;
    chunked_eof = false;
    chunkLength = 0;

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                       range.isValid() ? range.getStartByte() : 0);

    if(!connected() && ( params.getHostname().empty() || !connect() ))
        return VLC_EGENERIC;

    bytesRange = range;
    if(range.isValid() && range.getEndByte() > 0)
        contentLength = range.getEndByte() - range.getStartByte() + 1;

    std::string header = buildRequestHeader(path);
    if(connectionClose)
        header.append("Connection: close\r\n");
    header.append("\r\n");

    if(!send( header ))
    {
        socket->disconnect();
        if(!connectionClose)
        {
            /* server closed connection pipeline after last req. need new */
            connectionClose = true;
            return request(path, range);
        }
        return VLC_EGENERIC;
    }

    int i_ret = parseReply();
    if(i_ret == VLC_SUCCESS)
    {
        queryOk = true;
    }
    else if(i_ret == VLC_EGENERIC)
    {
        socket->disconnect();
        if(!connectionClose)
        {
            connectionClose = true;
            return request(path, range);
        }
    }

    return i_ret;
}

ssize_t HTTPConnection::read(void *p_buffer, size_t len)
{
    if( !connected() ||
       (!queryOk && bytesRead == 0) )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    queryOk = false;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = ( chunked ) ? readChunk(p_buffer, len)
                              : socket->read(p_object, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len || /* set EOF */
       contentLength == bytesRead )
    {
        socket->disconnect();
        return ret;
    }

    return ret;
}

bool HTTPConnection::send(const std::string &data)
{
    return send(data.c_str(), data.length());
}

bool HTTPConnection::send(const void *buf, size_t size)
{
    return socket->send(p_object, buf, size);
}

int HTTPConnection::parseReply()
{
    std::string line = readLine();

    if(line.empty())
        return VLC_EGENERIC;

    if (line.compare(0, 9, "HTTP/1.1 ")!=0)
    {
        if(line.compare(0, 9, "HTTP/1.0 ")!=0)
            return VLC_ENOOBJ;
        else
            connectionClose = true;
    }

    std::istringstream ss(line.substr(9));
    ss.imbue(std::locale("C"));
    int replycode;
    ss >> replycode;
    if (replycode != 200 && replycode != 206)
    {
        msg_Err(p_object, "Failed reading %s: %s", params.getUrl().c_str(), line.c_str());
        return VLC_ENOOBJ;
    }

    line = readLine();

    while(!line.empty() && line.compare("\r\n"))
    {
        size_t split = line.find_first_of(':');
        size_t value = split + 1;

        while(line.at(value) == ' ')
            value++;

        onHeader(line.substr(0, split), line.substr(value));
        line = readLine();
    }

    return VLC_SUCCESS;
}

ssize_t HTTPConnection::readChunk(void *p_buffer, size_t len)
{
    size_t copied = 0;

    for( ; copied < len && !chunked_eof; )
    {
        /* adapted from access/http/chunked.c */
        if(chunkLength == 0)
        {
            std::string line = readLine();
            int end;
            if (std::sscanf(line.c_str(), "%zx%n", &chunkLength, &end) < 1
                    || (line[end] != '\0' && line[end] != ';' /* ignore extension(s) */))
                return -1;
        }

        if(chunkLength > 0)
        {
            size_t toread = len - copied;
            if(toread > chunkLength)
                toread = chunkLength;

            ssize_t in = socket->read(p_object, &((uint8_t*)p_buffer)[copied], toread);
            if(in < 0)
            {
                return (copied == 0) ? in : copied;
            }
            else if((size_t)in < toread)
            {
               return copied + in;
            }
            copied += in;
            chunkLength -= in;
        }
        else chunked_eof = true;

        if(chunkLength == 0)
        {
            char crlf[2];
            ssize_t in = socket->read(p_object, &crlf, 2);
            if(in < 2 || memcmp(crlf, "\r\n", 2))
                return (copied == 0) ? -1 : copied;
        }
    }

    return copied;
}

std::string HTTPConnection::readLine()
{
    return socket->readline(p_object);
}

void HTTPConnection::setUsed( bool b )
{
    available = !b;
    if(available)
    {
        if(!connectionClose && contentLength == bytesRead )
        {
            queryOk = false;
            bytesRead = 0;
            contentLength = 0;
            bytesRange = BytesRange();
        }
        else  /* We can't resend request if we haven't finished reading */
            disconnect();
    }
}

void HTTPConnection::onHeader(const std::string &key,
                              const std::string &value)
{
    if(key == "Content-Length")
    {
        std::istringstream ss(value);
        ss.imbue(std::locale("C"));
        size_t length;
        ss >> length;
        contentLength = length;
    }
    else if (key == "Connection" && value =="close")
    {
        connectionClose = true;
    }
    else if (key == "Transfer-Encoding" && value == "chunked")
    {
        chunked = true;
    }
}

std::string HTTPConnection::buildRequestHeader(const std::string &path) const
{
    std::stringstream req;
    req << "GET " << path << " HTTP/1.1\r\n" <<
           "Host: " << params.getHostname() << "\r\n" <<
           "Cache-Control: no-cache" << "\r\n" <<
           "User-Agent: " << std::string(psz_useragent) << "\r\n";
    req << extraRequestHeaders();
    return req.str();
}

std::string HTTPConnection::extraRequestHeaders() const
{
    std::stringstream ss;
    ss.imbue(std::locale("C"));
    if(bytesRange.isValid())
    {
        ss << "Range: bytes=" << bytesRange.getStartByte() << "-";
        if(bytesRange.getEndByte())
            ss << bytesRange.getEndByte();
        ss << "\r\n";
    }
    return ss.str();
}

StreamUrlConnection::StreamUrlConnection(vlc_object_t *p_object)
    : AbstractConnection(p_object)
{
    p_streamurl = NULL;
    bytesRead = 0;
    contentLength = 0;
}

StreamUrlConnection::~StreamUrlConnection()
{
    reset();
}

void StreamUrlConnection::reset()
{
    if(p_streamurl)
        vlc_stream_Delete(p_streamurl);
    p_streamurl = NULL;
    bytesRead = 0;
    contentLength = 0;
    bytesRange = BytesRange();
}

bool StreamUrlConnection::canReuse(const ConnectionParams &) const
{
    return available;
}

int StreamUrlConnection::request(const std::string &path, const BytesRange &range)
{
    reset();

    /* Set new path for this query */
    params.setPath(path);

    msg_Dbg(p_object, "Retrieving %s @%zu", params.getUrl().c_str(),
                      range.isValid() ? range.getStartByte() : 0);

    p_streamurl = vlc_stream_NewURL(p_object, params.getUrl().c_str());
    if(!p_streamurl)
        return VLC_EGENERIC;

    if(range.isValid() && range.getEndByte() > 0)
    {
        if(vlc_stream_Seek(p_streamurl, range.getStartByte()) != VLC_SUCCESS)
        {
            vlc_stream_Delete(p_streamurl);
            return VLC_EGENERIC;
        }
        bytesRange = range;
        contentLength = range.getEndByte() - range.getStartByte() + 1;
    }

    int64_t i_size = stream_Size(p_streamurl);
    if(i_size > -1)
    {
        if(!range.isValid() || contentLength > (size_t) i_size)
            contentLength = (size_t) i_size;
    }
    return VLC_SUCCESS;
}

ssize_t StreamUrlConnection::read(void *p_buffer, size_t len)
{
    if( !p_streamurl )
        return VLC_EGENERIC;

    if(len == 0)
        return VLC_SUCCESS;

    const size_t toRead = (contentLength) ? contentLength - bytesRead : len;
    if (toRead == 0)
        return VLC_SUCCESS;

    if(len > toRead)
        len = toRead;

    ssize_t ret = vlc_stream_Read(p_streamurl, p_buffer, len);
    if(ret >= 0)
        bytesRead += ret;

    if(ret < 0 || (size_t)ret < len || /* set EOF */
       contentLength == bytesRead )
    {
        reset();
        return ret;
    }

    return ret;
}

void StreamUrlConnection::setUsed( bool b )
{
    available = !b;
    if(available && contentLength == bytesRead)
       reset();
}

ConnectionFactory::ConnectionFactory()
{
}

ConnectionFactory::~ConnectionFactory()
{
}

AbstractConnection * ConnectionFactory::createConnection(vlc_object_t *p_object,
                                                         const ConnectionParams &params)
{
    if((params.getScheme() != "http" && params.getScheme() != "https") || params.getHostname().empty())
        return NULL;

    const int sockettype = (params.getScheme() == "https") ? TLSSocket::TLS : Socket::REGULAR;
    Socket *socket = (sockettype == TLSSocket::TLS) ? new (std::nothrow) TLSSocket()
                                                    : new (std::nothrow) Socket();
    if(!socket)
        return NULL;

    /* disable pipelined tls until we have ticket/resume session support */
    HTTPConnection *conn = new (std::nothrow)
            HTTPConnection(p_object, socket, sockettype != TLSSocket::TLS);
    if(!conn)
    {
        delete socket;
        return NULL;
    }

    return conn;
}

AbstractConnection * StreamUrlConnectionFactory::createConnection(vlc_object_t *p_object,
                                                                  const ConnectionParams &)
{
    return new (std::nothrow) StreamUrlConnection(p_object);
}
<|endoftext|>