<commit_before>// Copyright (c) 2016 Doyub Kim

#include <pch.h>
#include <physics_helpers.h>
#include <jet/array_utils.h>
#include <jet/grid_fractional_boundary_condition_solver3.h>
#include <jet/level_set_utils.h>
#include <jet/surface_to_implicit3.h>
#include <algorithm>

using namespace jet;

GridFractionalBoundaryConditionSolver3
::GridFractionalBoundaryConditionSolver3() {
}

GridFractionalBoundaryConditionSolver3::
~GridFractionalBoundaryConditionSolver3() {
}

void GridFractionalBoundaryConditionSolver3::constrainVelocity(
    FaceCenteredGrid3* velocity,
    unsigned int extrapolationDepth) {
    Size3 size = velocity->resolution();
    if (_colliderSdf.resolution() != size) {
        updateCollider(
            collider(),
            size,
            velocity->gridSpacing(),
            velocity->origin());
    }

    auto u = velocity->uAccessor();
    auto v = velocity->vAccessor();
    auto w = velocity->wAccessor();
    auto uPos = velocity->uPosition();
    auto vPos = velocity->vPosition();
    auto wPos = velocity->wPosition();

    Array3<double> uTemp(u.size());
    Array3<double> vTemp(v.size());
    Array3<double> wTemp(w.size());
    Array3<char> uMarker(u.size(), 1);
    Array3<char> vMarker(v.size(), 1);
    Array3<char> wMarker(w.size(), 1);

    Vector3D h = velocity->gridSpacing();

    // Assign collider's velocity first and initialize markers
    velocity->parallelForEachUIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = uPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.5 * h.x, 0.0, 0.0));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.5 * h.x, 0.0, 0.0));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            uMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            u(i, j, k) = colliderVel.x;
            uMarker(i, j, k) = 0;
        }
    });

    velocity->parallelForEachVIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = vPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.0, 0.5 * h.y, 0.0));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.0, 0.5 * h.y, 0.0));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            vMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            v(i, j, k) = colliderVel.y;
            vMarker(i, j, k) = 0;
        }
    });

    velocity->parallelForEachWIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = wPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.0, 0.0, 0.5 * h.z));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.0, 0.0, 0.5 * h.z));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            wMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            w(i, j, k) = colliderVel.z;
            wMarker(i, j, k) = 0;
        }
    });

    // Free-slip: Extrapolate fluid velocity into the collider
    extrapolateToRegion(
        velocity->uConstAccessor(), uMarker, extrapolationDepth, u);
    extrapolateToRegion(
        velocity->vConstAccessor(), vMarker, extrapolationDepth, v);
    extrapolateToRegion(
        velocity->wConstAccessor(), wMarker, extrapolationDepth, w);

    // No-flux: project the extrapolated velocity to the collider's surface
    // normal
    velocity->parallelForEachUIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = uPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                uTemp(i, j, k) = velp.x;
            } else {
                uTemp(i, j, k) = colliderVel.x;
            }
        } else {
            uTemp(i, j, k) = u(i, j, k);
        }
    });

    velocity->parallelForEachVIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = vPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                vTemp(i, j, k) = velp.y;
            } else {
                vTemp(i, j, k) = colliderVel.y;
            }
        } else {
            vTemp(i, j, k) = v(i, j, k);
        }
    });

    velocity->parallelForEachWIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = wPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                wTemp(i, j, k) = velp.z;
            } else {
                wTemp(i, j, k) = colliderVel.z;
            }
        } else {
            wTemp(i, j, k) = v(i, j, k);
        }
    });

    // Transfer results
    u.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        u(i, j, k) = uTemp(i, j, k);
    });
    v.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        v(i, j, k) = vTemp(i, j, k);
    });
    w.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        w(i, j, k) = wTemp(i, j, k);
    });

    // No-flux: Project velocity on the domain boundary if closed
    if (closedDomainBoundaryFlag() & kDirectionLeft) {
        for (size_t k = 0; k < u.size().z; ++k) {
            for (size_t j = 0; j < u.size().y; ++j) {
                u(0, j, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionRight) {
        for (size_t k = 0; k < u.size().z; ++k) {
            for (size_t j = 0; j < u.size().y; ++j) {
                u(u.size().x - 1, j, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionDown) {
        for (size_t k = 0; k < v.size().z; ++k) {
            for (size_t i = 0; i < v.size().x; ++i) {
                v(i, 0, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionUp) {
        for (size_t k = 0; k < v.size().z; ++k) {
            for (size_t i = 0; i < v.size().x; ++i) {
                v(i, v.size().y - 1, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionBack) {
        for (size_t j = 0; j < w.size().y; ++j) {
            for (size_t i = 0; i < w.size().x; ++i) {
                w(i, j, 0) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionFront) {
        for (size_t j = 0; j < w.size().y; ++j) {
            for (size_t i = 0; i < w.size().x; ++i) {
                w(i, j, w.size().z - 1) = 0;
            }
        }
    }
}

const CellCenteredScalarGrid3&
GridFractionalBoundaryConditionSolver3::colliderSdf() const {
    return _colliderSdf;
}

void GridFractionalBoundaryConditionSolver3::onColliderUpdated(
    const Size3& gridSize,
    const Vector3D& gridSpacing,
    const Vector3D& gridOrigin) {
    _colliderSdf.resize(gridSize, gridSpacing, gridOrigin);

    if (collider() != nullptr) {
        Surface3Ptr surface = collider()->surface();
        ImplicitSurface3Ptr implicitSurface
            = std::dynamic_pointer_cast<ImplicitSurface3>(surface);
        if (implicitSurface == nullptr) {
            implicitSurface = std::make_shared<SurfaceToImplicit3>(surface);
        }

        _colliderSdf.fill([&](const Vector3D& pt) {
            return implicitSurface->signedDistance(pt);
        });
    } else {
        _colliderSdf.fill(kMaxD);
    }
}
<commit_msg>Fix wrong array accessor problem<commit_after>// Copyright (c) 2016 Doyub Kim

#include <pch.h>
#include <physics_helpers.h>
#include <jet/array_utils.h>
#include <jet/grid_fractional_boundary_condition_solver3.h>
#include <jet/level_set_utils.h>
#include <jet/surface_to_implicit3.h>
#include <algorithm>

using namespace jet;

GridFractionalBoundaryConditionSolver3
::GridFractionalBoundaryConditionSolver3() {
}

GridFractionalBoundaryConditionSolver3::
~GridFractionalBoundaryConditionSolver3() {
}

void GridFractionalBoundaryConditionSolver3::constrainVelocity(
    FaceCenteredGrid3* velocity,
    unsigned int extrapolationDepth) {
    Size3 size = velocity->resolution();
    if (_colliderSdf.resolution() != size) {
        updateCollider(
            collider(),
            size,
            velocity->gridSpacing(),
            velocity->origin());
    }

    auto u = velocity->uAccessor();
    auto v = velocity->vAccessor();
    auto w = velocity->wAccessor();
    auto uPos = velocity->uPosition();
    auto vPos = velocity->vPosition();
    auto wPos = velocity->wPosition();

    Array3<double> uTemp(u.size());
    Array3<double> vTemp(v.size());
    Array3<double> wTemp(w.size());
    Array3<char> uMarker(u.size(), 1);
    Array3<char> vMarker(v.size(), 1);
    Array3<char> wMarker(w.size(), 1);

    Vector3D h = velocity->gridSpacing();

    // Assign collider's velocity first and initialize markers
    velocity->parallelForEachUIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = uPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.5 * h.x, 0.0, 0.0));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.5 * h.x, 0.0, 0.0));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            uMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            u(i, j, k) = colliderVel.x;
            uMarker(i, j, k) = 0;
        }
    });

    velocity->parallelForEachVIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = vPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.0, 0.5 * h.y, 0.0));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.0, 0.5 * h.y, 0.0));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            vMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            v(i, j, k) = colliderVel.y;
            vMarker(i, j, k) = 0;
        }
    });

    velocity->parallelForEachWIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = wPos(i, j, k);
        double phi0 = _colliderSdf.sample(pt - Vector3D(0.0, 0.0, 0.5 * h.z));
        double phi1 = _colliderSdf.sample(pt + Vector3D(0.0, 0.0, 0.5 * h.z));
        double frac = fractionInsideSdf(phi0, phi1);
        frac = 1.0 - clamp(frac, 0.0, 1.0);

        if (frac > 0.0) {
            wMarker(i, j, k) = 1;
        } else {
            Vector3D colliderVel = collider()->velocityAt(pt);
            w(i, j, k) = colliderVel.z;
            wMarker(i, j, k) = 0;
        }
    });

    // Free-slip: Extrapolate fluid velocity into the collider
    extrapolateToRegion(
        velocity->uConstAccessor(), uMarker, extrapolationDepth, u);
    extrapolateToRegion(
        velocity->vConstAccessor(), vMarker, extrapolationDepth, v);
    extrapolateToRegion(
        velocity->wConstAccessor(), wMarker, extrapolationDepth, w);

    // No-flux: project the extrapolated velocity to the collider's surface
    // normal
    velocity->parallelForEachUIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = uPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                uTemp(i, j, k) = velp.x;
            } else {
                uTemp(i, j, k) = colliderVel.x;
            }
        } else {
            uTemp(i, j, k) = u(i, j, k);
        }
    });

    velocity->parallelForEachVIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = vPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                vTemp(i, j, k) = velp.y;
            } else {
                vTemp(i, j, k) = colliderVel.y;
            }
        } else {
            vTemp(i, j, k) = v(i, j, k);
        }
    });

    velocity->parallelForEachWIndex([&](size_t i, size_t j, size_t k) {
        Vector3D pt = wPos(i, j, k);
        if (isInsideSdf(_colliderSdf.sample(pt))) {
            Vector3D colliderVel = collider()->velocityAt(pt);
            Vector3D vel = velocity->sample(pt);
            Vector3D g = _colliderSdf.gradient(pt);
            if (g.lengthSquared() > 0.0) {
                Vector3D n = g.normalized();
                Vector3D velr = vel - colliderVel;
                Vector3D velt = projectAndApplyFriction(
                    velr, n, collider()->frictionCoefficient());

                Vector3D velp = velt + colliderVel;
                wTemp(i, j, k) = velp.z;
            } else {
                wTemp(i, j, k) = colliderVel.z;
            }
        } else {
            wTemp(i, j, k) = w(i, j, k);
        }
    });

    // Transfer results
    u.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        u(i, j, k) = uTemp(i, j, k);
    });
    v.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        v(i, j, k) = vTemp(i, j, k);
    });
    w.parallelForEachIndex([&](size_t i, size_t j, size_t k) {
        w(i, j, k) = wTemp(i, j, k);
    });

    // No-flux: Project velocity on the domain boundary if closed
    if (closedDomainBoundaryFlag() & kDirectionLeft) {
        for (size_t k = 0; k < u.size().z; ++k) {
            for (size_t j = 0; j < u.size().y; ++j) {
                u(0, j, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionRight) {
        for (size_t k = 0; k < u.size().z; ++k) {
            for (size_t j = 0; j < u.size().y; ++j) {
                u(u.size().x - 1, j, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionDown) {
        for (size_t k = 0; k < v.size().z; ++k) {
            for (size_t i = 0; i < v.size().x; ++i) {
                v(i, 0, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionUp) {
        for (size_t k = 0; k < v.size().z; ++k) {
            for (size_t i = 0; i < v.size().x; ++i) {
                v(i, v.size().y - 1, k) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionBack) {
        for (size_t j = 0; j < w.size().y; ++j) {
            for (size_t i = 0; i < w.size().x; ++i) {
                w(i, j, 0) = 0;
            }
        }
    }
    if (closedDomainBoundaryFlag() & kDirectionFront) {
        for (size_t j = 0; j < w.size().y; ++j) {
            for (size_t i = 0; i < w.size().x; ++i) {
                w(i, j, w.size().z - 1) = 0;
            }
        }
    }
}

const CellCenteredScalarGrid3&
GridFractionalBoundaryConditionSolver3::colliderSdf() const {
    return _colliderSdf;
}

void GridFractionalBoundaryConditionSolver3::onColliderUpdated(
    const Size3& gridSize,
    const Vector3D& gridSpacing,
    const Vector3D& gridOrigin) {
    _colliderSdf.resize(gridSize, gridSpacing, gridOrigin);

    if (collider() != nullptr) {
        Surface3Ptr surface = collider()->surface();
        ImplicitSurface3Ptr implicitSurface
            = std::dynamic_pointer_cast<ImplicitSurface3>(surface);
        if (implicitSurface == nullptr) {
            implicitSurface = std::make_shared<SurfaceToImplicit3>(surface);
        }

        _colliderSdf.fill([&](const Vector3D& pt) {
            return implicitSurface->signedDistance(pt);
        });
    } else {
        _colliderSdf.fill(kMaxD);
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: opostponedtruncationstream.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-10-19 14:34:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX
#define _SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif
#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
#include <com/sun/star/io/XSeekable.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XTRUNCATE_HPP_
#include <com/sun/star/io/XTruncate.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XSTREAM_HPP_
#include <com/sun/star/io/XStream.hpp>
#endif
#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
#include <com/sun/star/embed/XTransactedObject.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XSIMPLEFILEACCESS_HPP_
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XASYNCOUTPUTMONITOR_HPP_
#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#ifndef _CPPUHELPER_IMPLBASE6_HXX_
#include <cppuhelper/implbase6.hxx>
#endif

#ifndef INCLUDED_SFX2_DLLAPI_H
#include "sfx2/dllapi.h"
#endif

//==================================================================
// OPostponedTruncationFileStream
//
// Allows to get stream access to a file, where the first truncation
// of the file is postponed till the first writing. If no writing happens
// after the first truncation/creation, it has no effect. ( The postponing of
// the creation can be switched off during initialization. Here the postponing
// of the creation means that the file will be created immediatelly, but
// if nothing is written into it, it will be removed during destruction
// of the object. )
//
// On creation of this object the target file is scheduled for
// creation/truncation. But the action happens only during the first
// write access. After the first write access the object behaves
// itself as the original stream.
//==================================================================

struct PTFStreamData_Impl;
class SFX2_DLLPUBLIC OPostponedTruncationFileStream
        : public ::cppu::WeakImplHelper6 <
                                        ::com::sun::star::io::XStream,
                                        ::com::sun::star::io::XInputStream,
                                        ::com::sun::star::io::XOutputStream,
                                        ::com::sun::star::io::XTruncate,
                                        ::com::sun::star::io::XSeekable,
                                        ::com::sun::star::io::XAsyncOutputMonitor >
{
    ::osl::Mutex    m_aMutex;
    PTFStreamData_Impl* m_pStreamData;

    void CloseAll_Impl();

    void CheckScheduledTruncation_Impl();

public:

    OPostponedTruncationFileStream(
        const ::rtl::OUString& aURL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess,
        sal_Bool bDeleteNewIfNotWritten );

    ~OPostponedTruncationFileStream();

// com::sun::star::io::XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XInputStream
    virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL available(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XOutputStream
    virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL flush(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeOutput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XTruncate
    virtual void SAL_CALL truncate(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XSeekable
    virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int64 SAL_CALL getPosition(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int64 SAL_CALL getLength(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::io::XAsyncOutputMonitor
    virtual void SAL_CALL waitForCompletion(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

};

#endif //_SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.3.710); FILE MERGED 2008/04/01 15:39:21 thb 1.3.710.3: #i85898# Stripping all external header guards 2008/04/01 12:40:49 thb 1.3.710.2: #i85898# Stripping all external header guards 2008/03/31 13:38:29 rt 1.3.710.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: opostponedtruncationstream.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX
#define _SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <com/sun/star/io/XAsyncOutputMonitor.hpp>
#include <osl/mutex.hxx>
#include <cppuhelper/implbase6.hxx>
#include "sfx2/dllapi.h"

//==================================================================
// OPostponedTruncationFileStream
//
// Allows to get stream access to a file, where the first truncation
// of the file is postponed till the first writing. If no writing happens
// after the first truncation/creation, it has no effect. ( The postponing of
// the creation can be switched off during initialization. Here the postponing
// of the creation means that the file will be created immediatelly, but
// if nothing is written into it, it will be removed during destruction
// of the object. )
//
// On creation of this object the target file is scheduled for
// creation/truncation. But the action happens only during the first
// write access. After the first write access the object behaves
// itself as the original stream.
//==================================================================

struct PTFStreamData_Impl;
class SFX2_DLLPUBLIC OPostponedTruncationFileStream
        : public ::cppu::WeakImplHelper6 <
                                        ::com::sun::star::io::XStream,
                                        ::com::sun::star::io::XInputStream,
                                        ::com::sun::star::io::XOutputStream,
                                        ::com::sun::star::io::XTruncate,
                                        ::com::sun::star::io::XSeekable,
                                        ::com::sun::star::io::XAsyncOutputMonitor >
{
    ::osl::Mutex    m_aMutex;
    PTFStreamData_Impl* m_pStreamData;

    void CloseAll_Impl();

    void CheckScheduledTruncation_Impl();

public:

    OPostponedTruncationFileStream(
        const ::rtl::OUString& aURL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess,
        sal_Bool bDeleteNewIfNotWritten );

    ~OPostponedTruncationFileStream();

// com::sun::star::io::XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XInputStream
    virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int32 SAL_CALL available(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XOutputStream
    virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL flush(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeOutput(  ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XTruncate
    virtual void SAL_CALL truncate(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// com::sun::star::io::XSeekable
    virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int64 SAL_CALL getPosition(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int64 SAL_CALL getLength(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::io::XAsyncOutputMonitor
    virtual void SAL_CALL waitForCompletion(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

};

#endif //_SFX_OPOSTPONEDTRUNCATIONFILESTREAM_HXX

<|endoftext|>


<commit_before>/*
 * Copyright 2016-2019 libfptu authors: please see AUTHORS file.
 *
 * This file is part of libfptu, aka "Fast Positive Tuples".
 *
 * libfptu is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libfptu 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libfptu.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "../fptu_test.h"
#include "fast_positive/details/cpu_features.h"

#include <array>
#include <vector>

#include "fast_positive/details/warnings_push_pt.h"

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

#pragma pack(push, 1)
struct Foo {
  char x;
  int Bar;
};
#pragma pack(pop)

struct MyToken_FooBar_int : public FPTU_TOKEN(Foo, Bar) {
  MyToken_FooBar_int() noexcept {
    static_assert(static_offset == 1, "WTF?");
    static_assert(std::is_base_of<::fptu::details::token_static_tag,
                                  MyToken_FooBar_int>::value,
                  "WTF?");
    static_assert(MyToken_FooBar_int::is_static_token::value, "WTF?");
  }
};

FPTU_TEMPLATE_FOR_STATIC_TOKEN
bool probe2static(const TOKEN &token) {
  (void)token;
  return true;
}

bool probe2static(const fptu::token &token) {
  (void)token;
  return false;
}

TEST(Token, StaticPreplaced) {
  MyToken_FooBar_int token;

  EXPECT_TRUE(token.is_preplaced());
  EXPECT_FALSE(token.is_loose());
  EXPECT_FALSE(token.is_inlay());
  EXPECT_FALSE(token.is_collection());
  EXPECT_EQ(fptu::genus::i32, token.type());
  EXPECT_TRUE(probe2static(token));
  EXPECT_TRUE(MyToken_FooBar_int::is_static_preplaced());
  EXPECT_TRUE(MyToken_FooBar_int::is_static_token::value);

#ifndef __clang__
  const fptu::tuple_ro_weak tuple_ro;
  /* FIXME: CLANG ?-6-7-8 WTF? */
  EXPECT_THROW(tuple_ro.collection(token).empty(), ::fptu::collection_required);
#endif
}

#ifdef __clang__
TEST(clang_WTF, DISABLED_ExceptionHandling) {
#else
TEST(clang_WTF, ExceptionHandling) {
#endif
  try {
    bool got_collection_required_exception = false;
    try {
      // fptu::throw_collection_required();
      const fptu::tuple_ro_weak tuple_ro;
      MyToken_FooBar_int token;
      tuple_ro.collection(token).empty();
    } catch (const ::fptu::collection_required &) {
      got_collection_required_exception = true;
    }
    EXPECT_TRUE(got_collection_required_exception);
  } catch (const ::std::exception &e) {
    std::string msg = fptu::format("Unexpected exception type '%s': %s",
                                   typeid(e).name(), e.what());
    GTEST_FATAL_FAILURE_(msg.c_str());
  } catch (...) {
    GTEST_FATAL_FAILURE_("Unknown NOT std::exception");
  }
}

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

TEST(Smoke, trivia_set) {
  fptu::tuple_rw_managed rw;
  fptu::token token(fptu::u16, 0);
  rw.set_u16(token, 42);
  auto value = rw.get_u16(token);
  EXPECT_EQ(42, value);
}

TEST(Smoke, trivia_autogrowth) {
  fptu::tuple_rw_managed rw;
  fptu::token token(fptu::text, 0, true);
  EXPECT_GT(size_t(fptu::max_tuple_bytes_netto), rw.capacity());
  for (int i = 1; i < 555; ++i)
    rw.insert_string(token,
                     fptu::format("This is the string #%*d.", i - 555, i));

  EXPECT_EQ(size_t(fptu::max_tuple_bytes_netto), rw.capacity());
}

TEST(Smoke, trivia_managing) {
  cxx14_constexpr fptu::token token_utc32(fptu::genus::datetime_utc, 0);
  cxx14_constexpr fptu::token token_datetime64(fptu::genus::datetime_utc, 0);
  cxx14_constexpr fptu::token token_i64(fptu::i64, 0);
  fptu::tuple_rw_fixed rw_fixed;
  rw_fixed.set_datetime(token_utc32, fptu::datetime_t::now());
  rw_fixed.set_datetime(token_utc32, fptu::datetime_t::now_coarse());
  rw_fixed.set_datetime(token_datetime64, fptu::datetime_t::now_fine());
  rw_fixed.set_integer(token_i64, INT64_MIN);
  rw_fixed.set_integer(token_i64, INT64_MAX);

  fptu::tuple_ro_weak ro_weak = rw_fixed.take_weak().first;
  EXPECT_FALSE(ro_weak.empty());
  EXPECT_TRUE(ro_weak.is_present(token_utc32));
  EXPECT_TRUE(ro_weak.is_present(token_datetime64));
  EXPECT_TRUE(ro_weak.is_present(token_i64));

  fptu::tuple_ro_managed ro_managed = rw_fixed.take_managed_clone().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  ro_managed = rw_fixed.move_to_ro();
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = std::move(ro_managed);
  ro_managed = rw_fixed.take_managed_clone().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = fptu::tuple_rw_fixed::clone(ro_managed);
  ro_weak = rw_fixed.take_weak().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = fptu::tuple_rw_fixed::clone(ro_weak);
  ro_weak = rw_fixed.take_weak().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  EXPECT_EQ(1, ro_managed.get_buffer()->ref_counter);
  auto ro_managed2 = ro_managed;
  EXPECT_EQ(2, ro_managed.get_buffer()->ref_counter);
  ro_managed.purge();
  EXPECT_FALSE(ro_managed);
  EXPECT_EQ(1, ro_managed2.get_buffer()->ref_counter);
}

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

TEST(Smoke, trivia_schema_definition) {
  auto schema = fptu::schema::create();
  for (unsigned n = 0; n < 42; ++n)
    for (fptu::genus type = fptu::genus(0); type != fptu::genus::hole;
         type = fptu::genus(type + 1))
      schema->define_field(
          false, fptu::format("#%u of %s", n, std::to_string(type).c_str()),
          type);
  std::set<std::string> names = {"datafield1",   "event_src.host",
                                 "event_src.ip", "event_src.title",
                                 "generator",    "id",
                                 "mime",         "object.name",
                                 "reason",       "subject.group",
                                 "subject.id",   "tag",
                                 "type"};
  for (auto item : names)
    schema->define_field(item == "generator", std::move(item),
                         fptu::genus::text);
  fptu::defaults::setup(fptu::initiation_scale::small, std::move(schema));

  fptu::tuple_rw_managed rw;
  rw.set_string(fptu::defaults::schema->get_token("datafield1"),
                std::string("229099411"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.host"),
                std::string("91.142.135.113"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.ip"),
                std::string("91.142.135.113"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.title"),
                std::string("unix_like"));
  rw.set_string(fptu::defaults::schema->get_token("generator"),
                std::string("N8.0.1309"));
  rw.set_string(fptu::defaults::schema->get_token("id"),
                std::string("PT_UNIX_like_auditd_syslog_path_msg"));
  rw.set_string(fptu::defaults::schema->get_token("mime"),
                std::string("text/plain"));
  rw.set_string(fptu::defaults::schema->get_token("object.name"),
                std::string("/proc/1/comm"));
  rw.set_string(fptu::defaults::schema->get_token("reason"),
                std::string("File was created or deleted"));
  rw.set_string(fptu::defaults::schema->get_token("subject.group"),
                std::string("0"));
  rw.set_string(fptu::defaults::schema->get_token("subject.id"),
                std::string("0"));
  rw.set_string(fptu::defaults::schema->get_token("tag"),
                std::string("syslog"));
  rw.set_string(fptu::defaults::schema->get_token("type"), std::string("norm"));
  rw.take_managed_clone_optimized();
}

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

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>fptu-tests: add smoke-autogrowth_with_preplaced.<commit_after>/*
 * Copyright 2016-2019 libfptu authors: please see AUTHORS file.
 *
 * This file is part of libfptu, aka "Fast Positive Tuples".
 *
 * libfptu is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libfptu 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libfptu.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "../fptu_test.h"
#include "fast_positive/details/cpu_features.h"

#include <array>
#include <vector>

#include "fast_positive/details/warnings_push_pt.h"

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

#pragma pack(push, 1)
struct Foo {
  char x;
  int Bar;
};
#pragma pack(pop)

struct MyToken_FooBar_int : public FPTU_TOKEN(Foo, Bar) {
  MyToken_FooBar_int() noexcept {
    static_assert(static_offset == 1, "WTF?");
    static_assert(std::is_base_of<::fptu::details::token_static_tag,
                                  MyToken_FooBar_int>::value,
                  "WTF?");
    static_assert(MyToken_FooBar_int::is_static_token::value, "WTF?");
  }
};

FPTU_TEMPLATE_FOR_STATIC_TOKEN
bool probe2static(const TOKEN &token) {
  (void)token;
  return true;
}

bool probe2static(const fptu::token &token) {
  (void)token;
  return false;
}

TEST(Token, StaticPreplaced) {
  MyToken_FooBar_int token;

  EXPECT_TRUE(token.is_preplaced());
  EXPECT_FALSE(token.is_loose());
  EXPECT_FALSE(token.is_inlay());
  EXPECT_FALSE(token.is_collection());
  EXPECT_EQ(fptu::genus::i32, token.type());
  EXPECT_TRUE(probe2static(token));
  EXPECT_TRUE(MyToken_FooBar_int::is_static_preplaced());
  EXPECT_TRUE(MyToken_FooBar_int::is_static_token::value);

#ifndef __clang__
  const fptu::tuple_ro_weak tuple_ro;
  /* FIXME: CLANG ?-6-7-8 WTF? */
  EXPECT_THROW(tuple_ro.collection(token).empty(), ::fptu::collection_required);
#endif
}

#ifdef __clang__
TEST(clang_WTF, DISABLED_ExceptionHandling) {
#else
TEST(clang_WTF, ExceptionHandling) {
#endif
  try {
    bool got_collection_required_exception = false;
    try {
      // fptu::throw_collection_required();
      const fptu::tuple_ro_weak tuple_ro;
      MyToken_FooBar_int token;
      tuple_ro.collection(token).empty();
    } catch (const ::fptu::collection_required &) {
      got_collection_required_exception = true;
    }
    EXPECT_TRUE(got_collection_required_exception);
  } catch (const ::std::exception &e) {
    std::string msg = fptu::format("Unexpected exception type '%s': %s",
                                   typeid(e).name(), e.what());
    GTEST_FATAL_FAILURE_(msg.c_str());
  } catch (...) {
    GTEST_FATAL_FAILURE_("Unknown NOT std::exception");
  }
}

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

TEST(Smoke, trivia_set) {
  fptu::tuple_rw_managed rw;
  fptu::token token(fptu::u16, 0);
  rw.set_u16(token, 42);
  auto value = rw.get_u16(token);
  EXPECT_EQ(42, value);
}

TEST(Smoke, trivia_autogrowth) {
  fptu::tuple_rw_managed rw;
  fptu::token token(fptu::text, 0, true);
  EXPECT_GT(size_t(fptu::max_tuple_bytes_netto), rw.capacity());
  for (int i = 1; i < 555; ++i)
    rw.insert_string(token,
                     fptu::format("This is the string #%*d.", i - 555, i));

  EXPECT_EQ(size_t(fptu::max_tuple_bytes_netto), rw.capacity());
}

TEST(Smoke, autogrowth_with_preplaced) {
  auto schema = fptu::schema::create();

  std::vector<std::pair<std::string, std::size_t>> values = {
      {"event_src.host", 16},
      {"event_src.hostname", 16},
      {"event_src.subsys", 8},
      {"event_src.title", 7},
      {"event_src.vendor", 9}, /*{"generator", 9},*/
      {"id", 53},
      {"mime", 25},
      {"msgid", 4},
      {"object.id", 1037}};

  for (auto p : values)
    schema->define_loose(std::move(p.first), fptu::genus::text);

  schema->define_preplaced("generator", fptu::genus::text);
  fptu::defaults::setup(fptu::initiation_scale::small, std::move(schema));

  fptu::tuple_rw_managed rw;
  for (auto p : values) {
    std::string stub{};
    stub.resize(p.second, 'a');
    rw.set_string(fptu::defaults::schema->get_token(p.first.data()), stub);
  }
  rw.take_managed_clone_optimized();
}

TEST(Smoke, trivia_managing) {
  cxx14_constexpr fptu::token token_utc32(fptu::genus::datetime_utc, 0);
  cxx14_constexpr fptu::token token_datetime64(fptu::genus::datetime_utc, 0);
  cxx14_constexpr fptu::token token_i64(fptu::i64, 0);
  fptu::tuple_rw_fixed rw_fixed;
  rw_fixed.set_datetime(token_utc32, fptu::datetime_t::now());
  rw_fixed.set_datetime(token_utc32, fptu::datetime_t::now_coarse());
  rw_fixed.set_datetime(token_datetime64, fptu::datetime_t::now_fine());
  rw_fixed.set_integer(token_i64, INT64_MIN);
  rw_fixed.set_integer(token_i64, INT64_MAX);

  fptu::tuple_ro_weak ro_weak = rw_fixed.take_weak().first;
  EXPECT_FALSE(ro_weak.empty());
  EXPECT_TRUE(ro_weak.is_present(token_utc32));
  EXPECT_TRUE(ro_weak.is_present(token_datetime64));
  EXPECT_TRUE(ro_weak.is_present(token_i64));

  fptu::tuple_ro_managed ro_managed = rw_fixed.take_managed_clone().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  ro_managed = rw_fixed.move_to_ro();
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = std::move(ro_managed);
  ro_managed = rw_fixed.take_managed_clone().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = fptu::tuple_rw_fixed::clone(ro_managed);
  ro_weak = rw_fixed.take_weak().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  rw_fixed = fptu::tuple_rw_fixed::clone(ro_weak);
  ro_weak = rw_fixed.take_weak().first;
  EXPECT_EQ(ro_weak.size(), ro_managed.size());
  EXPECT_EQ(0,
            std::memcmp(ro_weak.data(), ro_managed.data(), ro_managed.size()));

  EXPECT_EQ(1, ro_managed.get_buffer()->ref_counter);
  auto ro_managed2 = ro_managed;
  EXPECT_EQ(2, ro_managed.get_buffer()->ref_counter);
  ro_managed.purge();
  EXPECT_FALSE(ro_managed);
  EXPECT_EQ(1, ro_managed2.get_buffer()->ref_counter);
}

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

TEST(Smoke, trivia_schema_definition) {
  auto schema = fptu::schema::create();
  for (unsigned n = 0; n < 42; ++n)
    for (fptu::genus type = fptu::genus(0); type != fptu::genus::hole;
         type = fptu::genus(type + 1))
      schema->define_field(
          false, fptu::format("#%u of %s", n, std::to_string(type).c_str()),
          type);
  std::set<std::string> names = {"datafield1",   "event_src.host",
                                 "event_src.ip", "event_src.title",
                                 "generator",    "id",
                                 "mime",         "object.name",
                                 "reason",       "subject.group",
                                 "subject.id",   "tag",
                                 "type"};
  for (auto item : names)
    schema->define_field(item == "generator", std::move(item),
                         fptu::genus::text);
  fptu::defaults::setup(fptu::initiation_scale::small, std::move(schema));

  fptu::tuple_rw_managed rw;
  rw.set_string(fptu::defaults::schema->get_token("datafield1"),
                std::string("229099411"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.host"),
                std::string("91.142.135.113"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.ip"),
                std::string("91.142.135.113"));
  rw.set_string(fptu::defaults::schema->get_token("event_src.title"),
                std::string("unix_like"));
  rw.set_string(fptu::defaults::schema->get_token("generator"),
                std::string("N8.0.1309"));
  rw.set_string(fptu::defaults::schema->get_token("id"),
                std::string("PT_UNIX_like_auditd_syslog_path_msg"));
  rw.set_string(fptu::defaults::schema->get_token("mime"),
                std::string("text/plain"));
  rw.set_string(fptu::defaults::schema->get_token("object.name"),
                std::string("/proc/1/comm"));
  rw.set_string(fptu::defaults::schema->get_token("reason"),
                std::string("File was created or deleted"));
  rw.set_string(fptu::defaults::schema->get_token("subject.group"),
                std::string("0"));
  rw.set_string(fptu::defaults::schema->get_token("subject.id"),
                std::string("0"));
  rw.set_string(fptu::defaults::schema->get_token("tag"),
                std::string("syslog"));
  rw.set_string(fptu::defaults::schema->get_token("type"), std::string("norm"));
  rw.take_managed_clone_optimized();
}

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

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<int OtherSize> struct symm_extra {
  template<typename M1, typename M2, typename Scalar>
  static void run(M1& m1, M1& m2, M2& rhs2, M2& rhs22, M2& rhs23, Scalar s1, Scalar s2)
  {
    m2 = m1.template triangularView<Lower>();
    VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<Lower>(),
                    rhs23 = (rhs2) * (m1));
    VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<Lower>(),
                    rhs23 = (s2*rhs2) * (s1*m1));
  }
};

template<> struct symm_extra<1> {
  template<typename M1, typename M2, typename Scalar>
  static void run(M1&, M1&, M2&, M2&, M2&, Scalar, Scalar) {}
};

template<typename Scalar, int Size, int OtherSize> void symm(int size = Size, int othersize = OtherSize)
{
  typedef typename NumTraits<Scalar>::Real RealScalar;

  typedef Matrix<Scalar, Size, Size> MatrixType;
  typedef Matrix<Scalar, Size, OtherSize> Rhs1;
  typedef Matrix<Scalar, OtherSize, Size> Rhs2;
  enum { order = OtherSize==1 ? 0 : RowMajor };
  typedef Matrix<Scalar, Size, OtherSize,order> Rhs3;
  typedef MatrixType::Index Index;

  Index rows = size;
  Index cols = size;

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols), m3;

  m1 = (m1+m1.adjoint()).eval();

  Rhs1 rhs1 = Rhs1::Random(cols, othersize), rhs12(cols, othersize), rhs13(cols, othersize);
  Rhs2 rhs2 = Rhs2::Random(othersize, rows), rhs22(othersize, rows), rhs23(othersize, rows);
  Rhs3 rhs3 = Rhs3::Random(cols, othersize), rhs32(cols, othersize), rhs33(cols, othersize);

  Scalar s1 = ei_random<Scalar>(),
         s2 = ei_random<Scalar>();

  m2 = m1.template triangularView<Lower>();
  m3 = m2.template selfadjointView<Lower>();
  VERIFY_IS_EQUAL(m1, m3);
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs1),
                   rhs13 = (s1*m1) * (s2*rhs1));

  m2 = m1.template triangularView<Upper>(); rhs12.setRandom(); rhs13 = rhs12;
  m3 = m2.template selfadjointView<Upper>();
  VERIFY_IS_EQUAL(m1, m3);
  VERIFY_IS_APPROX(rhs12 += (s1*m2).template selfadjointView<Upper>() * (s2*rhs1),
                   rhs13 += (s1*m1) * (s2*rhs1));

  m2 = m1.template triangularView<Lower>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Upper>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));

  // test row major = <...>
  m2 = m1.template triangularView<Lower>(); rhs12.setRandom(); rhs13 = rhs12;
  VERIFY_IS_APPROX(rhs12 -= (s1*m2).template selfadjointView<Lower>() * (s2*rhs3),
                   rhs13 -= (s1*m1) * (s2 * rhs3));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate(),
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());

  m2 = m1.template triangularView<Upper>(); rhs13 = rhs12;
  VERIFY_IS_APPROX(rhs12.noalias() += s1 * ((m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate()),
                   rhs13 += (s1*m1.adjoint()) * (s2*rhs3).conjugate());

  // test matrix * selfadjoint
  symm_extra<OtherSize>::run(m1,m2,rhs2,rhs22,rhs23,s1,s2);

}

void test_product_symm()
{
  for(int i = 0; i < g_repeat ; i++)
  {
    CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
    CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
    CALL_SUBTEST_3(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));

    CALL_SUBTEST_4(( symm<float,Dynamic,1>(ei_random<int>(10,320)) ));
    CALL_SUBTEST_5(( symm<double,Dynamic,1>(ei_random<int>(10,320)) ));
    CALL_SUBTEST_6(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) ));
  }
}
<commit_msg>add missing typename<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@gmail.com>
//
// Eigen 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 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<int OtherSize> struct symm_extra {
  template<typename M1, typename M2, typename Scalar>
  static void run(M1& m1, M1& m2, M2& rhs2, M2& rhs22, M2& rhs23, Scalar s1, Scalar s2)
  {
    m2 = m1.template triangularView<Lower>();
    VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<Lower>(),
                    rhs23 = (rhs2) * (m1));
    VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<Lower>(),
                    rhs23 = (s2*rhs2) * (s1*m1));
  }
};

template<> struct symm_extra<1> {
  template<typename M1, typename M2, typename Scalar>
  static void run(M1&, M1&, M2&, M2&, M2&, Scalar, Scalar) {}
};

template<typename Scalar, int Size, int OtherSize> void symm(int size = Size, int othersize = OtherSize)
{
  typedef typename NumTraits<Scalar>::Real RealScalar;

  typedef Matrix<Scalar, Size, Size> MatrixType;
  typedef Matrix<Scalar, Size, OtherSize> Rhs1;
  typedef Matrix<Scalar, OtherSize, Size> Rhs2;
  enum { order = OtherSize==1 ? 0 : RowMajor };
  typedef Matrix<Scalar, Size, OtherSize,order> Rhs3;
  typedef typename MatrixType::Index Index;

  Index rows = size;
  Index cols = size;

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols), m3;

  m1 = (m1+m1.adjoint()).eval();

  Rhs1 rhs1 = Rhs1::Random(cols, othersize), rhs12(cols, othersize), rhs13(cols, othersize);
  Rhs2 rhs2 = Rhs2::Random(othersize, rows), rhs22(othersize, rows), rhs23(othersize, rows);
  Rhs3 rhs3 = Rhs3::Random(cols, othersize), rhs32(cols, othersize), rhs33(cols, othersize);

  Scalar s1 = ei_random<Scalar>(),
         s2 = ei_random<Scalar>();

  m2 = m1.template triangularView<Lower>();
  m3 = m2.template selfadjointView<Lower>();
  VERIFY_IS_EQUAL(m1, m3);
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs1),
                   rhs13 = (s1*m1) * (s2*rhs1));

  m2 = m1.template triangularView<Upper>(); rhs12.setRandom(); rhs13 = rhs12;
  m3 = m2.template selfadjointView<Upper>();
  VERIFY_IS_EQUAL(m1, m3);
  VERIFY_IS_APPROX(rhs12 += (s1*m2).template selfadjointView<Upper>() * (s2*rhs1),
                   rhs13 += (s1*m1) * (s2*rhs1));

  m2 = m1.template triangularView<Lower>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Upper>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1) * (s2*rhs2.adjoint()));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));

  // test row major = <...>
  m2 = m1.template triangularView<Lower>(); rhs12.setRandom(); rhs13 = rhs12;
  VERIFY_IS_APPROX(rhs12 -= (s1*m2).template selfadjointView<Lower>() * (s2*rhs3),
                   rhs13 -= (s1*m1) * (s2 * rhs3));

  m2 = m1.template triangularView<Upper>();
  VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate(),
                   rhs13 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());

  m2 = m1.template triangularView<Upper>(); rhs13 = rhs12;
  VERIFY_IS_APPROX(rhs12.noalias() += s1 * ((m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate()),
                   rhs13 += (s1*m1.adjoint()) * (s2*rhs3).conjugate());

  // test matrix * selfadjoint
  symm_extra<OtherSize>::run(m1,m2,rhs2,rhs22,rhs23,s1,s2);

}

void test_product_symm()
{
  for(int i = 0; i < g_repeat ; i++)
  {
    CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
    CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));
    CALL_SUBTEST_3(( symm<std::complex<double>,Dynamic,Dynamic>(ei_random<int>(10,320),ei_random<int>(10,320)) ));

    CALL_SUBTEST_4(( symm<float,Dynamic,1>(ei_random<int>(10,320)) ));
    CALL_SUBTEST_5(( symm<double,Dynamic,1>(ei_random<int>(10,320)) ));
    CALL_SUBTEST_6(( symm<std::complex<double>,Dynamic,1>(ei_random<int>(10,320)) ));
  }
}
<|endoftext|>


<commit_before>#include "enchanthighlighter.hh"
#include <enchant++.h>
#include <QDebug>

EnchantHighlighter::EnchantHighlighter(QTextDocument *parent) :
    QSyntaxHighlighter(parent)
{
    format.setUnderlineColor(QColor(Qt::red));
    format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
}

EnchantHighlighter::~EnchantHighlighter() {}

void EnchantHighlighter::check(const QString &text, int begin, int i) {
    QStringRef sub(&text, begin, i-begin);
    auto ba = sub.toUtf8();
    if(!dict->check(std::string {ba.data(), (std::string::size_type)ba.size()}))
        setFormat(begin, i-begin, format);
}

void EnchantHighlighter::highlightBlock(const QString& text) {
    if(!dict)
        return;
    int begin = 0;
    int i = 0;
    for(; i<text.length(); ++i) {
        auto ch = text.at(i);
        if(ch < 'A') {
            if(begin >= i)
                begin++;
            else if(begin<i) {
                check(text, begin, i);
                begin = i+1;
            }
        }
    }
    if(begin < i)
        check(text, begin, i);
}

bool EnchantHighlighter::setLanguage(const std::string &lang) {
    if(!enchant::Broker::instance()->dict_exists(lang))
        return false;
    dict.reset(enchant::Broker::instance()->request_dict(lang));
    return true;
}
<commit_msg>Don't import QDebug<commit_after>#include "enchanthighlighter.hh"
#include <enchant++.h>

EnchantHighlighter::EnchantHighlighter(QTextDocument *parent) :
    QSyntaxHighlighter(parent)
{
    format.setUnderlineColor(QColor(Qt::red));
    format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
}

EnchantHighlighter::~EnchantHighlighter() {}

void EnchantHighlighter::check(const QString &text, int begin, int i) {
    QStringRef sub(&text, begin, i-begin);
    auto ba = sub.toUtf8();
    if(!dict->check(std::string {ba.data(), (std::string::size_type)ba.size()}))
        setFormat(begin, i-begin, format);
}

void EnchantHighlighter::highlightBlock(const QString& text) {
    if(!dict)
        return;
    int begin = 0;
    int i = 0;
    for(; i<text.length(); ++i) {
        auto ch = text.at(i);
        if(ch < 'A') {
            if(begin >= i)
                begin++;
            else if(begin<i) {
                check(text, begin, i);
                begin = i+1;
            }
        }
    }
    if(begin < i)
        check(text, begin, i);
}

bool EnchantHighlighter::setLanguage(const std::string &lang) {
    if(!enchant::Broker::instance()->dict_exists(lang))
        return false;
    dict.reset(enchant::Broker::instance()->request_dict(lang));
    return true;
}
<|endoftext|>


<commit_before>#include "internal.hh"

#include <cstring>

using namespace std;

DWARFPP_BEGIN_NAMESPACE

sec_offset
value::get_section_offset() const
{
        return cu->info.offset + offset;
}

taddr
value::as_address() const
{
        if (form != DW_FORM::addr)
                throw value_type_mismatch("cannot read " + to_string(typ) + " as address");

        cursor cur(cu->subsec, offset);
        return cur.address();
}

const void *
value::as_block(size_t *size_out) const
{
        // XXX It appears that expressions are often encoded as
        // blocks, not as exprlocs.  Need DW_AT-aware types?
        // XXX Blocks can contain all sorts of things, including
        // references, which couldn't be resolved by callers in the
        // current minimal API.
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::block1:
                *size_out = cur.fixed<uint8_t>();
                break;
        case DW_FORM::block2:
                *size_out = cur.fixed<uint16_t>();
                break;
        case DW_FORM::block4:
                *size_out = cur.fixed<uint32_t>();
                break;
        case DW_FORM::block:
        case DW_FORM::exprloc:
                *size_out = cur.uleb128();
                break;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as block");
        }
        cur.ensure(*size_out);
        return cur.pos;
}

uint64_t
value::as_uconstant() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data1:
                return cur.fixed<uint8_t>();
        case DW_FORM::data2:
                return cur.fixed<uint16_t>();
        case DW_FORM::data4:
                return cur.fixed<uint32_t>();
        case DW_FORM::data8:
                return cur.fixed<uint64_t>();
        case DW_FORM::udata:
                return cur.uleb128();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as uconstant");
        }
}

int64_t
value::as_sconstant() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data1:
                return cur.fixed<int8_t>();
        case DW_FORM::data2:
                return cur.fixed<int16_t>();
        case DW_FORM::data4:
                return cur.fixed<int32_t>();
        case DW_FORM::data8:
                return cur.fixed<int64_t>();
        case DW_FORM::sdata:
                return cur.sleb128();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as sconstant");
        }
}

expr
value::as_exprloc() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        size_t size;
        // Prior to DWARF 4, exprlocs were encoded as blocks.
        switch (form) {
        case DW_FORM::exprloc:
        case DW_FORM::block:
                size = cur.uleb128();
                break;
        case DW_FORM::block1:
                size = cur.fixed<uint8_t>();
                break;
        case DW_FORM::block2:
                size = cur.fixed<uint16_t>();
                break;
        case DW_FORM::block4:
                size = cur.fixed<uint32_t>();
                break;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as exprloc");
        }
        return expr(cu, cur.section_offset(), size);
}

bool
value::as_flag() const
{
        switch (form) {
        case DW_FORM::flag: {
                cursor cur(cu->subsec, offset);
                return cur.fixed<ubyte>() != 0;
        }
        case DW_FORM::flag_present:
                return true;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as flag");
        }
}

die
value::as_reference() const
{
        sec_offset off;
        // XXX Would be nice if we could avoid this.  The cursor is
        // all overhead here.
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::ref1:
                off = cur.fixed<ubyte>();
                break;
        case DW_FORM::ref2:
                off = cur.fixed<uhalf>();
                break;
        case DW_FORM::ref4:
                off = cur.fixed<uword>();
                break;
        case DW_FORM::ref8:
                off = cur.fixed<uint64_t>();
                break;
        case DW_FORM::ref_udata:
                off = cur.uleb128();
                break;

                // XXX Implement
        case DW_FORM::ref_addr:
                throw runtime_error("DW_FORM::ref_addr not implemented");
        case DW_FORM::ref_sig8:
                throw runtime_error("DW_FORM::ref_sig8 not implemented");

        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as reference");
        }

        die d(cu);
        d.read(off);
        return d;
}

void
value::as_string(string &buf) const
{
        size_t size;
        const char *p = as_cstr(&size);
        buf.resize(size);
        memmove(&buf.front(), p, size);
}

string
value::as_string() const
{
        size_t size;
        const char *s = as_cstr(&size);
        return string(s, size);
}

const char *
value::as_cstr(size_t *size_out) const
{
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::string:
                return cur.cstr(size_out);
        case DW_FORM::strp: {
                sec_offset off = cur.offset();
                cursor scur(cu->file->get_sec_str(), off);
                return scur.cstr(size_out);
        }
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as string");
        }
}

