<commit_before>/** @file

  session_process.cc - encrypt and decrypt sessions

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <cmath>
#include <cstring>
#include <cerrno>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <ts/ts.h>

#include "session_process.h"
#include "ssl_utils.h"

#include "common.h"

const unsigned char salt[] = {115, 97, 108, 117, 0, 85, 137, 229};

int
encrypt_session(const char *session_data, int32_t session_data_len, const unsigned char *key, int key_length,
                std::string &encrypted_data)
{
  size_t len_all = 0;
  size_t offset  = 0;
  char *pBuf     = nullptr;

  int encrypted_buffer_size    = 0;
  int encrypted_msg_len        = 0;
  unsigned char *encrypted_msg = nullptr;
  int ret                      = 0;

  offset  = 0;
  len_all = sizeof(int64_t) + sizeof(int32_t) + session_data_len;

  pBuf = new char[len_all];

  // Put in a fixed experation time of 7 hours, just to have communication consistency with the original
  // protocol
  int64_t expire_time = time(nullptr) + 2 * 3600;
  memcpy(pBuf + offset, &expire_time, sizeof(expire_time));
  offset += sizeof(int64_t);

  memcpy(pBuf + offset, &session_data_len, sizeof(int32_t));
  offset += sizeof(session_data_len);
  memcpy(pBuf + offset, session_data, session_data_len);

  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // generate key and iv
  int generated_key_len = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), (unsigned char *)salt, key, key_length, 1, gen_key, iv);
  if (generated_key_len <= 0) {
    TSDebug(PLUGIN, "Error generating key");
  }

  // Set context AES128 with the generated key and iv
  if (1 != EVP_EncryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }

  int elen;
  encrypted_buffer_size = ENCRYPT_LEN(len_all);
  encrypted_msg_len     = encrypted_buffer_size;
  encrypted_msg         = new unsigned char[encrypted_buffer_size];
  if (1 != EVP_EncryptUpdate(context, (unsigned char *)encrypted_msg, &elen, (unsigned char *)pBuf, len_all)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }
  encrypted_msg_len = elen;
  if (1 != EVP_EncryptFinal_ex(context, encrypted_msg + elen, &elen)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }
  encrypted_msg_len += elen;

  TSDebug(PLUGIN, "Encrypted buffer of size %d to buffer of size %d\n", session_data_len, encrypted_msg_len);

  encrypted_data.assign((char *)encrypted_msg, encrypted_msg_len);

Cleanup:

  if (pBuf)
    delete[] pBuf;
  if (encrypted_msg)
    delete[] encrypted_msg;
  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}

/**
 * The initial value of session_data_len is the number of bytes in session_data
 * The return value of session_data_len is the number of bytes actually stored in session_data
 * The return value is -1 on error or the number of bytes in the decrypted session data (may be more
 * than the initial value of sesion_data_len
 */
int
decrypt_session(const std::string &encrypted_data, const unsigned char *key, int key_length, char *session_data,
                int32_t &session_data_len)
{
  unsigned char *ssl_sess_ptr  = nullptr;
  int decrypted_buffer_size    = 0;
  int decrypted_msg_len        = 0;
  unsigned char *decrypted_msg = nullptr;
  int ret                      = 0;

  // Initialize context
  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // generate key and iv
  int generated_key_len = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), (unsigned char *)salt, key, key_length, 1, gen_key, iv);

  if (generated_key_len <= 0) {
    TSDebug(PLUGIN, "Error generating key");
  }
  // set context with the generated key and iv
  if (1 != EVP_DecryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "Decryption of encrypted session data failed");
    goto Cleanup;
  }

  decrypted_buffer_size = DECRYPT_LEN(encrypted_data.length());
  decrypted_msg         = (unsigned char *)new char[decrypted_buffer_size + 1];
  decrypted_msg_len     = decrypted_buffer_size + 1;
  if (decrypted_msg == nullptr)
    TSError("decrypted_msg allocate failure");
  if (1 != EVP_DecryptUpdate(context, decrypted_msg, &decrypted_msg_len, (unsigned char *)encrypted_data.c_str(),
                             encrypted_data.length())) {
    TSDebug(PLUGIN, "Decryption of encrypted session data failed");
    goto Cleanup;
  }

  // Retrieve ssl_session
  ssl_sess_ptr = (unsigned char *)decrypted_msg;

  // Skip the expiration time.  Just a place holder to interact with the old version
  ssl_sess_ptr += sizeof(int64_t);

  // Length
  ret = *(int32_t *)ssl_sess_ptr;
  ssl_sess_ptr += sizeof(int32_t);
  TSDebug(PLUGIN, "Decrypted buffer of size %d from buffer of size %d\n", ret, session_data_len);
  // If there is less data than the maxiumum buffer size, reduce accordingly
  if (ret < session_data_len) {
    session_data_len = ret;
  }
  memcpy(session_data, ssl_sess_ptr, session_data_len);

Cleanup:

  if (decrypted_msg)
    delete[] decrypted_msg;

  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}

int
decode_id(const std::string &encoded_id, char *decoded_data, int &decoded_data_len)
{
  size_t decode_len = 0;
  memset(decoded_data, 0, decoded_data_len);
  if (TSBase64Decode((const char *)encoded_id.c_str(), encoded_id.length(), (unsigned char *)decoded_data, decoded_data_len,
                     &decode_len) != 0) {
    TSError("Base 64 decoding failed.");
    return -1;
  }
  decoded_data_len = decode_len;
  return 0;
}

int
encode_id(const char *id, int idlen, std::string &encoded_data)
{
  char *encoded = new char[ENCODED_LEN(idlen)];
  memset(encoded, 0, ENCODED_LEN(idlen));
  size_t encoded_len = 0;
  if (TSBase64Encode((const char *)id, idlen, encoded, ENCODED_LEN(idlen), &encoded_len) != 0) {
    TSError("Base 64 encoding failed.");
    if (encoded)
      delete[] encoded;
    return -1;
  }

  encoded_data.assign(encoded);
  if (encoded)
    delete[] encoded;

  return 0;
}

int
add_session(char *session_id, int session_id_len, const std::string &encrypted_session)
{
  char session_data[SSL_SESSION_MAX_DER];
  int32_t session_data_len = SSL_SESSION_MAX_DER;
  if (decrypt_session(encrypted_session, (unsigned char *)get_key_ptr(), get_key_length(), session_data, session_data_len) < 0) {
    TSError("Failed to decrypt session %.*s", session_id_len, session_id);
    return -1;
  }
  const unsigned char *loc = reinterpret_cast<const unsigned char *>(session_data);
  SSL_SESSION *sess        = d2i_SSL_SESSION(nullptr, &loc, session_data_len);
  if (nullptr == sess) {
    TSError("Failed to transform session buffer %.*s", session_id_len, session_id);
  }
  TSSslSessionID sid;
  memcpy(reinterpret_cast<char *>(sid.bytes), session_id, session_id_len);
  sid.len = session_id_len;
  if (sid.len > sizeof(sid.bytes)) {
    sid.len = sizeof(sid.bytes);
  }
  TSSslSessionInsert(&sid, reinterpret_cast<TSSslSession>(sess));
  // Free the sesison object created by d2i_SSL_SESSION
  // We should make an API that just takes the ASN buffer
  SSL_SESSION_free(sess);
  return 0;
}
<commit_msg>Remove unused assignment to satisfy clang-analyzer<commit_after>/** @file

  session_process.cc - encrypt and decrypt sessions

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <cmath>
#include <cstring>
#include <cerrno>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <ts/ts.h>

#include "session_process.h"
#include "ssl_utils.h"

#include "common.h"

const unsigned char salt[] = {115, 97, 108, 117, 0, 85, 137, 229};

int
encrypt_session(const char *session_data, int32_t session_data_len, const unsigned char *key, int key_length,
                std::string &encrypted_data)
{
  size_t len_all = 0;
  size_t offset  = 0;
  char *pBuf     = nullptr;

  int encrypted_buffer_size    = 0;
  int encrypted_msg_len        = 0;
  unsigned char *encrypted_msg = nullptr;
  int ret                      = 0;

  offset  = 0;
  len_all = sizeof(int64_t) + sizeof(int32_t) + session_data_len;

  pBuf = new char[len_all];

  // Put in a fixed experation time of 7 hours, just to have communication consistency with the original
  // protocol
  int64_t expire_time = time(nullptr) + 2 * 3600;
  memcpy(pBuf + offset, &expire_time, sizeof(expire_time));
  offset += sizeof(int64_t);

  memcpy(pBuf + offset, &session_data_len, sizeof(int32_t));
  offset += sizeof(session_data_len);
  memcpy(pBuf + offset, session_data, session_data_len);

  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // generate key and iv
  int generated_key_len = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), (unsigned char *)salt, key, key_length, 1, gen_key, iv);
  if (generated_key_len <= 0) {
    TSDebug(PLUGIN, "Error generating key");
  }

  // Set context AES128 with the generated key and iv
  if (1 != EVP_EncryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }

  int elen;
  encrypted_buffer_size = ENCRYPT_LEN(len_all);
  encrypted_msg         = new unsigned char[encrypted_buffer_size];
  if (1 != EVP_EncryptUpdate(context, (unsigned char *)encrypted_msg, &elen, (unsigned char *)pBuf, len_all)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }
  encrypted_msg_len = elen;
  if (1 != EVP_EncryptFinal_ex(context, encrypted_msg + elen, &elen)) {
    TSDebug(PLUGIN, "Encryption of session data failed");
    ret = -1;
    goto Cleanup;
  }
  encrypted_msg_len += elen;

  TSDebug(PLUGIN, "Encrypted buffer of size %d to buffer of size %d\n", session_data_len, encrypted_msg_len);

  encrypted_data.assign((char *)encrypted_msg, encrypted_msg_len);

Cleanup:

  if (pBuf)
    delete[] pBuf;
  if (encrypted_msg)
    delete[] encrypted_msg;
  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}

/**
 * The initial value of session_data_len is the number of bytes in session_data
 * The return value of session_data_len is the number of bytes actually stored in session_data
 * The return value is -1 on error or the number of bytes in the decrypted session data (may be more
 * than the initial value of sesion_data_len
 */
