<commit_before>//******************************************************************
//
// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// 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.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

extern "C"
{
    #include "ocstack.h"
    #include "ocpayload.h"
    #include "ocpayloadcbor.h"
    #include "logger.h"
    #include "oic_malloc.h"
}

#include "gtest/gtest.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>

#include <iostream>
#include <stdint.h>

#include "gtest_helper.h"

//-----------------------------------------------------------------------------
// CBOR_BIN_STRING_DEBUG may be defined when compiling to save the output of
// the OC payload conversion to CBOR to a file for further examination with any
// CBOR related tools.
//-----------------------------------------------------------------------------
//#define CBOR_BIN_STRING_DEBUG

class CborByteStringTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            // Create Payload
            payload_in = OCRepPayloadCreate();
            ASSERT_TRUE(payload_in != NULL);
        }

        virtual void TearDown() {
            OCPayloadDestroy((OCPayload*)payload_in);
        }

        OCRepPayload* payload_in;
};

TEST_F(CborByteStringTest, ByteStringSetGetTest)
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
                        0xD, 0xE, 0xF};
    OCByteString quakedata_in = { binval, sizeof(binval)};

    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));

    OCByteString quakedata_out = { NULL, 0};
    ASSERT_EQ(true, OCRepPayloadGetPropByteString(payload_in, "quakedata", &quakedata_out));
    ASSERT_NE((uint8_t*)NULL, quakedata_out.bytes);
    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));

    // Cleanup
    OICFree(quakedata_out.bytes);
}

TEST_F(CborByteStringTest, ByteStringConvertParseTest)
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
                        0xD, 0xE, 0xF};
    OCByteString quakedata_in = { binval, sizeof(binval)};

    // Set ByteString in Payload
    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));

#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstring.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                 payload_cbor, payload_cbor_size));

    OCByteString quakedata_out = {NULL, 0};
    ASSERT_EQ(true, OCRepPayloadGetPropByteString((OCRepPayload*)payload_out, "quakedata", &quakedata_out));

    // Compare input and output data
    ASSERT_NE((uint8_t*)NULL, quakedata_out.bytes);
    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));

    // Cleanup
    OICFree(payload_cbor);
    OICFree(quakedata_out.bytes);
    OCPayloadDestroy((OCPayload*)payload_out);
}

TEST_F(CborByteStringTest, ByteStringArraySetGetTest )
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};

    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
                                    {binval2, sizeof(binval2)},
                                    {binval3, sizeof(binval3)}};

    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
                quakedata_in, dimensions_in));

    OCByteString* quakedata_out = NULL;
    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
    ASSERT_EQ(true, OCRepPayloadGetByteStringArray(payload_in, "quakedata",
                &quakedata_out, dimensions_out));

    for(size_t i = 0; i < dimensions_in[0]; i++)
    {
        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
    }

    // Cleanup
    for(size_t i = 0; i < dimensions_out[0]; i++)
    {
        OICFree(quakedata_out[i].bytes);
    }
    OICFree(quakedata_out);
}

TEST_F(CborByteStringTest, ByteStringArrayConvertParseTest )
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};

    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
                                    {binval2, sizeof(binval2)},
                                    {binval3, sizeof(binval3)}};

    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
                quakedata_in, dimensions_in));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));
#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstringarr.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                payload_cbor, payload_cbor_size));

    OCByteString* quakedata_out = NULL;
    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
    ASSERT_EQ(true, OCRepPayloadGetByteStringArray((OCRepPayload*)payload_out, "quakedata",
                &quakedata_out, dimensions_out));

    for(size_t i = 0; i < dimensions_in[0]; i++)
    {
        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
    }

    // Cleanup
    OICFree(payload_cbor);
    for(size_t i = 0; i < dimensions_out[0]; i++)
    {
        OICFree(quakedata_out[i].bytes);
    }
    OICFree(quakedata_out);

    OCPayloadDestroy((OCPayload*)payload_out);
}

TEST(CborHeterogeneousArrayTest, ConvertParseTest)
{
    OCRepPayload *arr = OCRepPayloadCreate();
    ASSERT_TRUE(arr != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropString(arr, "0", "string"));
    EXPECT_TRUE(OCRepPayloadSetPropDouble(arr, "1", 1.0));
    OCRepPayload *obj = OCRepPayloadCreate();
    ASSERT_TRUE(obj != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropString(obj, "member", "value"));
    EXPECT_TRUE(OCRepPayloadSetPropObjectAsOwner(arr, "2", obj));
    const char *strArray[] = { "string" };
    size_t dim[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
    EXPECT_TRUE(OCRepPayloadSetStringArray(arr, "3", strArray, dim));

    OCRepPayload* payload_in = OCRepPayloadCreate();
    ASSERT_TRUE(payload_in != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropObjectAsOwner(payload_in, "property", arr));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));
#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstringhetarr.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG
    OCRepPayloadDestroy(payload_in);

    // Compare that array encoding was used
    uint8_t binstring[] = {
        0xbf, 0x68, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x84, 0x66, 0x73, 0x74, 0x72, 0x69,
        0x6e, 0x67, 0xfb, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x66, 0x6d, 0x65, 0x6d,
        0x62, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0xff, 0x81, 0x66, 0x73, 0x74, 0x72, 0x69,
        0x6e, 0x67, 0xff
    };
    ASSERT_EQ(sizeof(binstring), payload_cbor_size);
    EXPECT_EQ(0, memcmp(binstring, payload_cbor, payload_cbor_size));

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                                          payload_cbor, payload_cbor_size));

    // Compare values
    EXPECT_TRUE(OCRepPayloadGetPropObject((OCRepPayload*) payload_out, "property", &arr));
    char *str;
    EXPECT_TRUE(OCRepPayloadGetPropString(arr, "0", &str));
    EXPECT_STREQ("string", str);
    OICFree(str);
    double d;
    EXPECT_TRUE(OCRepPayloadGetPropDouble(arr, "1", &d));
    EXPECT_EQ(1.0, d);
    EXPECT_TRUE(OCRepPayloadGetPropObject(arr, "2", &obj));
    OCRepPayloadDestroy(obj);
    char **strArr;
    EXPECT_TRUE(OCRepPayloadGetStringArray(arr, "3", &strArr, dim));
    EXPECT_EQ(1u, dim[0]);
    EXPECT_EQ(0u, dim[1]);
    EXPECT_EQ(0u, dim[2]);
    EXPECT_STREQ("string", strArr[0]);
    for (size_t i = 0; i < dim[0]; ++i)
    {
        OICFree(strArr[i]);
    }
    OICFree(strArr);
    OCRepPayloadDestroy(arr);

    // Cleanup
    OICFree(payload_cbor);
    OCPayloadDestroy(payload_out);
}
<commit_msg>csdk: Include config header before any header<commit_after>//******************************************************************
//
// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//
// 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.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#include "iotivity_config.h"

extern "C"
{
    #include "ocstack.h"
    #include "ocpayload.h"
    #include "ocpayloadcbor.h"
    #include "logger.h"
    #include "oic_malloc.h"
}

#include "gtest/gtest.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>

#include <iostream>
#include <stdint.h>

#include "gtest_helper.h"

//-----------------------------------------------------------------------------
// CBOR_BIN_STRING_DEBUG may be defined when compiling to save the output of
// the OC payload conversion to CBOR to a file for further examination with any
// CBOR related tools.
//-----------------------------------------------------------------------------
//#define CBOR_BIN_STRING_DEBUG

class CborByteStringTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            // Create Payload
            payload_in = OCRepPayloadCreate();
            ASSERT_TRUE(payload_in != NULL);
        }

        virtual void TearDown() {
            OCPayloadDestroy((OCPayload*)payload_in);
        }

        OCRepPayload* payload_in;
};

TEST_F(CborByteStringTest, ByteStringSetGetTest)
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
                        0xD, 0xE, 0xF};
    OCByteString quakedata_in = { binval, sizeof(binval)};

    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));

    OCByteString quakedata_out = { NULL, 0};
    ASSERT_EQ(true, OCRepPayloadGetPropByteString(payload_in, "quakedata", &quakedata_out));
    ASSERT_NE((uint8_t*)NULL, quakedata_out.bytes);
    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));

    // Cleanup
    OICFree(quakedata_out.bytes);
}

TEST_F(CborByteStringTest, ByteStringConvertParseTest)
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0xA, 0xB, 0xC,
                        0xD, 0xE, 0xF};
    OCByteString quakedata_in = { binval, sizeof(binval)};

    // Set ByteString in Payload
    EXPECT_EQ(true, OCRepPayloadSetPropByteString(payload_in, "quakedata", quakedata_in));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));

#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstring.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                 payload_cbor, payload_cbor_size));

    OCByteString quakedata_out = {NULL, 0};
    ASSERT_EQ(true, OCRepPayloadGetPropByteString((OCRepPayload*)payload_out, "quakedata", &quakedata_out));

    // Compare input and output data
    ASSERT_NE((uint8_t*)NULL, quakedata_out.bytes);
    EXPECT_EQ(quakedata_in.len, quakedata_out.len);
    EXPECT_EQ(0, memcmp(quakedata_in.bytes, quakedata_out.bytes, quakedata_in.len));

    // Cleanup
    OICFree(payload_cbor);
    OICFree(quakedata_out.bytes);
    OCPayloadDestroy((OCPayload*)payload_out);
}

