<commit_before>#include "Halide.h"

using namespace Halide;

int multi_type_test() {
    Func f1("f1"), f2("f2"), f3("f3"), f4("f4"), f5("f5"), f6("f6");
    Var x, y, z;

    f1(x, y, z) = cast<uint8_t>(1);
    f2(x, y, z) = cast<uint32_t>(f1(x+1, y, z) + f1(x, y+1, z));
    f3(x, y, z) = cast<uint16_t>(f2(x+1, y, z) + f2(x, y+1, z));
    f4(x, y, z) = cast<uint16_t>(f3(x+1, y, z) + f3(x, y+1, z));
    f5(x, y, z) = cast<uint32_t>(f4(x+1, y, z) + f4(x, y+1, z));
    f6(x, y, z) = cast<uint8_t>(f5(x+1, y, z) + f5(x, y+1, z));

    f6.compute_root().gpu_tile(x, y, 1, 1);
    f5.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f4.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f3.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f2.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f1.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);

    const int size_x = 200;
    const int size_y = 200;
    const int size_z = 4;

    Image<uint8_t> out = f6.realize(size_x, size_y, size_z);

    uint8_t correct = 32;
    for (int z = 0; z < size_z; z++) {
        for (int y = 0; y < size_y; y++) {
            for (int x = 0; x < size_x; x++) {
                if (out(x, y, z) != correct) {
                    printf("out(%d, %d, %d) = %d instead of %d\n",
                           x, y, z, out(x, y, z), correct);
                    return -1;
                }
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int pyramid_test() {
    const int levels = 10;
    const int size_x = 100;
    const int size_y = 100;

    Var x, y, z, xo, xi, yo, yi;

    std::vector<Func> funcs(levels);

    funcs[0](x, y) = 1;
    for (int i = 1; i < levels; ++i) {
        funcs[i](x, y) = funcs[i-1](2*x, y);
    }

    funcs[levels-1].compute_root()
        .gpu_tile(x, y, 4, 4);
    for (int i = levels-2; i >= 0; --i) {
        funcs[i].compute_at(funcs[levels-1], Var::gpu_blocks())
            .split(x, xo, xi, 1 << (levels - i - 1))
            .gpu_threads(xo, y);
    }

    Image<int> out = funcs[levels-1].realize(size_x, size_y);

    int correct = 1;
    for (int y = 0; y < size_y; y++) {
        for (int x = 0; x < size_x; x++) {
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n",
                       x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int inverted_pyramid_test() {
    const int levels = 6;
    const int size_x = 8*16;
    const int size_y = 8*16;

    Var x, y, z, yo, yi, xo, xi;

    std::vector<Func> funcs(levels);

    funcs[0](x, y) = 1;
    for (int i = 1; i < levels; ++i) {
        funcs[i](x, y) = funcs[i-1](x/2, y);
    }

    funcs[levels-1].compute_root()
        .tile(x, y, xo, yo, xi, yi, 16, 16)
        .gpu_tile(xo, yo, 8, 8);
    for (int i = levels-2; i >= 0; --i) {
        funcs[i].compute_at(funcs[levels-1], Var::gpu_blocks())
            .tile(x, y, xo, yo, xi, yi, 16, 16)
            .gpu_threads(xo, yo);
    }

    Image<int> out = funcs[levels-1].realize(size_x, size_y);

    int correct = 1;
    for (int y = 0; y < size_y; y++) {
        for (int x = 0; x < size_x; x++) {
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n",
                       x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int dynamic_shared_test() {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("Not running test because no gpu target enabled\n");
        return 0;
    }

    Func f1, f2, f3, f4;
    Var x, xo, xi;

    f1(x) = x;
    f2(x) = f1(x) + f1(2*x);
    f3(x) = f2(x) + f2(2*x);
    f4(x) = f3(x) + f3(2*x);

    f4.split(x, xo, xi, 16).gpu_tile(xo, 16);
    f3.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);
    f2.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);
    f1.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);

    // The amount of shared memory required varies with x

    Image<int> out = f4.realize(500);
    for (int x = 0; x < out.width(); x++) {
        int correct = 27*x;
        if (out(x) != correct) {
            printf("out(%d) = %d instead of %d\n",
                   x, out(x), correct);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}

int main(int argc, char **argv) {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("Not running test because no gpu target enabled\n");
        return 0;
    }

    printf("Running multi type test!\n");
    if (multi_type_test() != 0) {
        return -1;
    }

    printf("Running pyramid test!\n");
    if (pyramid_test() != 0) {
        return -1;
    }

    printf("Running inverted pyramid test!\n");
    if (inverted_pyramid_test() != 0) {
        return -1;
    }

    printf("Running dynamic shared test!\n");
    if (dynamic_shared_test() != 0) {
        return -1;
    }

    return 0;
}
<commit_msg>Limit shared memory usage to 32k<commit_after>#include "Halide.h"

using namespace Halide;

int multi_type_test() {
    Func f1("f1"), f2("f2"), f3("f3"), f4("f4"), f5("f5"), f6("f6");
    Var x, y, z;

    f1(x, y, z) = cast<uint8_t>(1);
    f2(x, y, z) = cast<uint32_t>(f1(x+1, y, z) + f1(x, y+1, z));
    f3(x, y, z) = cast<uint16_t>(f2(x+1, y, z) + f2(x, y+1, z));
    f4(x, y, z) = cast<uint16_t>(f3(x+1, y, z) + f3(x, y+1, z));
    f5(x, y, z) = cast<uint32_t>(f4(x+1, y, z) + f4(x, y+1, z));
    f6(x, y, z) = cast<uint8_t>(f5(x+1, y, z) + f5(x, y+1, z));

    f6.compute_root().gpu_tile(x, y, 1, 1);
    f5.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f4.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f3.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f2.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);
    f1.compute_at(f6, Var::gpu_blocks()).gpu_threads(x, y);

    const int size_x = 200;
    const int size_y = 200;
    const int size_z = 4;

    Image<uint8_t> out = f6.realize(size_x, size_y, size_z);

    uint8_t correct = 32;
    for (int z = 0; z < size_z; z++) {
        for (int y = 0; y < size_y; y++) {
            for (int x = 0; x < size_x; x++) {
                if (out(x, y, z) != correct) {
                    printf("out(%d, %d, %d) = %d instead of %d\n",
                           x, y, z, out(x, y, z), correct);
                    return -1;
                }
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int pyramid_test() {
    const int levels = 10;
    const int size_x = 100;
    const int size_y = 100;

    Var x, y, z, xo, xi, yo, yi;

    std::vector<Func> funcs(levels);

    funcs[0](x, y) = 1;
    for (int i = 1; i < levels; ++i) {
        funcs[i](x, y) = funcs[i-1](2*x, y);
    }

    funcs[levels-1].compute_root()
        .gpu_tile(x, y, 3, 4);
    for (int i = levels-2; i >= 0; --i) {
        funcs[i].compute_at(funcs[levels-1], Var::gpu_blocks())
            .split(x, xo, xi, 1 << (levels - i - 1))
            .gpu_threads(xo, y);
    }

    Image<int> out = funcs[levels-1].realize(size_x, size_y);

    int correct = 1;
    for (int y = 0; y < size_y; y++) {
        for (int x = 0; x < size_x; x++) {
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n",
                       x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int inverted_pyramid_test() {
    const int levels = 6;
    const int size_x = 8*16*4;
    const int size_y = 8*16*4;

    Var x, y, z, yo, yi, yii, xo, xi, xii;

    std::vector<Func> funcs(levels);

    funcs[0](x, y) = 1;
    for (int i = 1; i < levels; ++i) {
        funcs[i](x, y) = funcs[i-1](x/2, y);
    }

    funcs[levels-1].compute_root()
        .tile(x, y, xi, yi, 64, 64)
        .gpu_blocks(x, y)
        .tile(xi, yi, xii, yii, 16, 16)
        .gpu_threads(xi, yi);
    for (int i = levels-2; i >= 0; --i) {
        funcs[i].compute_at(funcs[levels-1], Var::gpu_blocks())
            .tile(x, y, xi, yi, 4, 4)
            .gpu_threads(xi, yi);
    }

    funcs[levels-1].bound(x, 0, size_x).bound(y, 0, size_y);

    Image<int> out = funcs[levels-1].realize(size_x, size_y);

    int correct = 1;
    for (int y = 0; y < size_y; y++) {
        for (int x = 0; x < size_x; x++) {
            if (out(x, y) != correct) {
                printf("out(%d, %d) = %d instead of %d\n",
                       x, y, out(x, y), correct);
                return -1;
            }
        }
    }

    printf("Success!\n");
    return 0;
}

int dynamic_shared_test() {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("Not running test because no gpu target enabled\n");
        return 0;
    }

    Func f1, f2, f3, f4;
    Var x, xo, xi;

    f1(x) = x;
    f2(x) = f1(x) + f1(2*x);
    f3(x) = f2(x) + f2(2*x);
    f4(x) = f3(x) + f3(2*x);

    f4.split(x, xo, xi, 16).gpu_tile(xo, 16);
    f3.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);
    f2.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);
    f1.compute_at(f4, Var::gpu_blocks()).split(x, xo, xi, 16).gpu_threads(xi);

    // The amount of shared memory required varies with x

    Image<int> out = f4.realize(500);
    for (int x = 0; x < out.width(); x++) {
        int correct = 27*x;
        if (out(x) != correct) {
            printf("out(%d) = %d instead of %d\n",
                   x, out(x), correct);
            return -1;
        }
    }

    printf("Success!\n");
    return 0;
}

int main(int argc, char **argv) {
    if (!get_jit_target_from_environment().has_gpu_feature()) {
        printf("Not running test because no gpu target enabled\n");
        return 0;
    }

    printf("Running multi type test!\n");
    if (multi_type_test() != 0) {
        return -1;
    }

    printf("Running pyramid test!\n");
    if (pyramid_test() != 0) {
        return -1;
    }

    printf("Running inverted pyramid test!\n");
    if (inverted_pyramid_test() != 0) {
        return -1;
    }

    printf("Running dynamic shared test!\n");
    if (dynamic_shared_test() != 0) {
        return -1;
    }

    return 0;
}
<|endoftext|>


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

#pragma hdrstop

#include "doc.hxx"
#include "node.hxx"
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif

#ifndef _FMTANCHR_HXX //autogen
#include <fmtanchr.hxx>
#endif
#include "flypos.hxx"
#include "frmfmt.hxx"
#include "dcontact.hxx"
#include "dview.hxx"
#include "flyfrm.hxx"
#include "dflyobj.hxx"
#include "ndindex.hxx"

SV_IMPL_OP_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr )

SwPosFlyFrm::SwPosFlyFrm( const SwNodeIndex& rIdx, const SwFrmFmt* pFmt,
                            USHORT nArrPos )
    : pNdIdx( (SwNodeIndex*) &rIdx ), pFrmFmt( pFmt )
{
    BOOL bFnd = FALSE;
    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
    if( FLY_PAGE == rAnchor.GetAnchorId() )
        pNdIdx = new SwNodeIndex( rIdx );
    else if( pFmt->GetDoc()->GetRootFrm() )
    {
        SwClientIter aIter( (SwFmt&)*pFmt );
        if( RES_FLYFRMFMT == pFmt->Which() )
        {
            // Schauen, ob es ein SdrObject dafuer gibt
            if( aIter.First( TYPE( SwFlyFrm) ) )
                nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum(),
                bFnd = TRUE;
        }
        else if( RES_DRAWFRMFMT == pFmt->Which() )
        {
            // Schauen, ob es ein SdrObject dafuer gibt
            if( aIter.First( TYPE(SwDrawContact) ) )
                nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum(),
                bFnd = TRUE;
        }
    }

    if( !bFnd )
    {
        nOrdNum = pFmt->GetDoc()->GetSpzFrmFmts()->Count();
        nOrdNum += nArrPos;
    }
}

SwPosFlyFrm::~SwPosFlyFrm()
{
    const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
    if( FLY_PAGE == rAnchor.GetAnchorId() )
        delete pNdIdx;
}

BOOL SwPosFlyFrm::operator==( const SwPosFlyFrm& rPosFly )
{
    return FALSE;   // FlyFrames koennen auf der gleichen Position stehen
}

BOOL SwPosFlyFrm::operator<( const SwPosFlyFrm& rPosFly )
{
    if( pNdIdx->GetIndex() == rPosFly.pNdIdx->GetIndex() )
    {
        // dann entscheidet die Ordnungsnummer!
        return nOrdNum < rPosFly.nOrdNum;
    }
    return pNdIdx->GetIndex() < rPosFly.pNdIdx->GetIndex();
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.1254); FILE MERGED 2005/09/05 13:40:16 rt 1.2.1254.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: flypos.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 04:13:27 $
 *
 *  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
 *
 ************************************************************************/

#pragma hdrstop

#include "doc.hxx"
#include "node.hxx"
#ifndef _DOCARY_HXX
#include <docary.hxx>
#endif

#ifndef _FMTANCHR_HXX //autogen
#include <fmtanchr.hxx>
#endif
#include "flypos.hxx"
#include "frmfmt.hxx"
#include "dcontact.hxx"
#include "dview.hxx"
#include "flyfrm.hxx"
#include "dflyobj.hxx"
#include "ndindex.hxx"

SV_IMPL_OP_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr )

SwPosFlyFrm::SwPosFlyFrm( const SwNodeIndex& rIdx, const SwFrmFmt* pFmt,
                            USHORT nArrPos )
    : pNdIdx( (SwNodeIndex*) &rIdx ), pFrmFmt( pFmt )
{
    BOOL bFnd = FALSE;
    const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
    if( FLY_PAGE == rAnchor.GetAnchorId() )
        pNdIdx = new SwNodeIndex( rIdx );
    else if( pFmt->GetDoc()->GetRootFrm() )
    {
        SwClientIter aIter( (SwFmt&)*pFmt );
        if( RES_FLYFRMFMT == pFmt->Which() )
        {
            // Schauen, ob es ein SdrObject dafuer gibt
            if( aIter.First( TYPE( SwFlyFrm) ) )
                nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum(),
                bFnd = TRUE;
        }
        else if( RES_DRAWFRMFMT == pFmt->Which() )
        {
            // Schauen, ob es ein SdrObject dafuer gibt
            if( aIter.First( TYPE(SwDrawContact) ) )
                nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum(),
                bFnd = TRUE;
        }
    }

    if( !bFnd )
    {
        nOrdNum = pFmt->GetDoc()->GetSpzFrmFmts()->Count();
        nOrdNum += nArrPos;
    }
}

SwPosFlyFrm::~SwPosFlyFrm()
{
    const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor();
    if( FLY_PAGE == rAnchor.GetAnchorId() )
        delete pNdIdx;
}

BOOL SwPosFlyFrm::operator==( const SwPosFlyFrm& rPosFly )
{
    return FALSE;   // FlyFrames koennen auf der gleichen Position stehen
}

BOOL SwPosFlyFrm::operator<( const SwPosFlyFrm& rPosFly )
{
    if( pNdIdx->GetIndex() == rPosFly.pNdIdx->GetIndex() )
    {
        // dann entscheidet die Ordnungsnummer!
        return nOrdNum < rPosFly.nOrdNum;
    }
    return pNdIdx->GetIndex() < rPosFly.pNdIdx->GetIndex();
}

<|endoftext|>


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

#pragma hdrstop

#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif
#ifndef _SWACORR_HXX
#include <swacorr.hxx>
#endif
#ifndef _SWBLOCKS_HXX
#include <swblocks.hxx>
#endif
#ifndef _SW_XMLTEXTBLOCKS_HXX
#include "SwXMLTextBlocks.hxx"
#endif
#ifndef _SWSERROR_H
#include <swerror.h>
#endif
#ifndef _DOCSH_HXX
#include <docsh.hxx>
#endif
#ifndef _EDITSH_HXX
#include <editsh.hxx>
#endif
#include <sot/storage.hxx>

TYPEINIT1( SwAutoCorrect, SvxAutoCorrect );

    //  - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
    //      koennen aus der Wortliste herausgeholt werden!)
    //      rShort ist der Stream-Name - gecryptet!

BOOL SwAutoCorrect::GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg, const String& rFileName, const String& rShort, String& rLong )
{
    ULONG nRet;
    if (rStg.is())
    {
        // mba: relative URLs don't make sense here
        SwXMLTextBlocks aBlk( rStg, rFileName );
        nRet = aBlk.GetText( rShort, rLong );
    }
    else
        ASSERT ( rStg.is(), "Someone passed SwAutoCorrect::GetLongText a dud storage!");
    return !IsError( nRet ) && rLong.Len();
}

    //  - Text mit Attributierung (kann nur der SWG - SWG-Format!)
    //      rShort ist der Stream-Name - gecryptet!
BOOL SwAutoCorrect::PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&  rStg, const String& rFileName, const String& rShort,
                            SfxObjectShell& rObjSh, String& rLong )
{
    if( !rObjSh.IsA( TYPE(SwDocShell) ) )
        return FALSE;

    SwDocShell& rDShell = (SwDocShell&)rObjSh;
    ULONG nRet = 0;

    // mba: relative URLs don't make sense here
    SwXMLTextBlocks aBlk( rStg, rFileName );
    SwDoc* pDoc = aBlk.GetDoc();

    nRet = aBlk.BeginPutDoc( rShort, rShort );
    if( !IsError( nRet ) )
    {
        ((SwEditShell*)rDShell.GetWrtShell())->_CopySelToDoc( pDoc );
        nRet = aBlk.PutDoc();
        aBlk.AddName ( rShort, rShort, FALSE );
        if( !IsError( nRet ) )
            nRet = aBlk.GetText( rShort, rLong );
    }
    return !IsError( nRet );
}

SwAutoCorrect::SwAutoCorrect( const SvxAutoCorrect& rACorr )
    : SvxAutoCorrect( rACorr )
{
    SwEditShell::SetAutoFmtFlags(&GetSwFlags());
}

SwAutoCorrect::~SwAutoCorrect()
{
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.8.386); FILE MERGED 2005/09/05 13:40:33 rt 1.8.386.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: swacorr.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 04:41:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif
#ifndef _SWACORR_HXX
#include <swacorr.hxx>
#endif
#ifndef _SWBLOCKS_HXX
#include <swblocks.hxx>
#endif
#ifndef _SW_XMLTEXTBLOCKS_HXX
#include "SwXMLTextBlocks.hxx"
#endif
#ifndef _SWSERROR_H
#include <swerror.h>
#endif
#ifndef _DOCSH_HXX
#include <docsh.hxx>
#endif
#ifndef _EDITSH_HXX
#include <editsh.hxx>
#endif
#include <sot/storage.hxx>

TYPEINIT1( SwAutoCorrect, SvxAutoCorrect );

    //  - return den Ersetzungstext (nur fuer SWG-Format, alle anderen
    //      koennen aus der Wortliste herausgeholt werden!)
    //      rShort ist der Stream-Name - gecryptet!

BOOL SwAutoCorrect::GetLongText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rStg, const String& rFileName, const String& rShort, String& rLong )
{
    ULONG nRet;
    if (rStg.is())
    {
        // mba: relative URLs don't make sense here
        SwXMLTextBlocks aBlk( rStg, rFileName );
        nRet = aBlk.GetText( rShort, rLong );
    }
    else
        ASSERT ( rStg.is(), "Someone passed SwAutoCorrect::GetLongText a dud storage!");
    return !IsError( nRet ) && rLong.Len();
}

    //  - Text mit Attributierung (kann nur der SWG - SWG-Format!)
    //      rShort ist der Stream-Name - gecryptet!
BOOL SwAutoCorrect::PutText( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >&  rStg, const String& rFileName, const String& rShort,
                            SfxObjectShell& rObjSh, String& rLong )
{
    if( !rObjSh.IsA( TYPE(SwDocShell) ) )
        return FALSE;

    SwDocShell& rDShell = (SwDocShell&)rObjSh;
    ULONG nRet = 0;

    // mba: relative URLs don't make sense here
    SwXMLTextBlocks aBlk( rStg, rFileName );
    SwDoc* pDoc = aBlk.GetDoc();

    nRet = aBlk.BeginPutDoc( rShort, rShort );
    if( !IsError( nRet ) )
    {
        ((SwEditShell*)rDShell.GetWrtShell())->_CopySelToDoc( pDoc );
        nRet = aBlk.PutDoc();
        aBlk.AddName ( rShort, rShort, FALSE );
        if( !IsError( nRet ) )
            nRet = aBlk.GetText( rShort, rLong );
    }
    return !IsError( nRet );
}

SwAutoCorrect::SwAutoCorrect( const SvxAutoCorrect& rACorr )
    : SvxAutoCorrect( rACorr )
{
    SwEditShell::SetAutoFmtFlags(&GetSwFlags());
}

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


<commit_before><commit_msg>sw: replace pointless unused position update in SwTxtNode::Update()<commit_after><|endoftext|>


<commit_before>#include "twister.h"

const unsigned CYCLE = 0x100;

//Suggest we wrap these arrays inside an fsm or test base class
const unsigned C_TRANS_ = 0xff;
int block_units[][0x10] = {
	0x74, 0x63, 0x69, 0x67, 0x72, 0x68, 0x6e, 0x6c, 0x61, 0x67, 0x74, 0x6c, 0x69, 0x73, 0x61, 0x61, 0x6f, 0x6d, 0x6f, 0x72, 0x6e, 0x72, 0x69, 0x6d, 0x6e, 0x6e, 0x65, 0x74, 0x72, 0x6e, 0x6b, 0x73, 0x61, 0x6f, 0x65, 0x69, 0x73, 0x64, 0x6c, 0x65, 0x69, 0x6b, 0x68, 0x68, 0x68, 0x65, 0x72, 0x64, 0x66, 0x74, 0x61, 0x73, 0x6f, 0x69, 0x65, 0x74, 0x69, 0x68, 0x6e, 0x65, 0x62, 0x74, 0x6b, 0x65
  };
int triad_units[][0x03] = {
	0x31, 0xfe, 0x45, 0x74, 0x68, 0x65, 0x74, 0x68, 0x61, 0x65, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x68, 0x61, 0x74, 0x68, 0x69, 0x73, 0x1a, 0x36, 0x49, 0x91, 0x43, 0x53
};
const int transition_seq[] = { 0xce, 0xab, 0xdf, 0xcf, 0xee,
                               0xcf, 0xad, 0xdf, 0xff, 0xce,
                               0x32, 0x40, 0xd3, 0x27, 0x82,
                               0xda, 0xee, 0xff, 0xfc, 0xbf,
                               0x1c, 0x90, 0x13, 0x4a, 0xa5,
                               0xe0, 0x21, 0x9f, 0xe1, 0xc6,
                               0xaf, 0x05, 0x81, 0xf0, 0xee,
                               0xe4, 0x38, 0x1f, 0x60, 0x24,
                               0x0c, 0x35, 0x51, 0x32, 0xcf,
                               0x12, 0x9a, 0x30, 0x44, 0x72,
                               0x51, 0x3c, 0x61, 0x2d, 0x5f,
                               0x04, 0x1c, 0x52, 0xca, 0xdf,
                               0x12, 0x0b, 0x30, 0xa0, 0x1e,
                               0x03, 0x14, 0x09, 0x73, 0x23,
                               0xf2, 0xca, 0xa2, 0x51, 0xc6,
                               0x01, 0xdf, 0x41, 0x96, 0xa0,
                               0x51, 0x19, 0x71, 0x23, 0x47,
                               0xcb, 0xbd, 0xba, 0xac, 0xdf,
			       0xdf, 0xde, 0xcd, 0xfd, 0xca };

int ENTRY_LINK__ = 0x05;
int ENTRY_LINK__TEST = 0x09;
int ENTRY_C_REF_ECM = 0x10;
int ENTRY_C_REF_ECM_TEST = 0x03;
int ENTRY_C_OUTER = 0x51;
int ENTRY_C_OUTER_PROD = 0x41;
int ENTRY_C_OUTER_PROD_TEST = 0x33;
int ENTRY_C_OUTER_PROD_TOR_TEST = 0x57;
int ENTRY_A_OUTER_PROD_TOR_TEST = 0xc9;
int ENTRY_B_OUTER_PROD_EUC_TEST = 0xaf;
int ENTRY_C_OUTER_PROD_EUC_TEST = 0xa1;
int ENTRY_C_INNER_PROD_EUC_TEST = 0xc5;
int ENTRY_C_INNER_PROD_ELIP_TEST = 0xa2;
int ENTRY_C_INNER_PROD_RELAY_TEST = 0xf5;
int ENTRY_C_BLOCK_REL_FLAG_TEST = 0x0fffffff;
int ENTRY_C_BLOCK_REL_FLAG_VECTOR = 0x0effffff;

unsigned reflect(unsigned center, unsigned (*r)(unsigned))
{
  return (*r)(center)^center;
}
unsigned char base(unsigned char a, unsigned char (*s)(unsigned char), int pos)
{
	return (*s)(pos)^a;
}

void transHomExt(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^base(d, g, d);
    }
    data[i] = d;
  }
}
void transHom(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^(*g)(d);
    }
    data[i] = d;
  }
}

