<commit_before>/*****************************************************************************
 * util.cpp : matroska demuxer
 *****************************************************************************
 * Copyright (C) 2003-2004 VLC authors and VideoLAN
 * $Id$
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Steve Lhomme <steve.lhomme@free.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#include "mkv.hpp"
#include "util.hpp"
#include "demux.hpp"

#include <stdint.h>
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/

#ifdef HAVE_ZLIB_H
int32_t zlib_decompress_extra( demux_t * p_demux, mkv_track_t * tk )
{
    int result;
    z_stream d_stream;
    size_t n = 0;
    uint8_t * p_new_extra = NULL;

    msg_Dbg(p_demux,"Inflating private data");

    d_stream.zalloc = Z_NULL;
    d_stream.zfree = Z_NULL;
    d_stream.opaque = Z_NULL;
    if( inflateInit( &d_stream ) != Z_OK )
    {
        msg_Err( p_demux, "Couldn't initiate inflation ignore track %d",
                 tk->i_number );
        free(tk->p_extra_data);
        delete tk;
        return 1;
    }

    d_stream.next_in = tk->p_extra_data;
    d_stream.avail_in = tk->i_extra_data;
    do
    {
        n++;
        p_new_extra = (uint8_t *) realloc(p_new_extra, n*1024);
        if( !p_new_extra )
        {
            msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
                      tk->i_number );
            inflateEnd( &d_stream );
            free(tk->p_extra_data);
            delete tk;
            return 1;
        }
        d_stream.next_out = &p_new_extra[(n - 1) * 1024];
        d_stream.avail_out = 1024;
        result = inflate(&d_stream, Z_NO_FLUSH);
        if( result != Z_OK && result != Z_STREAM_END )
        {
            msg_Err( p_demux, "Zlib decompression failed. Result: %d", result );
            inflateEnd( &d_stream );
            free(p_new_extra);
            free(tk->p_extra_data);
            delete tk;
            return 1;
        }
    }
    while ( d_stream.avail_out == 0 && d_stream.avail_in != 0  &&
            result != Z_STREAM_END );

    free( tk->p_extra_data );
    tk->i_extra_data = d_stream.total_out;
    p_new_extra = (uint8_t *) realloc(p_new_extra, tk->i_extra_data);
    if( !p_new_extra )
    {
        msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
                 tk->i_number );
        inflateEnd( &d_stream );
        free(p_new_extra);
        delete tk;
        return 1;
    }

    tk->p_extra_data = p_new_extra;

    inflateEnd( &d_stream );
    return 0;
}

block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
    int result, dstsize, n;
    unsigned char *dst;
    block_t *p_block;
    z_stream d_stream;

    d_stream.zalloc = (alloc_func)0;
    d_stream.zfree = (free_func)0;
    d_stream.opaque = (voidpf)0;
    result = inflateInit(&d_stream);
    if( result != Z_OK )
    {
        msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
        return NULL;
    }

    d_stream.next_in = (Bytef *)p_in_block->p_buffer;
    d_stream.avail_in = p_in_block->i_buffer;
    n = 0;
    p_block = block_Alloc( 0 );
    dst = NULL;
    do
    {
        n++;
        p_block = block_Realloc( p_block, 0, n * 1000 );
        dst = (unsigned char *)p_block->p_buffer;
        d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
        d_stream.avail_out = 1000;
        result = inflate(&d_stream, Z_NO_FLUSH);
        if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
        {
            msg_Err( p_this, "Zlib decompression failed. Result: %d", result );
            inflateEnd( &d_stream );
            block_Release( p_block );
            return p_in_block;
        }
    }
    while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
           ( result != Z_STREAM_END ) );

    dstsize = d_stream.total_out;
    inflateEnd( &d_stream );

    p_block = block_Realloc( p_block, 0, dstsize );
    p_block->i_buffer = dstsize;
    block_Release( p_in_block );

    return p_block;
}
#endif

/* Utility function for BlockDecode */
block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset)
{
    if( unlikely( i_mem > SIZE_MAX - offset ) )
        return NULL;

    block_t *p_block = block_Alloc( i_mem + offset );
    if( likely(p_block != NULL) )
    {
        memcpy( p_block->p_buffer + offset, p_mem, i_mem );
    }
    return p_block;
}

void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, mtime_t i_pts)
{
    uint8_t * p_frame = p_blk->p_buffer;
    Cook_PrivateTrackData * p_sys = (Cook_PrivateTrackData *) p_tk->p_sys;
    size_t size = p_blk->i_buffer;

    if( p_tk->i_last_dts == VLC_TS_INVALID )
    {
        for( size_t i = 0; i < p_sys->i_subpackets; i++)
            if( p_sys->p_subpackets[i] )
            {
                block_Release(p_sys->p_subpackets[i]);
                p_sys->p_subpackets[i] = NULL;
            }
        p_sys->i_subpacket = 0;
    }

    if( p_tk->fmt.i_codec == VLC_CODEC_COOK ||
        p_tk->fmt.i_codec == VLC_CODEC_ATRAC3 )
    {
        const uint32_t i_num = p_sys->i_frame_size / p_sys->i_subpacket_size;
        const int y = p_sys->i_subpacket / ( p_sys->i_frame_size / p_sys->i_subpacket_size );

        for( int i = 0; i < i_num; i++ )
        {
            int i_index = p_sys->i_sub_packet_h * i +
                          ((p_sys->i_sub_packet_h + 1) / 2) * (y&1) + (y>>1);
            if( i_index >= p_sys->i_subpackets )
                return;

            block_t *p_block = block_Alloc( p_sys->i_subpacket_size );
            if( !p_block )
                return;

            if( size < p_sys->i_subpacket_size )
                return;

            memcpy( p_block->p_buffer, p_frame, p_sys->i_subpacket_size );
            p_block->i_dts = VLC_TS_INVALID;
            p_block->i_pts = VLC_TS_INVALID;
            if( !p_sys->i_subpacket )
            {
                p_tk->i_last_dts =
                p_block->i_pts = i_pts + VLC_TS_0;
            }

            p_frame += p_sys->i_subpacket_size;
            size -=  p_sys->i_subpacket_size;

            p_sys->i_subpacket++;
            p_sys->p_subpackets[i_index] = p_block;
        }
    }
    else
    {
        /*TODO*/
    }
    if( p_sys->i_subpacket == p_sys->i_subpackets )
    {
        for( size_t i = 0; i < p_sys->i_subpackets; i++)
        {
            es_out_Send( p_demux->out, p_tk->p_es,  p_sys->p_subpackets[i]);
            p_sys->p_subpackets[i] = NULL;
        }
        p_sys->i_subpacket = 0;
    }
}

int32_t Cook_PrivateTrackData::Init()
{
    i_subpackets = (size_t) i_sub_packet_h * (size_t) i_frame_size / (size_t) i_subpacket_size;
    p_subpackets = (block_t**) calloc(i_subpackets, sizeof(block_t*));

    if( unlikely( !p_subpackets ) )
    {
        i_subpackets = 0;
        return 1;
    }

    return 0;
}

Cook_PrivateTrackData::~Cook_PrivateTrackData()
{
    for( size_t i = 0; i < i_subpackets; i++ )
        if( p_subpackets[i] )
            block_Release( p_subpackets[i] );

    free( p_subpackets );
}

static inline void fill_wvpk_block(uint16_t version, uint32_t block_samples, uint32_t flags,
                                   uint32_t crc, uint8_t * src, size_t srclen, uint8_t * dst)
{
    const uint8_t wvpk_header[] = {'w','v','p','k',         /* ckId */
                                    0x0, 0x0, 0x0, 0x0,     /* ckSize */
                                    0x0, 0x0,               /* version */
                                    0x0,                    /* track_no */
                                    0x0,                    /* index_no */
                                    0xFF, 0xFF, 0xFF, 0xFF, /* total_samples */
                                    0x0, 0x0, 0x0, 0x0 };   /* block_index */
    memcpy( dst, wvpk_header, sizeof( wvpk_header ) );
    SetDWLE( dst + 4, srclen + 24 );
    SetWLE( dst + 8, version );
    SetDWLE( dst + 20, block_samples );
    SetDWLE( dst + 24, flags );
    SetDWLE( dst + 28, crc );
    memcpy( dst + 32, src, srclen );
}