TEST_F(CborByteStringTest, ByteStringArraySetGetTest )
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};

    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
                                    {binval2, sizeof(binval2)},
                                    {binval3, sizeof(binval3)}};

    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
                quakedata_in, dimensions_in));

    OCByteString* quakedata_out = NULL;
    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
    ASSERT_EQ(true, OCRepPayloadGetByteStringArray(payload_in, "quakedata",
                &quakedata_out, dimensions_out));

    for(size_t i = 0; i < dimensions_in[0]; i++)
    {
        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
    }

    // Cleanup
    for(size_t i = 0; i < dimensions_out[0]; i++)
    {
        OICFree(quakedata_out[i].bytes);
    }
    OICFree(quakedata_out);
}

TEST_F(CborByteStringTest, ByteStringArrayConvertParseTest )
{
    OCRepPayloadSetUri(payload_in, "/a/quake_sensor");
    OCRepPayloadSetPropInt(payload_in, "scale", 4);

    size_t dimensions_in[MAX_REP_ARRAY_DEPTH] = { 3, 0, 0};
    uint8_t binval1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19};
    uint8_t binval2[] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29};
    uint8_t binval3[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};

    OCByteString quakedata_in[3] = {{binval1, sizeof(binval1)},
                                    {binval2, sizeof(binval2)},
                                    {binval3, sizeof(binval3)}};

    EXPECT_EQ(true, OCRepPayloadSetByteStringArray(payload_in, "quakedata",
                quakedata_in, dimensions_in));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));
#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstringarr.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                payload_cbor, payload_cbor_size));

    OCByteString* quakedata_out = NULL;
    size_t dimensions_out[MAX_REP_ARRAY_DEPTH] = {0};
    ASSERT_EQ(true, OCRepPayloadGetByteStringArray((OCRepPayload*)payload_out, "quakedata",
                &quakedata_out, dimensions_out));

    for(size_t i = 0; i < dimensions_in[0]; i++)
    {
        EXPECT_EQ(quakedata_in[i].len, quakedata_out[i].len);
        EXPECT_EQ(0, memcmp(quakedata_in[i].bytes, quakedata_out[i].bytes, quakedata_in[i].len));
    }

    // Cleanup
    OICFree(payload_cbor);
    for(size_t i = 0; i < dimensions_out[0]; i++)
    {
        OICFree(quakedata_out[i].bytes);
    }
    OICFree(quakedata_out);

    OCPayloadDestroy((OCPayload*)payload_out);
}

TEST(CborHeterogeneousArrayTest, ConvertParseTest)
{
    OCRepPayload *arr = OCRepPayloadCreate();
    ASSERT_TRUE(arr != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropString(arr, "0", "string"));
    EXPECT_TRUE(OCRepPayloadSetPropDouble(arr, "1", 1.0));
    OCRepPayload *obj = OCRepPayloadCreate();
    ASSERT_TRUE(obj != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropString(obj, "member", "value"));
    EXPECT_TRUE(OCRepPayloadSetPropObjectAsOwner(arr, "2", obj));
    const char *strArray[] = { "string" };
    size_t dim[MAX_REP_ARRAY_DEPTH] = { 1, 0, 0 };
    EXPECT_TRUE(OCRepPayloadSetStringArray(arr, "3", strArray, dim));

    OCRepPayload* payload_in = OCRepPayloadCreate();
    ASSERT_TRUE(payload_in != NULL);
    EXPECT_TRUE(OCRepPayloadSetPropObjectAsOwner(payload_in, "property", arr));

    // Convert OCPayload to CBOR
    uint8_t *payload_cbor = NULL;
    size_t payload_cbor_size = 0;
    EXPECT_EQ(OC_STACK_OK, OCConvertPayload((OCPayload*) payload_in, OC_FORMAT_CBOR,
            &payload_cbor, &payload_cbor_size));
#ifdef CBOR_BIN_STRING_DEBUG
    FILE *fp = fopen("binstringhetarr.cbor", "wb+");
    if (fp)
    {
        fwrite(payload_cbor, 1, payload_cbor_size, fp);
        fclose(fp);
    }
#endif //CBOR_BIN_STRING_DEBUG
    OCRepPayloadDestroy(payload_in);

    // Compare that array encoding was used
    uint8_t binstring[] = {
        0xbf, 0x68, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x84, 0x66, 0x73, 0x74, 0x72, 0x69,
        0x6e, 0x67, 0xfb, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x66, 0x6d, 0x65, 0x6d,
        0x62, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0xff, 0x81, 0x66, 0x73, 0x74, 0x72, 0x69,
        0x6e, 0x67, 0xff
    };
    ASSERT_EQ(sizeof(binstring), payload_cbor_size);
    EXPECT_EQ(0, memcmp(binstring, payload_cbor, payload_cbor_size));

    // Parse CBOR back to OCPayload
    OCPayload* payload_out = NULL;
    EXPECT_EQ(OC_STACK_OK, OCParsePayload(&payload_out, OC_FORMAT_CBOR, PAYLOAD_TYPE_REPRESENTATION,
                                          payload_cbor, payload_cbor_size));

    // Compare values
    EXPECT_TRUE(OCRepPayloadGetPropObject((OCRepPayload*) payload_out, "property", &arr));
    char *str;
    EXPECT_TRUE(OCRepPayloadGetPropString(arr, "0", &str));
    EXPECT_STREQ("string", str);
    OICFree(str);
    double d;
    EXPECT_TRUE(OCRepPayloadGetPropDouble(arr, "1", &d));
    EXPECT_EQ(1.0, d);
    EXPECT_TRUE(OCRepPayloadGetPropObject(arr, "2", &obj));
    OCRepPayloadDestroy(obj);
    char **strArr;
    EXPECT_TRUE(OCRepPayloadGetStringArray(arr, "3", &strArr, dim));
    EXPECT_EQ(1u, dim[0]);
    EXPECT_EQ(0u, dim[1]);
    EXPECT_EQ(0u, dim[2]);
    EXPECT_STREQ("string", strArr[0]);
    for (size_t i = 0; i < dim[0]; ++i)
    {
        OICFree(strArr[i]);
    }
    OICFree(strArr);
    OCRepPayloadDestroy(arr);

    // Cleanup
    OICFree(payload_cbor);
    OCPayloadDestroy(payload_out);
}
<|endoftext|>


<commit_before>// Copyright 2017 The Abseil Authors.
//
// 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.

#include <vector>

#include "benchmark/benchmark.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/mutex.h"

namespace {

// Measure the overhead of conditions on mutex release (when they must be
// evaluated).  Mutex has (some) support for equivalence classes allowing
// Conditions with the same function/argument to potentially not be multiply
// evaluated.
//
// num_classes==0 is used for the special case of every waiter being distinct.
void BM_ConditionWaiters(benchmark::State& state) {
  int num_classes = state.range(0);
  int num_waiters = state.range(1);

  struct Helper {
    static void Waiter(absl::BlockingCounter* init, absl::Mutex* m, int* p) {
      init->DecrementCount();
      m->LockWhen(absl::Condition(
          static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p));
      m->Unlock();
    }
  };

  if (num_classes == 0) {
    // No equivalence classes.
    num_classes = num_waiters;
  }

  absl::BlockingCounter init(num_waiters);
  absl::Mutex mu;
  std::vector<int> equivalence_classes(num_classes, 1);

  // Must be declared last to be destroyed first.
  absl::synchronization_internal::ThreadPool pool(num_waiters);

  for (int i = 0; i < num_waiters; i++) {
    // Mutex considers Conditions with the same function and argument
    // to be equivalent.
    pool.Schedule([&, i] {
      Helper::Waiter(&init, &mu, &equivalence_classes[i % num_classes]);
    });
  }
  init.Wait();

  for (auto _ : state) {
    mu.Lock();
    mu.Unlock();  // Each unlock requires Condition evaluation for our waiters.
  }

  mu.Lock();
  for (int i = 0; i < num_classes; i++) {
    equivalence_classes[i] = 0;
  }
  mu.Unlock();
}

#ifdef THREAD_SANITIZER
// ThreadSanitizer can't handle 8192 threads.
constexpr int kMaxConditionWaiters = 2048;
#else
constexpr int kMaxConditionWaiters = 8192;
#endif
BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);

void BM_ContendedMutex(benchmark::State& state) {
  static absl::Mutex* mu = new absl::Mutex;
  for (auto _ : state) {
    absl::MutexLock lock(mu);
  }
}
BENCHMARK(BM_ContendedMutex)->Threads(1);
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();

}  // namespace
<commit_msg>Export of internal Abseil changes. -- ee644a89fb1429d9337852690a01182853f68964 by Derek Mauro <dmauro@google.com>:<commit_after>// Copyright 2017 The Abseil Authors.
//
// 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.

#include <vector>

#include "benchmark/benchmark.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/mutex.h"