sec_offset
value::as_sec_offset() const
{
        // Prior to DWARF 4, sec_offsets were encoded as data4 or
        // data8.
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data4:
                return cur.fixed<uint32_t>();
        case DW_FORM::data8:
                return cur.fixed<uint64_t>();
        case DW_FORM::sec_offset:
                return cur.offset();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as sec_offset");
        }
}

void
value::resolve_indirect(DW_AT name)
{
        if (form != DW_FORM::indirect)
                return;

        cursor c(cu->subsec, offset);
        DW_FORM form;
        do {
                form = (DW_FORM)c.uleb128();
        } while (form == DW_FORM::indirect);
        typ = attribute_spec(name, form).type;
        offset = c.section_offset();
}

string
to_string(const value &v)
{
        switch (v.get_type()) {
        case value::type::invalid:
                return "<invalid value type>";
        case value::type::address:
                return "0x" + to_hex(v.as_address());
        case value::type::block: {
                size_t size;
                const char *b = (const char*)v.as_block(&size);
                string res = ::to_string(size) + " byte block:";
                for (size_t pos = 0; pos < size; ++pos) {
                        res += ' ';
                        res += to_hex(b[pos]);
                }
                return res;
        }
        case value::type::constant:
                return "0x" + to_hex(v.as_uconstant());
        case value::type::uconstant:
                return ::to_string(v.as_uconstant());
        case value::type::sconstant:
                return ::to_string(v.as_sconstant());
        case value::type::exprloc:
                // XXX
                return "<exprloc>";
        case value::type::flag:
                return v.as_flag() ? "true" : "false";
        case value::type::reference:
                return "<0x" + to_hex(v.as_reference().get_section_offset()) + ">";
        case value::type::string:
                return v.as_string();
        default:
                return "<to_string of " + to_string(v.get_type()) + " not implemented>";
        }
}