block_t * packetize_wavpack( mkv_track_t * p_tk, uint8_t * buffer, size_t  size)
{
    uint16_t version = 0x403;
    uint32_t block_samples;
    uint32_t flags;
    uint32_t crc;
    block_t * p_block = NULL;

    if( p_tk->i_extra_data >= 2 )
        version = GetWLE( p_tk->p_extra_data );

    if( size < 12 )
        return NULL;

    block_samples = GetDWLE(buffer);
    buffer += 4;
    flags = GetDWLE(buffer);
    size -= 4;

    /* Check if WV_INITIAL_BLOCK and WV_FINAL_BLOCK are present */
    if( ( flags & 0x1800 ) == 0x1800 )
    {
        crc = GetDWLE(buffer+4);
        buffer += 8;
        size -= 8;

        p_block = block_Alloc( size + 32 );
        if( !p_block )
            return NULL;

        fill_wvpk_block(version, block_samples, flags, crc, buffer, size, p_block->p_buffer);
    }
    else
    {
        /* Multiblock */
        size_t total_size = 0;

        p_block = block_Alloc( 0 );
        if( !p_block )
            return NULL;

        while(size >= 12)
        {
            flags = GetDWLE(buffer);
            buffer += 4;
            crc = GetDWLE(buffer);
            buffer += 4;
            uint32_t bsz = GetDWLE(buffer);
            buffer+= 4;
            size -= 12;

            bsz = (bsz < size)?bsz:size;

            total_size += bsz + 32;

            assert(total_size >= p_block->i_buffer);

            p_block = block_Realloc( p_block, 0, total_size );

            if( !p_block )
                return NULL;

            fill_wvpk_block(version, block_samples, flags, crc, buffer, bsz,
                            p_block->p_buffer + total_size - bsz - 32 );
            buffer += bsz;
            size -= bsz;
        }
    }

    return p_block;
}
<commit_msg>demux: mkv: fix warning & int overflow<commit_after>/*****************************************************************************
 * util.cpp : matroska demuxer
 *****************************************************************************
 * Copyright (C) 2003-2004 VLC authors and VideoLAN
 * $Id$
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Steve Lhomme <steve.lhomme@free.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
#include "mkv.hpp"
#include "util.hpp"
#include "demux.hpp"

#include <stdint.h>
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/

#ifdef HAVE_ZLIB_H
int32_t zlib_decompress_extra( demux_t * p_demux, mkv_track_t * tk )
{
    int result;
    z_stream d_stream;
    size_t n = 0;
    uint8_t * p_new_extra = NULL;

    msg_Dbg(p_demux,"Inflating private data");

    d_stream.zalloc = Z_NULL;
    d_stream.zfree = Z_NULL;
    d_stream.opaque = Z_NULL;
    if( inflateInit( &d_stream ) != Z_OK )
    {
        msg_Err( p_demux, "Couldn't initiate inflation ignore track %d",
                 tk->i_number );
        free(tk->p_extra_data);
        delete tk;
        return 1;
    }

    d_stream.next_in = tk->p_extra_data;
    d_stream.avail_in = tk->i_extra_data;
    do
    {
        n++;
        p_new_extra = (uint8_t *) realloc(p_new_extra, n*1024);
        if( !p_new_extra )
        {
            msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
                      tk->i_number );
            inflateEnd( &d_stream );
            free(tk->p_extra_data);
            delete tk;
            return 1;
        }
        d_stream.next_out = &p_new_extra[(n - 1) * 1024];
        d_stream.avail_out = 1024;
        result = inflate(&d_stream, Z_NO_FLUSH);
        if( result != Z_OK && result != Z_STREAM_END )
        {
            msg_Err( p_demux, "Zlib decompression failed. Result: %d", result );
            inflateEnd( &d_stream );
            free(p_new_extra);
            free(tk->p_extra_data);
            delete tk;
            return 1;
        }
    }
    while ( d_stream.avail_out == 0 && d_stream.avail_in != 0  &&
            result != Z_STREAM_END );

    free( tk->p_extra_data );
    tk->i_extra_data = d_stream.total_out;
    p_new_extra = (uint8_t *) realloc(p_new_extra, tk->i_extra_data);
    if( !p_new_extra )
    {
        msg_Err( p_demux, "Couldn't allocate buffer to inflate data, ignore track %d",
                 tk->i_number );
        inflateEnd( &d_stream );
        free(p_new_extra);
        delete tk;
        return 1;
    }

    tk->p_extra_data = p_new_extra;

    inflateEnd( &d_stream );
    return 0;
}

block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block ) {
    int result, dstsize, n;
    unsigned char *dst;
    block_t *p_block;
    z_stream d_stream;

    d_stream.zalloc = (alloc_func)0;
    d_stream.zfree = (free_func)0;
    d_stream.opaque = (voidpf)0;
    result = inflateInit(&d_stream);
    if( result != Z_OK )
    {
        msg_Dbg( p_this, "inflateInit() failed. Result: %d", result );
        return NULL;
    }

    d_stream.next_in = (Bytef *)p_in_block->p_buffer;
    d_stream.avail_in = p_in_block->i_buffer;
    n = 0;
    p_block = block_Alloc( 0 );
    dst = NULL;
    do
    {
        n++;
        p_block = block_Realloc( p_block, 0, n * 1000 );
        dst = (unsigned char *)p_block->p_buffer;
        d_stream.next_out = (Bytef *)&dst[(n - 1) * 1000];
        d_stream.avail_out = 1000;
        result = inflate(&d_stream, Z_NO_FLUSH);
        if( ( result != Z_OK ) && ( result != Z_STREAM_END ) )
        {
            msg_Err( p_this, "Zlib decompression failed. Result: %d", result );
            inflateEnd( &d_stream );
            block_Release( p_block );
            return p_in_block;
        }
    }
    while( ( d_stream.avail_out == 0 ) && ( d_stream.avail_in != 0 ) &&
           ( result != Z_STREAM_END ) );

    dstsize = d_stream.total_out;
    inflateEnd( &d_stream );

    p_block = block_Realloc( p_block, 0, dstsize );
    p_block->i_buffer = dstsize;
    block_Release( p_in_block );

    return p_block;
}
#endif

/* Utility function for BlockDecode */
block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset)
{
    if( unlikely( i_mem > SIZE_MAX - offset ) )
        return NULL;

    block_t *p_block = block_Alloc( i_mem + offset );
    if( likely(p_block != NULL) )
    {
        memcpy( p_block->p_buffer + offset, p_mem, i_mem );
    }
    return p_block;
}

void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, mtime_t i_pts)
{
    uint8_t * p_frame = p_blk->p_buffer;
    Cook_PrivateTrackData * p_sys = (Cook_PrivateTrackData *) p_tk->p_sys;
    size_t size = p_blk->i_buffer;

    if( p_tk->i_last_dts == VLC_TS_INVALID )
    {
        for( size_t i = 0; i < p_sys->i_subpackets; i++)
            if( p_sys->p_subpackets[i] )
            {
                block_Release(p_sys->p_subpackets[i]);
                p_sys->p_subpackets[i] = NULL;
            }
        p_sys->i_subpacket = 0;
    }

    if( p_tk->fmt.i_codec == VLC_CODEC_COOK ||
        p_tk->fmt.i_codec == VLC_CODEC_ATRAC3 )
    {
        const uint16_t i_num = p_sys->i_frame_size / p_sys->i_subpacket_size;
        const size_t y = p_sys->i_subpacket / ( p_sys->i_frame_size / p_sys->i_subpacket_size );

        for( uint16_t i = 0; i < i_num; i++ )
        {
            size_t i_index = (size_t) p_sys->i_sub_packet_h * i +
                          ((p_sys->i_sub_packet_h + 1) / 2) * (y&1) + (y>>1);
            if( i_index >= p_sys->i_subpackets )
                return;

            block_t *p_block = block_Alloc( p_sys->i_subpacket_size );
            if( !p_block )
                return;

            if( size < p_sys->i_subpacket_size )
                return;

            memcpy( p_block->p_buffer, p_frame, p_sys->i_subpacket_size );
            p_block->i_dts = VLC_TS_INVALID;
            p_block->i_pts = VLC_TS_INVALID;
            if( !p_sys->i_subpacket )
            {
                p_tk->i_last_dts =
                p_block->i_pts = i_pts + VLC_TS_0;
            }

            p_frame += p_sys->i_subpacket_size;
            size -=  p_sys->i_subpacket_size;

            p_sys->i_subpacket++;
            p_sys->p_subpackets[i_index] = p_block;
        }
    }
    else
    {
        /*TODO*/
    }
    if( p_sys->i_subpacket == p_sys->i_subpackets )
    {
        for( size_t i = 0; i < p_sys->i_subpackets; i++)
        {
            es_out_Send( p_demux->out, p_tk->p_es,  p_sys->p_subpackets[i]);
            p_sys->p_subpackets[i] = NULL;
        }
        p_sys->i_subpacket = 0;
    }
}

int32_t Cook_PrivateTrackData::Init()
{
    i_subpackets = (size_t) i_sub_packet_h * (size_t) i_frame_size / (size_t) i_subpacket_size;
    p_subpackets = (block_t**) calloc(i_subpackets, sizeof(block_t*));

    if( unlikely( !p_subpackets ) )
    {
        i_subpackets = 0;
        return 1;
    }

    return 0;
}

Cook_PrivateTrackData::~Cook_PrivateTrackData()
{
    for( size_t i = 0; i < i_subpackets; i++ )
        if( p_subpackets[i] )
            block_Release( p_subpackets[i] );

    free( p_subpackets );
}

static inline void fill_wvpk_block(uint16_t version, uint32_t block_samples, uint32_t flags,
                                   uint32_t crc, uint8_t * src, size_t srclen, uint8_t * dst)
{
    const uint8_t wvpk_header[] = {'w','v','p','k',         /* ckId */
                                    0x0, 0x0, 0x0, 0x0,     /* ckSize */
                                    0x0, 0x0,               /* version */
                                    0x0,                    /* track_no */
                                    0x0,                    /* index_no */
                                    0xFF, 0xFF, 0xFF, 0xFF, /* total_samples */
                                    0x0, 0x0, 0x0, 0x0 };   /* block_index */
    memcpy( dst, wvpk_header, sizeof( wvpk_header ) );
    SetDWLE( dst + 4, srclen + 24 );
    SetWLE( dst + 8, version );
    SetDWLE( dst + 20, block_samples );
    SetDWLE( dst + 24, flags );
    SetDWLE( dst + 28, crc );
    memcpy( dst + 32, src, srclen );
}

block_t * packetize_wavpack( mkv_track_t * p_tk, uint8_t * buffer, size_t  size)
{
    uint16_t version = 0x403;
    uint32_t block_samples;
    uint32_t flags;
    uint32_t crc;
    block_t * p_block = NULL;

    if( p_tk->i_extra_data >= 2 )
        version = GetWLE( p_tk->p_extra_data );

    if( size < 12 )
        return NULL;

    block_samples = GetDWLE(buffer);
    buffer += 4;
    flags = GetDWLE(buffer);
    size -= 4;

    /* Check if WV_INITIAL_BLOCK and WV_FINAL_BLOCK are present */
    if( ( flags & 0x1800 ) == 0x1800 )
    {
        crc = GetDWLE(buffer+4);
        buffer += 8;
        size -= 8;

        p_block = block_Alloc( size + 32 );
        if( !p_block )
            return NULL;

        fill_wvpk_block(version, block_samples, flags, crc, buffer, size, p_block->p_buffer);
    }
    else
    {
        /* Multiblock */
        size_t total_size = 0;

        p_block = block_Alloc( 0 );
        if( !p_block )
            return NULL;

        while(size >= 12)
        {
            flags = GetDWLE(buffer);
            buffer += 4;
            crc = GetDWLE(buffer);
            buffer += 4;
            uint32_t bsz = GetDWLE(buffer);
            buffer+= 4;
            size -= 12;

            bsz = (bsz < size)?bsz:size;

            total_size += bsz + 32;

            assert(total_size >= p_block->i_buffer);

            p_block = block_Realloc( p_block, 0, total_size );

            if( !p_block )
                return NULL;

            fill_wvpk_block(version, block_samples, flags, crc, buffer, bsz,
                            p_block->p_buffer + total_size - bsz - 32 );
            buffer += bsz;
            size -= bsz;
        }
    }

    return p_block;
}
<|endoftext|>


<commit_before>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Antonin Bas (antonin@barefootnetworks.com)
 *
 */

#include <PI/pi.h>
#include <PI/target/pi_imp.h>

#include <string>
#include <cstring>  // for memset

#include "conn_mgr.h"
#include "common.h"
#include "cpu_send_recv.h"

#define NUM_DEVICES 256

namespace pibmv2 {

conn_mgr_t *conn_mgr_state = NULL;

device_info_t device_info_state[NUM_DEVICES];

extern void start_learn_listener(const std::string &addr, int rpc_port_num);
extern void stop_learn_listener();

}  // namespace pibmv2

namespace {

pibmv2::CpuSendRecv *cpu_send_recv = nullptr;

}  // namespace