int
decrypt_session(const std::string &encrypted_data, const unsigned char *key, int key_length, char *session_data,
                int32_t &session_data_len)
{
  unsigned char *ssl_sess_ptr  = nullptr;
  int decrypted_buffer_size    = 0;
  int decrypted_msg_len        = 0;
  unsigned char *decrypted_msg = nullptr;
  int ret                      = 0;

  // Initialize context
  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // generate key and iv
  int generated_key_len = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), (unsigned char *)salt, key, key_length, 1, gen_key, iv);

  if (generated_key_len <= 0) {
    TSDebug(PLUGIN, "Error generating key");
  }
  // set context with the generated key and iv
  if (1 != EVP_DecryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "Decryption of encrypted session data failed");
    goto Cleanup;
  }

  decrypted_buffer_size = DECRYPT_LEN(encrypted_data.length());
  decrypted_msg         = (unsigned char *)new char[decrypted_buffer_size + 1];
  decrypted_msg_len     = decrypted_buffer_size + 1;
  if (decrypted_msg == nullptr)
    TSError("decrypted_msg allocate failure");
  if (1 != EVP_DecryptUpdate(context, decrypted_msg, &decrypted_msg_len, (unsigned char *)encrypted_data.c_str(),
                             encrypted_data.length())) {
    TSDebug(PLUGIN, "Decryption of encrypted session data failed");
    goto Cleanup;
  }

  // Retrieve ssl_session
  ssl_sess_ptr = (unsigned char *)decrypted_msg;

  // Skip the expiration time.  Just a place holder to interact with the old version
  ssl_sess_ptr += sizeof(int64_t);

  // Length
  ret = *(int32_t *)ssl_sess_ptr;
  ssl_sess_ptr += sizeof(int32_t);
  TSDebug(PLUGIN, "Decrypted buffer of size %d from buffer of size %d\n", ret, session_data_len);
  // If there is less data than the maxiumum buffer size, reduce accordingly
  if (ret < session_data_len) {
    session_data_len = ret;
  }
  memcpy(session_data, ssl_sess_ptr, session_data_len);

Cleanup:

  if (decrypted_msg)
    delete[] decrypted_msg;

  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}

int
decode_id(const std::string &encoded_id, char *decoded_data, int &decoded_data_len)
{
  size_t decode_len = 0;
  memset(decoded_data, 0, decoded_data_len);
  if (TSBase64Decode((const char *)encoded_id.c_str(), encoded_id.length(), (unsigned char *)decoded_data, decoded_data_len,
                     &decode_len) != 0) {
    TSError("Base 64 decoding failed.");
    return -1;
  }
  decoded_data_len = decode_len;
  return 0;
}

int
encode_id(const char *id, int idlen, std::string &encoded_data)
{
  char *encoded = new char[ENCODED_LEN(idlen)];
  memset(encoded, 0, ENCODED_LEN(idlen));
  size_t encoded_len = 0;
  if (TSBase64Encode((const char *)id, idlen, encoded, ENCODED_LEN(idlen), &encoded_len) != 0) {
    TSError("Base 64 encoding failed.");
    if (encoded)
      delete[] encoded;
    return -1;
  }

  encoded_data.assign(encoded);
  if (encoded)
    delete[] encoded;

  return 0;
}