DWARFPP_END_NAMESPACE
<commit_msg>Finish value to_string<commit_after>#include "internal.hh"

#include <cstring>

using namespace std;

DWARFPP_BEGIN_NAMESPACE

sec_offset
value::get_section_offset() const
{
        return cu->info.offset + offset;
}

taddr
value::as_address() const
{
        if (form != DW_FORM::addr)
                throw value_type_mismatch("cannot read " + to_string(typ) + " as address");

        cursor cur(cu->subsec, offset);
        return cur.address();
}

const void *
value::as_block(size_t *size_out) const
{
        // XXX It appears that expressions are often encoded as
        // blocks, not as exprlocs.  Need DW_AT-aware types?
        // XXX Blocks can contain all sorts of things, including
        // references, which couldn't be resolved by callers in the
        // current minimal API.
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::block1:
                *size_out = cur.fixed<uint8_t>();
                break;
        case DW_FORM::block2:
                *size_out = cur.fixed<uint16_t>();
                break;
        case DW_FORM::block4:
                *size_out = cur.fixed<uint32_t>();
                break;
        case DW_FORM::block:
        case DW_FORM::exprloc:
                *size_out = cur.uleb128();
                break;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as block");
        }
        cur.ensure(*size_out);
        return cur.pos;
}

uint64_t
value::as_uconstant() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data1:
                return cur.fixed<uint8_t>();
        case DW_FORM::data2:
                return cur.fixed<uint16_t>();
        case DW_FORM::data4:
                return cur.fixed<uint32_t>();
        case DW_FORM::data8:
                return cur.fixed<uint64_t>();
        case DW_FORM::udata:
                return cur.uleb128();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as uconstant");
        }
}