void trans(vector<unsigned char>& data, unsigned char (*f)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d);
    }
    data[i] = d;
  }
}

vector<double> f_dist(vector<unsigned char>& in)
{
  vector<double> fdist;
  fdist.resize(256);
  for(unsigned i = 0; i<in.size(); i++)
  {
    fdist[in[i]]++;
  }

  for(unsigned i=0; i<fdist.size(); i++)
  {
    fdist[i] = (fdist[i] / in.size()) * 100;
  }

  return fdist;
}

double s_entropy(vector<double>& v)
{
  double entropy = 0;
  double p;

  for(unsigned i = 0; i < v.size(); i++)
  {
    p = v[i] / 100;
    if (p == 0) continue;
    entropy += p * std::log(p) / std::log(2);
  }
  return -entropy;
}
void rms(const string& s, string& r)
{
  for(unsigned int i=0; i<s.size(); i++)
  {
    if(::isspace(s[i])) continue;
    r+= s[i];
  }
}
//add extended euc
double sw(double weight, int i, int j, int (*inv)(int, int))
{
  return weight*(*inv)(i, j);
}
//Suggest we wrap these routines in a base class in particular for testing
//and expose test api
void hPerm(int s, int n, void (*p)(int), void (*inv)(int, int), void (*center)(int))
{
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST ] == s)
  {
	  (*center)(s);
	  return;
  }
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST ] == s)
  {
	  (*p)(s);
	  return;
  }
  if(s == 1)
  {
    (*p)(n);
    return;
  }
  for(int i=0; i< s; i++)
  {
    hPerm(s-1, n, p, inv, p);
    if(s%2 == 1)
      (*inv)(0, s-1);
    else
      (*inv)(i, s-1);
  }
}