namespace {

// Measure the overhead of conditions on mutex release (when they must be
// evaluated).  Mutex has (some) support for equivalence classes allowing
// Conditions with the same function/argument to potentially not be multiply
// evaluated.
//
// num_classes==0 is used for the special case of every waiter being distinct.
void BM_ConditionWaiters(benchmark::State& state) {
  int num_classes = state.range(0);
  int num_waiters = state.range(1);

  struct Helper {
    static void Waiter(absl::BlockingCounter* init, absl::Mutex* m, int* p) {
      init->DecrementCount();
      m->LockWhen(absl::Condition(
          static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p));
      m->Unlock();
    }
  };

  if (num_classes == 0) {
    // No equivalence classes.
    num_classes = num_waiters;
  }

  absl::BlockingCounter init(num_waiters);
  absl::Mutex mu;
  std::vector<int> equivalence_classes(num_classes, 1);

  // Must be declared last to be destroyed first.
  absl::synchronization_internal::ThreadPool pool(num_waiters);

  for (int i = 0; i < num_waiters; i++) {
    // Mutex considers Conditions with the same function and argument
    // to be equivalent.
    pool.Schedule([&, i] {
      Helper::Waiter(&init, &mu, &equivalence_classes[i % num_classes]);
    });
  }
  init.Wait();

  for (auto _ : state) {
    mu.Lock();
    mu.Unlock();  // Each unlock requires Condition evaluation for our waiters.
  }

  mu.Lock();
  for (int i = 0; i < num_classes; i++) {
    equivalence_classes[i] = 0;
  }
  mu.Unlock();
}

// Some configurations have higher thread limits than others.
#if defined(__linux__) && !defined(THREAD_SANITIZER)
constexpr int kMaxConditionWaiters = 8192;
#else
constexpr int kMaxConditionWaiters = 1024;
#endif
BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);

void BM_ContendedMutex(benchmark::State& state) {
  static absl::Mutex* mu = new absl::Mutex;
  for (auto _ : state) {
    absl::MutexLock lock(mu);
  }
}
BENCHMARK(BM_ContendedMutex)->Threads(1);
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();

}  // namespace
<|endoftext|>


<commit_before>// RUN: cat %s | %cling -Xclang -verify | FileCheck %s
//This file checks a call instruction. The called function has arguments with nonnull attribute.
#include <string.h>
//XFAIL: darwin

char *p = 0;
strcmp("a", p); // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

strcmp(p, "a"); // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

extern "C" int printf(const char* fmt, ...);
.rawInput 1
extern "C" int cannotCallWithNull(int* p = 0);
extern "C" int cannotCallWithNull(int* p) __attribute__((nonnull(1)));
extern "C" int cannotCallWithNull(int* p);
extern "C" int cannotCallWithNull(int* p);
.rawInput 0

extern "C" int cannotCallWithNull(int* p) {
  if (!p)
    printf("Must not be called with p=0.\n");
  return 1;
}

cannotCallWithNull() // warning-expected {{null passed to a callee which requires a non-null argument}}
// expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}
//CHECK-NOT: Must not be called with p=0.
//CHECK: (int) 1

.q
<commit_msg>Spell correctly expected-warning and not warning expected. Call a function with non null and check the expected result.<commit_after>// RUN: cat %s | %cling -Xclang -verify | FileCheck %s
//This file checks a call instruction. The called function has arguments with nonnull attribute.
#include <string.h>
//XFAIL: darwin

char *p = 0;
strcmp("a", p); // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

strcmp(p, "a"); // expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}

extern "C" int printf(const char* fmt, ...);
.rawInput 1
extern "C" int cannotCallWithNull(int* p = 0);
extern "C" int cannotCallWithNull(int* p) __attribute__((nonnull(1)));
extern "C" int cannotCallWithNull(int* p);
extern "C" int cannotCallWithNull(int* p);
.rawInput 0

extern "C" int cannotCallWithNull(int* p) {
  if (!p)
    printf("Must not be called with p=0.\n");
  return 1;
}

cannotCallWithNull() // expected-warning {{null passed to a callee which requires a non-null argument}}
// expected-warning {{you are about to dereference null ptr, which probably will lead to seg violation. Do you want to proceed?[y/n]}}
//CHECK-NOT: Must not be called with p=0.
cannotCallWithNull(new int(4))
//CHECK: (int) 1

.q
<|endoftext|>


<commit_before>/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.

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. */

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>

#include "paddle/fluid/inference/tests/api/tester_helper.h"

namespace paddle {
namespace inference {

DEFINE_bool(use_tensorrt, true, "Test the performance of TensorRT engine.");
DEFINE_string(prog_filename, "", "Name of model file.");
DEFINE_string(param_filename, "", "Name of parameters file.");

template <typename ConfigType>
void SetConfig(ConfigType* config, std::string model_dir, bool use_gpu,
               bool use_tensorrt = false, int batch_size = -1) {
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    config->prog_file = model_dir + "/" + FLAGS_prog_filename;
    config->param_file = model_dir + "/" + FLAGS_param_filename;
  } else {
    config->model_dir = model_dir;
  }
  if (use_gpu) {
    config->use_gpu = true;
    config->device = 0;
    config->fraction_of_gpu_memory = 0.15;
  }
}

template <>
void SetConfig<AnalysisConfig>(AnalysisConfig* config, std::string model_dir,
                               bool use_gpu, bool use_tensorrt,
                               int batch_size) {
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    config->SetModel(model_dir + "/" + FLAGS_prog_filename,
                     model_dir + "/" + FLAGS_param_filename);
  } else {
    config->SetModel(model_dir);
  }
  if (use_gpu) {
    config->EnableUseGpu(100, 0);
    if (use_tensorrt) {
      config->EnableTensorRtEngine(1 << 10, batch_size, 3,
                                   AnalysisConfig::Precision::kFloat32, false);
      config->pass_builder()->DeletePass("conv_bn_fuse_pass");
      config->pass_builder()->DeletePass("fc_fuse_pass");
      config->pass_builder()->TurnOnDebug();
    } else {
      config->SwitchIrOptim();
    }
  }
}

void profile(std::string model_dir, bool use_analysis, bool use_tensorrt) {
  std::vector<std::vector<PaddleTensor>> inputs_all;
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                      FLAGS_param_filename);
  } else {
    SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");
  }

  std::vector<std::vector<PaddleTensor>> outputs;
  if (use_analysis || use_tensorrt) {
    AnalysisConfig config;
    config.EnableUseGpu(100, 0);
    config.pass_builder()->TurnOnDebug();
    SetConfig<AnalysisConfig>(&config, model_dir, true, use_tensorrt,
                              FLAGS_batch_size);
    TestPrediction(reinterpret_cast<PaddlePredictor::Config*>(&config),
                   inputs_all, &outputs, FLAGS_num_threads, true);
  } else {
    NativeConfig config;
    SetConfig<NativeConfig>(&config, model_dir, true, false);
    TestPrediction(reinterpret_cast<PaddlePredictor::Config*>(&config),
                   inputs_all, &outputs, FLAGS_num_threads, false);
  }
}

void compare(std::string model_dir, bool use_tensorrt) {
  std::vector<std::vector<PaddleTensor>> inputs_all;
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                      FLAGS_param_filename);
  } else {
    SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");
  }

  AnalysisConfig analysis_config;
  SetConfig<AnalysisConfig>(&analysis_config, model_dir, true, use_tensorrt,
                            FLAGS_batch_size);
  CompareNativeAndAnalysis(
      reinterpret_cast<const PaddlePredictor::Config*>(&analysis_config),
      inputs_all);
}

void compare_continuous_input(std::string model_dir, bool use_tensorrt) {
  AnalysisConfig analysis_config;
  SetConfig<AnalysisConfig>(&analysis_config, model_dir, true, use_tensorrt,
                            FLAGS_batch_size);
  auto config =
      reinterpret_cast<const PaddlePredictor::Config*>(&analysis_config);
  auto native_pred = CreateTestPredictor(config, false);
  auto analysis_pred = CreateTestPredictor(config, true);
  for (int i = 0; i < 100; i++) {
    std::vector<std::vector<PaddleTensor>> inputs_all;
    if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
      SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                        FLAGS_param_filename, nullptr, i);
    } else {
      SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "", nullptr,
                        i);
    }
    CompareNativeAndAnalysis(native_pred.get(), analysis_pred.get(),
                             inputs_all);
  }
}

TEST(TensorRT_mobilenet, compare) {
  std::string model_dir = FLAGS_infer_model + "/mobilenet";
  compare(model_dir, /* use_tensorrt */ true);
}

TEST(TensorRT_resnet50, compare) {
  std::string model_dir = FLAGS_infer_model + "/resnet50";
  compare(model_dir, /* use_tensorrt */ true);
}

TEST(TensorRT_resnext50, compare) {
  std::string model_dir = FLAGS_infer_model + "/resnext50";
  compare(model_dir, /* use_tensorrt */ true);
}

TEST(TensorRT_resnext50, profile) {
  std::string model_dir = FLAGS_infer_model + "/resnext50";
  // Set FLAGS_record_benchmark to true to record benchmark to file.
  // FLAGS_record_benchmark=true;
  FLAGS_model_name = "resnext50";
  profile(model_dir, /* use_analysis */ true, FLAGS_use_tensorrt);
}