int64_t
value::as_sconstant() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data1:
                return cur.fixed<int8_t>();
        case DW_FORM::data2:
                return cur.fixed<int16_t>();
        case DW_FORM::data4:
                return cur.fixed<int32_t>();
        case DW_FORM::data8:
                return cur.fixed<int64_t>();
        case DW_FORM::sdata:
                return cur.sleb128();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as sconstant");
        }
}

expr
value::as_exprloc() const
{
        // XXX Does automatic coercion
        cursor cur(cu->subsec, offset);
        size_t size;
        // Prior to DWARF 4, exprlocs were encoded as blocks.
        switch (form) {
        case DW_FORM::exprloc:
        case DW_FORM::block:
                size = cur.uleb128();
                break;
        case DW_FORM::block1:
                size = cur.fixed<uint8_t>();
                break;
        case DW_FORM::block2:
                size = cur.fixed<uint16_t>();
                break;
        case DW_FORM::block4:
                size = cur.fixed<uint32_t>();
                break;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as exprloc");
        }
        return expr(cu, cur.section_offset(), size);
}

bool
value::as_flag() const
{
        switch (form) {
        case DW_FORM::flag: {
                cursor cur(cu->subsec, offset);
                return cur.fixed<ubyte>() != 0;
        }
        case DW_FORM::flag_present:
                return true;
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as flag");
        }
}