extern "C" {

pi_status_t _pi_init(void *extra) {
  (void) extra;
  memset(pibmv2::device_info_state, 0, sizeof(pibmv2::device_info_state));
  pibmv2::conn_mgr_state = pibmv2::conn_mgr_create();
  cpu_send_recv = new pibmv2::CpuSendRecv();
  cpu_send_recv->start();
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_assign_device(pi_dev_id_t dev_id, const pi_p4info_t *p4info,
                              pi_assign_extra_t *extra) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  assert(!d_info->assigned);
  int rpc_port_num = -1;
  std::string bm_notifications_addr("");
  for (; !extra->end_of_extras; extra++) {
    std::string key(extra->key);
    if (key == "port" && extra->v) {
      try {
        rpc_port_num = std::stoi(std::string(extra->v), nullptr, 0);
      }
      catch (const std::exception& e) {
        return PI_STATUS_INVALID_INIT_EXTRA_PARAM;
      }
    } else if (key == "notifications" && extra->v) {
      bm_notifications_addr = std::string(extra->v);
    } else if (key == "cpu_iface" && extra->v) {
      int rc = cpu_send_recv->add_device(std::string(extra->v), dev_id);
      if (rc < 0) return PI_STATUS_INVALID_INIT_EXTRA_PARAM;
    }
  }
  if (rpc_port_num == -1) return PI_STATUS_MISSING_INIT_EXTRA_PARAM;
  if (conn_mgr_client_init(pibmv2::conn_mgr_state, dev_id, rpc_port_num))
    return PI_STATUS_TARGET_TRANSPORT_ERROR;

  if (bm_notifications_addr != "")
    pibmv2::start_learn_listener(bm_notifications_addr, rpc_port_num);

  d_info->p4info = p4info;
  d_info->assigned = 1;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_update_device_start(pi_dev_id_t dev_id,
                                    const pi_p4info_t *p4info,
                                    const char *device_data,
                                    size_t device_data_size) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  std::string new_config(device_data, device_data_size);

  auto client = conn_mgr_client(pibmv2::conn_mgr_state, dev_id);
  try {
    client.c->bm_load_new_config(std::move(new_config));
  } catch (InvalidSwapOperation &iso) {
    const char *what =
        _SwapOperationErrorCode_VALUES_TO_NAMES.find(iso.code)->second;
    std::cout << "Invalid swap operation (" << iso.code << "): "
              << what << std::endl;
    return static_cast<pi_status_t>(PI_STATUS_TARGET_ERROR + iso.code);
  }

  d_info->p4info = p4info;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_update_device_end(pi_dev_id_t dev_id) {
  auto client = conn_mgr_client(pibmv2::conn_mgr_state, dev_id);
  try {
    client.c->bm_swap_configs();
  } catch (InvalidSwapOperation &iso) {
    const char *what =
        _SwapOperationErrorCode_VALUES_TO_NAMES.find(iso.code)->second;
    std::cout << "Invalid swap operation (" << iso.code << "): "
              << what << std::endl;
    return static_cast<pi_status_t>(PI_STATUS_TARGET_ERROR + iso.code);
  }
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_remove_device(pi_dev_id_t dev_id) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  assert(d_info->assigned);
  pibmv2::conn_mgr_client_close(pibmv2::conn_mgr_state, dev_id);
  cpu_send_recv->remove_device(dev_id);
  d_info->assigned = 0;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_destroy() {
  pibmv2::conn_mgr_destroy(pibmv2::conn_mgr_state);
  pibmv2::stop_learn_listener();
  delete cpu_send_recv;
  return PI_STATUS_SUCCESS;
}

// bmv2 does not support transaction and has no use for the session_handle
pi_status_t _pi_session_init(pi_session_handle_t *session_handle) {
  *session_handle = 0;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_session_cleanup(pi_session_handle_t session_handle) {
  (void) session_handle;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_packetout_send(pi_dev_id_t dev_id, const char *pkt,
                               size_t size) {
  if (cpu_send_recv->send_pkt(dev_id, pkt, size) != static_cast<int>(size))
    return PI_STATUS_PACKETOUT_SEND_ERROR;
  return PI_STATUS_SUCCESS;
}

}
<commit_msg>fixed typo in bmv2 CPU receiver<commit_after>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Antonin Bas (antonin@barefootnetworks.com)
 *
 */

#include <PI/pi.h>
#include <PI/target/pi_imp.h>

#include <string>
#include <cstring>  // for memset

#include "conn_mgr.h"
#include "common.h"
#include "cpu_send_recv.h"

#define NUM_DEVICES 256

namespace pibmv2 {

conn_mgr_t *conn_mgr_state = NULL;

device_info_t device_info_state[NUM_DEVICES];

extern void start_learn_listener(const std::string &addr, int rpc_port_num);
extern void stop_learn_listener();

}  // namespace pibmv2

namespace {

pibmv2::CpuSendRecv *cpu_send_recv = nullptr;

}  // namespace

extern "C" {

pi_status_t _pi_init(void *extra) {
  (void) extra;
  memset(pibmv2::device_info_state, 0, sizeof(pibmv2::device_info_state));
  pibmv2::conn_mgr_state = pibmv2::conn_mgr_create();
  cpu_send_recv = new pibmv2::CpuSendRecv();
  cpu_send_recv->start();
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_assign_device(pi_dev_id_t dev_id, const pi_p4info_t *p4info,
                              pi_assign_extra_t *extra) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  assert(!d_info->assigned);
  int rpc_port_num = -1;
  std::string bm_notifications_addr("");
  for (; !extra->end_of_extras; extra++) {
    std::string key(extra->key);
    if (key == "port" && extra->v) {
      try {
        rpc_port_num = std::stoi(std::string(extra->v), nullptr, 0);
      }
      catch (const std::exception& e) {
        return PI_STATUS_INVALID_INIT_EXTRA_PARAM;
      }
    } else if (key == "notifications" && extra->v) {
      bm_notifications_addr = std::string(extra->v);
    } else if (key == "cpu_iface" && extra->v) {
      int rc = cpu_send_recv->add_device(std::string(extra->v), dev_id);
      if (rc < 0) return PI_STATUS_INVALID_INIT_EXTRA_PARAM;
    }
  }
  if (rpc_port_num == -1) return PI_STATUS_MISSING_INIT_EXTRA_PARAM;
  if (conn_mgr_client_init(pibmv2::conn_mgr_state, dev_id, rpc_port_num))
    return PI_STATUS_TARGET_TRANSPORT_ERROR;

  if (bm_notifications_addr != "")
    pibmv2::start_learn_listener(bm_notifications_addr, rpc_port_num);

  d_info->p4info = p4info;
  d_info->assigned = 1;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_update_device_start(pi_dev_id_t dev_id,
                                    const pi_p4info_t *p4info,
                                    const char *device_data,
                                    size_t device_data_size) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  std::string new_config(device_data, device_data_size);

  auto client = conn_mgr_client(pibmv2::conn_mgr_state, dev_id);
  try {
    client.c->bm_load_new_config(std::move(new_config));
  } catch (InvalidSwapOperation &iso) {
    const char *what =
        _SwapOperationErrorCode_VALUES_TO_NAMES.find(iso.code)->second;
    std::cout << "Invalid swap operation (" << iso.code << "): "
              << what << std::endl;
    return static_cast<pi_status_t>(PI_STATUS_TARGET_ERROR + iso.code);
  }

  d_info->p4info = p4info;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_update_device_end(pi_dev_id_t dev_id) {
  auto client = conn_mgr_client(pibmv2::conn_mgr_state, dev_id);
  try {
    client.c->bm_swap_configs();
  } catch (InvalidSwapOperation &iso) {
    const char *what =
        _SwapOperationErrorCode_VALUES_TO_NAMES.find(iso.code)->second;
    std::cout << "Invalid swap operation (" << iso.code << "): "
              << what << std::endl;
    return static_cast<pi_status_t>(PI_STATUS_TARGET_ERROR + iso.code);
  }
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_remove_device(pi_dev_id_t dev_id) {
  pibmv2::device_info_t *d_info = pibmv2::get_device_info(dev_id);
  assert(d_info->assigned);
  pibmv2::conn_mgr_client_close(pibmv2::conn_mgr_state, dev_id);
  cpu_send_recv->remove_device(dev_id);
  d_info->assigned = 0;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_destroy() {
  pibmv2::conn_mgr_destroy(pibmv2::conn_mgr_state);
  pibmv2::stop_learn_listener();
  delete cpu_send_recv;
  return PI_STATUS_SUCCESS;
}

// bmv2 does not support transaction and has no use for the session_handle
pi_status_t _pi_session_init(pi_session_handle_t *session_handle) {
  *session_handle = 0;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_session_cleanup(pi_session_handle_t session_handle) {
  (void) session_handle;
  return PI_STATUS_SUCCESS;
}

pi_status_t _pi_packetout_send(pi_dev_id_t dev_id, const char *pkt,
                               size_t size) {
  if (cpu_send_recv->send_pkt(dev_id, pkt, size) != 0)
    return PI_STATUS_PACKETOUT_SEND_ERROR;
  return PI_STATUS_SUCCESS;
}

}
<|endoftext|>


<commit_before>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
	KROLL_MODULE(PHPModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));
	static Logger* logger = Logger::Get("PHPModule");
	const static std::string phpSuffix("module.php");
	static bool buffering = false;

	PHPModule* PHPModule::instance_ = NULL;
	std::ostringstream PHPModule::buffer;
	std::string PHPModule::mimeType("text/html");

	static int UnbufferedWrite(const char *, unsigned int TSRMLS_DC);
	static void SetIniDefault(HashTable*, const char*, const char*);
	static void IniDefaults(HashTable*);
	static void LogMessage(char*);
	static int HeaderHandler(sapi_header_struct*, sapi_header_op_enum,
		sapi_headers_struct* TSRMLS_DC);

	void PHPModule::Initialize()
	{
		PHPModule::instance_ = this;
		int argc = 1;
		char *argv[2] = { "php_kroll", NULL };

		php_embed_module.ub_write = UnbufferedWrite;
		php_embed_module.log_message = LogMessage;
		php_embed_module.ini_defaults = IniDefaults;
		php_embed_module.header_handler = HeaderHandler;
		php_embed_init(argc, argv PTSRMLS_CC);

		PHPUtils::InitializePHPKrollClasses();
		this->InitializeBinding();
		host->AddModuleProvider(this);

		const char* resourcesPath =
			host->GetApplication()->GetResourcesPath().c_str();
		zend_alter_ini_entry("include_path", sizeof("include_path"),
			(char*) resourcesPath, strlen(resourcesPath),
			ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
	}

	/*static*/
	void PHPModule::SetBuffering(bool newBuffering)
	{
		if (buffering)
		{
			buffer.str("");
		}
		buffering = newBuffering;
	}

	void PHPModule::Stop()
	{
		PHPModule::instance_ = NULL;

		SharedKObject global = this->host->GetGlobalObject();
		Script::GetInstance()->RemoveScriptEvaluator(this->binding);
		global->Set("PHP", Value::Undefined);
		this->binding->Set("evaluate", Value::Undefined);
		this->binding = 0;
		PHPModule::instance_ = 0;

		php_embed_shutdown(TSRMLS_C);
	}

	void PHPModule::InitializeBinding()
	{
		PHPModule::mimeType = SG(default_mimetype);

		SharedKObject global = this->host->GetGlobalObject();
		this->binding = new PHPEvaluator();
		global->Set("PHP", Value::NewObject(this->binding));
		Script::GetInstance()->AddScriptEvaluator(this->binding);

		zval *titaniumValue = PHPUtils::ToPHPValue(Value::NewObject(global));
		ZEND_SET_SYMBOL(&EG(symbol_table), PRODUCT_NAME, titaniumValue);
	}

	bool PHPModule::IsModule(std::string& path)
	{
		return (path.substr(path.length()-phpSuffix.length()) == phpSuffix);
	}

	Module* PHPModule::CreateModule(std::string& path)
	{
		zend_first_try
		{
			std::string includeScript = "include '" + path + "';";
			if (SUCCESS != zend_eval_string((char *) includeScript.c_str(),
				NULL, (char *) path.c_str() TSRMLS_CC))
				logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_catch
		{
			logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_end_try();

		Poco::Path p(path);
		std::string name(p.getBaseName());
		std::string moduledir(p.makeParent().toString());
		logger->Info("Loading PHP module name=%s path=%s", name.c_str(), path.c_str());

		return new PHPModuleInstance(host, path, moduledir, name);
	}

	static int UnbufferedWrite(const char *str, unsigned int length TSRMLS_DC)
	{
		std::string string(str, length);
		std::ostringstream& buffer = PHPModule::GetBuffer();

		// This shouldn't need to be thread safe right?
		if (buffering)
		{
			buffer << string;
		}
		else
		{
			logger->Info(string.c_str());
		}
		return length;
	}

	static void SetIniDefault(HashTable* config, const char* name, const char* value)
	{
		// Forgive me Martin, borrowed from php_cli.c line 409
		// Thou are forgiven.
		zval tmp;
		Z_SET_REFCOUNT(tmp, 0);
		Z_UNSET_ISREF(tmp);
		ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0);
		zend_hash_update(config, name, sizeof(name), &tmp, sizeof(zval), NULL);
	}

	static void IniDefaults(HashTable* configuration)
	{
		SetIniDefault(configuration, "display_errors", "1");
	}

	static void LogMessage(char* message)
	{
		logger->Debug(message);
	}

	static int HeaderHandler(sapi_header_struct* sapiHeader,
		sapi_header_op_enum op, sapi_headers_struct* sapiHeaders TSRMLS_DC)
	{
		if (sapiHeaders && sapiHeaders->mimetype)
		{
			std::string& mimeType = PHPModule::GetMimeType();
			mimeType = sapiHeaders->mimetype;
		}
		return op;
	}
}
<commit_msg>Fix for invalid memory access issue in PHP Module.<commit_after>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */
#include <signal.h>
#include "php_module.h"
#include <Poco/Path.h>

#ifdef ZTS
void ***tsrm_ls;
#endif

namespace kroll
{
	KROLL_MODULE(PHPModule, STRING(MODULE_NAME), STRING(MODULE_VERSION));
	static Logger* logger = Logger::Get("PHPModule");
	const static std::string phpSuffix("module.php");
	static bool buffering = false;

	PHPModule* PHPModule::instance_ = NULL;
	std::ostringstream PHPModule::buffer;
	std::string PHPModule::mimeType("text/html");

	static int UnbufferedWrite(const char *, unsigned int TSRMLS_DC);
	static void SetIniDefault(HashTable*, const char*, const char*);
	static void IniDefaults(HashTable*);
	static void LogMessage(char*);
	static int HeaderHandler(sapi_header_struct*, sapi_header_op_enum,
		sapi_headers_struct* TSRMLS_DC);

	void PHPModule::Initialize()
	{
		PHPModule::instance_ = this;
		int argc = 1;
		char *argv[2] = { "php_kroll", NULL };

		php_embed_module.ub_write = UnbufferedWrite;
		php_embed_module.log_message = LogMessage;
		php_embed_module.ini_defaults = IniDefaults;
		php_embed_module.header_handler = HeaderHandler;
		php_embed_init(argc, argv PTSRMLS_CC);

		PHPUtils::InitializePHPKrollClasses();
		this->InitializeBinding();
		host->AddModuleProvider(this);

		std::string resourcesPath(host->GetApplication()->GetResourcesPath());
		zend_alter_ini_entry("include_path", sizeof("include_path"),
			(char*) resourcesPath.c_str(), resourcesPath.size() - 1,
			ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
	}

	/*static*/
	void PHPModule::SetBuffering(bool newBuffering)
	{
		if (buffering)
		{
			buffer.str("");
		}
		buffering = newBuffering;
	}

	void PHPModule::Stop()
	{
		PHPModule::instance_ = NULL;

		SharedKObject global = this->host->GetGlobalObject();
		Script::GetInstance()->RemoveScriptEvaluator(this->binding);
		global->Set("PHP", Value::Undefined);
		this->binding->Set("evaluate", Value::Undefined);
		this->binding = 0;
		PHPModule::instance_ = 0;

		php_embed_shutdown(TSRMLS_C);
	}

	void PHPModule::InitializeBinding()
	{
		PHPModule::mimeType = SG(default_mimetype);

		SharedKObject global = this->host->GetGlobalObject();
		this->binding = new PHPEvaluator();
		global->Set("PHP", Value::NewObject(this->binding));
		Script::GetInstance()->AddScriptEvaluator(this->binding);

		zval *titaniumValue = PHPUtils::ToPHPValue(Value::NewObject(global));
		ZEND_SET_SYMBOL(&EG(symbol_table), PRODUCT_NAME, titaniumValue);
	}

	bool PHPModule::IsModule(std::string& path)
	{
		return (path.substr(path.length()-phpSuffix.length()) == phpSuffix);
	}

	Module* PHPModule::CreateModule(std::string& path)
	{
		zend_first_try
		{
			std::string includeScript = "include '" + path + "';";
			if (SUCCESS != zend_eval_string((char *) includeScript.c_str(),
				NULL, (char *) path.c_str() TSRMLS_CC))
				logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_catch
		{
			logger->Error("Error evaluating module at path: %s", path.c_str());
		}
		zend_end_try();

		Poco::Path p(path);
		std::string name(p.getBaseName());
		std::string moduledir(p.makeParent().toString());
		logger->Info("Loading PHP module name=%s path=%s", name.c_str(), path.c_str());

		return new PHPModuleInstance(host, path, moduledir, name);
	}

	static int UnbufferedWrite(const char *str, unsigned int length TSRMLS_DC)
	{
		std::string string(str, length);
		std::ostringstream& buffer = PHPModule::GetBuffer();

		// This shouldn't need to be thread safe right?
		if (buffering)
		{
			buffer << string;
		}
		else
		{
			logger->Info(string.c_str());
		}
		return length;
	}

	static void SetIniDefault(HashTable* config, const char* name, const char* value)
	{
		// Forgive me Martin, borrowed from php_cli.c line 409
		// Thou are forgiven.
		zval tmp;
		Z_SET_REFCOUNT(tmp, 0);
		Z_UNSET_ISREF(tmp);
		ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0);
		zend_hash_update(config, name, sizeof(name), &tmp, sizeof(zval), NULL);
	}

	static void IniDefaults(HashTable* configuration)
	{
		SetIniDefault(configuration, "display_errors", "1");
	}

	static void LogMessage(char* message)
	{
		logger->Debug(message);
	}

	static int HeaderHandler(sapi_header_struct* sapiHeader,
		sapi_header_op_enum op, sapi_headers_struct* sapiHeaders TSRMLS_DC)
	{
		if (sapiHeaders && sapiHeaders->mimetype)
		{
			std::string& mimeType = PHPModule::GetMimeType();
			mimeType = sapiHeaders->mimetype;
		}
		return op;
	}
}
<|endoftext|>


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

#ifndef _SBX_BRWVIEW_HXX
#define _SBX_BRWVIEW_HXX

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#ifndef _TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _TOOLS_RESID_HXX //autogen wg. ResId
#include <tools/resid.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

// =========================================================================
class ResMgr;
class Splitter;

namespace dbaui
{
    class DBTreeListModel;
    class DBTreeView;
    class SbaGridControl;

    class UnoDataBrowserView : public Window
    {
    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >        m_xMe;              // our own UNO representation
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >                 m_xGrid;            // our grid's UNO representation
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xServiceFactory;  // the service factory to work with

        DBTreeView*             m_pTreeView;
        Splitter*               m_pSplitter;
        ToolBox*                m_pToolBox;     // our toolbox (may be NULL)
        SbaGridControl*         m_pVclControl;  // our grid's VCL representation

        DECL_LINK( SplitHdl, void* );
    // attribute access
    public:
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >             getGridControl() const  { return m_xGrid; }
        SbaGridControl*         getVclControl() const   { return m_pVclControl; }
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >    getContainer() const    { return m_xMe; }

        ToolBox*        getToolBox() const      { return m_pToolBox; }

    public:
        UnoDataBrowserView(Window* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~UnoDataBrowserView();

        /// late construction
        virtual void Construct(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& xModel);

        /** as columns may be hidden there is a difference between a columns model pos and its view pos
            so we you may use these translation function
        */
        sal_uInt16 Model2ViewPos(sal_uInt16 nPos) const;
        sal_uInt16 View2ModelPos(sal_uInt16 nPos) const;
        /// for the same reason the view column count isn't the same as the model column count
        sal_uInt16 ViewColumnCount() const;

        /** use this if you want to have a ToolBox to be displayed at the top of the grid control
            The ownership of the window specified by pTB is transfered to this view object itself,
            i.e. it is deleted in the destructor (or in the next call to setToolBox).
            Specify a NULL pointer if you want to remove an existing ToolBox.
        */
        void setToolBox(ToolBox* pTB);
        void setSplitter(Splitter* _pSplitter);
        void setTreeView(DBTreeView* _pTreeView);

    protected:
        // window overridables
        virtual void Resize();

        virtual void GetFocus();
    };
}
#endif // _SBX_BRWVIEW_HXX

<commit_msg>Resize is public now<commit_after>/*************************************************************************
 *
 *  $RCSfile: brwview.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: fs $ $Date: 2000-12-08 21: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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SBX_BRWVIEW_HXX
#define _SBX_BRWVIEW_HXX

#ifndef _SV_WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif

#ifndef _TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _TOOLS_RESID_HXX //autogen wg. ResId
#include <tools/resid.hxx>
#endif

#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_
#include <com/sun/star/awt/XControlContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

// =========================================================================
class ResMgr;
class Splitter;

namespace dbaui
{
    class DBTreeListModel;
    class DBTreeView;
    class SbaGridControl;

    class UnoDataBrowserView : public Window
    {
    protected:
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >        m_xMe;              // our own UNO representation
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >                 m_xGrid;            // our grid's UNO representation
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xServiceFactory;  // the service factory to work with

        DBTreeView*             m_pTreeView;
        Splitter*               m_pSplitter;
        ToolBox*                m_pToolBox;     // our toolbox (may be NULL)
        SbaGridControl*         m_pVclControl;  // our grid's VCL representation

        DECL_LINK( SplitHdl, void* );
    // attribute access
    public:
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >             getGridControl() const  { return m_xGrid; }
        SbaGridControl*         getVclControl() const   { return m_pVclControl; }
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer >    getContainer() const    { return m_xMe; }

        ToolBox*        getToolBox() const      { return m_pToolBox; }

    public:
        UnoDataBrowserView(Window* pParent, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~UnoDataBrowserView();

        /// late construction
        virtual void Construct(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& xModel);

        /** as columns may be hidden there is a difference between a columns model pos and its view pos
            so we you may use these translation function
        */
        sal_uInt16 Model2ViewPos(sal_uInt16 nPos) const;
        sal_uInt16 View2ModelPos(sal_uInt16 nPos) const;
        /// for the same reason the view column count isn't the same as the model column count
        sal_uInt16 ViewColumnCount() const;

        /** use this if you want to have a ToolBox to be displayed at the top of the grid control
            The ownership of the window specified by pTB is transfered to this view object itself,
            i.e. it is deleted in the destructor (or in the next call to setToolBox).
            Specify a NULL pointer if you want to remove an existing ToolBox.
        */
        void setToolBox(ToolBox* pTB);
        void setSplitter(Splitter* _pSplitter);
        void setTreeView(DBTreeView* _pTreeView);

        // window overridables
        virtual void Resize();

    protected:
        virtual void GetFocus();
    };
}
#endif // _SBX_BRWVIEW_HXX

<|endoftext|>


<commit_before>/// @file Merge.cpp
///
/// The merging unit.
///
/// @par Full Description
/// The class defines the merging entity.
///
/// @ingroup Merge
///
/// @par Copyright (c) 2016 vcdMaker team
///
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included
/// in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
/// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
/// IN THE SOFTWARE.

#include <algorithm>
#include <ratio>

#include "Merge.h"
#include "Utils.h"

const uint64_t MERGE::Merge::TEN_POWER[] =
{
    1ull,
    static_cast<uint64_t>(std::kilo::num),
    static_cast<uint64_t>(std::mega::num),
    static_cast<uint64_t>(std::giga::num),
    static_cast<uint64_t>(std::tera::num),
    static_cast<uint64_t>(std::peta::num)
};

void MERGE::Merge::Run()
{
    // Find the minimum merging unit.
    m_MinTimeUnit = FindMinUnit();

    // If the output time unit is not forced use the minimum value.
    if (m_TimeUnit.empty())
    {
        // The minimum time unit used in sources.
        m_TimeUnit = m_MinTimeUnit;
    }

    // Create the output signal database and set its base time unit.
    m_pMerged = std::make_unique<SIGNAL::SignalDb>(m_TimeUnit);

    // Find the longest leading time for among all sources.
    m_MaxLeadingTime = FindMaxLeadingTime();

    // Merge Sources.
    for (const SignalSource *source : m_Sources)
    {
        // Get the source's time unit.
        const std::string sourceTimeUnit = source->GetTimeUnit();

        // Source sync time in the target unit.
        const uint64_t transformedSourceSync =
            TransformTimestamp(source->GetSyncPoint(), m_MinTimeUnit, sourceTimeUnit);

        // Merge signals here.
        for (auto current_signal : source->Get()->GetSignals())
        {
            SIGNAL::Signal *signal = current_signal->Clone();

            // Set the signal's new timestamp.
            signal->SetTimestamp(CalculateNewTime(TransformTimestamp(signal->GetTimestamp(),
                                                                     m_MinTimeUnit,
                                                                     sourceTimeUnit),
                                                  transformedSourceSync));

            // Update its name.
            signal->SetName(source->GetPrefix() + signal->GetName());

            // Add to the output signals database.
            m_pMerged->Add(signal);
        }
    }
}

std::string MERGE::Merge::FindMinUnit()
{
    size_t maxIndex = 0;

    for (const SignalSource *const source : m_Sources)
    {
        const size_t index = UTILS::GetTimeUnitIndex(source->GetTimeUnit());
        maxIndex = std::max(index, maxIndex);
    }

    return SIGNAL::Signal::TIME_UNITS[maxIndex];
}

uint64_t MERGE::Merge::FindMaxLeadingTime()
{
    uint64_t maxLeadingTime = 0;

    for (const SignalSource *const source : m_Sources)
    {
        uint64_t leadingTime = TransformTimestamp(source->GetLeadingTime(),
                                                  m_MinTimeUnit,
                                                  source->GetTimeUnit());
        maxLeadingTime = std::max(leadingTime, maxLeadingTime);
    }

    return maxLeadingTime;
}

uint64_t MERGE::Merge::TransformTimestamp(uint64_t time,
                                          const std::string &targetTimeUnit,
                                          const std::string &sourceTimeUnit)
{
    uint64_t newTime = time;
    uint32_t nominator = 0;
    uint32_t denominator = 0;

    const uint32_t targetPower = UTILS::GetTimeUnitIndex(targetTimeUnit);
    const uint32_t sourcePower = UTILS::GetTimeUnitIndex(sourceTimeUnit);

    if (targetPower > sourcePower)
    {
        nominator = (targetPower - sourcePower);
    }
    else if (targetPower < sourcePower)
    {
        denominator = (sourcePower - targetPower);
        /// @todo Range checking must be done.
        newTime = time + (TEN_POWER[denominator]) / 2);
    }

    const double unitsRatio =
        static_cast<double>(TEN_POWER[nominator]) / TEN_POWER[denominator];

    /// @todo Range checking must be done.
    return static_cast<uint64_t>(newTime * unitsRatio);
}

uint64_t MERGE::Merge::CalculateNewTime(uint64_t time,
                                        uint64_t syncPoint)
{
    /// @todo Detect uint64_t overflow.
    return (TransformTimestamp(time + m_MaxLeadingTime - syncPoint,
                               m_TimeUnit,
                               m_MinTimeUnit));
}
<commit_msg>Typo fix (compilation error)<commit_after>/// @file Merge.cpp
///
/// The merging unit.
///
/// @par Full Description
/// The class defines the merging entity.
///
/// @ingroup Merge
///
/// @par Copyright (c) 2016 vcdMaker team
///
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included
/// in all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
/// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
/// IN THE SOFTWARE.

#include <algorithm>
#include <ratio>

#include "Merge.h"
#include "Utils.h"

const uint64_t MERGE::Merge::TEN_POWER[] =
{
    1ull,
    static_cast<uint64_t>(std::kilo::num),
    static_cast<uint64_t>(std::mega::num),
    static_cast<uint64_t>(std::giga::num),
    static_cast<uint64_t>(std::tera::num),
    static_cast<uint64_t>(std::peta::num)
};

void MERGE::Merge::Run()
{
    // Find the minimum merging unit.
    m_MinTimeUnit = FindMinUnit();

    // If the output time unit is not forced use the minimum value.
    if (m_TimeUnit.empty())
    {
        // The minimum time unit used in sources.
        m_TimeUnit = m_MinTimeUnit;
    }

    // Create the output signal database and set its base time unit.
    m_pMerged = std::make_unique<SIGNAL::SignalDb>(m_TimeUnit);

    // Find the longest leading time for among all sources.
    m_MaxLeadingTime = FindMaxLeadingTime();

    // Merge Sources.
    for (const SignalSource *source : m_Sources)
    {
        // Get the source's time unit.
        const std::string sourceTimeUnit = source->GetTimeUnit();

        // Source sync time in the target unit.
        const uint64_t transformedSourceSync =
            TransformTimestamp(source->GetSyncPoint(), m_MinTimeUnit, sourceTimeUnit);

        // Merge signals here.
        for (auto current_signal : source->Get()->GetSignals())
        {
            SIGNAL::Signal *signal = current_signal->Clone();

            // Set the signal's new timestamp.
            signal->SetTimestamp(CalculateNewTime(TransformTimestamp(signal->GetTimestamp(),
                                                                     m_MinTimeUnit,
                                                                     sourceTimeUnit),
                                                  transformedSourceSync));

            // Update its name.
            signal->SetName(source->GetPrefix() + signal->GetName());

            // Add to the output signals database.
            m_pMerged->Add(signal);
        }
    }
}

std::string MERGE::Merge::FindMinUnit()
{
    size_t maxIndex = 0;

    for (const SignalSource *const source : m_Sources)
    {
        const size_t index = UTILS::GetTimeUnitIndex(source->GetTimeUnit());
        maxIndex = std::max(index, maxIndex);
    }

    return SIGNAL::Signal::TIME_UNITS[maxIndex];
}

uint64_t MERGE::Merge::FindMaxLeadingTime()
{
    uint64_t maxLeadingTime = 0;

    for (const SignalSource *const source : m_Sources)
    {
        uint64_t leadingTime = TransformTimestamp(source->GetLeadingTime(),
                                                  m_MinTimeUnit,
                                                  source->GetTimeUnit());
        maxLeadingTime = std::max(leadingTime, maxLeadingTime);
    }

    return maxLeadingTime;
}

uint64_t MERGE::Merge::TransformTimestamp(uint64_t time,
                                          const std::string &targetTimeUnit,
                                          const std::string &sourceTimeUnit)
{
    uint64_t newTime = time;
    uint32_t nominator = 0;
    uint32_t denominator = 0;

    const uint32_t targetPower = UTILS::GetTimeUnitIndex(targetTimeUnit);
    const uint32_t sourcePower = UTILS::GetTimeUnitIndex(sourceTimeUnit);

    if (targetPower > sourcePower)
    {
        nominator = (targetPower - sourcePower);
    }
    else if (targetPower < sourcePower)
    {
        denominator = (sourcePower - targetPower);
        /// @todo Range checking must be done.
        newTime = time + (TEN_POWER[denominator] / 2);
    }

    const double unitsRatio =
        static_cast<double>(TEN_POWER[nominator]) / TEN_POWER[denominator];

    /// @todo Range checking must be done.
    return static_cast<uint64_t>(newTime * unitsRatio);
}

uint64_t MERGE::Merge::CalculateNewTime(uint64_t time,
                                        uint64_t syncPoint)
{
    /// @todo Detect uint64_t overflow.
    return (TransformTimestamp(time + m_MaxLeadingTime - syncPoint,
                               m_TimeUnit,
                               m_MinTimeUnit));
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm/copy.hpp>
#include "keys.hh"
#include "schema.hh"
#include "schema_builder.hh"
#include "types.hh"

#include "idl/keys.dist.hh"
#include "serializer_impl.hh"
#include "idl/keys.dist.impl.hh"

BOOST_AUTO_TEST_CASE(test_key_is_prefixed_by) {
    schema s({}, "", "", {{"c1", bytes_type}}, {{"c2", bytes_type}, {"c3", bytes_type}, {"c4", bytes_type}}, {}, {}, utf8_type);

    auto key = clustering_key::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")});

    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a")})));
    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("b")})));
    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")})));

    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes()})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("b"), bytes("c")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("c"), bytes("b")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("abc")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("ab")})));
}