double ic(const string& t)
{
  string text; rms(t, text);
  vector<double> freq(256,0);
  for(unsigned int i=0; i<text.size(); i++)
  {
    if(text[i] == ' ') continue;
    freq[text[i]] ++;
  }
  double sum=0;
  for(unsigned int i=0; i<freq.size(); i++)
  {
    if(freq[i] != 0)
    {
      double c = freq[i];
      if(c != 0)
        sum += c * (c - 1);
    }
  }
  double ic = 26 * sum / (text.size() * (text.size() - 1));
  return ic;
}

int outer_sect(int (*s)(int), int (*t)(int), int r, int q)
{
  return (*s)(r) * (*t)(q);
}

void switchIO(unsigned char (*p)(unsigned char, unsigned char), unsigned char m)
{
  //test seq
  (*p)(transition_seq[ENTRY_LINK__], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m);
  (*p)(transition_seq[ENTRY_C_REF_ECM], m);
  (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST  ], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_LINK__TEST]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_REF_ECM]);
}

//Suggest we wrap these in util base class, abstract col cont
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta, int (*col)(int x, int y))
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha, col);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}

std::tuple<int, int, int> extended_gcd(int __alpha, int __beta)
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
<commit_msg>block rel,  flag test, ext<commit_after>#include "twister.h"

const unsigned CYCLE = 0x100;

//Suggest we wrap these arrays inside an fsm or test base class
const unsigned C_TRANS_ = 0xff;
int block_units[][0x10] = {
	0x74, 0x63, 0x69, 0x67, 0x72, 0x68, 0x6e, 0x6c, 0x61, 0x67, 0x74, 0x6c, 0x69, 0x73, 0x61, 0x61, 0x6f, 0x6d, 0x6f, 0x72, 0x6e, 0x72, 0x69, 0x6d, 0x6e, 0x6e, 0x65, 0x74, 0x72, 0x6e, 0x6b, 0x73, 0x61, 0x6f, 0x65, 0x69, 0x73, 0x64, 0x6c, 0x65, 0x69, 0x6b, 0x68, 0x68, 0x68, 0x65, 0x72, 0x64, 0x66, 0x74, 0x61, 0x73, 0x6f, 0x69, 0x65, 0x74, 0x69, 0x68, 0x6e, 0x65, 0x62, 0x74, 0x6b, 0x65
  };
int triad_units[][0x03] = {
	0x31, 0xfe, 0x45, 0x74, 0x68, 0x65, 0x74, 0x68, 0x61, 0x65, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x68, 0x61, 0x74, 0x68, 0x69, 0x73, 0x1a, 0x36, 0x49, 0x91, 0x43, 0x53
};
const int transition_seq[] = { 0xce, 0xab, 0xdf, 0xcf, 0xee,
                               0xcf, 0xad, 0xdf, 0xff, 0xce,
                               0x32, 0x40, 0xd3, 0x27, 0x82,
                               0xda, 0xee, 0xff, 0xfc, 0xbf,
                               0x1c, 0x90, 0x13, 0x4a, 0xa5,
                               0xe0, 0x21, 0x9f, 0xe1, 0xc6,
                               0xaf, 0x05, 0x81, 0xf0, 0xee,
                               0xe4, 0x38, 0x1f, 0x60, 0x24,
                               0x0c, 0x35, 0x51, 0x32, 0xcf,
                               0x12, 0x9a, 0x30, 0x44, 0x72,
                               0x51, 0x3c, 0x61, 0x2d, 0x5f,
                               0x04, 0x1c, 0x52, 0xca, 0xdf,
                               0x12, 0x0b, 0x30, 0xa0, 0x1e,
                               0x03, 0x14, 0x09, 0x73, 0x23,
                               0xf2, 0xca, 0xa2, 0x51, 0xc6,
                               0x01, 0xdf, 0x41, 0x96, 0xa0,
                               0x51, 0x19, 0x71, 0x23, 0x47,
                               0xcb, 0xbd, 0xba, 0xac, 0xdf,
			       0xdf, 0xde, 0xcd, 0xfd, 0xca };

int ENTRY_LINK__ = 0x05;
int ENTRY_LINK__TEST = 0x09;
int ENTRY_C_REF_ECM = 0x10;
int ENTRY_C_REF_ECM_TEST = 0x03;
int ENTRY_C_OUTER = 0x51;
int ENTRY_C_OUTER_PROD = 0x41;
int ENTRY_C_OUTER_PROD_TEST = 0x33;
int ENTRY_C_OUTER_PROD_TOR_TEST = 0x57;
int ENTRY_A_OUTER_PROD_TOR_TEST = 0xc9;
int ENTRY_B_OUTER_PROD_EUC_TEST = 0xaf;
int ENTRY_C_OUTER_PROD_EUC_TEST = 0xa1;
int ENTRY_C_INNER_PROD_EUC_TEST = 0xc5;
int ENTRY_C_INNER_PROD_ELIP_TEST = 0xa2;
int ENTRY_C_INNER_PROD_RELAY_TEST = 0xf5;
int ENTRY_C_BLOCK_REL_FLAG_TEST = 0x0fffffff;
int ENTRY_C_BLOCK_REL_FLAG_VECTOR = 0x0effffff;

unsigned reflect(unsigned center, unsigned (*r)(unsigned))
{
  return (*r)(center)^center;
}
unsigned char base(unsigned char a, unsigned char (*s)(unsigned char), int pos)
{
	return (*s)(pos)^a;
}

void transHomExt(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^base(d, g, d);
    }
    data[i] = d;
  }
}
void transHom(vector<unsigned char>& data, unsigned char (*f)(unsigned char), unsigned char (*g)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d)^(*g)(d);
    }
    data[i] = d;
  }
}