die
value::as_reference() const
{
        sec_offset off;
        // XXX Would be nice if we could avoid this.  The cursor is
        // all overhead here.
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::ref1:
                off = cur.fixed<ubyte>();
                break;
        case DW_FORM::ref2:
                off = cur.fixed<uhalf>();
                break;
        case DW_FORM::ref4:
                off = cur.fixed<uword>();
                break;
        case DW_FORM::ref8:
                off = cur.fixed<uint64_t>();
                break;
        case DW_FORM::ref_udata:
                off = cur.uleb128();
                break;

                // XXX Implement
        case DW_FORM::ref_addr:
                throw runtime_error("DW_FORM::ref_addr not implemented");
        case DW_FORM::ref_sig8:
                throw runtime_error("DW_FORM::ref_sig8 not implemented");

        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as reference");
        }

        die d(cu);
        d.read(off);
        return d;
}

void
value::as_string(string &buf) const
{
        size_t size;
        const char *p = as_cstr(&size);
        buf.resize(size);
        memmove(&buf.front(), p, size);
}

string
value::as_string() const
{
        size_t size;
        const char *s = as_cstr(&size);
        return string(s, size);
}

const char *
value::as_cstr(size_t *size_out) const
{
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::string:
                return cur.cstr(size_out);
        case DW_FORM::strp: {
                sec_offset off = cur.offset();
                cursor scur(cu->file->get_sec_str(), off);
                return scur.cstr(size_out);
        }
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as string");
        }
}