BOOST_AUTO_TEST_CASE(test_key_component_iterator) {
    schema s({}, "", "",
        {
            {"c1", bytes_type}
        }, {
            {"c2", bytes_type}, {"c3", bytes_type}, {"c4", bytes_type}
        },
        {}, {}, utf8_type);

    auto key = clustering_key::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")});

    auto i = key.begin(s);
    auto end = key.end(s);

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("a")));
    ++i;

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("b")));
    ++i;

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("c")));
    ++i;

    BOOST_REQUIRE(i == end);
}

BOOST_AUTO_TEST_CASE(test_legacy_ordering_for_non_composite_key) {
    schema s({}, "", "", {{"c1", bytes_type}}, {}, {}, {}, utf8_type);

    auto to_key = [&s] (sstring value) {
        return partition_key::from_single_value(s, to_bytes(value));
    };

    auto cmp = [&s] (const partition_key& k1, const partition_key& k2) {
        return k1.legacy_tri_compare(s, k2);
    };

    BOOST_REQUIRE(cmp(to_key("A"), to_key("B"))  < 0);
    BOOST_REQUIRE(cmp(to_key("AA"), to_key("B")) < 0);
    BOOST_REQUIRE(cmp(to_key("B"), to_key("AB")) > 0);
    BOOST_REQUIRE(cmp(to_key("B"), to_key("A"))  > 0);
    BOOST_REQUIRE(cmp(to_key("A"), to_key("A")) == 0);
}