int
add_session(char *session_id, int session_id_len, const std::string &encrypted_session)
{
  char session_data[SSL_SESSION_MAX_DER];
  int32_t session_data_len = SSL_SESSION_MAX_DER;
  if (decrypt_session(encrypted_session, (unsigned char *)get_key_ptr(), get_key_length(), session_data, session_data_len) < 0) {
    TSError("Failed to decrypt session %.*s", session_id_len, session_id);
    return -1;
  }
  const unsigned char *loc = reinterpret_cast<const unsigned char *>(session_data);
  SSL_SESSION *sess        = d2i_SSL_SESSION(nullptr, &loc, session_data_len);
  if (nullptr == sess) {
    TSError("Failed to transform session buffer %.*s", session_id_len, session_id);
  }
  TSSslSessionID sid;
  memcpy(reinterpret_cast<char *>(sid.bytes), session_id, session_id_len);
  sid.len = session_id_len;
  if (sid.len > sizeof(sid.bytes)) {
    sid.len = sizeof(sid.bytes);
  }
  TSSslSessionInsert(&sid, reinterpret_cast<TSSslSession>(sess));
  // Free the sesison object created by d2i_SSL_SESSION
  // We should make an API that just takes the ASN buffer
  SSL_SESSION_free(sess);
  return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
/*!
 * \file DTK_Benchmark_MonteCarloMesh.hpp
 * \brief MonteCarlo mesh interface for the hybrid transport benchmark.
 */
//---------------------------------------------------------------------------//

#ifndef DTK_MONTECARLOMESH_HPP
#define DTK_MONTECARLOMESH_HPP

#include "DTK_Benchmark_CartesianMesh.hpp"

#include <Teuchos_Comm.hpp>
#include <Teuchos_RCP.hpp>

#include <memory>
#include <vector>

namespace DataTransferKit
{
namespace Benchmark
{
//---------------------------------------------------------------------------//
/*!
 * \class MonteCarloMesh
 * \brief Mesh and partitioner for Monte Carlo transport simulations.
 *
 * Monte Carlo grids are typically subdivided into a small number of "blocks",
 * which can be interpreted as grid partitions, and "sets" which can be
 * interpreted as a number of replications of the grid.
 *
 * The block decomposition, or spatial partitioning of the mesh, is always
 * computed with user provided planes indicating the spatial boundaries of
 * each block. The underlying grid is then subdivided into blocks based on the
 * plane locations. If a plane intersects a cell, that cell is assigned to
 * both blocks adjacent to the plane.
 *
 * Note that the boundary mesh planes don't have to contain the grid - we will
 * just use them to carve out partitions from the background grid.
 *
 * The resulting partitioning is used to create the needed data in the base
 * class with mesh data being accessed through the base class
 * interface. Really think about this class as a decorator for the base class
 * which provides an initial partitioning.
 */
class MonteCarloMesh
{
  public:
    /*!
     * \brief Uniform cell size constructor.
     *
     * Builds a regular grid with a uniform cell size and partitions it using
     * the input boundary mesh arrays.
     *
     * \param comm The communicator over which the mesh will be partitioned.
     *
     * \param num_cells_i The global number of mesh cells in the X direction.
     *
     * \param num_cells_j The global number of mesh cells in the Y direction.
     *
     * \param num_cells_k The global number of mesh cells in the Z direction.
     *
     * \param delta_x The size of the mesh cells in the X direction.
     *
     * \param delta_y The size of the mesh cells in the Y direction.
     *
     * \param delta_z The size of the mesh cells in the Z direction.
     *
     * \param x_bnd_mesh The boundary mesh node locations in the x direction.
     *
     * \param y_bnd_mesh The boundary mesh node locations in the y direction.
     *
     * \param z_bnd_mesh The boundary mesh node locations in the z direction.
     */
    MonteCarloMesh( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets, const int num_cells_i,
                    const int num_cells_j, const int num_cells_k,
                    const double delta_x, const double delta_y,
                    const double delta_z, const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    /*!
     * \brief Global edge constructor. A global list of node locations will be
     * used to create the mesh. The mesh will be partitioned using the input
     * boundary mesh arrays.
     *
     * \param comm The parallel communicator over which the mesh is built.
     *
     * \param global_x_edges Global list of node locations in the X direction.
     *
     * \param global_y_edges Global list of node locations in the Y direction.
     *
     * \param global_z_edges Global list of node locations in the Z direction.
     *
     * \param x_bnd_mesh The boundary mesh node locations in the x direction.
     *
     * \param y_bnd_mesh The boundary mesh node locations in the y direction.
     *
     * \param z_bnd_mesh The boundary mesh node locations in the z direction.
     */
    MonteCarloMesh( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets,
                    const std::vector<double> &global_x_edges,
                    const std::vector<double> &global_y_edges,
                    const std::vector<double> &global_z_edges,
                    const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    /*!
     * \brief Get the local Cartesian mesh owned by this process.
     */
    std::shared_ptr<CartesianMesh> cartesianMesh() const
    {
        return _cartesian_mesh;
    }

  private:
    // Partition the mesh.
    void partition( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets,
                    const std::vector<double> &global_x_edges,
                    const std::vector<double> &global_y_edges,
                    const std::vector<double> &global_z_edges,
                    const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    // Calculate local edge arrays.
    void computeLocalEdges( const std::vector<double> &global_edges,
                            const std::vector<double> &bnd_mesh,
                            const int my_block,
                            std::vector<double> &local_edges,
                            int &offset ) const;

  private:
    // The Cartesian mesh owned by this process.
    std::shared_ptr<CartesianMesh> _cartesian_mesh;
};

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

} // end namespace Benchmark
} // end namespace DataTransferKit

#endif // end DTK_MONTECARLOMESH_HPP
<commit_msg>adding missing parameter to doxygen for MonteCarloMesh<commit_after>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
/*!
 * \file DTK_Benchmark_MonteCarloMesh.hpp
 * \brief MonteCarlo mesh interface for the hybrid transport benchmark.
 */
//---------------------------------------------------------------------------//

#ifndef DTK_MONTECARLOMESH_HPP
#define DTK_MONTECARLOMESH_HPP

#include "DTK_Benchmark_CartesianMesh.hpp"

#include <Teuchos_Comm.hpp>
#include <Teuchos_RCP.hpp>

#include <memory>
#include <vector>

namespace DataTransferKit
{
namespace Benchmark
{
//---------------------------------------------------------------------------//
/*!
 * \class MonteCarloMesh
 * \brief Mesh and partitioner for Monte Carlo transport simulations.
 *
 * Monte Carlo grids are typically subdivided into a small number of "blocks",
 * which can be interpreted as grid partitions, and "sets" which can be
 * interpreted as a number of replications of the grid.
 *
 * The block decomposition, or spatial partitioning of the mesh, is always
 * computed with user provided planes indicating the spatial boundaries of
 * each block. The underlying grid is then subdivided into blocks based on the
 * plane locations. If a plane intersects a cell, that cell is assigned to
 * both blocks adjacent to the plane.
 *
 * Note that the boundary mesh planes don't have to contain the grid - we will
 * just use them to carve out partitions from the background grid.
 *
 * The resulting partitioning is used to create the needed data in the base
 * class with mesh data being accessed through the base class
 * interface. Really think about this class as a decorator for the base class
 * which provides an initial partitioning.
 */
class MonteCarloMesh
{
  public:
    /*!
     * \brief Uniform cell size constructor.
     *
     * Builds a regular grid with a uniform cell size and partitions it using
     * the input boundary mesh arrays.
     *
     * \param comm The communicator over which the mesh will be partitioned.
     *
     * \param num_sets The number of sets over which to decompose the
     * mesh. This is the total number of times the mesh is replicated.
     *
     * \param num_cells_i The global number of mesh cells in the X direction.
     *
     * \param num_cells_j The global number of mesh cells in the Y direction.
     *
     * \param num_cells_k The global number of mesh cells in the Z direction.
     *
     * \param delta_x The size of the mesh cells in the X direction.
     *
     * \param delta_y The size of the mesh cells in the Y direction.
     *
     * \param delta_z The size of the mesh cells in the Z direction.
     *
     * \param x_bnd_mesh The boundary mesh node locations in the x direction.
     *
     * \param y_bnd_mesh The boundary mesh node locations in the y direction.
     *
     * \param z_bnd_mesh The boundary mesh node locations in the z direction.
     */
    MonteCarloMesh( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets, const int num_cells_i,
                    const int num_cells_j, const int num_cells_k,
                    const double delta_x, const double delta_y,
                    const double delta_z, const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    /*!
     * \brief Global edge constructor. A global list of node locations will be
     * used to create the mesh. The mesh will be partitioned using the input
     * boundary mesh arrays.
     *
     * \param comm The parallel communicator over which the mesh is built.
     *
     * \param num_sets The number of sets over which to decompose the
     * mesh. This is the total number of times the mesh is replicated.
     *
     * \param global_x_edges Global list of node locations in the X direction.
     *
     * \param global_y_edges Global list of node locations in the Y direction.
     *
     * \param global_z_edges Global list of node locations in the Z direction.
     *
     * \param x_bnd_mesh The boundary mesh node locations in the x direction.
     *
     * \param y_bnd_mesh The boundary mesh node locations in the y direction.
     *
     * \param z_bnd_mesh The boundary mesh node locations in the z direction.
     */
    MonteCarloMesh( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets,
                    const std::vector<double> &global_x_edges,
                    const std::vector<double> &global_y_edges,
                    const std::vector<double> &global_z_edges,
                    const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    /*!
     * \brief Get the local Cartesian mesh owned by this process.
     */
    std::shared_ptr<CartesianMesh> cartesianMesh() const
    {
        return _cartesian_mesh;
    }

  private:
    // Partition the mesh.
    void partition( const Teuchos::RCP<const Teuchos::Comm<int>> &comm,
                    const int num_sets,
                    const std::vector<double> &global_x_edges,
                    const std::vector<double> &global_y_edges,
                    const std::vector<double> &global_z_edges,
                    const std::vector<double> &x_bnd_mesh,
                    const std::vector<double> &y_bnd_mesh,
                    const std::vector<double> &z_bnd_mesh );

    // Calculate local edge arrays.
    void computeLocalEdges( const std::vector<double> &global_edges,
                            const std::vector<double> &bnd_mesh,
                            const int my_block,
                            std::vector<double> &local_edges,
                            int &offset ) const;

  private:
    // The Cartesian mesh owned by this process.
    std::shared_ptr<CartesianMesh> _cartesian_mesh;
};

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

} // end namespace Benchmark
} // end namespace DataTransferKit

#endif // end DTK_MONTECARLOMESH_HPP
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QObject>
#include <qmobilityglobal.h>
#include <qtorganizer.h>
#include <QtTest/QtTest>
#include <QDebug>

QTM_USE_NAMESPACE

const QString m_managerNameSymbian("symbian");

Q_DECLARE_METATYPE(QOrganizerItemRecurrenceRule)
Q_DECLARE_METATYPE(QOrganizerItemPriority)
Q_DECLARE_METATYPE(QOrganizerItemLocation)

class TestItemOccurrence : public QObject
{
    Q_OBJECT

private slots:
    void init();
    void cleanup();

private slots:
    void addOccurrenceDetail_data();
    void addOccurrenceDetail();
    void addOccurrenceWithException_data();
    void addOccurrenceWithException();
    void fetchNegative_data();
    void fetchNegative();
private:
    QStringList getAvailableManagers();
    void addOccurrenceData(QString managerName, QString itemType);

private:
    QOrganizerItemManager *m_om;

};

void TestItemOccurrence::init()
{
    QFETCH(QString, managerName);

    // Create a new item manager instance
    m_om = new QOrganizerItemManager(managerName);

    // Cleanup by deleting all items
    m_om->removeItems(m_om->itemIds(), 0);
}

void TestItemOccurrence::cleanup()
{
    if (m_om) {
        delete m_om;
        m_om = 0;
    }
}

QStringList TestItemOccurrence::getAvailableManagers()
{
    // Get the list of all available item managers
    QStringList availableManagers = QOrganizerItemManager::availableManagers();

    // Remove these since test would fail
    availableManagers.removeAll("invalid");
    availableManagers.removeAll("skeleton");
    availableManagers.removeAll("memory");

    return availableManagers;
}

void TestItemOccurrence::addOccurrenceDetail_data()
{
    QStringList availableManagers = getAvailableManagers();
    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");
    QTest::addColumn<QOrganizerItemRecurrenceRule>("rrule");

    foreach(QString manager, availableManagers) {
        addOccurrenceData(manager, QOrganizerItemType::TypeEvent);
    }
}

void TestItemOccurrence::addOccurrenceData(QString managerName, QString itemType)
{
    QOrganizerItemRecurrenceRule rrule;
    rrule.setFrequency(QOrganizerItemRecurrenceRule::Weekly);
    rrule.setCount(3);
    QList<Qt::DayOfWeek> daysOfWeek;
    daysOfWeek.append(Qt::Wednesday);
    rrule.setDaysOfWeek(daysOfWeek);
    QTest::newRow(QString("[%1] weekly on Wednesday for 3 weeks").arg(managerName).toLatin1().constData())
        << managerName
        << itemType
        <<  QDateTime(QDate(QDate::currentDate().year() , 9, 1))
        << rrule;

}

void TestItemOccurrence::addOccurrenceDetail()
{
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);
    QFETCH(QOrganizerItemRecurrenceRule, rrule);

    // Set the item type
    QOrganizerItem item;
    item.setType(itemType);
    QDateTime endTime(QDate(QDate::currentDate().year() , 9, 30));
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Add recurrence rules to the item
    QList<QOrganizerItemRecurrenceRule> rrules;
    rrules.append(rrule);
    QOrganizerItemRecurrence recurrence;
    recurrence.setRecurrenceRules(rrules);
    QVERIFY(item.saveDetail(&recurrence));

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));

    // Fetch the saved item
    item = m_om->item(item.localId());

    // Fetch the item again
    QList<QOrganizerItem> instanceList = m_om->itemInstances(item,startTime,endTime);

    QCOMPARE(instanceList.size(), 3);
    QOrganizerItem lastItem = instanceList.at(2);
    QCOMPARE(lastItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence thirdEvent = static_cast<QOrganizerEventOccurrence>(lastItem);
    QCOMPARE(thirdEvent.startDateTime(), QDateTime(QDate(QDate::currentDate().year() , 9, 15)));
    QCOMPARE(thirdEvent.localId(), (unsigned int)0);
    QCOMPARE(thirdEvent.parentLocalId(), item.localId());

    //Fetch instances using maxcount only.
    instanceList.clear();
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),2);
    QCOMPARE(instanceList.size(), 2);
    QOrganizerItem secondItem = instanceList.at(1);
    QCOMPARE(secondItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence secondEvent = static_cast<QOrganizerEventOccurrence>(secondItem);
    QCOMPARE(secondEvent.startDateTime(), QDateTime(QDate(QDate::currentDate().year() , 9, 8)));
    QCOMPARE(secondEvent.localId(), (unsigned int)0);
    QCOMPARE(secondEvent.parentLocalId(), item.localId());

}

void TestItemOccurrence::addOccurrenceWithException_data()
{
    // Get the list of all available item managers
    QStringList availableManagers = getAvailableManagers();

    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");
    QTest::addColumn<QDate>("exceptionDate");
    QTest::addColumn<QOrganizerItemRecurrenceRule>("rrule");
    QTest::addColumn<QOrganizerItemPriority>("priority");
    QTest::addColumn<QOrganizerItemLocation>("location");

    QString itemType  = QOrganizerItemType::TypeEvent;
    QOrganizerItemPriority priority;
    priority.setPriority(QOrganizerItemPriority::HighestPriority);
    QOrganizerItemLocation location;
    location.setLocationName("checkLocationName");
    location.setGeoLocation("20.176876;15.988765");
    foreach(QString manager, availableManagers) {
        QOrganizerItemRecurrenceRule rrule;
        rrule.setFrequency(QOrganizerItemRecurrenceRule::Daily);
        rrule.setCount(10);
        QTest::newRow(QString("[%1] Daily event for 10 occurrences").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime(QDate(QDate::currentDate().year() , 9, 1))
            << QDate(QDate::currentDate().year() , 9, 3)
            << rrule
            << priority
            << location;
    }
}

void TestItemOccurrence::addOccurrenceWithException()
{
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);
    QFETCH(QDate,exceptionDate );
    QFETCH(QOrganizerItemRecurrenceRule, rrule);
    QFETCH(QOrganizerItemPriority, priority);
    QFETCH(QOrganizerItemLocation, location);

    // Set the item type
    QOrganizerItem item;
    item.setType(itemType);
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Add recurrence rules to the item
    QList<QOrganizerItemRecurrenceRule> rrules;
    QList<QDate> exceptionList;
    rrules.append(rrule);
    exceptionList.append(exceptionDate);
    QOrganizerItemRecurrence recurrence;
    recurrence.setRecurrenceRules(rrules);
    recurrence.setExceptionDates(exceptionList);
    QVERIFY(item.saveDetail(&recurrence));

    //Add other attributes to the item.
    item.setDescription("checkoccurrence");
    item.saveDetail(&priority);
    item.saveDetail(&location);

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));
    item = m_om->item(item.localId());

    //Fetch instance on the exception date.An empty list should be returned
    QList<QOrganizerItem> instanceList = m_om->itemInstances(item,QDateTime(exceptionDate),QDateTime(exceptionDate));
    QCOMPARE(instanceList.size(),0);

    // Fetch the item again
    instanceList.clear();
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),rrule.count());
    QCOMPARE(instanceList.size(),rrule.count() -1);

    QOrganizerItem lastItem = instanceList.at(rrule.count()-2);
    QCOMPARE(lastItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence lastEvent = static_cast<QOrganizerEventOccurrence>(lastItem);

    QCOMPARE(lastEvent.description(),item.description());
    QOrganizerItemPriority itemPriority = item.detail(QOrganizerItemPriority::DefinitionName);
    QCOMPARE(lastEvent.priority(),priority.priority());
    QOrganizerItemLocation itemLocation = item.detail(QOrganizerItemLocation::DefinitionName);
    QCOMPARE(lastEvent.locationName(),itemLocation.locationName());
    QCOMPARE(lastEvent.locationGeoCoordinates(),itemLocation.geoLocation());
}

void TestItemOccurrence::fetchNegative_data()
{
    // Get the list of all available item managers
    QStringList availableManagers = getAvailableManagers();

    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");

    QString itemType = QOrganizerItemType::TypeEvent;
    foreach(QString manager, availableManagers) {
       QTest::newRow(QString("[%1] non repeating entry").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime::currentDateTime().addSecs(3600);
    }
}
void TestItemOccurrence::fetchNegative()
{
    //Fetch instances for a non recurring entry
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);

    // Set the item type
    QOrganizerItem item;
    QList<QOrganizerItem> instanceList;
    item.setType(itemType);
    QDateTime endTime(startTime);
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));

    // Fetch the saved item
    item = m_om->item(item.localId());

    // Fetch the item instances for a non repeating entry
    instanceList = m_om->itemInstances(item,startTime,endTime);

    //Only a single instance should be returned for non-repeating entry
    QCOMPARE(instanceList.size(), 1);

    //Fetch instance when end period is less than start period
    QDateTime previousEndTime(startTime);
    previousEndTime.setDate(QDate(startTime.date().year() - 2, startTime.date().month(),startTime.date().day()));
    instanceList = m_om->itemInstances(item,startTime,previousEndTime);
    QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

    //Fetch iteminstance for invalid itemtype eventoccurrence
    QOrganizerEventOccurrence invalidItem;
    instanceList = m_om->itemInstances(invalidItem,startTime,endTime);
    QCOMPARE(m_om->error(), QOrganizerItemManager::InvalidItemTypeError);

    // Fetch the item instance with invalid count
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),-2);
    QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

   // Fetch the item instance with invalid starttime
   instanceList = m_om->itemInstances(item,QDateTime(),endTime);
   QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

   // Fetch the item instance with invalid endtime
   instanceList = m_om->itemInstances(item,startTime,QDateTime());
   QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);
}
QTEST_MAIN(TestItemOccurrence);