TEST(resnext50, compare_analysis_native) {
  std::string model_dir = FLAGS_infer_model + "/resnext50";
  compare(model_dir, false /*use tensorrt*/);
}

TEST(TensorRT_mobilenet, analysis) {
  std::string model_dir = FLAGS_infer_model + "/" + "mobilenet";
  compare(model_dir, false /* use_tensorrt */);
}

TEST(AnalysisPredictor, use_gpu) {
  std::string model_dir = FLAGS_infer_model + "/" + "mobilenet";
  AnalysisConfig config;
  config.EnableUseGpu(100, 0);
  config.SetModel(model_dir);
  config.pass_builder()->TurnOnDebug();

  std::vector<std::vector<PaddleTensor>> inputs_all;
  auto predictor = CreatePaddlePredictor(config);
  SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");

  std::vector<PaddleTensor> outputs;
  for (auto& input : inputs_all) {
    ASSERT_TRUE(predictor->Run(input, &outputs));
  }
}

TEST(TensorRT_mobilenet, profile) {
  std::string model_dir = FLAGS_infer_model + "/" + "mobilenet";
  profile(model_dir, true, false);
}

TEST(resnet50, compare_continuous_input) {
  std::string model_dir = FLAGS_infer_model + "/resnet50";
  compare_continuous_input(model_dir, true);
}

TEST(resnet50, compare_continuous_input_native) {
  std::string model_dir = FLAGS_infer_model + "/resnet50";
  compare_continuous_input(model_dir, false);
}

}  // namespace inference
}  // namespace paddle
<commit_msg>minus trt ci times. test=develop<commit_after>/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.

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. */

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>

#include "paddle/fluid/inference/tests/api/tester_helper.h"

namespace paddle {
namespace inference {

DEFINE_bool(use_tensorrt, true, "Test the performance of TensorRT engine.");
DEFINE_string(prog_filename, "", "Name of model file.");
DEFINE_string(param_filename, "", "Name of parameters file.");

template <typename ConfigType>
void SetConfig(ConfigType* config, std::string model_dir, bool use_gpu,
               bool use_tensorrt = false, int batch_size = -1) {
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    config->prog_file = model_dir + "/" + FLAGS_prog_filename;
    config->param_file = model_dir + "/" + FLAGS_param_filename;
  } else {
    config->model_dir = model_dir;
  }
  if (use_gpu) {
    config->use_gpu = true;
    config->device = 0;
    config->fraction_of_gpu_memory = 0.15;
  }
}

template <>
void SetConfig<AnalysisConfig>(AnalysisConfig* config, std::string model_dir,
                               bool use_gpu, bool use_tensorrt,
                               int batch_size) {
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    config->SetModel(model_dir + "/" + FLAGS_prog_filename,
                     model_dir + "/" + FLAGS_param_filename);
  } else {
    config->SetModel(model_dir);
  }
  if (use_gpu) {
    config->EnableUseGpu(100, 0);
    if (use_tensorrt) {
      config->EnableTensorRtEngine(1 << 10, batch_size, 3,
                                   AnalysisConfig::Precision::kFloat32, false);
      config->pass_builder()->DeletePass("conv_bn_fuse_pass");
      config->pass_builder()->DeletePass("fc_fuse_pass");
      config->pass_builder()->TurnOnDebug();
    } else {
      config->SwitchIrOptim();
    }
  }
}

void profile(std::string model_dir, bool use_analysis, bool use_tensorrt) {
  std::vector<std::vector<PaddleTensor>> inputs_all;
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                      FLAGS_param_filename);
  } else {
    SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");
  }

  std::vector<std::vector<PaddleTensor>> outputs;
  if (use_analysis || use_tensorrt) {
    AnalysisConfig config;
    config.EnableUseGpu(100, 0);
    config.pass_builder()->TurnOnDebug();
    SetConfig<AnalysisConfig>(&config, model_dir, true, use_tensorrt,
                              FLAGS_batch_size);
    TestPrediction(reinterpret_cast<PaddlePredictor::Config*>(&config),
                   inputs_all, &outputs, FLAGS_num_threads, true);
  } else {
    NativeConfig config;
    SetConfig<NativeConfig>(&config, model_dir, true, false);
    TestPrediction(reinterpret_cast<PaddlePredictor::Config*>(&config),
                   inputs_all, &outputs, FLAGS_num_threads, false);
  }
}

void compare(std::string model_dir, bool use_tensorrt) {
  std::vector<std::vector<PaddleTensor>> inputs_all;
  if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
    SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                      FLAGS_param_filename);
  } else {
    SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");
  }

  AnalysisConfig analysis_config;
  SetConfig<AnalysisConfig>(&analysis_config, model_dir, true, use_tensorrt,
                            FLAGS_batch_size);
  CompareNativeAndAnalysis(
      reinterpret_cast<const PaddlePredictor::Config*>(&analysis_config),
      inputs_all);
}

void compare_continuous_input(std::string model_dir, bool use_tensorrt) {
  AnalysisConfig analysis_config;
  SetConfig<AnalysisConfig>(&analysis_config, model_dir, true, use_tensorrt,
                            FLAGS_batch_size);
  auto config =
      reinterpret_cast<const PaddlePredictor::Config*>(&analysis_config);
  auto native_pred = CreateTestPredictor(config, false);
  auto analysis_pred = CreateTestPredictor(config, true);
  for (int i = 0; i < 20; i++) {
    std::vector<std::vector<PaddleTensor>> inputs_all;
    if (!FLAGS_prog_filename.empty() && !FLAGS_param_filename.empty()) {
      SetFakeImageInput(&inputs_all, model_dir, true, FLAGS_prog_filename,
                        FLAGS_param_filename, nullptr, i);
    } else {
      SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "", nullptr,
                        i);
    }
    CompareNativeAndAnalysis(native_pred.get(), analysis_pred.get(),
                             inputs_all);
  }
}

TEST(TensorRT_mobilenet, compare) {
  std::string model_dir = FLAGS_infer_model + "/mobilenet";
  compare(model_dir, /* use_tensorrt */ true);
  // Open it when need.
  // profile(model_dir, /* use_analysis */ true, FLAGS_use_tensorrt);
}

TEST(resnet50, compare_continuous_input) {
  std::string model_dir = FLAGS_infer_model + "/resnet50";
  compare_continuous_input(model_dir, true);
}

TEST(TensorRT_resnext50, compare) {
  std::string model_dir = FLAGS_infer_model + "/resnext50";
  compare(model_dir, /* use_tensorrt */ true);
}

TEST(AnalysisPredictor, use_gpu) {
  std::string model_dir = FLAGS_infer_model + "/" + "mobilenet";
  AnalysisConfig config;
  config.EnableUseGpu(100, 0);
  config.SetModel(model_dir);
  config.pass_builder()->TurnOnDebug();

  std::vector<std::vector<PaddleTensor>> inputs_all;
  auto predictor = CreatePaddlePredictor(config);
  SetFakeImageInput(&inputs_all, model_dir, false, "__model__", "");

  std::vector<PaddleTensor> outputs;
  for (auto& input : inputs_all) {
    ASSERT_TRUE(predictor->Run(input, &outputs));
  }
}

}  // namespace inference
}  // namespace paddle
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <vector>

#include <iod/sio.hh>
#include <iod/sio_utils.hh>
#include <iod/json.hh>
#include <iod/tuple_utils.hh>
#include <silicon/procedure_desc.hh>

namespace iod
{

  template <typename M, typename C>
  struct handler;

  namespace error
  {
    struct error
    {
    public:
      error(int status, const std::string& what) : status_(status), what_(what) {}
      error(int status, const char* what) : status_(status), what_(what) {}
      auto status() const { return status_; }
      auto what() const { return what_; }

    private:
      int status_;
      std::string what_;
    };

    template <typename E>
    inline void format_error_(E&) {}

    template <typename E, typename T1, typename... T>
    inline void format_error_(E& err, T1 a, T... args)
    {
      err << a;
      format_error_(err, std::forward<T>(args)...);
    }

    template <typename... T>
    inline std::string format_error(T&&... args) {
      std::stringstream ss;
      format_error_(ss, std::forward<T>(args)...);
      return ss.str();
    }

#define SILICON_HTTP_ERROR(CODE, ERR)                           \
    template <typename... A> auto ERR(A&&... m) { return error(CODE, format_error(m...)); } \
    auto ERR(const char* w) { return error(CODE, w); }

    SILICON_HTTP_ERROR(400, bad_request)
    SILICON_HTTP_ERROR(401, unauthorized)
    SILICON_HTTP_ERROR(403, forbidden)
    SILICON_HTTP_ERROR(404, not_found)

    SILICON_HTTP_ERROR(500, internal_server_error)
    SILICON_HTTP_ERROR(501, not_implemented)

#undef SILICON_HTTP_ERROR
  }

  template <typename M>
  struct handler_base
  {
    handler_base(std::string n) : name_(n) {}
    virtual void operator()(M& middlewares, request& request, response& response) = 0;

