<commit_before>// Color.cc for Fluxbox window manager
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@users.sourceforge.net)
//
// 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.

// $Id: Color.cc,v 1.1 2002/09/14 12:47:50 fluxgen Exp $

#include "Color.hh"

namespace {
unsigned char maxValue(unsigned short colval) {
	if (colval == 65535)
		return 0xFF;

	return static_cast<unsigned char>(colval/0xFF);
}

};

namespace FbTk {
Color::Color():
m_allocated(false) {

}

Color::Color(unsigned char red, unsigned char green, unsigned char blue, int screen):
m_red(red),	m_green(green), m_blue(blue),
m_pixel(0), m_allocated(false) {

	Display *disp = BaseDisplay::getXDisplay();
	XColor color;
	// fill xcolor structure
	color.red = red;
	color.blue = blue;
	color.green = green;

	if (!XAllocColor(disp, DefaultColormap(disp, screen), &color)) {
		cerr<<"FbTk::Color: Allocation error."<<endl;
	} else {
		setRGB(maxValue(color.red),
			maxValue(color.green),
			maxValue(color.blue));
		setPixel(color.pixel);
		setAllocated(true);
	}
}

Color::Color(const char *color_string, int screen):
m_allocated(false) {
	setFromString(color_string, screen);
}

bool Color::setFromString(const char *color_string, int screen) {

	if (color_string == 0) {
		free();
		return false;
	}

	Display *disp = BaseDisplay::instance()->getXDisplay();
	Colormap colm = DefaultColormap(disp, screen);

	XColor color;

	if (! XParseColor(disp, colm, color_string, &color))
		cerr<<"FbTk::Color: Parse color error: \""<<color_string<<"\""<<endl;
	else if (! XAllocColor(disp, colm, &color))
		cerr<<"FbTk::Color: Allocation error: \""<<color_string<<"\""<<endl;

	setPixel(color.pixel);
	setRGB(maxValue(color.red),
		maxValue(color.green),
		maxValue(color.blue));
	setAllocated(true);

	return true;
}

void Color::free() {
	if (isAllocated()) {
		unsigned long pixel = col.pixel();
		XFreeColors(disp, colm, &pixel, 1, 0);
		setPixel(0);
		setRGB(0, 0, 0);
		setAllocated(false);
	}
}

};
<commit_msg>fixed copy<commit_after>// Color.cc for Fluxbox window manager
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@users.sourceforge.net)
//
// 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.

// $Id: Color.cc,v 1.2 2002/09/14 13:49:51 fluxgen Exp $

#include "Color.hh"

#include "BaseDisplay.hh"

#include <iostream>
using namespace std;

namespace {
unsigned char maxValue(unsigned short colval) {
	if (colval == 65535)
		return 0xFF;

	return static_cast<unsigned char>(colval/0xFF);
}

};

namespace FbTk {
Color::Color():
m_allocated(false),
m_screen(0) {

}

Color::Color(const Color &col_copy) {
	copy(col_copy);
}

Color::Color(unsigned char red, unsigned char green, unsigned char blue, int screen):
m_red(red),	m_green(green), m_blue(blue),
m_pixel(0), m_allocated(false),
m_screen(screen) {
	allocate(red, green, blue, screen);
}

Color::Color(const char *color_string, int screen):
m_allocated(false) {
	setFromString(color_string, screen);
}

Color::~Color() {
	free();
}

bool Color::setFromString(const char *color_string, int screen) {

	if (color_string == 0) {
		free();
		return false;
	}

	Display *disp = BaseDisplay::instance()->getXDisplay();
	Colormap colm = DefaultColormap(disp, screen);

	XColor color;

	if (! XParseColor(disp, colm, color_string, &color))
		cerr<<"FbTk::Color: Parse color error: \""<<color_string<<"\""<<endl;
	else if (! XAllocColor(disp, colm, &color))
		cerr<<"FbTk::Color: Allocation error: \""<<color_string<<"\""<<endl;

	setPixel(color.pixel);
	setRGB(maxValue(color.red),
		maxValue(color.green),
		maxValue(color.blue));
	setAllocated(true);
	m_screen = screen;

	return true;
}

Color &Color::Color::operator  = (const Color &col_copy) {
	copy(col_copy);
	return *this;
}

void Color::free() {
	if (isAllocated()) {
		unsigned long pixel = m_pixel;
		Display *disp = BaseDisplay::getXDisplay();
		XFreeColors(disp, DefaultColormap(disp, m_screen), &pixel, 1, 0);
		setPixel(0);
		setRGB(0, 0, 0);
		setAllocated(false);
	}
}

void Color::copy(const Color &col_copy) {
	if (!col_copy.isAllocated()) {
		free();
		return;
	}

	free();

	allocate(col_copy.red(),
		col_copy.green(),
		col_copy.blue(),
		col_copy.m_screen);

}

void Color::allocate(unsigned char red, unsigned char green, unsigned char blue, int screen) {

	Display *disp = BaseDisplay::getXDisplay();
	XColor color;
	// fill xcolor structure
	color.red = red;
	color.blue = blue;
	color.green = green;

	if (!XAllocColor(disp, DefaultColormap(disp, screen), &color)) {
		cerr<<"FbTk::Color: Allocation error."<<endl;
	} else {
		setRGB(maxValue(color.red),
			maxValue(color.green),
			maxValue(color.blue));
		setPixel(color.pixel);
		setAllocated(true);
	}
}

void Color::setRGB(unsigned char red, unsigned char green, unsigned char blue) {
	m_red = red;
	m_green = green;
	m_blue = blue;
}
};
<|endoftext|>


<commit_before>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>

#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "dg/llvm/LLVMDependenceGraph.h"
#include "dg/llvm/LLVMDependenceGraphBuilder.h"
#include "dg/llvm/LLVMSlicer.h"
#include "dg/llvm/LLVMDG2Dot.h"
#include "dg/llvm/PointerAnalysis/PointerAnalysis.h"
#include "dg/PointerAnalysis/PointerAnalysisFS.h"
#include "dg/PointerAnalysis/PointerAnalysisFI.h"
#include "dg/PointerAnalysis/PointerAnalysisFSInv.h"
#include "dg/llvm/DataDependence/DataDependence.h"

#include "TimeMeasure.h"

