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

#include <assert.h>
#include <stdlib.h>

#include "trace_file.hpp"
#include "trace_snappyfile.hpp"
#include "trace_parser.hpp"

#define TRACE_VERBOSE 0

namespace Trace {

Parser::Parser() {
    file = NULL;
    next_call_no = 0;
    version = 0;
}

Parser::~Parser() {
    close();
}

bool Parser::open(const char *filename) {
    assert(!file);
    if (File::isZLibCompressed(filename)) {
        file = new ZLibFile;
    } else {
        file = new SnappyFile;
    }

    if (!file->open(filename, File::Read)) {
        return false;
    }

    version = read_uint();
    if (version > TRACE_VERSION) {
        std::cerr << "error: unsupported trace format version " << version << "\n";
        return false;
    }

    return true;
}

template <typename Iter>
inline void
deleteAll(Iter begin, Iter end)
{
    while (begin != end) {
        delete *begin;
        ++begin;
    }
}

template <typename Container>
inline void
deleteAll(const Container &c)
{
    deleteAll(c.begin(), c.end());
}

void Parser::close(void) {
    if (file) {
        file->close();
        delete file;
        file = NULL;
    }

    deleteAll(calls);
    deleteAll(functions);
    deleteAll(structs);
    deleteAll(enums);
    deleteAll(bitmasks);
}

Call *Parser::parse_call(void) {
    do {
        int c = read_byte();
        switch(c) {
        case Trace::EVENT_ENTER:
            parse_enter();
            break;
        case Trace::EVENT_LEAVE:
            return parse_leave();
        default:
            std::cerr << "error: unknown event " << c << "\n";
            exit(1);
        case -1:
            for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
                std::cerr << "warning: incomplete call " << (*it)->name() << "\n";
                std::cerr << **it << "\n";
            }
            return NULL;
        }
    } while(true);
}

/**
 * Helper function to lookup an ID in a vector, resizing the vector if it doesn't fit.
 */
template<class T>
T *lookup(std::vector<T *> &map, size_t index) {
    if (index >= map.size()) {
        map.resize(index + 1);
        return NULL;
    } else {
        return map[index];
    }
}

void Parser::parse_enter(void) {
    size_t id = read_uint();

    FunctionSig *sig = lookup(functions, id);
    if (!sig) {
        sig = new FunctionSig;
        sig->id = id;
        sig->name = read_string();
        sig->num_args = read_uint();
        const char **arg_names = new const char *[sig->num_args];
        for (unsigned i = 0; i < sig->num_args; ++i) {
            arg_names[i] = read_string();
        }
        sig->arg_names = arg_names;
        functions[id] = sig;
    }
    assert(sig);

    Call *call = new Call(sig);
    call->no = next_call_no++;

    if (parse_call_details(call)) {
        calls.push_back(call);
    } else {
        delete call;
    }
}

Call *Parser::parse_leave(void) {
    unsigned call_no = read_uint();
    Call *call = NULL;
    for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
        if ((*it)->no == call_no) {
            call = *it;
            calls.erase(it);
            break;
        }
    }
    if (!call) {
        return NULL;
    }

    if (parse_call_details(call)) {
        return call;
    } else {
        delete call;
        return NULL;
    }
}

bool Parser::parse_call_details(Call *call) {
    do {
        int c = read_byte();
        switch(c) {
        case Trace::CALL_END:
            return true;
        case Trace::CALL_ARG:
            parse_arg(call);
            break;
        case Trace::CALL_RET:
            call->ret = parse_value();
            break;
        default:
            std::cerr << "error: ("<<call->name()<< ") unknown call detail "
                      << c << "\n";
            exit(1);
        case -1:
            return false;
        }
    } while(true);
}

void Parser::parse_arg(Call *call) {
    unsigned index = read_uint();
    Value *value = parse_value();
    if (index >= call->args.size()) {
        call->args.resize(index + 1);
    }
    call->args[index] = value;
}

Value *Parser::parse_value(void) {
    int c;
    Value *value;
    c = read_byte();
    switch(c) {
    case Trace::TYPE_NULL:
        value = new Null;
        break;
    case Trace::TYPE_FALSE:
        value = new Bool(false);
        break;
    case Trace::TYPE_TRUE:
        value = new Bool(true);
        break;
    case Trace::TYPE_SINT:
        value = parse_sint();
        break;
    case Trace::TYPE_UINT:
        value = parse_uint();
        break;
    case Trace::TYPE_FLOAT:
        value = parse_float();
        break;
    case Trace::TYPE_DOUBLE:
        value = parse_double();
        break;
    case Trace::TYPE_STRING:
        value = parse_string();
        break;
    case Trace::TYPE_ENUM:
        value = parse_enum();
        break;
    case Trace::TYPE_BITMASK:
        value = parse_bitmask();
        break;
    case Trace::TYPE_ARRAY:
        value = parse_array();
        break;
    case Trace::TYPE_STRUCT:
        value = parse_struct();
        break;
    case Trace::TYPE_BLOB:
        value = parse_blob();
        break;
    case Trace::TYPE_OPAQUE:
        value = parse_opaque();
        break;
    default:
        std::cerr << "error: unknown type " << c << "\n";
        exit(1);
    case -1:
        value = NULL;
        break;
    }
#if TRACE_VERBOSE
    if (value) {
        std::cerr << "\tVALUE " << value << "\n";
    }
#endif
    return value;
}

Value *Parser::parse_sint() {
    return new SInt(-(signed long long)read_uint());
}

Value *Parser::parse_uint() {
    return new UInt(read_uint());
}

Value *Parser::parse_float() {
    float value;
    file->read(&value, sizeof value);
    return new Float(value);
}

Value *Parser::parse_double() {
    double value;
    file->read(&value, sizeof value);
    return new Float(value);
}

Value *Parser::parse_string() {
    return new String(read_string());
}

Value *Parser::parse_enum() {
    size_t id = read_uint();
    EnumSig *sig = lookup(enums, id);
    if (!sig) {
        sig = new EnumSig;
        sig->id = id;
        sig->name = read_string();
        Value *value = parse_value();
        sig->value = value->toSInt();
        delete value;
        enums[id] = sig;
    }
    assert(sig);
    return new Enum(sig);
}

Value *Parser::parse_bitmask() {
    size_t id = read_uint();
    BitmaskSig *sig = lookup(bitmasks, id);
    if (!sig) {
        sig = new BitmaskSig;
        sig->id = id;
        sig->num_flags = read_uint();
        BitmaskFlag *flags = new BitmaskFlag[sig->num_flags];
        for (BitmaskFlag *it = flags; it != flags + sig->num_flags; ++it) {
            it->name = read_string();
            it->value = read_uint();
            if (it->value == 0 && it != flags) {
                std::cerr << "warning: bitmask " << it->name << " is zero but is not first flag\n";
            }
        }
        sig->flags = flags;
        bitmasks[id] = sig;
    }
    assert(sig);

    unsigned long long value = read_uint();

    return new Bitmask(sig, value);
}

Value *Parser::parse_array(void) {
    size_t len = read_uint();
    Array *array = new Array(len);
    for (size_t i = 0; i < len; ++i) {
        array->values[i] = parse_value();
    }
    return array;
}

Value *Parser::parse_blob(void) {
    size_t size = read_uint();
    Blob *blob = new Blob(size);
    if (size) {
        file->read(blob->buf, (unsigned)size);
    }
    return blob;
}

Value *Parser::parse_struct() {
    size_t id = read_uint();

    StructSig *sig = lookup(structs, id);
    if (!sig) {
        sig = new StructSig;
        sig->id = id;
        sig->name = read_string();
        sig->num_members = read_uint();
        const char **member_names = new const char *[sig->num_members];
        for (unsigned i = 0; i < sig->num_members; ++i) {
            member_names[i] = read_string();
        }
        sig->member_names = member_names;
        structs[id] = sig;
    }
    assert(sig);

    Struct *value = new Struct(sig);

    for (size_t i = 0; i < sig->num_members; ++i) {
        value->members[i] = parse_value();
    }

    return value;
}

Value *Parser::parse_opaque() {
    unsigned long long addr;
    addr = read_uint();
    return new Pointer(addr);
}

const char * Parser::read_string(void) {
    size_t len = read_uint();
    char * value = new char[len + 1];
    if (len) {
        file->read(value, (unsigned)len);
    }
    value[len] = 0;
#if TRACE_VERBOSE
    std::cerr << "\tSTRING \"" << value << "\"\n";
#endif
    return value;
}

unsigned long long Parser::read_uint(void) {
    unsigned long long value = 0;
    int c;
    unsigned shift = 0;
    do {
        c = file->getc();
        if (c == -1) {
            break;
        }
        value |= (unsigned long long)(c & 0x7f) << shift;
        shift += 7;
    } while(c & 0x80);
#if TRACE_VERBOSE
    std::cerr << "\tUINT " << value << "\n";
#endif
    return value;
}

inline int Parser::read_byte(void) {
    int c = file->getc();
#if TRACE_VERBOSE
    if (c < 0)
        std::cerr << "\tEOF" << "\n";
    else
        std::cerr << "\tBYTE 0x" << std::hex << c << std::dec << "\n";
#endif
    return c;
}

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

#include <assert.h>
#include <stdlib.h>

#include "trace_file.hpp"
#include "trace_snappyfile.hpp"
#include "trace_parser.hpp"

#define TRACE_VERBOSE 0