#include "tst_itemoccurrence.moc"
<commit_msg>additional test cases for finditeminstances<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QObject>
#include <qmobilityglobal.h>
#include <qtorganizer.h>
#include <QtTest/QtTest>
#include <QDebug>

QTM_USE_NAMESPACE

const QString m_managerNameSymbian("symbian");

Q_DECLARE_METATYPE(QOrganizerItemRecurrenceRule)
Q_DECLARE_METATYPE(QOrganizerItemPriority)
Q_DECLARE_METATYPE(QOrganizerItemLocation)

class TestItemOccurrence : public QObject
{
    Q_OBJECT

private slots:
    void init();
    void cleanup();

private slots:
    void addOccurrenceDetail_data();
    void addOccurrenceDetail();
    void addOccurrenceWithException_data();
    void addOccurrenceWithException();
    void fetchNegative_data();
    void fetchNegative();
private:
    QStringList getAvailableManagers();
    void addOccurrenceData(QString managerName, QString itemType);

private:
    QOrganizerItemManager *m_om;

};

void TestItemOccurrence::init()
{
    QFETCH(QString, managerName);

    // Create a new item manager instance
    m_om = new QOrganizerItemManager(managerName);

    // Cleanup by deleting all items
    m_om->removeItems(m_om->itemIds(), 0);
}

void TestItemOccurrence::cleanup()
{
    if (m_om) {
        delete m_om;
        m_om = 0;
    }
}

QStringList TestItemOccurrence::getAvailableManagers()
{
    // Get the list of all available item managers
    QStringList availableManagers = QOrganizerItemManager::availableManagers();

    // Remove these since test would fail
    availableManagers.removeAll("invalid");
    availableManagers.removeAll("skeleton");
    availableManagers.removeAll("memory");

    return availableManagers;
}

void TestItemOccurrence::addOccurrenceDetail_data()
{
    QStringList availableManagers = getAvailableManagers();
    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");
    QTest::addColumn<QOrganizerItemRecurrenceRule>("rrule");

    foreach(QString manager, availableManagers) {
        addOccurrenceData(manager, QOrganizerItemType::TypeEvent);
    }
}

void TestItemOccurrence::addOccurrenceData(QString managerName, QString itemType)
{
    QOrganizerItemRecurrenceRule rrule;
    rrule.setFrequency(QOrganizerItemRecurrenceRule::Weekly);
    rrule.setCount(3);
    QList<Qt::DayOfWeek> daysOfWeek;
    daysOfWeek.append(Qt::Wednesday);
    rrule.setDaysOfWeek(daysOfWeek);
    QTest::newRow(QString("[%1] weekly on Wednesday for 3 weeks").arg(managerName).toLatin1().constData())
        << managerName
        << itemType
        <<  QDateTime(QDate(QDate::currentDate().year() , 9, 1))
        << rrule;
}

void TestItemOccurrence::addOccurrenceDetail()
{
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);
    QFETCH(QOrganizerItemRecurrenceRule, rrule);

    // Set the item type
    QOrganizerItem item;
    item.setType(itemType);
    QDateTime endTime(QDate(QDate::currentDate().year() , 9, 30));
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Add recurrence rules to the item
    QList<QOrganizerItemRecurrenceRule> rrules;
    rrules.append(rrule);
    QOrganizerItemRecurrence recurrence;
    recurrence.setRecurrenceRules(rrules);
    QVERIFY(item.saveDetail(&recurrence));

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));

    // Fetch the saved item
    item = m_om->item(item.localId());

    // Fetch the item again
    QList<QOrganizerItem> instanceList = m_om->itemInstances(item,startTime,endTime);

    QCOMPARE(instanceList.size(), 3);
    QOrganizerItem lastItem = instanceList.at(2);
    QCOMPARE(lastItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence thirdEvent = static_cast<QOrganizerEventOccurrence>(lastItem);
    QCOMPARE(thirdEvent.startDateTime(), QDateTime(QDate(QDate::currentDate().year() , 9, 15)));
    QCOMPARE(thirdEvent.localId(), (unsigned int)0);
    QCOMPARE(thirdEvent.parentLocalId(), item.localId());

    //Fetch instances using maxcount only.
    instanceList.clear();
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),2);
    QCOMPARE(instanceList.size(), 2);
    QOrganizerItem secondItem = instanceList.at(1);
    QCOMPARE(secondItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence secondEvent = static_cast<QOrganizerEventOccurrence>(secondItem);
    QCOMPARE(secondEvent.startDateTime(), QDateTime(QDate(QDate::currentDate().year() , 9, 8)));
    QCOMPARE(secondEvent.localId(), (unsigned int)0);
    QCOMPARE(secondEvent.parentLocalId(), item.localId());
}

void TestItemOccurrence::addOccurrenceWithException_data()
{
    // Get the list of all available item managers
    QStringList availableManagers = getAvailableManagers();

    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");
    QTest::addColumn<QDate>("rDate");
    QTest::addColumn<QDate>("exceptionDate");
    QTest::addColumn<QOrganizerItemRecurrenceRule>("rrule");
    QTest::addColumn<QOrganizerItemPriority>("priority");
    QTest::addColumn<QOrganizerItemLocation>("location");

    QString itemType  = QOrganizerItemType::TypeEvent;
    QOrganizerItemPriority priority;
    priority.setPriority(QOrganizerItemPriority::HighestPriority);
    QOrganizerItemLocation location;
    location.setLocationName("checkLocationName");
    location.setGeoLocation("20.176876;15.988765");
    foreach(QString manager, availableManagers) {
        QOrganizerItemRecurrenceRule rrule;
        rrule.setFrequency(QOrganizerItemRecurrenceRule::Daily);
        rrule.setCount(10);
        QDate rDate(QDate::currentDate().year() , 9, 11);
        QDate exceptionDate(QDate::currentDate().year() , 9, 3);
        QTest::newRow(QString("[%1] Daily event for 10 occurrences").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime(QDate(QDate::currentDate().year() , 9, 1))
            << rDate
            << exceptionDate
            << rrule
            << priority
            << location;

        QOrganizerItemRecurrenceRule monthRule;
        monthRule.setFrequency(QOrganizerItemRecurrenceRule::Monthly);
        monthRule.setCount(5);

        QTest::newRow(QString("[%1] Monthly event for 5 occurrences").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime(QDate(QDate::currentDate().year() , 8, 3))
            << rDate
            << exceptionDate
            << monthRule
            << priority
            << location;

        QOrganizerItemRecurrenceRule yearRule;
        yearRule.setFrequency(QOrganizerItemRecurrenceRule::Yearly);
        QList<QOrganizerItemRecurrenceRule::Month> months;
        months.append(QOrganizerItemRecurrenceRule::September);
        yearRule.setCount(3);
        yearRule.setInterval(2);
        yearRule.setMonths(months);
        QDate yearException(QDate(QDate::currentDate().year() , 9, 1));
        QTest::newRow(QString("[%1] yearly rule every other year").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime(QDate(QDate::currentDate().year() + 2, 9, 1))
            << rDate
            << yearException
            << yearRule
            << priority
            << location;
    }
}

void TestItemOccurrence::addOccurrenceWithException()
{
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);
    QFETCH(QDate, rDate);
    QFETCH(QDate,exceptionDate );
    QFETCH(QOrganizerItemRecurrenceRule, rrule);
    QFETCH(QOrganizerItemPriority, priority);
    QFETCH(QOrganizerItemLocation, location);

    // Set the item type
    QOrganizerItem item;
    item.setType(itemType);
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Add recurrence rules to the item
    QList<QOrganizerItemRecurrenceRule> rrules;
    QList<QDate> exceptionList;
    QList<QDate> rDateList;
    rrules.append(rrule);
    rDateList.append(rDate);
    exceptionList.append(exceptionDate);
    QOrganizerItemRecurrence recurrence;
    recurrence.setRecurrenceRules(rrules);
    recurrence.setExceptionDates(exceptionList);
    recurrence.setRecurrenceDates(rDateList);
    QVERIFY(item.saveDetail(&recurrence));

    //Add other attributes to the item.
    item.setDescription("checkoccurrence");
    item.saveDetail(&priority);
    item.saveDetail(&location);

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));
    item = m_om->item(item.localId());

    //Fetch instance on the exception date.An empty list should be returned
    QList<QOrganizerItem> instanceList = m_om->itemInstances(item,QDateTime(exceptionDate),QDateTime(exceptionDate));
    QCOMPARE(instanceList.size(),0);

    //Fetch the instance on rdate should return one instance
    instanceList.clear();
    instanceList = m_om->itemInstances(item,QDateTime(rDate),QDateTime(rDate));
    QCOMPARE(instanceList.size(),1);
    QOrganizerItem rDateItem = instanceList.at(0);
    QCOMPARE(rDateItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence event = static_cast<QOrganizerEventOccurrence>(rDateItem);
    QCOMPARE(event.startDateTime(), QDateTime(QDate(QDate::currentDate().year() , 9, 11)));

    // Fetch the item again
    instanceList.clear();
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),20);
    QCOMPARE(instanceList.size(),rrule.count());

    QOrganizerItem lastItem = instanceList.at(rrule.count()-1);
    QCOMPARE(lastItem.type(), QLatin1String(QOrganizerItemType::TypeEventOccurrence));
    QOrganizerEventOccurrence lastEvent = static_cast<QOrganizerEventOccurrence>(lastItem);

    QCOMPARE(lastEvent.description(),item.description());
    QOrganizerItemPriority itemPriority = item.detail(QOrganizerItemPriority::DefinitionName);
    QCOMPARE(lastEvent.priority(),priority.priority());
    QOrganizerItemLocation itemLocation = item.detail(QOrganizerItemLocation::DefinitionName);
    QCOMPARE(lastEvent.locationName(),itemLocation.locationName());
    QCOMPARE(lastEvent.locationGeoCoordinates(),itemLocation.geoLocation());

    //Fetch instance on 1\9\2011.Since interval is 2 the insatnceList size should be 0.
    instanceList.clear();
    QDateTime intervalDate(QDate(QDate::currentDate().year()+ 1 , 9, 1));
    instanceList = m_om->itemInstances(item,intervalDate,intervalDate);
    QCOMPARE(instanceList.size(),0);
}