using namespace dg;
using llvm::errs;

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool mark_only = false;
    bool bb_only = false;
    bool threads = false;
    const char *module = nullptr;
    const char *slicing_criterion = nullptr;
    const char *dump_func_only = nullptr;
    const char *pts = "fi";
    const char *entry_func = "main";
    LLVMControlDependenceAnalysisOptions::CDAlgorithm cd_alg;

    using namespace debug;
    uint32_t opts = PRINT_CFG | PRINT_DD | PRINT_CD | PRINT_USE | PRINT_ID;

    // parse options
    for (int i = 1; i < argc; ++i) {
        if (strcmp(argv[i], "-no-control") == 0) {
            opts &= ~PRINT_CD;
        } else if (strcmp(argv[i], "-no-use") == 0) {
            opts &= ~PRINT_USE;
        } else if (strcmp(argv[i], "-pta") == 0) {
            pts = argv[++i];
        /*
        } else if (strcmp(argv[i], "-dda") == 0) {
            dda = argv[++i];
        */
        } else if (strcmp(argv[i], "-no-data") == 0) {
            opts &= ~PRINT_DD;
        } else if (strcmp(argv[i], "-no-cfg") == 0) {
            opts &= ~PRINT_CFG;
        } else if (strcmp(argv[i], "-call") == 0) {
            opts |= PRINT_CALL;
        } else if (strcmp(argv[i], "-postdom") == 0) {
            opts |= PRINT_POSTDOM;
        } else if (strcmp(argv[i], "-bb-only") == 0) {
            bb_only = true;
        } else if (strcmp(argv[i], "-cfgall") == 0) {
            opts |= PRINT_CFG;
            opts |= PRINT_REV_CFG;
        } else if (strcmp(argv[i], "-func") == 0) {
            dump_func_only = argv[++i];
        } else if (strcmp(argv[i], "-slice") == 0) {
            slicing_criterion = argv[++i];
        } else if (strcmp(argv[i], "-mark") == 0) {
            mark_only = true;
            slicing_criterion = argv[++i];
        } else if (strcmp(argv[i], "-threads") == 0) {
            threads = true;
        } else if (strcmp(argv[i], "-entry") == 0) {
            entry_func = argv[++i];
        } else if (strcmp(argv[i], "-cd-alg") == 0) {
            const char *arg = argv[++i];
            if (strcmp(arg, "standard") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::STANDARD;
            else if (strcmp(arg, "classic") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::STANDARD;
            else if (strcmp(arg, "ntscd") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::NTSCD;
            else {
                errs() << "Invalid control dependencies algorithm, try: classic, ce\n";
                abort();
            }

        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    llvmdg::LLVMDependenceGraphOptions options;

    options.CDAOptions.algorithm = cd_alg;
    options.threads = threads;
    options.PTAOptions.threads = threads;
    options.DDAOptions.threads = threads;
    options.PTAOptions.entryFunction = entry_func;
    options.DDAOptions.entryFunction = entry_func;
    if (strcmp(pts, "fs") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::fs;
    } else if (strcmp(pts, "fi") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::fi;
    } else if (strcmp(pts, "inv") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::inv;
    } else {
        llvm::errs() << "Unknown points to analysis, try: fs, fi, inv\n";
        abort();
    }

    llvmdg::LLVMDependenceGraphBuilder builder(M, options);
    auto dg = builder.build();

    std::set<LLVMNode *> callsites;
    if (slicing_criterion) {
        const char *sc[] = {
            slicing_criterion,
            "klee_assume",
            NULL
        };

        dg->getCallSites(sc, &callsites);

        llvmdg::LLVMSlicer slicer;

        if (strcmp(slicing_criterion, "ret") == 0) {
            if (mark_only)
                slicer.mark(dg->getExit());
            else
                slicer.slice(dg.get(), dg->getExit());
        } else {
            if (callsites.empty()) {
                errs() << "ERR: slicing criterion not found: "
                       << slicing_criterion << "\n";
                exit(1);
            }

            uint32_t slid = 0;
            for (LLVMNode *start : callsites)
                slid = slicer.mark(start, slid);

            if (!mark_only)
               slicer.slice(dg.get(), nullptr, slid);
        }

        if (!mark_only) {
            std::string fl(module);
            fl.append(".sliced");
            std::ofstream ofs(fl);
            llvm::raw_os_ostream output(ofs);

            SlicerStatistics& st = slicer.getStatistics();
            errs() << "INFO: Sliced away " << st.nodesRemoved
                   << " from " << st.nodesTotal << " nodes\n";

#if (LLVM_VERSION_MAJOR > 6)
            llvm::WriteBitcodeToFile(*M, output);
#else
            llvm::WriteBitcodeToFile(M, output);
#endif
        }
    }

    if (bb_only) {
        LLVMDGDumpBlocks dumper(dg.get(), opts);
        dumper.dump(nullptr, dump_func_only);
    } else {
        LLVMDG2Dot dumper(dg.get(), opts);
        dumper.dump(nullptr, dump_func_only);
    }

    return 0;
}
<commit_msg>llvm-dg-dump: fix possibly uninitialized variable<commit_after>#ifndef HAVE_LLVM
#error "This code needs LLVM enabled"
#endif

#include <set>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>

#include <cassert>
#include <cstdio>

// ignore unused parameters in LLVM libraries
#if (__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Instructions.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_os_ostream.h>
#include <llvm/IRReader/IRReader.h>

#if LLVM_VERSION_MAJOR >= 4
#include <llvm/Bitcode/BitcodeReader.h>
#include <llvm/Bitcode/BitcodeWriter.h>
#else
#include <llvm/Bitcode/ReaderWriter.h>
#endif

#if (__clang__)
#pragma clang diagnostic pop // ignore -Wunused-parameter
#else
#pragma GCC diagnostic pop
#endif

#include "dg/llvm/LLVMDependenceGraph.h"
#include "dg/llvm/LLVMDependenceGraphBuilder.h"
#include "dg/llvm/LLVMSlicer.h"
#include "dg/llvm/LLVMDG2Dot.h"
#include "dg/llvm/PointerAnalysis/PointerAnalysis.h"
#include "dg/PointerAnalysis/PointerAnalysisFS.h"
#include "dg/PointerAnalysis/PointerAnalysisFI.h"
#include "dg/PointerAnalysis/PointerAnalysisFSInv.h"
#include "dg/llvm/DataDependence/DataDependence.h"

#include "TimeMeasure.h"

using namespace dg;
using llvm::errs;

int main(int argc, char *argv[])
{
    llvm::Module *M;
    llvm::LLVMContext context;
    llvm::SMDiagnostic SMD;
    bool mark_only = false;
    bool bb_only = false;
    bool threads = false;
    const char *module = nullptr;
    const char *slicing_criterion = nullptr;
    const char *dump_func_only = nullptr;
    const char *pts = "fi";
    const char *entry_func = "main";
    LLVMControlDependenceAnalysisOptions::CDAlgorithm cd_alg =
        LLVMControlDependenceAnalysisOptions::CDAlgorithm::STANDARD;

    using namespace debug;
    uint32_t opts = PRINT_CFG | PRINT_DD | PRINT_CD | PRINT_USE | PRINT_ID;

    // parse options
    for (int i = 1; i < argc; ++i) {
        if (strcmp(argv[i], "-no-control") == 0) {
            opts &= ~PRINT_CD;
        } else if (strcmp(argv[i], "-no-use") == 0) {
            opts &= ~PRINT_USE;
        } else if (strcmp(argv[i], "-pta") == 0) {
            pts = argv[++i];
        /*
        } else if (strcmp(argv[i], "-dda") == 0) {
            dda = argv[++i];
        */
        } else if (strcmp(argv[i], "-no-data") == 0) {
            opts &= ~PRINT_DD;
        } else if (strcmp(argv[i], "-no-cfg") == 0) {
            opts &= ~PRINT_CFG;
        } else if (strcmp(argv[i], "-call") == 0) {
            opts |= PRINT_CALL;
        } else if (strcmp(argv[i], "-postdom") == 0) {
            opts |= PRINT_POSTDOM;
        } else if (strcmp(argv[i], "-bb-only") == 0) {
            bb_only = true;
        } else if (strcmp(argv[i], "-cfgall") == 0) {
            opts |= PRINT_CFG;
            opts |= PRINT_REV_CFG;
        } else if (strcmp(argv[i], "-func") == 0) {
            dump_func_only = argv[++i];
        } else if (strcmp(argv[i], "-slice") == 0) {
            slicing_criterion = argv[++i];
        } else if (strcmp(argv[i], "-mark") == 0) {
            mark_only = true;
            slicing_criterion = argv[++i];
        } else if (strcmp(argv[i], "-threads") == 0) {
            threads = true;
        } else if (strcmp(argv[i], "-entry") == 0) {
            entry_func = argv[++i];
        } else if (strcmp(argv[i], "-cd-alg") == 0) {
            const char *arg = argv[++i];
            if (strcmp(arg, "standard") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::STANDARD;
            else if (strcmp(arg, "classic") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::STANDARD;
            else if (strcmp(arg, "ntscd") == 0)
                cd_alg = LLVMControlDependenceAnalysisOptions::CDAlgorithm::NTSCD;
            else {
                errs() << "Invalid control dependencies algorithm, try: classic, ce\n";
                abort();
            }

        } else {
            module = argv[i];
        }
    }

    if (!module) {
        errs() << "Usage: % IR_module [output_file]\n";
        return 1;
    }

#if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 5))
    M = llvm::ParseIRFile(module, SMD, context);
#else
    auto _M = llvm::parseIRFile(module, SMD, context);
    // _M is unique pointer, we need to get Module *
    M = _M.get();
#endif

    if (!M) {
        llvm::errs() << "Failed parsing '" << module << "' file:\n";
        SMD.print(argv[0], errs());
        return 1;
    }

    llvmdg::LLVMDependenceGraphOptions options;

    options.CDAOptions.algorithm = cd_alg;
    options.threads = threads;
    options.PTAOptions.threads = threads;
    options.DDAOptions.threads = threads;
    options.PTAOptions.entryFunction = entry_func;
    options.DDAOptions.entryFunction = entry_func;
    if (strcmp(pts, "fs") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::fs;
    } else if (strcmp(pts, "fi") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::fi;
    } else if (strcmp(pts, "inv") == 0) {
        options.PTAOptions.analysisType
            = LLVMPointerAnalysisOptions::AnalysisType::inv;
    } else {
        llvm::errs() << "Unknown points to analysis, try: fs, fi, inv\n";
        abort();
    }

    llvmdg::LLVMDependenceGraphBuilder builder(M, options);
    auto dg = builder.build();

    std::set<LLVMNode *> callsites;
    if (slicing_criterion) {
        const char *sc[] = {
            slicing_criterion,
            "klee_assume",
            NULL
        };

        dg->getCallSites(sc, &callsites);

        llvmdg::LLVMSlicer slicer;

        if (strcmp(slicing_criterion, "ret") == 0) {
            if (mark_only)
                slicer.mark(dg->getExit());
            else
                slicer.slice(dg.get(), dg->getExit());
        } else {
            if (callsites.empty()) {
                errs() << "ERR: slicing criterion not found: "
                       << slicing_criterion << "\n";
                exit(1);
            }

            uint32_t slid = 0;
            for (LLVMNode *start : callsites)
                slid = slicer.mark(start, slid);

            if (!mark_only)
               slicer.slice(dg.get(), nullptr, slid);
        }

        if (!mark_only) {
            std::string fl(module);
            fl.append(".sliced");
            std::ofstream ofs(fl);
            llvm::raw_os_ostream output(ofs);

            SlicerStatistics& st = slicer.getStatistics();
            errs() << "INFO: Sliced away " << st.nodesRemoved
                   << " from " << st.nodesTotal << " nodes\n";

#if (LLVM_VERSION_MAJOR > 6)
            llvm::WriteBitcodeToFile(*M, output);
#else
            llvm::WriteBitcodeToFile(M, output);
#endif
        }
    }

    if (bb_only) {
        LLVMDGDumpBlocks dumper(dg.get(), opts);
        dumper.dump(nullptr, dump_func_only);
    } else {
        LLVMDG2Dot dumper(dg.get(), opts);
        dumper.dump(nullptr, dump_func_only);
    }

    return 0;
}
<|endoftext|>


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

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

#define _TOOLS_RC_CXX

#include <string.h>

#ifndef _DATE_HXX
#include <tools/date.hxx>
#endif
#ifndef _TIME_HXX
#include <tools/time.hxx>
#endif

#ifndef _TOOLS_RC_HXX
#include <tools/rc.hxx>
#endif
#ifndef _TOOLS_RCID_H
#include <tools/rcid.h>
#endif

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

Resource::Resource( const ResId& rResId )
{
    GetRes( rResId.SetRT( RSC_RESOURCE ) );
}

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

void Resource::GetRes( const ResId& rResId )
{
    if( rResId.GetResMgr() )
        m_pResMgr = rResId.GetResMgr();
    m_pResMgr->GetResource( rResId, this );
    IncrementRes( sizeof( RSHEADER_TYPE ) );
}

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

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

Time::Time( const ResId& rResId )
{
    nTime = 0;
    rResId.SetRT( RSC_TIME );
    ResMgr* pResMgr = NULL;

    ResMgr::GetResourceSkipHeader( rResId, &pResMgr );

    ULONG nObjMask = (USHORT)pResMgr->ReadLong();

    if ( 0x01 & nObjMask )
        SetHour( (USHORT)pResMgr->ReadShort() );
    if ( 0x02 & nObjMask )
        SetMin( (USHORT)pResMgr->ReadShort() );
    if ( 0x04 & nObjMask )
        SetSec( (USHORT)pResMgr->ReadShort() );
    if ( 0x08 & nObjMask )
        Set100Sec( (USHORT)pResMgr->ReadShort() );
}

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

Date::Date( const ResId& rResId )
{
    rResId.SetRT( RSC_DATE );
    ResMgr* pResMgr = NULL;

    ResMgr::GetResourceSkipHeader( rResId, &pResMgr );

    ULONG nObjMask = (USHORT)pResMgr->ReadLong();

    if ( 0x01 & nObjMask )
        SetYear( (USHORT)pResMgr->ReadShort() );
    if ( 0x02 & nObjMask )
        SetMonth( (USHORT)pResMgr->ReadShort() );
    if ( 0x04 & nObjMask )
        SetDay( (USHORT)pResMgr->ReadShort() );
}
<commit_msg>INTEGRATION: CWS fwk81_DEV300 (1.10.58); FILE MERGED 2008/01/21 13:42:03 cd 1.10.58.1: #i85363# Initialize member in ResId ctor<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rc.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-27 10:19:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#define _TOOLS_RC_CXX

#include <string.h>

#ifndef _DATE_HXX
#include <tools/date.hxx>
#endif
#ifndef _TIME_HXX
#include <tools/time.hxx>
#endif

#ifndef _TOOLS_RC_HXX
#include <tools/rc.hxx>
#endif
#ifndef _TOOLS_RCID_H
#include <tools/rcid.h>
#endif

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

Resource::Resource( const ResId& rResId )
{
    GetRes( rResId.SetRT( RSC_RESOURCE ) );
}

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

void Resource::GetRes( const ResId& rResId )
{
    if( rResId.GetResMgr() )
        m_pResMgr = rResId.GetResMgr();
    m_pResMgr->GetResource( rResId, this );
    IncrementRes( sizeof( RSHEADER_TYPE ) );
}

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

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

Time::Time( const ResId& rResId )
{
    nTime = 0;
    rResId.SetRT( RSC_TIME );
    ResMgr* pResMgr = NULL;

    ResMgr::GetResourceSkipHeader( rResId, &pResMgr );

    ULONG nObjMask = (USHORT)pResMgr->ReadLong();

    if ( 0x01 & nObjMask )
        SetHour( (USHORT)pResMgr->ReadShort() );
    if ( 0x02 & nObjMask )
        SetMin( (USHORT)pResMgr->ReadShort() );
    if ( 0x04 & nObjMask )
        SetSec( (USHORT)pResMgr->ReadShort() );
    if ( 0x08 & nObjMask )
        Set100Sec( (USHORT)pResMgr->ReadShort() );
}

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

Date::Date( const ResId& rResId ) : nDate(0)
{
    rResId.SetRT( RSC_DATE );
    ResMgr* pResMgr = NULL;

    ResMgr::GetResourceSkipHeader( rResId, &pResMgr );

    ULONG nObjMask = (USHORT)pResMgr->ReadLong();

    if ( 0x01 & nObjMask )
        SetYear( (USHORT)pResMgr->ReadShort() );
    if ( 0x02 & nObjMask )
        SetMonth( (USHORT)pResMgr->ReadShort() );
    if ( 0x04 & nObjMask )
        SetDay( (USHORT)pResMgr->ReadShort() );
}
<|endoftext|>


<commit_before>#include "Game.h"

Game::Game()
{
   run();
}

Game::~Game()
{
}

bool Game::init()
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Could not init SDL: %s", SDL_GetError());
        return false;
    }

    window = SDL_CreateWindow("Romperador", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        printf("Could not create SDL Window: %s", SDL_GetError());
        return false;
    }

    //primarySurface = SDL_GetWindowSurface(window);

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
    if (renderer == nullptr) {
        printf("Could not create SDL Renderer: %s", SDL_GetError());
        return false;
    }

    SDL_SetRenderDrawColor(renderer, 55, 55, 55, 255);

    if (!(IMG_Init(IMG_INIT_PNG) && IMG_INIT_PNG)) {
        printf("Could not initialize SDL_Image: %s", IMG_GetError());
    }

    // Load textures
    txtPaddle = { renderer };
    txtPaddle.loadFromFile("content/img/paddleRed.png");

    return true;
}

void Game::run()
{
    init();

    SDL_Event e;

    Uint32 lastTime, currentTime, frameTime;
    float deltaTime;
    currentTime = SDL_GetTicks();

    while (running) {
        lastTime = currentTime;
        currentTime = SDL_GetTicks();
        deltaTime = (currentTime - lastTime) / 1000.0f;

        while (SDL_PollEvent(&e) != 0) {
            if (e.type == SDL_QUIT) {
                running = false;
            }

            paddle.handleEvent(e);
        }

        render(deltaTime);

        frameTime = SDL_GetTicks() - currentTime;
        if (frameTime < DELAY_TIME) {
            SDL_Delay((int)(DELAY_TIME - frameTime));
        }
    }

    clean();
}

void Game::render(float deltaTime)
{
    SDL_RenderClear(renderer);

    // Move the paddle
    paddle.move(deltaTime);

    // Render the paddle
    paddle.render(txtPaddle);

    SDL_RenderPresent(renderer);
}

void Game::clean()
{
    if (renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = nullptr;
    }

    if (window) {
        SDL_DestroyWindow(window);
        window = nullptr;
    }

    IMG_Quit();
    SDL_Quit();
}

SDL_Renderer* Game::getRenderer()
{
    return renderer;
}

int Game::getWidth()
{
    return WIDTH;
}

int Game::getHeight()
{
    return HEIGHT;
}
<commit_msg>rename game<commit_after>#include "Game.h"

Game::Game()
{
   run();
}

Game::~Game()
{
}

bool Game::init()
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Could not init SDL: %s", SDL_GetError());
        return false;
    }

    window = SDL_CreateWindow("Rompetono", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        printf("Could not create SDL Window: %s", SDL_GetError());
        return false;
    }

    //primarySurface = SDL_GetWindowSurface(window);

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
    if (renderer == nullptr) {
        printf("Could not create SDL Renderer: %s", SDL_GetError());
        return false;
    }

    SDL_SetRenderDrawColor(renderer, 55, 55, 55, 255);

    if (!(IMG_Init(IMG_INIT_PNG) && IMG_INIT_PNG)) {
        printf("Could not initialize SDL_Image: %s", IMG_GetError());
    }

    // Load textures
    txtPaddle = { renderer };
    txtPaddle.loadFromFile("content/img/paddleRed.png");

    return true;
}

void Game::run()
{
    init();

    SDL_Event e;

    Uint32 lastTime, currentTime, frameTime;
    float deltaTime;
    currentTime = SDL_GetTicks();

    while (running) {
        lastTime = currentTime;
        currentTime = SDL_GetTicks();
        deltaTime = (currentTime - lastTime) / 1000.0f;

        while (SDL_PollEvent(&e) != 0) {
            if (e.type == SDL_QUIT) {
                running = false;
            }

            paddle.handleEvent(e);
        }

        render(deltaTime);

        frameTime = SDL_GetTicks() - currentTime;
        if (frameTime < DELAY_TIME) {
            SDL_Delay((int)(DELAY_TIME - frameTime));
        }
    }

    clean();
}

void Game::render(float deltaTime)
{
    SDL_RenderClear(renderer);

    // Move the paddle
    paddle.move(deltaTime);

    // Render the paddle
    paddle.render(txtPaddle);

    SDL_RenderPresent(renderer);
}

void Game::clean()
{
    if (renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = nullptr;
    }

    if (window) {
        SDL_DestroyWindow(window);
        window = nullptr;
    }

    IMG_Quit();
    SDL_Quit();
}

SDL_Renderer* Game::getRenderer()
{
    return renderer;
}

int Game::getWidth()
{
    return WIDTH;
}

int Game::getHeight()
{
    return HEIGHT;
}
<|endoftext|>


<commit_before>#ifndef __ENVIRE_MAPS_GRID_HPP__
#define __ENVIRE_MAPS_GRID_HPP__

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <boost/intrusive_ptr.hpp>
#include <boost/function.hpp>

#include "LocalMap.hpp"

namespace envire { namespace maps
{

    /**@brief type for the number of cells
     */
    typedef Eigen::Matrix<unsigned int, 2, 1> Vector2ui;

    typedef Eigen::Vector2d Vector2d;

    typedef Eigen::Vector3d Vector3d;

    /**@brief Internal structure used to represent a position on the grid
     * itself, as a cell index
     */
    class Index : public Eigen::Matrix<unsigned int, 2, 1>
    {
        public:
            typedef Eigen::Matrix<unsigned int, 2, 1> Base;

            Index()
                : Eigen::Matrix<unsigned int, 2, 1>(0, 0)
            {}

            Index(unsigned int x, unsigned int y)
                : Eigen::Matrix<unsigned int, 2, 1>(x, y)
            {}

            // This constructor allows you to construct Index from Eigen expressions
            template<typename OtherDerived>
            Index(const Eigen::MatrixBase<OtherDerived>& other)
                : Eigen::Matrix<unsigned int, 2, 1>(other)
            {}

            bool operator<(const Index& other) const
            {
                return (x() < other.x()
                    || (x() == other.x() && y() < other.y()));
            }

            bool operator>(const Index& other) const
            {
                return (x() > other.x()
                    || (x() == other.x() && y() > other.y()));
            }

            // TODO: add exception if the other is bigger
            // than this. due to uint
            //Index operator-(const Index& other) const
            //{
            //}
    };

    /** Base class for all 2D gridbased maps.
     * - describes the grid structure: resolution and number of cells in x- and y- axes.
     * - converts position -> index and index -> position
     * - checks if the position or index is inside the grid
     */
    class Grid : public LocalMap
    {
        public:
            typedef boost::intrusive_ptr<Grid> Ptr;

        protected:
            /** Number of cells in X-axis and Y-axis **/
            Vector2ui num_cells;

            /**
             * Resolution in local X-axis and Y-axis
             * (Size of the cell in local X-axis and Y-axis in world unit)
             */
            Vector2d resolution;

        public:
            Grid();

            Grid(const Vector2ui &num_cells, const Vector2d &resolution);

            /**
             * @brief [brief description]
             * @details share the LocalMapData
             *
             * @param num_cells [description]
             * @param resolution [description]
             * @param data [description]
             */
            Grid(const Vector2ui &num_cells,
                const Vector2d &resolution,
                const boost::shared_ptr<LocalMapData> &data);

            virtual ~Grid();

            /** @brief get the number of cells
             */
            const Vector2ui& getNumCells() const;

            /**
             * @brief get the resolution of the grid
             * @return cell size in local X-axis and Y-axis in world unit
             */
            const Vector2d& getResolution() const;

            /**
             * @brief get the size of the grid in world unit
             * @return size of the grid in local X-axis and Y-axis in wold unit
             */
            Vector2d getSize() const;

            bool inGrid(const Index& idx) const;

            /**
             * @brief convert the index (the grid position) into position in local frame
             * by taking the offset (base::Transform3d) into account as description
             * of local grid frame
             *
             */
            bool fromGrid(const Index& idx, Vector3d& pos) const;

            /**
             * @brief Converts coordinates from the map-local grid coordinates to
             * the coordinates in the specified \c frame
             */
            bool fromGrid(const Index& idx, Vector3d& pos_in_frame, const base::Transform3d &frame_in_grid) const;

            /**
             * @brief [brief description]
             * @details for the corner and border cases no definite solution
             *
             * @param pos [description]
             * @param idx [description]
             *
             * @return [description]
             */
            bool toGrid(const Vector3d& pos, Index& idx) const;

            bool toGrid(const Vector3d& pos, Index& idx, Vector3d &pos_diff) const;

            bool toGrid(const Vector3d& pos_in_frame, Index& idx, const base::Transform3d &frame_in_grid) const;
    };
}}

#endif // __ENVIRE_MAPS_GRIDBASE_HPP__
<commit_msg>src: remove intrusive_ptr in Grid<commit_after>#ifndef __ENVIRE_MAPS_GRID_HPP__
#define __ENVIRE_MAPS_GRID_HPP__

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <boost/function.hpp>

#include "LocalMap.hpp"

namespace envire { namespace maps
{

    /**@brief type for the number of cells
     */
    typedef Eigen::Matrix<unsigned int, 2, 1> Vector2ui;

    typedef Eigen::Vector2d Vector2d;

    typedef Eigen::Vector3d Vector3d;

    /**@brief Internal structure used to represent a position on the grid
     * itself, as a cell index
     */
    class Index : public Eigen::Matrix<unsigned int, 2, 1>
    {
        public:
            typedef Eigen::Matrix<unsigned int, 2, 1> Base;

            Index()
                : Eigen::Matrix<unsigned int, 2, 1>(0, 0)
            {}

            Index(unsigned int x, unsigned int y)
                : Eigen::Matrix<unsigned int, 2, 1>(x, y)
            {}

            // This constructor allows you to construct Index from Eigen expressions
            template<typename OtherDerived>
            Index(const Eigen::MatrixBase<OtherDerived>& other)
                : Eigen::Matrix<unsigned int, 2, 1>(other)
            {}

            bool operator<(const Index& other) const
            {
                return (x() < other.x()
                    || (x() == other.x() && y() < other.y()));
            }

            bool operator>(const Index& other) const
            {
                return (x() > other.x()
                    || (x() == other.x() && y() > other.y()));
            }

            // TODO: add exception if the other is bigger
            // than this. due to uint
            //Index operator-(const Index& other) const
            //{
            //}
    };

    /** Base class for all 2D gridbased maps.
     * - describes the grid structure: resolution and number of cells in x- and y- axes.
     * - converts position -> index and index -> position
     * - checks if the position or index is inside the grid
     */
    class Grid : public LocalMap
    {
        public:
            typedef boost::shared_ptr<Grid> Ptr;

        protected:
            /** Number of cells in X-axis and Y-axis **/
            Vector2ui num_cells;

            /**
             * Resolution in local X-axis and Y-axis
             * (Size of the cell in local X-axis and Y-axis in world unit)
             */
            Vector2d resolution;

        public:
            Grid();

            Grid(const Vector2ui &num_cells, const Vector2d &resolution);

            /**
             * @brief [brief description]
             * @details share the LocalMapData
             *
             * @param num_cells [description]
             * @param resolution [description]
             * @param data [description]
             */
            Grid(const Vector2ui &num_cells,
                const Vector2d &resolution,
                const boost::shared_ptr<LocalMapData> &data);

            virtual ~Grid();

            /** @brief get the number of cells
             */
            const Vector2ui& getNumCells() const;

            /**
             * @brief get the resolution of the grid
             * @return cell size in local X-axis and Y-axis in world unit
             */
            const Vector2d& getResolution() const;

            /**
             * @brief get the size of the grid in world unit
             * @return size of the grid in local X-axis and Y-axis in wold unit
             */
            Vector2d getSize() const;

            bool inGrid(const Index& idx) const;

            /**
             * @brief convert the index (the grid position) into position in local frame
             * by taking the offset (base::Transform3d) into account as description
             * of local grid frame
             *
             */
            bool fromGrid(const Index& idx, Vector3d& pos) const;

            /**
             * @brief Converts coordinates from the map-local grid coordinates to
             * the coordinates in the specified \c frame
             */
            bool fromGrid(const Index& idx, Vector3d& pos_in_frame, const base::Transform3d &frame_in_grid) const;

            /**
             * @brief [brief description]
             * @details for the corner and border cases no definite solution
             *
             * @param pos [description]
             * @param idx [description]
             *
             * @return [description]
             */
            bool toGrid(const Vector3d& pos, Index& idx) const;

            bool toGrid(const Vector3d& pos, Index& idx, Vector3d &pos_diff) const;

            bool toGrid(const Vector3d& pos_in_frame, Index& idx, const base::Transform3d &frame_in_grid) const;
    };
}}

#endif // __ENVIRE_MAPS_GRIDBASE_HPP__
<|endoftext|>


<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015-2019 Hugo Beauzée-Luyssen, Videolabs, VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.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.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "Show.h"

#include "Media.h"
#include "ShowEpisode.h"
#include "MediaLibrary.h"

#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"

namespace medialibrary
{

const std::string Show::Table::Name = "Show";
const std::string Show::Table::PrimaryKeyColumn = "id_show";
int64_t Show::* const Show::Table::PrimaryKey = &Show::m_id;
const std::string Show::FtsTable::Name = "ShowFts";

Show::Show( MediaLibraryPtr ml, sqlite::Row& row )
    : m_ml( ml )
    , m_id( row.extract<decltype(m_id)>() )
    , m_title( row.extract<decltype(m_title)>() )
    , m_nbEpisodes( row.extract<decltype(m_nbEpisodes)>() )
    , m_releaseDate( row.extract<decltype(m_releaseDate)>() )
    , m_shortSummary( row.extract<decltype(m_shortSummary)>() )
    , m_artworkMrl( row.extract<decltype(m_artworkMrl)>() )
    , m_tvdbId( row.extract<decltype(m_tvdbId)>() )
    // Don't load is_present
{
    assert( row.nbColumns() == 8 );
}

Show::Show( MediaLibraryPtr ml, std::string name )
    : m_ml( ml )
    , m_id( 0 )
    , m_title( std::move( name ) )
    , m_nbEpisodes( 0 )
    , m_releaseDate( 0 )
{
}

int64_t Show::id() const
{
    return m_id;
}

const std::string& Show::title() const
{
    return m_title;
}

time_t Show::releaseDate() const
{
    return m_releaseDate;
}

bool Show::setReleaseDate( time_t date )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET release_date = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, date, m_id ) == false )
        return false;
    m_releaseDate = date;
    return true;
}