namespace Trace {

Parser::Parser() {
    file = NULL;
    next_call_no = 0;
    version = 0;
}

Parser::~Parser() {
    close();
}

bool Parser::open(const char *filename) {
    assert(!file);
    if (File::isZLibCompressed(filename)) {
        file = new ZLibFile;
    } else {
        file = new SnappyFile;
    }

    if (!file->open(filename, File::Read)) {
        return false;
    }

    version = read_uint();
    if (version > TRACE_VERSION) {
        std::cerr << "error: unsupported trace format version " << version << "\n";
        return false;
    }

    return true;
}

template <typename Iter>
inline void
deleteAll(Iter begin, Iter end)
{
    while (begin != end) {
        delete *begin;
        ++begin;
    }
}

template <typename Container>
inline void
deleteAll(Container &c)
{
    deleteAll(c.begin(), c.end());
    c.clear();
}

void Parser::close(void) {
    if (file) {
        file->close();
        delete file;
        file = NULL;
    }

    deleteAll(calls);
    deleteAll(functions);
    deleteAll(structs);
    deleteAll(enums);
    deleteAll(bitmasks);
}

Call *Parser::parse_call(void) {
    do {
        int c = read_byte();
        switch(c) {
        case Trace::EVENT_ENTER:
            parse_enter();
            break;
        case Trace::EVENT_LEAVE:
            return parse_leave();
        default:
            std::cerr << "error: unknown event " << c << "\n";
            exit(1);
        case -1:
            for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
                std::cerr << "warning: incomplete call " << (*it)->name() << "\n";
                std::cerr << **it << "\n";
            }
            return NULL;
        }
    } while(true);
}

/**
 * Helper function to lookup an ID in a vector, resizing the vector if it doesn't fit.
 */
template<class T>
T *lookup(std::vector<T *> &map, size_t index) {
    if (index >= map.size()) {
        map.resize(index + 1);
        return NULL;
    } else {
        return map[index];
    }
}

void Parser::parse_enter(void) {
    size_t id = read_uint();

    FunctionSig *sig = lookup(functions, id);
    if (!sig) {
        sig = new FunctionSig;
        sig->id = id;
        sig->name = read_string();
        sig->num_args = read_uint();
        const char **arg_names = new const char *[sig->num_args];
        for (unsigned i = 0; i < sig->num_args; ++i) {
            arg_names[i] = read_string();
        }
        sig->arg_names = arg_names;
        functions[id] = sig;
    }
    assert(sig);

    Call *call = new Call(sig);
    call->no = next_call_no++;

    if (parse_call_details(call)) {
        calls.push_back(call);
    } else {
        delete call;
    }
}

Call *Parser::parse_leave(void) {
    unsigned call_no = read_uint();
    Call *call = NULL;
    for (CallList::iterator it = calls.begin(); it != calls.end(); ++it) {
        if ((*it)->no == call_no) {
            call = *it;
            calls.erase(it);
            break;
        }
    }
    if (!call) {
        return NULL;
    }

    if (parse_call_details(call)) {
        return call;
    } else {
        delete call;
        return NULL;
    }
}

bool Parser::parse_call_details(Call *call) {
    do {
        int c = read_byte();
        switch(c) {
        case Trace::CALL_END:
            return true;
        case Trace::CALL_ARG:
            parse_arg(call);
            break;
        case Trace::CALL_RET:
            call->ret = parse_value();
            break;
        default:
            std::cerr << "error: ("<<call->name()<< ") unknown call detail "
                      << c << "\n";
            exit(1);
        case -1:
            return false;
        }
    } while(true);
}

void Parser::parse_arg(Call *call) {
    unsigned index = read_uint();
    Value *value = parse_value();
    if (index >= call->args.size()) {
        call->args.resize(index + 1);
    }
    call->args[index] = value;
}

Value *Parser::parse_value(void) {
    int c;
    Value *value;
    c = read_byte();
    switch(c) {
    case Trace::TYPE_NULL:
        value = new Null;
        break;
    case Trace::TYPE_FALSE:
        value = new Bool(false);
        break;
    case Trace::TYPE_TRUE:
        value = new Bool(true);
        break;
    case Trace::TYPE_SINT:
        value = parse_sint();
        break;
    case Trace::TYPE_UINT:
        value = parse_uint();
        break;
    case Trace::TYPE_FLOAT:
        value = parse_float();
        break;
    case Trace::TYPE_DOUBLE:
        value = parse_double();
        break;
    case Trace::TYPE_STRING:
        value = parse_string();
        break;
    case Trace::TYPE_ENUM:
        value = parse_enum();
        break;
    case Trace::TYPE_BITMASK:
        value = parse_bitmask();
        break;
    case Trace::TYPE_ARRAY:
        value = parse_array();
        break;
    case Trace::TYPE_STRUCT:
        value = parse_struct();
        break;
    case Trace::TYPE_BLOB:
        value = parse_blob();
        break;
    case Trace::TYPE_OPAQUE:
        value = parse_opaque();
        break;
    default:
        std::cerr << "error: unknown type " << c << "\n";
        exit(1);
    case -1:
        value = NULL;
        break;
    }
#if TRACE_VERBOSE
    if (value) {
        std::cerr << "\tVALUE " << value << "\n";
    }
#endif
    return value;
}

Value *Parser::parse_sint() {
    return new SInt(-(signed long long)read_uint());
}

Value *Parser::parse_uint() {
    return new UInt(read_uint());
}

Value *Parser::parse_float() {
    float value;
    file->read(&value, sizeof value);
    return new Float(value);
}

Value *Parser::parse_double() {
    double value;
    file->read(&value, sizeof value);
    return new Float(value);
}

Value *Parser::parse_string() {
    return new String(read_string());
}

Value *Parser::parse_enum() {
    size_t id = read_uint();
    EnumSig *sig = lookup(enums, id);
    if (!sig) {
        sig = new EnumSig;
        sig->id = id;
        sig->name = read_string();
        Value *value = parse_value();
        sig->value = value->toSInt();
        delete value;
        enums[id] = sig;
    }
    assert(sig);
    return new Enum(sig);
}

Value *Parser::parse_bitmask() {
    size_t id = read_uint();
    BitmaskSig *sig = lookup(bitmasks, id);
    if (!sig) {
        sig = new BitmaskSig;
        sig->id = id;
        sig->num_flags = read_uint();
        BitmaskFlag *flags = new BitmaskFlag[sig->num_flags];
        for (BitmaskFlag *it = flags; it != flags + sig->num_flags; ++it) {
            it->name = read_string();
            it->value = read_uint();
            if (it->value == 0 && it != flags) {
                std::cerr << "warning: bitmask " << it->name << " is zero but is not first flag\n";
            }
        }
        sig->flags = flags;
        bitmasks[id] = sig;
    }
    assert(sig);

    unsigned long long value = read_uint();

    return new Bitmask(sig, value);
}

Value *Parser::parse_array(void) {
    size_t len = read_uint();
    Array *array = new Array(len);
    for (size_t i = 0; i < len; ++i) {
        array->values[i] = parse_value();
    }
    return array;
}

Value *Parser::parse_blob(void) {
    size_t size = read_uint();
    Blob *blob = new Blob(size);
    if (size) {
        file->read(blob->buf, (unsigned)size);
    }
    return blob;
}

Value *Parser::parse_struct() {
    size_t id = read_uint();

    StructSig *sig = lookup(structs, id);
    if (!sig) {
        sig = new StructSig;
        sig->id = id;
        sig->name = read_string();
        sig->num_members = read_uint();
        const char **member_names = new const char *[sig->num_members];
        for (unsigned i = 0; i < sig->num_members; ++i) {
            member_names[i] = read_string();
        }
        sig->member_names = member_names;
        structs[id] = sig;
    }
    assert(sig);

    Struct *value = new Struct(sig);

    for (size_t i = 0; i < sig->num_members; ++i) {
        value->members[i] = parse_value();
    }

    return value;
}

Value *Parser::parse_opaque() {
    unsigned long long addr;
    addr = read_uint();
    return new Pointer(addr);
}

const char * Parser::read_string(void) {
    size_t len = read_uint();
    char * value = new char[len + 1];
    if (len) {
        file->read(value, (unsigned)len);
    }
    value[len] = 0;
#if TRACE_VERBOSE
    std::cerr << "\tSTRING \"" << value << "\"\n";
#endif
    return value;
}

unsigned long long Parser::read_uint(void) {
    unsigned long long value = 0;
    int c;
    unsigned shift = 0;
    do {
        c = file->getc();
        if (c == -1) {
            break;
        }
        value |= (unsigned long long)(c & 0x7f) << shift;
        shift += 7;
    } while(c & 0x80);
#if TRACE_VERBOSE
    std::cerr << "\tUINT " << value << "\n";
#endif
    return value;
}

inline int Parser::read_byte(void) {
    int c = file->getc();
#if TRACE_VERBOSE
    if (c < 0)
        std::cerr << "\tEOF" << "\n";
    else
        std::cerr << "\tBYTE 0x" << std::hex << c << std::dec << "\n";
#endif
    return c;
}

} /* namespace Trace */
<|endoftext|>


<commit_before>/** @file dbfactory.cc
 * @brief Database factories for non-remote databases.
 */
/* Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2011,2012,2013,2014,2015,2016,2017,2019 Olly Betts
 * Copyright 2008 Lemur Consulting Ltd
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "config.h"

#include "xapian/dbfactory.h"

#include "xapian/constants.h"
#include "xapian/database.h"
#include "xapian/error.h"
#include "xapian/version.h" // For XAPIAN_HAS_XXX_BACKEND.

#include "xapian/backends/backends.h"
#include "xapian/backends/databasehelpers.h"
#include "xapian/common/debuglog.h"
#include "xapian/common/filetests.h"
#include "xapian/common/fileutils.h"
#include "xapian/common/posixy_wrapper.h"
#include "xapian/common/str.h"

#include <cerrno>
#include <cstdlib> // For atoi().

#ifdef XAPIAN_HAS_GLASS_BACKEND
# include "xapian/backends/glass/glass_database.h"
#endif
#include "xapian/backends/glass/glass_defs.h"
#ifdef XAPIAN_HAS_HONEY_BACKEND
# include "xapian/backends/honey/honey_database.h"
#endif
#include "xapian/backends/honey/honey_defs.h"
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
# include "xapian/backends/inmemory/inmemory_database.h"
#endif
// Even if none of the above get included, we still need a definition of
// Database::Internal.
#include "xapian/backends/databaseinternal.h"

#include <fstream>
#include <string>

using namespace std;

namespace Xapian {

static void
open_stub(Database& db, const string& file)
{
    read_stub_file(file,
		   [&db](const string& path) {
		       db.add_database(Database(path));
		   },
		   [&db](const string& path) {
#ifdef XAPIAN_HAS_GLASS_BACKEND
		       db.add_database(Database(new GlassDatabase(path)));
#else
		       (void)path;
#endif
		   },
		   [&db](const string& path) {
#ifdef XAPIAN_HAS_HONEY_BACKEND
		       db.add_database(Database(new HoneyDatabase(path)));
#else
		       (void)path;
#endif
		   },
		   [&db](const string& prog, const string& args) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open(prog, args));
#else
		       (void)prog;
		       (void)args;
#endif
		   },
		   [&db](const string& host, unsigned port) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open(host, port));
#else
		       (void)host;
		       (void)port;
#endif
		   },
		   [&db]() {
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
		       db.add_database(Database(string(), DB_BACKEND_INMEMORY));
#endif
		   });

    // Allowing a stub database with no databases listed allows things like
    // a "search all databases" feature to be implemented by generating a
    // stub database file without having to special case there not being any
    // databases yet.
    //
    // 1.0.x threw DatabaseOpeningError here, but with a "Bad line" message
    // with the line number just past the end of the file, which was a bit odd.
}

static void
open_stub(WritableDatabase& db, const string& file, int flags)
{
    read_stub_file(file,
		   [&db, flags](const string& path) {
		       db.add_database(WritableDatabase(path, flags));
		   },
		   [&db, &flags](const string& path) {
		       flags |= DB_BACKEND_GLASS;
		       db.add_database(WritableDatabase(path, flags));
		   },
		   [](const string&) {
		       auto msg = "Honey databases don't support writing";
		       throw Xapian::DatabaseOpeningError(msg);
		   },
		   [&db, flags](const string& prog, const string& args) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open_writable(prog, args,
							     0, flags));
#else
		       (void)prog;
		       (void)args;
#endif
		   },
		   [&db, flags](const string& host, unsigned port) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open_writable(host, port,
							     0, 10000, flags));
#else
		       (void)host;
		       (void)port;
#endif
		   },
		   [&db]() {
		       db.add_database(WritableDatabase(string(),
							DB_BACKEND_INMEMORY));
		   });

    if (db.internal->size() == 0) {
	throw DatabaseOpeningError(file + ": No databases listed");
    }
}

Database::Database(const string& path, int flags)
    : Database()
{
    LOGCALL_CTOR(API, "Database", path|flags);

    int type = flags & DB_BACKEND_MASK_;
    switch (type) {
	case DB_BACKEND_CHERT:
	    throw FeatureUnavailableError("Chert backend no longer supported");
	case DB_BACKEND_GLASS:
#ifdef XAPIAN_HAS_GLASS_BACKEND
	    internal = new GlassDatabase(path);
	    return;
#else
	    throw FeatureUnavailableError("Glass backend disabled");
#endif
	case DB_BACKEND_HONEY:
#ifdef XAPIAN_HAS_HONEY_BACKEND
	    internal = new HoneyDatabase(path);
	    return;
#else
	    throw FeatureUnavailableError("Honey backend disabled");
#endif
	case DB_BACKEND_STUB:
	    open_stub(*this, path);
	    return;
	case DB_BACKEND_INMEMORY:
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
	    internal = new InMemoryDatabase();
	    return;
#else
	    throw FeatureUnavailableError("Inmemory backend disabled");
#endif
    }

    struct stat statbuf;
    if (stat(path.c_str(), &statbuf) == -1) {
	throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
    }

    if (S_ISREG(statbuf.st_mode)) {
	// Could be a stub database file, or a single file glass database.

	// Initialise to avoid bogus warning from GCC 4.9.2 with -Os.
	int fd = -1;
	switch (test_if_single_file_db(statbuf, path, &fd)) {
	    case BACKEND_GLASS:
#ifdef XAPIAN_HAS_GLASS_BACKEND
		// Single file glass format.
		internal = new GlassDatabase(fd);
		return;
#else
		throw FeatureUnavailableError("Glass backend disabled");
#endif
	    case BACKEND_HONEY:
#ifdef XAPIAN_HAS_HONEY_BACKEND
		// Single file honey format.
		internal = new HoneyDatabase(fd);
		return;
#else
		throw FeatureUnavailableError("Honey backend disabled");
#endif
	}

	open_stub(*this, path);
	return;
    }

    if (rare(!S_ISDIR(statbuf.st_mode))) {
	throw DatabaseOpeningError("Not a regular file or directory: '" + path + "'");
    }

#ifdef XAPIAN_HAS_GLASS_BACKEND
    if (file_exists(path + "/iamglass")) {
	internal = new GlassDatabase(path);
	return;
    }
#endif

#ifdef XAPIAN_HAS_HONEY_BACKEND
    if (file_exists(path + "/iamhoney")) {
	internal = new HoneyDatabase(path);
	return;
    }
#endif

    // Check for "stub directories".
    string stub_file = path;
    stub_file += "/XAPIANDB";
    if (usual(file_exists(stub_file))) {
	open_stub(*this, stub_file);
	return;
    }

#ifndef XAPIAN_HAS_GLASS_BACKEND
    if (file_exists(path + "/iamglass")) {
	throw FeatureUnavailableError("Glass backend disabled");
    }
#endif
#ifndef XAPIAN_HAS_HONEY_BACKEND
    if (file_exists(path + "/iamhoney")) {
	throw FeatureUnavailableError("Honey backend disabled");
    }
#endif
    if (file_exists(path + "/iamchert")) {
	throw FeatureUnavailableError("Chert backend no longer supported");
    }
    if (file_exists(path + "/iamflint")) {
	throw FeatureUnavailableError("Flint backend no longer supported");
    }

    throw DatabaseOpeningError("Couldn't detect type of database");
}

Database::Database(int fd, int flags)
{
    LOGCALL_CTOR(API, "Database", fd|flags);

    if (rare(fd < 0))
	throw InvalidArgumentError("fd < 0");

#ifdef XAPIAN_HAS_GLASS_BACKEND
    int type = flags & DB_BACKEND_MASK_;
    switch (type) {
	case 0:
	case DB_BACKEND_GLASS:
	    internal = new GlassDatabase(fd);
    }
#else
    (void)flags;
#endif

    (void)::close(fd);
    throw DatabaseOpeningError("Couldn't detect type of database");
}

#if defined XAPIAN_HAS_GLASS_BACKEND
#define HAVE_DISK_BACKEND
#endif

WritableDatabase::WritableDatabase(const std::string &path, int flags, int block_size)
    : Database()
{
    LOGCALL_CTOR(API, "WritableDatabase", path|flags|block_size);
    // Avoid warning if all disk-based backends are disabled.
    (void)block_size;
    int type = flags & DB_BACKEND_MASK_;
    // Clear the backend bits, so we just pass on other flags to open_stub, etc.
    flags &= ~DB_BACKEND_MASK_;
    if (type == 0) {
	struct stat statbuf;
	if (stat(path.c_str(), &statbuf) == -1) {
	    // ENOENT probably just means that we need to create the directory.
	    if (errno != ENOENT)
		throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
	} else {
	    // File or directory already exists.

	    if (S_ISREG(statbuf.st_mode)) {
		// The path is a file, so assume it is a stub database file.
		open_stub(*this, path, flags);
		return;
	    }

	    if (rare(!S_ISDIR(statbuf.st_mode))) {
		throw DatabaseOpeningError("Not a regular file or directory: '" + path + "'");
	    }

	    if (file_exists(path + "/iamglass")) {
		// Existing glass DB.
#ifdef XAPIAN_HAS_GLASS_BACKEND
		type = DB_BACKEND_GLASS;
#else
		throw FeatureUnavailableError("Glass backend disabled");
#endif
	    } else if (file_exists(path + "/iamhoney")) {
		// Existing honey DB.
		throw InvalidOperationError("Honey backend doesn't support "
					    "updating existing databases");
	    } else if (file_exists(path + "/iamchert")) {
		// Existing chert DB.
		throw FeatureUnavailableError("Chert backend no longer supported");
	    } else if (file_exists(path + "/iamflint")) {
		// Existing flint DB.
		throw FeatureUnavailableError("Flint backend no longer supported");
	    } else {
		// Check for "stub directories".
		string stub_file = path;
		stub_file += "/XAPIANDB";
		if (usual(file_exists(stub_file))) {
		    open_stub(*this, stub_file, flags);
		    return;
		}
	    }
	}
    }

    switch (type) {
	case DB_BACKEND_STUB:
	    open_stub(*this, path, flags);
	    return;
	case 0:
	    // Fall through to first enabled case, so order the remaining cases
	    // by preference.
#ifdef XAPIAN_HAS_GLASS_BACKEND
	case DB_BACKEND_GLASS:
	    internal = new GlassWritableDatabase(path, flags, block_size);
	    return;
#endif
	case DB_BACKEND_HONEY:
	    throw InvalidArgumentError("Honey backend doesn't support "
				       "updating existing databases");
	case DB_BACKEND_CHERT:
	    throw FeatureUnavailableError("Chert backend no longer supported");
	case DB_BACKEND_INMEMORY:
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
	    internal = new InMemoryDatabase();
	    return;
#else
	    throw FeatureUnavailableError("Inmemory backend disabled");
#endif
    }
#ifndef HAVE_DISK_BACKEND
    throw FeatureUnavailableError("No disk-based writable backend is enabled");
#endif
}

}
<commit_msg>xapian-core: Throw DatabaseNotFoundError if directory doesn't exist<commit_after>/** @file dbfactory.cc
 * @brief Database factories for non-remote databases.
 */
/* Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2011,2012,2013,2014,2015,2016,2017,2019 Olly Betts
 * Copyright 2008 Lemur Consulting Ltd
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "config.h"

#include "xapian/dbfactory.h"

#include "xapian/constants.h"
#include "xapian/database.h"
#include "xapian/error.h"
#include "xapian/version.h" // For XAPIAN_HAS_XXX_BACKEND.

#include "xapian/backends/backends.h"
#include "xapian/backends/databasehelpers.h"
#include "xapian/common/debuglog.h"
#include "xapian/common/filetests.h"
#include "xapian/common/fileutils.h"
#include "xapian/common/posixy_wrapper.h"
#include "xapian/common/str.h"

#include <cerrno>
#include <cstdlib> // For atoi().

#ifdef XAPIAN_HAS_GLASS_BACKEND
# include "xapian/backends/glass/glass_database.h"
#endif
#include "xapian/backends/glass/glass_defs.h"
#ifdef XAPIAN_HAS_HONEY_BACKEND
# include "xapian/backends/honey/honey_database.h"
#endif
#include "xapian/backends/honey/honey_defs.h"
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
# include "xapian/backends/inmemory/inmemory_database.h"
#endif
// Even if none of the above get included, we still need a definition of
// Database::Internal.
#include "xapian/backends/databaseinternal.h"

#include <fstream>
#include <string>

using namespace std;

namespace Xapian {

static void
open_stub(Database& db, const string& file)
{
    read_stub_file(file,
		   [&db](const string& path) {
		       db.add_database(Database(path));
		   },
		   [&db](const string& path) {
#ifdef XAPIAN_HAS_GLASS_BACKEND
		       db.add_database(Database(new GlassDatabase(path)));
#else
		       (void)path;
#endif
		   },
		   [&db](const string& path) {
#ifdef XAPIAN_HAS_HONEY_BACKEND
		       db.add_database(Database(new HoneyDatabase(path)));
#else
		       (void)path;
#endif
		   },
		   [&db](const string& prog, const string& args) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open(prog, args));
#else
		       (void)prog;
		       (void)args;
#endif
		   },
		   [&db](const string& host, unsigned port) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open(host, port));
#else
		       (void)host;
		       (void)port;
#endif
		   },
		   [&db]() {
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
		       db.add_database(Database(string(), DB_BACKEND_INMEMORY));
#endif
		   });

    // Allowing a stub database with no databases listed allows things like
    // a "search all databases" feature to be implemented by generating a
    // stub database file without having to special case there not being any
    // databases yet.
    //
    // 1.0.x threw DatabaseOpeningError here, but with a "Bad line" message
    // with the line number just past the end of the file, which was a bit odd.
}

static void
open_stub(WritableDatabase& db, const string& file, int flags)
{
    read_stub_file(file,
		   [&db, flags](const string& path) {
		       db.add_database(WritableDatabase(path, flags));
		   },
		   [&db, &flags](const string& path) {
		       flags |= DB_BACKEND_GLASS;
		       db.add_database(WritableDatabase(path, flags));
		   },
		   [](const string&) {
		       auto msg = "Honey databases don't support writing";
		       throw Xapian::DatabaseOpeningError(msg);
		   },
		   [&db, flags](const string& prog, const string& args) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open_writable(prog, args,
							     0, flags));
#else
		       (void)prog;
		       (void)args;
#endif
		   },
		   [&db, flags](const string& host, unsigned port) {
#ifdef XAPIAN_HAS_REMOTE_BACKEND
		       db.add_database(Remote::open_writable(host, port,
							     0, 10000, flags));
#else
		       (void)host;
		       (void)port;
#endif
		   },
		   [&db]() {
		       db.add_database(WritableDatabase(string(),
							DB_BACKEND_INMEMORY));
		   });

    if (db.internal->size() == 0) {
	throw DatabaseOpeningError(file + ": No databases listed");
    }
}

Database::Database(const string& path, int flags)
    : Database()
{
    LOGCALL_CTOR(API, "Database", path|flags);

    int type = flags & DB_BACKEND_MASK_;
    switch (type) {
	case DB_BACKEND_CHERT:
	    throw FeatureUnavailableError("Chert backend no longer supported");
	case DB_BACKEND_GLASS:
#ifdef XAPIAN_HAS_GLASS_BACKEND
	    internal = new GlassDatabase(path);
	    return;
#else
	    throw FeatureUnavailableError("Glass backend disabled");
#endif
	case DB_BACKEND_HONEY:
#ifdef XAPIAN_HAS_HONEY_BACKEND
	    internal = new HoneyDatabase(path);
	    return;
#else
	    throw FeatureUnavailableError("Honey backend disabled");
#endif
	case DB_BACKEND_STUB:
	    open_stub(*this, path);
	    return;
	case DB_BACKEND_INMEMORY:
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
	    internal = new InMemoryDatabase();
	    return;
#else
	    throw FeatureUnavailableError("Inmemory backend disabled");
#endif
    }

    struct stat statbuf;
    if (stat(path.c_str(), &statbuf) == -1) {
	if (errno == ENOENT) {
	    throw DatabaseNotFoundError("Couldn't stat '" + path + "'", errno);
	} else {
	    throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
	}
    }

    if (S_ISREG(statbuf.st_mode)) {
	// Could be a stub database file, or a single file glass database.

	// Initialise to avoid bogus warning from GCC 4.9.2 with -Os.
	int fd = -1;
	switch (test_if_single_file_db(statbuf, path, &fd)) {
	    case BACKEND_GLASS:
#ifdef XAPIAN_HAS_GLASS_BACKEND
		// Single file glass format.
		internal = new GlassDatabase(fd);
		return;
#else
		throw FeatureUnavailableError("Glass backend disabled");
#endif
	    case BACKEND_HONEY:
#ifdef XAPIAN_HAS_HONEY_BACKEND
		// Single file honey format.
		internal = new HoneyDatabase(fd);
		return;
#else
		throw FeatureUnavailableError("Honey backend disabled");
#endif
	}

	open_stub(*this, path);
	return;
    }

    if (rare(!S_ISDIR(statbuf.st_mode))) {
	throw DatabaseOpeningError("Not a regular file or directory: '" + path + "'");
    }

#ifdef XAPIAN_HAS_GLASS_BACKEND
    if (file_exists(path + "/iamglass")) {
	internal = new GlassDatabase(path);
	return;
    }
#endif

#ifdef XAPIAN_HAS_HONEY_BACKEND
    if (file_exists(path + "/iamhoney")) {
	internal = new HoneyDatabase(path);
	return;
    }
#endif

    // Check for "stub directories".
    string stub_file = path;
    stub_file += "/XAPIANDB";
    if (usual(file_exists(stub_file))) {
	open_stub(*this, stub_file);
	return;
    }

#ifndef XAPIAN_HAS_GLASS_BACKEND
    if (file_exists(path + "/iamglass")) {
	throw FeatureUnavailableError("Glass backend disabled");
    }
#endif
#ifndef XAPIAN_HAS_HONEY_BACKEND
    if (file_exists(path + "/iamhoney")) {
	throw FeatureUnavailableError("Honey backend disabled");
    }
#endif
    if (file_exists(path + "/iamchert")) {
	throw FeatureUnavailableError("Chert backend no longer supported");
    }
    if (file_exists(path + "/iamflint")) {
	throw FeatureUnavailableError("Flint backend no longer supported");
    }

    throw DatabaseNotFoundError("Couldn't detect type of database");
}

Database::Database(int fd, int flags)
{
    LOGCALL_CTOR(API, "Database", fd|flags);

    if (rare(fd < 0))
	throw InvalidArgumentError("fd < 0");

#ifdef XAPIAN_HAS_GLASS_BACKEND
    int type = flags & DB_BACKEND_MASK_;
    switch (type) {
	case 0:
	case DB_BACKEND_GLASS:
	    internal = new GlassDatabase(fd);
    }
#else
    (void)flags;
#endif

    (void)::close(fd);
    throw DatabaseOpeningError("Couldn't detect type of database");
}

#if defined XAPIAN_HAS_GLASS_BACKEND
#define HAVE_DISK_BACKEND
#endif

WritableDatabase::WritableDatabase(const std::string &path, int flags, int block_size)
    : Database()
{
    LOGCALL_CTOR(API, "WritableDatabase", path|flags|block_size);
    // Avoid warning if all disk-based backends are disabled.
    (void)block_size;
    int type = flags & DB_BACKEND_MASK_;
    // Clear the backend bits, so we just pass on other flags to open_stub, etc.
    flags &= ~DB_BACKEND_MASK_;
    if (type == 0) {
	struct stat statbuf;
	if (stat(path.c_str(), &statbuf) == -1) {
	    // ENOENT probably just means that we need to create the directory.
	    if (errno != ENOENT)
		throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
	} else {
	    // File or directory already exists.

	    if (S_ISREG(statbuf.st_mode)) {
		// The path is a file, so assume it is a stub database file.
		open_stub(*this, path, flags);
		return;
	    }

	    if (rare(!S_ISDIR(statbuf.st_mode))) {
		throw DatabaseOpeningError("Not a regular file or directory: '" + path + "'");
	    }

	    if (file_exists(path + "/iamglass")) {
		// Existing glass DB.
#ifdef XAPIAN_HAS_GLASS_BACKEND
		type = DB_BACKEND_GLASS;
#else
		throw FeatureUnavailableError("Glass backend disabled");
#endif
	    } else if (file_exists(path + "/iamhoney")) {
		// Existing honey DB.
		throw InvalidOperationError("Honey backend doesn't support "
					    "updating existing databases");
	    } else if (file_exists(path + "/iamchert")) {
		// Existing chert DB.
		throw FeatureUnavailableError("Chert backend no longer supported");
	    } else if (file_exists(path + "/iamflint")) {
		// Existing flint DB.
		throw FeatureUnavailableError("Flint backend no longer supported");
	    } else {
		// Check for "stub directories".
		string stub_file = path;
		stub_file += "/XAPIANDB";
		if (usual(file_exists(stub_file))) {
		    open_stub(*this, stub_file, flags);
		    return;
		}
	    }
	}
    }

    switch (type) {
	case DB_BACKEND_STUB:
	    open_stub(*this, path, flags);
	    return;
	case 0:
	    // Fall through to first enabled case, so order the remaining cases
	    // by preference.
#ifdef XAPIAN_HAS_GLASS_BACKEND
	case DB_BACKEND_GLASS:
	    internal = new GlassWritableDatabase(path, flags, block_size);
	    return;
#endif
	case DB_BACKEND_HONEY:
	    throw InvalidArgumentError("Honey backend doesn't support "
				       "updating existing databases");
	case DB_BACKEND_CHERT:
	    throw FeatureUnavailableError("Chert backend no longer supported");
	case DB_BACKEND_INMEMORY:
#ifdef XAPIAN_HAS_INMEMORY_BACKEND
	    internal = new InMemoryDatabase();
	    return;
#else
	    throw FeatureUnavailableError("Inmemory backend disabled");
#endif
    }
#ifndef HAVE_DISK_BACKEND
    throw FeatureUnavailableError("No disk-based writable backend is enabled");
#endif
}

}
<|endoftext|>


<commit_before>#include "MainMenuScene.h"
#include "NNInputSystem.h"
#include "NNSceneDirector.h"
#include "NNApplication.h"

#include "StoryScene.h"

MainMenuScene::MainMenuScene()
	: m_MainMenuImage(nullptr)
{
	m_MenuSellction = 0;

	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();

	m_MainMenuImage = NNSprite::Create( L"Sprite/MainMenu.jpg" );
	m_MainMenuImage->SetPosition( width/2, height/2 );
	m_MainMenuImage->SetCenter( m_MainMenuImage->GetPositionX()/2.f, m_MainMenuImage->GetPositionY()/2.f + 70.f );
	AddChild( m_MainMenuImage );

	/* MenuSellectionBar type
	m_MainMenuSellcetionBar = NNSprite::Create( L"Sprite/MenuSellectionBar.png");
	m_MainMenuSellcetionBar->SetPosition( width/2 + 200.f, height/2 + 200.f + m_MenuSellction * 50 );
	AddChild( m_MainMenuSellcetionBar ) ;
	*/

	m_MainMenuSellcetionBar = NNSprite::Create( L"Sprite/MenuSellecter.gif");
	m_MainMenuSellcetionBar->SetPosition( width/2, height/2 );
	m_MainMenuSellcetionBar->SetScale( 0.5f, 0.5f );
	AddChild( m_MainMenuSellcetionBar ) ;

	m_MianMenuLable[MENU_PLAY] = NNLabel::Create( L"Play", L" ", 35.f );
	m_MianMenuLable[MENU_PLAY]->SetPosition( width/2 + 200.f, height/2 + 150.f );
	AddChild( m_MianMenuLable[MENU_PLAY] );

	m_MianMenuLable[MENU_EXIT] = NNLabel::Create( L"Exit", L" ", 35.f );
	m_MianMenuLable[MENU_EXIT]->SetPosition( width/2 + 200.f, height/2 + 200.f);
	AddChild( m_MianMenuLable[MENU_EXIT] );

}