void TestItemOccurrence::fetchNegative_data()
{
    // Get the list of all available item managers
    QStringList availableManagers = getAvailableManagers();

    QTest::addColumn<QString>("managerName");
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QDateTime>("startTime");

    QString itemType = QOrganizerItemType::TypeEvent;
    foreach(QString manager, availableManagers) {
       QTest::newRow(QString("[%1] non repeating entry").arg(manager).toLatin1().constData())
            << manager
            << itemType
            << QDateTime::currentDateTime().addSecs(3600);
    }
}
void TestItemOccurrence::fetchNegative()
{
    //Fetch instances for a non recurring entry
    QFETCH(QString, managerName);
    QFETCH(QString, itemType);
    QFETCH(QDateTime, startTime);

    // Set the item type
    QOrganizerItem item;
    QList<QOrganizerItem> instanceList;
    item.setType(itemType);
    QDateTime endTime(startTime);
    QOrganizerEventTimeRange timeRange;
    timeRange.setStartDateTime(startTime);
    QVERIFY(item.saveDetail(&timeRange));

    // Save item with recurrence rule.
    QVERIFY(m_om->saveItem(&item));

    // Fetch the saved item
    item = m_om->item(item.localId());

    // Fetch the item instances for a non repeating entry
    instanceList = m_om->itemInstances(item,startTime,endTime);

    //Only a single instance should be returned for non-repeating entry
    QCOMPARE(instanceList.size(), 1);

    //Fetch instance when end period is less than start period
    QDateTime previousEndTime(startTime);
    previousEndTime.setDate(QDate(startTime.date().year() - 2, startTime.date().month(),startTime.date().day()));
    instanceList = m_om->itemInstances(item,startTime,previousEndTime);
    QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

    //Fetch iteminstance for invalid itemtype eventoccurrence
    QOrganizerEventOccurrence invalidItem;
    instanceList = m_om->itemInstances(invalidItem,startTime,endTime);
    QCOMPARE(m_om->error(), QOrganizerItemManager::InvalidItemTypeError);

    // Fetch the item instance with invalid count
    instanceList = m_om->itemInstances(item,startTime,QDateTime(),-2);
    QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

   // Fetch the item instance with invalid starttime
   instanceList = m_om->itemInstances(item,QDateTime(),endTime);
   QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);

   // Fetch the item instance with invalid endtime
   instanceList = m_om->itemInstances(item,startTime,QDateTime());
   QCOMPARE(m_om->error(), QOrganizerItemManager::BadArgumentError);
}
QTEST_MAIN(TestItemOccurrence);

#include "tst_itemoccurrence.moc"
<|endoftext|>


<commit_before>#include "HaxeRuntime.h"
#include "HaxeInit.h"
#include "Engine.h"
#include <cstdio>

#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE
	#include <windows.h>
#elif PLATFORM_MAC || PLATFORM_IOS || PLATFORM_LINUX || PLATFORM_ANDROID
	#include <pthread.h>
#else
#endif

extern "C" void  gc_set_top_of_stack(int *inTopOfStack,bool inForce);
extern "C" const char *hxRunLibrary();
// void __scriptable_load_cppia(String inCode);

#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE
  #define DECLARE_FAST_TLS(name) static __declspec( thread ) void *name
  #define GET_TLS_VALUE(name) name
  #define SET_TLS_VALUE(name, value) name = value
#elif PLATFORM_LINUX || PLATFORM_ANDROID
  #define DECLARE_FAST_TLS(name) static thread_local void *name
  #define GET_TLS_VALUE(name) name
  #define SET_TLS_VALUE(name, value) name = value
#else
  #define DECLARE_FAST_TLS(name) static uint32 name = FPlatformTLS::AllocTlsSlot()
  #define GET_TLS_VALUE(name) FPlatformTLS::GetTlsValue(name)
  #define SET_TLS_VALUE(name, value) FPlatformTLS::SetTlsValue(name, value)
#endif

static void *get_top_of_stack(void)
{
#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE //TODO: see if XBOXONE really behaves like Windows
  MEMORY_BASIC_INFORMATION info;
  VirtualQuery(&info, &info, sizeof(MEMORY_BASIC_INFORMATION));
  return (void *) (( (char *) info.BaseAddress) + info.RegionSize);
#elif PLATFORM_MAC || PLATFORM_IOS
  return pthread_get_stackaddr_np(pthread_self());
#elif PLATFORM_LINUX || PLATFORM_ANDROID
  pthread_t self = pthread_self();
  pthread_attr_t attr;
  void* addr;
  size_t size;

  pthread_getattr_np(self, &attr);
  pthread_attr_getstack(&attr, &addr, &size);
  pthread_attr_destroy(&attr);

  return (void *) (((intptr_t)addr) + size);
#else //PLATFORM_PS4, PLATFORM_HTML5
  return NULL;
#endif
}

static volatile int32 gDidInit = 0;
DECLARE_FAST_TLS(tlsDidInit);

void check_hx_init()
{
  bool firstInit = true;
  if (gDidInit || FPlatformAtomics::InterlockedCompareExchange(&gDidInit, 1, 0) != 0) {
    // check if the thread was registered
    if (!GET_TLS_VALUE(tlsDidInit)) {
      SET_TLS_VALUE(tlsDidInit, (void *) (intptr_t) 1);
    } else {
      return;
    }
    while (gDidInit == 1) {
      // spin while waiting for the initialization to finish
      FPlatformProcess::Sleep(0.01f);
    }

    firstInit = false;
  } else {
    // main thread needs TLS too
    SET_TLS_VALUE(tlsDidInit, (void *) (intptr_t) 1);
  }

  // This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
  int x;
  void *top_of_stack = get_top_of_stack();
  if (NULL == top_of_stack)
  {
    // UE_LOG(HXR, Error, TEXT("Currently unsupported Haxe runtime platform. Trying to get approximate stack size"));
    top_of_stack = &x;
  }

#ifdef WITH_HAXE
  gc_set_top_of_stack((int *)top_of_stack, false);
  if (firstInit) {
    const char *error = hxRunLibrary();
    if (error) { fprintf(stderr, "Error on Haxe main function: %s", error); }
  }
#endif
  gDidInit = 2;
}
<commit_msg>Fail if an error was thrown on initialization<commit_after>#include "HaxeRuntime.h"
#include "HaxeInit.h"
#include "Engine.h"
#include <cstdio>

#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE
	#include <windows.h>
#elif PLATFORM_MAC || PLATFORM_IOS || PLATFORM_LINUX || PLATFORM_ANDROID
	#include <pthread.h>
#else
#endif

// DECLARE_LOG_CATEGORY_EXTERN(HaxeInitLog, Log, All);
// DEFINE_LOG_CATEGORY(HaxeInitLog);
DECLARE_LOG_CATEGORY_EXTERN(HaxeLog, Log, All);

extern "C" void  gc_set_top_of_stack(int *inTopOfStack,bool inForce);
extern "C" const char *hxRunLibrary();
// void __scriptable_load_cppia(String inCode);

#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE
  #define DECLARE_FAST_TLS(name) static __declspec( thread ) void *name
  #define GET_TLS_VALUE(name) name
  #define SET_TLS_VALUE(name, value) name = value
#elif PLATFORM_LINUX || PLATFORM_ANDROID
  #define DECLARE_FAST_TLS(name) static thread_local void *name
  #define GET_TLS_VALUE(name) name
  #define SET_TLS_VALUE(name, value) name = value
#else
  #define DECLARE_FAST_TLS(name) static uint32 name = FPlatformTLS::AllocTlsSlot()
  #define GET_TLS_VALUE(name) FPlatformTLS::GetTlsValue(name)
  #define SET_TLS_VALUE(name, value) FPlatformTLS::SetTlsValue(name, value)
#endif

static void *get_top_of_stack(void)
{
#if PLATFORM_WINDOWS || PLATFORM_WINRT || PLATFORM_XBOXONE //TODO: see if XBOXONE really behaves like Windows
  MEMORY_BASIC_INFORMATION info;
  VirtualQuery(&info, &info, sizeof(MEMORY_BASIC_INFORMATION));
  return (void *) (( (char *) info.BaseAddress) + info.RegionSize);
#elif PLATFORM_MAC || PLATFORM_IOS
  return pthread_get_stackaddr_np(pthread_self());
#elif PLATFORM_LINUX || PLATFORM_ANDROID
  pthread_t self = pthread_self();
  pthread_attr_t attr;
  void* addr;
  size_t size;

  pthread_getattr_np(self, &attr);
  pthread_attr_getstack(&attr, &addr, &size);
  pthread_attr_destroy(&attr);

  return (void *) (((intptr_t)addr) + size);
#else //PLATFORM_PS4, PLATFORM_HTML5
  return NULL;
#endif
}

static volatile int32 gDidInit = 0;
DECLARE_FAST_TLS(tlsDidInit);