const std::string& Show::shortSummary() const
{
    return m_shortSummary;
}

bool Show::setShortSummary( const std::string& summary )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET short_summary = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, summary, m_id ) == false )
        return false;
    m_shortSummary = summary;
    return true;
}

const std::string& Show::artworkMrl() const
{
    return m_artworkMrl;
}

bool Show::setArtworkMrl( const std::string& artworkMrl )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET artwork_mrl = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, artworkMrl, m_id ) == false )
        return false;
    m_artworkMrl = artworkMrl;
    return true;
}

const std::string& Show::tvdbId() const
{
    return m_tvdbId;
}

bool Show::setTvdbId( const std::string& tvdbId )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET tvdb_id = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, tvdbId, m_id ) == false )
        return false;
    m_tvdbId = tvdbId;
    return true;
}

std::shared_ptr<ShowEpisode> Show::addEpisode( Media& media, uint32_t seasonId,
                                               uint32_t episodeId,
                                               std::string title )
{
    auto episode = ShowEpisode::create( m_ml, media.id(), seasonId, episodeId,
                                        std::move( title ), m_id );
    media.setShowEpisode( episode );
    m_nbEpisodes++;
    return episode;
}

Query<IMedia> Show::episodes( const QueryParameters* params ) const
{
    std::string req = "FROM " + Media::Table::Name + " med "
            " INNER JOIN " + ShowEpisode::Table::Name + " ep ON ep.media_id = med.id_media "
            + " WHERE ep.show_id = ?"
            " AND med.is_present != 0";
    std::string orderBy = " ORDER BY ";
    auto sort = params != nullptr ? params->sort : SortingCriteria::Default;
    auto desc = params != nullptr ? params->desc : false;
    switch ( sort )
    {
        case SortingCriteria::Alpha:
            orderBy += "med.name";
            if ( desc == true )
                orderBy += " DESC";
            break;
        default:
            LOG_WARN( "Unsupported sorting criteria, falling back to SortingCriteria::Default" );
            /* fall-through */
        case SortingCriteria::Default:
            if ( desc == true )
                orderBy += "ep.season_number DESC, ep.episode_number DESC";
            else
                orderBy += "ep.season_number, ep.episode_number";
            break;

    }
    return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ),
                                      std::move( orderBy), m_id );
}