MainMenuScene::~MainMenuScene()
{
}

void MainMenuScene::Render()
{
	NNScene::Render();
}

void MainMenuScene::Update( float dTime )
{
	NNScene::Update( dTime );

	m_MainMenuImage->SetVisible( true );

	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();

	if ( NNInputSystem::GetInstance()->GetKeyState( VK_UP ) == KEY_DOWN
		|| NNInputSystem::GetInstance()->GetKeyState( VK_LEFT ) == KEY_DOWN )
	{
		--m_MenuSellction;
	}
	if ( NNInputSystem::GetInstance()->GetKeyState( VK_DOWN ) == KEY_DOWN
		|| NNInputSystem::GetInstance()->GetKeyState( VK_RIGHT ) == KEY_DOWN )
	{
		++m_MenuSellction;
	}

	m_MainMenuSellcetionBar->SetPosition( width/2 + 150.f, height/2 + 150.f + m_MenuSellction * 50 );

	m_MenuSellction = ( m_MenuSellction + MENU_EXIT + 1 ) % ( MENU_EXIT + 1);

	if ( m_MenuSellction == 0 && NNInputSystem::GetInstance()->GetKeyState(VK_RETURN) == KEY_UP )
	{
		NNSceneDirector::GetInstance()->ChangeScene( StoryScene::Create() );
	}
	else if ( m_MenuSellction == 1 )
	{
		// exit
	}
}<commit_msg>@ MenuSellecter changed<commit_after>#include "MainMenuScene.h"
#include "NNInputSystem.h"
#include "NNSceneDirector.h"
#include "NNApplication.h"

#include "StoryScene.h"

MainMenuScene::MainMenuScene()
	: m_MainMenuImage(nullptr)
{
	m_MenuSellction = 0;

	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();

	m_MainMenuImage = NNSprite::Create( L"Sprite/MainMenu.jpg" );
	m_MainMenuImage->SetPosition( width/2, height/2 );
	m_MainMenuImage->SetCenter( m_MainMenuImage->GetPositionX()/2.f, m_MainMenuImage->GetPositionY()/2.f + 70.f );
	AddChild( m_MainMenuImage );

	/* MenuSellectionBar type
	m_MainMenuSellcetionBar = NNSprite::Create( L"Sprite/MenuSellectionBar.png");
	m_MainMenuSellcetionBar->SetPosition( width/2 + 200.f, height/2 + 200.f + m_MenuSellction * 50 );
	AddChild( m_MainMenuSellcetionBar ) ;
	*/

	m_MainMenuSellcetionBar = NNSprite::Create( L"Sprite/MenuSellecter.gif");
	m_MainMenuSellcetionBar->SetPosition( width/2, height/2 );
	m_MainMenuSellcetionBar->SetScale( 0.5f, 0.5f );
	AddChild( m_MainMenuSellcetionBar ) ;

	m_MianMenuLable[MENU_PLAY] = NNLabel::Create( L"Play", L" ", 35.f );
	m_MianMenuLable[MENU_PLAY]->SetPosition( width/2 + 200.f, height/2 + 150.f );
	AddChild( m_MianMenuLable[MENU_PLAY] );

	m_MianMenuLable[MENU_EXIT] = NNLabel::Create( L"Exit", L" ", 35.f );
	m_MianMenuLable[MENU_EXIT]->SetPosition( width/2 + 200.f, height/2 + 200.f);
	AddChild( m_MianMenuLable[MENU_EXIT] );

}

MainMenuScene::~MainMenuScene()
{
}

void MainMenuScene::Render()
{
	NNScene::Render();
}

void MainMenuScene::Update( float dTime )
{
	NNScene::Update( dTime );

	m_MainMenuImage->SetVisible( true );

	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();

	if ( NNInputSystem::GetInstance()->GetKeyState( VK_UP ) == KEY_DOWN
		|| NNInputSystem::GetInstance()->GetKeyState( VK_LEFT ) == KEY_DOWN )
	{
		--m_MenuSellction;
	}
	if ( NNInputSystem::GetInstance()->GetKeyState( VK_DOWN ) == KEY_DOWN
		|| NNInputSystem::GetInstance()->GetKeyState( VK_RIGHT ) == KEY_DOWN )
	{
		++m_MenuSellction;
	}

	m_MainMenuSellcetionBar->SetPosition( width/2 + 150.f, height/2 + 150.f + m_MenuSellction * 50 );

	m_MenuSellction = ( m_MenuSellction + MENU_EXIT + 1 ) % ( MENU_EXIT + 1);

	if ( m_MenuSellction == 0 && NNInputSystem::GetInstance()->GetKeyState(VK_RETURN) == KEY_UP )
	{
		NNSceneDirector::GetInstance()->ChangeScene( StoryScene::Create() );
	}
	else if ( m_MenuSellction == 1 )
	{
		// exit
	}
}<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include "acmacs-base/argc-argv.hh"
#include "acmacs-base/quicklook.hh"
#include "seqdb/seqdb.hh"

#include "signature-page.hh"
#include "settings.hh"

using namespace std::string_literals;

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