void trans(vector<unsigned char>& data, unsigned char (*f)(unsigned char))
{
  for(unsigned i = 0; i<data.size(); i++)
  {
    unsigned char d = data[i];
    for(unsigned j=0; j<CYCLE; j++)
    {
      d = (*f)(d);
    }
    data[i] = d;
  }
}

vector<double> f_dist(vector<unsigned char>& in)
{
  vector<double> fdist;
  fdist.resize(256);
  for(unsigned i = 0; i<in.size(); i++)
  {
    fdist[in[i]]++;
  }

  for(unsigned i=0; i<fdist.size(); i++)
  {
    fdist[i] = (fdist[i] / in.size()) * 100;
  }

  return fdist;
}

double s_entropy(vector<double>& v)
{
  double entropy = 0;
  double p;

  for(unsigned i = 0; i < v.size(); i++)
  {
    p = v[i] / 100;
    if (p == 0) continue;
    entropy += p * std::log(p) / std::log(2);
  }
  return -entropy;
}
void rms(const string& s, string& r)
{
  for(unsigned int i=0; i<s.size(); i++)
  {
    if(::isspace(s[i])) continue;
    r+= s[i];
  }
}
//add extended euc
double sw(double weight, int i, int j, int (*inv)(int, int))
{
  return weight*(*inv)(i, j);
}
//Suggest we wrap these routines in a base class in particular for testing
//and expose test api
void hPerm(int s, int n, void (*p)(int), void (*inv)(int, int), void (*center)(int))
{
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST] == s)
  {
	  (*center)(s);
	  return;
  }
  if(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST ] == s)
  {
	  (*p)(s);
	  return;
  }
  if(s == 1)
  {
    (*p)(n);
    return;
  }
  for(int i=0; i< s; i++)
  {
    hPerm(s-1, n, p, inv, p);
    if(s%2 == 1)
      (*inv)(0, s-1);
    else
      (*inv)(i, s-1);
  }
}

double ic(const string& t)
{
  string text; rms(t, text);
  vector<double> freq(256,0);
  for(unsigned int i=0; i<text.size(); i++)
  {
    if(text[i] == ' ') continue;
    freq[text[i]] ++;
  }
  double sum=0;
  for(unsigned int i=0; i<freq.size(); i++)
  {
    if(freq[i] != 0)
    {
      double c = freq[i];
      if(c != 0)
        sum += c * (c - 1);
    }
  }
  double ic = 26 * sum / (text.size() * (text.size() - 1));
  return ic;
}

int outer_sect(int (*s)(int), int (*t)(int), int r, int q)
{
  return (*s)(r) * (*t)(q);
}

void switchIO(unsigned char (*p)(unsigned char, unsigned char), unsigned char m)
{
  //test seq
  (*p)(transition_seq[ENTRY_LINK__], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m);
  (*p)(transition_seq[ENTRY_C_REF_ECM], m);
  (*p)(transition_seq[ENTRY_C_INNER_PROD_ELIP_TEST  ], m);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_LINK__TEST]);
  (*p)(transition_seq[ENTRY_LINK__TEST], m ^ transition_seq[ENTRY_C_REF_ECM]);
}

//Suggest we wrap these in util base class, abstract col cont
std::tuple<int, int, int> extended_gcd(int __alpha, int __beta, int (*col)(int x, int y))
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha, col);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}

std::tuple<int, int, int> extended_gcd(int __alpha, int __beta)
{
  if(__alpha == 0) return make_tuple(__beta,0,1);
  int __com=0;
  int x=0;
  int y=0;
  tie(__com, x, y) = extended_gcd(__beta%__alpha, __alpha);
  return make_tuple(__com, y-(__beta/__alpha)*x, x);
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <queue>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#include <stack>
#include <queue>

using namespace std;

queue<string> lv1;
queue<string> lv2;
queue<string> lv3;

string temp;
int templv;
int temptime=0;
int usernum;
int users=0;
int read(int now){
	if(now < temptime || users>usernum) return 0;

	do{

		if(temp.empty()){

		}else{

			switch(templv){
				case 1:
					lv1.push(temp);break;
				case 2:
					lv2.push(temp);break;
				case 3:
					lv3.push(temp);break;
			}
		}
		users++;
		if(users<=usernum){
			cin >>temptime>>templv>>temp;
		}
		else
			return 0;
	}while(temptime<=now);

}
int pop(){

	if(lv3.size()>0){
		cout<<lv3.front()<<endl;
		lv3.pop();
		return 3;
	}

	if(lv2.size()>0){
		cout<<lv2.front()<<endl;
		lv2.pop();
		return 2;
	}

	if(lv1.size()>0){
		cout<<lv1.front()<<endl;
		lv1.pop();
		return 1;
	}
	return 0;
}
int main(int argc, char const *argv[])
{
		int time;
		scanf("%d%d",&usernum,&time);
		for (int i = 0; i < time; ++i)
		{
			read(i);
			//cout<<i<<"\n"<<lv1.size()<<lv2.size()<<lv3.size()<<endl;
			if(i%5==0)
				pop();
		}
		//while(pop()){}

	return 0;
}<commit_msg>update uoj2254<commit_after>#include <stdio.h>
#include <queue>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#include <stack>
#include <queue>

using namespace std;

queue<string> lv1;
queue<string> lv2;
queue<string> lv3;
queue<string> lv4;

string temp;
int templv;
int temptime=0;
int usernum;
int users=0;
int read(int now){
	if(now < temptime || users>usernum) return 0;

	do{

		if(temp.empty()){

		}else{

			switch(templv){
				case 1:
					lv1.push(temp);break;
				case 2:
					lv2.push(temp);break;
					case 3:
					lv3.push(temp);break;
					case 4:
					lv4.push(temp);break;
			}
		}
		users++;
		if(users<=usernum){
			cin >>temptime>>templv>>temp;
		}
		else
			return 0;
	}while(temptime<=now);

}
int pop(){

if(lv4.size()>0){
		cout<<lv4.front()<<endl;
		lv4.pop();
		return 4;
	}

	if(lv3.size()>0){
		cout<<lv3.front()<<endl;
		lv3.pop();
		return 3;
	}

	if(lv2.size()>0){
		cout<<lv2.front()<<endl;
		lv2.pop();
		return 2;
	}

	if(lv1.size()>0){
		cout<<lv1.front()<<endl;
		lv1.pop();
		return 1;
	}
	return 0;
}
int main(int argc, char const *argv[])
{
		int time;
		scanf("%d%d",&usernum,&time);
		for (int i = 0; i < time; ++i)
		{
			read(i);
			//cout<<i<<"\n"<<lv1.size()<<lv2.size()<<lv3.size()<<endl;
			if(i%5==0)
				pop();
		}
		//while(pop()){}

	return 0;
}<|endoftext|>


<commit_before>#include "tictactoe.h"
#include <iostream>
#include <utility>

using namespace std;

const string TicTacToe::SPACE = "   ";
const int TicTacToe::X = 1;
const int TicTacToe::O = 2;
const string TicTacToe::LINE = "-----------";

TicTacToe::TicTacToe() {
    for(int row = 0; row < 3; row++) {
        for(int col = 0; col < 3; col++) {
            board[row][col] = 0;
        }
    }
}

void TicTacToe::draw_board() {
    cout << LINE << endl;
    for(int row = 0; row < 3; row++) {
        cout << "|";
        for(int col = 0; col < 3; col++) {
            cout << char_map[board[row][col]] << (col == 2 ? "|" : SPACE);
        }
        cout << endl;
    }
    cout << LINE << endl;
}

bool TicTacToe::game_over() {
    return check_rows() || check_cols() || check_diagonals();
}

bool TicTacToe::check_rows() {
    for(int row = 0; row < 3; row++) {
        if( ((board[row][0] == board[row][1]) && (board[row][0] == board[row][2])) && board[row][0]) {
            return true;
        }
    }
    return false;
}

bool TicTacToe::check_cols() {
    for(int col = 0; col < 3; col++) {
        if( ((board[0][col] == board[1][col]) && (board[0][col] == board[2][col])) && board[0][col]) {
            return true;
        }
    }
    return false;
}

bool TicTacToe::check_diagonals() {
    if( (board[1][1] > 0) && (
            (board[0][0] == board[1][1] && board[0][0] == board[2][2]) || (board[0][2] == board[1][1] && board[0][2] == board[2][0])
        )
    ) {
        return true;
    }
    return false;
}

bool TicTacToe::check_move(int row, int col) {
    if (row > 2 || col > 2) {
        return false;
    }
    return board[row][col] == 0;
}

bool TicTacToe::player_move(int row, int col, int player) {
    if(check_move(row, col)) {
        board[row][col] = player;
        return true;
    }
    return false;
}

void TicTacToe::start() {
    draw_board();
    pair<int, int> Players(X, O);
    pair<int, int> Swapped(O, X);
    int row, column;
    while(!game_over()) {
        cout << "Player " << char_map[Players.first] << ", make your move, row and column on separate lines" << endl;
        cin >> row >> column;
        if (cin.fail()) {
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        if(player_move(row, column, Players.first)) {
            draw_board();
            swap(Players, Swapped);
        } else {
            draw_board();
        }
    }
    draw_board();
    cout << "Game Over" << endl;
    return;
}
<commit_msg>Unsigned short int for rows, columns<commit_after>#include "tictactoe.h"
#include <iostream>
#include <utility>

using namespace std;

const string TicTacToe::SPACE = "   ";
const int TicTacToe::X = 1;
const int TicTacToe::O = 2;
const string TicTacToe::LINE = "-----------";

TicTacToe::TicTacToe() {
    for(int row = 0; row < 3; row++) {
        for(int col = 0; col < 3; col++) {
            board[row][col] = 0;
        }
    }
}

void TicTacToe::draw_board() {
    cout << LINE << endl;
    for(int row = 0; row < 3; row++) {
        cout << "|";
        for(int col = 0; col < 3; col++) {
            cout << char_map[board[row][col]] << (col == 2 ? "|" : SPACE);
        }
        cout << endl;
    }
    cout << LINE << endl;
}

bool TicTacToe::game_over() {
    return check_rows() || check_cols() || check_diagonals();
}

bool TicTacToe::check_rows() {
    for(int row = 0; row < 3; row++) {
        if( ((board[row][0] == board[row][1]) && (board[row][0] == board[row][2])) && board[row][0]) {
            return true;
        }
    }
    return false;
}

bool TicTacToe::check_cols() {
    for(int col = 0; col < 3; col++) {
        if( ((board[0][col] == board[1][col]) && (board[0][col] == board[2][col])) && board[0][col]) {
            return true;
        }
    }
    return false;
}

bool TicTacToe::check_diagonals() {
    if( (board[1][1] > 0) && (
            (board[0][0] == board[1][1] && board[0][0] == board[2][2]) || (board[0][2] == board[1][1] && board[0][2] == board[2][0])
        )
    ) {
        return true;
    }
    return false;
}

bool TicTacToe::check_move(int row, int col) {
    if (row > 2 || col > 2) {
        return false;
    }
    return board[row][col] == 0;
}

bool TicTacToe::player_move(int row, int col, int player) {
    if(check_move(row, col)) {
        board[row][col] = player;
        return true;
    }
    return false;
}

void TicTacToe::start() {
    draw_board();
    pair<int, int> Players(X, O);
    pair<int, int> Swapped(O, X);
    short unsigned int row, column;
    while(!game_over()) {
        cout << "Player " << char_map[Players.first] << ", make your move, row and column on separate lines" << endl;
        cin >> row >> column;
        if (cin.fail()) {
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        if(player_move(row, column, Players.first)) {
            draw_board();
            swap(Players, Swapped);
        } else {
            draw_board();
        }
    }
    draw_board();
    cout << "Game Over" << endl;
    return;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <vector>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

using namespace std;
int main()
{
	std::vector<ElemType> v;
	int a, i;
	ElemType e, x;
	if(v.empty())    // 判断顺序表是否创建成功
	{
		printf("A Sequence List Has Created.\n");
	}
	while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);
					vector<ElemType>::iterator I;
					 I = v.begin()+i;
					if(v.insert(I,x)) printf("Insert Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Inserted!\n", x);
					break;
			case 2: scanf("%d",&i);
					vector<ElemType>::iterator I = v.begin();
					I=I+i;

					if(v.erase(I)) printf("Delete Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Deleted!\n", e);
					break;
			case 3:
			vector<ElemType>::iterator tempIterator;
			for( tempIterator = v.begin(); tempIterator != v.end(); tempIterator++ )
    				cout << *tempIterator;
    		cout << endl;
					break;
			case 0: return 1;
		}
	}
}<commit_msg>update uoj8576<commit_after>#include <stdio.h>
#include <vector>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

using namespace std;
int main()
{
	std::vector<ElemType> v;
	int a, i;
	ElemType e, x;
	if(v.empty())    // 判断顺序表是否创建成功
	{
		printf("A Sequence List Has Created.\n");
	}
	while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);

					if(v.insert(v.begin()+i,x)) printf("Insert Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Inserted!\n", x);
					break;
			case 2: scanf("%d",&i);
					vector<ElemType>::iterator I = v.begin();
					I=I+i;

					if(v.erase(I)) printf("Delete Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Deleted!\n", e);
					break;
			case 3:
			vector<ElemType>::iterator tempIterator;
			for( tempIterator = v.begin(); tempIterator != v.end(); tempIterator++ )
    				cout << *tempIterator;
    		cout << endl;
					break;
			case 0: return 1;
		}
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2014-2018 The Crown developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "updater.h"
#include "clientversion.h"
#include "util.h"
#include "chainparams.h"
#include "rpcprotocol.h"