void check_hx_init()
{
  bool firstInit = true;
  if (gDidInit || FPlatformAtomics::InterlockedCompareExchange(&gDidInit, 1, 0) != 0) {
    // check if the thread was registered
    if (!GET_TLS_VALUE(tlsDidInit)) {
      SET_TLS_VALUE(tlsDidInit, (void *) (intptr_t) 1);
    } else {
      return;
    }
    while (gDidInit == 1) {
      // spin while waiting for the initialization to finish
      FPlatformProcess::Sleep(0.01f);
    }

    firstInit = false;
  } else {
    // main thread needs TLS too
    SET_TLS_VALUE(tlsDidInit, (void *) (intptr_t) 1);
  }

  // This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
  int x;
  void *top_of_stack = get_top_of_stack();
  if (NULL == top_of_stack)
  {
    // UE_LOG(HXR, Error, TEXT("Currently unsupported Haxe runtime platform. Trying to get approximate stack size"));
    top_of_stack = &x;
  }

#ifdef WITH_HAXE
  gc_set_top_of_stack((int *)top_of_stack, false);
  if (firstInit) {
    const char *error = hxRunLibrary();
    if (error) { UE_LOG(HaxeLog, Fatal, TEXT("Error on Haxe main function: %s"), UTF8_TO_TCHAR(error)); }
  }
#endif
  gDidInit = 2;
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//      https://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 "iree/compiler/IR/Dialect.h"
#include "iree/compiler/IR/Interpreter/HLDialect.h"
#include "iree/compiler/IR/Interpreter/HLOps.h"
#include "iree/compiler/IR/Interpreter/LLDialect.h"
#include "iree/compiler/IR/Interpreter/LLOps.h"
#include "iree/compiler/IR/Ops.h"
#include "iree/compiler/Serialization/BytecodeTables.h"
#include "iree/schemas/bytecode/interpreter_bytecode_v0.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "mlir/Dialect/StandardOps/Ops.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/Utils.h"

namespace mlir {
namespace iree_compiler {

namespace {

struct LowerBranchOpPattern
    : public OpRewritePattern<IREEInterp::HL::BranchOp> {
  using OpRewritePattern<IREEInterp::HL::BranchOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(IREEInterp::HL::BranchOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> operands{op.getOperation()->getOperands()};

    rewriter.replaceOpWithNewOp<IREEInterp::LL::BranchOp>(op, op.getDest(),
                                                          operands);
    return matchSuccess();
  }
};

struct LowerCondCondBranchOpPattern
    : public OpRewritePattern<IREEInterp::HL::CondBranchOp> {
  using OpRewritePattern<IREEInterp::HL::CondBranchOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(IREEInterp::HL::CondBranchOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> trueOperands{op.getTrueOperands()};
    SmallVector<Value *, 8> falseOperands{op.getFalseOperands()};

    rewriter.replaceOpWithNewOp<IREEInterp::LL::CondBranchOp>(
        op, op.getCondition(), op.getTrueDest(), trueOperands,
        op.getFalseDest(), falseOperands);
    return matchSuccess();
  }
};

// Returns true if the op defined by |opName| (like 'iree_ll_interp.reshape')
// uses output operands for results (like iree_ll_interp.add_i) or returns real
// results.
bool opTakesOutputOperands(llvm::StringRef opName) {
  if (!opName.consume_front("iree_ll_interp.")) {
    assert(false && "op not part of IREE LL Interpreter dialect");
    return false;
  }
  auto opcode = GetInterpreterOpcodeByName(opName.str());
  assert(opcode.hasValue() && "op has no corresponding opcode");
  const auto &info = GetInterpreterOpcodeInfo(opcode.getValue());
  for (auto &operand : info.operands) {
    if (operand == iree::OperandEncoding::kOutputSlot ||
        operand == iree::OperandEncoding::kVariadicOutputSlots) {
      return true;
    }
  }
  return false;
}

template <typename SrcOp, typename DstOp>
class SimpleOpLowering : public OpRewritePattern<SrcOp> {
  using OpRewritePattern<SrcOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(SrcOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> operands{op.getOperation()->getOperands()};

    // Most ops take results as output operands to populate during execution.
    // Certain ops, like reshape, return references to existing memrefs and
    // should still retain their results.
    if (!opTakesOutputOperands(DstOp::getOperationName())) {
      SmallVector<Type, 8> resultTypes{op.getOperation()->getResultTypes()};

      rewriter.replaceOpWithNewOp<DstOp>(op, resultTypes, operands,
                                         op.getAttrs());
      return this->matchSuccess();
    }

    for (Value *result : op.getOperation()->getResults()) {
      auto memRefType = result->getType().cast<MemRefType>();
      if (!memRefType.hasStaticShape()) {
        // TODO(benvanik): real thing here - dynamic shaping required.
        // This should emit a shape calculation based on the operation. Most
        // are likely simple and by running DCE after this we can clean up
        // parts that are static or unused.
        op.emitOpError() << "uses unsupported dynamic shapes";
        return this->matchFailure();
      }
      ArrayRef<Value *> dim_pieces;
      auto allocOp = rewriter.create<IREEInterp::LL::AllocHeapOp>(
          op.getLoc(), memRefType, dim_pieces);
      operands.push_back(allocOp);
      result->replaceAllUsesWith(allocOp);
    }
    ArrayRef<Type> resultTypes;
    rewriter.create<DstOp>(op.getLoc(), resultTypes, operands, op.getAttrs());
    op.erase();
    return this->matchSuccess();
  }
};

}  // namespace

void populateInterpreterLoweringPatterns(OwningRewritePatternList &patterns,
                                         MLIRContext *ctx) {
  patterns.insert<LowerBranchOpPattern, LowerCondCondBranchOpPattern>(ctx);
  patterns.insert<
      SimpleOpLowering<IREE::ConstantOp, IREEInterp::LL::ConstantOp>,
      SimpleOpLowering<IREEInterp::HL::CopyOp, IREEInterp::LL::DynamicCopyOp>,
      SimpleOpLowering<IREEInterp::HL::SliceOp,
                       IREEInterp::LL::DynamicSliceOp>>(ctx);
#define SAME_NAME_SIMPLE_PATTERN(op_name) \
  SimpleOpLowering<IREEInterp::HL::op_name, IREEInterp::LL::op_name>
  // clang-format off
  patterns.insert<
      SAME_NAME_SIMPLE_PATTERN(AssignOp),
      SAME_NAME_SIMPLE_PATTERN(AbsFOp),
      SAME_NAME_SIMPLE_PATTERN(AbsIOp),
      SAME_NAME_SIMPLE_PATTERN(AddFOp),
      SAME_NAME_SIMPLE_PATTERN(AddIOp),
      SAME_NAME_SIMPLE_PATTERN(AllocHeapOp),
      SAME_NAME_SIMPLE_PATTERN(AndOp),
      SAME_NAME_SIMPLE_PATTERN(Atan2FOp),
      SAME_NAME_SIMPLE_PATTERN(BreakOp),
      SAME_NAME_SIMPLE_PATTERN(BroadcastOp),
      SAME_NAME_SIMPLE_PATTERN(CallOp),
      SAME_NAME_SIMPLE_PATTERN(CallIndirectOp),
      SAME_NAME_SIMPLE_PATTERN(CeilFOp),
      SAME_NAME_SIMPLE_PATTERN(ClampFOp),
      SAME_NAME_SIMPLE_PATTERN(CloneOp),
      SAME_NAME_SIMPLE_PATTERN(CmpFOp),
      SAME_NAME_SIMPLE_PATTERN(CmpIOp),
      SAME_NAME_SIMPLE_PATTERN(CondAssignOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertSSOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertUUOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertSUOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertUSOp),
      SAME_NAME_SIMPLE_PATTERN(CondBreakOp),
      SAME_NAME_SIMPLE_PATTERN(CosFOp),
      SAME_NAME_SIMPLE_PATTERN(DimOp),
      SAME_NAME_SIMPLE_PATTERN(DivFOp),
      SAME_NAME_SIMPLE_PATTERN(DivISOp),
      SAME_NAME_SIMPLE_PATTERN(DivIUOp),
      SAME_NAME_SIMPLE_PATTERN(ExpFOp),
      SAME_NAME_SIMPLE_PATTERN(LogFOp),
      SAME_NAME_SIMPLE_PATTERN(RsqrtFOp),
      SAME_NAME_SIMPLE_PATTERN(FloorFOp),
      SAME_NAME_SIMPLE_PATTERN(LengthOp),
      SAME_NAME_SIMPLE_PATTERN(MatMulFOp),
      SAME_NAME_SIMPLE_PATTERN(MatMulIOp),
      SAME_NAME_SIMPLE_PATTERN(MaxFOp),
      SAME_NAME_SIMPLE_PATTERN(MaxISOp),
      SAME_NAME_SIMPLE_PATTERN(MaxIUOp),
      SAME_NAME_SIMPLE_PATTERN(MinFOp),
      SAME_NAME_SIMPLE_PATTERN(MinISOp),
      SAME_NAME_SIMPLE_PATTERN(MinIUOp),
      SAME_NAME_SIMPLE_PATTERN(MulAddFOp),
      SAME_NAME_SIMPLE_PATTERN(MulAddIOp),
      SAME_NAME_SIMPLE_PATTERN(MulFOp),
      SAME_NAME_SIMPLE_PATTERN(MulIOp),
      SAME_NAME_SIMPLE_PATTERN(NotOp),
      SAME_NAME_SIMPLE_PATTERN(OrOp),
      SAME_NAME_SIMPLE_PATTERN(PadOp),
      SAME_NAME_SIMPLE_PATTERN(RankOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceSumIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceSumFOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMinIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMinFOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMaxIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMaxFOp),
      SAME_NAME_SIMPLE_PATTERN(ReshapeOp),
      SAME_NAME_SIMPLE_PATTERN(ReturnOp),
      SAME_NAME_SIMPLE_PATTERN(SelectOp),
      SAME_NAME_SIMPLE_PATTERN(ShapeOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftLeftOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftRightArithmeticOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftRightLogicalOp),
      SAME_NAME_SIMPLE_PATTERN(SinFOp),
      SAME_NAME_SIMPLE_PATTERN(SplitOp),
      SAME_NAME_SIMPLE_PATTERN(SubFOp),
      SAME_NAME_SIMPLE_PATTERN(SubIOp),
      SAME_NAME_SIMPLE_PATTERN(TanhFOp),
      SAME_NAME_SIMPLE_PATTERN(TileOp),
      SAME_NAME_SIMPLE_PATTERN(TraceOp),
      SAME_NAME_SIMPLE_PATTERN(TransposeOp),
      SAME_NAME_SIMPLE_PATTERN(ReverseOp),
      SAME_NAME_SIMPLE_PATTERN(XorOp)>(ctx);
  // clang-format on
#undef SAME_NAME_SIMPLE_PATTERN
}

namespace {
class LowerInterpreterDialectPass
    : public FunctionPass<LowerInterpreterDialectPass> {
 public:
  void runOnFunction() override {
    OwningRewritePatternList patterns;
    populateInterpreterLoweringPatterns(patterns, &getContext());

    ConversionTarget target(getContext());
    target.addLegalDialect<IREELLInterpreterDialect>();
    target.addLegalOp<FuncOp, IREE::ReturnOp>();
    if (failed(applyFullConversion(getFunction(), target, patterns))) {
      return signalPassFailure();
    }
  }
};
}  // namespace

std::unique_ptr<OpPassBase<FuncOp>> createLowerInterpreterDialectPass() {
  return std::make_unique<LowerInterpreterDialectPass>();
}

static PassRegistration<LowerInterpreterDialectPass> pass(
    "lower-iree-interpreter-hl-to-ll", "Lowers IREE HL ops to IREE LL ops");

}  // namespace iree_compiler
}  // namespace mlir
<commit_msg>Replace inline replacement with use of 'replaceOp'.<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//      https://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 "iree/compiler/IR/Dialect.h"
#include "iree/compiler/IR/Interpreter/HLDialect.h"
#include "iree/compiler/IR/Interpreter/HLOps.h"
#include "iree/compiler/IR/Interpreter/LLDialect.h"
#include "iree/compiler/IR/Interpreter/LLOps.h"
#include "iree/compiler/IR/Ops.h"
#include "iree/compiler/Serialization/BytecodeTables.h"
#include "iree/schemas/bytecode/interpreter_bytecode_v0.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "mlir/Dialect/StandardOps/Ops.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BlockAndValueMapping.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/StandardTypes.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassRegistry.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/Utils.h"

namespace mlir {
namespace iree_compiler {

namespace {

struct LowerBranchOpPattern
    : public OpRewritePattern<IREEInterp::HL::BranchOp> {
  using OpRewritePattern<IREEInterp::HL::BranchOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(IREEInterp::HL::BranchOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> operands{op.getOperation()->getOperands()};

    rewriter.replaceOpWithNewOp<IREEInterp::LL::BranchOp>(op, op.getDest(),
                                                          operands);
    return matchSuccess();
  }
};

struct LowerCondCondBranchOpPattern
    : public OpRewritePattern<IREEInterp::HL::CondBranchOp> {
  using OpRewritePattern<IREEInterp::HL::CondBranchOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(IREEInterp::HL::CondBranchOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> trueOperands{op.getTrueOperands()};
    SmallVector<Value *, 8> falseOperands{op.getFalseOperands()};

    rewriter.replaceOpWithNewOp<IREEInterp::LL::CondBranchOp>(
        op, op.getCondition(), op.getTrueDest(), trueOperands,
        op.getFalseDest(), falseOperands);
    return matchSuccess();
  }
};

// Returns true if the op defined by |opName| (like 'iree_ll_interp.reshape')
// uses output operands for results (like iree_ll_interp.add_i) or returns real
// results.
bool opTakesOutputOperands(llvm::StringRef opName) {
  if (!opName.consume_front("iree_ll_interp.")) {
    assert(false && "op not part of IREE LL Interpreter dialect");
    return false;
  }
  auto opcode = GetInterpreterOpcodeByName(opName.str());
  assert(opcode.hasValue() && "op has no corresponding opcode");
  const auto &info = GetInterpreterOpcodeInfo(opcode.getValue());
  for (auto &operand : info.operands) {
    if (operand == iree::OperandEncoding::kOutputSlot ||
        operand == iree::OperandEncoding::kVariadicOutputSlots) {
      return true;
    }
  }
  return false;
}

template <typename SrcOp, typename DstOp>
class SimpleOpLowering : public OpRewritePattern<SrcOp> {
  using OpRewritePattern<SrcOp>::OpRewritePattern;

  PatternMatchResult matchAndRewrite(SrcOp op,
                                     PatternRewriter &rewriter) const {
    SmallVector<Value *, 8> operands{op.getOperation()->getOperands()};

    // Most ops take results as output operands to populate during execution.
    // Certain ops, like reshape, return references to existing memrefs and
    // should still retain their results.
    if (!opTakesOutputOperands(DstOp::getOperationName())) {
      SmallVector<Type, 8> resultTypes{op.getOperation()->getResultTypes()};

      rewriter.replaceOpWithNewOp<DstOp>(op, resultTypes, operands,
                                         op.getAttrs());
      return this->matchSuccess();
    }

    SmallVector<Value *, 4> replacementValues;
    for (Value *result : op.getOperation()->getResults()) {
      auto memRefType = result->getType().cast<MemRefType>();
      if (!memRefType.hasStaticShape()) {
        // TODO(benvanik): real thing here - dynamic shaping required.
        // This should emit a shape calculation based on the operation. Most
        // are likely simple and by running DCE after this we can clean up
        // parts that are static or unused.
        op.emitOpError() << "uses unsupported dynamic shapes";
        return this->matchFailure();
      }
      ArrayRef<Value *> dim_pieces;
      auto allocOp = rewriter.create<IREEInterp::LL::AllocHeapOp>(
          op.getLoc(), memRefType, dim_pieces);
      operands.push_back(allocOp);
      replacementValues.push_back(allocOp);
    }
    ArrayRef<Type> resultTypes;
    rewriter.create<DstOp>(op.getLoc(), resultTypes, operands, op.getAttrs());
    rewriter.replaceOp(op, replacementValues);
    return this->matchSuccess();
  }
};

}  // namespace

void populateInterpreterLoweringPatterns(OwningRewritePatternList &patterns,
                                         MLIRContext *ctx) {
  patterns.insert<LowerBranchOpPattern, LowerCondCondBranchOpPattern>(ctx);
  patterns.insert<
      SimpleOpLowering<IREE::ConstantOp, IREEInterp::LL::ConstantOp>,
      SimpleOpLowering<IREEInterp::HL::CopyOp, IREEInterp::LL::DynamicCopyOp>,
      SimpleOpLowering<IREEInterp::HL::SliceOp,
                       IREEInterp::LL::DynamicSliceOp>>(ctx);
#define SAME_NAME_SIMPLE_PATTERN(op_name) \
  SimpleOpLowering<IREEInterp::HL::op_name, IREEInterp::LL::op_name>
  // clang-format off
  patterns.insert<
      SAME_NAME_SIMPLE_PATTERN(AssignOp),
      SAME_NAME_SIMPLE_PATTERN(AbsFOp),
      SAME_NAME_SIMPLE_PATTERN(AbsIOp),
      SAME_NAME_SIMPLE_PATTERN(AddFOp),
      SAME_NAME_SIMPLE_PATTERN(AddIOp),
      SAME_NAME_SIMPLE_PATTERN(AllocHeapOp),
      SAME_NAME_SIMPLE_PATTERN(AndOp),
      SAME_NAME_SIMPLE_PATTERN(Atan2FOp),
      SAME_NAME_SIMPLE_PATTERN(BreakOp),
      SAME_NAME_SIMPLE_PATTERN(BroadcastOp),
      SAME_NAME_SIMPLE_PATTERN(CallOp),
      SAME_NAME_SIMPLE_PATTERN(CallIndirectOp),
      SAME_NAME_SIMPLE_PATTERN(CeilFOp),
      SAME_NAME_SIMPLE_PATTERN(ClampFOp),
      SAME_NAME_SIMPLE_PATTERN(CloneOp),
      SAME_NAME_SIMPLE_PATTERN(CmpFOp),
      SAME_NAME_SIMPLE_PATTERN(CmpIOp),
      SAME_NAME_SIMPLE_PATTERN(CondAssignOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertSSOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertUUOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertSUOp),
      SAME_NAME_SIMPLE_PATTERN(ConvertUSOp),
      SAME_NAME_SIMPLE_PATTERN(CondBreakOp),
      SAME_NAME_SIMPLE_PATTERN(CosFOp),
      SAME_NAME_SIMPLE_PATTERN(DimOp),
      SAME_NAME_SIMPLE_PATTERN(DivFOp),
      SAME_NAME_SIMPLE_PATTERN(DivISOp),
      SAME_NAME_SIMPLE_PATTERN(DivIUOp),
      SAME_NAME_SIMPLE_PATTERN(ExpFOp),
      SAME_NAME_SIMPLE_PATTERN(LogFOp),
      SAME_NAME_SIMPLE_PATTERN(RsqrtFOp),
      SAME_NAME_SIMPLE_PATTERN(FloorFOp),
      SAME_NAME_SIMPLE_PATTERN(LengthOp),
      SAME_NAME_SIMPLE_PATTERN(MatMulFOp),
      SAME_NAME_SIMPLE_PATTERN(MatMulIOp),
      SAME_NAME_SIMPLE_PATTERN(MaxFOp),
      SAME_NAME_SIMPLE_PATTERN(MaxISOp),
      SAME_NAME_SIMPLE_PATTERN(MaxIUOp),
      SAME_NAME_SIMPLE_PATTERN(MinFOp),
      SAME_NAME_SIMPLE_PATTERN(MinISOp),
      SAME_NAME_SIMPLE_PATTERN(MinIUOp),
      SAME_NAME_SIMPLE_PATTERN(MulAddFOp),
      SAME_NAME_SIMPLE_PATTERN(MulAddIOp),
      SAME_NAME_SIMPLE_PATTERN(MulFOp),
      SAME_NAME_SIMPLE_PATTERN(MulIOp),
      SAME_NAME_SIMPLE_PATTERN(NotOp),
      SAME_NAME_SIMPLE_PATTERN(OrOp),
      SAME_NAME_SIMPLE_PATTERN(PadOp),
      SAME_NAME_SIMPLE_PATTERN(RankOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceSumIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceSumFOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMinIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMinFOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMaxIOp),
      SAME_NAME_SIMPLE_PATTERN(ReduceMaxFOp),
      SAME_NAME_SIMPLE_PATTERN(ReshapeOp),
      SAME_NAME_SIMPLE_PATTERN(ReturnOp),
      SAME_NAME_SIMPLE_PATTERN(SelectOp),
      SAME_NAME_SIMPLE_PATTERN(ShapeOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftLeftOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftRightArithmeticOp),
      SAME_NAME_SIMPLE_PATTERN(ShiftRightLogicalOp),
      SAME_NAME_SIMPLE_PATTERN(SinFOp),
      SAME_NAME_SIMPLE_PATTERN(SplitOp),
      SAME_NAME_SIMPLE_PATTERN(SubFOp),
      SAME_NAME_SIMPLE_PATTERN(SubIOp),
      SAME_NAME_SIMPLE_PATTERN(TanhFOp),
      SAME_NAME_SIMPLE_PATTERN(TileOp),
      SAME_NAME_SIMPLE_PATTERN(TraceOp),
      SAME_NAME_SIMPLE_PATTERN(TransposeOp),
      SAME_NAME_SIMPLE_PATTERN(ReverseOp),
      SAME_NAME_SIMPLE_PATTERN(XorOp)>(ctx);
  // clang-format on
#undef SAME_NAME_SIMPLE_PATTERN
}

namespace {
class LowerInterpreterDialectPass
    : public FunctionPass<LowerInterpreterDialectPass> {
 public:
  void runOnFunction() override {
    OwningRewritePatternList patterns;
    populateInterpreterLoweringPatterns(patterns, &getContext());

    ConversionTarget target(getContext());
    target.addLegalDialect<IREELLInterpreterDialect>();
    target.addLegalOp<FuncOp, IREE::ReturnOp>();
    if (failed(applyFullConversion(getFunction(), target, patterns))) {
      return signalPassFailure();
    }
  }
};
}  // namespace

std::unique_ptr<OpPassBase<FuncOp>> createLowerInterpreterDialectPass() {
  return std::make_unique<LowerInterpreterDialectPass>();
}

static PassRegistration<LowerInterpreterDialectPass> pass(
    "lower-iree-interpreter-hl-to-ll", "Lowers IREE HL ops to IREE LL ops");

}  // namespace iree_compiler
}  // namespace mlir
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryViewSwitch.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:31:11 $
 *
 *  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 DBAUI_QUERYVIEWSWITCH_HXX
#define DBAUI_QUERYVIEWSWITCH_HXX

#ifndef DBAUI_QUERYVIEW_HXX
#include "queryview.hxx"
#endif

namespace dbaui
{
    class OQueryDesignView;
    class OQueryTextView;
    class OAddTableDlg;
    class OQueryContainerWindow;
    class OQueryViewSwitch
    {
        OQueryDesignView*   m_pDesignView;
        OQueryTextView*     m_pTextView;
        sal_Bool            m_bAddTableDialogWasVisible; // true if so
    public:
        OQueryViewSwitch(OQueryContainerWindow* pParent, OQueryController* _pController,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~OQueryViewSwitch();

        virtual sal_Bool isCutAllowed();
        virtual sal_Bool isPasteAllowed();
        virtual sal_Bool isCopyAllowed();
        virtual void copy();
        virtual void cut();
        virtual void paste();
        // clears the whole query
        virtual void clear();
        // set the view readonly or not
        virtual void setReadOnly(sal_Bool _bReadOnly);
        // check if the statement is correct when not returning false
        virtual sal_Bool checkStatement();
        // set the statement for representation
        virtual void setStatement(const ::rtl::OUString& _rsStatement);
        // returns the current sql statement
        virtual ::rtl::OUString getStatement();
        /// late construction
        virtual void Construct();
        virtual void initialize();
        /** show the text or the design view
            @return
                <TRUE/> when all went right otherwise <FALSE/> which implies an aditional
                call of switchView from the controller to restore the old state
        */
        sal_Bool switchView();
        sal_Bool isSlotEnabled(sal_Int32 _nSlotId);
        void     setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable);
        void     setNoneVisbleRow(sal_Int32 _nRows);
        // returs the add table dialog from the design view
        OAddTableDlg* getAddTableDialog();
        BOOL IsAddAllowed();
        void zoomTableView(const Fraction& _rFraction);
        void SaveUIConfig();
        void clearDesignView();
        void GetFocus();
        void reset();
        void GrabFocus();

        OQueryDesignView*       getDesignView() const { return m_pDesignView; }
        OQueryContainerWindow*  getContainer() const;

        Window* getActive() const;

        void SetPosSizePixel( Point _rPt,Size _rSize);
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() const;
    protected:
        // return the Rectangle where I can paint myself
        virtual void resizeDocumentView(Rectangle& rRect);
    };
}
#endif // DBAUI_QUERYVIEWSWITCH_HXX

<commit_msg>INTEGRATION: CWS dba23a (1.12.254); FILE MERGED 2007/02/26 10:34:00 fs 1.12.254.1: remove unused code Issue number:  #i74776# Submitted by:  jnavrati@openoffice.org Reviewed by:   frank.schoenheit@sun.com<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryViewSwitch.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 10:28:48 $
 *
 *  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 DBAUI_QUERYVIEWSWITCH_HXX
#define DBAUI_QUERYVIEWSWITCH_HXX

#ifndef DBAUI_QUERYVIEW_HXX
#include "queryview.hxx"
#endif

namespace dbaui
{
    class OQueryDesignView;
    class OQueryTextView;
    class OAddTableDlg;
    class OQueryContainerWindow;
    class OQueryViewSwitch
    {
        OQueryDesignView*   m_pDesignView;
        OQueryTextView*     m_pTextView;
        sal_Bool            m_bAddTableDialogWasVisible; // true if so
    public:
        OQueryViewSwitch(OQueryContainerWindow* pParent, OQueryController* _pController,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~OQueryViewSwitch();

        virtual sal_Bool isCutAllowed();
        virtual sal_Bool isPasteAllowed();
        virtual sal_Bool isCopyAllowed();
        virtual void copy();
        virtual void cut();
        virtual void paste();
        // clears the whole query
        virtual void clear();
        // set the view readonly or not
        virtual void setReadOnly(sal_Bool _bReadOnly);
        // check if the statement is correct when not returning false
        virtual sal_Bool checkStatement();
        // set the statement for representation
        virtual void setStatement(const ::rtl::OUString& _rsStatement);
        // returns the current sql statement
        virtual ::rtl::OUString getStatement();
        /// late construction
        virtual void Construct();
        virtual void initialize();
        /** show the text or the design view
            @return
                <TRUE/> when all went right otherwise <FALSE/> which implies an aditional
                call of switchView from the controller to restore the old state
        */
        sal_Bool switchView();
        sal_Bool isSlotEnabled(sal_Int32 _nSlotId);
        void     setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable);
        void     setNoneVisbleRow(sal_Int32 _nRows);
        // returs the add table dialog from the design view
        OAddTableDlg* getAddTableDialog();
        void SaveUIConfig();
        void reset();
        void GrabFocus();

        OQueryDesignView*       getDesignView() const { return m_pDesignView; }
        OQueryContainerWindow*  getContainer() const;

        void SetPosSizePixel( Point _rPt,Size _rSize);
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() const;
    protected:
        // return the Rectangle where I can paint myself
        virtual void resizeDocumentView(Rectangle& rRect);
    };
}
#endif // DBAUI_QUERYVIEWSWITCH_HXX

<|endoftext|>


<commit_before>//----------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2001, 2002 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------------------------------------------

// only compile this file if in 2d
#if deal_II_dimension == 2

#include <fe/fe_nedelec.h>

// Transfer matrices for finite elements: have one matrix for each of
// the four child cells which tells us how the degrees of freedom on
// the child cell are obtained from the degrees of freedom on the
// mother cell
//
// TODO: [Anna] check whether the following paragraph is correct. if so, then please multiply the values in the four following matrices by two

// note the following: since the shape functions themselves and not
// only the gradients are transformed using the mapping object from
// the unit cell to the real cell, the actual values of the function
// on the real cell is degree of freedom times value of the shape
// function on the unit cell times Jacobian. Thus, what has the DoF
// value 1 on the mother cell must have the DoF value 2 on the child
// cell since the latter is smaller by a (linear scaling) factor of
// two.
namespace FE_Nedelec_2d
{
  static const double q1_into_q1_refined_0[] =
  {
	1.,  0,  0,  0,
	0,   0.5,0,  0.5,
	0.5, 0,  0.5,0,
	0,   0,  0,  1
  };

  static const double q1_into_q1_refined_1[] =
  {
  	1., 0., 0., 0.,
  	0., 1., 0., 0.,
  	0.5, 0., 0.5, 0.,
	0., 0.5, 0., 0.5,
  };

  static const double q1_into_q1_refined_2[] =
  {
  	0.5, 0., 0.5, 0.,
 	0., 1., 0., 0.,
	0., 0., 1., 0.,
  	0., 0.5, 0., 0.5,
  };

  static const double q1_into_q1_refined_3[] =
  {
  	0.5, 0., 0.5, 0.,
  	0., 0.5, 0., 0.5,
	0., 0., 1., 0.,
  	0., 0., 0., 1.,
  };
};  // namespace FE_Nedelec_2d

// embedding matrices

template <>
const double * const
FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::children_per_cell] =
{
      { FE_Nedelec_2d::q1_into_q1_refined_0, FE_Nedelec_2d::q1_into_q1_refined_1,
	FE_Nedelec_2d::q1_into_q1_refined_2, FE_Nedelec_2d::q1_into_q1_refined_3 }
};