int main(int argc, const char *argv[])
{
    try {
        argc_argv args(argc, argv, {
                {"--db-dir", ""},
                {"--seqdb", ""},

                {"-s", argc_argv::strings{}}, //value<std::vector<std::string>>(&aOptions.settings_filename), "signature page drawing settings (json) filename")
                {"--init-settings", ""}, // value<std::string>(&aOptions.init_settings_filename), "initialize signature page drawing settings (json) filename")
                {"--report-cumulative", false}, // bool_switch(&aOptions.report_cumulative)->default_value(false), "report cumulative edge lengths for leaf nodes of the tree")
                {"--report-hz-section_antigens", false}, // bool_switch(&aOptions.report_antigens_in_hz_sections)->default_value(false), "report antigens in each hz section")
                {"--list-ladderized", false}, // bool_switch(&aOptions.list_ladderized)->default_value(false), "list strain names after ladderizing")
                {"--no-draw", false}, // bool_switch(&aOptions.no_draw)->default_value(false), "do not generate pdf")
                {"--chart", ""}, // value<std::string>(&aOptions.chart_filename), "path to a chart for the signature page")

                {"--open", false},
                {"-v", false},
                {"--verbose", false},
                {"-h", false},
                {"--help", false},
            });

          // {"tree", value<std::string>(&aOptions.tree_filename)->required(), "path to tree to draw")
          // ("output,o", value<std::string>(&aOptions.output_filename)->required(), "output pdf")

        if (args["-h"] || args["--help"] || args.number_of_arguments() != 2) {
            throw std::runtime_error("Usage: "s + args.program() + " [options] <tree.json> <output.pdf>\n" + args.usage_options());
        }
        const bool verbose = args["-v"] || args["--verbose"];
        seqdb::setup_dbs(args["--db-dir"], verbose);
        if (args["--seqdb"])
            seqdb::setup(args["--seqdb"], verbose);

        SignaturePageDraw signature_page;

        auto load_settings = [&signature_page,verbose](argc_argv::strings aFilenames) {
            for (auto fn: aFilenames) {
                if (verbose)
                    std::cerr << "DEBUG: reading settings from " << fn << '\n';
                signature_page.load_settings(fn);
            }
        };
        if (args["-s"])
            load_settings(args["-s"]);

        signature_page.tree(args[0]);
        if (args["--chart"])
            signature_page.chart(args["--chart"]); // before make_surface!
        signature_page.make_surface(args[1], args["--init-settings"], !args["--no-draw"]); // before init_layout!
        if (args["--init-settings"]) {
            signature_page.init_layout();
            signature_page.init_settings();
        }
        signature_page.prepare();
        if (args["--report-cumulative"])
            signature_page.tree().report_cumulative_edge_length(std::cout);
        if (args["--list-ladderized"])
            signature_page.tree().list_strains(std::cout);
        if (!args["--no-draw"])
            signature_page.draw(args["--report-hz-section_antigens"]);
        if (args["--init-settings"])
            signature_page.write_initialized_settings(args["--init-settings"]);

        if (args["--open"])
            acmacs::open(args[1], 2);

        return 0;
    }
    catch (std::exception& err) {
        std::cerr << "ERROR: " << err.what() << '\n';
        return 1;
    }
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>minor improvement<commit_after>#include <iostream>
#include <string>

#include "acmacs-base/argc-argv.hh"
#include "acmacs-base/quicklook.hh"
#include "seqdb/seqdb.hh"

#include "signature-page.hh"
#include "settings.hh"

using namespace std::string_literals;

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

int main(int argc, const char *argv[])
{
    try {
        argc_argv args(argc, argv, {
                {"--db-dir", ""},
                {"--seqdb", ""},

                {"-s", argc_argv::strings{}}, //value<std::vector<std::string>>(&aOptions.settings_filename), "signature page drawing settings (json) filename")
                {"--init-settings", ""}, // value<std::string>(&aOptions.init_settings_filename), "initialize signature page drawing settings (json) filename")
                {"--report-cumulative", false}, // bool_switch(&aOptions.report_cumulative)->default_value(false), "report cumulative edge lengths for leaf nodes of the tree")
                {"--report-hz-section_antigens", false}, // bool_switch(&aOptions.report_antigens_in_hz_sections)->default_value(false), "report antigens in each hz section")
                {"--list-ladderized", false}, // bool_switch(&aOptions.list_ladderized)->default_value(false), "list strain names after ladderizing")
                {"--no-draw", false}, // bool_switch(&aOptions.no_draw)->default_value(false), "do not generate pdf")
                {"--chart", ""}, // value<std::string>(&aOptions.chart_filename), "path to a chart for the signature page")

                {"--open", false},
                {"-v", false},
                {"--verbose", false},
                {"-h", false},
                {"--help", false},
            });

          // {"tree", value<std::string>(&aOptions.tree_filename)->required(), "path to tree to draw")
          // ("output,o", value<std::string>(&aOptions.output_filename)->required(), "output pdf")

        if (args["-h"] || args["--help"] || args.number_of_arguments() != 2) {
            throw std::runtime_error("Usage: "s + args.program() + " [options] <tree.json> <output.pdf>\n" + args.usage_options());
        }
        const bool verbose = args["-v"] || args["--verbose"];
        seqdb::setup_dbs(args["--db-dir"], verbose);
        if (args["--seqdb"])
            seqdb::setup(args["--seqdb"], verbose);

        {
            SignaturePageDraw signature_page;

            auto load_settings = [&signature_page,verbose](argc_argv::strings aFilenames) {
                                     for (auto fn: aFilenames) {
                                         if (verbose)
                                             std::cerr << "DEBUG: reading settings from " << fn << '\n';
                                         signature_page.load_settings(fn);
                                     }
                                 };
            if (args["-s"])
                load_settings(args["-s"]);

            signature_page.tree(args[0]);
            if (args["--chart"])
                signature_page.chart(args["--chart"]); // before make_surface!
            signature_page.make_surface(args[1], args["--init-settings"], !args["--no-draw"]); // before init_layout!
            if (args["--init-settings"]) {
                signature_page.init_layout();
                signature_page.init_settings();
            }
            signature_page.prepare();
            if (args["--report-cumulative"])
                signature_page.tree().report_cumulative_edge_length(std::cout);
            if (args["--list-ladderized"])
                signature_page.tree().list_strains(std::cout);
            if (!args["--no-draw"])
                signature_page.draw(args["--report-hz-section_antigens"]);
            if (args["--init-settings"])
                signature_page.write_initialized_settings(args["--init-settings"]);
        }

        if (args["--open"])
            acmacs::open(args[1], 2);

        return 0;
    }
    catch (std::exception& err) {
        std::cerr << "ERROR: " << err.what() << '\n';
        return 1;
    }
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_MAT_FUN_TO_VAR_HPP
#define STAN_MATH_REV_MAT_FUN_TO_VAR_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/typedefs.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/mat/fun/typedefs.hpp>
#include <stan/math/rev/scal/fun/to_var.hpp>

namespace stan {
namespace math {

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] m A Matrix with scalars
 * @return A Matrix with automatic differentiation variables
 */
inline matrix_v to_var(const matrix_d& m) {
  matrix_v m_v = m;
  return m_v;
}

/**
 * Specialization of to_var for non-const matrices of vars
 *
 *
 * @param[in,out] m A matrix of automatic differentation variables.
 * @return The input matrix of automatic differentiation variables.
 */
 inline matrix_v& to_var(matrix_v& m) { return m; }

/**
 * Specialization of to_var for const matrices of vars
 *
 *
 * @param[in,out] m A matrix of automatic differentation variables.
 * @return The input matrix of automatic differentiation variables.
 */
inline const matrix_v& to_var(const matrix_v& m) { return m; }

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] v A Vector of scalars
 * @return A Vector of automatic differentiation variables with
 *   values of v
 */
inline vector_v to_var(const vector_d& v) {
  vector_v v_v = v;
  return v_v;
}

/**
 * Specialization of to_var for const column vector of vars
 *
 *
 * @param[in,out] v A column vector of automatic differentation variables.
 * @return The input column vector of automatic differentiation variables.
 */
inline const vector_v& to_var(const vector_v& v) { return v; }

/**
 * Specialization of to_var for non-const column vector of vars
 *
 *
 * @param[in,out] v A column vector of automatic differentation variables.
 * @return The input column vector of automatic differentiation variables.
 */
inline vector_v& to_var(vector_v& v) { return v; }

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] rv A row vector of scalars
 * @return A row vector of automatic differentation variables with
 *   values of rv.
 */
inline row_vector_v to_var(const row_vector_d& rv) {
  row_vector_v rv_v = rv;
  return rv_v;
}

/**
 * Specialization of to_var for const row vector of vars
 *
 *
 * @param[in,out] rv A column vector of automatic differentation variables.
 * @return The input row vector of automatic differentiation variables.
 */
inline const row_vector_v& to_var(const row_vector_v& rv) { return rv; }

/**
 * Specialization of to_var for non-const row vector of vars
 *
 *
 * @param[in,out] rv A column vector of automatic differentation variables.
 * @return The input row vector of automatic differentiation variables.
 */
inline row_vector_v& to_var(row_vector_v& rv) { return rv; }

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)<commit_after>#ifndef STAN_MATH_REV_MAT_FUN_TO_VAR_HPP
#define STAN_MATH_REV_MAT_FUN_TO_VAR_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/typedefs.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/mat/fun/typedefs.hpp>
#include <stan/math/rev/scal/fun/to_var.hpp>

namespace stan {
namespace math {

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] m A Matrix with scalars
 * @return A Matrix with automatic differentiation variables
 */
inline matrix_v to_var(const matrix_d& m) {
  matrix_v m_v = m;
  return m_v;
}

/**
 * Specialization of to_var for non-const matrices of vars
 *
 *
 * @param[in,out] m A matrix of automatic differentation variables.
 * @return The input matrix of automatic differentiation variables.
 */
inline matrix_v& to_var(matrix_v& m) { return m; }

/**
 * Specialization of to_var for const matrices of vars
 *
 *
 * @param[in,out] m A matrix of automatic differentation variables.
 * @return The input matrix of automatic differentiation variables.
 */
inline const matrix_v& to_var(const matrix_v& m) { return m; }

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] v A Vector of scalars
 * @return A Vector of automatic differentiation variables with
 *   values of v
 */