    virtual procedure_desc description() = 0;

    std::string name_;
  };

  template <typename M, typename C>
  struct handler : public handler_base<M>
  {
    typedef C content_type;
    handler(std::string n, C c) : handler_base<M>(n), content_(c) {}

    virtual void operator()(M& middlewares, request& request, response& response)
    {
      try
      {
        run_handler(*this, middlewares, request, response);
      }
      catch(const error::error& e)
      {
        response.set_status(e.status());
        response << e.what();
      }
      catch(const std::runtime_error& e)
      {
        std::cout << e.what() << std::endl;
        response.set_status(500);
        response << "Internal server error.";
      }

    }

    virtual procedure_desc description()
    {
      return std::move(procedure_desc(*this));
    }

    C content_;
  };

  template <typename S, typename... T>
  struct pre_typed_handler_creator
  {
    pre_typed_handler_creator(S* s, std::string name) : s_(s), name_(name) {}

    template <typename C, typename... U>
    void run(C content, std::tuple<U...>*);

    template <typename C>
    void operator=(C content)
    {
      typedef decltype(D(std::declval<T>()...)) params_type;
      run(content, (callable_arguments_tuple_t<decltype(&C::template operator()<params_type>)>*)0);
    }

    S* s_;
    std::string name_;
  };

  template <typename S>
  struct handler_creator
  {
    handler_creator(S* s, std::string name) : s_(s), name_(name) {}

    template <typename C>
    void operator=(C content);

    template <typename U, bool>
    struct add_missing_string_value_types { typedef U type; };
    template <typename U>
    struct add_missing_string_value_types<U, true> {
      typedef typename U::template variable_type<std::string> type;
    };

    template <typename... T>
    auto operator()(T...)
    {
      return pre_typed_handler_creator<S, typename add_missing_string_value_types<T, std::is_base_of<symbol<T>, T>::value>::type...>
                                                   (s_, name_);
    }

    S* s_;
    std::string name_;
  };

  template <typename S>
  struct route_handler_creator
  {
    route_handler_creator(S* s, std::string route) : s_(s), route_(route) {}

    template <typename C>
    void operator=(C content);

    S* s_;
    std::string route_;
  };

  template <typename M>
  struct server
  {
    typedef server<M> self_type;

    server(M&& middlewares) : middlewares_(middlewares)
    {}

    auto operator[](std::string procedure_name)
    {
      return handler_creator<self_type>(this, procedure_name);
    }

    auto route(std::string route_path)
    {
      return route_handler_creator<self_type>(this, route_path);
    }

    template <typename F>
    auto add_procedure(std::string name, F f)
    {
      handlers.push_back(new handler<M, F>(name, f));
      return *this;
    }

    template <typename F>
    auto add_route(std::string name, F f)
    {
      routes[name] = new handler<M, F>(name, f);
      return *this;
    }

    void handle(request& request,
                response& response)
      try
      {
        handler_base<M>* h = nullptr;

        if (request.location() == "/") // Routing with handler_id
        {
          // get rq metadata.
          auto md = iod::D(s::_Handler_id = int());
          int pos;
          iod::json_decode(md, request.get_body_string(), pos);
          request.set_params_position(pos);

          if (md.handler_id < int(handlers.size()) and md.handler_id >= 0)
            h = handlers[md.handler_id];
          else
            throw error::not_found("Procedure id = ", md.handler_id, " does not exist.");
        }
        else // Classing routing
        {
          auto r = routes.find(request.location());
          if (r != routes.end())
            h = r->second;
          else
            throw error::not_found("Route ", request.location(), " does not exist.");
        }

        (*h)(middlewares_, request, response);
      }
      catch(const error::error& e)
      {
        response.set_status(e.status());
        response << e.what();
      }

    void serve(int port)
    {
      backend_.serve(port, [this] (auto& req, auto& res) { this->handle(req, res); });
    }

    const std::vector<handler_base<M>*>& get_handlers() const { return handlers; }

    M middlewares_;
    backend backend_;
    std::vector<handler_base<M>*> handlers;
    std::map<std::string, handler_base<M>*> routes;
  };

  template <typename T, typename S>
  T& get_middleware(S& server)
  {
    return tuple_get_by_type<T>(server.middlewares_);
  }

  template <typename... M>
  auto silicon(M&&... middlewares)
  {
    return server<decltype(std::make_tuple(middlewares...))>
      (std::make_tuple(middlewares...));
  }

  template <typename S>
  template <typename C>
  void handler_creator<S>::operator=(C content)
  {
    s_->add_procedure(name_, content);
  }

  template <typename S>
  template <typename C>
  void route_handler_creator<S>::operator=(C content)
  {
    s_->add_route(route_, content);
  }

  template <typename S, typename... T>
  template <typename C, typename... U>
  void
  pre_typed_handler_creator<S, T...>::run(C content, std::tuple<U...>*)
  {
    s_->add_procedure(name_,
                      [&content] (U&&... tail)
                      {
                        return content(std::forward<U>(tail)...);
                      });
  };

}

#include <silicon/run_handler.hh>
<commit_msg>Parameters for routes.<commit_after>#pragma once

#include <string>
#include <vector>

#include <iod/sio.hh>
#include <iod/sio_utils.hh>
#include <iod/json.hh>
#include <iod/tuple_utils.hh>
#include <silicon/procedure_desc.hh>

namespace iod
{

  template <typename M, typename C>
  struct handler;

  namespace error
  {
    struct error
    {
    public:
      error(int status, const std::string& what) : status_(status), what_(what) {}
      error(int status, const char* what) : status_(status), what_(what) {}
      auto status() const { return status_; }
      auto what() const { return what_; }

    private:
      int status_;
      std::string what_;
    };

    template <typename E>
    inline void format_error_(E&) {}

    template <typename E, typename T1, typename... T>
    inline void format_error_(E& err, T1 a, T... args)
    {
      err << a;
      format_error_(err, std::forward<T>(args)...);
    }

    template <typename... T>
    inline std::string format_error(T&&... args) {
      std::stringstream ss;
      format_error_(ss, std::forward<T>(args)...);
      return ss.str();
    }

#define SILICON_HTTP_ERROR(CODE, ERR)                           \
    template <typename... A> auto ERR(A&&... m) { return error(CODE, format_error(m...)); } \
    auto ERR(const char* w) { return error(CODE, w); }

    SILICON_HTTP_ERROR(400, bad_request)
    SILICON_HTTP_ERROR(401, unauthorized)
    SILICON_HTTP_ERROR(403, forbidden)
    SILICON_HTTP_ERROR(404, not_found)

    SILICON_HTTP_ERROR(500, internal_server_error)
    SILICON_HTTP_ERROR(501, not_implemented)

#undef SILICON_HTTP_ERROR
  }

  template <typename M>
  struct handler_base
  {
    handler_base(std::string n) : name_(n) {}
    virtual void operator()(M& middlewares, request& request, response& response) = 0;

    virtual procedure_desc description() = 0;

    std::string name_;
  };

  template <typename M, typename C>
  struct handler : public handler_base<M>
  {
    typedef C content_type;
    handler(std::string n, C c) : handler_base<M>(n), content_(c) {}

    virtual void operator()(M& middlewares, request& request, response& response)
    {
      try
      {
        run_handler(*this, middlewares, request, response);
      }
      catch(const error::error& e)
      {
        response.set_status(e.status());
        response << e.what();
      }
      catch(const std::runtime_error& e)
      {
        std::cout << e.what() << std::endl;
        response.set_status(500);
        response << "Internal server error.";
      }

    }

    virtual procedure_desc description()
    {
      return std::move(procedure_desc(*this));
    }

    C content_;
  };

  template <typename F, typename... T>
  struct pre_typed_handler_creator
  {
    pre_typed_handler_creator(F f) : f_(f) {}

    template <typename C, typename... U>
    void run(C content, std::tuple<U...>*);

    template <typename C>
    void operator=(C content)
    {
      typedef decltype(D(std::declval<T>()...)) params_type;
      run(content, (callable_arguments_tuple_t<decltype(&C::template operator()<params_type>)>*)0);
    }

    F f_;
  };

  template <typename F>
  struct handler_creator
  {
    handler_creator(F f) : f_(f) {}

    template <typename C>
    void operator=(C content);

    template <typename U, bool>
    struct add_missing_string_value_types { typedef U type; };
    template <typename U>
    struct add_missing_string_value_types<U, true> {
      typedef typename U::template variable_type<std::string> type;
    };

    template <typename... T>
    auto operator()(T...)
    {
      return pre_typed_handler_creator<F, typename add_missing_string_value_types<T, std::is_base_of<symbol<T>, T>::value>::type...>
                                                   (f_);
    }

    F f_;
  };

  template <typename M>
  struct server
  {
    typedef server<M> self_type;

    server(M&& middlewares) : middlewares_(middlewares)
    {}

    auto operator[](std::string procedure_name)
    {
      auto f = [this,procedure_name] (auto&& f) { this->add_procedure(procedure_name, f); };
      return handler_creator<decltype(f)>(f);
    }