Query<IMedia> Show::searchEpisodes( const std::string& pattern,
                                    const QueryParameters* params ) const
{
    return Media::searchShowEpisodes( m_ml, pattern, m_id, params );
}

uint32_t Show::nbSeasons() const
{
    return 0;
}

uint32_t Show::nbEpisodes() const
{
    return m_nbEpisodes;
}

void Show::createTable( sqlite::Connection* dbConnection )
{
    const std::string reqs[] = {
        schema( Table::Name, Settings::DbModelVersion ),
        schema( FtsTable::Name, Settings::DbModelVersion )
    };
    for ( const auto& req : reqs )
        sqlite::Tools::executeRequest( dbConnection, req );
}

void Show::createTriggers( sqlite::Connection* dbConnection )
{
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::InsertFts,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::DeleteFts,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::IncrementNbEpisode,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::DecrementNbEpisode,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::UpdateIsPresent,
                                            Settings::DbModelVersion ) );
}

std::string Show::schema( const std::string& tableName, uint32_t dbModelVersion )
{
    if ( tableName == FtsTable::Name )
    {
        return "CREATE VIRTUAL TABLE " + FtsTable::Name +
               " USING FTS3(title)";
    }
    assert( tableName == Table::Name );
    if ( dbModelVersion < 23 )
    {
        return "CREATE TABLE " + Table::Name +
        "("
           "id_show INTEGER PRIMARY KEY AUTOINCREMENT,"
           "title TEXT,"
           "release_date UNSIGNED INTEGER,"
           "short_summary TEXT,"
           "artwork_mrl TEXT,"
           "tvdb_id TEXT"
        ")";
    }
    return "CREATE TABLE " + Table::Name +
    "("
       "id_show INTEGER PRIMARY KEY AUTOINCREMENT,"
       "title TEXT,"
       "nb_episodes UNSIGNED INTEGER NOT NULL DEFAULT 0,"
       "release_date UNSIGNED INTEGER,"
       "short_summary TEXT,"
       "artwork_mrl TEXT,"
       "tvdb_id TEXT,"
       "is_present UNSIGNED INTEGER NOT NULL DEFAULT 0 "
            "CHECK(is_present <= nb_episodes)"
    ")";
}