sec_offset
value::as_sec_offset() const
{
        // Prior to DWARF 4, sec_offsets were encoded as data4 or
        // data8.
        cursor cur(cu->subsec, offset);
        switch (form) {
        case DW_FORM::data4:
                return cur.fixed<uint32_t>();
        case DW_FORM::data8:
                return cur.fixed<uint64_t>();
        case DW_FORM::sec_offset:
                return cur.offset();
        default:
                throw value_type_mismatch("cannot read " + to_string(typ) + " as sec_offset");
        }
}

void
value::resolve_indirect(DW_AT name)
{
        if (form != DW_FORM::indirect)
                return;

        cursor c(cu->subsec, offset);
        DW_FORM form;
        do {
                form = (DW_FORM)c.uleb128();
        } while (form == DW_FORM::indirect);
        typ = attribute_spec(name, form).type;
        offset = c.section_offset();
}

string
to_string(const value &v)
{
        switch (v.get_type()) {
        case value::type::invalid:
                return "<invalid value type>";
        case value::type::address:
                return "0x" + to_hex(v.as_address());
        case value::type::block: {
                size_t size;
                const char *b = (const char*)v.as_block(&size);
                string res = ::to_string(size) + " byte block:";
                for (size_t pos = 0; pos < size; ++pos) {
                        res += ' ';
                        res += to_hex(b[pos]);
                }
                return res;
        }
        case value::type::constant:
                return "0x" + to_hex(v.as_uconstant());
        case value::type::uconstant:
                return ::to_string(v.as_uconstant());
        case value::type::sconstant:
                return ::to_string(v.as_sconstant());
        case value::type::exprloc:
                // XXX
                return "<exprloc>";
        case value::type::flag:
                return v.as_flag() ? "true" : "false";
        case value::type::lineptr:
                return "<lineptr 0x" + to_hex(v.as_sec_offset()) + ">";
        case value::type::loclistptr:
                return "<loclistptr 0x" + to_hex(v.as_sec_offset()) + ">";
        case value::type::macptr:
                return "<macptr 0x" + to_hex(v.as_sec_offset()) + ">";
        case value::type::rangelistptr:
                return "<rangelistptr 0x" + to_hex(v.as_sec_offset()) + ">";
        case value::type::reference:
                return "<0x" + to_hex(v.as_reference().get_section_offset()) + ">";
        case value::type::string:
                return v.as_string();
        }
        return "<unexpected value type " + to_string(v.get_type()) + ">";
}