template <>
const unsigned int
FE_Nedelec<2>::Matrices::n_embedding_matrices
= sizeof(FE_Nedelec<2>::Matrices::embedding) /
sizeof(FE_Nedelec<2>::Matrices::embedding[0]);

// Constraint matrices: how do the new value on child faces depend on
// the values on the mother face if that face has a hanging node
//
// Here, the same applies as for the embedding matrices: since the DoF
// values are not only multiplied by the values of the shape function
// on the unit cell, but also by the transformation, we have to
// multiply the value on the large face by two to get the same value
// back on the small face
namespace FE_Nedelec_2d
{
  static const double constraint_q1[] =
  {
					 // the function is constant
					 // along each edge, so each
					 // degree of freedom on the
					 // refined edge has the same
					 // value as that on the
					 // coarse edge, modulo the
					 // issue with the
					 // transformation described
					 // above
  	2., 2.
  };

};

template <>
const double * const
FE_Nedelec<2>::Matrices::constraint_matrices[] =
{
      FE_Nedelec_2d::constraint_q1
};

template <>
const unsigned int
FE_Nedelec<2>::Matrices::n_constraint_matrices
= sizeof(FE_Nedelec<2>::Matrices::constraint_matrices) /
sizeof(FE_Nedelec<2>::Matrices::constraint_matrices[0]);