std::string Show::trigger( Show::Triggers trigger, uint32_t dbModel )
{
    switch ( trigger )
    {
        case Triggers::InsertFts:
        {
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER INSERT ON " + Table::Name +
                   " BEGIN"
                   " INSERT INTO " + FtsTable::Name + "(rowid,title)"
                        " VALUES(new.id_show, new.title);"
                   " END";
        }
        case Triggers::DeleteFts:
        {
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " BEFORE DELETE ON " + Table::Name +
                   " BEGIN"
                   " DELETE FROM " + FtsTable::Name +
                        " WHERE rowid = old.id_show;"
                   " END";
        }
        case Triggers::IncrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER INSERT ON " + ShowEpisode::Table::Name +
                   " BEGIN"
                   " UPDATE " + Table::Name +
                       " SET nb_episodes = nb_episodes + 1,"
                       " is_present = is_present + 1"
                            " WHERE id_show = new.show_id;"
                   " END";
        }
        case Triggers::DecrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER DELETE ON " + ShowEpisode::Table::Name +
                   " BEGIN"
                   " UPDATE " + Table::Name +
                       " SET nb_episodes = nb_episodes - 1,"
                       " is_present = is_present - 1"
                            " WHERE id_show = old.show_id;"
                   " END";
        }
        case Triggers::UpdateIsPresent:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER UPDATE OF "
                       "is_present ON " + Media::Table::Name +
                   " WHEN new.subtype = " +
                       std::to_string(
                        static_cast<typename std::underlying_type<IMedia::SubType>::type>(
                                           IMedia::SubType::ShowEpisode ) ) +
                   " AND new.is_present != old.is_present"
                   " BEGIN "
                   " UPDATE " + Table::Name + " SET is_present=is_present +"
                       " (CASE new.is_present WHEN 0 THEN -1 ELSE 1 END)"
                       " WHERE id_show = (SELECT show_id FROM " + ShowEpisode::Table::Name +
                           " WHERE media_id = new.id_media);"
                   " END";
        }
        default:
            assert( !"Invalid trigger provided" );
    }
    return "<invalid request>";
}

std::string Show::triggerName( Triggers trigger, uint32_t dbModel )
{
    UNUSED_IN_RELEASE( dbModel );

    switch ( trigger )
    {
        case Triggers::InsertFts:
            return "insert_show_fts";
        case Triggers::DeleteFts:
            return "delete_show_fts";
        case Triggers::IncrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "show_increment_nb_episode";
        }
        case Triggers::DecrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "show_decrement_nb_episode";
        }
        case Triggers::UpdateIsPresent:
        {
            assert( dbModel >= 23 );
            return "show_update_is_present";
        }
        default:
            assert( !"Invalid trigger provided" );
    }
    return "<invalid request>";
}

bool Show::checkDbModel(MediaLibraryPtr ml)
{
    if ( sqlite::Tools::checkTableSchema( ml->getConn(),
                                       schema( Table::Name, Settings::DbModelVersion ),
                                       Table::Name ) == false ||
           sqlite::Tools::checkTableSchema( ml->getConn(),
                                       schema( FtsTable::Name, Settings::DbModelVersion ),
                                       FtsTable::Name ) == false )
        return false;

    auto checkTrigger = []( sqlite::Connection* dbConn, Triggers t ) {
        return sqlite::Tools::checkTriggerStatement( dbConn,
                                    trigger( t, Settings::DbModelVersion ),
                                    triggerName( t, Settings::DbModelVersion ) );
    };
    return checkTrigger( ml->getConn(), Triggers::InsertFts ) &&
            checkTrigger( ml->getConn(), Triggers::DeleteFts ) &&
            checkTrigger( ml->getConn(), Triggers::IncrementNbEpisode ) &&
            checkTrigger( ml->getConn(), Triggers::DecrementNbEpisode ) &&
            checkTrigger( ml->getConn(), Triggers::UpdateIsPresent );
}

std::shared_ptr<Show> Show::create( MediaLibraryPtr ml, std::string name )
{
    auto show = std::make_shared<Show>( ml, std::move( name ) );
    static const std::string req = "INSERT INTO " + Show::Table::Name
            + "(title) VALUES(?)";
    if ( insert( ml, show, req, show->m_title ) == false )
        return nullptr;
    return show;
}

Query<IShow> Show::listAll( MediaLibraryPtr ml, const QueryParameters* params )
{
    std::string req = "FROM " + Show::Table::Name;
    if ( params == nullptr || params->includeMissing == false )
        req += " WHERE is_present != 0";
    return make_query<Show, IShow>( ml, "*", std::move( req ), orderBy( params ) );
}

std::string Show::orderBy( const QueryParameters* params )
{
    std::string req = " ORDER BY ";
    SortingCriteria sort = params != nullptr ? params->sort : SortingCriteria::Default;
    switch ( sort )
    {
        case SortingCriteria::ReleaseDate:
            req += "release_date";
            break;
        case SortingCriteria::Default:
        case SortingCriteria::Alpha:
        default:
            req += "title";
            break;

    }
    if ( params != nullptr && params->desc == true )
        req += " DESC";
    return req;
}

Query<IShow> Show::search( MediaLibraryPtr ml, const std::string& pattern,
                           const QueryParameters* params )
{
    std::string req = "FROM " + Show::Table::Name + " WHERE id_show IN"
            "(SELECT rowid FROM " + Show::FtsTable::Name + " WHERE " +
            Show::FtsTable::Name + " MATCH ?)";
    if ( params == nullptr || params->includeMissing == false )
        req += " AND is_present != 0";
    return make_query<Show, IShow>( ml, "*", std::move( req ),
                                    orderBy( params ),
                                    sqlite::Tools::sanitizePattern( pattern ) );
}

bool Show::createUnknownShow( sqlite::Connection* dbConn )
{
    const std::string req = "INSERT INTO " + Table::Name + " (id_show) VALUES(?)";
    return sqlite::Tools::executeInsert( dbConn, req, UnknownShowID );
}

}
<commit_msg>Show: Use enum_to_string<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015-2019 Hugo Beauzée-Luyssen, Videolabs, VideoLAN
 *
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.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.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "Show.h"

#include "Media.h"
#include "ShowEpisode.h"
#include "MediaLibrary.h"
#include "utils/Enums.h"

#include "database/SqliteTools.h"
#include "database/SqliteQuery.h"

namespace medialibrary
{

const std::string Show::Table::Name = "Show";
const std::string Show::Table::PrimaryKeyColumn = "id_show";
int64_t Show::* const Show::Table::PrimaryKey = &Show::m_id;
const std::string Show::FtsTable::Name = "ShowFts";

Show::Show( MediaLibraryPtr ml, sqlite::Row& row )
    : m_ml( ml )
    , m_id( row.extract<decltype(m_id)>() )
    , m_title( row.extract<decltype(m_title)>() )
    , m_nbEpisodes( row.extract<decltype(m_nbEpisodes)>() )
    , m_releaseDate( row.extract<decltype(m_releaseDate)>() )
    , m_shortSummary( row.extract<decltype(m_shortSummary)>() )
    , m_artworkMrl( row.extract<decltype(m_artworkMrl)>() )
    , m_tvdbId( row.extract<decltype(m_tvdbId)>() )
    // Don't load is_present
{
    assert( row.nbColumns() == 8 );
}

Show::Show( MediaLibraryPtr ml, std::string name )
    : m_ml( ml )
    , m_id( 0 )
    , m_title( std::move( name ) )
    , m_nbEpisodes( 0 )
    , m_releaseDate( 0 )
{
}

int64_t Show::id() const
{
    return m_id;
}

const std::string& Show::title() const
{
    return m_title;
}

time_t Show::releaseDate() const
{
    return m_releaseDate;
}

bool Show::setReleaseDate( time_t date )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET release_date = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, date, m_id ) == false )
        return false;
    m_releaseDate = date;
    return true;
}

const std::string& Show::shortSummary() const
{
    return m_shortSummary;
}

bool Show::setShortSummary( const std::string& summary )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET short_summary = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, summary, m_id ) == false )
        return false;
    m_shortSummary = summary;
    return true;
}

const std::string& Show::artworkMrl() const
{
    return m_artworkMrl;
}

bool Show::setArtworkMrl( const std::string& artworkMrl )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET artwork_mrl = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, artworkMrl, m_id ) == false )
        return false;
    m_artworkMrl = artworkMrl;
    return true;
}

const std::string& Show::tvdbId() const
{
    return m_tvdbId;
}

bool Show::setTvdbId( const std::string& tvdbId )
{
    static const std::string req = "UPDATE " + Show::Table::Name
            + " SET tvdb_id = ? WHERE id_show = ?";
    if ( sqlite::Tools::executeUpdate( m_ml->getConn(), req, tvdbId, m_id ) == false )
        return false;
    m_tvdbId = tvdbId;
    return true;
}

std::shared_ptr<ShowEpisode> Show::addEpisode( Media& media, uint32_t seasonId,
                                               uint32_t episodeId,
                                               std::string title )
{
    auto episode = ShowEpisode::create( m_ml, media.id(), seasonId, episodeId,
                                        std::move( title ), m_id );
    media.setShowEpisode( episode );
    m_nbEpisodes++;
    return episode;
}

Query<IMedia> Show::episodes( const QueryParameters* params ) const
{
    std::string req = "FROM " + Media::Table::Name + " med "
            " INNER JOIN " + ShowEpisode::Table::Name + " ep ON ep.media_id = med.id_media "
            + " WHERE ep.show_id = ?"
            " AND med.is_present != 0";
    std::string orderBy = " ORDER BY ";
    auto sort = params != nullptr ? params->sort : SortingCriteria::Default;
    auto desc = params != nullptr ? params->desc : false;
    switch ( sort )
    {
        case SortingCriteria::Alpha:
            orderBy += "med.name";
            if ( desc == true )
                orderBy += " DESC";
            break;
        default:
            LOG_WARN( "Unsupported sorting criteria, falling back to SortingCriteria::Default" );
            /* fall-through */
        case SortingCriteria::Default:
            if ( desc == true )
                orderBy += "ep.season_number DESC, ep.episode_number DESC";
            else
                orderBy += "ep.season_number, ep.episode_number";
            break;

    }
    return make_query<Media, IMedia>( m_ml, "med.*", std::move( req ),
                                      std::move( orderBy), m_id );
}

Query<IMedia> Show::searchEpisodes( const std::string& pattern,
                                    const QueryParameters* params ) const
{
    return Media::searchShowEpisodes( m_ml, pattern, m_id, params );
}

uint32_t Show::nbSeasons() const
{
    return 0;
}

uint32_t Show::nbEpisodes() const
{
    return m_nbEpisodes;
}

void Show::createTable( sqlite::Connection* dbConnection )
{
    const std::string reqs[] = {
        schema( Table::Name, Settings::DbModelVersion ),
        schema( FtsTable::Name, Settings::DbModelVersion )
    };
    for ( const auto& req : reqs )
        sqlite::Tools::executeRequest( dbConnection, req );
}