DWARFPP_END_NAMESPACE
<|endoftext|>


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

namespace sd
{

DialogListBox::DialogListBox( Window* pParent, WinBits nWinStyle ) :
    Control( pParent, nWinStyle ),
    mpChild( 0 )
{
    mpVScrollBar    = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
    mpHScrollBar    = new ScrollBar( this, WB_HSCROLL | WB_DRAG );
    mpScrollBarBox  = new ScrollBarBox( this );

    Link aLink( LINK( this, DialogListBox, ScrollBarHdl ) );
    mpVScrollBar->SetScrollHdl( aLink );
    mpHScrollBar->SetScrollHdl( aLink );

    mbVScroll       = false;
    mbHScroll       = false;
    mbAutoHScroll   = ( nWinStyle & WB_AUTOHSCROLL ) ? true : false;
}

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

DialogListBox::~DialogListBox()
{
    delete mpHScrollBar;
    delete mpVScrollBar;
    delete mpScrollBarBox;
    delete mpChild;
}

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

void DialogListBox::SetChildWindow( Window* pChild, const Size& rMinSize )
{
    if( mpChild )
        delete mpChild;

    mpChild = pChild;
    maMinSize = rMinSize;
    ImplResizeControls();
    ImplCheckScrollBars();
}

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

void DialogListBox::GetFocus()
{
    if( mpChild )
        mpChild->GrabFocus();
}

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

::Window* DialogListBox::GetPreferredKeyInputWindow()
{
    if( mpChild )
        return mpChild;
    else
        return this;
}

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

void DialogListBox::Resize()
{
    Control::Resize();
    ImplResizeControls();
    ImplCheckScrollBars();
}

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

IMPL_LINK( DialogListBox, ScrollBarHdl, ScrollBar*, pSB )
{
    ImplResizeChild();
    return 1;
}

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

void DialogListBox::ImplCheckScrollBars()
{
    bool bArrange = false;

    Size aOutSz = GetOutputSizePixel();

    // vert. ScrollBar
    if( aOutSz.Height() < maMinSize.Height() )
    {
        if( !mbVScroll )
            bArrange = true;
        mbVScroll = true;
    }
    else
    {
        if( mbVScroll )
            bArrange = true;
        mbVScroll = false;
    }

    // horz. ScrollBar
    if( mbAutoHScroll )
    {
        long nWidth = aOutSz.Width();
        if ( mbVScroll )
            nWidth -= mpVScrollBar->GetSizePixel().Width();
        if( nWidth < maMinSize.Width() )
        {
            if( !mbHScroll )
                bArrange = true;
            mbHScroll = true;

            if ( !mbVScroll )
            {
                int nHeight = aOutSz.Height() - mpHScrollBar->GetSizePixel().Height();
                if( nHeight < maMinSize.Height() )
                {
                    if( !mbVScroll )
                        bArrange = true;
                    mbVScroll = true;
                }
            }
        }
        else
        {
            if( mbHScroll )
                bArrange = true;
            mbHScroll = false;
        }
    }

    if( bArrange )
        ImplResizeControls();

    ImplInitScrollBars();
}

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

void DialogListBox::ImplInitScrollBars()
{
    if( mpChild )
    {
        Size aOutSize( GetOutputSizePixel() );
        if( mbHScroll ) aOutSize.Height() -= mpHScrollBar->GetSizePixel().Height();
        if( mbVScroll ) aOutSize.Width() -= mpVScrollBar->GetSizePixel().Width();

        if ( mbVScroll )
        {
            mpVScrollBar->SetRangeMax( maMinSize.Height() );
            mpVScrollBar->SetVisibleSize( aOutSize.Height() );
            mpVScrollBar->SetPageSize( 16 );
        }

        if ( mbHScroll )
        {
            mpHScrollBar->SetRangeMax( maMinSize.Width() );
            mpHScrollBar->SetVisibleSize( aOutSize.Width() );
            mpHScrollBar->SetPageSize( 16 );
        }
    }
}

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

void DialogListBox::ImplResizeControls()
{
    Size aOutSz( GetOutputSizePixel() );
    long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
    nSBWidth = CalcZoom( nSBWidth );

    maInnerSize = aOutSz;
    if ( mbVScroll )
        maInnerSize.Width() -= nSBWidth;
    if ( mbHScroll )
        maInnerSize.Height() -= nSBWidth;

    // ScrollBarBox
    if( mbVScroll && mbHScroll )
    {
        Point aBoxPos( maInnerSize.Width(), maInnerSize.Height() );
        mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
        mpScrollBarBox->Show();
    }
    else
    {
        mpScrollBarBox->Hide();
    }

    // vert. ScrollBar
    if( mbVScroll )
    {
        // Scrollbar on left or right side?
        Point aVPos( aOutSz.Width() - nSBWidth, 0 );
        mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, maInnerSize.Height() ) );
        mpVScrollBar->Show();
    }
    else
    {
        mpVScrollBar->Hide();
    }

    // horz. ScrollBar
    if( mbHScroll )
    {
        Point aHPos( 0, aOutSz.Height() - nSBWidth );
        mpHScrollBar->SetPosSizePixel( aHPos, Size( maInnerSize.Width(), nSBWidth ) );
        mpHScrollBar->Show();
    }
    else
    {
        mpHScrollBar->Hide();
    }

    ImplResizeChild();
}

void DialogListBox::ImplResizeChild()
{
    Point aWinPos;
    Size aSize( maInnerSize );

    int nOffset;
    if( mbHScroll )
    {
        nOffset = mpHScrollBar->GetThumbPos();
        aWinPos.X() = -nOffset;
        aSize.Width() += nOffset;
    }

    if( mbVScroll )
    {
        nOffset = mpVScrollBar->GetThumbPos();
        aWinPos.Y() = -nOffset;
        aSize.Height() += nOffset;
    }

    mpChild->SetPosSizePixel( aWinPos, aSize );
}

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