    auto route(std::string route_path)
    {
      auto f = [this,route_path] (auto&& f) { this->add_route(route_path, f); };
      return handler_creator<decltype(f)>(f);
    }

    template <typename F>
    auto add_procedure(std::string name, F f)
    {
      handlers.push_back(new handler<M, F>(name, f));
      return *this;
    }

    template <typename F>
    auto add_route(std::string name, F f)
    {
      routes[name] = new handler<M, F>(name, f);
      return *this;
    }

    void handle(request& request,
                response& response)
      try
      {
        handler_base<M>* h = nullptr;
        const std::string& location = request.location();
        if (location.size() > 3 and
            location[0] == '/' and
            location[1] == '_' and
            location[2] == '_') // Routing with /__handler_id
        {
          int hid = 0;
          unsigned i = 3;
          while (i < location.size() and location[i] >= '0' and location[i] <= '9')
            hid = hid * 10 + location[i++] - '0';

          request.set_params_position(0);

          if (hid < int(handlers.size()) and hid >= 0)
            h = handlers[hid];
          else
            throw error::not_found("Procedure id = ", hid, " does not exist.");
        }
        else // Classic routing
        {
          auto r = routes.find(request.location());
          if (r != routes.end())
            h = r->second;
          else
            throw error::not_found("Route ", request.location(), " does not exist.");
        }

        (*h)(middlewares_, request, response);
      }
      catch(const error::error& e)
      {
        response.set_status(e.status());
        response << e.what();
      }

    void serve(int port)
    {
      backend_.serve(port, [this] (auto& req, auto& res) { this->handle(req, res); });
    }

    const std::vector<handler_base<M>*>& get_handlers() const { return handlers; }

    M middlewares_;
    backend backend_;
    std::vector<handler_base<M>*> handlers;
    std::map<std::string, handler_base<M>*> routes;
  };

  template <typename T, typename S>
  T& get_middleware(S& server)
  {
    return tuple_get_by_type<T>(server.middlewares_);
  }

  template <typename... M>
  auto silicon(M&&... middlewares)
  {
    return server<decltype(std::make_tuple(middlewares...))>
      (std::make_tuple(middlewares...));
  }

  template <typename S>
  template <typename C>
  void handler_creator<S>::operator=(C content)
  {
    f_(content);
  }

  template <typename S, typename... T>
  template <typename C, typename... U>
  void
  pre_typed_handler_creator<S, T...>::run(C content, std::tuple<U...>*)
  {
    f_([&content] (U&&... tail)
       {
         return content(std::forward<U>(tail)...);
       });
  };

}

#include <silicon/run_handler.hh>
<|endoftext|>


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

#ifndef SD_MEDIA_OBJECT_BAR_HXX
#define SD_MEDIA_OBJECT_BAR_HXX

#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#ifndef _SD_GLOB_HXX
#include "glob.hxx"
#endif

namespace sd {

class View;
class ViewShell;

class MediaObjectBar
    : public SfxShell
{
public:
    TYPEINFO();
    SFX_DECL_INTERFACE( SD_IF_SDDRAWMEDIAOBJECTBAR );

    MediaObjectBar (ViewShell* pSdViewShell, ::sd::View* pSdView);
    virtual ~MediaObjectBar (void);

    void            GetState( SfxItemSet& rSet );
    void            Execute( SfxRequest& rReq );

protected:
    ::sd::View* pView;
    ViewShell*  pViewSh;
};

} // end of namespace sd

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

#ifndef SD_MEDIA_OBJECT_BAR_HXX
#define SD_MEDIA_OBJECT_BAR_HXX

#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#ifndef _SD_GLOB_HXX
#include "glob.hxx"
#endif

namespace sd {

class View;
class ViewShell;

class MediaObjectBar
    : public SfxShell
{
public:
    TYPEINFO();
    SFX_DECL_INTERFACE( SD_IF_SDDRAWMEDIAOBJECTBAR );

    MediaObjectBar (ViewShell* pSdViewShell, ::sd::View* pSdView);
    virtual ~MediaObjectBar (void);

    void            GetState( SfxItemSet& rSet );
    void            Execute( SfxRequest& rReq );

protected:
    ::sd::View* pView;
    ViewShell*  pViewSh;
};

} // end of namespace sd

#endif
<|endoftext|>


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

#include "ViewClipboard.hxx"

#include "DrawDocShell.hxx"
#include "View.hxx"
#include "ViewShell.hxx"
#include "Window.hxx"

#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "sdxfer.hxx"
#include "sdresid.hxx"
#include "glob.hrc"

#include <svx/svdpagv.hxx>