#include <stdio.h>
#include <curl/curl.h>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>

using namespace boost::filesystem;

struct DownloadProgress {
    double lastruntime;
    CURL *curl;
    void(*progressFunction)(curl_off_t, curl_off_t);
};

// Global updater instance
Updater updater;

Updater::Updater() :
    os(DetectOS()),
    status(false),
    version(-1),
    stopDownload(false),
    url("https://raw.githubusercontent.com/Crowndev/crowncoin/master/update.json")
{
}

Updater::OS Updater::DetectOS()
{
    OS os = Updater::LINUX_32;
    #ifdef _WIN32
        os = Updater::WINDOWS_32;
        #ifdef _WIN64
            os = Updater::WINDOWS_64;
        #endif
    #elif __APPLE__
        os = Updater::MAC_OS;
    #elif __linux__
        os = Updater::LINUX_32;
        #if defined(__i386__) || defined(__i686__) || defined(__i486__) || defined(__i586__)
            os = Updater::LINUX_32;
        #elif defined(__x86_64__) || defined(__amd64__)
            os = Updater::LINUX_64;
        #endif
    #endif
    return os;
}

size_t GetUpdateData(const char *data, size_t size, size_t nmemb, std::string *updateData) {
    size_t len = size * nmemb;

    if (updateData != NULL)
    {
        // Append the data to the buffer
        updateData->append(data, len);
    }

    return len;
}

Value Updater::ParseJson(std::string info)
{
    Value value;
    json_spirit::read_string(info, value);
    return value;
}

bool Updater::NeedToBeUpdated()
{
    if (jsonData.type() == obj_type)
    {
        Value version = find_value(jsonData.get_obj(), "NeedToBeUpdated");
        if (version.type() == bool_type)
        {
            return version.get_bool();
        }
    }
    return false;
}

void Updater::SetJsonPath()
{
    updaterInfoUrl = url;
    if (mapArgs.count("-updateurl"))
    {
        updaterInfoUrl = mapArgs["-updateurl"];
    }
}

void Updater::LoadUpdateInfo()
{
    CURL *curl;
    std::string updateData;
    SetJsonPath();
    CURLcode res = CURLE_FAILED_INIT;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, updaterInfoUrl.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetUpdateData);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &updateData);
        res = curl_easy_perform(curl);
        if (res == CURLE_OK)
        {
            long response_code;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
            if (response_code == HTTP_OK)
            {
                CheckAndUpdateStatus(updateData);
            }
            else
            {
                LogPrintf("Updater::GetUpdateInfo() - Error! Server response code - %d\n", response_code);
                throw std::runtime_error(strprintf("Error! Failed to get update information. \nServer response code - %d\n", response_code));
            }
        }
        else
        {
            LogPrintf("Updater::GetUpdateInfo() - Error! Couldn't get data json. Error code - %d\n", res);
            throw std::runtime_error(strprintf("Error! Couldn't get data json. Error code - %d\n", res));
        }
        curl_easy_cleanup(curl);
    }
}

std::string Updater::GetOsString(boost::optional<OS> os)
{
    if (!os) {
        return GetOsString(GetOS());
    }
    switch(os.get()) {
        case Updater::LINUX_32:
            return "Linux32";
        case Updater::LINUX_64:
            return "Linux64";
        case Updater::WINDOWS_32:
            return "Win32";
        case Updater::WINDOWS_64:
            return "Win64";
        case Updater::MAC_OS:
            return "Osx";
        default:
            assert(false);
    }
    return "";
}

std::string Updater::GetUrl(const Value& value)
{
    if (value.type() == obj_type)
    {
        Value urlValue = find_value(value.get_obj(), "Url");
        if (urlValue.type() == str_type)
        {
            return urlValue.get_str();
        }
    }
    return "";
}

std::string Updater::GetSha256sum(Value value)
{
    if (value.type() == obj_type)
    {
        Value sha256sumValue = find_value(value.get_obj(), "sha256sum");
        if (sha256sumValue.type() == str_type)
        {
            return sha256sumValue.get_str();
        }
    }
    return "";
}

int Updater::GetVersionFromJson()
{
    if (jsonData.type() == obj_type)
    {
        Value version = find_value(jsonData.get_obj(), "Version");
        if (version.type() == int_type)
        {
            return version.get_int();
        }
    }
    return -1;
}

std::string Updater::GetDownloadUrl(boost::optional<OS> version)
{
    Value json = find_value(jsonData.get_obj(), GetOsString(version));
    return GetUrl(json);
}

std::string Updater::GetDownloadSha256Sum(boost::optional<OS> version)
{
    Value json = find_value(jsonData.get_obj(), GetOsString(version));
    return GetSha256sum(json);
}

static size_t write_data(void *ptr, size_t size, size_t nmemb, const void *stream)
{
    size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
    return written;
}

static int xferinfo(void *p,
        curl_off_t dltotal, curl_off_t dlnow,
        curl_off_t ultotal, curl_off_t ulnow)
{
    struct DownloadProgress *myp = (struct DownloadProgress*)p;
    myp->progressFunction(dlnow, dltotal);
    return updater.GetStopDownload();
}

void Updater::DownloadFileAsync(std::string url, std::string fileName, void(progressFunction)(curl_off_t, curl_off_t))
{
    boost::thread t(boost::bind(&Updater::DownloadFile, this, url, fileName, progressFunction));
}

CURLcode Updater::DownloadFile(std::string url, std::string fileName, void(progressFunction)(curl_off_t, curl_off_t))
{
    stopDownload = false;
    CURL *curl_handle;
    struct DownloadProgress prog;
    prog.progressFunction = progressFunction;
    FILE *pagefile;
    CURLcode res = CURLE_FAILED_INIT;

    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

    curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, xferinfo);
    curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, &prog);
    pagefile = fopen(fileName.c_str(), "wb");
    if(pagefile) {
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);
        res = curl_easy_perform(curl_handle);
        fclose(pagefile);
    }
    curl_easy_cleanup(curl_handle);

    if (res != CURLE_OK)
    {
        LogPrintf("Updater::DownloadFile() - Error! Failed to download file - %s. Error code - %d\n", url, res);
    }
    return res;
}

void Updater::StopDownload()
{
    stopDownload = true;
}

void Updater::CheckAndUpdateStatus(const std::string& updateData)
{
    jsonData = ParseJson(updateData);
    version = GetVersionFromJson();
    LogPrintf("Updater::GetUpdateInfo() - Got version from json: %d\n", version);
    if (version > CLIENT_VERSION && NeedToBeUpdated())
    {
        LogPrintf("Updater::GetUpdateInfo() - Version is old\n");
        // There is an update
        status = true;
    }
}

bool Updater::GetStatus()
{
    LoadUpdateInfo();
    return status;
}
<commit_msg>Fixed certificate issue<commit_after>// Copyright (c) 2014-2018 The Crown developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "updater.h"
#include "clientversion.h"
#include "util.h"
#include "chainparams.h"
#include "rpcprotocol.h"

#include <stdio.h>
#include <curl/curl.h>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>

using namespace boost::filesystem;

struct DownloadProgress {
    double lastruntime;
    CURL *curl;
    void(*progressFunction)(curl_off_t, curl_off_t);
};

// Global updater instance
Updater updater;

Updater::Updater() :
    os(DetectOS()),
    status(false),
    version(-1),
    stopDownload(false),
    url("https://raw.githubusercontent.com/Crowndev/crowncoin/master/update.json")
{
}

Updater::OS Updater::DetectOS()
{
    OS os = Updater::LINUX_32;
    #ifdef _WIN32
        os = Updater::WINDOWS_32;
        #ifdef _WIN64
            os = Updater::WINDOWS_64;
        #endif
    #elif __APPLE__
        os = Updater::MAC_OS;
    #elif __linux__
        os = Updater::LINUX_32;
        #if defined(__i386__) || defined(__i686__) || defined(__i486__) || defined(__i586__)
            os = Updater::LINUX_32;
        #elif defined(__x86_64__) || defined(__amd64__)
            os = Updater::LINUX_64;
        #endif
    #endif
    return os;
}

size_t GetUpdateData(const char *data, size_t size, size_t nmemb, std::string *updateData) {
    size_t len = size * nmemb;

    if (updateData != NULL)
    {
        // Append the data to the buffer
        updateData->append(data, len);
    }

    return len;
}