void Show::createTriggers( sqlite::Connection* dbConnection )
{
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::InsertFts,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::DeleteFts,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::IncrementNbEpisode,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::DecrementNbEpisode,
                                            Settings::DbModelVersion ) );
    sqlite::Tools::executeRequest( dbConnection,
                                   trigger( Triggers::UpdateIsPresent,
                                            Settings::DbModelVersion ) );
}

std::string Show::schema( const std::string& tableName, uint32_t dbModelVersion )
{
    if ( tableName == FtsTable::Name )
    {
        return "CREATE VIRTUAL TABLE " + FtsTable::Name +
               " USING FTS3(title)";
    }
    assert( tableName == Table::Name );
    if ( dbModelVersion < 23 )
    {
        return "CREATE TABLE " + Table::Name +
        "("
           "id_show INTEGER PRIMARY KEY AUTOINCREMENT,"
           "title TEXT,"
           "release_date UNSIGNED INTEGER,"
           "short_summary TEXT,"
           "artwork_mrl TEXT,"
           "tvdb_id TEXT"
        ")";
    }
    return "CREATE TABLE " + Table::Name +
    "("
       "id_show INTEGER PRIMARY KEY AUTOINCREMENT,"
       "title TEXT,"
       "nb_episodes UNSIGNED INTEGER NOT NULL DEFAULT 0,"
       "release_date UNSIGNED INTEGER,"
       "short_summary TEXT,"
       "artwork_mrl TEXT,"
       "tvdb_id TEXT,"
       "is_present UNSIGNED INTEGER NOT NULL DEFAULT 0 "
            "CHECK(is_present <= nb_episodes)"
    ")";
}

std::string Show::trigger( Show::Triggers trigger, uint32_t dbModel )
{
    switch ( trigger )
    {
        case Triggers::InsertFts:
        {
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER INSERT ON " + Table::Name +
                   " BEGIN"
                   " INSERT INTO " + FtsTable::Name + "(rowid,title)"
                        " VALUES(new.id_show, new.title);"
                   " END";
        }
        case Triggers::DeleteFts:
        {
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " BEFORE DELETE ON " + Table::Name +
                   " BEGIN"
                   " DELETE FROM " + FtsTable::Name +
                        " WHERE rowid = old.id_show;"
                   " END";
        }
        case Triggers::IncrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER INSERT ON " + ShowEpisode::Table::Name +
                   " BEGIN"
                   " UPDATE " + Table::Name +
                       " SET nb_episodes = nb_episodes + 1,"
                       " is_present = is_present + 1"
                            " WHERE id_show = new.show_id;"
                   " END";
        }
        case Triggers::DecrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER DELETE ON " + ShowEpisode::Table::Name +
                   " BEGIN"
                   " UPDATE " + Table::Name +
                       " SET nb_episodes = nb_episodes - 1,"
                       " is_present = is_present - 1"
                            " WHERE id_show = old.show_id;"
                   " END";
        }
        case Triggers::UpdateIsPresent:
        {
            assert( dbModel >= 23 );
            return "CREATE TRIGGER " + triggerName( trigger, dbModel ) +
                   " AFTER UPDATE OF "
                       "is_present ON " + Media::Table::Name +
                   " WHEN new.subtype = " +
                       utils::enum_to_string( IMedia::SubType::ShowEpisode ) +
                   " AND new.is_present != old.is_present"
                   " BEGIN "
                   " UPDATE " + Table::Name + " SET is_present=is_present +"
                       " (CASE new.is_present WHEN 0 THEN -1 ELSE 1 END)"
                       " WHERE id_show = (SELECT show_id FROM " + ShowEpisode::Table::Name +
                           " WHERE media_id = new.id_media);"
                   " END";
        }
        default:
            assert( !"Invalid trigger provided" );
    }
    return "<invalid request>";
}

std::string Show::triggerName( Triggers trigger, uint32_t dbModel )
{
    UNUSED_IN_RELEASE( dbModel );

    switch ( trigger )
    {
        case Triggers::InsertFts:
            return "insert_show_fts";
        case Triggers::DeleteFts:
            return "delete_show_fts";
        case Triggers::IncrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "show_increment_nb_episode";
        }
        case Triggers::DecrementNbEpisode:
        {
            assert( dbModel >= 23 );
            return "show_decrement_nb_episode";
        }
        case Triggers::UpdateIsPresent:
        {
            assert( dbModel >= 23 );
            return "show_update_is_present";
        }
        default:
            assert( !"Invalid trigger provided" );
    }
    return "<invalid request>";
}

bool Show::checkDbModel(MediaLibraryPtr ml)
{
    if ( sqlite::Tools::checkTableSchema( ml->getConn(),
                                       schema( Table::Name, Settings::DbModelVersion ),
                                       Table::Name ) == false ||
           sqlite::Tools::checkTableSchema( ml->getConn(),
                                       schema( FtsTable::Name, Settings::DbModelVersion ),
                                       FtsTable::Name ) == false )
        return false;

    auto checkTrigger = []( sqlite::Connection* dbConn, Triggers t ) {
        return sqlite::Tools::checkTriggerStatement( dbConn,
                                    trigger( t, Settings::DbModelVersion ),
                                    triggerName( t, Settings::DbModelVersion ) );
    };
    return checkTrigger( ml->getConn(), Triggers::InsertFts ) &&
            checkTrigger( ml->getConn(), Triggers::DeleteFts ) &&
            checkTrigger( ml->getConn(), Triggers::IncrementNbEpisode ) &&
            checkTrigger( ml->getConn(), Triggers::DecrementNbEpisode ) &&
            checkTrigger( ml->getConn(), Triggers::UpdateIsPresent );
}

std::shared_ptr<Show> Show::create( MediaLibraryPtr ml, std::string name )
{
    auto show = std::make_shared<Show>( ml, std::move( name ) );
    static const std::string req = "INSERT INTO " + Show::Table::Name
            + "(title) VALUES(?)";
    if ( insert( ml, show, req, show->m_title ) == false )
        return nullptr;
    return show;
}

Query<IShow> Show::listAll( MediaLibraryPtr ml, const QueryParameters* params )
{
    std::string req = "FROM " + Show::Table::Name;
    if ( params == nullptr || params->includeMissing == false )
        req += " WHERE is_present != 0";
    return make_query<Show, IShow>( ml, "*", std::move( req ), orderBy( params ) );
}

std::string Show::orderBy( const QueryParameters* params )
{
    std::string req = " ORDER BY ";
    SortingCriteria sort = params != nullptr ? params->sort : SortingCriteria::Default;
    switch ( sort )
    {
        case SortingCriteria::ReleaseDate:
            req += "release_date";
            break;
        case SortingCriteria::Default:
        case SortingCriteria::Alpha:
        default:
            req += "title";
            break;

    }
    if ( params != nullptr && params->desc == true )
        req += " DESC";
    return req;
}

Query<IShow> Show::search( MediaLibraryPtr ml, const std::string& pattern,
                           const QueryParameters* params )
{
    std::string req = "FROM " + Show::Table::Name + " WHERE id_show IN"
            "(SELECT rowid FROM " + Show::FtsTable::Name + " WHERE " +
            Show::FtsTable::Name + " MATCH ?)";
    if ( params == nullptr || params->includeMissing == false )
        req += " AND is_present != 0";
    return make_query<Show, IShow>( ml, "*", std::move( req ),
                                    orderBy( params ),
                                    sqlite::Tools::sanitizePattern( pattern ) );
}

bool Show::createUnknownShow( sqlite::Connection* dbConn )
{
    const std::string req = "INSERT INTO " + Table::Name + " (id_show) VALUES(?)";
    return sqlite::Tools::executeInsert( dbConn, req, UnknownShowID );
}

}
<|endoftext|>


<commit_before>#include "Sync.h"

#include <iostream>

#include "../gen/SyncMessage.pb.h"
#include "Logger.h"

Sync::Sync()
	: _udp_con(CONNECTION_PORT)
	, _running(false)
	, _sync_thread(&Sync::_threadHandle, this)
	, _is_leader(false) {}

Sync::~Sync(){
	_running = false;
	_udp_con.closeConnection();
	_sync_thread.join();
}

int Sync::connect(){
	SyncMessage sm;
	int timeout = 10000;
	int found_leader = 0;

	_udp_con.createConnection(CLIENT, -1, "");
	_udp_con.enableBroadcast();
	_udp_con.setRecvTimout(timeout);

	sm.set_type(SyncMessage_Type_ELECTION);
	sm.set_leader(false);
	_sendMessage(sm, BROADCAST_IP);

	while (1){
		if (_recvMessage(sm) != 0){
			//timout
			break;
		} else {
			// TODO save ips in list
			if (sm.type() == SyncMessage_Type_ELECTION && sm.leader()){
				found_leader = 1;
			}
		}
	}

	_running = true;
	_is_leader = found_leader ? false : true;

	return found_leader;
}

void Sync::getTime(uint64_t* t){
	struct timespec tv;

	clock_gettime(CLOCK_REALTIME, &tv);

	t[0] = (uint64_t) tv.tv_sec;
	t[1] = (uint64_t) tv.tv_nsec;
}

void Sync::_setTime(int64_t offset_sec, int64_t offset_nsec){
	struct timespec t;
	if(clock_gettime(CLOCK_REALTIME, &t) == -1){
		cout << "settime error: " << strerror(errno) << endl;
	}

	t.tv_sec += offset_sec;
	t.tv_nsec += offset_nsec;

	if(clock_settime(CLOCK_REALTIME, &t) == -1){
		cout << "settime error: " << strerror(errno) << endl;
	}
}

void Sync::_sendMessage(MessageLite& m, string ip){
	if (m.ByteSize() > 254){
		LOG_WARNING << "serialized SyncMessage length exceeded 254 Bytes ("
			<< m.ByteSize() << ")" << endl;
		return;
	}

	char size = m.ByteSize();
	char buffer[255] = {0};

	m.SerializeToArray(&buffer[1], 254);
	buffer[0] = size;

	_udp_con.sendData(buffer, 255, ip);
}

int Sync::_recvMessage(MessageLite& m){
	char buffer[255] = {0};

	if (_udp_con.recvData(buffer, 255) < 0){
		return _udp_con.getLastErrno();
	}

	int msg_len = buffer[0];

	m.ParseFromArray(&buffer[1], msg_len);

	return 0;
}

void Sync::__berkleyAlgorithm(){
	if (_is_leader){
		//send broadcast

		// wait for responses

		//average all clock times

		//send offset
	} else {
		// wait for broadcast

		//send time

		//wait for offset

		// adjust time
	}
}