#else // #if deal_II_dimension
// On gcc2.95 on Alpha OSF1, the native assembler does not like empty
// files, so provide some dummy code
namespace { void dummy () {}; };
#endif // #if deal_II_dimension == 2
<commit_msg>Fix constraint matrices.<commit_after>//----------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2001, 2002 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------------------------------------------

// only compile this file if in 2d
#if deal_II_dimension == 2

#include <fe/fe_nedelec.h>

// Transfer matrices for finite elements: have one matrix for each of
// the four child cells which tells us how the degrees of freedom on
// the child cell are obtained from the degrees of freedom on the
// mother cell
//
// TODO: [Anna] check whether the following paragraph is correct. if so, then please multiply the values in the four following matrices by two

// note the following: since the shape functions themselves and not
// only the gradients are transformed using the mapping object from
// the unit cell to the real cell, the actual values of the function
// on the real cell is degree of freedom times value of the shape
// function on the unit cell times Jacobian. Thus, what has the DoF
// value 1 on the mother cell must have the DoF value 2 on the child
// cell since the latter is smaller by a (linear scaling) factor of
// two.
namespace FE_Nedelec_2d
{
  static const double q1_into_q1_refined_0[] =
  {
	1.,  0,  0,  0,
	0,   0.5,0,  0.5,
	0.5, 0,  0.5,0,
	0,   0,  0,  1
  };

  static const double q1_into_q1_refined_1[] =
  {
  	1., 0., 0., 0.,
  	0., 1., 0., 0.,
  	0.5, 0., 0.5, 0.,
	0., 0.5, 0., 0.5,
  };

  static const double q1_into_q1_refined_2[] =
  {
  	0.5, 0., 0.5, 0.,
 	0., 1., 0., 0.,
	0., 0., 1., 0.,
  	0., 0.5, 0., 0.5,
  };

  static const double q1_into_q1_refined_3[] =
  {
  	0.5, 0., 0.5, 0.,
  	0., 0.5, 0., 0.5,
	0., 0., 1., 0.,
  	0., 0., 0., 1.,
  };
};  // namespace FE_Nedelec_2d

// embedding matrices

template <>
const double * const
FE_Nedelec<2>::Matrices::embedding[][GeometryInfo<2>::children_per_cell] =
{
      { FE_Nedelec_2d::q1_into_q1_refined_0, FE_Nedelec_2d::q1_into_q1_refined_1,
	FE_Nedelec_2d::q1_into_q1_refined_2, FE_Nedelec_2d::q1_into_q1_refined_3 }
};

template <>
const unsigned int
FE_Nedelec<2>::Matrices::n_embedding_matrices
= sizeof(FE_Nedelec<2>::Matrices::embedding) /
sizeof(FE_Nedelec<2>::Matrices::embedding[0]);

// Constraint matrices: how do the new value on child faces depend on
// the values on the mother face if that face has a hanging node
//
// Here, the same applies as for the embedding matrices: since the DoF
// values are not only multiplied by the values of the shape function
// on the unit cell, but also by the transformation, we have to
// multiply the value on the large face by 1/2 to get the same value
// back on the small face.  in other words, if a DoF has weight 1 on
// the big cell, then it has to have weight 1/2 on the small ones, in
// order to give the same value of the shape function in real space
namespace FE_Nedelec_2d
{
  static const double constraint_q1[] =
  {
					 // the function is constant
					 // along each edge, so each
					 // degree of freedom on the
					 // refined edge has the same
					 // value as that on the
					 // coarse edge, modulo the
					 // issue with the
					 // transformation described
					 // above
  	1./2., 1./2.
  };

};

template <>
const double * const
FE_Nedelec<2>::Matrices::constraint_matrices[] =
{
      FE_Nedelec_2d::constraint_q1
};

template <>
const unsigned int
FE_Nedelec<2>::Matrices::n_constraint_matrices
= sizeof(FE_Nedelec<2>::Matrices::constraint_matrices) /
sizeof(FE_Nedelec<2>::Matrices::constraint_matrices[0]);

#else // #if deal_II_dimension
// On gcc2.95 on Alpha OSF1, the native assembler does not like empty
// files, so provide some dummy code
namespace { void dummy () {}; };
#endif // #if deal_II_dimension == 2
<|endoftext|>