Value Updater::ParseJson(std::string info)
{
    Value value;
    json_spirit::read_string(info, value);
    return value;
}

bool Updater::NeedToBeUpdated()
{
    if (jsonData.type() == obj_type)
    {
        Value version = find_value(jsonData.get_obj(), "NeedToBeUpdated");
        if (version.type() == bool_type)
        {
            return version.get_bool();
        }
    }
    return false;
}

void Updater::SetJsonPath()
{
    updaterInfoUrl = url;
    if (mapArgs.count("-updateurl"))
    {
        updaterInfoUrl = mapArgs["-updateurl"];
    }
}

void Updater::LoadUpdateInfo()
{
    CURL *curl;
    std::string updateData;
    SetJsonPath();
    CURLcode res = CURLE_FAILED_INIT;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, updaterInfoUrl.c_str());
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetUpdateData);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &updateData);
        res = curl_easy_perform(curl);
        if (res == CURLE_OK)
        {
            long response_code;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
            if (response_code == HTTP_OK)
            {
                CheckAndUpdateStatus(updateData);
            }
            else
            {
                LogPrintf("Updater::GetUpdateInfo() - Error! Server response code - %d\n", response_code);
                throw std::runtime_error(strprintf("Error! Failed to get update information. \nServer response code - %d\n", response_code));
            }
        }
        else
        {
            LogPrintf("Updater::GetUpdateInfo() - Error! Couldn't get data json. Error code - %d\n", res);
            throw std::runtime_error(strprintf("Error! Couldn't get data json. Error code - %d\n", res));
        }
        curl_easy_cleanup(curl);
    }
}

std::string Updater::GetOsString(boost::optional<OS> os)
{
    if (!os) {
        return GetOsString(GetOS());
    }
    switch(os.get()) {
        case Updater::LINUX_32:
            return "Linux32";
        case Updater::LINUX_64:
            return "Linux64";
        case Updater::WINDOWS_32:
            return "Win32";
        case Updater::WINDOWS_64:
            return "Win64";
        case Updater::MAC_OS:
            return "Osx";
        default:
            assert(false);
    }
    return "";
}

std::string Updater::GetUrl(const Value& value)
{
    if (value.type() == obj_type)
    {
        Value urlValue = find_value(value.get_obj(), "Url");
        if (urlValue.type() == str_type)
        {
            return urlValue.get_str();
        }
    }
    return "";
}

std::string Updater::GetSha256sum(Value value)
{
    if (value.type() == obj_type)
    {
        Value sha256sumValue = find_value(value.get_obj(), "sha256sum");
        if (sha256sumValue.type() == str_type)
        {
            return sha256sumValue.get_str();
        }
    }
    return "";
}

int Updater::GetVersionFromJson()
{
    if (jsonData.type() == obj_type)
    {
        Value version = find_value(jsonData.get_obj(), "Version");
        if (version.type() == int_type)
        {
            return version.get_int();
        }
    }
    return -1;
}

std::string Updater::GetDownloadUrl(boost::optional<OS> version)
{
    Value json = find_value(jsonData.get_obj(), GetOsString(version));
    return GetUrl(json);
}

std::string Updater::GetDownloadSha256Sum(boost::optional<OS> version)
{
    Value json = find_value(jsonData.get_obj(), GetOsString(version));
    return GetSha256sum(json);
}

static size_t write_data(void *ptr, size_t size, size_t nmemb, const void *stream)
{
    size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
    return written;
}

static int xferinfo(void *p,
        curl_off_t dltotal, curl_off_t dlnow,
        curl_off_t ultotal, curl_off_t ulnow)
{
    struct DownloadProgress *myp = (struct DownloadProgress*)p;
    myp->progressFunction(dlnow, dltotal);
    return updater.GetStopDownload();
}

void Updater::DownloadFileAsync(std::string url, std::string fileName, void(progressFunction)(curl_off_t, curl_off_t))
{
    boost::thread t(boost::bind(&Updater::DownloadFile, this, url, fileName, progressFunction));
}

CURLcode Updater::DownloadFile(std::string url, std::string fileName, void(progressFunction)(curl_off_t, curl_off_t))
{
    stopDownload = false;
    CURL *curl_handle;
    struct DownloadProgress prog;
    prog.progressFunction = progressFunction;
    FILE *pagefile;
    CURLcode res = CURLE_FAILED_INIT;

    curl_global_init(CURL_GLOBAL_ALL);
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, false);
    curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

    curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, xferinfo);
    curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, &prog);
    pagefile = fopen(fileName.c_str(), "wb");
    if(pagefile) {
        curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);
        res = curl_easy_perform(curl_handle);
        fclose(pagefile);
    }
    curl_easy_cleanup(curl_handle);

    if (res != CURLE_OK)
    {
        LogPrintf("Updater::DownloadFile() - Error! Failed to download file - %s. Error code - %d\n", url, res);
    }
    return res;
}

void Updater::StopDownload()
{
    stopDownload = true;
}

void Updater::CheckAndUpdateStatus(const std::string& updateData)
{
    jsonData = ParseJson(updateData);
    version = GetVersionFromJson();
    LogPrintf("Updater::GetUpdateInfo() - Got version from json: %d\n", version);
    if (version > CLIENT_VERSION && NeedToBeUpdated())
    {
        LogPrintf("Updater::GetUpdateInfo() - Version is old\n");
        // There is an update
        status = true;
    }
}

bool Updater::GetStatus()
{
    LoadUpdateInfo();
    return status;
}
<|endoftext|>


<commit_before>#include <HsFFI.h>
#include <QtCore/QString>
#include <QtCore/QMutexLocker>
#include <QtQml/QQmlEngine>

#include "Object.h"
#include "Class.h"
#include "Manager.h"

static const char* cRefSrcNames[] = {"Hndl", "Weak", "Obj", "Event", "Var"};

HsQMLObjectFinaliser::HsQMLObjectFinaliser(HsQMLObjFinaliserCb cb)
    : mFinaliseCb(cb)
{}

HsQMLObjectFinaliser::~HsQMLObjectFinaliser()
{
    gManager->freeFun(reinterpret_cast<HsFunPtr>(mFinaliseCb));
}

void HsQMLObjectFinaliser::finalise(HsQMLObjectProxy* proxy) const
{
    mFinaliseCb(reinterpret_cast<HsQMLObjectHandle*>(proxy));
}

HsQMLObjectProxy::HsQMLObjectProxy(HsStablePtr haskell, HsQMLClass* klass)
    : mHaskell(haskell)
    , mKlass(klass)
    , mSerial(gManager->updateCounter(HsQMLManager::ObjectSerial, 1))
    , mObject(NULL)
    , mRefCount(0)
{
    ref(Handle);
    mKlass->ref(HsQMLClass::ObjProxy);
    gManager->updateCounter(HsQMLManager::ObjectCount, 1);
}

HsQMLObjectProxy::~HsQMLObjectProxy()
{
    mKlass->deref(HsQMLClass::ObjProxy);
    gManager->updateCounter(HsQMLManager::ObjectCount, -1);
}

HsStablePtr HsQMLObjectProxy::haskell() const
{
    return mHaskell;
}

HsQMLClass* HsQMLObjectProxy::klass() const
{
    return mKlass;
}

HsQMLObject* HsQMLObjectProxy::object(HsQMLEngine* engine)
{
    Q_ASSERT(gManager->isEventThread());
    Q_ASSERT(engine);
    if (!mObject) {
        mObject = new HsQMLObject(this, engine);

        HSQML_LOG(5,
            QString().sprintf("New QObject, class=%s, id=%d, qptr=%p.",
            mKlass->name(), mSerial, mObject));
    }

    // Old objects may have lost their lock via weak references in addition
    // to new objects needing it.
    tryGCLock();

    return mObject;
}

void HsQMLObjectProxy::clearObject()
{
    Q_ASSERT(gManager->isEventThread());

    HSQML_LOG(5,
        QString().sprintf("Release QObject, class=%s, id=%d, qptr=%p.",
        mKlass->name(), mSerial, mObject));

    mObject = NULL;
    runFinalisers();
}

void HsQMLObjectProxy::tryGCLock()
{
    Q_ASSERT(gManager->isEventThread());

    if (mObject && mHndlCount.loadAcquire() > 0 && !mObject->isGCLocked()) {
        mObject->setGCLock();

        HSQML_LOG(5,
            QString().sprintf("Lock QObject, class=%s, id=%d, qptr=%p.",
            mKlass->name(), mSerial, mObject));
    }
}

void HsQMLObjectProxy::removeGCLock()
{
    Q_ASSERT(gManager->isEventThread());

    if (mObject && mHndlCount.loadAcquire() == 0) {
        if (mObject->isGCLocked()) {
            mObject->clearGCLock();

            HSQML_LOG(5,
                QString().sprintf("Unlock QObject, class=%s, id=%d, qptr=%p.",
                mKlass->name(), mSerial, mObject));
        }
        else {
            // If there had been a QML object then this would have happened
            // when the QML GC collected it.
            runFinalisers();
        }
    }
}

void HsQMLObjectProxy::addFinaliser(const HsQMLObjectFinaliser::Ref& f)
{
    QMutexLocker locker(&mFinaliseMutex);
    mFinalisers.append(f);
}

void HsQMLObjectProxy::runFinalisers()
{
    // Copy and clear finalisers under lock
    mFinaliseMutex.lock();
    const Finalisers fs = mFinalisers;
    mFinalisers.clear();
    mFinaliseMutex.unlock();

    // Call finalisers outside lock so they can re-addFinaliser()
    Q_FOREACH(const HsQMLObjectFinaliser::Ref& f, fs) {
        ref(Handle);
        f->finalise(this);
    }
}

HsQMLEngine* HsQMLObjectProxy::engine() const
{
    if (mObject != NULL) {
        return mObject->engine();
    }
    return NULL;
}

void HsQMLObjectProxy::ref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(1);

    HSQML_LOG(count == 0 ? 3 : 4,
        QString().sprintf("%s ObjProxy, class=%s, id=%d, src=%s, count=%d.",
        count ? "Ref" : "New", mKlass->name(),
        mSerial, cRefSrcNames[src], count+1));

    if (src == Handle || src == Variant) {
        mHndlCount.fetchAndAddOrdered(1);
    }
}

void HsQMLObjectProxy::deref(RefSrc src)
{
    // Remove JavaScript GC lock when there are no strong handles
    if (src == Handle || src == Variant) {
        int hndlCount = mHndlCount.fetchAndAddOrdered(-1);
        if (hndlCount == 1 && mObject) {
            if (src == Handle) {
                // Handles can be dereferenced from any thread. The event will
                // remove the lock if there are still no handles by the time
                // it reaches the event loop.
                gManager->postObjectEvent(new HsQMLObjectEvent(this));
            }
            else {
                removeGCLock();
            }
        }
    }

    int count = mRefCount.fetchAndAddOrdered(-1);

    HSQML_LOG(count == 1 ? 3 : 4,
        QString().sprintf("%s ObjProxy, class=%s, id=%d, src=%s, count=%d.",
        count > 1 ? "Deref" : "Delete", mKlass->name(),
        mSerial, cRefSrcNames[src], count));

    if (count == 1) {
        delete this;
    }
}