void Sync::_threadHandle(){
	SyncMessage sm;

	//wait until instance is connected
	while (!_running);

	while (_running){
		// TODO implement message queue from sync to server
		_recvMessage(sm);

		if (sm.type() == SyncMessage_Type_SYNC){

		} else if (sm.type() == SyncMessage_Type_ELECTION) {
			sm.set_type(SyncMessage_Type_ELECTION);
			sm.set_leader(_is_leader);
			_sendMessage(sm, _udp_con.getIPFromLastSender());
		} else {
			LOG_WARNING << "Unknown SyncMessage type " << sm.type() << endl;
		}

		//__berkleyAlgorithm();
	}

	LOG_DEBUG << "leaving _threadHandle" << endl;
}
<commit_msg>add debug message for election process<commit_after>#include "Sync.h"

#include <iostream>

#include "../gen/SyncMessage.pb.h"
#include "Logger.h"

Sync::Sync()
	: _udp_con(CONNECTION_PORT)
	, _running(false)
	, _sync_thread(&Sync::_threadHandle, this)
	, _is_leader(false) {}

Sync::~Sync(){
	_running = false;
	_udp_con.closeConnection();
	_sync_thread.join();
}

int Sync::connect(){
	SyncMessage sm;
	int timeout = 10000;
	int found_leader = 0;

	_udp_con.createConnection(CLIENT, -1, "");
	_udp_con.enableBroadcast();
	_udp_con.setRecvTimout(timeout);

	sm.set_type(SyncMessage_Type_ELECTION);
	sm.set_leader(false);
	_sendMessage(sm, BROADCAST_IP);

	while (1){
		if (_recvMessage(sm) != 0){
			//timout
			LOG_DEBUG << "Election timeout" << endl;
			if (found_leader == 0){
				_is_leader = true;
				LOG_DEBUG << "I am the new leader" << endl;
			}
			break;
		} else {
			// TODO save ips in list
			LOG_DEBUG << "Received election message from "
				<< _udp_con.getIPFromLastSender() << ", Leader = "
				<< sm.leader() << endl;
			if (sm.type() == SyncMessage_Type_ELECTION && sm.leader()){
				found_leader = 1;
			}
		}
	}

	_running = true;

	return found_leader;
}

void Sync::getTime(uint64_t* t){
	struct timespec tv;

	clock_gettime(CLOCK_REALTIME, &tv);

	t[0] = (uint64_t) tv.tv_sec;
	t[1] = (uint64_t) tv.tv_nsec;
}

void Sync::_setTime(int64_t offset_sec, int64_t offset_nsec){
	struct timespec t;
	if(clock_gettime(CLOCK_REALTIME, &t) == -1){
		cout << "settime error: " << strerror(errno) << endl;
	}

	t.tv_sec += offset_sec;
	t.tv_nsec += offset_nsec;

	if(clock_settime(CLOCK_REALTIME, &t) == -1){
		cout << "settime error: " << strerror(errno) << endl;
	}
}

void Sync::_sendMessage(MessageLite& m, string ip){
	if (m.ByteSize() > 254){
		LOG_WARNING << "serialized SyncMessage length exceeded 254 Bytes ("
			<< m.ByteSize() << ")" << endl;
		return;
	}

	char size = m.ByteSize();
	char buffer[255] = {0};

	m.SerializeToArray(&buffer[1], 254);
	buffer[0] = size;

	_udp_con.sendData(buffer, 255, ip);
}

int Sync::_recvMessage(MessageLite& m){
	char buffer[255] = {0};

	if (_udp_con.recvData(buffer, 255) < 0){
		return _udp_con.getLastErrno();
	}

	int msg_len = buffer[0];

	m.ParseFromArray(&buffer[1], msg_len);

	return 0;
}

void Sync::__berkleyAlgorithm(){
	if (_is_leader){
		//send broadcast

		// wait for responses

		//average all clock times

		//send offset
	} else {
		// wait for broadcast

		//send time

		//wait for offset

		// adjust time
	}
}

void Sync::_threadHandle(){
	SyncMessage sm;

	//wait until instance is connected
	while (!_running);

	while (_running){
		// TODO implement message queue from sync to server
		_recvMessage(sm);

		if (sm.type() == SyncMessage_Type_SYNC){

		} else if (sm.type() == SyncMessage_Type_ELECTION) {
			sm.set_type(SyncMessage_Type_ELECTION);
			sm.set_leader(_is_leader);
			_sendMessage(sm, _udp_con.getIPFromLastSender());
		} else {
			LOG_WARNING << "Unknown SyncMessage type " << sm.type() << endl;
		}

		//__berkleyAlgorithm();
	}

	LOG_DEBUG << "leaving _threadHandle" << endl;
}
<|endoftext|>


<commit_before>#include "Text.hpp"
#include <iostream>
#include <Engine/util/json.hpp>

namespace engine {
	Text::Text(Scene* scene) : Node(scene), m_align(ALIGN_LEFT) {
	}

	Text::~Text() {
	}

	void Text::SetText(std::string text) {
		m_text.setString(text);
		switch (m_align) {
			case ALIGN_LEFT:
				m_text.setOrigin(0, 0);
				break;
			case ALIGN_RIGHT:
				m_text.setOrigin(m_text.getGlobalBounds().width, 0);
				break;
			case ALIGN_CENTER:
				m_text.setOrigin(m_text.getGlobalBounds().width / 2, 0);
				break;
			default:
				std::cerr << "Unknown alignment (" << m_align << ")" << std::endl;
		}
	}

	void Text::OnDraw(sf::RenderTarget& target, sf::RenderStates states, float delta) {
		target.draw(m_text, states);
	}

	bool Text::initialize(Json::Value& root) {
		if (!Node::initialize(root)) {
			return false;
		}
		auto text = root["text"];
		if (text.isObject()) {
			m_font.loadFromFile(text.get("font", "").asString());
			m_text.setFont(m_font);
			m_text.setCharacterSize(text.get("size", 30).asInt());
			m_text.setColor(jsonNodeAs<sf::Color>(text["color"]));
			auto align = text["align"];
			if (align.isString()) {
				const std::string& a = align.asString();
				if (a == "left") {
					m_align = ALIGN_LEFT;
				} else if (a == "center") {
					m_align = ALIGN_CENTER;
				} else if (a == "right") {
					m_align = ALIGN_RIGHT;
				}
			}
			uint32_t style = 0;
			if (text.get("bold", false).asBool()) {
				style |= sf::Text::Bold;
			}
			if (text.get("italic", false).asBool()) {
				style |= sf::Text::Italic;
			}
			if (text.get("underlined", false).asBool()) {
				style |= sf::Text::Underlined;
			}
			if (text.get("strikethrough", false).asBool()) {
				style |= sf::Text::StrikeThrough;
			}
			m_text.setStyle(style);
			SetText(text.get("text", "").asString());
		}
		return true;
	}
}

<commit_msg>Proper type<commit_after>#include "Text.hpp"
#include <iostream>
#include <Engine/util/json.hpp>

namespace engine {
	Text::Text(Scene* scene) : Node(scene), m_align(ALIGN_LEFT) {
	}

	Text::~Text() {
	}

	void Text::SetText(std::string text) {
		m_text.setString(text);
		switch (m_align) {
			case ALIGN_LEFT:
				m_text.setOrigin(0, 0);
				break;
			case ALIGN_RIGHT:
				m_text.setOrigin(m_text.getGlobalBounds().width, 0);
				break;
			case ALIGN_CENTER:
				m_text.setOrigin(m_text.getGlobalBounds().width / 2, 0);
				break;
			default:
				std::cerr << "Unknown alignment (" << m_align << ")" << std::endl;
		}
	}

	void Text::OnDraw(sf::RenderTarget& target, sf::RenderStates states, float delta) {
		target.draw(m_text, states);
	}

	bool Text::initialize(Json::Value& root) {
		if (!Node::initialize(root)) {
			return false;
		}
		auto text = root["text"];
		if (text.isObject()) {
			m_font.loadFromFile(text.get("font", "").asString());
			m_text.setFont(m_font);
			m_text.setCharacterSize(text.get("size", 30).asUInt());
			m_text.setColor(jsonNodeAs<sf::Color>(text["color"]));
			auto align = text["align"];
			if (align.isString()) {
				const std::string& a = align.asString();
				if (a == "left") {
					m_align = ALIGN_LEFT;
				} else if (a == "center") {
					m_align = ALIGN_CENTER;
				} else if (a == "right") {
					m_align = ALIGN_RIGHT;
				}
			}
			uint32_t style = 0;
			if (text.get("bold", false).asBool()) {
				style |= sf::Text::Bold;
			}
			if (text.get("italic", false).asBool()) {
				style |= sf::Text::Italic;
			}
			if (text.get("underlined", false).asBool()) {
				style |= sf::Text::Underlined;
			}
			if (text.get("strikethrough", false).asBool()) {
				style |= sf::Text::StrikeThrough;
			}
			m_text.setStyle(style);
			SetText(text.get("text", "").asString());
		}
		return true;
	}
}

<|endoftext|>


<commit_before>
#include <libclientserver.h>

/**
 * Sleep
 * @param[in] Timeout The total length of time to sleep for
 */
void Time::Sleep(const struct timespec *Timeout)
{
	struct timespec ts;
	struct timespec rem;
	memcpy(&ts, Timeout, sizeof(ts));

restart:
	int ret = nanosleep(&ts, &rem);
	if (ret < 0)
	{
		switch(errno)
		{
			case EINTR:
				memcpy(&ts, &rem, sizeof(ts));
				goto restart;
				break;
			default:
				abort();
				break;
		}
	}
}

/**
 * Sleep
 * @param[in] Timeout The total length of time to sleep for
 */
void Time::Sleep(const struct timeval *Timeout)
{
	struct timespec ts;
	TimeValtoTimeSpec(Timeout, &ts);
	Sleep(Timeout);
}

/**
 * TimeSpecToTimeVal
 * @param[in] ts Source Value
 * @param[out] tv Output Value
 *
 * Convert the input timespec to a timeval structure.
 */
void Time::TimeSpecToTimeVal(const struct timespec *ts, struct timeval *tv)
{
	tv->tv_sec = ts->tv_sec;
	tv->tv_usec = ts->tv_nsec / 1000;
}

/**
 * TimeValtoTimeSpec
 * @param[in] tv Source Value
 * @param[out] ts Output Value
 *
 * Convert the input timeval to a timespec structure.
 */
void Time::TimeValtoTimeSpec(const struct timeval *tv, struct timespec *ts)
{
	ts->tv_sec = tv->tv_sec;
	ts->tv_nsec = tv->tv_usec * 1000;
}