BOOST_AUTO_TEST_CASE(test_legacy_ordering_for_composite_keys) {
    schema s({}, "", "", {{"c1", bytes_type}, {"c2", bytes_type}}, {}, {}, {}, utf8_type);

    auto to_key = [&s] (sstring v1, sstring v2) {
        return partition_key::from_exploded(s, std::vector<bytes>{to_bytes(v1), to_bytes(v2)});
    };

    auto cmp = [&s] (const partition_key& k1, const partition_key& k2) {
        return k1.legacy_tri_compare(s, k2);
    };

    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("A", "B")) == 0);
    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("A", "C")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("B", "B")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", "C"), to_key("B", "B")) < 0);
    BOOST_REQUIRE(cmp(to_key("B", "A"), to_key("A", "A")) > 0);

    BOOST_REQUIRE(cmp(to_key("AA", "B"), to_key("B", "B")) > 0);
    BOOST_REQUIRE(cmp(to_key("A", "AA"), to_key("A", "A")) > 0);

    BOOST_REQUIRE(cmp(to_key("", "A"), to_key("A", "A")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", ""), to_key("A", "A")) < 0);
}

BOOST_AUTO_TEST_CASE(test_conversions_between_view_and_wrapper) {
    schema s({}, "", "", {{"c1", bytes_type}}, {}, {}, {}, utf8_type);

    auto key = partition_key::from_deeply_exploded(s, {data_value(bytes("value"))});
    partition_key_view key_view = key;

    BOOST_REQUIRE(key_view.equal(s, key));
    BOOST_REQUIRE(key.equal(s, key_view));

    partition_key key2 = key_view;

    BOOST_REQUIRE(key2.equal(s, key));
    BOOST_REQUIRE(key.equal(s, key2));

    BOOST_REQUIRE(*key.begin(s) == bytes("value"));
}

template<typename T>
inline
T reserialize(const T& v) {
    auto buf = ser::serialize_to_buffer<bytes>(v);
    auto in = ser::as_input_stream(buf);
    return ser::deserialize(in, boost::type<T>());
}

BOOST_AUTO_TEST_CASE(test_serialization) {
    auto s = schema_builder("ks", "cf")
            .with_column("pk", bytes_type, column_kind::partition_key)
            .with_column("v", bytes_type)
            .build();

    auto pk_value = bytes("value");
    partition_key key(std::vector<bytes>({pk_value}));

    BOOST_REQUIRE(key.equal(*s, reserialize(key)));
}
<commit_msg>keys_test: add a test for nodetool_style string<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>
#include <boost/range/algorithm/copy.hpp>
#include "keys.hh"
#include "schema.hh"
#include "schema_builder.hh"
#include "types.hh"

#include "idl/keys.dist.hh"
#include "serializer_impl.hh"
#include "idl/keys.dist.impl.hh"

BOOST_AUTO_TEST_CASE(test_key_is_prefixed_by) {
    schema s({}, "", "", {{"c1", bytes_type}}, {{"c2", bytes_type}, {"c3", bytes_type}, {"c4", bytes_type}}, {}, {}, utf8_type);

    auto key = clustering_key::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")});

    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a")})));
    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("b")})));
    BOOST_REQUIRE(key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")})));

    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes()})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("b"), bytes("c")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("a"), bytes("c"), bytes("b")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("abc")})));
    BOOST_REQUIRE(!key.is_prefixed_by(s, clustering_key_prefix::from_exploded(s, {bytes("ab")})));
}