HsQMLObjectEvent::HsQMLObjectEvent(HsQMLObjectProxy* proxy)
    : QEvent(HsQMLManagerApp::RemoveGCLockEvent)
    , mProxy(proxy)
{
    mProxy->ref(HsQMLObjectProxy::Event);
}

HsQMLObjectEvent::~HsQMLObjectEvent()
{
    mProxy->deref(HsQMLObjectProxy::Event);
}

void HsQMLObjectEvent::process()
{
    Q_ASSERT(type() == HsQMLManagerApp::RemoveGCLockEvent);
    mProxy->removeGCLock();
}

HsQMLObject::HsQMLObject(HsQMLObjectProxy* proxy, HsQMLEngine* engine)
    : mProxy(proxy)
    , mHaskell(proxy->haskell())
    , mKlass(proxy->klass())
    , mEngine(engine)
{
    QQmlEngine::setObjectOwnership(
        this, QQmlEngine::JavaScriptOwnership);
    mProxy->ref(HsQMLObjectProxy::Object);
    gManager->registerObject(this);
    gManager->updateCounter(HsQMLManager::QObjectCount, 1);
}

HsQMLObject::~HsQMLObject()
{
    mProxy->clearObject();
    mProxy->deref(HsQMLObjectProxy::Object);
    gManager->unregisterObject(this);
    gManager->updateCounter(HsQMLManager::QObjectCount, -1);
}

const QMetaObject* HsQMLObject::metaObject() const
{
    return QObject::d_ptr->metaObject ?
        QObject::d_ptr->dynamicMetaObject() : mKlass->metaObj();
}

void* HsQMLObject::qt_metacast(const char* clname)
{
    if (!clname) {
        return 0;
    }
    if (!strcmp(clname, mKlass->metaObj()->className())) {
        return static_cast<void*>(const_cast<HsQMLObject*>(this));
    }
    return QObject::qt_metacast(clname);
}

int HsQMLObject::qt_metacall(QMetaObject::Call c, int id, void** a)
{
    id = QObject::qt_metacall(c, id, a);
    if (id < 0) {
        return id;
    }
    gManager->setActiveEngine(mEngine);
    if (QMetaObject::InvokeMetaMethod == c) {
        mKlass->methods()[id](this, a);
        id -= mKlass->methodCount();
    }
    else if (QMetaObject::ReadProperty == c) {
        mKlass->properties()[2*id](this, a);
        id -= mKlass->propertyCount();
    }
    else if (QMetaObject::WriteProperty == c) {
        HsQMLUniformFunc uf = mKlass->properties()[2*id+1];
        if (uf) {
            uf(this, a);
        }
        id -= mKlass->propertyCount();
    }
    else if (QMetaObject::QueryPropertyDesignable == c ||
             QMetaObject::QueryPropertyScriptable == c ||
             QMetaObject::QueryPropertyStored == c ||
             QMetaObject::QueryPropertyEditable == c ||
             QMetaObject::QueryPropertyUser == c) {
        id -= mKlass->propertyCount();
    }
    gManager->setActiveEngine(NULL);
    return id;
}

void HsQMLObject::setGCLock()
{
    mGCLock = mEngine->declEngine()->newQObject(this);
}

void HsQMLObject::clearGCLock()
{
    mGCLock = QJSValue(QJSValue::NullValue);
}

bool HsQMLObject::isGCLocked() const
{
    return mGCLock.isQObject();
}

QJSValue* HsQMLObject::gcLockVar()
{
    return &mGCLock;
}

HsQMLObjectProxy* HsQMLObject::proxy() const
{
    return mProxy;
}

HsQMLEngine* HsQMLObject::engine() const
{
    return mEngine;
}

extern "C" HsQMLObjectHandle* hsqml_create_object(
    HsStablePtr haskell, HsQMLClassHandle* kHndl)
{
    HsQMLObjectProxy* proxy = new HsQMLObjectProxy(haskell, (HsQMLClass*)kHndl);
    return (HsQMLObjectHandle*)proxy;
}

extern "C" int hsqml_object_set_active(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    if (proxy) {
        HsQMLEngine* engine = proxy->engine();
        if (engine) {
            gManager->setActiveEngine(engine);
        }
        else {
            // Nothing can be done if the object hasn't been marshalled before
            // because otherwise the relevant engine is unknown.
            return false;
        }
    }
    else {
        gManager->setActiveEngine(NULL);
    }
    return true;
}

extern "C" HsStablePtr hsqml_object_get_hs_typerep(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    return proxy->klass()->hsTypeRep();
}

extern HsStablePtr hsqml_object_get_hs_value(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    return proxy->haskell();
}

extern void* hsqml_object_get_pointer(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    return (void*)proxy->object(gManager->activeEngine());
}

extern HsQMLJValHandle* hsqml_object_get_jval(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    HsQMLObject* obj = proxy->object(gManager->activeEngine());
    return reinterpret_cast<HsQMLJValHandle*>(obj->gcLockVar());
}

extern HsQMLObjectHandle* hsqml_get_object_from_pointer(
    void* ptr)
{
    // Return NULL if the input pointer is NULL
    if (!ptr) {
        return NULL;
    }

    // Get object proxy
    HsQMLObject* object = (HsQMLObject*)ptr;
    HsQMLObjectProxy* proxy = object->proxy();
    proxy->ref(HsQMLObjectProxy::Handle);
    proxy->tryGCLock();

    return (HsQMLObjectHandle*)proxy;
}

extern HsQMLObjectHandle* hsqml_get_object_from_jval(
    HsQMLJValHandle* jvalHndl)
{
    QJSValue* jval = reinterpret_cast<QJSValue*>(jvalHndl);
    return hsqml_get_object_from_pointer(jval->toQObject());
}

extern void hsqml_object_reference_handle(
    HsQMLObjectHandle* hndl,
    int weak)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    proxy->ref(weak ? HsQMLObjectProxy::WeakHandle : HsQMLObjectProxy::Handle);
}

extern void hsqml_finalise_object_handle(
    HsQMLObjectHandle* hndl)
{
    if (hndl) {
        HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
        proxy->deref(HsQMLObjectProxy::Handle);
    }
}

extern void hsqml_finalise_object_weak_handle(
    HsQMLObjectHandle* hndl)
{
    if (hndl) {
        HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
        proxy->deref(HsQMLObjectProxy::WeakHandle);
    }
}

extern void hsqml_fire_signal(
    HsQMLObjectHandle* hndl, int idx, void** args)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    HsQMLEngine* engine = proxy->engine();
    // Ignore objects which haven't been marshalled as they are not connected.
    if (engine) {
        // Clear active engine in case the slot code calls back into Haskell.
        Q_ASSERT(gManager->activeEngine() == engine);
        gManager->setActiveEngine(NULL);
        HsQMLObject* obj = proxy->object(engine);
        QMetaObject::activate(obj, proxy->klass()->metaObj(), idx, args);
    }
}

extern HsQMLObjFinaliserHandle* hsqml_create_obj_finaliser(
    HsQMLObjFinaliserCb cb)
{
    return reinterpret_cast<HsQMLObjFinaliserHandle*>(
        new HsQMLObjectFinaliser::Ref(new HsQMLObjectFinaliser(cb)));
}

extern void hsqml_finalise_obj_finaliser(
    HsQMLObjFinaliserHandle* hndl)
{
    HsQMLObjectFinaliser::Ref* fp =
        reinterpret_cast<HsQMLObjectFinaliser::Ref*>(hndl);
    delete fp;
}

extern void hsqml_object_add_finaliser(
    HsQMLObjectHandle* hndl, HsQMLObjFinaliserHandle* fhndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    proxy->addFinaliser(*reinterpret_cast<HsQMLObjectFinaliser::Ref*>(fhndl));
}
<commit_msg>Fix leaking stable pointers when objects are collected.<commit_after>#include <HsFFI.h>
#include <QtCore/QString>
#include <QtCore/QMutexLocker>
#include <QtQml/QQmlEngine>

#include "Object.h"
#include "Class.h"
#include "Manager.h"

static const char* cRefSrcNames[] = {"Hndl", "Weak", "Obj", "Event", "Var"};

HsQMLObjectFinaliser::HsQMLObjectFinaliser(HsQMLObjFinaliserCb cb)
    : mFinaliseCb(cb)
{}

HsQMLObjectFinaliser::~HsQMLObjectFinaliser()
{
    gManager->freeFun(reinterpret_cast<HsFunPtr>(mFinaliseCb));
}

void HsQMLObjectFinaliser::finalise(HsQMLObjectProxy* proxy) const
{
    mFinaliseCb(reinterpret_cast<HsQMLObjectHandle*>(proxy));
}

HsQMLObjectProxy::HsQMLObjectProxy(HsStablePtr haskell, HsQMLClass* klass)
    : mHaskell(haskell)
    , mKlass(klass)
    , mSerial(gManager->updateCounter(HsQMLManager::ObjectSerial, 1))
    , mObject(NULL)
    , mRefCount(0)
{
    ref(Handle);
    mKlass->ref(HsQMLClass::ObjProxy);
    gManager->updateCounter(HsQMLManager::ObjectCount, 1);
}

HsQMLObjectProxy::~HsQMLObjectProxy()
{
    mKlass->deref(HsQMLClass::ObjProxy);
    gManager->updateCounter(HsQMLManager::ObjectCount, -1);
    gManager->freeStable(mHaskell);
}

HsStablePtr HsQMLObjectProxy::haskell() const
{
    return mHaskell;
}

HsQMLClass* HsQMLObjectProxy::klass() const
{
    return mKlass;
}

HsQMLObject* HsQMLObjectProxy::object(HsQMLEngine* engine)
{
    Q_ASSERT(gManager->isEventThread());
    Q_ASSERT(engine);
    if (!mObject) {
        mObject = new HsQMLObject(this, engine);

        HSQML_LOG(5,
            QString().sprintf("New QObject, class=%s, id=%d, qptr=%p.",
            mKlass->name(), mSerial, mObject));
    }

    // Old objects may have lost their lock via weak references in addition
    // to new objects needing it.
    tryGCLock();

    return mObject;
}

void HsQMLObjectProxy::clearObject()
{
    Q_ASSERT(gManager->isEventThread());

    HSQML_LOG(5,
        QString().sprintf("Release QObject, class=%s, id=%d, qptr=%p.",
        mKlass->name(), mSerial, mObject));

    mObject = NULL;
    runFinalisers();
}

void HsQMLObjectProxy::tryGCLock()
{
    Q_ASSERT(gManager->isEventThread());

    if (mObject && mHndlCount.loadAcquire() > 0 && !mObject->isGCLocked()) {
        mObject->setGCLock();

        HSQML_LOG(5,
            QString().sprintf("Lock QObject, class=%s, id=%d, qptr=%p.",
            mKlass->name(), mSerial, mObject));
    }
}