/**
 * Add
 * @param[in] ts1 First Input Value
 * @param[in] ts2 Second Input Value
 * @param[out] res Output Value
 *
 * Add two timespec struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Add(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	res->tv_sec = ts1->tv_sec + ts2->tv_sec;
	res->tv_nsec = ts1->tv_nsec + ts2->tv_nsec;
	if (res->tv_nsec > 999999999)
	{
		res->tv_sec++;
		res->tv_nsec -= 1000000000;
	}
}

/**
 * Add
 * @param[in] tv1 First Input Value
 * @param[in] tv2 Second Input Value
 * @param[out] res Output Value
 *
 * Add two timeval struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Add(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	res->tv_sec = tv1->tv_sec + tv2->tv_sec;
	res->tv_usec = tv1->tv_usec + tv2->tv_usec;
	if (res->tv_usec > 999999)
	{
		res->tv_sec++;
		res->tv_usec -= 1000000;
	}
}

/**
 * Sub
 * @param[in] ts1 First Input Value
 * @param[in] ts2 Second Input Value
 * @param[out] res Output Value
 *
 * Subtrace two timespec struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Sub(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	res->tv_sec = ts1->tv_sec - ts2->tv_sec;
	res->tv_nsec = ts2->tv_nsec - ts2->tv_nsec;
	if (res->tv_nsec < 0)
	{
		res->tv_sec--;
		res->tv_nsec += 1000000000;
	}
}

/**
 * Sub
 * @param[in] tv1 First Input Value
 * @param[in] tv2 Second Input Value
 * @param[out] res Output Value
 *
 * Subtract two timeval struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Sub(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	res->tv_sec = tv1->tv_sec - tv2->tv_sec;
	res->tv_usec = tv2->tv_usec - tv2->tv_usec;
	if (res->tv_usec < 0)
	{
		res->tv_sec--;
		res->tv_usec += 1000000;
	}
}

/**
 * Diff
 * @param[in] ts1 Input One
 * @param[in] ts2 Input Two
 * @param[out] res Output the difference
 *
 * This will calculate the difference between two times. The value outputted will always be a positive value regardless of the order of ts1 and ts2
 */
void Time::Diff(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	if (IsGreater(ts1, ts2))
	{
		Sub(ts2, ts1, res);
	}
	else
	{
		Sub(ts2, ts1, res);
	}
}

/**
 * Diff
 * @param[in] tv1 Input One
 * @param[in] tv2 Input Two
 * @param[out] res Output the difference
 *
 * This will calculate the difference between two times. The value outputted will always be a positive value regardless of the order of ts1 and ts2
 */
void Time::Diff(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	if (IsGreater(tv1, tv2))
	{
		Sub(tv2, tv1, res);
	}
	else
	{
		Sub(tv2, tv1, res);
	}
}

/**
 * IsLess
 * @param[in] ts1
 * @param[in] ts2
 * @return True if ts1 is less than ts2
 *
 * Returns true if the values in ts1 is less than the value in ts2
 */
bool Time::IsLess(const struct timespec *ts1, const struct timespec *ts2)
{
	if (ts1->tv_sec < ts2->tv_sec)
		return true;
	if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec < ts2->tv_nsec)
		return true;
	return false;
}

/**
 * IsLess
 * @param[in] tv1
 * @param[in] tv2
 * @return True if tv1 is less than tv2
 *
 * Returns true if the values in tv1 is less than the value in tv2
 */
bool Time::IsLess(const struct timeval *tv1, const struct timeval *tv2)
{
	if (tv1->tv_sec < tv2->tv_sec)
		return true;
	if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec < tv2->tv_usec)
		return true;
	return false;
}

/**
 * IsGreater
 * @param[in] ts1
 * @param[in] ts2
 * @return True if ts1 is greater than ts2
 *
 * Returns true if the values in ts1 is greater than the value in ts2
 */
bool Time::IsGreater(const struct timespec *ts1, const struct timespec *ts2)
{
	if (ts1->tv_sec > ts2->tv_sec)
		return true;
	if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec > ts2->tv_nsec)
		return true;
	return false;
}

/**
 * IsGreater
 * @param[in] tv1
 * @param[in] tv2
 * @return True if tv1 is greater than tv2
 *
 * Returns true if the values in tv1 is greater than the value in tv2
 */
bool Time::IsGreater(const struct timeval *tv1, const struct timeval *tv2)
{
	if (tv1->tv_sec > tv2->tv_sec)
		return true;
	if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec)
		return true;
	return false;

}

<commit_msg>Fixed Bug in Time subtract<commit_after>
#include <libclientserver.h>

/**
 * Sleep
 * @param[in] Timeout The total length of time to sleep for
 */
void Time::Sleep(const struct timespec *Timeout)
{
	struct timespec ts;
	struct timespec rem;
	memcpy(&ts, Timeout, sizeof(ts));

restart:
	int ret = nanosleep(&ts, &rem);
	if (ret < 0)
	{
		switch(errno)
		{
			case EINTR:
				memcpy(&ts, &rem, sizeof(ts));
				goto restart;
				break;
			default:
				abort();
				break;
		}
	}
}

/**
 * Sleep
 * @param[in] Timeout The total length of time to sleep for
 */
void Time::Sleep(const struct timeval *Timeout)
{
	struct timespec ts;
	TimeValtoTimeSpec(Timeout, &ts);
	Sleep(Timeout);
}

/**
 * TimeSpecToTimeVal
 * @param[in] ts Source Value
 * @param[out] tv Output Value
 *
 * Convert the input timespec to a timeval structure.
 */
void Time::TimeSpecToTimeVal(const struct timespec *ts, struct timeval *tv)
{
	tv->tv_sec = ts->tv_sec;
	tv->tv_usec = ts->tv_nsec / 1000;
}

/**
 * TimeValtoTimeSpec
 * @param[in] tv Source Value
 * @param[out] ts Output Value
 *
 * Convert the input timeval to a timespec structure.
 */
void Time::TimeValtoTimeSpec(const struct timeval *tv, struct timespec *ts)
{
	ts->tv_sec = tv->tv_sec;
	ts->tv_nsec = tv->tv_usec * 1000;
}

/**
 * Add
 * @param[in] ts1 First Input Value
 * @param[in] ts2 Second Input Value
 * @param[out] res Output Value
 *
 * Add two timespec struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Add(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	res->tv_sec = ts1->tv_sec + ts2->tv_sec;
	res->tv_nsec = ts1->tv_nsec + ts2->tv_nsec;
	if (res->tv_nsec > 999999999)
	{
		res->tv_sec++;
		res->tv_nsec -= 1000000000;
	}
}

/**
 * Add
 * @param[in] tv1 First Input Value
 * @param[in] tv2 Second Input Value
 * @param[out] res Output Value
 *
 * Add two timeval struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Add(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	res->tv_sec = tv1->tv_sec + tv2->tv_sec;
	res->tv_usec = tv1->tv_usec + tv2->tv_usec;
	if (res->tv_usec > 999999)
	{
		res->tv_sec++;
		res->tv_usec -= 1000000;
	}
}

/**
 * Sub
 * @param[in] ts1 First Input Value
 * @param[in] ts2 Second Input Value
 * @param[out] res Output Value
 *
 * Subtrace two timespec struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Sub(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	res->tv_sec = ts1->tv_sec - ts2->tv_sec;
	res->tv_nsec = ts1->tv_nsec - ts2->tv_nsec;
	if (res->tv_nsec < 0)
	{
		res->tv_sec--;
		res->tv_nsec += 1000000000;
	}
}

/**
 * Sub
 * @param[in] tv1 First Input Value
 * @param[in] tv2 Second Input Value
 * @param[out] res Output Value
 *
 * Subtract two timeval struct together to form the output.
 * It is safe to have the output specificed as the same address as either of the two input structures.
 */
void Time::Sub(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	res->tv_sec = tv1->tv_sec - tv2->tv_sec;
	res->tv_usec = tv1->tv_usec - tv2->tv_usec;
	if (res->tv_usec < 0)
	{
		res->tv_sec--;
		res->tv_usec += 1000000;
	}
}

/**
 * Diff
 * @param[in] ts1 Input One
 * @param[in] ts2 Input Two
 * @param[out] res Output the difference
 *
 * This will calculate the difference between two times. The value outputted will always be a positive value regardless of the order of ts1 and ts2
 */
void Time::Diff(const struct timespec *ts1, const struct timespec *ts2, struct timespec *res)
{
	if (IsGreater(ts1, ts2))
	{
		Sub(ts2, ts1, res);
	}
	else
	{
		Sub(ts2, ts1, res);
	}
}

/**
 * Diff
 * @param[in] tv1 Input One
 * @param[in] tv2 Input Two
 * @param[out] res Output the difference
 *
 * This will calculate the difference between two times. The value outputted will always be a positive value regardless of the order of ts1 and ts2
 */
void Time::Diff(const struct timeval *tv1, const struct timeval *tv2, struct timeval *res)
{
	if (IsGreater(tv1, tv2))
	{
		Sub(tv2, tv1, res);
	}
	else
	{
		Sub(tv2, tv1, res);
	}
}

/**
 * IsLess
 * @param[in] ts1
 * @param[in] ts2
 * @return True if ts1 is less than ts2
 *
 * Returns true if the values in ts1 is less than the value in ts2
 */
bool Time::IsLess(const struct timespec *ts1, const struct timespec *ts2)
{
	if (ts1->tv_sec < ts2->tv_sec)
		return true;
	if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec < ts2->tv_nsec)
		return true;
	return false;
}

/**
 * IsLess
 * @param[in] tv1
 * @param[in] tv2
 * @return True if tv1 is less than tv2
 *
 * Returns true if the values in tv1 is less than the value in tv2
 */
bool Time::IsLess(const struct timeval *tv1, const struct timeval *tv2)
{
	if (tv1->tv_sec < tv2->tv_sec)
		return true;
	if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec < tv2->tv_usec)
		return true;
	return false;
}

/**
 * IsGreater
 * @param[in] ts1
 * @param[in] ts2
 * @return True if ts1 is greater than ts2
 *
 * Returns true if the values in ts1 is greater than the value in ts2
 */
bool Time::IsGreater(const struct timespec *ts1, const struct timespec *ts2)
{
	if (ts1->tv_sec > ts2->tv_sec)
		return true;
	if (ts1->tv_sec == ts2->tv_sec && ts1->tv_nsec > ts2->tv_nsec)
		return true;
	return false;
}

/**
 * IsGreater
 * @param[in] tv1
 * @param[in] tv2
 * @return True if tv1 is greater than tv2
 *
 * Returns true if the values in tv1 is greater than the value in tv2
 */
bool Time::IsGreater(const struct timeval *tv1, const struct timeval *tv2)
{
	if (tv1->tv_sec > tv2->tv_sec)
		return true;
	if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec)
		return true;
	return false;

}

<|endoftext|>