inline vector_v to_var(const vector_d& v) {
  vector_v v_v = v;
  return v_v;
}

/**
 * Specialization of to_var for const column vector of vars
 *
 *
 * @param[in,out] v A column vector of automatic differentation variables.
 * @return The input column vector of automatic differentiation variables.
 */
inline const vector_v& to_var(const vector_v& v) { return v; }

/**
 * Specialization of to_var for non-const column vector of vars
 *
 *
 * @param[in,out] v A column vector of automatic differentation variables.
 * @return The input column vector of automatic differentiation variables.
 */
inline vector_v& to_var(vector_v& v) { return v; }

/**
 * Converts argument to an automatic differentiation variable.
 *
 * Returns a var variable with the input value.
 *
 * @param[in] rv A row vector of scalars
 * @return A row vector of automatic differentation variables with
 *   values of rv.
 */
inline row_vector_v to_var(const row_vector_d& rv) {
  row_vector_v rv_v = rv;
  return rv_v;
}

/**
 * Specialization of to_var for const row vector of vars
 *
 *
 * @param[in,out] rv A column vector of automatic differentation variables.
 * @return The input row vector of automatic differentiation variables.
 */
inline const row_vector_v& to_var(const row_vector_v& rv) { return rv; }

/**
 * Specialization of to_var for non-const row vector of vars
 *
 *
 * @param[in,out] rv A column vector of automatic differentation variables.
 * @return The input row vector of automatic differentiation variables.
 */
inline row_vector_v& to_var(row_vector_v& rv) { return rv; }

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS eforms2 (1.2.44); FILE MERGED 2004/10/14 10:32:18 dvo 1.2.44.1: resolve merge conflicts<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed fixme: Narrowed include.<commit_after><|endoftext|>


<commit_before>#include "mitkBoundingObjectGroup.h"
#include "vtkTransform.h"

mitk::BoundingObjectGroup::BoundingObjectGroup()
:  m_Counter(0), m_CSGMode(Difference) //m_CSGMode(Union) m_CSGMode(Intersection)
{
  m_Geometry3D->Initialize();
  m_BoundingObjects = mitk::BoundingObjectGroup::BoundingObjectContainer::New();
  SetVtkPolyData(NULL);
}

mitk::BoundingObjectGroup::~BoundingObjectGroup()
{
}

void mitk::BoundingObjectGroup::SetRequestedRegionToLargestPossibleRegion()
{
}

bool mitk::BoundingObjectGroup::RequestedRegionIsOutsideOfTheBufferedRegion()
{
  return ! VerifyRequestedRegion();
}

bool mitk::BoundingObjectGroup::VerifyRequestedRegion()
{
  assert(m_Geometry3D.IsNotNull());
  return true;
}

void mitk::BoundingObjectGroup::SetRequestedRegion(itk::DataObject *data)
{
}

void mitk::BoundingObjectGroup::UpdateOutputInformation()
{
  float bounds[6]={0,1,0,1,0,1};  // {xmin,x_max, ymin,y_max,zmin,z_max};

  // calculate global bounding box
  mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIterator = m_BoundingObjects->Begin();
  const mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIteratorEnd = m_BoundingObjects->End();

  if(boundingObjectsIterator == boundingObjectsIteratorEnd) // if there is no BoundingObject, the bounding box is zero
  {
    bounds[0] = bounds[1] = bounds[2] = bounds[3] = bounds[4] = bounds[5] = 0.0;
    return;
  }
  mitk::BoundingBox::Pointer boundingBox;
  mitk::BoundingBox::PointType minPoint;
  mitk::BoundingBox::PointType globalMinPoint;
  mitk::BoundingBox::PointType globalMaxPoint;
  float* posPoint;

  /* Initialize globalMin/MaxPoints */
  boundingObjectsIterator.Value()->UpdateOutputInformation();
  boundingBox = const_cast<mitk::BoundingBox*>(boundingObjectsIterator.Value()->GetGeometry()->GetBoundingBox());

  minPoint = boundingBox->GetMinimum();
  mitk::ScalarType min[3];
  min[0] = minPoint[0];   min[1] = minPoint[1];   min[2] = minPoint[2];
  boundingObjectsIterator.Value()->GetGeometry()->GetVtkTransform()->TransformPoint(min, min);
  globalMinPoint[0] = min[0];   globalMinPoint[1] = min[1];   globalMinPoint[2] = min[2];
  globalMaxPoint[0] = min[0];   globalMaxPoint[1] = min[1];   globalMaxPoint[2] = min[2];
  //boundingObjectsIterator++;
  while (boundingObjectsIterator != boundingObjectsIteratorEnd) // calculate a bounding box that includes all BoundingObjects
  {
    boundingObjectsIterator.Value()->UpdateOutputInformation();
    boundingBox = const_cast<mitk::BoundingBox*>(boundingObjectsIterator.Value()->GetGeometry()->GetBoundingBox());

    /* create all 8 points of the bounding box */
    mitk::BoundingBox::PointsContainerPointer points = mitk::BoundingBox::PointsContainer::New();
    mitk::ITKPoint3D p;
    p = boundingBox->GetMinimum();
    points->InsertElement(0, p);
    p[0] = -p[0];
    points->InsertElement(1, p);
    p = boundingBox->GetMinimum();
    p[1] = -p[1];
    points->InsertElement(2, p);
    p = boundingBox->GetMinimum();
    p[2] = -p[2];
    points->InsertElement(3, p);
    p = boundingBox->GetMaximum();
    points->InsertElement(4, p);
    p[0] = -p[0];
    points->InsertElement(5, p);
    p = boundingBox->GetMaximum();
    p[1] = -p[1];
    points->InsertElement(6, p);
    p = boundingBox->GetMaximum();
    p[2] = -p[2];
    points->InsertElement(7, p);
    mitk::BoundingBox::PointsContainerConstIterator pointsIterator = points->Begin();
    mitk::BoundingBox::PointsContainerConstIterator pointsIteratorEnd = points->End();
    while (pointsIterator != pointsIteratorEnd) // for each vertex of the bounding box
    {
      minPoint = pointsIterator->Value();
      min[0] = minPoint[0];   min[1] = minPoint[1];   min[2] = minPoint[2];
      boundingObjectsIterator.Value()->GetGeometry()->GetVtkTransform()->TransformPoint(min, min);  // transform vertex point to world coordinates

      globalMinPoint[0] = (min[0] < globalMinPoint[0]) ? min[0] : globalMinPoint[0];  // check if world point
      globalMinPoint[1] = (min[1] < globalMinPoint[1]) ? min[1] : globalMinPoint[1];  // has a lower or a
      globalMinPoint[2] = (min[2] < globalMinPoint[2]) ? min[2] : globalMinPoint[2];  // higher value as
      globalMaxPoint[0] = (min[0] > globalMaxPoint[0]) ? min[0] : globalMaxPoint[0];  // the last known highest
      globalMaxPoint[1] = (min[1] > globalMaxPoint[1]) ? min[1] : globalMaxPoint[1];  // value
      globalMaxPoint[2] = (min[2] > globalMaxPoint[2]) ? min[2] : globalMaxPoint[2];  // in each axis
      pointsIterator++;
    }
    boundingObjectsIterator++;
  }

  /* BoundingBox is centered around the center of all sub bounding objects */
  mitk::BoundingBox::PointType centerPoint;
  centerPoint[0] = (globalMinPoint[0] + globalMaxPoint[0])/ 2.0;
  centerPoint[1] = (globalMinPoint[1] + globalMaxPoint[1])/ 2.0;
  centerPoint[2] = (globalMinPoint[2] + globalMaxPoint[2])/ 2.0;

  bounds[0] = globalMinPoint[0] - centerPoint[0]; // x Min
  bounds[1] = globalMaxPoint[0] - centerPoint[0]; // x Max
  bounds[2] = globalMinPoint[1] - centerPoint[1]; // y Min
  bounds[3] = globalMaxPoint[1] - centerPoint[1]; // y Max
  bounds[4] = globalMinPoint[2] - centerPoint[2]; // z Min
  bounds[5] = globalMaxPoint[2] - centerPoint[2]; // z Max
  m_Geometry3D->SetBoundingBox(bounds);

  /* the objects position is the center of all sub bounding objects */
  m_Geometry3D->GetVtkTransform()->Identity();
  m_Geometry3D->GetVtkTransform()->Translate(centerPoint[0], centerPoint[1], centerPoint[2]);

}

void mitk::BoundingObjectGroup::AddBoundingObject(mitk::BoundingObject::Pointer boundingObject)
{
  m_BoundingObjects->InsertElement( m_Counter++, boundingObject);
  UpdateOutputInformation();
}