BOOST_AUTO_TEST_CASE(test_key_component_iterator) {
    schema s({}, "", "",
        {
            {"c1", bytes_type}
        }, {
            {"c2", bytes_type}, {"c3", bytes_type}, {"c4", bytes_type}
        },
        {}, {}, utf8_type);

    auto key = clustering_key::from_exploded(s, {bytes("a"), bytes("b"), bytes("c")});

    auto i = key.begin(s);
    auto end = key.end(s);

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("a")));
    ++i;

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("b")));
    ++i;

    BOOST_REQUIRE(i != end);
    BOOST_REQUIRE(*i == bytes_view(bytes("c")));
    ++i;

    BOOST_REQUIRE(i == end);
}

BOOST_AUTO_TEST_CASE(test_legacy_ordering_for_non_composite_key) {
    schema s({}, "", "", {{"c1", bytes_type}}, {}, {}, {}, utf8_type);

    auto to_key = [&s] (sstring value) {
        return partition_key::from_single_value(s, to_bytes(value));
    };

    auto cmp = [&s] (const partition_key& k1, const partition_key& k2) {
        return k1.legacy_tri_compare(s, k2);
    };

    BOOST_REQUIRE(cmp(to_key("A"), to_key("B"))  < 0);
    BOOST_REQUIRE(cmp(to_key("AA"), to_key("B")) < 0);
    BOOST_REQUIRE(cmp(to_key("B"), to_key("AB")) > 0);
    BOOST_REQUIRE(cmp(to_key("B"), to_key("A"))  > 0);
    BOOST_REQUIRE(cmp(to_key("A"), to_key("A")) == 0);
}

BOOST_AUTO_TEST_CASE(test_legacy_ordering_for_composite_keys) {
    schema s({}, "", "", {{"c1", bytes_type}, {"c2", bytes_type}}, {}, {}, {}, utf8_type);

    auto to_key = [&s] (sstring v1, sstring v2) {
        return partition_key::from_exploded(s, std::vector<bytes>{to_bytes(v1), to_bytes(v2)});
    };

    auto cmp = [&s] (const partition_key& k1, const partition_key& k2) {
        return k1.legacy_tri_compare(s, k2);
    };

    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("A", "B")) == 0);
    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("A", "C")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", "B"), to_key("B", "B")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", "C"), to_key("B", "B")) < 0);
    BOOST_REQUIRE(cmp(to_key("B", "A"), to_key("A", "A")) > 0);

    BOOST_REQUIRE(cmp(to_key("AA", "B"), to_key("B", "B")) > 0);
    BOOST_REQUIRE(cmp(to_key("A", "AA"), to_key("A", "A")) > 0);

    BOOST_REQUIRE(cmp(to_key("", "A"), to_key("A", "A")) < 0);
    BOOST_REQUIRE(cmp(to_key("A", ""), to_key("A", "A")) < 0);
}

BOOST_AUTO_TEST_CASE(test_conversions_between_view_and_wrapper) {
    schema s({}, "", "", {{"c1", bytes_type}}, {}, {}, {}, utf8_type);

    auto key = partition_key::from_deeply_exploded(s, {data_value(bytes("value"))});
    partition_key_view key_view = key;

    BOOST_REQUIRE(key_view.equal(s, key));
    BOOST_REQUIRE(key.equal(s, key_view));

    partition_key key2 = key_view;

    BOOST_REQUIRE(key2.equal(s, key));
    BOOST_REQUIRE(key.equal(s, key2));

    BOOST_REQUIRE(*key.begin(s) == bytes("value"));
}

template<typename T>
inline
T reserialize(const T& v) {
    auto buf = ser::serialize_to_buffer<bytes>(v);
    auto in = ser::as_input_stream(buf);
    return ser::deserialize(in, boost::type<T>());
}

BOOST_AUTO_TEST_CASE(test_serialization) {
    auto s = schema_builder("ks", "cf")
            .with_column("pk", bytes_type, column_kind::partition_key)
            .with_column("v", bytes_type)
            .build();

    auto pk_value = bytes("value");
    partition_key key(std::vector<bytes>({pk_value}));

    BOOST_REQUIRE(key.equal(*s, reserialize(key)));
}

