<commit_before>// Copyright (c) 2012 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <string>

#include "../src/glue/cvtutf.h"

namespace libj {
namespace glue {

TEST(GTestCvtUtf, TestUtf8ToUtf32) {
    std::u32string s32;
    char s1[] = { 0xe3, 0x81, 0x82, 0x00 };
    s32 = toUtf32(s1, UTF8, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF8, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF8, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0xe3, 0x81, 0x82 };
    s32 = toUtf32(s2, UTF8, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0xe3, 0x81, 0x00 };
    s32 = toUtf32(s3, UTF8, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf16BEToUtf32) {
    std::u32string s32;
    char s1[] = { 0x30, 0x42, 0x00, 0x00 };
    s32 = toUtf32(s1, UTF16BE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF16BE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0x30, 0x42 };
    s32 = toUtf32(s2, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0xd8, 0x40, 0xdc, 0x0b };
    s32 = toUtf32(s3, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s4[] = { 0xdf, 0xff, 0xdf, 0xff };
    s32 = toUtf32(s4, UTF16BE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf16LEToUtf32) {
    std::u32string s32;
    char s1[] = { 0x42, 0x30, 0x00, 0x00 };
    s32 = toUtf32(s1, UTF16LE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF16LE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0x42, 0x30 };
    s32 = toUtf32(s2, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0x40, 0xd8, 0x0b, 0xdc };
    s32 = toUtf32(s3, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s4[] = { 0xff, 0xdf, 0xff, 0xdf };
    s32 = toUtf32(s4, UTF16LE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32BEToUtf32) {
    std::u32string s32;
    char s1[] = {
        0x00, 0x02, 0x00, 0x0b,
        0x00, 0x00, 0x00, 0x00
    };
    s32 = toUtf32(s1, UTF32BE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF32BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);
    s32 = toUtf32(s1, UTF32BE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s2[] = {
        0x00, 0x02, 0x00, 0x0b
    };
    s32 = toUtf32(s2, UTF32BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s3[] = { 0xff, 0xff, 0xff, 0xff };
    s32 = toUtf32(s3, UTF32BE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32LEToUtf32) {
    std::u32string s32;
    char s1[] = {
        0x0b, 0x00, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x00
    };
    s32 = toUtf32(s1, UTF32LE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF32LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);
    s32 = toUtf32(s1, UTF32LE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s2[] = {
        0x0b, 0x00, 0x02, 0x00
    };
    s32 = toUtf32(s2, UTF32LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s3[] = { 0xff, 0xff, 0xff, 0xff };
    s32 = toUtf32(s3, UTF32LE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32ToUtf8) {
    std::u32string s32;
    std::string s8 = fromUtf32(s32, UTF8);
    ASSERT_EQ(0, s8.length());

    s32 += 0x3042;
    s32 += 0x3044;
    s8 = fromUtf32(s32, UTF8);
    ASSERT_EQ(6, s8.length());
    ASSERT_EQ(static_cast<char>(0xe3), s8[0]);
    ASSERT_EQ(static_cast<char>(0x81), s8[1]);
    ASSERT_EQ(static_cast<char>(0x82), s8[2]);
    ASSERT_EQ(static_cast<char>(0xe3), s8[3]);
    ASSERT_EQ(static_cast<char>(0x81), s8[4]);
    ASSERT_EQ(static_cast<char>(0x84), s8[5]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16BE) {
    std::u32string s32;
    std::string s16be = fromUtf32(s32, UTF16BE);
    ASSERT_EQ(0, s16be.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s16be = fromUtf32(s32, UTF16BE);
    ASSERT_EQ(6, s16be.length());
    ASSERT_EQ(static_cast<char>(0x30), s16be[0]);
    ASSERT_EQ(static_cast<char>(0x42), s16be[1]);
    ASSERT_EQ(static_cast<char>(0xd8), s16be[2]);
    ASSERT_EQ(static_cast<char>(0x40), s16be[3]);
    ASSERT_EQ(static_cast<char>(0xdc), s16be[4]);
    ASSERT_EQ(static_cast<char>(0x0b), s16be[5]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16LE) {
    std::u32string s32;
    std::string s16le = fromUtf32(s32, UTF16LE);
    ASSERT_EQ(0, s16le.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s16le = fromUtf32(s32, UTF16LE);
    ASSERT_EQ(6, s16le.length());
    ASSERT_EQ(static_cast<char>(0x42), s16le[0]);
    ASSERT_EQ(static_cast<char>(0x30), s16le[1]);
    ASSERT_EQ(static_cast<char>(0x40), s16le[2]);
    ASSERT_EQ(static_cast<char>(0xd8), s16le[3]);
    ASSERT_EQ(static_cast<char>(0x0b), s16le[4]);
    ASSERT_EQ(static_cast<char>(0xdc), s16le[5]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf32BE) {
    std::u32string s32;
    std::string s32be = fromUtf32(s32, UTF32BE);
    ASSERT_EQ(0, s32be.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s32be = fromUtf32(s32, UTF32BE);
    ASSERT_EQ(8, s32be.length());
    ASSERT_EQ(static_cast<char>(0x00), s32be[0]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[1]);
    ASSERT_EQ(static_cast<char>(0x30), s32be[2]);
    ASSERT_EQ(static_cast<char>(0x42), s32be[3]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[4]);
    ASSERT_EQ(static_cast<char>(0x02), s32be[5]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[6]);
    ASSERT_EQ(static_cast<char>(0x0b), s32be[7]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf32LE) {
    std::u32string s32;
    std::string s32le = fromUtf32(s32, UTF32LE);
    ASSERT_EQ(0, s32le.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s32le = fromUtf32(s32, UTF32LE);
    ASSERT_EQ(8, s32le.length());
    ASSERT_EQ(static_cast<char>(0x42), s32le[0]);
    ASSERT_EQ(static_cast<char>(0x30), s32le[1]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[2]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[3]);
    ASSERT_EQ(static_cast<char>(0x0b), s32le[4]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[5]);
    ASSERT_EQ(static_cast<char>(0x02), s32le[6]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[7]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16) {
    std::u32string s32;
    std::u16string s16 = utf32ToUtf16(s32);
    ASSERT_EQ(0, s16.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s16 = utf32ToUtf16(s32);
    ASSERT_EQ(3, s16.length());
    ASSERT_EQ(static_cast<char16_t>(0x3042), s16[0]);
    ASSERT_EQ(static_cast<char16_t>(0xd840), s16[1]);
    ASSERT_EQ(static_cast<char16_t>(0xdc0b), s16[2]);
}

}  // namespace glue
}  // namespace libj
<commit_msg>add new tests and fix wrong asserts<commit_after>// Copyright (c) 2012 Plenluno All rights reserved.

#include <gtest/gtest.h>
#include <string>

#include "../src/glue/cvtutf.h"

namespace libj {
namespace glue {

TEST(GTestCvtUtf, TestUtf8ToUtf32) {
    std::u32string s32;
    char s1[] = { 0xe3, 0x81, 0x82, 0x00 };
    s32 = toUtf32(s1, UTF8, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF8, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF8, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0xe3, 0x81, 0x82 };
    s32 = toUtf32(s2, UTF8, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0xe3, 0x81, 0x00 };
    s32 = toUtf32(s3, UTF8, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf16BEToUtf32) {
    std::u32string s32;
    char s1[] = { 0x30, 0x42, 0x00, 0x00 };
    s32 = toUtf32(s1, UTF16BE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF16BE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0x30, 0x42 };
    s32 = toUtf32(s2, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0xd8, 0x40, 0xdc, 0x0b };
    s32 = toUtf32(s3, UTF16BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s4[] = { 0xdf, 0xff, 0xdf, 0xff };
    s32 = toUtf32(s4, UTF16BE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf16LEToUtf32) {
    std::u32string s32;
    char s1[] = { 0x42, 0x30, 0x00, 0x00 };
    s32 = toUtf32(s1, UTF16LE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);
    s32 = toUtf32(s1, UTF16LE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s2[] = { 0x42, 0x30 };
    s32 = toUtf32(s2, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x3042, s32[0]);

    char s3[] = { 0x40, 0xd8, 0x0b, 0xdc };
    s32 = toUtf32(s3, UTF16LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s4[] = { 0xff, 0xdf, 0xff, 0xdf };
    s32 = toUtf32(s4, UTF16LE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32BEToUtf32) {
    std::u32string s32;
    char s1[] = {
        0x00, 0x02, 0x00, 0x0b,
        0x00, 0x00, 0x00, 0x00
    };
    s32 = toUtf32(s1, UTF32BE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF32BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);
    s32 = toUtf32(s1, UTF32BE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s2[] = {
        0x00, 0x02, 0x00, 0x0b
    };
    s32 = toUtf32(s2, UTF32BE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s3[] = { 0xff, 0xff, 0xff, 0xff };
    s32 = toUtf32(s3, UTF32BE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32LEToUtf32) {
    std::u32string s32;
    char s1[] = {
        0x0b, 0x00, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x00
    };
    s32 = toUtf32(s1, UTF32LE, 0);
    ASSERT_EQ(0, s32.length());
    s32 = toUtf32(s1, UTF32LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);
    s32 = toUtf32(s1, UTF32LE, -1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s2[] = {
        0x0b, 0x00, 0x02, 0x00
    };
    s32 = toUtf32(s2, UTF32LE, 1);
    ASSERT_EQ(1, s32.length());
    ASSERT_EQ(0x2000b, s32[0]);

    char s3[] = { 0xff, 0xff, 0xff, 0xff };
    s32 = toUtf32(s3, UTF32LE, 1);
    ASSERT_EQ(0, s32.length());
}

TEST(GTestCvtUtf, TestUtf32ToUtf8) {
    std::u32string s32;
    std::string s8 = fromUtf32(s32, UTF8);
    ASSERT_EQ(0, s8.length());

    s32 += 0x3042;
    s32 += 0x3044;
    s8 = fromUtf32(s32, UTF8);
    ASSERT_EQ(6, s8.length());
    ASSERT_EQ(static_cast<char>(0xe3), s8[0]);
    ASSERT_EQ(static_cast<char>(0x81), s8[1]);
    ASSERT_EQ(static_cast<char>(0x82), s8[2]);
    ASSERT_EQ(static_cast<char>(0xe3), s8[3]);
    ASSERT_EQ(static_cast<char>(0x81), s8[4]);
    ASSERT_EQ(static_cast<char>(0x84), s8[5]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16BE) {
    std::u32string s32;
    std::string s16be = fromUtf32(s32, UTF16BE);
    ASSERT_EQ(2, s16be.length());
    ASSERT_EQ(static_cast<char>(0x00), s16be[0]);
    ASSERT_EQ(static_cast<char>(0x00), s16be[1]);

    s32 += 0x3042;
    s32 += 0x2000b;
    s16be = fromUtf32(s32, UTF16BE);
    ASSERT_EQ(8, s16be.length());
    ASSERT_EQ(static_cast<char>(0x30), s16be[0]);
    ASSERT_EQ(static_cast<char>(0x42), s16be[1]);
    ASSERT_EQ(static_cast<char>(0xd8), s16be[2]);
    ASSERT_EQ(static_cast<char>(0x40), s16be[3]);
    ASSERT_EQ(static_cast<char>(0xdc), s16be[4]);
    ASSERT_EQ(static_cast<char>(0x0b), s16be[5]);
    ASSERT_EQ(static_cast<char>(0x00), s16be[6]);
    ASSERT_EQ(static_cast<char>(0x00), s16be[7]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16LE) {
    std::u32string s32;
    std::string s16le = fromUtf32(s32, UTF16LE);
    ASSERT_EQ(2, s16le.length());
    ASSERT_EQ(static_cast<char>(0x00), s16le[0]);
    ASSERT_EQ(static_cast<char>(0x00), s16le[1]);

    s32 += 0x3042;
    s32 += 0x2000b;
    s16le = fromUtf32(s32, UTF16LE);
    ASSERT_EQ(8, s16le.length());
    ASSERT_EQ(static_cast<char>(0x42), s16le[0]);
    ASSERT_EQ(static_cast<char>(0x30), s16le[1]);
    ASSERT_EQ(static_cast<char>(0x40), s16le[2]);
    ASSERT_EQ(static_cast<char>(0xd8), s16le[3]);
    ASSERT_EQ(static_cast<char>(0x0b), s16le[4]);
    ASSERT_EQ(static_cast<char>(0xdc), s16le[5]);
    ASSERT_EQ(static_cast<char>(0x00), s16le[6]);
    ASSERT_EQ(static_cast<char>(0x00), s16le[7]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf32BE) {
    std::u32string s32;
    std::string s32be = fromUtf32(s32, UTF32BE);
    ASSERT_EQ(4, s32be.length());
    ASSERT_EQ(static_cast<char>(0x00), s32be[0]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[1]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[2]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[3]);

    s32 += 0x3042;
    s32 += 0x2000b;
    s32be = fromUtf32(s32, UTF32BE);
    ASSERT_EQ(12, s32be.length());
    ASSERT_EQ(static_cast<char>(0x00), s32be[0]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[1]);
    ASSERT_EQ(static_cast<char>(0x30), s32be[2]);
    ASSERT_EQ(static_cast<char>(0x42), s32be[3]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[4]);
    ASSERT_EQ(static_cast<char>(0x02), s32be[5]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[6]);
    ASSERT_EQ(static_cast<char>(0x0b), s32be[7]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[8]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[9]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[10]);
    ASSERT_EQ(static_cast<char>(0x00), s32be[11]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf32LE) {
    std::u32string s32;
    std::string s32le = fromUtf32(s32, UTF32LE);
    ASSERT_EQ(4, s32le.length());
    ASSERT_EQ(static_cast<char>(0x00), s32le[0]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[1]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[2]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[3]);

    s32 += 0x3042;
    s32 += 0x2000b;
    s32le = fromUtf32(s32, UTF32LE);
    ASSERT_EQ(12, s32le.length());
    ASSERT_EQ(static_cast<char>(0x42), s32le[0]);
    ASSERT_EQ(static_cast<char>(0x30), s32le[1]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[2]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[3]);
    ASSERT_EQ(static_cast<char>(0x0b), s32le[4]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[5]);
    ASSERT_EQ(static_cast<char>(0x02), s32le[6]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[7]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[8]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[9]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[10]);
    ASSERT_EQ(static_cast<char>(0x00), s32le[11]);
}

TEST(GTestCvtUtf, TestUtf16ToUtf32) {
    std::u16string s16;
    std::u32string s32 = utf16ToUtf32(s16);
    ASSERT_EQ(0, s16.length());

    s16 += 0x3042;
    s16 += 0xd840;
    s16 += 0xdc0b;
    s32 = utf16ToUtf32(s16);
    ASSERT_EQ(2, s32.length());
    ASSERT_EQ(static_cast<char32_t>(0x3042), s32[0]);
    ASSERT_EQ(static_cast<char32_t>(0x2000b), s32[1]);
}

TEST(GTestCvtUtf, TestUtf32ToUtf16) {
    std::u32string s32;
    std::u16string s16 = utf32ToUtf16(s32);
    ASSERT_EQ(0, s16.length());

    s32 += 0x3042;
    s32 += 0x2000b;
    s16 = utf32ToUtf16(s32);
    ASSERT_EQ(3, s16.length());
    ASSERT_EQ(static_cast<char16_t>(0x3042), s16[0]);
    ASSERT_EQ(static_cast<char16_t>(0xd840), s16[1]);
    ASSERT_EQ(static_cast<char16_t>(0xdc0b), s16[2]);
}

}  // namespace glue
}  // namespace libj
<|endoftext|>


<commit_before>#include "prepostorderstorage.h"

#include "../dfs.h"
#include "../exactannovaluesearch.h"
#include "../exactannokeysearch.h"

#include <set>
#include <stack>

#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/map.hpp>

using namespace annis;

PrePostOrderStorage::PrePostOrderStorage(StringStorage &strings, const Component &component)
{

}

PrePostOrderStorage::~PrePostOrderStorage()
{

}

bool PrePostOrderStorage::load(std::string dirPath)
{
  node2order.clear();
  order2node.clear();

  bool result = edgeAnno.load(dirPath);
  std::ifstream in;

  in.open(dirPath + "/node2order.btree", std::ios::binary);
  result = result && node2order.restore(in);
  in.close();

  in.open(dirPath + "/order2node.btree", std::ios::binary);
  result = result && order2node.restore(in);
  in.close();

  return result;
}

bool PrePostOrderStorage::save(std::string dirPath)
{
  bool result = edgeAnno.save(dirPath);

  std::ofstream out;

  out.open(dirPath + "/node2order.btree", std::ios::binary);
  node2order.dump(out);
  out.close();

  out.open(dirPath + "/order2node.btree", std::ios::binary);
  order2node.dump(out);
  out.close();

  return result;

}

void PrePostOrderStorage::copy(const DB& db, const ReadableGraphStorage& orig)
{
  using ItType = stx::btree_set<Edge>::const_iterator;
  clear();

  // find all roots of the component
  std::set<nodeid_t> roots;
  ExactAnnoKeySearch nodes(db, annis_ns, annis_node_name);
  // first add all nodes that are a source of an edge as possible roots
  while(nodes.hasNext())
  {
    nodeid_t n = nodes.next().node;
    // insert all nodes to the root candidate list which are part of this component
    if(!orig.getOutgoingEdges(n).empty())
    {
      roots.insert(n);
    }
  }

  nodes.reset();
  while(nodes.hasNext())
  {
    nodeid_t source = nodes.next().node;

    std::vector<nodeid_t> outEdges = orig.getOutgoingEdges(source);
    for(auto target : outEdges)
    {
      Edge e = {source, target};

      // remove the nodes that have an incoming edge from the root list
      roots.erase(target);

      std::vector<Annotation> edgeAnnos = orig.getEdgeAnnotations(e);
      for(auto a : edgeAnnos)
      {
        edgeAnno.addEdgeAnnotation(e, a);
      }
    }
  }

  uint32_t currentOrder = 0;

  // traverse the graph for each sub-component
  for(const auto& startNode : roots)
  {
    unsigned int lastDistance = 0;

    NStack nodeStack;

    enterNode(currentOrder, startNode, startNode, 0, nodeStack);

    CycleSafeDFS dfs(orig, startNode, 1, uintmax);
    for(DFSIteratorResult step = dfs.nextDFS(); step.found;
          step = dfs.nextDFS())
    {
      if(step.distance > lastDistance)
      {
        // first visited, set pre-order
        enterNode(currentOrder, step.node, startNode, step.distance, nodeStack);
      }
      else
      {
        // Neighbour node, the last subtree was iterated completly, thus the last node
        // can be assigned a post-order.
        // The parent node must be at the top of the node stack,
        // thus exit every node which comes after the parent node.
        // Distance starts with 0 but the stack size starts with 1.
        while(nodeStack.size() > step.distance)
        {
          exitNode(currentOrder, nodeStack);
        }
        // new node
        enterNode(currentOrder, step.node, startNode, step.distance, nodeStack);
      }
      lastDistance = step.distance;
    } // end for each DFS step

    while(!nodeStack.empty())
    {
      exitNode(currentOrder, nodeStack);
    }

  } // end for each root
}

void PrePostOrderStorage::clear()
{
  node2order.clear();
  order2node.clear();
  edgeAnno.clear();
}

void PrePostOrderStorage::enterNode(uint32_t& currentOrder, nodeid_t nodeID, nodeid_t rootNode,
                                        int level, NStack& nodeStack)
{
  NodeStackEntry newEntry;
  newEntry.id = nodeID;
  newEntry.order.pre = currentOrder++;
  newEntry.order.level = level;

  nodeStack.push(newEntry);
}

void PrePostOrderStorage::exitNode(uint32_t& currentOrder, NStack &nodeStack)
{
  // find the correct pre/post entry and update the post-value
  auto& entry = nodeStack.top();
  entry.order.post = currentOrder++;

  node2order.insert2(entry.id, entry.order);
  order2node[entry.order] = entry.id;

  nodeStack.pop();
}

bool PrePostOrderStorage::isConnected(const Edge &edge, unsigned int minDistance, unsigned int maxDistance) const
{
  const auto itSourceBegin = node2order.lower_bound(edge.source);
  const auto itSourceEnd = node2order.upper_bound(edge.source);

  for(auto itSource=itSourceBegin; itSource != itSourceEnd; itSource++)
  {
    auto itTargetRange = node2order.equal_range(edge.target);
    for(auto itTarget=itTargetRange.first; itTarget != itTargetRange.second; itTarget++)
    {
      if(itSource->second.pre <= itTarget->second.pre
         && itTarget->second.post <= itSource->second.post)
      {
        // check the level
        int diffLevel = (itTarget->second.level - itSource->second.level);
        if(minDistance <= diffLevel && diffLevel <= maxDistance)
        {
          return true;
        }
      }
    }
  }
  return false;
}

int PrePostOrderStorage::distance(const Edge &edge) const
{
  if(edge.source == edge.target)
  {
    return 0;
  }

  const auto itSourceBegin = node2order.lower_bound(edge.source);
  const auto itSourceEnd = node2order.upper_bound(edge.source);

  bool wasFound = false;
  int32_t minLevel = std::numeric_limits<int32_t>::max();

  for(auto itSource=itSourceBegin; itSource != itSourceEnd; itSource++)
  {
    auto itTargetRange = node2order.equal_range(edge.target);
    for(auto itTarget=itTargetRange.first; itTarget != itTargetRange.second; itTarget++)
    {
      if(itSource->second.pre <= itTarget->second.pre
         && itTarget->second.post <= itSource->second.post)
      {
        // check the level
        int32_t diffLevel = (itTarget->second.level - itSource->second.level);
        if(diffLevel >= 0)
        {
          wasFound = true;
          minLevel = std::min(minLevel, diffLevel);
        }
      }
    }
  }
  if(wasFound)
  {
    return minLevel;
  }
  else
  {
    return -1;
  }
}

std::unique_ptr<EdgeIterator> PrePostOrderStorage::findConnected(nodeid_t sourceNode, unsigned int minDistance, unsigned int maxDistance) const
{
  return std::unique_ptr<EdgeIterator>(
        new PrePostIterator(*this, sourceNode, minDistance, maxDistance));
}

std::vector<nodeid_t> PrePostOrderStorage::getOutgoingEdges(nodeid_t node) const
{
  std::vector<nodeid_t> result;
  result.reserve(10);

  auto connectedIt = findConnected(node, 1, 1);
  for(auto c=connectedIt->next(); c.first; c=connectedIt->next())
  {
    result.push_back(c.second);
  }

  return result;
}

std::vector<nodeid_t> PrePostOrderStorage::getIncomingEdges(nodeid_t node) const
{
  std::set<nodeid_t> sources;
  auto itRange = node2order.equal_range(node);
  for(auto itTarget=itRange.first; itTarget != itRange.second; itTarget++)
  {
    const auto& targetOrder = itTarget->second;
    // get all nodes that are potential predecessors
    PrePost minPrePost = {0, 0, 0};
    PrePost maxPrePost = {targetOrder.pre-1, uintmax, std::numeric_limits<int32_t>::max()};
    auto itMin = order2node.lower_bound(minPrePost);
    auto itMax = order2node.upper_bound(maxPrePost);
    for(auto itSource=itMin; itSource != itMax; itSource++)
    {
      const PrePost& sourceOrder = itSource->first;
      if(sourceOrder.level == targetOrder.level-1
         && targetOrder.post < sourceOrder.post
         && sourceOrder.pre < targetOrder.pre)
      {
        sources.insert(itSource->second);
      }
    }
  }

  std::vector<nodeid_t> result;
  result.reserve(sources.size());
  for(auto n : sources)
  {
    result.push_back(n);
  }
  return result;

}

PrePostIterator::PrePostIterator(const PrePostOrderStorage &storage, const nodeid_t &startNode,
                                 const unsigned int &minDistance, const unsigned int &maxDistance)
  : storage(storage), startNode(startNode),
    minDistance(minDistance), maxDistance(maxDistance)
{
  init();
}

std::pair<bool, nodeid_t> PrePostIterator::next()
{
  std::pair<bool, nodeid_t> result(0, false);

  while(!ranges.empty())
  {
    const auto& upper = ranges.top().upper;
    const auto& maximumPost = ranges.top().maximumPost;
    const auto& startLevel = ranges.top().startLevel;

    while(currentNode != upper)
    {
      const auto& currentPre = currentNode->first.pre;
      const auto& currentPost = currentNode->first.post;
      const auto& currentLevel = currentNode->first.level;

      int diffLevel = currentLevel - startLevel;

      // check post order and level as well
      if(currentPost <= maximumPost && minDistance <= diffLevel && diffLevel <= maxDistance
         && visited.find(currentNode->second) == visited.end())
      {
        // success
        result.first = true;
        result.second = currentNode->second;

        visited.insert(result.second);

        currentNode++;
        return result;
      }
      else if(currentPre < maximumPost)
      {
        // proceed with the next entry in the range
        currentNode++;
      }
      else
      {
        // abort searching in this range
        break;
      }
    } // end while range not finished yet

    // this range is finished, try next one
    ranges.pop();
    if(!ranges.empty())
    {
      currentNode = ranges.top().lower;
    }
  }

  return result;
}

void PrePostIterator::init()
{
  auto subComponentsLower = storage.node2order.lower_bound(startNode);
  auto subComponentsUpper = storage.node2order.upper_bound(startNode);

  for(auto it=subComponentsLower; it != subComponentsUpper; it++)
  {
    const auto& pre = it->second.pre;
    const auto& post = it->second.post;
    auto lowerIt = storage.order2node.lower_bound({pre, 0, 0});
    auto upperIt = storage.order2node.upper_bound({post, uintmax, std::numeric_limits<int32_t>::max()});

    ranges.push({lowerIt, upperIt, post, it->second.level});
  }
  if(!ranges.empty())
  {
    currentNode = ranges.top().lower;
  }
}

void PrePostIterator::reset()
{
  while(!ranges.empty())
  {
    ranges.pop();
  }

  visited.clear();

  init();
}

PrePostIterator::~PrePostIterator()
{

}
<commit_msg>use equal_range instead of seperate calls to lower_bound and upper_bound<commit_after>#include "prepostorderstorage.h"

#include "../dfs.h"
#include "../exactannovaluesearch.h"
#include "../exactannokeysearch.h"

#include <set>
#include <stack>

#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/map.hpp>

using namespace annis;

PrePostOrderStorage::PrePostOrderStorage(StringStorage &strings, const Component &component)
{

}

PrePostOrderStorage::~PrePostOrderStorage()
{

}

bool PrePostOrderStorage::load(std::string dirPath)
{
  node2order.clear();
  order2node.clear();

  bool result = edgeAnno.load(dirPath);
  std::ifstream in;

  in.open(dirPath + "/node2order.btree", std::ios::binary);
  result = result && node2order.restore(in);
  in.close();

  in.open(dirPath + "/order2node.btree", std::ios::binary);
  result = result && order2node.restore(in);
  in.close();

  return result;
}

bool PrePostOrderStorage::save(std::string dirPath)
{
  bool result = edgeAnno.save(dirPath);

  std::ofstream out;

  out.open(dirPath + "/node2order.btree", std::ios::binary);
  node2order.dump(out);
  out.close();

  out.open(dirPath + "/order2node.btree", std::ios::binary);
  order2node.dump(out);
  out.close();

  return result;

}

void PrePostOrderStorage::copy(const DB& db, const ReadableGraphStorage& orig)
{
  using ItType = stx::btree_set<Edge>::const_iterator;
  clear();

  // find all roots of the component
  std::set<nodeid_t> roots;
  ExactAnnoKeySearch nodes(db, annis_ns, annis_node_name);
  // first add all nodes that are a source of an edge as possible roots
  while(nodes.hasNext())
  {
    nodeid_t n = nodes.next().node;
    // insert all nodes to the root candidate list which are part of this component
    if(!orig.getOutgoingEdges(n).empty())
    {
      roots.insert(n);
    }
  }

  nodes.reset();
  while(nodes.hasNext())
  {
    nodeid_t source = nodes.next().node;

    std::vector<nodeid_t> outEdges = orig.getOutgoingEdges(source);
    for(auto target : outEdges)
    {
      Edge e = {source, target};

      // remove the nodes that have an incoming edge from the root list
      roots.erase(target);

      std::vector<Annotation> edgeAnnos = orig.getEdgeAnnotations(e);
      for(auto a : edgeAnnos)
      {
        edgeAnno.addEdgeAnnotation(e, a);
      }
    }
  }

  uint32_t currentOrder = 0;

  // traverse the graph for each sub-component
  for(const auto& startNode : roots)
  {
    unsigned int lastDistance = 0;

    NStack nodeStack;

    enterNode(currentOrder, startNode, startNode, 0, nodeStack);

    CycleSafeDFS dfs(orig, startNode, 1, uintmax);
    for(DFSIteratorResult step = dfs.nextDFS(); step.found;
          step = dfs.nextDFS())
    {
      if(step.distance > lastDistance)
      {
        // first visited, set pre-order
        enterNode(currentOrder, step.node, startNode, step.distance, nodeStack);
      }
      else
      {
        // Neighbour node, the last subtree was iterated completly, thus the last node
        // can be assigned a post-order.
        // The parent node must be at the top of the node stack,
        // thus exit every node which comes after the parent node.
        // Distance starts with 0 but the stack size starts with 1.
        while(nodeStack.size() > step.distance)
        {
          exitNode(currentOrder, nodeStack);
        }
        // new node
        enterNode(currentOrder, step.node, startNode, step.distance, nodeStack);
      }
      lastDistance = step.distance;
    } // end for each DFS step

    while(!nodeStack.empty())
    {
      exitNode(currentOrder, nodeStack);
    }

  } // end for each root
}

void PrePostOrderStorage::clear()
{
  node2order.clear();
  order2node.clear();
  edgeAnno.clear();
}

void PrePostOrderStorage::enterNode(uint32_t& currentOrder, nodeid_t nodeID, nodeid_t rootNode,
                                        int level, NStack& nodeStack)
{
  NodeStackEntry newEntry;
  newEntry.id = nodeID;
  newEntry.order.pre = currentOrder++;
  newEntry.order.level = level;

  nodeStack.push(newEntry);
}

void PrePostOrderStorage::exitNode(uint32_t& currentOrder, NStack &nodeStack)
{
  // find the correct pre/post entry and update the post-value
  auto& entry = nodeStack.top();
  entry.order.post = currentOrder++;

  node2order.insert2(entry.id, entry.order);
  order2node[entry.order] = entry.id;

  nodeStack.pop();
}

bool PrePostOrderStorage::isConnected(const Edge &edge, unsigned int minDistance, unsigned int maxDistance) const
{
  const auto itSourceBegin = node2order.lower_bound(edge.source);
  const auto itSourceEnd = node2order.upper_bound(edge.source);

  for(auto itSource=itSourceBegin; itSource != itSourceEnd; itSource++)
  {
    auto itTargetRange = node2order.equal_range(edge.target);
    for(auto itTarget=itTargetRange.first; itTarget != itTargetRange.second; itTarget++)
    {
      if(itSource->second.pre <= itTarget->second.pre
         && itTarget->second.post <= itSource->second.post)
      {
        // check the level
        int diffLevel = (itTarget->second.level - itSource->second.level);
        if(minDistance <= diffLevel && diffLevel <= maxDistance)
        {
          return true;
        }
      }
    }
  }
  return false;
}

int PrePostOrderStorage::distance(const Edge &edge) const
{
  if(edge.source == edge.target)
  {
    return 0;
  }

  const auto itSourceBegin = node2order.lower_bound(edge.source);
  const auto itSourceEnd = node2order.upper_bound(edge.source);

  bool wasFound = false;
  int32_t minLevel = std::numeric_limits<int32_t>::max();

  for(auto itSource=itSourceBegin; itSource != itSourceEnd; itSource++)
  {
    auto itTargetRange = node2order.equal_range(edge.target);
    for(auto itTarget=itTargetRange.first; itTarget != itTargetRange.second; itTarget++)
    {
      if(itSource->second.pre <= itTarget->second.pre
         && itTarget->second.post <= itSource->second.post)
      {
        // check the level
        int32_t diffLevel = (itTarget->second.level - itSource->second.level);
        if(diffLevel >= 0)
        {
          wasFound = true;
          minLevel = std::min(minLevel, diffLevel);
        }
      }
    }
  }
  if(wasFound)
  {
    return minLevel;
  }
  else
  {
    return -1;
  }
}

std::unique_ptr<EdgeIterator> PrePostOrderStorage::findConnected(nodeid_t sourceNode, unsigned int minDistance, unsigned int maxDistance) const
{
  return std::unique_ptr<EdgeIterator>(
        new PrePostIterator(*this, sourceNode, minDistance, maxDistance));
}

std::vector<nodeid_t> PrePostOrderStorage::getOutgoingEdges(nodeid_t node) const
{
  std::vector<nodeid_t> result;
  result.reserve(10);

  auto connectedIt = findConnected(node, 1, 1);
  for(auto c=connectedIt->next(); c.first; c=connectedIt->next())
  {
    result.push_back(c.second);
  }

  return result;
}

std::vector<nodeid_t> PrePostOrderStorage::getIncomingEdges(nodeid_t node) const
{
  std::set<nodeid_t> sources;
  auto itRange = node2order.equal_range(node);
  for(auto itTarget=itRange.first; itTarget != itRange.second; itTarget++)
  {
    const auto& targetOrder = itTarget->second;
    // get all nodes that are potential predecessors
    PrePost minPrePost = {0, 0, 0};
    PrePost maxPrePost = {targetOrder.pre-1, uintmax, std::numeric_limits<int32_t>::max()};
    auto itMin = order2node.lower_bound(minPrePost);
    auto itMax = order2node.upper_bound(maxPrePost);
    for(auto itSource=itMin; itSource != itMax; itSource++)
    {
      const PrePost& sourceOrder = itSource->first;
      if(sourceOrder.level == targetOrder.level-1
         && targetOrder.post < sourceOrder.post
         && sourceOrder.pre < targetOrder.pre)
      {
        sources.insert(itSource->second);
      }
    }
  }

  std::vector<nodeid_t> result;
  result.reserve(sources.size());
  for(auto n : sources)
  {
    result.push_back(n);
  }
  return result;

}

PrePostIterator::PrePostIterator(const PrePostOrderStorage &storage, const nodeid_t &startNode,
                                 const unsigned int &minDistance, const unsigned int &maxDistance)
  : storage(storage), startNode(startNode),
    minDistance(minDistance), maxDistance(maxDistance)
{
  init();
}

std::pair<bool, nodeid_t> PrePostIterator::next()
{
  std::pair<bool, nodeid_t> result(0, false);

  while(!ranges.empty())
  {
    const auto& upper = ranges.top().upper;
    const auto& maximumPost = ranges.top().maximumPost;
    const auto& startLevel = ranges.top().startLevel;

    while(currentNode != upper)
    {
      const auto& currentPre = currentNode->first.pre;
      const auto& currentPost = currentNode->first.post;
      const auto& currentLevel = currentNode->first.level;

      int diffLevel = currentLevel - startLevel;

      // check post order and level as well
      if(currentPost <= maximumPost && minDistance <= diffLevel && diffLevel <= maxDistance
         && visited.find(currentNode->second) == visited.end())
      {
        // success
        result.first = true;
        result.second = currentNode->second;

        visited.insert(result.second);

        currentNode++;
        return result;
      }
      else if(currentPre < maximumPost)
      {
        // proceed with the next entry in the range
        currentNode++;
      }
      else
      {
        // abort searching in this range
        break;
      }
    } // end while range not finished yet

    // this range is finished, try next one
    ranges.pop();
    if(!ranges.empty())
    {
      currentNode = ranges.top().lower;
    }
  }

  return result;
}

void PrePostIterator::init()
{
  auto subComponents = storage.node2order.equal_range(startNode);

  for(auto it=subComponents.first; it != subComponents.second; it++)
  {
    const auto& pre = it->second.pre;
    const auto& post = it->second.post;
    auto lowerIt = storage.order2node.lower_bound({pre, 0, 0});
    auto upperIt = storage.order2node.upper_bound({post, uintmax, std::numeric_limits<int32_t>::max()});

    ranges.push({lowerIt, upperIt, post, it->second.level});
  }
  if(!ranges.empty())
  {
    currentNode = ranges.top().lower;
  }
}

void PrePostIterator::reset()
{
  while(!ranges.empty())
  {
    ranges.pop();
  }

  visited.clear();

  init();
}

PrePostIterator::~PrePostIterator()
{

}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_aura.h"

#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h"
#include "content/browser/tab_contents/interstitial_page.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "ui/aura/window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/views_delegate.h"

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, public:

NativeTabContentsContainerAura::NativeTabContentsContainerAura(
    TabContentsContainer* container)
    : container_(container) {
  set_id(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
}

NativeTabContentsContainerAura::~NativeTabContentsContainerAura() {
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, NativeTabContentsContainer overrides:

void NativeTabContentsContainerAura::AttachContents(TabContents* contents) {
  // We need to register the tab contents window with the BrowserContainer so
  // that the BrowserContainer is the focused view when the focus is on the
  // TabContents window (for the TabContents case).
  set_focus_view(this);

  Attach(contents->GetNativeView());
}

void NativeTabContentsContainerAura::DetachContents(TabContents* contents) {
  // Detach the TabContents.  Do this before we unparent the
  // TabContentsViewViews so that the window hierarchy is intact for any
  // cleanup during Detach().
  Detach();
}

void NativeTabContentsContainerAura::SetFastResize(bool fast_resize) {
  set_fast_resize(fast_resize);
}

bool NativeTabContentsContainerAura::GetFastResize() const {
  return fast_resize();
}

bool NativeTabContentsContainerAura::FastResizeAtLastLayout() const {
  return fast_resize_at_last_layout();
}

void NativeTabContentsContainerAura::RenderViewHostChanged(
    RenderViewHost* old_host,
    RenderViewHost* new_host) {
  // If we are focused, we need to pass the focus to the new RenderViewHost.
  if (GetFocusManager()->GetFocusedView() == this)
    OnFocus();
}

views::View* NativeTabContentsContainerAura::GetView() {
  return this;
}

void NativeTabContentsContainerAura::TabContentsFocused(
    TabContents* tab_contents) {
  views::FocusManager* focus_manager = GetFocusManager();
  if (!focus_manager) {
    NOTREACHED();
    return;
  }
  focus_manager->SetFocusedView(this);
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, views::View overrides:

bool NativeTabContentsContainerAura::SkipDefaultKeyEventProcessing(
    const views::KeyEvent& e) {
  // Don't look-up accelerators or tab-traversal if we are showing a non-crashed
  // TabContents.
  // We'll first give the page a chance to process the key events.  If it does
  // not process them, they'll be returned to us and we'll treat them as
  // accelerators then.
  return container_->tab_contents() &&
         !container_->tab_contents()->is_crashed();
}

bool NativeTabContentsContainerAura::IsFocusable() const {
  // We need to be focusable when our contents is not a view hierarchy, as
  // clicking on the contents needs to focus us.
  return container_->tab_contents() != NULL;
}

void NativeTabContentsContainerAura::OnFocus() {
  if (container_->tab_contents())
    container_->tab_contents()->Focus();
}

void NativeTabContentsContainerAura::RequestFocus() {
  // This is a hack to circumvent the fact that a the OnFocus() method is not
  // invoked when RequestFocus() is called on an already focused view.
  // The TabContentsContainer is the view focused when the TabContents has
  // focus.  When switching between from one tab that has focus to another tab
  // that should also have focus, RequestFocus() is invoked one the
  // TabContentsContainer.  In order to make sure OnFocus() is invoked we need
  // to clear the focus before hands.
  {
    // Disable notifications.  Clear focus will assign the focus to the main
    // browser window.  Because this change of focus was not user requested,
    // don't send it to listeners.
    views::AutoNativeNotificationDisabler local_notification_disabler;
    GetFocusManager()->ClearFocus();
  }
  View::RequestFocus();
}

void NativeTabContentsContainerAura::AboutToRequestFocusFromTabTraversal(
    bool reverse) {
  container_->tab_contents()->FocusThroughTabTraversal(reverse);
}

void NativeTabContentsContainerAura::GetAccessibleState(
    ui::AccessibleViewState* state) {
  state->role = ui::AccessibilityTypes::ROLE_GROUPING;
}

gfx::NativeViewAccessible
    NativeTabContentsContainerAura::GetNativeViewAccessible() {
  // TODO(beng):
  NOTIMPLEMENTED();
  return View::GetNativeViewAccessible();
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainer, public:

// static
NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
    TabContentsContainer* container) {
  return new NativeTabContentsContainerAura(container);
}
<commit_msg>views: Fix the include path for views_delegate.h<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/tab_contents/native_tab_contents_container_aura.h"

#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h"
#include "content/browser/tab_contents/interstitial_page.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "ui/aura/window.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "views/views_delegate.h"

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, public:

NativeTabContentsContainerAura::NativeTabContentsContainerAura(
    TabContentsContainer* container)
    : container_(container) {
  set_id(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW);
}

NativeTabContentsContainerAura::~NativeTabContentsContainerAura() {
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, NativeTabContentsContainer overrides:

void NativeTabContentsContainerAura::AttachContents(TabContents* contents) {
  // We need to register the tab contents window with the BrowserContainer so
  // that the BrowserContainer is the focused view when the focus is on the
  // TabContents window (for the TabContents case).
  set_focus_view(this);

  Attach(contents->GetNativeView());
}

void NativeTabContentsContainerAura::DetachContents(TabContents* contents) {
  // Detach the TabContents.  Do this before we unparent the
  // TabContentsViewViews so that the window hierarchy is intact for any
  // cleanup during Detach().
  Detach();
}

void NativeTabContentsContainerAura::SetFastResize(bool fast_resize) {
  set_fast_resize(fast_resize);
}

bool NativeTabContentsContainerAura::GetFastResize() const {
  return fast_resize();
}

bool NativeTabContentsContainerAura::FastResizeAtLastLayout() const {
  return fast_resize_at_last_layout();
}

void NativeTabContentsContainerAura::RenderViewHostChanged(
    RenderViewHost* old_host,
    RenderViewHost* new_host) {
  // If we are focused, we need to pass the focus to the new RenderViewHost.
  if (GetFocusManager()->GetFocusedView() == this)
    OnFocus();
}

views::View* NativeTabContentsContainerAura::GetView() {
  return this;
}

void NativeTabContentsContainerAura::TabContentsFocused(
    TabContents* tab_contents) {
  views::FocusManager* focus_manager = GetFocusManager();
  if (!focus_manager) {
    NOTREACHED();
    return;
  }
  focus_manager->SetFocusedView(this);
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainerAura, views::View overrides:

bool NativeTabContentsContainerAura::SkipDefaultKeyEventProcessing(
    const views::KeyEvent& e) {
  // Don't look-up accelerators or tab-traversal if we are showing a non-crashed
  // TabContents.
  // We'll first give the page a chance to process the key events.  If it does
  // not process them, they'll be returned to us and we'll treat them as
  // accelerators then.
  return container_->tab_contents() &&
         !container_->tab_contents()->is_crashed();
}

bool NativeTabContentsContainerAura::IsFocusable() const {
  // We need to be focusable when our contents is not a view hierarchy, as
  // clicking on the contents needs to focus us.
  return container_->tab_contents() != NULL;
}

void NativeTabContentsContainerAura::OnFocus() {
  if (container_->tab_contents())
    container_->tab_contents()->Focus();
}

void NativeTabContentsContainerAura::RequestFocus() {
  // This is a hack to circumvent the fact that a the OnFocus() method is not
  // invoked when RequestFocus() is called on an already focused view.
  // The TabContentsContainer is the view focused when the TabContents has
  // focus.  When switching between from one tab that has focus to another tab
  // that should also have focus, RequestFocus() is invoked one the
  // TabContentsContainer.  In order to make sure OnFocus() is invoked we need
  // to clear the focus before hands.
  {
    // Disable notifications.  Clear focus will assign the focus to the main
    // browser window.  Because this change of focus was not user requested,
    // don't send it to listeners.
    views::AutoNativeNotificationDisabler local_notification_disabler;
    GetFocusManager()->ClearFocus();
  }
  View::RequestFocus();
}

void NativeTabContentsContainerAura::AboutToRequestFocusFromTabTraversal(
    bool reverse) {
  container_->tab_contents()->FocusThroughTabTraversal(reverse);
}

void NativeTabContentsContainerAura::GetAccessibleState(
    ui::AccessibleViewState* state) {
  state->role = ui::AccessibilityTypes::ROLE_GROUPING;
}

gfx::NativeViewAccessible
    NativeTabContentsContainerAura::GetNativeViewAccessible() {
  // TODO(beng):
  NOTIMPLEMENTED();
  return View::GetNativeViewAccessible();
}

////////////////////////////////////////////////////////////////////////////////
// NativeTabContentsContainer, public:

// static
NativeTabContentsContainer* NativeTabContentsContainer::CreateNativeContainer(
    TabContentsContainer* container) {
  return new NativeTabContentsContainerAura(container);
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/sbeio/sbeioreasoncodes.H $                    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2013,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __SBEIOREASONCODES_H
#define __SBEIOREASONCODES_H

// -----------------------------------------------
// Includes
// -----------------------------------------------
#include <hbotcompid.H>

namespace SBEIO
{

/**
* @enum SbeioModuleid
*
* @brief Module Ids used in created errorlogs.  Indicates which
*      functions an error log was created in.
*
*/
enum sbeioModuleId
{
    SBEIO_INVALID_MODULE                = 0x00,
    SBEIO_PSU                           = 0x01,
    SBEIO_FIFO                          = 0x02,
    SBEIO_FFDC_PARSER                   = 0x03,
};

/**
 * @enum sbeReasonCode
 *
 * @brief Reasoncodes used to describe what errors are being indicated.
 *
 */
enum sbeioReasonCode
{
    SBEIO_INVALID_REASONCODE           = SBEIO_COMP_ID | 0x00,   // Invalid RC

    // SBE PSU error codes
    SBEIO_PSU_RESPONSE_TIMEOUT         = SBEIO_COMP_ID | 0x01,
    SBEIO_PSU_RESPONSE_ERROR           = SBEIO_COMP_ID | 0x02,
    SBEIO_PSU_NOT_READY                = SBEIO_COMP_ID | 0x03,

    // SBE FIFO error codes
    SBEIO_FIFO_UPSTREAM_TIMEOUT        = SBEIO_COMP_ID | 0x10,
    SBEIO_FIFO_NO_DOWNSTREAM_EOT       = SBEIO_COMP_ID | 0x11,
    SBEIO_FIFO_INVALID_STATUS_DISTANCE = SBEIO_COMP_ID | 0x12,
    SBEIO_FIFO_RESPONSE_ERROR          = SBEIO_COMP_ID | 0x13,
    SBEIO_FIFO_DOWNSTREAM_TIMEOUT      = SBEIO_COMP_ID | 0x14,
    SBEIO_FIFO_INVALID_LENGTH          = SBEIO_COMP_ID | 0x15,
    SBEIO_FIFO_INVALID_OPERATION       = SBEIO_COMP_ID | 0x16,
    SBEIO_FIFO_NULL_TARGET             = SBEIO_COMP_ID | 0x17,
    SBEIO_FIFO_MASTER_TARGET           = SBEIO_COMP_ID | 0x18,
    SBEIO_FIFO_SENTINEL_TARGET         = SBEIO_COMP_ID | 0x19,

    // SBE FFDC Parser error codes
    SBEIO_FFDC_PARSER_BUFF_OVERFLOW    = SBEIO_COMP_ID | 0x1A,

    // Remove once we collect the FFDC ourselves - @todo-RTC:144313
    //termination_rc
    SBEIO_HWSV_COLLECT_SBE_RC          = SBEIO_COMP_ID | 0xFF,
};

};  // end SBE

#endif
<commit_msg>Add SBEIO_DEAD_SBE to trigger reconfig loop<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/sbeio/sbeioreasoncodes.H $                    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2013,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __SBEIOREASONCODES_H
#define __SBEIOREASONCODES_H

// -----------------------------------------------
// Includes
// -----------------------------------------------
#include <hbotcompid.H>

namespace SBEIO
{

/**
* @enum SbeioModuleid
*
* @brief Module Ids used in created errorlogs.  Indicates which
*      functions an error log was created in.
*
*/
enum sbeioModuleId
{
    SBEIO_INVALID_MODULE                = 0x00,
    SBEIO_PSU                           = 0x01,
    SBEIO_FIFO                          = 0x02,
    SBEIO_FFDC_PARSER                   = 0x03,
};

/**
 * @enum sbeReasonCode
 *
 * @brief Reasoncodes used to describe what errors are being indicated.
 *
 */
enum sbeioReasonCode
{
    SBEIO_INVALID_REASONCODE           = SBEIO_COMP_ID | 0x00,   // Invalid RC

    // SBE PSU error codes
    SBEIO_PSU_RESPONSE_TIMEOUT         = SBEIO_COMP_ID | 0x01,
    SBEIO_PSU_RESPONSE_ERROR           = SBEIO_COMP_ID | 0x02,
    SBEIO_PSU_NOT_READY                = SBEIO_COMP_ID | 0x03,

    // SBE FIFO error codes
    SBEIO_FIFO_UPSTREAM_TIMEOUT        = SBEIO_COMP_ID | 0x10,
    SBEIO_FIFO_NO_DOWNSTREAM_EOT       = SBEIO_COMP_ID | 0x11,
    SBEIO_FIFO_INVALID_STATUS_DISTANCE = SBEIO_COMP_ID | 0x12,
    SBEIO_FIFO_RESPONSE_ERROR          = SBEIO_COMP_ID | 0x13,
    SBEIO_FIFO_DOWNSTREAM_TIMEOUT      = SBEIO_COMP_ID | 0x14,
    SBEIO_FIFO_INVALID_LENGTH          = SBEIO_COMP_ID | 0x15,
    SBEIO_FIFO_INVALID_OPERATION       = SBEIO_COMP_ID | 0x16,
    SBEIO_FIFO_NULL_TARGET             = SBEIO_COMP_ID | 0x17,
    SBEIO_FIFO_MASTER_TARGET           = SBEIO_COMP_ID | 0x18,
    SBEIO_FIFO_SENTINEL_TARGET         = SBEIO_COMP_ID | 0x19,

    // SBE FFDC Parser error codes
    SBEIO_FFDC_PARSER_BUFF_OVERFLOW    = SBEIO_COMP_ID | 0x1A,

    // Note - HWSV keys off of this to trigger a reconfig
    //   loop to recover the SBE
    //termination_rc
    SBEIO_DEAD_SBE                     = SBEIO_COMP_ID | 0x1B,

    // Remove once we collect the FFDC ourselves - @todo-RTC:144313
    //termination_rc
    SBEIO_HWSV_COLLECT_SBE_RC          = SBEIO_COMP_ID | 0xFF,
};

};  // end SBE

#endif
<|endoftext|>


<commit_before>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#include <triton/cpuSize.hpp>
#include <triton/exceptions.hpp>
#include <triton/tritonToZ3Ast.hpp>

namespace triton {
  namespace ast {

    TritonToZ3Ast::TritonToZ3Ast(triton::engines::symbolic::SymbolicEngine* symbolicEngine, bool eval)
      : context() {
      if (symbolicEngine == nullptr)
        throw triton::exceptions::AstTranslations("TritonToZ3Ast::TritonToZ3Ast(): The symbolicEngine API cannot be null.");

      this->symbolicEngine = symbolicEngine;
      this->isEval = eval;
    }

    triton::__uint TritonToZ3Ast::getUintValue(const z3::expr& expr) {
      triton::__uint result = 0;

      if (!expr.is_int())
        throw triton::exceptions::Exception("TritonToZ3Ast::getUintValue(): The ast is not a numerical value.");

      #if defined(__x86_64__) || defined(_M_X64)
      Z3_get_numeral_uint64(this->context, expr, &result);
      #endif
      #if defined(__i386) || defined(_M_IX86)
      Z3_get_numeral_uint(this->context, expr, &result);
      #endif

      return result;
    }

    std::string TritonToZ3Ast::getStringValue(const z3::expr& expr) {
      return Z3_get_numeral_string(this->context, expr);
    }

    z3::context& TritonToZ3Ast::getContext(void) {
      return this->context;
    }

    z3::expr TritonToZ3Ast::convert(triton::ast::AbstractNode* node) {
      if (node == nullptr)
        throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): node cannot be null.");

      switch (node->getKind()) {
        case BVADD_NODE:
          return to_expr(this->context, Z3_mk_bvadd(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVAND_NODE:
          return to_expr(this->context, Z3_mk_bvand(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVASHR_NODE:
          return to_expr(this->context, Z3_mk_bvashr(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVLSHR_NODE:
          return to_expr(this->context, Z3_mk_bvlshr(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVMUL_NODE:
          return to_expr(this->context, Z3_mk_bvmul(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNAND_NODE:
          return to_expr(this->context, Z3_mk_bvnand(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNEG_NODE:
          return to_expr(this->context, Z3_mk_bvneg(this->context, this->convert(node->getChildren()[0])));

        case BVNOR_NODE:
          return to_expr(this->context, Z3_mk_bvnor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNOT_NODE:
          return to_expr(this->context, Z3_mk_bvnot(this->context, this->convert(node->getChildren()[0])));

        case BVOR_NODE:
          return to_expr(this->context, Z3_mk_bvor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVROL_NODE: {
          triton::uint32 op1 = reinterpret_cast<triton::ast::DecimalNode*>(node->getChildren()[0])->getValue().convert_to<triton::uint32>();
          return to_expr(this->context, Z3_mk_rotate_left(this->context, op1, this->convert(node->getChildren()[1])));
        }

        case BVROR_NODE: {
          triton::uint32 op1 = reinterpret_cast<triton::ast::DecimalNode*>(node->getChildren()[0])->getValue().convert_to<triton::uint32>();
          return to_expr(this->context, Z3_mk_rotate_right(this->context, op1, this->convert(node->getChildren()[1])));
        }

        case BVSDIV_NODE:
          return to_expr(this->context, Z3_mk_bvsdiv(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSGE_NODE:
          return to_expr(this->context, Z3_mk_bvsge(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSGT_NODE:
          return to_expr(this->context, Z3_mk_bvsgt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSHL_NODE:
          return to_expr(this->context, Z3_mk_bvshl(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSLE_NODE:
          return to_expr(this->context, Z3_mk_bvsle(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSLT_NODE:
          return to_expr(this->context, Z3_mk_bvslt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSMOD_NODE:
          return to_expr(this->context, Z3_mk_bvsmod(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSREM_NODE:
          return to_expr(this->context, Z3_mk_bvsrem(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSUB_NODE:
          return to_expr(this->context, Z3_mk_bvsub(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUDIV_NODE:
          return to_expr(this->context, Z3_mk_bvudiv(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUGE_NODE:
          return to_expr(this->context, Z3_mk_bvuge(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUGT_NODE:
          return to_expr(this->context, Z3_mk_bvugt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVULE_NODE:
          return to_expr(this->context, Z3_mk_bvule(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVULT_NODE:
          return to_expr(this->context, Z3_mk_bvult(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUREM_NODE:
          return to_expr(this->context, Z3_mk_bvurem(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVXNOR_NODE:
          return to_expr(this->context, Z3_mk_bvxnor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVXOR_NODE:
          return to_expr(this->context, Z3_mk_bvxor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BV_NODE: {
          z3::expr value        = this->convert(node->getChildren()[0]);
          z3::expr size         = this->convert(node->getChildren()[1]);
          triton::uint32 bvsize = static_cast<triton::uint32>(this->getUintValue(size));
          return this->context.bv_val(this->getStringValue(value).c_str(), bvsize);
        }

        case CONCAT_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          // Child[0] is the LSB
          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue = this->convert(children[idx]);
            currentValue = to_expr(this->context, Z3_mk_concat(this->context, currentValue, nextValue));
          }

          return currentValue;
        }

        case DECIMAL_NODE: {
          std::string value(reinterpret_cast<triton::ast::DecimalNode*>(node)->getValue());
          return this->context.int_val(value.c_str());
        }

        case DISTINCT_NODE: {
          z3::expr op1 = this->convert(node->getChildren()[0]);
          z3::expr op2 = this->convert(node->getChildren()[1]);
          Z3_ast ops[] = {op1, op2};

          return to_expr(this->context, Z3_mk_distinct(this->context, 2, ops));
        }

        case EQUAL_NODE:
          return to_expr(this->context, Z3_mk_eq(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case EXTRACT_NODE: {
          z3::expr high     = this->convert(node->getChildren()[0]);
          z3::expr low      = this->convert(node->getChildren()[1]);
          z3::expr value    = this->convert(node->getChildren()[2]);
          triton::uint32 hv = static_cast<triton::uint32>(this->getUintValue(high));
          triton::uint32 lv = static_cast<triton::uint32>(this->getUintValue(low));

          return to_expr(this->context, Z3_mk_extract(this->context, hv, lv, value));
        }

        case ITE_NODE: {
          z3::expr op1 = this->convert(node->getChildren()[0]); // condition
          z3::expr op2 = this->convert(node->getChildren()[1]); // if true
          z3::expr op3 = this->convert(node->getChildren()[2]); // if false

          return to_expr(this->context, Z3_mk_ite(this->context, op1, op2, op3));
        }

        case LAND_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue    = this->convert(children[idx]);
            Z3_ast ops[] = {currentValue, nextValue};
            currentValue = to_expr(this->context, Z3_mk_and(this->context, 2, ops));
          }

          return currentValue;
        }

        case LET_NODE: {
          std::string symbol    = reinterpret_cast<triton::ast::StringNode*>(node->getChildren()[0])->getValue();
          this->symbols[symbol] = node->getChildren()[1];

          return this->convert(node->getChildren()[2]);
        }

        case LNOT_NODE:
          return to_expr(this->context, Z3_mk_not(this->context, this->convert(node->getChildren()[0])));

        case LOR_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue    = this->convert(children[idx]);
            Z3_ast ops[] = {currentValue, nextValue};
            currentValue = to_expr(this->context, Z3_mk_or(this->context, 2, ops));
          }

          return currentValue;
        }

        case REFERENCE_NODE:
          return this->convert(reinterpret_cast<triton::ast::ReferenceNode*>(node)->getSymbolicExpression().getAst());

        case STRING_NODE: {
          std::string value = reinterpret_cast<triton::ast::StringNode*>(node)->getValue();

          if (this->symbols.find(value) == this->symbols.end())
            throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): [STRING_NODE] Symbols not found.");

          return this->convert(this->symbols[value]);
        }

        case SX_NODE: {
          z3::expr ext        = this->convert(node->getChildren()[0]);
          z3::expr value      = this->convert(node->getChildren()[1]);
          triton::uint32 extv = static_cast<triton::uint32>(this->getUintValue(ext));

          return to_expr(this->context, Z3_mk_sign_ext(this->context, extv, value));
        }

        case VARIABLE_NODE: {
          std::string varName = reinterpret_cast<triton::ast::VariableNode*>(node)->getVar().getName();
          triton::engines::symbolic::SymbolicVariable* symVar = this->symbolicEngine->getSymbolicVariableFromName(varName);

          if (symVar == nullptr)
            throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): [VARIABLE_NODE] Can't get the symbolic variable (nullptr).");

          /* If the conversion is used to evaluate a node, we concretize symbolic variables */
          if (this->isEval) {
            triton::uint512 value = reinterpret_cast<triton::ast::VariableNode*>(node)->evaluate();
            std::string strValue(value);
            return this->context.bv_val(strValue.c_str(), symVar->getSize());
          }

          /* Otherwise, we keep the symbolic variables for a real conversion */
          return this->context.bv_const(symVar->getName().c_str(), symVar->getSize());
        }

        case ZX_NODE: {
          z3::expr ext        = this->convert(node->getChildren()[0]);
          z3::expr value      = this->convert(node->getChildren()[1]);
          triton::uint32 extv = static_cast<triton::uint32>(this->getUintValue(ext));

          return to_expr(this->context, Z3_mk_zero_ext(this->context, extv, value));
        }

        default:
          throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): Invalid kind of node.");
      }
    }

  }; /* ast namespace */
}; /* triton namespace */
<commit_msg>[review] Update z3 things<commit_after>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#include <triton/cpuSize.hpp>
#include <triton/exceptions.hpp>
#include <triton/tritonToZ3Ast.hpp>

namespace triton {
  namespace ast {

    TritonToZ3Ast::TritonToZ3Ast(triton::engines::symbolic::SymbolicEngine* symbolicEngine, bool eval)
      : context() {
      if (symbolicEngine == nullptr)
        throw triton::exceptions::AstTranslations("TritonToZ3Ast::TritonToZ3Ast(): The symbolicEngine API cannot be null.");

      this->symbolicEngine = symbolicEngine;
      this->isEval = eval;
    }

    triton::__uint TritonToZ3Ast::getUintValue(const z3::expr& expr) {
      triton::__uint result = 0;

      if (!expr.is_int())
        throw triton::exceptions::Exception("TritonToZ3Ast::getUintValue(): The ast is not a numerical value.");

      #if defined(__x86_64__) || defined(_M_X64)
      Z3_get_numeral_uint64(this->context, expr, &result);
      #endif
      #if defined(__i386) || defined(_M_IX86)
      Z3_get_numeral_uint(this->context, expr, &result);
      #endif

      return result;
    }

    std::string TritonToZ3Ast::getStringValue(const z3::expr& expr) {
      std::string out;
      if(!expr.is_numeral(out))
        throw triton::exceptions::Exception("TritonToZ3Ast::getStringValue(): The ast is not a numerical value.");
      return out;
    }

    z3::context& TritonToZ3Ast::getContext(void) {
      return this->context;
    }

    z3::expr TritonToZ3Ast::convert(triton::ast::AbstractNode* node) {
      if (node == nullptr)
        throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): node cannot be null.");

      switch (node->getKind()) {
        case BVADD_NODE:
          return to_expr(this->context, Z3_mk_bvadd(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVAND_NODE:
          return to_expr(this->context, Z3_mk_bvand(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVASHR_NODE:
          return to_expr(this->context, Z3_mk_bvashr(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVLSHR_NODE:
          return to_expr(this->context, Z3_mk_bvlshr(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVMUL_NODE:
          return to_expr(this->context, Z3_mk_bvmul(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNAND_NODE:
          return to_expr(this->context, Z3_mk_bvnand(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNEG_NODE:
          return to_expr(this->context, Z3_mk_bvneg(this->context, this->convert(node->getChildren()[0])));

        case BVNOR_NODE:
          return to_expr(this->context, Z3_mk_bvnor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVNOT_NODE:
          return to_expr(this->context, Z3_mk_bvnot(this->context, this->convert(node->getChildren()[0])));

        case BVOR_NODE:
          return to_expr(this->context, Z3_mk_bvor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVROL_NODE: {
          triton::uint32 op1 = reinterpret_cast<triton::ast::DecimalNode*>(node->getChildren()[0])->getValue().convert_to<triton::uint32>();
          return to_expr(this->context, Z3_mk_rotate_left(this->context, op1, this->convert(node->getChildren()[1])));
        }

        case BVROR_NODE: {
          triton::uint32 op1 = reinterpret_cast<triton::ast::DecimalNode*>(node->getChildren()[0])->getValue().convert_to<triton::uint32>();
          return to_expr(this->context, Z3_mk_rotate_right(this->context, op1, this->convert(node->getChildren()[1])));
        }

        case BVSDIV_NODE:
          return to_expr(this->context, Z3_mk_bvsdiv(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSGE_NODE:
          return to_expr(this->context, Z3_mk_bvsge(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSGT_NODE:
          return to_expr(this->context, Z3_mk_bvsgt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSHL_NODE:
          return to_expr(this->context, Z3_mk_bvshl(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSLE_NODE:
          return to_expr(this->context, Z3_mk_bvsle(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSLT_NODE:
          return to_expr(this->context, Z3_mk_bvslt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSMOD_NODE:
          return to_expr(this->context, Z3_mk_bvsmod(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSREM_NODE:
          return to_expr(this->context, Z3_mk_bvsrem(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVSUB_NODE:
          return to_expr(this->context, Z3_mk_bvsub(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUDIV_NODE:
          return to_expr(this->context, Z3_mk_bvudiv(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUGE_NODE:
          return to_expr(this->context, Z3_mk_bvuge(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUGT_NODE:
          return to_expr(this->context, Z3_mk_bvugt(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVULE_NODE:
          return to_expr(this->context, Z3_mk_bvule(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVULT_NODE:
          return to_expr(this->context, Z3_mk_bvult(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVUREM_NODE:
          return to_expr(this->context, Z3_mk_bvurem(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVXNOR_NODE:
          return to_expr(this->context, Z3_mk_bvxnor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BVXOR_NODE:
          return to_expr(this->context, Z3_mk_bvxor(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case BV_NODE: {
          z3::expr value        = this->convert(node->getChildren()[0]);
          z3::expr size         = this->convert(node->getChildren()[1]);
          triton::uint32 bvsize = static_cast<triton::uint32>(this->getUintValue(size));
          return this->context.bv_val(this->getStringValue(value).c_str(), bvsize);
        }

        case CONCAT_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          // Child[0] is the LSB
          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue = this->convert(children[idx]);
            currentValue = to_expr(this->context, Z3_mk_concat(this->context, currentValue, nextValue));
          }

          return currentValue;
        }

        case DECIMAL_NODE: {
          std::string value(reinterpret_cast<triton::ast::DecimalNode*>(node)->getValue());
          return this->context.int_val(value.c_str());
        }

        case DISTINCT_NODE: {
          z3::expr op1 = this->convert(node->getChildren()[0]);
          z3::expr op2 = this->convert(node->getChildren()[1]);
          Z3_ast ops[] = {op1, op2};

          return to_expr(this->context, Z3_mk_distinct(this->context, 2, ops));
        }

        case EQUAL_NODE:
          return to_expr(this->context, Z3_mk_eq(this->context, this->convert(node->getChildren()[0]), this->convert(node->getChildren()[1])));

        case EXTRACT_NODE: {
          z3::expr high     = this->convert(node->getChildren()[0]);
          z3::expr low      = this->convert(node->getChildren()[1]);
          z3::expr value    = this->convert(node->getChildren()[2]);
          triton::uint32 hv = static_cast<triton::uint32>(this->getUintValue(high));
          triton::uint32 lv = static_cast<triton::uint32>(this->getUintValue(low));

          return to_expr(this->context, Z3_mk_extract(this->context, hv, lv, value));
        }

        case ITE_NODE: {
          z3::expr op1 = this->convert(node->getChildren()[0]); // condition
          z3::expr op2 = this->convert(node->getChildren()[1]); // if true
          z3::expr op3 = this->convert(node->getChildren()[2]); // if false

          return to_expr(this->context, Z3_mk_ite(this->context, op1, op2, op3));
        }

        case LAND_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue    = this->convert(children[idx]);
            Z3_ast ops[] = {currentValue, nextValue};
            currentValue = to_expr(this->context, Z3_mk_and(this->context, 2, ops));
          }

          return currentValue;
        }

        case LET_NODE: {
          std::string symbol    = reinterpret_cast<triton::ast::StringNode*>(node->getChildren()[0])->getValue();
          this->symbols[symbol] = node->getChildren()[1];

          return this->convert(node->getChildren()[2]);
        }

        case LNOT_NODE:
          return to_expr(this->context, Z3_mk_not(this->context, this->convert(node->getChildren()[0])));

        case LOR_NODE: {
          const std::vector<triton::ast::AbstractNode*>& children = node->getChildren();

          z3::expr currentValue = this->convert(node->getChildren()[0]);
          z3::expr nextValue(this->context);

          for (triton::uint32 idx = 1; idx < children.size(); idx++) {
            nextValue    = this->convert(children[idx]);
            Z3_ast ops[] = {currentValue, nextValue};
            currentValue = to_expr(this->context, Z3_mk_or(this->context, 2, ops));
          }

          return currentValue;
        }

        case REFERENCE_NODE:
          return this->convert(reinterpret_cast<triton::ast::ReferenceNode*>(node)->getSymbolicExpression().getAst());

        case STRING_NODE: {
          std::string value = reinterpret_cast<triton::ast::StringNode*>(node)->getValue();

          if (this->symbols.find(value) == this->symbols.end())
            throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): [STRING_NODE] Symbols not found.");

          return this->convert(this->symbols[value]);
        }

        case SX_NODE: {
          z3::expr ext        = this->convert(node->getChildren()[0]);
          z3::expr value      = this->convert(node->getChildren()[1]);
          triton::uint32 extv = static_cast<triton::uint32>(this->getUintValue(ext));

          return to_expr(this->context, Z3_mk_sign_ext(this->context, extv, value));
        }

        case VARIABLE_NODE: {
          std::string varName = reinterpret_cast<triton::ast::VariableNode*>(node)->getVar().getName();
          triton::engines::symbolic::SymbolicVariable* symVar = this->symbolicEngine->getSymbolicVariableFromName(varName);

          if (symVar == nullptr)
            throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): [VARIABLE_NODE] Can't get the symbolic variable (nullptr).");

          /* If the conversion is used to evaluate a node, we concretize symbolic variables */
          if (this->isEval) {
            triton::uint512 value = reinterpret_cast<triton::ast::VariableNode*>(node)->evaluate();
            std::string strValue(value);
            return this->context.bv_val(strValue.c_str(), symVar->getSize());
          }

          /* Otherwise, we keep the symbolic variables for a real conversion */
          return this->context.bv_const(symVar->getName().c_str(), symVar->getSize());
        }

        case ZX_NODE: {
          z3::expr ext        = this->convert(node->getChildren()[0]);
          z3::expr value      = this->convert(node->getChildren()[1]);
          triton::uint32 extv = static_cast<triton::uint32>(this->getUintValue(ext));

          return to_expr(this->context, Z3_mk_zero_ext(this->context, extv, value));
        }

        default:
          throw triton::exceptions::AstTranslations("TritonToZ3Ast::convert(): Invalid kind of node.");
      }
    }

  }; /* ast namespace */
}; /* triton namespace */
<|endoftext|>


<commit_before>// Copyright (c) 2019 The Stealth Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "QPQueue.hpp"
#include "util.h"

#include <sstream>

using namespace std;

unsigned int BitIsOn(const valtype& vch, unsigned int nBit)
{
    unsigned int nByte = nBit / 8;
    unsigned int nSize = vch.size();
    if (nByte >= nSize)
    {
        return 0;
    }
    return vch[nByte] & (0x80 >> (nBit % 8));
}

unsigned int SetBit(valtype& vch, unsigned int nBit)
{
     unsigned int nByte = nBit / 8;
     unsigned int nSize = vch.size();
     if (nByte >= nSize)
     {
         return 0;
     }
     unsigned char& chByte = vch[nByte];
     unsigned int nBitValue = 0x80 >> (nBit % 8);
     chByte |= nBitValue;
     return nBitValue;
}

const char* GetSlotStatusType(const QPSlotStatus status)
{
    switch (status)
    {
    case QPSLOT_INVALID:
        return "invalid";
    case QPSLOT_MISSED:
        return "missed";
    case QPSLOT_HIT:
        return "produced";
    case QPSLOT_CURRENT:
        return "current";
    case QPSLOT_FUTURE:
        return "future";
    }
}

const char* GetSlotStatusAbbrev(const QPSlotStatus status)
{
    switch (status)
    {
    case QPSLOT_INVALID:
        return "!";
    case QPSLOT_MISSED:
        return "x";
    case QPSLOT_HIT:
        return "+";
    case QPSLOT_CURRENT:
        return "-";
    case QPSLOT_FUTURE:
        return "o";
    }
}

QPQueue::QPQueue()
{
    SetNull();
}

QPQueue::QPQueue(unsigned int nSlotTime0In,
        const vector<unsigned int>& vStakerIDsIn)
{
    nVersion = QPQueue::CURRENT_VERSION;
    nCurrentSlot = 0;
    nSlotTime0 = nSlotTime0In;
    vStakerIDs = vStakerIDsIn;
    unsigned int nSize = vStakerIDs.size();
    if (nSize % 8 == 0)
    {
        vchBlockStats.resize(nSize / 8);
    }
    else
    {
        vchBlockStats.resize((nSize / 8) + 1);
    }
    fill(vchBlockStats.begin(), vchBlockStats.end(), 0);
}

void QPQueue::SetNull()
{
    nVersion = QPQueue::CURRENT_VERSION;
    nCurrentSlot = 0;
    nSlotTime0 = 0;
    vStakerIDs.clear();
    vchBlockStats.clear();
}

unsigned int QPQueue::GetCurrentSlot() const
{
    return nCurrentSlot;
}

const std::vector<unsigned int>& QPQueue::GetStakerIDs() const
{
    return vStakerIDs;
}

const valtype& QPQueue::GetBlockStats() const
{
    return vchBlockStats;
}

bool QPQueue::GetIDForSlot(unsigned int slot, unsigned int &nIDRet) const
{
    if (slot >= vStakerIDs.size())
    {
         return false;
    }
    nIDRet = vStakerIDs[slot];
    return true;
}
bool QPQueue::GetSlotForID(unsigned int nID, unsigned int& nSlotRet) const
{
    bool found = false;
    unsigned int slot = 0;
    QPQueueIterator it;
    for (it = vStakerIDs.begin(); it != vStakerIDs.end(); ++it)
    {
        if (*it == nID)
        {
            nSlotRet = slot;
            found = true;
            break;
        }
        ++slot;
    }
    return found;
}

bool QPQueue::GetWindowForID(unsigned int nID, QPWindow& windowRet) const
{
    unsigned int slot;
    if (!GetSlotForID(nID, slot))
    {
        return false;
    }
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * slot);
        windowRet.start = start;
        windowRet.end = start + QP_TARGET_TIME - 1;
    return true;
}

bool QPQueue::GetWindowForSlot(unsigned int nSlot, QPWindow& windowRet) const
{
    if (nSlot >= vStakerIDs.size())
    {
        return false;
    }
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nSlot);
    windowRet.start = start;
        windowRet.end = start + QP_TARGET_TIME - 1;
    return true;
}

bool QPQueue::GetStatusForSlot(unsigned int nSlot, QPSlotStatus& status) const
{
    if (nSlot >= vStakerIDs.size())
    {
        status = QPSLOT_INVALID;
        return false;
    }
    if (nSlot > nCurrentSlot)
    {
        status = QPSLOT_FUTURE;
    }
    else
    {
        unsigned int nBit = nSlot +
                            (vchBlockStats.size() * 8) -
                            vStakerIDs.size();
        if (BitIsOn(vchBlockStats, nBit))
        {
            status = QPSLOT_HIT;
        }
        else if (nSlot == nCurrentSlot)
        {
            status = QPSLOT_CURRENT;
        }
        else
        {
            status = QPSLOT_MISSED;
        }
    }
    return true;
}

unsigned int QPQueue::GetMinTime() const
{
    return nSlotTime0;
}

unsigned int QPQueue::GetMaxTime() const
{
    unsigned int nSize = static_cast<unsigned int>(vStakerIDs.size());
    return nSlotTime0 + (QP_TARGET_TIME * nSize) - 1;
}

bool QPQueue::GetSlotStartTime(unsigned int nSlot, unsigned int &nTimeRet) const
{
    if (nSlot >= vStakerIDs.size())
    {
        return false;
    }
    nTimeRet = nSlotTime0 + (QP_TARGET_TIME * (unsigned int)nSlot);
    return true;
}

bool QPQueue::GetSlotForTime(unsigned int nTime, unsigned int &nSlotRet) const
{
    if (nTime < nSlotTime0)
    {
        return error("GetSlotForTime(): time %u too early", nTime);
    }
    if (nTime > GetMaxTime())
    {
        return error("GetSlotForTime(): time %u too late", nTime);
    }
    nSlotRet = (nTime - nSlotTime0) / QP_TARGET_TIME;
    return true;
}

unsigned int QPQueue::GetCurrentSlotStart() const
{
    return nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
}

unsigned int QPQueue::GetCurrentSlotEnd() const
{
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
    return start + QP_TARGET_TIME - 1;
}

QPWindow QPQueue::GetCurrentSlotWindow() const
{
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
    QPWindow w;
    w.start = start;
    w.end = start + QP_TARGET_TIME - 1;
    return w;
}

bool QPQueue::TimeIsInCurrentSlotWindow(unsigned int nTime) const
{
    QPWindow w = GetCurrentSlotWindow();
    return ((w.start <= nTime) && (nTime <= w.end));
}

unsigned int QPQueue::GetCurrentID() const
{
    return vStakerIDs[nCurrentSlot];
}

unsigned int QPQueue::GetLastID() const
{
    return vStakerIDs.back();
}

bool QPQueue::IsOnLastSlot() const
{
    return (nCurrentSlot == (vStakerIDs.size() - 1));
}

QPQueueIterator QPQueue::Begin() const
{
    return vStakerIDs.begin();
}

QPQueueIterator QPQueue::End() const
{
    return vStakerIDs.end();
}

unsigned int QPQueue::Size() const
{
    return vStakerIDs.size();
}

bool QPQueue::IsEmpty() const
{
    return vStakerIDs.empty();
}

string QPQueue::ToString() const
{
    int n = vStakerIDs.size();
    int last = n - 1;
    ostringstream ss;
    for (int i = 0; i < n; ++i)
    {
        QPSlotStatus status;
        if (!GetStatusForSlot(i, status))
        {
            // this should never happen: practically impossible
            printf("QPQueue::ToString() TSNH No such slot\n");
        }
        const char* chStat = GetSlotStatusAbbrev(status);
        ss << chStat << i << ":" << vStakerIDs[i];
        if (i < last)
        {
            ss << ",";
        }
    }
    string sSlots = ss.str();
    return strprintf("QPQueue: start=%u, current_slot=%u,\n     slots=%s",
                     nSlotTime0, nCurrentSlot, sSlots.c_str());
}

unsigned int QPQueue::SlotProduced(unsigned int nSlot)
{
    unsigned int nBit = nSlot + (vchBlockStats.size() * 8) - vStakerIDs.size();
    return SetBit(vchBlockStats, nBit);
}

bool QPQueue::IncrementSlot()
{
    if (nCurrentSlot + 1 >= vStakerIDs.size())
    {
        return false;
    }
    nCurrentSlot += 1;
    return true;
}

void QPQueue::Reset()
{
    nCurrentSlot = 0;
}
<commit_msg>Fixing compiler warnings.<commit_after>// Copyright (c) 2019 The Stealth Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "QPQueue.hpp"
#include "util.h"

#include <sstream>

using namespace std;

unsigned int BitIsOn(const valtype& vch, unsigned int nBit)
{
    unsigned int nByte = nBit / 8;
    unsigned int nSize = vch.size();
    if (nByte >= nSize)
    {
        return 0;
    }
    return vch[nByte] & (0x80 >> (nBit % 8));
}

unsigned int SetBit(valtype& vch, unsigned int nBit)
{
     unsigned int nByte = nBit / 8;
     unsigned int nSize = vch.size();
     if (nByte >= nSize)
     {
         return 0;
     }
     unsigned char& chByte = vch[nByte];
     unsigned int nBitValue = 0x80 >> (nBit % 8);
     chByte |= nBitValue;
     return nBitValue;
}

const char* GetSlotStatusType(const QPSlotStatus status)
{
    switch (status)
    {
    case QPSLOT_INVALID:
        return "invalid";
    case QPSLOT_MISSED:
        return "missed";
    case QPSLOT_HIT:
        return "produced";
    case QPSLOT_CURRENT:
        return "current";
    case QPSLOT_FUTURE:
        return "future";
    }
    return "invalid";
}

const char* GetSlotStatusAbbrev(const QPSlotStatus status)
{
    switch (status)
    {
    case QPSLOT_INVALID:
        return "!";
    case QPSLOT_MISSED:
        return "x";
    case QPSLOT_HIT:
        return "+";
    case QPSLOT_CURRENT:
        return "-";
    case QPSLOT_FUTURE:
        return "o";
    }
    return "!";
}

QPQueue::QPQueue()
{
    SetNull();
}

QPQueue::QPQueue(unsigned int nSlotTime0In,
        const vector<unsigned int>& vStakerIDsIn)
{
    nVersion = QPQueue::CURRENT_VERSION;
    nCurrentSlot = 0;
    nSlotTime0 = nSlotTime0In;
    vStakerIDs = vStakerIDsIn;
    unsigned int nSize = vStakerIDs.size();
    if (nSize % 8 == 0)
    {
        vchBlockStats.resize(nSize / 8);
    }
    else
    {
        vchBlockStats.resize((nSize / 8) + 1);
    }
    fill(vchBlockStats.begin(), vchBlockStats.end(), 0);
}

void QPQueue::SetNull()
{
    nVersion = QPQueue::CURRENT_VERSION;
    nCurrentSlot = 0;
    nSlotTime0 = 0;
    vStakerIDs.clear();
    vchBlockStats.clear();
}

unsigned int QPQueue::GetCurrentSlot() const
{
    return nCurrentSlot;
}

const std::vector<unsigned int>& QPQueue::GetStakerIDs() const
{
    return vStakerIDs;
}

const valtype& QPQueue::GetBlockStats() const
{
    return vchBlockStats;
}

bool QPQueue::GetIDForSlot(unsigned int slot, unsigned int &nIDRet) const
{
    if (slot >= vStakerIDs.size())
    {
         return false;
    }
    nIDRet = vStakerIDs[slot];
    return true;
}
bool QPQueue::GetSlotForID(unsigned int nID, unsigned int& nSlotRet) const
{
    bool found = false;
    unsigned int slot = 0;
    QPQueueIterator it;
    for (it = vStakerIDs.begin(); it != vStakerIDs.end(); ++it)
    {
        if (*it == nID)
        {
            nSlotRet = slot;
            found = true;
            break;
        }
        ++slot;
    }
    return found;
}

bool QPQueue::GetWindowForID(unsigned int nID, QPWindow& windowRet) const
{
    unsigned int slot;
    if (!GetSlotForID(nID, slot))
    {
        return false;
    }
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * slot);
        windowRet.start = start;
        windowRet.end = start + QP_TARGET_TIME - 1;
    return true;
}

bool QPQueue::GetWindowForSlot(unsigned int nSlot, QPWindow& windowRet) const
{
    if (nSlot >= vStakerIDs.size())
    {
        return false;
    }
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nSlot);
    windowRet.start = start;
        windowRet.end = start + QP_TARGET_TIME - 1;
    return true;
}

bool QPQueue::GetStatusForSlot(unsigned int nSlot, QPSlotStatus& status) const
{
    if (nSlot >= vStakerIDs.size())
    {
        status = QPSLOT_INVALID;
        return false;
    }
    if (nSlot > nCurrentSlot)
    {
        status = QPSLOT_FUTURE;
    }
    else
    {
        unsigned int nBit = nSlot +
                            (vchBlockStats.size() * 8) -
                            vStakerIDs.size();
        if (BitIsOn(vchBlockStats, nBit))
        {
            status = QPSLOT_HIT;
        }
        else if (nSlot == nCurrentSlot)
        {
            status = QPSLOT_CURRENT;
        }
        else
        {
            status = QPSLOT_MISSED;
        }
    }
    return true;
}

unsigned int QPQueue::GetMinTime() const
{
    return nSlotTime0;
}

unsigned int QPQueue::GetMaxTime() const
{
    unsigned int nSize = static_cast<unsigned int>(vStakerIDs.size());
    return nSlotTime0 + (QP_TARGET_TIME * nSize) - 1;
}

bool QPQueue::GetSlotStartTime(unsigned int nSlot, unsigned int &nTimeRet) const
{
    if (nSlot >= vStakerIDs.size())
    {
        return false;
    }
    nTimeRet = nSlotTime0 + (QP_TARGET_TIME * (unsigned int)nSlot);
    return true;
}

bool QPQueue::GetSlotForTime(unsigned int nTime, unsigned int &nSlotRet) const
{
    if (nTime < nSlotTime0)
    {
        return error("GetSlotForTime(): time %u too early", nTime);
    }
    if (nTime > GetMaxTime())
    {
        return error("GetSlotForTime(): time %u too late", nTime);
    }
    nSlotRet = (nTime - nSlotTime0) / QP_TARGET_TIME;
    return true;
}

unsigned int QPQueue::GetCurrentSlotStart() const
{
    return nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
}

unsigned int QPQueue::GetCurrentSlotEnd() const
{
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
    return start + QP_TARGET_TIME - 1;
}

QPWindow QPQueue::GetCurrentSlotWindow() const
{
    unsigned int start = nSlotTime0 + (QP_TARGET_TIME * nCurrentSlot);
    QPWindow w;
    w.start = start;
    w.end = start + QP_TARGET_TIME - 1;
    return w;
}

bool QPQueue::TimeIsInCurrentSlotWindow(unsigned int nTime) const
{
    QPWindow w = GetCurrentSlotWindow();
    return ((w.start <= nTime) && (nTime <= w.end));
}

unsigned int QPQueue::GetCurrentID() const
{
    return vStakerIDs[nCurrentSlot];
}

unsigned int QPQueue::GetLastID() const
{
    return vStakerIDs.back();
}

bool QPQueue::IsOnLastSlot() const
{
    return (nCurrentSlot == (vStakerIDs.size() - 1));
}

QPQueueIterator QPQueue::Begin() const
{
    return vStakerIDs.begin();
}

QPQueueIterator QPQueue::End() const
{
    return vStakerIDs.end();
}

unsigned int QPQueue::Size() const
{
    return vStakerIDs.size();
}

bool QPQueue::IsEmpty() const
{
    return vStakerIDs.empty();
}

string QPQueue::ToString() const
{
    int n = vStakerIDs.size();
    int last = n - 1;
    ostringstream ss;
    for (int i = 0; i < n; ++i)
    {
        QPSlotStatus status;
        if (!GetStatusForSlot(i, status))
        {
            // this should never happen: practically impossible
            printf("QPQueue::ToString() TSNH No such slot\n");
        }
        const char* chStat = GetSlotStatusAbbrev(status);
        ss << chStat << i << ":" << vStakerIDs[i];
        if (i < last)
        {
            ss << ",";
        }
    }
    string sSlots = ss.str();
    return strprintf("QPQueue: start=%u, current_slot=%u,\n     slots=%s",
                     nSlotTime0, nCurrentSlot, sSlots.c_str());
}

unsigned int QPQueue::SlotProduced(unsigned int nSlot)
{
    unsigned int nBit = nSlot + (vchBlockStats.size() * 8) - vStakerIDs.size();
    return SetBit(vchBlockStats, nBit);
}

bool QPQueue::IncrementSlot()
{
    if (nCurrentSlot + 1 >= vStakerIDs.size())
    {
        return false;
    }
    nCurrentSlot += 1;
    return true;
}

void QPQueue::Reset()
{
    nCurrentSlot = 0;
}
<|endoftext|>