namespace sd {

ViewClipboard::ViewClipboard (::sd::View& rView)
    : mrView(rView)
{
}

ViewClipboard::~ViewClipboard (void)
{
}

void ViewClipboard::HandlePageDrop (const SdTransferable& rTransferable)
{
    // Determine whether to insert the given set of slides or to assign a
    // given master page.
    SdPage* pMasterPage = GetFirstMasterPage (rTransferable);
    if (pMasterPage != NULL)
        AssignMasterPage (rTransferable, pMasterPage);
    else
        InsertSlides (rTransferable, DetermineInsertPosition (rTransferable));
}

SdPage* ViewClipboard::GetFirstMasterPage (const SdTransferable& rTransferable)
{
    SdPage* pFirstMasterPage = NULL;

    if (rTransferable.HasPageBookmarks())
    {
        do
        {
            const List* pBookmarks = &rTransferable.GetPageBookmarks();
            if (pBookmarks == NULL)
                break;

            DrawDocShell* pDocShell = rTransferable.GetPageDocShell();
            if (pDocShell == NULL)
                break;

            SdDrawDocument* pDocument = pDocShell->GetDoc();
            if (pDocument == NULL)
                break;

            if (pBookmarks->Count() <= 0)
                break;

            int nBookmarkCount = pBookmarks->Count();
            for (int nIndex=0; nIndex<nBookmarkCount; nIndex++)
            {
                String sName (*(String*) pBookmarks->GetObject(nIndex));
                BOOL bIsMasterPage;

                // SdPage* GetMasterSdPage(USHORT nPgNum, PageKind ePgKind);
                // USHORT GetMasterSdPageCount(PageKind ePgKind) const;

                USHORT nBMPage = pDocument->GetPageByName (
                    sName, bIsMasterPage);
                if ( ! bIsMasterPage)
                {
                    // At least one regular slide: return NULL to indicate
                    // that not all bookmarks point to master pages.
                    pFirstMasterPage = NULL;
                    break;
                }
                else if (pFirstMasterPage == NULL)
                {
                    // Remember the first master page for later.
                    if (nBMPage != SDRPAGE_NOTFOUND)
                        pFirstMasterPage = static_cast<SdPage*>(
                            pDocument->GetMasterPage(nBMPage));
                }
            }
        }
        while (false);
    }

    return pFirstMasterPage;
}

void ViewClipboard::AssignMasterPage (
    const SdTransferable& rTransferable,
    SdPage* pMasterPage)
{
    do
    {
        if (pMasterPage == NULL)
            return;

        // Get the target page to which the master page is assigned.
        SdrPageView* pPageView = mrView.GetPageViewPvNum(0);
        if (pPageView == NULL)
            break;

        SdPage* pPage = static_cast<SdPage*>(pPageView->GetPage());
        if (pPage == NULL)
            break;

        SdDrawDocument* pDocument = mrView.GetDoc();
        if (pDocument == NULL)
            break;

        if ( ! rTransferable.HasPageBookmarks())
            break;

        DrawDocShell* pDataDocShell = rTransferable.GetPageDocShell();
        if (pDataDocShell == NULL)
            break;

        SdDrawDocument* pSourceDocument = pDataDocShell->GetDoc();
        if (pSourceDocument == NULL)
            break;

        // We have to remove the layout suffix from the layout name which is
        // appended again by SetMasterPage() to the given name.  Don't ask.
        String sLayoutSuffix (RTL_CONSTASCII_STRINGPARAM(SD_LT_SEPARATOR));
        sLayoutSuffix.Append (SdResId(STR_LAYOUT_OUTLINE));
        int nLength = sLayoutSuffix.Len();
        String sLayoutName (pMasterPage->GetLayoutName());
        if (String(sLayoutName, sLayoutName.Len()-nLength, nLength).Equals (
            sLayoutSuffix))
            sLayoutName = String(sLayoutName, 0, sLayoutName.Len()-nLength);

        pDocument->SetMasterPage (
            pPage->GetPageNum() / 2,
            sLayoutName,
            pSourceDocument,
            FALSE, // Exchange the master page of only the target page.
            FALSE // Keep unused master pages.
            );
    }
    while (false);
}

USHORT ViewClipboard::DetermineInsertPosition  (
    const SdTransferable& rTransferable)
{
    SdDrawDocument* pDoc = mrView.GetDoc();
    USHORT nPgCnt = pDoc->GetSdPageCount( PK_STANDARD );

    // Insert position is the behind the last selected page or behind the
    // last page when the selection is empty.
    USHORT nInsertPos = pDoc->GetSdPageCount( PK_STANDARD ) * 2 + 1;
    for( USHORT nPage = 0; nPage < nPgCnt; nPage++ )
    {
        SdPage* pPage = pDoc->GetSdPage( nPage, PK_STANDARD );

        if( pPage->IsSelected() )
            nInsertPos = nPage * 2 + 3;
    }

    return nInsertPos;
}

USHORT ViewClipboard::InsertSlides (
    const SdTransferable& rTransferable,
    USHORT nInsertPosition)
{
    SdDrawDocument* pDoc = mrView.GetDoc();

    USHORT nInsertPgCnt = 0;
    USHORT nPgCnt = pDoc->GetSdPageCount( PK_STANDARD );
    BOOL bMergeMasterPages = !rTransferable.HasSourceDoc( pDoc );

    // Prepare the insertion.
    const List* pBookmarkList;
    DrawDocShell* pDataDocSh;
    if (rTransferable.HasPageBookmarks())
    {
        // When the transferable contains page bookmarks then the referenced
        // pages are inserted.
        pBookmarkList = &rTransferable.GetPageBookmarks();
        pDataDocSh = rTransferable.GetPageDocShell();
        nInsertPgCnt = (USHORT)pBookmarkList->Count();
    }
    else
    {
        // Otherwise all pages of the document of the transferable are
        // inserted.
        SfxObjectShell* pShell = rTransferable.GetDocShell();
        pDataDocSh = (DrawDocShell*) pShell;
        SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
        pBookmarkList = NULL;
        if (pDataDoc!=NULL && pDataDoc->GetSdPageCount(PK_STANDARD))
            nInsertPgCnt = pDataDoc->GetSdPageCount(PK_STANDARD);
    }
    if (nInsertPgCnt > 0)
    {
        const ::vos::OGuard aGuard( Application::GetSolarMutex() );
        ::sd::Window* pWin = mrView.GetViewShell()->GetActiveWindow();
        const BOOL bWait = pWin && pWin->IsWait();

        if( bWait )
            pWin->LeaveWait();

        pDoc->InsertBookmarkAsPage(
            const_cast<List*>(pBookmarkList),
            NULL,
            FALSE,
            FALSE,
            nInsertPosition,
            (&rTransferable == SD_MOD()->pTransferDrag),
            pDataDocSh,
            TRUE,
            bMergeMasterPages,
            FALSE);

        if( bWait )
            pWin->EnterWait();
    }

    return nInsertPgCnt;
}

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

#include "ViewClipboard.hxx"

#include "DrawDocShell.hxx"
#include "View.hxx"
#include "ViewShell.hxx"
#include "Window.hxx"

#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "sdxfer.hxx"
#include "sdresid.hxx"
#include "glob.hrc"

#include <svx/svdpagv.hxx>

namespace sd {

ViewClipboard::ViewClipboard (::sd::View& rView)
    : mrView(rView)
{
}

ViewClipboard::~ViewClipboard (void)
{
}

void ViewClipboard::HandlePageDrop (const SdTransferable& rTransferable)
{
    // Determine whether to insert the given set of slides or to assign a
    // given master page.
    SdPage* pMasterPage = GetFirstMasterPage (rTransferable);
    if (pMasterPage != NULL)
        AssignMasterPage (rTransferable, pMasterPage);
    else
        InsertSlides (rTransferable, DetermineInsertPosition (rTransferable));
}

SdPage* ViewClipboard::GetFirstMasterPage (const SdTransferable& rTransferable)
{
    SdPage* pFirstMasterPage = NULL;

    if (rTransferable.HasPageBookmarks())
    {
        do
        {
            const List* pBookmarks = &rTransferable.GetPageBookmarks();
            if (pBookmarks == NULL)
                break;

            DrawDocShell* pDocShell = rTransferable.GetPageDocShell();
            if (pDocShell == NULL)
                break;

            SdDrawDocument* pDocument = pDocShell->GetDoc();
            if (pDocument == NULL)
                break;

            if (pBookmarks->Count() <= 0)
                break;

            int nBookmarkCount = pBookmarks->Count();
            for (int nIndex=0; nIndex<nBookmarkCount; nIndex++)
            {
                String sName (*(String*) pBookmarks->GetObject(nIndex));
                BOOL bIsMasterPage;

                // SdPage* GetMasterSdPage(USHORT nPgNum, PageKind ePgKind);
                // USHORT GetMasterSdPageCount(PageKind ePgKind) const;

                USHORT nBMPage = pDocument->GetPageByName (
                    sName, bIsMasterPage);
                if ( ! bIsMasterPage)
                {
                    // At least one regular slide: return NULL to indicate
                    // that not all bookmarks point to master pages.
                    pFirstMasterPage = NULL;
                    break;
                }
                else if (pFirstMasterPage == NULL)
                {
                    // Remember the first master page for later.
                    if (nBMPage != SDRPAGE_NOTFOUND)
                        pFirstMasterPage = static_cast<SdPage*>(
                            pDocument->GetMasterPage(nBMPage));
                }
            }
        }
        while (false);
    }

    return pFirstMasterPage;
}

void ViewClipboard::AssignMasterPage (
    const SdTransferable& rTransferable,
    SdPage* pMasterPage)
{
    do
    {
        if (pMasterPage == NULL)
            return;

        // Get the target page to which the master page is assigned.
        SdrPageView* pPageView = mrView.GetPageViewPvNum(0);
        if (pPageView == NULL)
            break;

        SdPage* pPage = static_cast<SdPage*>(pPageView->GetPage());
        if (pPage == NULL)
            break;

        SdDrawDocument* pDocument = mrView.GetDoc();
        if (pDocument == NULL)
            break;

        if ( ! rTransferable.HasPageBookmarks())
            break;

        DrawDocShell* pDataDocShell = rTransferable.GetPageDocShell();
        if (pDataDocShell == NULL)
            break;

        SdDrawDocument* pSourceDocument = pDataDocShell->GetDoc();
        if (pSourceDocument == NULL)
            break;

        // We have to remove the layout suffix from the layout name which is
        // appended again by SetMasterPage() to the given name.  Don't ask.
        String sLayoutSuffix (RTL_CONSTASCII_STRINGPARAM(SD_LT_SEPARATOR));
        sLayoutSuffix.Append (SdResId(STR_LAYOUT_OUTLINE));
        int nLength = sLayoutSuffix.Len();
        String sLayoutName (pMasterPage->GetLayoutName());
        if (String(sLayoutName, sLayoutName.Len()-nLength, nLength).Equals (
            sLayoutSuffix))
            sLayoutName = String(sLayoutName, 0, sLayoutName.Len()-nLength);

        pDocument->SetMasterPage (
            pPage->GetPageNum() / 2,
            sLayoutName,
            pSourceDocument,
            FALSE, // Exchange the master page of only the target page.
            FALSE // Keep unused master pages.
            );
    }
    while (false);
}

USHORT ViewClipboard::DetermineInsertPosition  (
    const SdTransferable& rTransferable)
{
    SdDrawDocument* pDoc = mrView.GetDoc();
    USHORT nPgCnt = pDoc->GetSdPageCount( PK_STANDARD );

    // Insert position is the behind the last selected page or behind the
    // last page when the selection is empty.
    USHORT nInsertPos = pDoc->GetSdPageCount( PK_STANDARD ) * 2 + 1;
    for( USHORT nPage = 0; nPage < nPgCnt; nPage++ )
    {
        SdPage* pPage = pDoc->GetSdPage( nPage, PK_STANDARD );

        if( pPage->IsSelected() )
            nInsertPos = nPage * 2 + 3;
    }

    return nInsertPos;
}

USHORT ViewClipboard::InsertSlides (
    const SdTransferable& rTransferable,
    USHORT nInsertPosition)
{
    SdDrawDocument* pDoc = mrView.GetDoc();

    USHORT nInsertPgCnt = 0;
    USHORT nPgCnt = pDoc->GetSdPageCount( PK_STANDARD );
    BOOL bMergeMasterPages = !rTransferable.HasSourceDoc( pDoc );

    // Prepare the insertion.
    const List* pBookmarkList;
    DrawDocShell* pDataDocSh;
    if (rTransferable.HasPageBookmarks())
    {
        // When the transferable contains page bookmarks then the referenced
        // pages are inserted.
        pBookmarkList = &rTransferable.GetPageBookmarks();
        pDataDocSh = rTransferable.GetPageDocShell();
        nInsertPgCnt = (USHORT)pBookmarkList->Count();
    }
    else
    {
        // Otherwise all pages of the document of the transferable are
        // inserted.
        SfxObjectShell* pShell = rTransferable.GetDocShell();
        pDataDocSh = (DrawDocShell*) pShell;
        SdDrawDocument* pDataDoc = pDataDocSh->GetDoc();
        pBookmarkList = NULL;
        if (pDataDoc!=NULL && pDataDoc->GetSdPageCount(PK_STANDARD))
            nInsertPgCnt = pDataDoc->GetSdPageCount(PK_STANDARD);
    }
    if (nInsertPgCnt > 0)
    {
        const ::vos::OGuard aGuard( Application::GetSolarMutex() );
        ::sd::Window* pWin = mrView.GetViewShell()->GetActiveWindow();
        const BOOL bWait = pWin && pWin->IsWait();

        if( bWait )
            pWin->LeaveWait();

        pDoc->InsertBookmarkAsPage(
            const_cast<List*>(pBookmarkList),
            NULL,
            FALSE,
            FALSE,
            nInsertPosition,
            (&rTransferable == SD_MOD()->pTransferDrag),
            pDataDocSh,
            TRUE,
            bMergeMasterPages,
            FALSE);

        if( bWait )
            pWin->EnterWait();
    }

    return nInsertPgCnt;
}

} // end of namespace ::sd
<|endoftext|>


<commit_before>#include "selfdrive/ui/qt/widgets/keyboard.h"

#include <QButtonGroup>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>

const int DEFAULT_STRETCH = 1;
const int SPACEBAR_STRETCH = 3;

const QString BACKSPACE_KEY = "⌫";
const QString ENTER_KEY = "⏎";

const QStringList CONTROL_BUTTONS = {"↑", "↓", "ABC", "#+=", "123"};

KeyboardLayout::KeyboardLayout(QWidget* parent, const std::vector<QVector<QString>>& layout) : QWidget(parent) {
  QVBoxLayout* main_layout = new QVBoxLayout(this);
  main_layout->setMargin(0);
  main_layout->setSpacing(20);

  QButtonGroup* btn_group = new QButtonGroup(this);
  QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*)));

  for (const auto &s : layout) {
    QHBoxLayout *hlayout = new QHBoxLayout;
    hlayout->setSpacing(15);

    if (main_layout->count() == 1) {
      hlayout->addSpacing(90);
    }

    for (const QString &p : s) {
      QPushButton* btn = new QPushButton(p);
      if (p == BACKSPACE_KEY) {
        btn->setAutoRepeat(true);
      } else if (p == ENTER_KEY) {
        btn->setStyleSheet("background-color: #465BEA;");
      }
      btn->setFixedHeight(135);
      btn_group->addButton(btn);
      hlayout->addWidget(btn, p == QString("  ") ? SPACEBAR_STRETCH : DEFAULT_STRETCH);
    }

    if (main_layout->count() == 1) {
      hlayout->addSpacing(90);
    }

    main_layout->addLayout(hlayout);
  }

  setStyleSheet(R"(
    QPushButton {
      font-size: 75px;
      margin: 0px;
      padding: 0px;
      border-radius: 10px;
      color: #dddddd;
      background-color: #444444;
    }
    QPushButton:pressed {
      background-color: #333333;
    }
  )");
}