void HsQMLObjectProxy::removeGCLock()
{
    Q_ASSERT(gManager->isEventThread());

    if (mObject && mHndlCount.loadAcquire() == 0) {
        if (mObject->isGCLocked()) {
            mObject->clearGCLock();

            HSQML_LOG(5,
                QString().sprintf("Unlock QObject, class=%s, id=%d, qptr=%p.",
                mKlass->name(), mSerial, mObject));
        }
        else {
            // If there had been a QML object then this would have happened
            // when the QML GC collected it.
            runFinalisers();
        }
    }
}

void HsQMLObjectProxy::addFinaliser(const HsQMLObjectFinaliser::Ref& f)
{
    QMutexLocker locker(&mFinaliseMutex);
    mFinalisers.append(f);
}

void HsQMLObjectProxy::runFinalisers()
{
    // Copy and clear finalisers under lock
    mFinaliseMutex.lock();
    const Finalisers fs = mFinalisers;
    mFinalisers.clear();
    mFinaliseMutex.unlock();

    // Call finalisers outside lock so they can re-addFinaliser()
    Q_FOREACH(const HsQMLObjectFinaliser::Ref& f, fs) {
        ref(Handle);
        f->finalise(this);
    }
}

HsQMLEngine* HsQMLObjectProxy::engine() const
{
    if (mObject != NULL) {
        return mObject->engine();
    }
    return NULL;
}

void HsQMLObjectProxy::ref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(1);

    HSQML_LOG(count == 0 ? 3 : 4,
        QString().sprintf("%s ObjProxy, class=%s, id=%d, src=%s, count=%d.",
        count ? "Ref" : "New", mKlass->name(),
        mSerial, cRefSrcNames[src], count+1));

    if (src == Handle || src == Variant) {
        mHndlCount.fetchAndAddOrdered(1);
    }
}

void HsQMLObjectProxy::deref(RefSrc src)
{
    // Remove JavaScript GC lock when there are no strong handles
    if (src == Handle || src == Variant) {
        int hndlCount = mHndlCount.fetchAndAddOrdered(-1);
        if (hndlCount == 1 && mObject) {
            if (src == Handle) {
                // Handles can be dereferenced from any thread. The event will
                // remove the lock if there are still no handles by the time
                // it reaches the event loop.
                gManager->postObjectEvent(new HsQMLObjectEvent(this));
            }
            else {
                removeGCLock();
            }
        }
    }

    int count = mRefCount.fetchAndAddOrdered(-1);

    HSQML_LOG(count == 1 ? 3 : 4,
        QString().sprintf("%s ObjProxy, class=%s, id=%d, src=%s, count=%d.",
        count > 1 ? "Deref" : "Delete", mKlass->name(),
        mSerial, cRefSrcNames[src], count));

    if (count == 1) {
        delete this;
    }
}

HsQMLObjectEvent::HsQMLObjectEvent(HsQMLObjectProxy* proxy)
    : QEvent(HsQMLManagerApp::RemoveGCLockEvent)
    , mProxy(proxy)
{
    mProxy->ref(HsQMLObjectProxy::Event);
}

HsQMLObjectEvent::~HsQMLObjectEvent()
{
    mProxy->deref(HsQMLObjectProxy::Event);
}

void HsQMLObjectEvent::process()
{
    Q_ASSERT(type() == HsQMLManagerApp::RemoveGCLockEvent);
    mProxy->removeGCLock();
}

HsQMLObject::HsQMLObject(HsQMLObjectProxy* proxy, HsQMLEngine* engine)
    : mProxy(proxy)
    , mHaskell(proxy->haskell())
    , mKlass(proxy->klass())
    , mEngine(engine)
{
    QQmlEngine::setObjectOwnership(
        this, QQmlEngine::JavaScriptOwnership);
    mProxy->ref(HsQMLObjectProxy::Object);
    gManager->registerObject(this);
    gManager->updateCounter(HsQMLManager::QObjectCount, 1);
}

HsQMLObject::~HsQMLObject()
{
    mProxy->clearObject();
    mProxy->deref(HsQMLObjectProxy::Object);
    gManager->unregisterObject(this);
    gManager->updateCounter(HsQMLManager::QObjectCount, -1);
}

const QMetaObject* HsQMLObject::metaObject() const
{
    return QObject::d_ptr->metaObject ?
        QObject::d_ptr->dynamicMetaObject() : mKlass->metaObj();
}

void* HsQMLObject::qt_metacast(const char* clname)
{
    if (!clname) {
        return 0;
    }
    if (!strcmp(clname, mKlass->metaObj()->className())) {
        return static_cast<void*>(const_cast<HsQMLObject*>(this));
    }
    return QObject::qt_metacast(clname);
}

int HsQMLObject::qt_metacall(QMetaObject::Call c, int id, void** a)
{
    id = QObject::qt_metacall(c, id, a);
    if (id < 0) {
        return id;
    }
    gManager->setActiveEngine(mEngine);
    if (QMetaObject::InvokeMetaMethod == c) {
        mKlass->methods()[id](this, a);
        id -= mKlass->methodCount();
    }
    else if (QMetaObject::ReadProperty == c) {
        mKlass->properties()[2*id](this, a);
        id -= mKlass->propertyCount();
    }
    else if (QMetaObject::WriteProperty == c) {
        HsQMLUniformFunc uf = mKlass->properties()[2*id+1];
        if (uf) {
            uf(this, a);
        }
        id -= mKlass->propertyCount();
    }
    else if (QMetaObject::QueryPropertyDesignable == c ||
             QMetaObject::QueryPropertyScriptable == c ||
             QMetaObject::QueryPropertyStored == c ||
             QMetaObject::QueryPropertyEditable == c ||
             QMetaObject::QueryPropertyUser == c) {
        id -= mKlass->propertyCount();
    }
    gManager->setActiveEngine(NULL);
    return id;
}

void HsQMLObject::setGCLock()
{
    mGCLock = mEngine->declEngine()->newQObject(this);
}

void HsQMLObject::clearGCLock()
{
    mGCLock = QJSValue(QJSValue::NullValue);
}

bool HsQMLObject::isGCLocked() const
{
    return mGCLock.isQObject();
}

QJSValue* HsQMLObject::gcLockVar()
{
    return &mGCLock;
}

HsQMLObjectProxy* HsQMLObject::proxy() const
{
    return mProxy;
}

HsQMLEngine* HsQMLObject::engine() const
{
    return mEngine;
}

extern "C" HsQMLObjectHandle* hsqml_create_object(
    HsStablePtr haskell, HsQMLClassHandle* kHndl)
{
    HsQMLObjectProxy* proxy = new HsQMLObjectProxy(haskell, (HsQMLClass*)kHndl);
    return (HsQMLObjectHandle*)proxy;
}

extern "C" int hsqml_object_set_active(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    if (proxy) {
        HsQMLEngine* engine = proxy->engine();
        if (engine) {
            gManager->setActiveEngine(engine);
        }
        else {
            // Nothing can be done if the object hasn't been marshalled before
            // because otherwise the relevant engine is unknown.
            return false;
        }
    }
    else {
        gManager->setActiveEngine(NULL);
    }
    return true;
}

extern "C" HsStablePtr hsqml_object_get_hs_typerep(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    return proxy->klass()->hsTypeRep();
}

extern HsStablePtr hsqml_object_get_hs_value(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    return proxy->haskell();
}

extern void* hsqml_object_get_pointer(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    return (void*)proxy->object(gManager->activeEngine());
}

extern HsQMLJValHandle* hsqml_object_get_jval(
    HsQMLObjectHandle* hndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    HsQMLObject* obj = proxy->object(gManager->activeEngine());
    return reinterpret_cast<HsQMLJValHandle*>(obj->gcLockVar());
}

extern HsQMLObjectHandle* hsqml_get_object_from_pointer(
    void* ptr)
{
    // Return NULL if the input pointer is NULL
    if (!ptr) {
        return NULL;
    }

    // Get object proxy
    HsQMLObject* object = (HsQMLObject*)ptr;
    HsQMLObjectProxy* proxy = object->proxy();
    proxy->ref(HsQMLObjectProxy::Handle);
    proxy->tryGCLock();

    return (HsQMLObjectHandle*)proxy;
}

extern HsQMLObjectHandle* hsqml_get_object_from_jval(
    HsQMLJValHandle* jvalHndl)
{
    QJSValue* jval = reinterpret_cast<QJSValue*>(jvalHndl);
    return hsqml_get_object_from_pointer(jval->toQObject());
}

extern void hsqml_object_reference_handle(
    HsQMLObjectHandle* hndl,
    int weak)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    proxy->ref(weak ? HsQMLObjectProxy::WeakHandle : HsQMLObjectProxy::Handle);
}

extern void hsqml_finalise_object_handle(
    HsQMLObjectHandle* hndl)
{
    if (hndl) {
        HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
        proxy->deref(HsQMLObjectProxy::Handle);
    }
}

extern void hsqml_finalise_object_weak_handle(
    HsQMLObjectHandle* hndl)
{
    if (hndl) {
        HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
        proxy->deref(HsQMLObjectProxy::WeakHandle);
    }
}

extern void hsqml_fire_signal(
    HsQMLObjectHandle* hndl, int idx, void** args)
{
    HsQMLObjectProxy* proxy = (HsQMLObjectProxy*)hndl;
    HsQMLEngine* engine = proxy->engine();
    // Ignore objects which haven't been marshalled as they are not connected.
    if (engine) {
        // Clear active engine in case the slot code calls back into Haskell.
        Q_ASSERT(gManager->activeEngine() == engine);
        gManager->setActiveEngine(NULL);
        HsQMLObject* obj = proxy->object(engine);
        QMetaObject::activate(obj, proxy->klass()->metaObj(), idx, args);
    }
}

extern HsQMLObjFinaliserHandle* hsqml_create_obj_finaliser(
    HsQMLObjFinaliserCb cb)
{
    return reinterpret_cast<HsQMLObjFinaliserHandle*>(
        new HsQMLObjectFinaliser::Ref(new HsQMLObjectFinaliser(cb)));
}

extern void hsqml_finalise_obj_finaliser(
    HsQMLObjFinaliserHandle* hndl)
{
    HsQMLObjectFinaliser::Ref* fp =
        reinterpret_cast<HsQMLObjectFinaliser::Ref*>(hndl);
    delete fp;
}

extern void hsqml_object_add_finaliser(
    HsQMLObjectHandle* hndl, HsQMLObjFinaliserHandle* fhndl)
{
    HsQMLObjectProxy* proxy = reinterpret_cast<HsQMLObjectProxy*>(hndl);
    proxy->addFinaliser(*reinterpret_cast<HsQMLObjectFinaliser::Ref*>(fhndl));
}
<|endoftext|>