bool mitk::BoundingObjectGroup::IsInside(mitk::ITKPoint3D p)
{
  mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIterator = m_BoundingObjects->Begin();
  const mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIteratorEnd = m_BoundingObjects->End();

  bool inside; // initialize with true for intersection, with false for union

  switch(m_CSGMode)
  {
    case Intersection:
    {
      inside = true;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {       // calculate intersection: each point, that is inside each BoundingObject is considered inside the group
        inside = boundingObjectsIterator.Value()->IsInside(p) && inside;
        if (!inside) // shortcut, it is enough to find one object that does not contain the point
          break;
        boundingObjectsIterator++;
      }
      break;
    }
    case Difference:
    {
      bool posInside = false;
      bool negInside = false;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {
        // calculate union: each point, that is inside least one BoundingObject is considered inside the group
        if (boundingObjectsIterator.Value()->GetPositive())
          posInside = boundingObjectsIterator.Value()->IsInside(p) || posInside;
        else
          negInside = boundingObjectsIterator.Value()->IsInside(p) || negInside;

        boundingObjectsIterator++;
      }
      if (posInside && !negInside)
        inside = true;
      else
        inside = false;
      break;
    }
    case Union:
    default:
    {
      inside = false;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {       // calculate union: each point, that is inside least one BoundingObject is considered inside the group
        inside = boundingObjectsIterator.Value()->IsInside(p) || inside;
        if (inside) // shortcut, it is enough to find one object that contains the point
          break;
        boundingObjectsIterator++;
      }
      break;
    }
  }
  return inside;
}

unsigned int mitk::BoundingObjectGroup::GetCount() const
{
  return m_Counter;
}
<commit_msg>code cleanup<commit_after>#include "mitkBoundingObjectGroup.h"
#include "vtkTransform.h"

mitk::BoundingObjectGroup::BoundingObjectGroup()
:  m_Counter(0), m_CSGMode(Difference) //m_CSGMode(Union) m_CSGMode(Intersection)
{
  m_Geometry3D->Initialize();
  m_BoundingObjects = mitk::BoundingObjectGroup::BoundingObjectContainer::New();
  SetVtkPolyData(NULL);
}

mitk::BoundingObjectGroup::~BoundingObjectGroup()
{
}

void mitk::BoundingObjectGroup::SetRequestedRegionToLargestPossibleRegion()
{
}

bool mitk::BoundingObjectGroup::RequestedRegionIsOutsideOfTheBufferedRegion()
{
  return ! VerifyRequestedRegion();
}

bool mitk::BoundingObjectGroup::VerifyRequestedRegion()
{
  assert(m_Geometry3D.IsNotNull());
  return true;
}

void mitk::BoundingObjectGroup::SetRequestedRegion(itk::DataObject *data)
{
}

void mitk::BoundingObjectGroup::UpdateOutputInformation()
{
  float bounds[6]={0,1,0,1,0,1};  // {xmin,x_max, ymin,y_max,zmin,z_max};

  // calculate global bounding box
  mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIterator = m_BoundingObjects->Begin();
  const mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIteratorEnd = m_BoundingObjects->End();

  if(boundingObjectsIterator == boundingObjectsIteratorEnd) // if there is no BoundingObject, the bounding box is zero
  {
    bounds[0] = bounds[1] = bounds[2] = bounds[3] = bounds[4] = bounds[5] = 0.0;
    return;
  }
  mitk::BoundingBox::Pointer boundingBox;
  mitk::BoundingBox::PointType minPoint;
  mitk::BoundingBox::PointType globalMinPoint;
  mitk::BoundingBox::PointType globalMaxPoint;

  /* Initialize globalMin/MaxPoints */
  boundingObjectsIterator.Value()->UpdateOutputInformation();
  boundingBox = const_cast<mitk::BoundingBox*>(boundingObjectsIterator.Value()->GetGeometry()->GetBoundingBox());

  minPoint = boundingBox->GetMinimum();
  mitk::ScalarType min[3];
  min[0] = minPoint[0];   min[1] = minPoint[1];   min[2] = minPoint[2];
  boundingObjectsIterator.Value()->GetGeometry()->GetVtkTransform()->TransformPoint(min, min);
  globalMinPoint[0] = min[0];   globalMinPoint[1] = min[1];   globalMinPoint[2] = min[2];
  globalMaxPoint[0] = min[0];   globalMaxPoint[1] = min[1];   globalMaxPoint[2] = min[2];
  //boundingObjectsIterator++;
  while (boundingObjectsIterator != boundingObjectsIteratorEnd) // calculate a bounding box that includes all BoundingObjects
  {
    boundingObjectsIterator.Value()->UpdateOutputInformation();
    boundingBox = const_cast<mitk::BoundingBox*>(boundingObjectsIterator.Value()->GetGeometry()->GetBoundingBox());

    /* create all 8 points of the bounding box */
    mitk::BoundingBox::PointsContainerPointer points = mitk::BoundingBox::PointsContainer::New();
    mitk::ITKPoint3D p;
    p = boundingBox->GetMinimum();
    points->InsertElement(0, p);
    p[0] = -p[0];
    points->InsertElement(1, p);
    p = boundingBox->GetMinimum();
    p[1] = -p[1];
    points->InsertElement(2, p);
    p = boundingBox->GetMinimum();
    p[2] = -p[2];
    points->InsertElement(3, p);
    p = boundingBox->GetMaximum();
    points->InsertElement(4, p);
    p[0] = -p[0];
    points->InsertElement(5, p);
    p = boundingBox->GetMaximum();
    p[1] = -p[1];
    points->InsertElement(6, p);
    p = boundingBox->GetMaximum();
    p[2] = -p[2];
    points->InsertElement(7, p);
    mitk::BoundingBox::PointsContainerConstIterator pointsIterator = points->Begin();
    mitk::BoundingBox::PointsContainerConstIterator pointsIteratorEnd = points->End();
    while (pointsIterator != pointsIteratorEnd) // for each vertex of the bounding box
    {
      minPoint = pointsIterator->Value();
      min[0] = minPoint[0];   min[1] = minPoint[1];   min[2] = minPoint[2];
      boundingObjectsIterator.Value()->GetGeometry()->GetVtkTransform()->TransformPoint(min, min);  // transform vertex point to world coordinates

      globalMinPoint[0] = (min[0] < globalMinPoint[0]) ? min[0] : globalMinPoint[0];  // check if world point
      globalMinPoint[1] = (min[1] < globalMinPoint[1]) ? min[1] : globalMinPoint[1];  // has a lower or a
      globalMinPoint[2] = (min[2] < globalMinPoint[2]) ? min[2] : globalMinPoint[2];  // higher value as
      globalMaxPoint[0] = (min[0] > globalMaxPoint[0]) ? min[0] : globalMaxPoint[0];  // the last known highest
      globalMaxPoint[1] = (min[1] > globalMaxPoint[1]) ? min[1] : globalMaxPoint[1];  // value
      globalMaxPoint[2] = (min[2] > globalMaxPoint[2]) ? min[2] : globalMaxPoint[2];  // in each axis
      pointsIterator++;
    }
    boundingObjectsIterator++;
  }

  /* BoundingBox is centered around the center of all sub bounding objects */
  mitk::BoundingBox::PointType centerPoint;
  centerPoint[0] = (globalMinPoint[0] + globalMaxPoint[0])/ 2.0;
  centerPoint[1] = (globalMinPoint[1] + globalMaxPoint[1])/ 2.0;
  centerPoint[2] = (globalMinPoint[2] + globalMaxPoint[2])/ 2.0;

  bounds[0] = globalMinPoint[0] - centerPoint[0]; // x Min
  bounds[1] = globalMaxPoint[0] - centerPoint[0]; // x Max
  bounds[2] = globalMinPoint[1] - centerPoint[1]; // y Min
  bounds[3] = globalMaxPoint[1] - centerPoint[1]; // y Max
  bounds[4] = globalMinPoint[2] - centerPoint[2]; // z Min
  bounds[5] = globalMaxPoint[2] - centerPoint[2]; // z Max
  m_Geometry3D->SetBoundingBox(bounds);

  /* the objects position is the center of all sub bounding objects */
  m_Geometry3D->GetVtkTransform()->Identity();
  m_Geometry3D->GetVtkTransform()->Translate(centerPoint[0], centerPoint[1], centerPoint[2]);

}

void mitk::BoundingObjectGroup::AddBoundingObject(mitk::BoundingObject::Pointer boundingObject)
{
  m_BoundingObjects->InsertElement( m_Counter++, boundingObject);
  UpdateOutputInformation();
}

bool mitk::BoundingObjectGroup::IsInside(mitk::ITKPoint3D p)
{
  mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIterator = m_BoundingObjects->Begin();
  const mitk::BoundingObjectGroup::BoundingObjectContainer::ConstIterator boundingObjectsIteratorEnd = m_BoundingObjects->End();

  bool inside; // initialize with true for intersection, with false for union

  switch(m_CSGMode)
  {
    case Intersection:
    {
      inside = true;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {       // calculate intersection: each point, that is inside each BoundingObject is considered inside the group
        inside = boundingObjectsIterator.Value()->IsInside(p) && inside;
        if (!inside) // shortcut, it is enough to find one object that does not contain the point
          break;
        boundingObjectsIterator++;
      }
      break;
    }
    case Difference:
    {
      bool posInside = false;
      bool negInside = false;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {
        // calculate union: each point, that is inside least one BoundingObject is considered inside the group
        if (boundingObjectsIterator.Value()->GetPositive())
          posInside = boundingObjectsIterator.Value()->IsInside(p) || posInside;
        else
          negInside = boundingObjectsIterator.Value()->IsInside(p) || negInside;

        boundingObjectsIterator++;
      }
      if (posInside && !negInside)
        inside = true;
      else
        inside = false;
      break;
    }
    case Union:
    default:
    {
      inside = false;
      while (boundingObjectsIterator != boundingObjectsIteratorEnd) // check each BoundingObject
      {       // calculate union: each point, that is inside least one BoundingObject is considered inside the group
        inside = boundingObjectsIterator.Value()->IsInside(p) || inside;
        if (inside) // shortcut, it is enough to find one object that contains the point
          break;
        boundingObjectsIterator++;
      }
      break;
    }
  }
  return inside;
}

unsigned int mitk::BoundingObjectGroup::GetCount() const
{
  return m_Counter;
}
<|endoftext|>