Keyboard::Keyboard(QWidget *parent) : QFrame(parent) {
  main_layout = new QStackedLayout(this);
  main_layout->setMargin(0);

  // lowercase
  std::vector<QVector<QString>> lowercase = {
    {"q","w","e","r","t","y","u","i","o","p"},
    {"a","s","d","f","g","h","j","k","l"},
    {"↑","z","x","c","v","b","n","m",BACKSPACE_KEY},
    {"123","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, lowercase));

  // uppercase
  std::vector<QVector<QString>> uppercase = {
    {"Q","W","E","R","T","Y","U","I","O","P"},
    {"A","S","D","F","G","H","J","K","L"},
    {"↓","Z","X","C","V","B","N","M",BACKSPACE_KEY},
    {"123","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, uppercase));

  // numbers + specials
  std::vector<QVector<QString>> numbers = {
    {"1","2","3","4","5","6","7","8","9","0"},
    {"-","/",":",";","(",")","$","&&","@","\""},
    {"#+=",".",",","?","!","`",BACKSPACE_KEY},
    {"ABC","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, numbers));

  // extra specials
  std::vector<QVector<QString>> specials = {
    {"[","]","{","}","#","%","^","*","+","="},
    {"_","\\","|","~","<",">","€","£","¥","•"},
    {"123",".",",","?","!","`",BACKSPACE_KEY},
    {"ABC","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, specials));

  main_layout->setCurrentIndex(0);
}

void Keyboard::handleButton(QAbstractButton* btn) {
  const QString key = btn->text();
  if (!QString::compare(key, "↓") || !QString::compare(key, "ABC")) {
    main_layout->setCurrentIndex(0);
  }
  if (!QString::compare(key, "↑")) {
    main_layout->setCurrentIndex(1);
  }
  if (!QString::compare(key, "123")) {
    main_layout->setCurrentIndex(2);
  }
  if (!QString::compare(key, "#+=")) {
    main_layout->setCurrentIndex(3);
  }
  if (!QString::compare(key, BACKSPACE_KEY)) {
    main_layout->setCurrentIndex(0);
  }
  if ("A" <= key && key <= "Z") {
    main_layout->setCurrentIndex(0);
  }

  // TODO: break up into separate signals
  if (!CONTROL_BUTTONS.contains(key)) {
    emit emitButton(key);
  }
}
<commit_msg>keyboard: fix backspace (#21602)<commit_after>#include "selfdrive/ui/qt/widgets/keyboard.h"

#include <QButtonGroup>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>

const int DEFAULT_STRETCH = 1;
const int SPACEBAR_STRETCH = 3;

const QString BACKSPACE_KEY = "⌫";
const QString ENTER_KEY = "⏎";

const QStringList CONTROL_BUTTONS = {"↑", "↓", "ABC", "#+=", "123"};

KeyboardLayout::KeyboardLayout(QWidget* parent, const std::vector<QVector<QString>>& layout) : QWidget(parent) {
  QVBoxLayout* main_layout = new QVBoxLayout(this);
  main_layout->setMargin(0);
  main_layout->setSpacing(20);

  QButtonGroup* btn_group = new QButtonGroup(this);
  QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*)));

  for (const auto &s : layout) {
    QHBoxLayout *hlayout = new QHBoxLayout;
    hlayout->setSpacing(15);

    if (main_layout->count() == 1) {
      hlayout->addSpacing(90);
    }

    for (const QString &p : s) {
      QPushButton* btn = new QPushButton(p);
      if (p == BACKSPACE_KEY) {
        btn->setAutoRepeat(true);
      } else if (p == ENTER_KEY) {
        btn->setStyleSheet("background-color: #465BEA;");
      }
      btn->setFixedHeight(135);
      btn_group->addButton(btn);
      hlayout->addWidget(btn, p == QString("  ") ? SPACEBAR_STRETCH : DEFAULT_STRETCH);
    }

    if (main_layout->count() == 1) {
      hlayout->addSpacing(90);
    }

    main_layout->addLayout(hlayout);
  }

  setStyleSheet(R"(
    QPushButton {
      font-size: 75px;
      margin: 0px;
      padding: 0px;
      border-radius: 10px;
      color: #dddddd;
      background-color: #444444;
    }
    QPushButton:pressed {
      background-color: #333333;
    }
  )");
}

Keyboard::Keyboard(QWidget *parent) : QFrame(parent) {
  main_layout = new QStackedLayout(this);
  main_layout->setMargin(0);

  // lowercase
  std::vector<QVector<QString>> lowercase = {
    {"q","w","e","r","t","y","u","i","o","p"},
    {"a","s","d","f","g","h","j","k","l"},
    {"↑","z","x","c","v","b","n","m",BACKSPACE_KEY},
    {"123","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, lowercase));

  // uppercase
  std::vector<QVector<QString>> uppercase = {
    {"Q","W","E","R","T","Y","U","I","O","P"},
    {"A","S","D","F","G","H","J","K","L"},
    {"↓","Z","X","C","V","B","N","M",BACKSPACE_KEY},
    {"123","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, uppercase));

  // numbers + specials
  std::vector<QVector<QString>> numbers = {
    {"1","2","3","4","5","6","7","8","9","0"},
    {"-","/",":",";","(",")","$","&&","@","\""},
    {"#+=",".",",","?","!","`",BACKSPACE_KEY},
    {"ABC","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, numbers));

  // extra specials
  std::vector<QVector<QString>> specials = {
    {"[","]","{","}","#","%","^","*","+","="},
    {"_","\\","|","~","<",">","€","£","¥","•"},
    {"123",".",",","?","!","`",BACKSPACE_KEY},
    {"ABC","  ",".",ENTER_KEY},
  };
  main_layout->addWidget(new KeyboardLayout(this, specials));

  main_layout->setCurrentIndex(0);
}

void Keyboard::handleButton(QAbstractButton* btn) {
  const QString key = btn->text();
  if (!QString::compare(key, "↓") || !QString::compare(key, "ABC")) {
    main_layout->setCurrentIndex(0);
  }
  if (!QString::compare(key, "↑")) {
    main_layout->setCurrentIndex(1);
  }
  if (!QString::compare(key, "123")) {
    main_layout->setCurrentIndex(2);
  }
  if (!QString::compare(key, "#+=")) {
    main_layout->setCurrentIndex(3);
  }
  if (!QString::compare(key, ENTER_KEY)) {
    main_layout->setCurrentIndex(0);
  }
  if ("A" <= key && key <= "Z") {
    main_layout->setCurrentIndex(0);
  }

  // TODO: break up into separate signals
  if (!CONTROL_BUTTONS.contains(key)) {
    emit emitButton(key);
  }
}
<|endoftext|>