BOOST_AUTO_TEST_CASE(test_from_nodetool_style_string) {
    auto s1 = make_lw_shared<schema>(
    schema({}, "", "",
        {
            {"c1", utf8_type}
        }, {
            {"c2", bytes_type}, {"c3", bytes_type}, {"c4", bytes_type}
        },
        {}, {}, utf8_type));

    auto pk_value = bytes("value");
    partition_key key1(std::vector<bytes>({pk_value}));

    auto key2 = partition_key::from_nodetool_style_string(s1, "value");
    BOOST_REQUIRE(key1.equal(*s1, key2));

    auto s2 = make_lw_shared<schema>(
    schema({}, "", "",
        {
            {"c1", utf8_type}, {"c2", utf8_type}
        }, {
            {"c3", bytes_type}, {"c4", bytes_type}
        },
        {}, {}, utf8_type));

    auto pk_value1 = bytes("value1");
    auto pk_value2 = bytes("value2");
    partition_key key3(std::vector<bytes>({pk_value1, pk_value2}));

    auto key4 = partition_key::from_nodetool_style_string(s2, "value1:value2");
    BOOST_REQUIRE(key3.equal(*s1, key4));
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 tildearrow
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "font.h"

int font::load(const char* filename, int size) {
  f=TTF_OpenFont(filename, size);
  if (f==NULL) {return 0;} else {return 1;}
  curfsize=64;
  formatcache=new char[curfsize];
}

void font::setrenderer(SDL_Renderer* r) {
  renderer=r;
}

void font::drawf(int x, int y, SDL_Color col, int align, int valign, const char* format, ...) {
  int chars;
  va_list va;
  va_start(va,format);
  while (1) {
    chars=vsnprintf(formatcache,curfsize,format,va);
    if (chars>curfsize) {
      delete[] formatcache;
      curfsize*=2;
      formatcache=new char[curfsize];
    } else {
      break;
    }
  }
  va_end(va);
  string tempstring;
  tempstring=formatcache;
  draw(x,y,col,align,valign,1,tempstring);
}

void font::draw(int x, int y, SDL_Color col, int align, int valign, bool nocache, string text) {
  temps=TTF_RenderUTF8_Blended(f, text.c_str(), col);
  if (temps==NULL) {printf("aaaa\n");}
  tempt=SDL_CreateTextureFromSurface(renderer, temps);
  tempr.x=x-((align==1)?(temps->clip_rect.w/2):(0));
  tempr.y=y-((valign==1)?(temps->clip_rect.h/2):(0));
  tempr.w=temps->clip_rect.w;
  tempr.h=temps->clip_rect.h;
  SDL_RenderCopy(renderer, tempt, &temps->clip_rect, &tempr);
  SDL_DestroyTexture(tempt);
  SDL_FreeSurface(temps);
}
<commit_msg>fixing drawf, thanks to vasprintf<commit_after>/*
 * Copyright (c) 2016 tildearrow
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "font.h"

int font::load(const char* filename, int size) {
  f=TTF_OpenFont(filename, size);
  if (f==NULL) {return 0;} else {return 1;}
  curfsize=64;
  formatcache=new char[curfsize];
}

void font::setrenderer(SDL_Renderer* r) {
  renderer=r;
}

void font::drawf(int x, int y, SDL_Color col, int align, int valign, const char* format, ...) {
  int chars;
  chars=0;
  va_list va;
  va_start(va,format);
  char* fs;
  vasprintf(&fs,format,va);
  va_end(va);
  string tempstring;
  tempstring=fs;
  delete[] fs;
  draw(x,y,col,align,valign,1,tempstring);
}

void font::draw(int x, int y, SDL_Color col, int align, int valign, bool nocache, string text) {
  temps=TTF_RenderUTF8_Blended(f, text.c_str(), col);
  if (temps==NULL) {printf("aaaa\n");}
  tempt=SDL_CreateTextureFromSurface(renderer, temps);
  tempr.x=x-((align==1)?(temps->clip_rect.w/2):(0));
  tempr.y=y-((valign==1)?(temps->clip_rect.h/2):(0));
  tempr.w=temps->clip_rect.w;
  tempr.h=temps->clip_rect.h;
  SDL_RenderCopy(renderer, tempt, &temps->clip_rect, &tempr);
  SDL_DestroyTexture(tempt);
  SDL_FreeSurface(temps);
}
<|endoftext|>


<commit_before><commit_msg>Bugfix: add missing `#include` line.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary `#include` line.<commit_after><|endoftext|>


<commit_before>#ifndef _internal_hpp_INCLUDED
#define _internal_hpp_INCLUDED

#include <cassert>
#include <climits>
#include <cstdio>
#include <vector>

/*------------------------------------------------------------------------*/

using namespace std;

/*------------------------------------------------------------------------*/

#include "avg.hpp"
#include "arena.hpp"
#include "ema.hpp"
#include "format.hpp"
#include "level.hpp"
#include "logging.hpp"
#include "options.hpp"
#include "profile.hpp"
#include "queue.hpp"
#include "stats.hpp"
#include "timer.hpp"
#include "watch.hpp"
#include "flags.hpp"

/*------------------------------------------------------------------------*/

namespace CaDiCaL {

class Proof;
class File;

class Internal {

  friend class Solver;

  friend class Arena;
  friend struct Logger;
  friend struct Message;
  friend class Parser;
  friend class Proof;
  friend struct Queue;
  friend struct Stats;

  friend struct trail_greater;
  friend struct trail_smaller;
  friend struct bump_earlier;

  /*----------------------------------------------------------------------*/

  // The actual state of the solver is in this section.

  int max_var;                  // maximum variable index
  size_t vsize;                 // actually allocated variable data size
  Var * vtab;                   // variable table
  signed char * vals;           // current partial assignment
  signed char * phases;         // saved last assignment
  Watches * wtab;               // table of watches for all literals
  Flags * ftab;                // seen, poison, minimized flags
  Queue queue;                  // variable move to front decision queue
  bool unsat;                   // empty clause found or learned
  int level;                    // decision level (levels.size () - 1)
  vector<Level> control;        // 'level + 1 == levels.size ()'
  vector<int> trail;            // assigned literals
  size_t propagated;            // next position on trail to propagate
  vector<int> clause;           // temporary clause in parsing & learning
  vector<Clause*> clauses;      // ordered collection of all clauses
  bool iterating;               // report learned unit (iteration)
  vector<int> bump;             // seen & bumped literals in 'analyze'
  vector<int> levels;           // decision levels of 1st UIP clause
  vector<int> minimized;        // marked removable or poison in 'minmize'
  vector<Clause*> resolved;     // large clauses in 'analyze'
  Clause * conflict;            // set in 'propagation', reset in 'analyze'
  bool clashing_unit;           // set in 'parse_dimacs'
  EMA fast_glue_avg;            // fast exponential moving average
  EMA slow_glue_avg;            // slow exponential moving average
  AVG jump_avg;                 // average back jump level
  long reduce_limit;            // conflict limit for next 'reduce'
  long restart_limit;           // conflict limit for next 'restart'
  long recently_resolved;       // to keep recently resolved clauses
  int fixed_limit;              // remember last number of units
  long reduce_inc;              // reduce interval increment
  long reduce_inc_inc;          // reduce interval increment increment
  Proof * proof;                // trace clausal proof if non zero
  Options opts;                 // run-time options
  Stats stats;                  // statistics
  signed char * solution;       // for debugging (like 'vals' and 'phases')
  vector<int> original;         // original CNF for debugging
  vector<Timer> timers;         // active timers for profiling functions
  Profiles profiles;            // global profiled time for functions
  Arena arena;                  // memory arena for moving garbage collector
  Format error;                 // last (persistent) error message
  Internal * internal;          // proxy to 'this' in macros (redundant)

  /*----------------------------------------------------------------------*/

  // Internal delegates and helpers for corresponding functions in 'Solver'.
  //
  void resize (int new_max_var);
  void add_original_lit (int lit);

  // Enlarge tables.
  //
  void enlarge_vtab (int new_vsize);
  void enlarge_vals (int new_vsize);
  void enlarge (int new_max_var);

  // Functions for monitoring resources.
  //
  size_t vector_bytes ();
  void inc_bytes (size_t);
  void dec_bytes (size_t);

  double seconds ();
  size_t max_bytes ();
  size_t current_bytes ();

  int active_variables () const { return max_var - stats.fixed; }

  // Regularly reports what is going on in 'report.cpp'.
  //
  void report (char type, bool verbose = false);

  // Unsigned literals (abs) with checks.
  //
  int vidx (int lit) const {
    int idx;
    assert (lit), assert (lit != INT_MIN);
    idx = abs (lit);
    assert (idx <= max_var);
    return idx;
  }

  // Get the index of variable (with checking).
  //
  int var2idx (Var * v) const {
    assert (v), assert (vtab < v), assert (v <= vtab + max_var);
    return v - vtab;
  }

  // Unsigned version with LSB denoting sign.  This is used in indexing arrays
  // by literals.  The idea is to keep the elements in such an array for both
  // the positive and negated version of a literal close together.
  //
  unsigned vlit (int lit) { return (lit < 0) + 2u * (unsigned) vidx (lit); }

  // Helper function to access variables and watches to avoid indexing bugs.
  //
  Var & var (int lit)         { return vtab [vidx (lit)]; }
  Watches & watches (int lit) { return wtab [vlit (lit)]; }

  // Watch literal 'lit' in clause with blocking literal 'blit'.
  // Inlined here, since it occurs in the tight inner loop of 'propagate'.
  //
  inline void watch_literal (int lit, int blit, Clause * c, int size) {
    Watches & ws = watches (lit);
    ws.push_back (Watch (blit, c, size));
    LOG (c, "watch %d blit %d in", lit, blit);
  }

  // Managing clauses in 'clause.cpp'.  Without explicit 'Clause' argument
  // these functions work on the global temporary 'clause'.
  //
  void watch_clause (Clause *);
  size_t bytes_clause (int size);
  Clause * new_clause (bool red, int glue = 0);
  void deallocate_clause (Clause *);
  void delete_clause (Clause *);
  bool tautological_clause ();
  void add_new_original_clause ();
  Clause * new_learned_clause (int glue);

  // Forward reasoning through propagation in 'propagate.cpp'.
  //
  void assign (int lit, Clause * reason = 0);
  bool propagate ();

  // Undo and restart in 'backtrack.cpp'.
  //
  void unassign (int lit);
  void backtrack (int target_level = 0);

  // Learning from conflicts in 'analyze.cc'.
  //
  void learn_empty_clause ();
  void learn_unit_clause (int lit);
  bool minimize_literal (int lit, int depth = 0);
  void minimize_clause ();
  void bump_variable (Var * v);
  void bump_variables ();
  void bump_resolved_clauses ();
  void resolve_clause (Clause *);
  void clear_seen ();
  void clear_levels ();
  bool analyze_literal (int);
  void analyze ();
  void iterate ();       // for reporting learned unit clause

  // Restarting policy in 'restart.cc'.
  //
  bool restarting ();
  int reuse_trail ();
  void restart ();

  // Reducing means garbage collecting useless clauses in 'reduce.cpp'.
  //
  bool reducing ();
  void protect_reasons ();
  void unprotect_reasons ();
  int clause_contains_fixed_literal (Clause *);
  void flush_falsified_literals (Clause *);
  void mark_satisfied_clauses_as_garbage ();
  void mark_useless_redundant_clauses_as_garbage ();
  void move_clause (Clause *);
  void move_non_garbage_clauses ();
  void delete_garbage_clauses ();
  void flush_watches ();
  void setup_watches ();
  void garbage_collection ();
  void reduce ();

  // Part on picking the next decision in 'decide.cpp'.
  //
  bool satisfied () const { return trail.size () == (size_t) max_var; }
  int next_decision_variable ();
  void decide ();

  // Main search functions in 'internal.cpp'.
  //
  int search ();                // CDCL loop
  void init_solving ();
  int solve ();

  // Built in profiling in 'profile.cpp'.
  //
  void start_profiling (Profile * p);
  void stop_profiling (Profile * p);
  void update_all_timers (double now);
  void print_profile (double now);

  // Checking solutions (see 'solution.cpp').
  //
  int sol (int lit) const;
  void check_clause ();

  void check (int (Internal::*assignment) (int) const);

  Internal ();
  ~Internal ();

  // Get the value of a literal: -1 = false, 0 = unassigned, 1 = true.
  //
  int val (int lit) const {
    assert (lit), assert (abs (lit) <= max_var);
    return vals[lit];
  }

  // Get and manipulate variable flags.
  //
  Flags & flags (int lit) { return ftab[vidx (lit)]; }
  const Flags & flags (int lit) const { return ftab[vidx (lit)]; }
  bool seen (int lit) const { return flags (lit).seen (); }

  // As 'val' but restricted to the root-level value of a literal.
  //
  int fixed (int lit) {
    int idx = vidx (lit), res = vals[idx];
    if (res && vtab[idx].level) res = 0;
    if (lit < 0) res = -res;
    return res;
  }

  // Parsing functions (handed over to 'parse.cpp').
  //
  const char * parse_dimacs (FILE *);
  const char * parse_dimacs (const char *);
  const char * parse_solution (const char *);

  // Enable and disable proof logging.
  void close_proof ();
  void new_proof (File *, bool owned = false);
};

};

#endif
<commit_msg>renamed tags to flags<commit_after>#ifndef _internal_hpp_INCLUDED
#define _internal_hpp_INCLUDED

#include <cassert>
#include <climits>
#include <cstdio>
#include <vector>

/*------------------------------------------------------------------------*/

using namespace std;

/*------------------------------------------------------------------------*/

#include "avg.hpp"
#include "arena.hpp"
#include "ema.hpp"
#include "format.hpp"
#include "level.hpp"
#include "logging.hpp"
#include "options.hpp"
#include "profile.hpp"
#include "queue.hpp"
#include "stats.hpp"
#include "timer.hpp"
#include "watch.hpp"
#include "flags.hpp"

/*------------------------------------------------------------------------*/

namespace CaDiCaL {

class Proof;
class File;

class Internal {

  friend class Solver;

  friend class Arena;
  friend struct Logger;
  friend struct Message;
  friend class Parser;
  friend class Proof;
  friend struct Queue;
  friend struct Stats;

  friend struct trail_greater;
  friend struct trail_smaller;
  friend struct bump_earlier;

  /*----------------------------------------------------------------------*/

  // The actual state of the solver is in this section.

  int max_var;                  // maximum variable index
  size_t vsize;                 // actually allocated variable data size
  Var * vtab;                   // variable table
  signed char * vals;           // current partial assignment
  signed char * phases;         // saved last assignment
  Watches * wtab;               // table of watches for all literals
  Flags * ftab;                 // seen, poison, minimized flags table
  Queue queue;                  // variable move to front decision queue
  bool unsat;                   // empty clause found or learned
  int level;                    // decision level (levels.size () - 1)
  vector<Level> control;        // 'level + 1 == levels.size ()'
  vector<int> trail;            // assigned literals
  size_t propagated;            // next position on trail to propagate
  vector<int> clause;           // temporary clause in parsing & learning
  vector<Clause*> clauses;      // ordered collection of all clauses
  bool iterating;               // report learned unit (iteration)
  vector<int> bump;             // seen & bumped literals in 'analyze'
  vector<int> levels;           // decision levels of 1st UIP clause
  vector<int> minimized;        // marked removable or poison in 'minmize'
  vector<Clause*> resolved;     // large clauses in 'analyze'
  Clause * conflict;            // set in 'propagation', reset in 'analyze'
  bool clashing_unit;           // set in 'parse_dimacs'
  EMA fast_glue_avg;            // fast exponential moving average
  EMA slow_glue_avg;            // slow exponential moving average
  AVG jump_avg;                 // average back jump level
  long reduce_limit;            // conflict limit for next 'reduce'
  long restart_limit;           // conflict limit for next 'restart'
  long recently_resolved;       // to keep recently resolved clauses
  int fixed_limit;              // remember last number of units
  long reduce_inc;              // reduce interval increment
  long reduce_inc_inc;          // reduce interval increment increment
  Proof * proof;                // trace clausal proof if non zero
  Options opts;                 // run-time options
  Stats stats;                  // statistics
  signed char * solution;       // for debugging (like 'vals' and 'phases')
  vector<int> original;         // original CNF for debugging
  vector<Timer> timers;         // active timers for profiling functions
  Profiles profiles;            // global profiled time for functions
  Arena arena;                  // memory arena for moving garbage collector
  Format error;                 // last (persistent) error message
  Internal * internal;          // proxy to 'this' in macros (redundant)

  /*----------------------------------------------------------------------*/

  // Internal delegates and helpers for corresponding functions in 'Solver'.
  //
  void resize (int new_max_var);
  void add_original_lit (int lit);

  // Enlarge tables.
  //
  void enlarge_vtab (int new_vsize);
  void enlarge_vals (int new_vsize);
  void enlarge (int new_max_var);

  // Functions for monitoring resources.
  //
  size_t vector_bytes ();
  void inc_bytes (size_t);
  void dec_bytes (size_t);

  double seconds ();
  size_t max_bytes ();
  size_t current_bytes ();

  int active_variables () const { return max_var - stats.fixed; }

  // Regularly reports what is going on in 'report.cpp'.
  //
  void report (char type, bool verbose = false);

  // Unsigned literals (abs) with checks.
  //
  int vidx (int lit) const {
    int idx;
    assert (lit), assert (lit != INT_MIN);
    idx = abs (lit);
    assert (idx <= max_var);
    return idx;
  }

  // Get the index of variable (with checking).
  //
  int var2idx (Var * v) const {
    assert (v), assert (vtab < v), assert (v <= vtab + max_var);
    return v - vtab;
  }

  // Unsigned version with LSB denoting sign.  This is used in indexing arrays
  // by literals.  The idea is to keep the elements in such an array for both
  // the positive and negated version of a literal close together.
  //
  unsigned vlit (int lit) { return (lit < 0) + 2u * (unsigned) vidx (lit); }

  // Helper function to access variables and watches to avoid indexing bugs.
  //
  Var & var (int lit)         { return vtab [vidx (lit)]; }
  Watches & watches (int lit) { return wtab [vlit (lit)]; }

  // Watch literal 'lit' in clause with blocking literal 'blit'.
  // Inlined here, since it occurs in the tight inner loop of 'propagate'.
  //
  inline void watch_literal (int lit, int blit, Clause * c, int size) {
    Watches & ws = watches (lit);
    ws.push_back (Watch (blit, c, size));
    LOG (c, "watch %d blit %d in", lit, blit);
  }

  // Managing clauses in 'clause.cpp'.  Without explicit 'Clause' argument
  // these functions work on the global temporary 'clause'.
  //
  void watch_clause (Clause *);
  size_t bytes_clause (int size);
  Clause * new_clause (bool red, int glue = 0);
  void deallocate_clause (Clause *);
  void delete_clause (Clause *);
  bool tautological_clause ();
  void add_new_original_clause ();
  Clause * new_learned_clause (int glue);

  // Forward reasoning through propagation in 'propagate.cpp'.
  //
  void assign (int lit, Clause * reason = 0);
  bool propagate ();

  // Undo and restart in 'backtrack.cpp'.
  //
  void unassign (int lit);
  void backtrack (int target_level = 0);

  // Learning from conflicts in 'analyze.cc'.
  //
  void learn_empty_clause ();
  void learn_unit_clause (int lit);
  bool minimize_literal (int lit, int depth = 0);
  void minimize_clause ();
  void bump_variable (Var * v);
  void bump_variables ();
  void bump_resolved_clauses ();
  void resolve_clause (Clause *);
  void clear_seen ();
  void clear_levels ();
  bool analyze_literal (int);
  void analyze ();
  void iterate ();       // for reporting learned unit clause

  // Restarting policy in 'restart.cc'.
  //
  bool restarting ();
  int reuse_trail ();
  void restart ();

  // Reducing means garbage collecting useless clauses in 'reduce.cpp'.
  //
  bool reducing ();
  void protect_reasons ();
  void unprotect_reasons ();
  int clause_contains_fixed_literal (Clause *);
  void flush_falsified_literals (Clause *);
  void mark_satisfied_clauses_as_garbage ();
  void mark_useless_redundant_clauses_as_garbage ();
  void move_clause (Clause *);
  void move_non_garbage_clauses ();
  void delete_garbage_clauses ();
  void flush_watches ();
  void setup_watches ();
  void garbage_collection ();
  void reduce ();

  // Part on picking the next decision in 'decide.cpp'.
  //
  bool satisfied () const { return trail.size () == (size_t) max_var; }
  int next_decision_variable ();
  void decide ();

  // Main search functions in 'internal.cpp'.
  //
  int search ();                // CDCL loop
  void init_solving ();
  int solve ();

  // Built in profiling in 'profile.cpp'.
  //
  void start_profiling (Profile * p);
  void stop_profiling (Profile * p);
  void update_all_timers (double now);
  void print_profile (double now);

  // Checking solutions (see 'solution.cpp').
  //
  int sol (int lit) const;
  void check_clause ();

  void check (int (Internal::*assignment) (int) const);

  Internal ();
  ~Internal ();

  // Get the value of a literal: -1 = false, 0 = unassigned, 1 = true.
  //
  int val (int lit) const {
    assert (lit), assert (abs (lit) <= max_var);
    return vals[lit];
  }

  // Get and manipulate variable flags.
  //
  Flags & flags (int lit) { return ftab[vidx (lit)]; }
  const Flags & flags (int lit) const { return ftab[vidx (lit)]; }
  bool seen (int lit) const { return flags (lit).seen (); }

  // As 'val' but restricted to the root-level value of a literal.
  //
  int fixed (int lit) {
    int idx = vidx (lit), res = vals[idx];
    if (res && vtab[idx].level) res = 0;
    if (lit < 0) res = -res;
    return res;
  }

  // Parsing functions (handed over to 'parse.cpp').
  //
  const char * parse_dimacs (FILE *);
  const char * parse_dimacs (const char *);
  const char * parse_solution (const char *);

  // Enable and disable proof logging.
  void close_proof ();
  void new_proof (File *, bool owned = false);
};

};

#endif
<|endoftext|>


<commit_before><commit_msg>TEXT2BMP.C updated<commit_after><|endoftext|>