void DialogListBox::StateChanged( StateChangedType nType )
{
    if ( nType == STATE_CHANGE_INITSHOW )
    {
        ImplCheckScrollBars();
    }
    else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
    {
        BOOL bUpdate = IsUpdateMode();
        mpChild->SetUpdateMode( bUpdate );
        if ( bUpdate && IsReallyVisible() )
            ImplCheckScrollBars();
    }
    else if( nType == STATE_CHANGE_ENABLE )
    {
        mpHScrollBar->Enable( IsEnabled() );
        mpVScrollBar->Enable( IsEnabled() );
        mpScrollBarBox->Enable( IsEnabled() );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_ZOOM )
    {
        mpChild->SetZoom( GetZoom() );
        Resize();
    }
    else if ( nType == STATE_CHANGE_CONTROLFONT )
    {
        mpChild->SetControlFont( GetControlFont() );
    }
    else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    {
        mpChild->SetControlForeground( GetControlForeground() );
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        mpChild->SetControlBackground( GetControlBackground() );
    }

    Control::StateChanged( nType );
}

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

long DialogListBox::Notify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if ( rNEvt.GetType() == EVENT_COMMAND )
    {
        const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
        if ( rCEvt.GetCommand() == COMMAND_WHEEL )
        {
            const CommandWheelData* pData = rCEvt.GetWheelData();
            if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
            {
                nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
            }
        }
    }

    return nDone ? nDone : Window::Notify( rNEvt );
}

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

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

namespace sd
{

DialogListBox::DialogListBox( Window* pParent, WinBits nWinStyle ) :
    Control( pParent, nWinStyle ),
    mpChild( 0 )
{
    mpVScrollBar    = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
    mpHScrollBar    = new ScrollBar( this, WB_HSCROLL | WB_DRAG );
    mpScrollBarBox  = new ScrollBarBox( this );

    Link aLink( LINK( this, DialogListBox, ScrollBarHdl ) );
    mpVScrollBar->SetScrollHdl( aLink );
    mpHScrollBar->SetScrollHdl( aLink );

    mbVScroll       = false;
    mbHScroll       = false;
    mbAutoHScroll   = ( nWinStyle & WB_AUTOHSCROLL ) ? true : false;
}

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

DialogListBox::~DialogListBox()
{
    delete mpHScrollBar;
    delete mpVScrollBar;
    delete mpScrollBarBox;
    delete mpChild;
}

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

void DialogListBox::SetChildWindow( Window* pChild, const Size& rMinSize )
{
    if( mpChild )
        delete mpChild;

    mpChild = pChild;
    maMinSize = rMinSize;
    ImplResizeControls();
    ImplCheckScrollBars();
}

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

void DialogListBox::GetFocus()
{
    if( mpChild )
        mpChild->GrabFocus();
}

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

::Window* DialogListBox::GetPreferredKeyInputWindow()
{
    if( mpChild )
        return mpChild;
    else
        return this;
}

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

void DialogListBox::Resize()
{
    Control::Resize();
    ImplResizeControls();
    ImplCheckScrollBars();
}

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

IMPL_LINK( DialogListBox, ScrollBarHdl, ScrollBar*, pSB )
{
    ImplResizeChild();
    return 1;
}

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

void DialogListBox::ImplCheckScrollBars()
{
    bool bArrange = false;

    Size aOutSz = GetOutputSizePixel();

    // vert. ScrollBar
    if( aOutSz.Height() < maMinSize.Height() )
    {
        if( !mbVScroll )
            bArrange = true;
        mbVScroll = true;
    }
    else
    {
        if( mbVScroll )
            bArrange = true;
        mbVScroll = false;
    }

    // horz. ScrollBar
    if( mbAutoHScroll )
    {
        long nWidth = aOutSz.Width();
        if ( mbVScroll )
            nWidth -= mpVScrollBar->GetSizePixel().Width();
        if( nWidth < maMinSize.Width() )
        {
            if( !mbHScroll )
                bArrange = true;
            mbHScroll = true;

            if ( !mbVScroll )
            {
                int nHeight = aOutSz.Height() - mpHScrollBar->GetSizePixel().Height();
                if( nHeight < maMinSize.Height() )
                {
                    if( !mbVScroll )
                        bArrange = true;
                    mbVScroll = true;
                }
            }
        }
        else
        {
            if( mbHScroll )
                bArrange = true;
            mbHScroll = false;
        }
    }

    if( bArrange )
        ImplResizeControls();

    ImplInitScrollBars();
}

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

void DialogListBox::ImplInitScrollBars()
{
    if( mpChild )
    {
        Size aOutSize( GetOutputSizePixel() );
        if( mbHScroll ) aOutSize.Height() -= mpHScrollBar->GetSizePixel().Height();
        if( mbVScroll ) aOutSize.Width() -= mpVScrollBar->GetSizePixel().Width();

        if ( mbVScroll )
        {
            mpVScrollBar->SetRangeMax( maMinSize.Height() );
            mpVScrollBar->SetVisibleSize( aOutSize.Height() );
            mpVScrollBar->SetPageSize( 16 );
        }

        if ( mbHScroll )
        {
            mpHScrollBar->SetRangeMax( maMinSize.Width() );
            mpHScrollBar->SetVisibleSize( aOutSize.Width() );
            mpHScrollBar->SetPageSize( 16 );
        }
    }
}

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

void DialogListBox::ImplResizeControls()
{
    Size aOutSz( GetOutputSizePixel() );
    long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
    nSBWidth = CalcZoom( nSBWidth );

    maInnerSize = aOutSz;
    if ( mbVScroll )
        maInnerSize.Width() -= nSBWidth;
    if ( mbHScroll )
        maInnerSize.Height() -= nSBWidth;

    // ScrollBarBox
    if( mbVScroll && mbHScroll )
    {
        Point aBoxPos( maInnerSize.Width(), maInnerSize.Height() );
        mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
        mpScrollBarBox->Show();
    }
    else
    {
        mpScrollBarBox->Hide();
    }

    // vert. ScrollBar
    if( mbVScroll )
    {
        // Scrollbar on left or right side?
        Point aVPos( aOutSz.Width() - nSBWidth, 0 );
        mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, maInnerSize.Height() ) );
        mpVScrollBar->Show();
    }
    else
    {
        mpVScrollBar->Hide();
    }

    // horz. ScrollBar
    if( mbHScroll )
    {
        Point aHPos( 0, aOutSz.Height() - nSBWidth );
        mpHScrollBar->SetPosSizePixel( aHPos, Size( maInnerSize.Width(), nSBWidth ) );
        mpHScrollBar->Show();
    }
    else
    {
        mpHScrollBar->Hide();
    }

    ImplResizeChild();
}

void DialogListBox::ImplResizeChild()
{
    Point aWinPos;
    Size aSize( maInnerSize );

    int nOffset;
    if( mbHScroll )
    {
        nOffset = mpHScrollBar->GetThumbPos();
        aWinPos.X() = -nOffset;
        aSize.Width() += nOffset;
    }

    if( mbVScroll )
    {
        nOffset = mpVScrollBar->GetThumbPos();
        aWinPos.Y() = -nOffset;
        aSize.Height() += nOffset;
    }

    mpChild->SetPosSizePixel( aWinPos, aSize );
}

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

void DialogListBox::StateChanged( StateChangedType nType )
{
    if ( nType == STATE_CHANGE_INITSHOW )
    {
        ImplCheckScrollBars();
    }
    else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
    {
        BOOL bUpdate = IsUpdateMode();
        mpChild->SetUpdateMode( bUpdate );
        if ( bUpdate && IsReallyVisible() )
            ImplCheckScrollBars();
    }
    else if( nType == STATE_CHANGE_ENABLE )
    {
        mpHScrollBar->Enable( IsEnabled() );
        mpVScrollBar->Enable( IsEnabled() );
        mpScrollBarBox->Enable( IsEnabled() );
        Invalidate();
    }
    else if ( nType == STATE_CHANGE_ZOOM )
    {
        mpChild->SetZoom( GetZoom() );
        Resize();
    }
    else if ( nType == STATE_CHANGE_CONTROLFONT )
    {
        mpChild->SetControlFont( GetControlFont() );
    }
    else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
    {
        mpChild->SetControlForeground( GetControlForeground() );
    }
    else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
    {
        mpChild->SetControlBackground( GetControlBackground() );
    }

    Control::StateChanged( nType );
}

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

long DialogListBox::Notify( NotifyEvent& rNEvt )
{
    long nDone = 0;
    if ( rNEvt.GetType() == EVENT_COMMAND )
    {
        const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
        if ( rCEvt.GetCommand() == COMMAND_WHEEL )
        {
            const CommandWheelData* pData = rCEvt.GetWheelData();
            if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
            {
                nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
            }
        }
    }

    return nDone ? nDone : Window::Notify( rNEvt );
}

} //  namespace sd
<|endoftext|>