<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "test/core/end2end/end2end_tests.h"

#include <stdio.h>
#include <string.h>

#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "test/core/end2end/cq_verifier.h"

static void* tag(intptr_t t) { return (void*)t; }

static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                            const char* test_name,
                                            grpc_channel_args* client_args,
                                            grpc_channel_args* server_args) {
  grpc_end2end_test_fixture f;
  gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
  f = config.create_fixture(client_args, server_args);
  config.init_server(&f, server_args);
  config.init_client(&f, client_args);
  return f;
}

static gpr_timespec n_seconds_from_now(int n) {
  return grpc_timeout_seconds_to_deadline(n);
}

static gpr_timespec five_seconds_from_now(void) {
  return n_seconds_from_now(5);
}

static void drain_cq(grpc_completion_queue* cq) {
  grpc_event ev;
  do {
    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
}

static void shutdown_server(grpc_end2end_test_fixture* f) {
  if (!f->server) return;
  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
                                         grpc_timeout_seconds_to_deadline(5),
                                         nullptr)
                 .type == GRPC_OP_COMPLETE);
  grpc_server_destroy(f->server);
  f->server = nullptr;
}

static void shutdown_client(grpc_end2end_test_fixture* f) {
  if (!f->client) return;
  grpc_channel_destroy(f->client);
  f->client = nullptr;
}

static void end_test(grpc_end2end_test_fixture* f) {
  shutdown_server(f);
  shutdown_client(f);

  grpc_completion_queue_shutdown(f->cq);
  drain_cq(f->cq);
  grpc_completion_queue_destroy(f->cq);
  grpc_completion_queue_destroy(f->shutdown_cq);
}

static void simple_request_body(grpc_end2end_test_config config,
                                grpc_end2end_test_fixture f) {
  grpc_call* c;
  grpc_call* s;
  cq_verifier* cqv = cq_verifier_create(f.cq);
  grpc_op ops[6];
  grpc_op* op;
  grpc_metadata_array initial_metadata_recv;
  grpc_metadata_array trailing_metadata_recv;
  grpc_metadata_array request_metadata_recv;
  grpc_call_details call_details;
  grpc_status_code status;
  const char* error_string;
  grpc_call_error error;
  grpc_slice details;
  int was_cancelled = 2;
  char* peer;
  grpc_stats_data* before =
      static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data)));
  grpc_stats_data* after =
      static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data)));

  grpc_stats_collect(before);

  gpr_timespec deadline = five_seconds_from_now();
  c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
                               grpc_slice_from_static_string("/foo"), nullptr,
                               deadline, nullptr);
  GPR_ASSERT(c);

  peer = grpc_call_get_peer(c);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
  gpr_free(peer);

  grpc_metadata_array_init(&initial_metadata_recv);
  grpc_metadata_array_init(&trailing_metadata_recv);
  grpc_metadata_array_init(&request_metadata_recv);
  grpc_call_details_init(&call_details);

  memset(ops, 0, sizeof(ops));
  op = ops;
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
  op->data.send_initial_metadata.count = 0;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_INITIAL_METADATA;
  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  op->data.recv_status_on_client.status = &status;
  op->data.recv_status_on_client.status_details = &details;
  op->data.recv_status_on_client.error_string = &error_string;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
                                nullptr);
  GPR_ASSERT(GRPC_CALL_OK == error);

  error =
      grpc_server_request_call(f.server, &s, &call_details,
                               &request_metadata_recv, f.cq, f.cq, tag(101));
  GPR_ASSERT(GRPC_CALL_OK == error);
  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  cq_verify(cqv);

  peer = grpc_call_get_peer(s);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "server_peer=%s", peer);
  gpr_free(peer);
  peer = grpc_call_get_peer(c);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "client_peer=%s", peer);
  gpr_free(peer);

  memset(ops, 0, sizeof(ops));
  op = ops;
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
  op->data.send_initial_metadata.count = 0;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  op->data.send_status_from_server.trailing_metadata_count = 0;
  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
  grpc_slice status_details = grpc_slice_from_static_string("xyz");
  op->data.send_status_from_server.status_details = &status_details;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  op->data.recv_close_on_server.cancelled = &was_cancelled;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
                                nullptr);
  GPR_ASSERT(GRPC_CALL_OK == error);

  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  cq_verify(cqv);

  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
  // the following sanity check makes sure that the requested error string is
  // correctly populated by the core. It looks for certain substrings that are
  // not likely to change much. Some parts of the error, like time created,
  // obviously are not checked.
  GPR_ASSERT(nullptr != strstr(error_string, "xyz"));
  GPR_ASSERT(nullptr != strstr(error_string, "description"));
  GPR_ASSERT(nullptr != strstr(error_string, "Error received from peer"));
  GPR_ASSERT(nullptr != strstr(error_string, "grpc_message"));
  GPR_ASSERT(nullptr != strstr(error_string, "grpc_status"));
  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
  GPR_ASSERT(0 == call_details.flags);
  GPR_ASSERT(was_cancelled == 1);

  grpc_slice_unref(details);
  gpr_free((void*)error_string);
  grpc_metadata_array_destroy(&initial_metadata_recv);
  grpc_metadata_array_destroy(&trailing_metadata_recv);
  grpc_metadata_array_destroy(&request_metadata_recv);
  grpc_call_details_destroy(&call_details);

  grpc_call_unref(c);
  grpc_call_unref(s);

  cq_verifier_destroy(cqv);

  grpc_stats_collect(after);

  char* stats = grpc_stats_data_as_json(after);
  gpr_log(GPR_DEBUG, "%s", stats);
  gpr_free(stats);

  int expected_calls = 1;
  if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
    expected_calls *= 2;
  }
#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
  GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] -
                 before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] ==
             expected_calls);
  GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] -
                 before->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] ==
             expected_calls);
#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
  gpr_free(before);
  gpr_free(after);
}

static void test_invoke_simple_request(grpc_end2end_test_config config) {
  grpc_end2end_test_fixture f;

  f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
  simple_request_body(config, f);
  end_test(&f);
  config.tear_down_data(&f);
}

// static void test_invoke_10_simple_requests(grpc_end2end_test_config config) {
//   int i;
//   grpc_end2end_test_fixture f =
//       begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr);
//   for (i = 0; i < 10; i++) {
//     simple_request_body(config, f);
//     gpr_log(GPR_INFO, "Running test: Passed simple request %d", i);
//   }
//   end_test(&f);
//   config.tear_down_data(&f);
// }

void simple_request(grpc_end2end_test_config config) {
  // int i;
  // for (i = 0; i < 10; i++) {
  test_invoke_simple_request(config);
  // }
  // test_invoke_10_simple_requests(config);
}

void simple_request_pre_init(void) {}
<commit_msg>Un-pare simple_request<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "test/core/end2end/end2end_tests.h"

#include <stdio.h>
#include <string.h>

#include <grpc/byte_buffer.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/string.h"
#include "test/core/end2end/cq_verifier.h"

static void* tag(intptr_t t) { return (void*)t; }

static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                            const char* test_name,
                                            grpc_channel_args* client_args,
                                            grpc_channel_args* server_args) {
  grpc_end2end_test_fixture f;
  gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
  f = config.create_fixture(client_args, server_args);
  config.init_server(&f, server_args);
  config.init_client(&f, client_args);
  return f;
}

static gpr_timespec n_seconds_from_now(int n) {
  return grpc_timeout_seconds_to_deadline(n);
}

static gpr_timespec five_seconds_from_now(void) {
  return n_seconds_from_now(5);
}

static void drain_cq(grpc_completion_queue* cq) {
  grpc_event ev;
  do {
    ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
}

static void shutdown_server(grpc_end2end_test_fixture* f) {
  if (!f->server) return;
  grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
  GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
                                         grpc_timeout_seconds_to_deadline(5),
                                         nullptr)
                 .type == GRPC_OP_COMPLETE);
  grpc_server_destroy(f->server);
  f->server = nullptr;
}

static void shutdown_client(grpc_end2end_test_fixture* f) {
  if (!f->client) return;
  grpc_channel_destroy(f->client);
  f->client = nullptr;
}

static void end_test(grpc_end2end_test_fixture* f) {
  shutdown_server(f);
  shutdown_client(f);

  grpc_completion_queue_shutdown(f->cq);
  drain_cq(f->cq);
  grpc_completion_queue_destroy(f->cq);
  grpc_completion_queue_destroy(f->shutdown_cq);
}

static void simple_request_body(grpc_end2end_test_config config,
                                grpc_end2end_test_fixture f) {
  grpc_call* c;
  grpc_call* s;
  cq_verifier* cqv = cq_verifier_create(f.cq);
  grpc_op ops[6];
  grpc_op* op;
  grpc_metadata_array initial_metadata_recv;
  grpc_metadata_array trailing_metadata_recv;
  grpc_metadata_array request_metadata_recv;
  grpc_call_details call_details;
  grpc_status_code status;
  const char* error_string;
  grpc_call_error error;
  grpc_slice details;
  int was_cancelled = 2;
  char* peer;
  grpc_stats_data* before =
      static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data)));
  grpc_stats_data* after =
      static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data)));

  grpc_stats_collect(before);

  gpr_timespec deadline = five_seconds_from_now();
  c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
                               grpc_slice_from_static_string("/foo"), nullptr,
                               deadline, nullptr);
  GPR_ASSERT(c);

  peer = grpc_call_get_peer(c);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
  gpr_free(peer);

  grpc_metadata_array_init(&initial_metadata_recv);
  grpc_metadata_array_init(&trailing_metadata_recv);
  grpc_metadata_array_init(&request_metadata_recv);
  grpc_call_details_init(&call_details);

  memset(ops, 0, sizeof(ops));
  op = ops;
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
  op->data.send_initial_metadata.count = 0;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_INITIAL_METADATA;
  op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  op->data.recv_status_on_client.status = &status;
  op->data.recv_status_on_client.status_details = &details;
  op->data.recv_status_on_client.error_string = &error_string;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
                                nullptr);
  GPR_ASSERT(GRPC_CALL_OK == error);

  error =
      grpc_server_request_call(f.server, &s, &call_details,
                               &request_metadata_recv, f.cq, f.cq, tag(101));
  GPR_ASSERT(GRPC_CALL_OK == error);
  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  cq_verify(cqv);

  peer = grpc_call_get_peer(s);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "server_peer=%s", peer);
  gpr_free(peer);
  peer = grpc_call_get_peer(c);
  GPR_ASSERT(peer != nullptr);
  gpr_log(GPR_DEBUG, "client_peer=%s", peer);
  gpr_free(peer);

  memset(ops, 0, sizeof(ops));
  op = ops;
  op->op = GRPC_OP_SEND_INITIAL_METADATA;
  op->data.send_initial_metadata.count = 0;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  op->data.send_status_from_server.trailing_metadata_count = 0;
  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
  grpc_slice status_details = grpc_slice_from_static_string("xyz");
  op->data.send_status_from_server.status_details = &status_details;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  op->data.recv_close_on_server.cancelled = &was_cancelled;
  op->flags = 0;
  op->reserved = nullptr;
  op++;
  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
                                nullptr);
  GPR_ASSERT(GRPC_CALL_OK == error);

  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  cq_verify(cqv);

  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
  // the following sanity check makes sure that the requested error string is
  // correctly populated by the core. It looks for certain substrings that are
  // not likely to change much. Some parts of the error, like time created,
  // obviously are not checked.
  GPR_ASSERT(nullptr != strstr(error_string, "xyz"));
  GPR_ASSERT(nullptr != strstr(error_string, "description"));
  GPR_ASSERT(nullptr != strstr(error_string, "Error received from peer"));
  GPR_ASSERT(nullptr != strstr(error_string, "grpc_message"));
  GPR_ASSERT(nullptr != strstr(error_string, "grpc_status"));
  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
  GPR_ASSERT(0 == call_details.flags);
  GPR_ASSERT(was_cancelled == 1);

  grpc_slice_unref(details);
  gpr_free((void*)error_string);
  grpc_metadata_array_destroy(&initial_metadata_recv);
  grpc_metadata_array_destroy(&trailing_metadata_recv);
  grpc_metadata_array_destroy(&request_metadata_recv);
  grpc_call_details_destroy(&call_details);

  grpc_call_unref(c);
  grpc_call_unref(s);

  cq_verifier_destroy(cqv);

  grpc_stats_collect(after);

  char* stats = grpc_stats_data_as_json(after);
  gpr_log(GPR_DEBUG, "%s", stats);
  gpr_free(stats);

  int expected_calls = 1;
  if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
    expected_calls *= 2;
  }
#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
  GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] -
                 before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] ==
             expected_calls);
  GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] -
                 before->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] ==
             expected_calls);
#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
  gpr_free(before);
  gpr_free(after);
}

static void test_invoke_simple_request(grpc_end2end_test_config config) {
  grpc_end2end_test_fixture f;

  f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr);
  simple_request_body(config, f);
  end_test(&f);
  config.tear_down_data(&f);
}

static void test_invoke_10_simple_requests(grpc_end2end_test_config config) {
  int i;
  grpc_end2end_test_fixture f =
      begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr);
  for (i = 0; i < 10; i++) {
    simple_request_body(config, f);
    gpr_log(GPR_INFO, "Running test: Passed simple request %d", i);
  }
  end_test(&f);
  config.tear_down_data(&f);
}

void simple_request(grpc_end2end_test_config config) {
  int i;
  for (i = 0; i < 10; i++) {
    test_invoke_simple_request(config);
  }
  test_invoke_10_simple_requests(config);
}

void simple_request_pre_init(void) {}
<|endoftext|>


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

#include <osl/diagnose.h>
#include <advisesink.hxx>
#include <olecomponent.hxx>

OleWrapperAdviseSink::OleWrapperAdviseSink( OleComponent* pOleComp )
: m_nRefCount( 0 )
, m_pOleComp( pOleComp )
{
    OSL_ENSURE( m_pOleComp, "No ole component is provided!\n" );
}

OleWrapperAdviseSink::~OleWrapperAdviseSink()
{
}

STDMETHODIMP OleWrapperAdviseSink::QueryInterface( REFIID riid , void** ppv )
{
    *ppv=NULL;

    if ( riid == IID_IUnknown )
        *ppv = (IUnknown*)this;

    if ( riid == IID_IAdviseSink )
        *ppv = (IAdviseSink*)this;

    if ( *ppv != NULL )
    {
        ((IUnknown*)*ppv)->AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) OleWrapperAdviseSink::AddRef()
{
    return osl_incrementInterlockedCount( &m_nRefCount);
}

STDMETHODIMP_(ULONG) OleWrapperAdviseSink::Release()
{
    ULONG nReturn = --m_nRefCount;
    if ( m_nRefCount == 0 )
        delete this;

    return nReturn;
}

void OleWrapperAdviseSink::disconnectOleComponent()
{
    // must not be called from the descructor of OleComponent!!!
    osl::MutexGuard aGuard( m_aMutex );
    m_pOleComp = NULL;
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnDataChange(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
{
    // Unused for now ( no registration for IDataObject events )
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnViewChange(DWORD dwAspect, LONG lindex)
{
    OleComponent* pLockComponent = NULL;

    {
        osl::MutexGuard aGuard( m_aMutex );
        if ( m_pOleComp )
        {
            pLockComponent = m_pOleComp;
            pLockComponent->acquire();
        }
    }

    if ( pLockComponent )
    {
        pLockComponent->OnViewChange_Impl( dwAspect );
        pLockComponent->release();
    }
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnRename(LPMONIKER pmk)
{
    // handled by default inprocess handler
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnSave(void)
{
    // TODO: ???
    // The object knows about document saving already since it contolls it as ClienSite
    // other interested listeners must be registered for the object
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnClose(void)
{
    // mainly handled by inprocess handler

    // TODO: sometimes it can be necessary to simulate OnShowWindow( False ) here
}

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

#include <osl/diagnose.h>
#include <advisesink.hxx>
#include <olecomponent.hxx>

OleWrapperAdviseSink::OleWrapperAdviseSink( OleComponent* pOleComp )
: m_nRefCount( 0 )
, m_pOleComp( pOleComp )
{
    OSL_ENSURE( m_pOleComp, "No ole component is provided!\n" );
}

OleWrapperAdviseSink::~OleWrapperAdviseSink()
{
}

STDMETHODIMP OleWrapperAdviseSink::QueryInterface( REFIID riid , void** ppv )
{
    *ppv=NULL;

    if ( riid == IID_IUnknown )
        *ppv = (IUnknown*)this;

    if ( riid == IID_IAdviseSink )
        *ppv = (IAdviseSink*)this;

    if ( *ppv != NULL )
    {
        ((IUnknown*)*ppv)->AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) OleWrapperAdviseSink::AddRef()
{
    return osl_incrementInterlockedCount( &m_nRefCount);
}

STDMETHODIMP_(ULONG) OleWrapperAdviseSink::Release()
{
    ULONG nReturn = --m_nRefCount;
    if ( m_nRefCount == 0 )
        delete this;

    return nReturn;
}

void OleWrapperAdviseSink::disconnectOleComponent()
{
    // must not be called from the descructor of OleComponent!!!
    osl::MutexGuard aGuard( m_aMutex );
    m_pOleComp = NULL;
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnDataChange(LPFORMATETC pFEIn, LPSTGMEDIUM pSTM)
{
    // Unused for now ( no registration for IDataObject events )
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnViewChange(DWORD dwAspect, LONG lindex)
{
    OleComponent* pLockComponent = NULL;

    {
        osl::MutexGuard aGuard( m_aMutex );
        if ( m_pOleComp )
        {
            pLockComponent = m_pOleComp;
            pLockComponent->acquire();
        }
    }

    if ( pLockComponent )
    {
        pLockComponent->OnViewChange_Impl( dwAspect );
        pLockComponent->release();
    }
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnRename(LPMONIKER pmk)
{
    // handled by default inprocess handler
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnSave(void)
{
    // TODO: ???
    // The object knows about document saving already since it contolls it as ClienSite
    // other interested listeners must be registered for the object
}

STDMETHODIMP_(void) OleWrapperAdviseSink::OnClose(void)
{
    // mainly handled by inprocess handler

    // TODO: sometimes it can be necessary to simulate OnShowWindow( False ) here
}

<|endoftext|>


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

#ifndef SD_SLIDESORTER_VIEW_FONT_PROVIDER_HXX
#define SD_SLIDESORTER_VIEW_FONT_PROVIDER_HXX

#include "tools/SdGlobalResourceContainer.hxx"

#include <boost/shared_ptr.hpp>
#include <vcl/mapmod.hxx>

class Font;
class OutputDevice;
class VclWindowEvent;

namespace sd { namespace slidesorter { namespace view {

/** This simple singleton class provides fonts that are scaled so that they
    have a fixed height on the given device regardless of its map mode.
*/
class FontProvider
    : public SdGlobalResource
{
public:
    typedef ::boost::shared_ptr<Font> SharedFontPointer;

    /** Return the single instance of this class.  Throws a RuntimeException
        when no instance can be created.
    */
    static FontProvider& Instance (void);

    /** Return a font that is scaled according to the current map mode of
        the given device.  Repeated calls with a device, not necessarily the
        same device, with the same map mode will return the same font.  The
        first call with a different map mode will release the old font and
        create a new one that is correctly scaled.
    */
    SharedFontPointer GetFont (const OutputDevice& rDevice);

    /** Call this method to tell an object to release its currently used
        font.  The next call to GetFont() will then create a new one.
        Typically called after a DataChange event when for instance a system
        font has been modified.
    */
    void Invalidate (void);

private:
    static FontProvider* mpInstance;

    /** The font that was created by a previous call to GetFont().  It is
        replaced by another one only when GetFont() is called with a device
        with a different map mode or by a call to Invalidate().
    */
    SharedFontPointer maFont;
    /** The mape mode for which maFont was created.
    */
    MapMode maMapMode;

    FontProvider (void);
    virtual ~FontProvider (void);

    // Copy constructor is not implemented.
    FontProvider (const FontProvider&);
    // Assignment operator is not implemented.
    FontProvider& operator= (const FontProvider&);
};

} } } // end of namespace ::sd::slidesorter::view

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.624); FILE MERGED 2008/03/31 13:58:52 rt 1.3.624.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SlsFontProvider.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_VIEW_FONT_PROVIDER_HXX
#define SD_SLIDESORTER_VIEW_FONT_PROVIDER_HXX

#include "tools/SdGlobalResourceContainer.hxx"

#include <boost/shared_ptr.hpp>
#include <vcl/mapmod.hxx>

class Font;
class OutputDevice;
class VclWindowEvent;

namespace sd { namespace slidesorter { namespace view {

/** This simple singleton class provides fonts that are scaled so that they
    have a fixed height on the given device regardless of its map mode.
*/
class FontProvider
    : public SdGlobalResource
{
public:
    typedef ::boost::shared_ptr<Font> SharedFontPointer;

    /** Return the single instance of this class.  Throws a RuntimeException
        when no instance can be created.
    */
    static FontProvider& Instance (void);

    /** Return a font that is scaled according to the current map mode of
        the given device.  Repeated calls with a device, not necessarily the
        same device, with the same map mode will return the same font.  The
        first call with a different map mode will release the old font and
        create a new one that is correctly scaled.
    */
    SharedFontPointer GetFont (const OutputDevice& rDevice);

    /** Call this method to tell an object to release its currently used
        font.  The next call to GetFont() will then create a new one.
        Typically called after a DataChange event when for instance a system
        font has been modified.
    */
    void Invalidate (void);

private:
    static FontProvider* mpInstance;

    /** The font that was created by a previous call to GetFont().  It is
        replaced by another one only when GetFont() is called with a device
        with a different map mode or by a call to Invalidate().
    */
    SharedFontPointer maFont;
    /** The mape mode for which maFont was created.
    */
    MapMode maMapMode;

    FontProvider (void);
    virtual ~FontProvider (void);

    // Copy constructor is not implemented.
    FontProvider (const FontProvider&);
    // Assignment operator is not implemented.
    FontProvider& operator= (const FontProvider&);
};

} } } // end of namespace ::sd::slidesorter::view

#endif
<|endoftext|>


<commit_before>#include "TestApplication.h"

TestApplication::TestApplication(void)
{
}

TestApplication::~TestApplication(void)
{
}

void TestApplication::createCamera()
{
	mCamera = mSceneMgr->createCamera("PlayerCam");

	mCamera->setPosition(Ogre::Vector3(0, 300, 500));
	mCamera->lookAt(Ogre::Vector3(0, 0, 0));
	mCamera->setNearClipDistance(5);

	mCameraMan = new OgreBites::SdkCameraMan(mCamera);
}

void TestApplication::createViewports()
{
	Ogre::Viewport* vp = mWindow->addViewport(mCamera);

	vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

	mCamera->setAspectRatio(
		Ogre::Real(vp->getActualWidth()) /
		Ogre::Real(vp->getActualHeight()));

}

void TestApplication::createScene()
{
	createLight();
	createPlane();
	createSphere();
}

void TestApplication::createPlane()
{
	// Create ground
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);

	Ogre::MeshManager::getSingleton().createPlane(
		"ground",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
		plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);

	Ogre::Entity* groundEntity = mSceneMgr->createEntity("ground");
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);

	groundEntity->setMaterialName("Examples/Rockwall");
	groundEntity->setCastShadows(false);
}

void TestApplication::createLight()
{
	mSceneMgr->setAmbientLight(Ogre::ColourValue::White);
	mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

	// Directional light
	Ogre::Light* directionalLight = mSceneMgr->createLight("DirectionalLight");
	directionalLight->setType(Ogre::Light::LT_DIRECTIONAL);

	directionalLight->setDiffuseColour(Ogre::ColourValue(.3, .3, .3));
	directionalLight->setSpecularColour(Ogre::ColourValue(.3, .3, .3));

	directionalLight->setDirection(Ogre::Vector3(0, -1, 1));
}

void TestApplication::createSphere()
{
	Ogre::Entity *sphereEntity = mSceneMgr->createEntity("Sphere", "sphere.mesh");
	ballNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 100, 0));
	ballNode->attachObject(sphereEntity);
}

bool iDown = false;
bool jDown = false;
bool kDown = false;
bool lDown = false;

bool TestApplication::keyPressed(const OIS::KeyEvent& ke)
{
	switch (ke.key)
	{
		case OIS::KC_I:
			iDown = true;
			break;
		case OIS::KC_J:
			jDown = true;
			break;
		case OIS::KC_K:
			kDown = true;
			break;
		case OIS::KC_L:
			lDown = true;
			break;
		default:
			break;
	}
	return BaseApplication::keyPressed(ke);
}

bool TestApplication::keyReleased(const OIS::KeyEvent& ke)
{
	switch (ke.key)
	{
	case OIS::KC_I:
		iDown = false;
		break;
	case OIS::KC_J:
		jDown = false;
		break;
	case OIS::KC_K:
		kDown = false;
		break;
	case OIS::KC_L:
		lDown = false;
		break;
	default:
		break;
	}

	return BaseApplication::keyReleased(ke);
}

bool TestApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	Ogre::Vector3 movePos = Ogre::Vector3(0, 0, 0);
	if (iDown)
	{
		movePos.z = -0.1f;
	}
	if (jDown)
	{
		movePos.x = -0.1f;
	}
	if (kDown)
	{
		movePos.z = 0.1f;
	}
	if (lDown)
	{
		movePos.x = 0.1f;
	}

	Ogre::Vector3 currPos = ballNode->getPosition();

	Ogre::Vector3 newPos = currPos + movePos;
	ballNode->setPosition(newPos);

	return BaseApplication::frameRenderingQueued(evt);
}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
	int main(int argc, char *argv[])
#endif
	{
		// Create application object
		TestApplication app;

		try {
			app.go();
		}
		catch (Ogre::Exception& e) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
			std::cerr << "An exception has occured: " <<
				e.getFullDescription().c_str() << std::endl;
#endif
		}

		return 0;
	}

#ifdef __cplusplus
}
#endif<commit_msg>Make movement speed constant, not fps dependant<commit_after>#include "TestApplication.h"
const float moveSpeed = 100;

TestApplication::TestApplication(void)
{
}

TestApplication::~TestApplication(void)
{
}

void TestApplication::createCamera()
{
	mCamera = mSceneMgr->createCamera("PlayerCam");

	mCamera->setPosition(Ogre::Vector3(0, 300, 500));
	mCamera->lookAt(Ogre::Vector3(0, 0, 0));
	mCamera->setNearClipDistance(5);

	mCameraMan = new OgreBites::SdkCameraMan(mCamera);
}

void TestApplication::createViewports()
{
	Ogre::Viewport* vp = mWindow->addViewport(mCamera);

	vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

	mCamera->setAspectRatio(
		Ogre::Real(vp->getActualWidth()) /
		Ogre::Real(vp->getActualHeight()));

}

void TestApplication::createScene()
{
	createLight();
	createPlane();
	createSphere();
}

void TestApplication::createPlane()
{
	// Create ground
	Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);

	Ogre::MeshManager::getSingleton().createPlane(
		"ground",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
		plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);

	Ogre::Entity* groundEntity = mSceneMgr->createEntity("ground");
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);

	groundEntity->setMaterialName("Examples/Rockwall");
	groundEntity->setCastShadows(false);
}

void TestApplication::createLight()
{
	mSceneMgr->setAmbientLight(Ogre::ColourValue::White);
	mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

	// Directional light
	Ogre::Light* directionalLight = mSceneMgr->createLight("DirectionalLight");
	directionalLight->setType(Ogre::Light::LT_DIRECTIONAL);

	directionalLight->setDiffuseColour(Ogre::ColourValue(.3, .3, .3));
	directionalLight->setSpecularColour(Ogre::ColourValue(.3, .3, .3));

	directionalLight->setDirection(Ogre::Vector3(0, -1, 1));
}

void TestApplication::createSphere()
{
	Ogre::Entity *sphereEntity = mSceneMgr->createEntity("Sphere", "sphere.mesh");
	ballNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 100, 0));
	ballNode->attachObject(sphereEntity);
}

bool iDown = false;
bool jDown = false;
bool kDown = false;
bool lDown = false;

bool TestApplication::keyPressed(const OIS::KeyEvent& ke)
{
	switch (ke.key)
	{
		case OIS::KC_I:
			iDown = true;
			break;
		case OIS::KC_J:
			jDown = true;
			break;
		case OIS::KC_K:
			kDown = true;
			break;
		case OIS::KC_L:
			lDown = true;
			break;
		default:
			break;
	}
	return BaseApplication::keyPressed(ke);
}

bool TestApplication::keyReleased(const OIS::KeyEvent& ke)
{
	switch (ke.key)
	{
	case OIS::KC_I:
		iDown = false;
		break;
	case OIS::KC_J:
		jDown = false;
		break;
	case OIS::KC_K:
		kDown = false;
		break;
	case OIS::KC_L:
		lDown = false;
		break;
	default:
		break;
	}

	return BaseApplication::keyReleased(ke);
}

bool TestApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	Ogre::Vector3 movePos = Ogre::Vector3(0, 0, 0);
	if (iDown)
	{
		movePos.z = -moveSpeed;
	}
	if (jDown)
	{
		movePos.x = -moveSpeed;
	}
	if (kDown)
	{
		movePos.z = moveSpeed;
	}
	if (lDown)
	{
		movePos.x = moveSpeed;
	}

	ballNode->translate(movePos * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
	// Ogre::Vector3 currPos = ballNode->getPosition();

	// Ogre::Vector3 newPos = currPos + movePos;
	// ballNode->setPosition(newPos);

	return BaseApplication::frameRenderingQueued(evt);
}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
	int main(int argc, char *argv[])
#endif
	{
		// Create application object
		TestApplication app;

		try {
			app.go();
		}
		catch (Ogre::Exception& e) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
			std::cerr << "An exception has occured: " <<
				e.getFullDescription().c_str() << std::endl;
#endif
		}

		return 0;
	}

#ifdef __cplusplus
}
#endif<|endoftext|>


<commit_before>// Copyright the project authors as listed in the AUTHORS file.
// All rights reserved. Use of this source code is governed by the
// license that can be found in the LICENSE file.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
//#include <OneWire.h>
#include <HX711.h>

// device specifics
#include "WirelessConfig.h"
#include "MqttScale.h"

#define TRANSMIT_INTERVAL_SECONDS 5
#define MILLIS_IN_SECOND 1000
#define LOOP_DELAY 100

#define MAX_MESSAGE_SIZE 100

HX711 scale;

void callback(char* topic, uint8_t* message, unsigned int length) {
  if (strcmp(topic, SCALE_TARE_TOPIC) == 0) {
    scale.tare();
  }
}

ESP8266WiFiGenericClass wifi;

#ifdef USE_CERTS
// if certs are used the following must be defined in WirelessConfig.h
//    unsigned char client_cert[] PROGMEM = {bytes in DER format};
//    unsigned int client_cert_len = 918;
//    unsigned char client_key[] PROGMEM = {bytes in DER format};
//    unsigned int client_key_len = 1193;
//
//    conversion can be done using
//    openssl x509 -in cert -out client.cert -outform DER
//    openssl rsa -in key -out client.key -outform DER
//    and then using xxd to generate the required array and lengths
//    see https://nofurtherquestions.wordpress.com/2016/03/14/making-an-esp8266-web-accessible/
//    for more detailed info
WiFiClientSecure wclient;
#else
WiFiClient wclient;
#endif

PubSubClient client(mqttServerString, mqttServerPort, callback, wclient);

int counter = 0;
char macAddress[] = "00:00:00:00:00:00";

// scale parameters
int SCALE_DOUT = D2;
int SCALE_SCK = D3;
int SCALE_READINGS = 20;
int BUTTON_PIN = D5;
unsigned int MIN_BUTTON_TIME_MICROS = 250000;

ICACHE_RAM_ATTR void handleButton() {
  static unsigned long lastInterruptTime = 0;

  long timeMicros = micros();
  if (digitalRead(BUTTON_PIN) == LOW) {
    // get the duration of the button press and only accept as button
    // press if it is long enough that we know it is not noise.
    unsigned long duration = timeMicros - lastInterruptTime;
    if (duration > MIN_BUTTON_TIME_MICROS) {
      scale.tare();
    }
  }

  lastInterruptTime = timeMicros;
}

void setup() {
  delay(1000);

  // Setup console
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println("Started");

  // setup the scale
  scale.begin(SCALE_DOUT, SCALE_SCK);
  scale.set_scale(SCALE_MULTIPLIER);
  scale.set_offset(0);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN),&handleButton,CHANGE);

#ifdef USE_CERTS
  wclient.setCertificate_P(client_cert, client_cert_len);
  wclient.setPrivateKey_P(client_key, client_key_len);
#endif

  // turn of the Access Point as we are not using it
  wifi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  // get the mac address to be used as a unique id for connecting to the mqtt server
  byte macRaw[6];
  WiFi.macAddress(macRaw);
  sprintf(macAddress,
          "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
          macRaw[0],
          macRaw[1],
          macRaw[2],
          macRaw[3],
          macRaw[4],
          macRaw[5]);
}

void loop() {
  client.loop();
  delay(LOOP_DELAY);

  // make sure we are good for wifi
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.reconnect();

    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
      Serial.println("Failed to reconnect WIFI");
      Serial.println(WiFi.waitForConnectResult());
      delay(1000);
      return;
    }
  }

  if (!client.connected()) {
    if (client.connect(macAddress)) {
      Serial.println("mqtt connected:");
      Serial.println(macAddress);
      Serial.println("\n");
      client.subscribe(SCALE_TARE_TOPIC);
    }
    scale.tare();
  }

  counter++;
  if (counter == (TRANSMIT_INTERVAL_SECONDS * (MILLIS_IN_SECOND/LOOP_DELAY))) {
    Serial.println("Sending");

    char tempMessage[MAX_MESSAGE_SIZE];
    char floatBuffer[10];
    Serial.println(scale.get_units(SCALE_READINGS), 2);
    float currentWeight = scale.get_units(SCALE_READINGS);
    snprintf(tempMessage, MAX_MESSAGE_SIZE, "%s",
             dtostrf(currentWeight, 4, 2, floatBuffer));
    client.publish(SCALE_TOPIC, tempMessage);

    counter = 0;
  }
}<commit_msg>src: round to nearest g<commit_after>// Copyright the project authors as listed in the AUTHORS file.
// All rights reserved. Use of this source code is governed by the
// license that can be found in the LICENSE file.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
//#include <OneWire.h>
#include <HX711.h>

// device specifics
#include "WirelessConfig.h"
#include "MqttScale.h"

#define TRANSMIT_INTERVAL_SECONDS 5
#define MILLIS_IN_SECOND 1000
#define LOOP_DELAY 100

#define MAX_MESSAGE_SIZE 100

HX711 scale;

void callback(char* topic, uint8_t* message, unsigned int length) {
  if (strcmp(topic, SCALE_TARE_TOPIC) == 0) {
    scale.tare();
  }
}

ESP8266WiFiGenericClass wifi;

#ifdef USE_CERTS
// if certs are used the following must be defined in WirelessConfig.h
//    unsigned char client_cert[] PROGMEM = {bytes in DER format};
//    unsigned int client_cert_len = 918;
//    unsigned char client_key[] PROGMEM = {bytes in DER format};
//    unsigned int client_key_len = 1193;
//
//    conversion can be done using
//    openssl x509 -in cert -out client.cert -outform DER
//    openssl rsa -in key -out client.key -outform DER
//    and then using xxd to generate the required array and lengths
//    see https://nofurtherquestions.wordpress.com/2016/03/14/making-an-esp8266-web-accessible/
//    for more detailed info
WiFiClientSecure wclient;
#else
WiFiClient wclient;
#endif

PubSubClient client(mqttServerString, mqttServerPort, callback, wclient);

int counter = 0;
char macAddress[] = "00:00:00:00:00:00";

// scale parameters
int SCALE_DOUT = D2;
int SCALE_SCK = D3;
int SCALE_READINGS = 20;
int BUTTON_PIN = D5;
unsigned int MIN_BUTTON_TIME_MICROS = 250000;

ICACHE_RAM_ATTR void handleButton() {
  static unsigned long lastInterruptTime = 0;

  long timeMicros = micros();
  if (digitalRead(BUTTON_PIN) == LOW) {
    // get the duration of the button press and only accept as button
    // press if it is long enough that we know it is not noise.
    unsigned long duration = timeMicros - lastInterruptTime;
    if (duration > MIN_BUTTON_TIME_MICROS) {
      scale.tare();
    }
  }

  lastInterruptTime = timeMicros;
}

void setup() {
  delay(1000);

  // Setup console
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println("Started");

  // setup the scale
  scale.begin(SCALE_DOUT, SCALE_SCK);
  scale.set_scale(SCALE_MULTIPLIER);
  scale.set_offset(0);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(BUTTON_PIN),&handleButton,CHANGE);

#ifdef USE_CERTS
  wclient.setCertificate_P(client_cert, client_cert_len);
  wclient.setPrivateKey_P(client_key, client_key_len);
#endif

  // turn of the Access Point as we are not using it
  wifi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  // get the mac address to be used as a unique id for connecting to the mqtt server
  byte macRaw[6];
  WiFi.macAddress(macRaw);
  sprintf(macAddress,
          "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
          macRaw[0],
          macRaw[1],
          macRaw[2],
          macRaw[3],
          macRaw[4],
          macRaw[5]);
}

void loop() {
  client.loop();
  delay(LOOP_DELAY);

  // make sure we are good for wifi
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.reconnect();

    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
      Serial.println("Failed to reconnect WIFI");
      Serial.println(WiFi.waitForConnectResult());
      delay(1000);
      return;
    }
  }

  if (!client.connected()) {
    if (client.connect(macAddress)) {
      Serial.println("mqtt connected:");
      Serial.println(macAddress);
      Serial.println("\n");
      client.subscribe(SCALE_TARE_TOPIC);
    }
    scale.tare();
  }

  counter++;
  if (counter == (TRANSMIT_INTERVAL_SECONDS * (MILLIS_IN_SECOND/LOOP_DELAY))) {
    Serial.println("Sending");

    char tempMessage[MAX_MESSAGE_SIZE];
    char floatBuffer[10];
    Serial.println(scale.get_units(SCALE_READINGS), 2);
    float currentWeight = round(scale.get_units(SCALE_READINGS));
    snprintf(tempMessage, MAX_MESSAGE_SIZE, "%s",
             dtostrf(currentWeight, 4, 0, floatBuffer));
    client.publish(SCALE_TOPIC, tempMessage);

    counter = 0;
  }
}<|endoftext|>


<commit_before>#ifndef PILA_MAX
#define PILA_MAX

#include "vector_dinamico.hpp"

template <class T>
class PilaMax{
  private:
    struct Elemento{
      T elem;
      T max;

      Elemento(){}
      Elemento(T e, T m): elem(e), max(m){}
    };

    VectorDinamico<Elemento> datos;

  public:
    /*
    Constructores, destructores y op asignacion
     */
    PilaMax<T>(){}
    PilaMax<T>(const PilaMax<T>& p):datos(p.datos){}
    //~PilaMax<T>();
    PilaMax<T>& operator=(const PilaMax<T>& p){datos = p.datos;}

    /*
    Metodos propios de una pila
     */

    bool vacia() const{return datos.vacia();}
    void poner(const T& t_elem);
    void quitar(){datos.popback();}
    T tope() const{return datos.getLast().elem;}
    T max() const{return datos.getLast().max;}
};

#include "../src/Pila_max_VD.cpp"

#endif
<commit_msg>Update Pila_max_VD.hpp<commit_after>/**
  * @file Pila_max_VD.h
  * @brief Fichero cabecera del TDA Pila_max_VD
  *
  */#ifndef PILA_MAX
#define PILA_MAX

#include "vector_dinamico.hpp"
/**
  *  @brief T.D.A. Pila_mx_VD
  *
  * Una instancia @e c del tipo de datos abstracto @c Pila_max_VD es un objeto
  * para agrupar datos de tipo Elemento en una Pila, compuesto Elemento por dos
  * objetos: elem y max,ambos de tipo T. La clase está compuesta por uN vector dinamico
  * de Elementos.
  *
  * @author J. Capote, G. Galindo y C. de la Torre
  * @date Noviembre 2016
  */
template <class T>
class PilaMax{
  private:
   /**
    * @page repConjunto Rep del TDA Pila_max_VD
    *
    * @section faConjunto Funci�n de abstracci�n
    *
    * Un objeto v�lido @e rep del TDA Pila_max_VD representa
    *
    * A un conjunto de Elementos agrupados en una vector dinamico
    *
    */
    struct Elemento{
      T elem;
      T max;
    /**
     * @brief Constructor por defecto de Elemento. Crea el elemento
     * con elem=0 y max=0.
     */
      Elemento(){}
      /**
       * @brief Constructor de Elemento. Crea el elemento con elem=e y
       * max=m.
       * @param e dato de tipo T que da el valor de elem
       * @param m dato de tipo T que da el valor de max
       */
      Elemento(T e, T m): elem(e), max(m){}
    };/**< Elemento */

    VectorDinamico<Elemento> datos;/** vectos dinamico de Elementos */

  public:
   /**
    * @brief Constructor por defecto de la clase. Crea el vectordinamico vacío.
    */
    PilaMax<T>(){}
    /**
    * @brief Constructor copia de la clase.
    * @param p objeto a copiar
    */
    PilaMax<T>(const PilaMax<T>& p):datos(p.datos){}
  /**
    * @brief Operador de asignacion.
    * @param p objeto a asignar.
    */
    PilaMax<T>& operator=(const PilaMax<T>& p){datos = p.datos;}
   /**
     * @brief Comprueba si la pila está vacía
     * @return bool verdadero si está vacía y falso si no lo está.
     */
    bool vacia() const{return datos.vacia();}
   /**
     * @brief Añade un nuevo elemento al vector dinamico de la pila
     * @param t_elem valor del nuevo elemento a añadir
     */
    void poner(const T& t_elem);
  /**
     * @brief Elimina el útimo elemento de la pila
     */
    void quitar(){datos.popback();}
  /**
     * @brief Devolver el tope de la pila
     * @return devuelve el valor del último elemento introducido en la pila
     */
    T tope() const{return datos.getLast().elem;}
   /**
     * @brief Devolver el valor maximo de los elementos de la pila
     * @return devuelve el valor del maximo elemento de toda la pila
     */
    T max() const{return datos.getLast().max;}
};

#include "../src/Pila_max_VD.cpp"

#endif
<|endoftext|>


<commit_before><commit_msg>File should not have been committed<commit_after><|endoftext|>


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

#include <string.h>

#include "native_client/src/include/nacl_macros.h"
#include "native_client/src/shared/ppapi_proxy/browser_callback.h"
#include "native_client/src/shared/ppapi_proxy/browser_globals.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "native_client/src/third_party/ppapi/c/pp_file_info.h"
#include "native_client/src/third_party/ppapi/c/pp_completion_callback.h"
#include "native_client/src/third_party/ppapi/c/pp_errors.h"
#include "native_client/src/third_party/ppapi/c/ppb_file_io.h"
#include "srpcgen/ppb_rpc.h"

using ppapi_proxy::DebugPrintf;
using ppapi_proxy::DeleteRemoteCallbackInfo;
using ppapi_proxy::MakeRemoteCompletionCallback;
using ppapi_proxy::PPBFileIOInterface;

void PpbFileIORpcServer::PPB_FileIO_Create(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      // input
      PP_Instance instance,
      // output
      PP_Resource* resource) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;

  *resource = PPBFileIOInterface()->Create(instance);
  DebugPrintf("PPB_FileIO::Create: resource=%"NACL_PRIu32"\n", *resource);
}

// TODO(sanga): Use a caching resource tracker instead of going over the proxy
// to determine if the given resource is a file io.
void PpbFileIORpcServer::PPB_FileIO_IsFileIO(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    // inputs
    PP_Resource resource,
    // output
    int32_t* success) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;

  PP_Bool pp_success = PPBFileIOInterface()->IsFileIO(resource);
  DebugPrintf("PPB_FileIO::IsFileIO: pp_success=%d\n", pp_success);

  *success = (pp_success == PP_TRUE);
}

void PpbFileIORpcServer::PPB_FileIO_Open(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    // inputs
    PP_Resource file_io,
    PP_Resource file_ref,
    int32_t open_flags,
    int32_t callback_id,
    // output
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Open(
      file_io,
      file_ref,
      open_flags,
      remote_callback);
  DebugPrintf("PPB_FileIO::Open: pp_error=%"NACL_PRId32"\n", *pp_error);

  if (*pp_error != PP_OK_COMPLETIONPENDING)  // Async error.
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

namespace {

bool IsResultPP_OK(int32_t result) {
  return (result == PP_OK);
}

nacl_abi_size_t SizeOfPP_FileInfo(int32_t /*query_callback_result*/) {
  return sizeof(PP_FileInfo);
}

}  // namespace

void PpbFileIORpcServer::PPB_FileIO_Query(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      PP_Resource file_io,
      int32_t bytes_to_read,
      int32_t callback_id,
      nacl_abi_size_t* info_bytes, char* info,
      int32_t* pp_error) {
  // Since PPB_FileIO::Query does not complete synchronously, and we use remote
  // completion callback with completion callback table on the untrusted side
  // (see browser_callback.h and plugin_callback.h), so the actual file info
  // parameter is not used.
  UNREFERENCED_PARAMETER(info);

  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  // TODO(sanga): Drop bytes_to_read for parameters since it is not part of the
  // interface, and just use the buffer size itself.
  CHECK(bytes_to_read == sizeof(PP_FileInfo));
  char* callback_buffer = NULL;
  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read,
                                   &callback_buffer, IsResultPP_OK,
                                   SizeOfPP_FileInfo);
  if (NULL == remote_callback.func)
    return;

  // callback_buffer has been assigned to a buffer on the heap, the size
  // of PP_FileInfo.
  PP_FileInfo* file_info = reinterpret_cast<PP_FileInfo*>(callback_buffer);
  *pp_error = PPBFileIOInterface()->Query(file_io, file_info, remote_callback);
  DebugPrintf("PPB_FileIO::Query: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Query should not complete synchronously

  *info_bytes = 0;
  if (*pp_error != PP_OK_COMPLETIONPENDING) {
    DeleteRemoteCallbackInfo(remote_callback);
  }
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Touch(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    double last_access_time,
    double last_modified_time,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel,
      callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Touch(file_io, last_access_time,
                                          last_modified_time, remote_callback);
  DebugPrintf("PPB_FileIO::Touch: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Touch should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Read(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      // inputs
      PP_Resource file_io,
      int64_t offset,
      int32_t bytes_to_read,
      int32_t callback_id,
      // outputs
      nacl_abi_size_t* buffer_size,
      char* buffer,
      int32_t* pp_error_or_bytes) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;
  CHECK(*buffer_size == static_cast<nacl_abi_size_t>(bytes_to_read));

  char* callback_buffer = NULL;
  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read,
                                   &callback_buffer);
  if (NULL == remote_callback.func)
    return;

  *pp_error_or_bytes = PPBFileIOInterface()->Read(
      file_io,
      offset,
      callback_buffer,
      bytes_to_read,
      remote_callback);
  DebugPrintf("PPB_FileIO::Read: pp_error_or_bytes=%"NACL_PRId32"\n",
              *pp_error_or_bytes);
  CHECK(*pp_error_or_bytes <= bytes_to_read);

  if (*pp_error_or_bytes > 0) {  // Bytes read into |callback_buffer|.
    // No callback scheduled.
    *buffer_size = static_cast<nacl_abi_size_t>(*pp_error_or_bytes);
    memcpy(buffer, callback_buffer, *buffer_size);
    DeleteRemoteCallbackInfo(remote_callback);
  } else if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) {  // Async error.
    // No callback scheduled.
    *buffer_size = 0;
    DeleteRemoteCallbackInfo(remote_callback);
  } else {
    // Callback scheduled.
    *buffer_size = 0;
  }

  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Write(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int64_t offset,
    nacl_abi_size_t buffer_bytes, char* buffer,
    int32_t bytes_to_write,
    int32_t callback_id,
    int32_t* pp_error_or_bytes) {
  // TODO(sanga): Add comments for the parameters.
  UNREFERENCED_PARAMETER(buffer_bytes);

  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error_or_bytes = PPBFileIOInterface()->Write(file_io, offset, buffer,
                                                   bytes_to_write,
                                                   remote_callback);
  DebugPrintf("PPB_FileIO::Write: pp_error_or_bytes=%"NACL_PRId32"\n",
              *pp_error_or_bytes);

  // Bytes must be written asynchronously.
  if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) {
    DeleteRemoteCallbackInfo(remote_callback);
  }
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_SetLength(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int64_t length,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->SetLength(file_io, length, remote_callback);
  DebugPrintf("PPB_FileIO::SetLength: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // SetLength should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Flush(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Flush(file_io, remote_callback);
  DebugPrintf("PPB_FileIO::Flush: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Flush should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Close(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;
  DebugPrintf("PPB_FileIO::Close: file_io=%"NACL_PRIu32"\n", file_io);
  PPBFileIOInterface()->Close(file_io);
}
<commit_msg>Adding a check for the number of bytes to write against the buffer size for PPB_FileIO_Write.<commit_after>// Copyright (c) 2011 The Native Client Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string.h>
#include <limits>

#include "native_client/src/include/nacl_macros.h"
#include "native_client/src/shared/ppapi_proxy/browser_callback.h"
#include "native_client/src/shared/ppapi_proxy/browser_globals.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "native_client/src/third_party/ppapi/c/pp_file_info.h"
#include "native_client/src/third_party/ppapi/c/pp_completion_callback.h"
#include "native_client/src/third_party/ppapi/c/pp_errors.h"
#include "native_client/src/third_party/ppapi/c/ppb_file_io.h"
#include "srpcgen/ppb_rpc.h"

using ppapi_proxy::DebugPrintf;
using ppapi_proxy::DeleteRemoteCallbackInfo;
using ppapi_proxy::MakeRemoteCompletionCallback;
using ppapi_proxy::PPBFileIOInterface;

void PpbFileIORpcServer::PPB_FileIO_Create(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      // input
      PP_Instance instance,
      // output
      PP_Resource* resource) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;

  *resource = PPBFileIOInterface()->Create(instance);
  DebugPrintf("PPB_FileIO::Create: resource=%"NACL_PRIu32"\n", *resource);
}

// TODO(sanga): Use a caching resource tracker instead of going over the proxy
// to determine if the given resource is a file io.
void PpbFileIORpcServer::PPB_FileIO_IsFileIO(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    // inputs
    PP_Resource resource,
    // output
    int32_t* success) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;

  PP_Bool pp_success = PPBFileIOInterface()->IsFileIO(resource);
  DebugPrintf("PPB_FileIO::IsFileIO: pp_success=%d\n", pp_success);

  *success = (pp_success == PP_TRUE);
}

void PpbFileIORpcServer::PPB_FileIO_Open(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    // inputs
    PP_Resource file_io,
    PP_Resource file_ref,
    int32_t open_flags,
    int32_t callback_id,
    // output
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Open(
      file_io,
      file_ref,
      open_flags,
      remote_callback);
  DebugPrintf("PPB_FileIO::Open: pp_error=%"NACL_PRId32"\n", *pp_error);

  if (*pp_error != PP_OK_COMPLETIONPENDING)  // Async error.
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

namespace {

bool IsResultPP_OK(int32_t result) {
  return (result == PP_OK);
}

nacl_abi_size_t SizeOfPP_FileInfo(int32_t /*query_callback_result*/) {
  return sizeof(PP_FileInfo);
}

}  // namespace

void PpbFileIORpcServer::PPB_FileIO_Query(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      PP_Resource file_io,
      int32_t bytes_to_read,
      int32_t callback_id,
      nacl_abi_size_t* info_bytes, char* info,
      int32_t* pp_error) {
  // Since PPB_FileIO::Query does not complete synchronously, and we use remote
  // completion callback with completion callback table on the untrusted side
  // (see browser_callback.h and plugin_callback.h), so the actual file info
  // parameter is not used.
  UNREFERENCED_PARAMETER(info);

  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  // TODO(sanga): Drop bytes_to_read for parameters since it is not part of the
  // interface, and just use the buffer size itself.
  CHECK(bytes_to_read == sizeof(PP_FileInfo));
  char* callback_buffer = NULL;
  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read,
                                   &callback_buffer, IsResultPP_OK,
                                   SizeOfPP_FileInfo);
  if (NULL == remote_callback.func)
    return;

  // callback_buffer has been assigned to a buffer on the heap, the size
  // of PP_FileInfo.
  PP_FileInfo* file_info = reinterpret_cast<PP_FileInfo*>(callback_buffer);
  *pp_error = PPBFileIOInterface()->Query(file_io, file_info, remote_callback);
  DebugPrintf("PPB_FileIO::Query: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Query should not complete synchronously

  *info_bytes = 0;
  if (*pp_error != PP_OK_COMPLETIONPENDING) {
    DeleteRemoteCallbackInfo(remote_callback);
  }
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Touch(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    double last_access_time,
    double last_modified_time,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel,
      callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Touch(file_io, last_access_time,
                                          last_modified_time, remote_callback);
  DebugPrintf("PPB_FileIO::Touch: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Touch should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Read(
      NaClSrpcRpc* rpc,
      NaClSrpcClosure* done,
      // inputs
      PP_Resource file_io,
      int64_t offset,
      int32_t bytes_to_read,
      int32_t callback_id,
      // outputs
      nacl_abi_size_t* buffer_size,
      char* buffer,
      int32_t* pp_error_or_bytes) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;
  CHECK(*buffer_size == static_cast<nacl_abi_size_t>(bytes_to_read));

  char* callback_buffer = NULL;
  PP_CompletionCallback remote_callback =
      MakeRemoteCompletionCallback(rpc->channel, callback_id, bytes_to_read,
                                   &callback_buffer);
  if (NULL == remote_callback.func)
    return;

  *pp_error_or_bytes = PPBFileIOInterface()->Read(
      file_io,
      offset,
      callback_buffer,
      bytes_to_read,
      remote_callback);
  DebugPrintf("PPB_FileIO::Read: pp_error_or_bytes=%"NACL_PRId32"\n",
              *pp_error_or_bytes);
  CHECK(*pp_error_or_bytes <= bytes_to_read);

  if (*pp_error_or_bytes > 0) {  // Bytes read into |callback_buffer|.
    // No callback scheduled.
    *buffer_size = static_cast<nacl_abi_size_t>(*pp_error_or_bytes);
    memcpy(buffer, callback_buffer, *buffer_size);
    DeleteRemoteCallbackInfo(remote_callback);
  } else if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) {  // Async error.
    // No callback scheduled.
    *buffer_size = 0;
    DeleteRemoteCallbackInfo(remote_callback);
  } else {
    // Callback scheduled.
    *buffer_size = 0;
  }

  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Write(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int64_t offset,
    nacl_abi_size_t buffer_bytes, char* buffer,
    int32_t bytes_to_write,
    int32_t callback_id,
    int32_t* pp_error_or_bytes) {
  // TODO(sanga): Add comments for the parameters.

  CHECK(buffer_bytes <=
        static_cast<nacl_abi_size_t>(std::numeric_limits<int32_t>::max()));
  CHECK(static_cast<nacl_abi_size_t>(bytes_to_write) <= buffer_bytes);

  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error_or_bytes = PPBFileIOInterface()->Write(file_io, offset, buffer,
                                                   bytes_to_write,
                                                   remote_callback);
  DebugPrintf("PPB_FileIO::Write: pp_error_or_bytes=%"NACL_PRId32"\n",
              *pp_error_or_bytes);

  // Bytes must be written asynchronously.
  if (*pp_error_or_bytes != PP_OK_COMPLETIONPENDING) {
    DeleteRemoteCallbackInfo(remote_callback);
  }
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_SetLength(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int64_t length,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->SetLength(file_io, length, remote_callback);
  DebugPrintf("PPB_FileIO::SetLength: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // SetLength should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Flush(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io,
    int32_t callback_id,
    int32_t* pp_error) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_APP_ERROR;

  PP_CompletionCallback remote_callback = MakeRemoteCompletionCallback(
      rpc->channel, callback_id);
  if (NULL == remote_callback.func)
    return;

  *pp_error = PPBFileIOInterface()->Flush(file_io, remote_callback);
  DebugPrintf("PPB_FileIO::Flush: pp_error=%"NACL_PRId32"\n", *pp_error);
  CHECK(*pp_error != PP_OK);  // Flush should not complete synchronously

  if (*pp_error != PP_OK_COMPLETIONPENDING)
    DeleteRemoteCallbackInfo(remote_callback);
  rpc->result = NACL_SRPC_RESULT_OK;
}

void PpbFileIORpcServer::PPB_FileIO_Close(
    NaClSrpcRpc* rpc,
    NaClSrpcClosure* done,
    PP_Resource file_io) {
  NaClSrpcClosureRunner runner(done);
  rpc->result = NACL_SRPC_RESULT_OK;
  DebugPrintf("PPB_FileIO::Close: file_io=%"NACL_PRIu32"\n", file_io);
  PPBFileIOInterface()->Close(file_io);
}
<|endoftext|>


<commit_before>/*
 * GLGraphicsPSO.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015-2019 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "GLGraphicsPSO.h"
#include "GLRenderPass.h"
#include "GLStatePool.h"
#include "../Ext/GLExtensions.h"
#include "../Shader/GLShaderProgram.h"
#include "../GLTypes.h"
#include "../GLCore.h"
#include "../../CheckedCast.h"
#include "../../../Core/Helper.h"
#include "../../../Core/ByteBufferIterator.h"
#include <LLGL/PipelineStateFlags.h>
#include <LLGL/StaticLimits.h>

namespace LLGL
{

GLGraphicsPSO::GLGraphicsPSO(const GraphicsPipelineDescriptor& desc, const RenderingLimits& limits) :
    GLPipelineState { true, desc.pipelineLayout, desc.shaderProgram }
{
    /* Convert input-assembler state */
    drawMode_       = GLTypes::ToDrawMode(desc.primitiveTopology);
    primitiveMode_  = GLTypes::ToPrimitiveMode(desc.primitiveTopology);

    if (IsPrimitiveTopologyPatches(desc.primitiveTopology))
    {
        /* Store patch vertices and check limit */
        const auto patchSize = GetPrimitiveTopologyPatchSize(desc.primitiveTopology);
        if (patchSize > limits.maxPatchVertices)
        {
            throw std::runtime_error(
                "renderer does not support " + std::to_string(patchVertices_) +
                " control points for patches (limit is " + std::to_string(limits.maxPatchVertices) + ")"
            );
        }
        else
            patchVertices_ = static_cast<GLint>(patchSize);
    }
    else
        patchVertices_ = 0;

    /* Create depth-stencil state */
    depthStencilState_ = GLStatePool::Get().CreateDepthStencilState(desc.depth, desc.stencil);

    /* Create rasterizer state */
    rasterizerState_ = GLStatePool::Get().CreateRasterizerState(desc.rasterizer);

    /* Create blend state */
    if (auto renderPass = desc.renderPass)
    {
        auto renderPassGL = LLGL_CAST(const GLRenderPass*, renderPass);
        blendState_ = GLStatePool::Get().CreateBlendState(desc.blend, renderPassGL->GetNumColorAttachments());
    }
    else
        blendState_ = GLStatePool::Get().CreateBlendState(desc.blend, 1);

    /* Build static state buffer for viewports and scissors */
    if (!desc.viewports.empty() || !desc.scissors.empty())
        BuildStaticStateBuffer(desc);
}

GLGraphicsPSO::~GLGraphicsPSO()
{
    GLStatePool::Get().ReleaseDepthStencilState(std::move(depthStencilState_));
    GLStatePool::Get().ReleaseRasterizerState(std::move(rasterizerState_));
    GLStatePool::Get().ReleaseBlendState(std::move(blendState_));
}

void GLGraphicsPSO::Bind(GLStateManager& stateMngr)
{
    /* Bind shader program and binding layout from base class */
    GLPipelineState::Bind(stateMngr);

    /* Set input-assembler state */
    if (patchVertices_ > 0)
        stateMngr.SetPatchVertices(patchVertices_);

    /* Bind depth-stencil, rasterizer, and blend states */
    stateMngr.BindDepthStencilState(depthStencilState_.get());
    stateMngr.BindRasterizerState(rasterizerState_.get());
    stateMngr.BindBlendState(blendState_.get());

    /* Set static viewports and scissors */
    if (staticStateBuffer_)
    {
        ByteBufferIterator byteBufferIter { staticStateBuffer_.get() };
        if (numStaticViewports_ > 0)
            SetStaticViewports(stateMngr, byteBufferIter);
        if (numStaticScissors_ > 0)
            SetStaticScissors(stateMngr, byteBufferIter);
    }
}

/*
 * ======= Private: =======
 */

void GLGraphicsPSO::BuildStaticStateBuffer(const GraphicsPipelineDescriptor& desc)
{
    /* Allocate packed raw buffer */
    const std::size_t bufferSize =
    (
        desc.viewports.size() * (sizeof(GLViewport) + sizeof(GLDepthRange)) +
        desc.scissors.size()  * (sizeof(GLScissor))
    );
    staticStateBuffer_ = MakeUniqueArray<char>(bufferSize);

    ByteBufferIterator byteBufferIter { staticStateBuffer_.get() };

    /* Build static viewports in raw buffer */
    if (!desc.viewports.empty())
        BuildStaticViewports(desc.viewports.size(), desc.viewports.data(), byteBufferIter);

    /* Build static scissors in raw buffer */
    if (!desc.scissors.empty())
        BuildStaticScissors(desc.scissors.size(), desc.scissors.data(), byteBufferIter);
}

void GLGraphicsPSO::BuildStaticViewports(std::size_t numViewports, const Viewport* viewports, ByteBufferIterator& byteBufferIter)
{
    /* Store number of viewports and validate limit */
    numStaticViewports_ = static_cast<GLsizei>(numViewports);

    if (numStaticViewports_ > LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS)
    {
        throw std::invalid_argument(
            "too many viewports in graphics pipeline state (" + std::to_string(numStaticViewports_) +
            " specified, but limit is " + std::to_string(LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS) + ")"
        );
    }

    /* Build <GLViewport> entries */
    for (std::size_t i = 0; i < numViewports; ++i)
    {
        auto dst = byteBufferIter.Next<GLViewport>();
        {
            dst->x      = static_cast<GLfloat>(viewports[i].x);
            dst->y      = static_cast<GLfloat>(viewports[i].y);
            dst->width  = static_cast<GLfloat>(viewports[i].width);
            dst->height = static_cast<GLfloat>(viewports[i].height);
        }
    }

    /* Build <GLDepthRange> entries */
    for (std::size_t i = 0; i < numViewports; ++i)
    {
        auto dst = byteBufferIter.Next<GLDepthRange>();
        {
            dst->minDepth = static_cast<GLclamp_t>(viewports[i].minDepth);
            dst->maxDepth = static_cast<GLclamp_t>(viewports[i].maxDepth);
        }
    }
}

void GLGraphicsPSO::BuildStaticScissors(std::size_t numScissors, const Scissor* scissors, ByteBufferIterator& byteBufferIter)
{
    /* Store number of scissors and validate limit */
    numStaticScissors_ = static_cast<GLsizei>(numScissors);

    if (numStaticScissors_ > LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS)
    {
        throw std::invalid_argument(
            "too many scissors in graphics pipeline state (" + std::to_string(numStaticScissors_) +
            " specified, but limit is " + std::to_string(LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS) + ")"
        );
    }

    /* Build <GLScissor> entries */
    for (std::size_t i = 0; i < numScissors; ++i)
    {
        auto dst = byteBufferIter.Next<GLScissor>();
        {
            dst->x      = static_cast<GLint>(scissors[i].x);
            dst->y      = static_cast<GLint>(scissors[i].y);
            dst->width  = static_cast<GLsizei>(scissors[i].width);
            dst->height = static_cast<GLsizei>(scissors[i].height);
        }
    }
}

void GLGraphicsPSO::SetStaticViewports(GLStateManager& stateMngr, ByteBufferIterator& byteBufferIter)
{
    /* Copy viewports to intermediate array (must be adjusted when framebuffer is bound) */
    GLViewport intermediateViewports[LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS];
    ::memcpy(
        intermediateViewports,
        byteBufferIter.Next<GLViewport>(numStaticViewports_),
        numStaticViewports_ * sizeof(GLViewport)
    );
    stateMngr.SetViewportArray(0, numStaticViewports_, intermediateViewports);

    /* Set depth ranges */
    stateMngr.SetDepthRangeArray(0, numStaticViewports_, byteBufferIter.Next<GLDepthRange>(numStaticViewports_));
}

void GLGraphicsPSO::SetStaticScissors(GLStateManager& stateMngr, ByteBufferIterator& byteBufferIter)
{
    /* Copy scissors to intermediate array (must be adjusted when framebuffer is bound) */
    GLScissor intermediateScissors[LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS];
    ::memcpy(
        intermediateScissors,
        byteBufferIter.Next<GLScissor>(numStaticScissors_),
        numStaticScissors_ * sizeof(GLScissor)
    );
    stateMngr.SetScissorArray(0, numStaticScissors_, intermediateScissors);
}

} // /namespace LLGL

// ================================================================================
<commit_msg>Remove unnecessary copy of viewport and depth-range arrays in GL graphics PSO after viewport interface change.<commit_after>/*
 * GLGraphicsPSO.cpp
 *
 * This file is part of the "LLGL" project (Copyright (c) 2015-2019 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "GLGraphicsPSO.h"
#include "GLRenderPass.h"
#include "GLStatePool.h"
#include "../Ext/GLExtensions.h"
#include "../Shader/GLShaderProgram.h"
#include "../GLTypes.h"
#include "../GLCore.h"
#include "../../CheckedCast.h"
#include "../../../Core/Helper.h"
#include "../../../Core/ByteBufferIterator.h"
#include <LLGL/PipelineStateFlags.h>
#include <LLGL/StaticLimits.h>

namespace LLGL
{

GLGraphicsPSO::GLGraphicsPSO(const GraphicsPipelineDescriptor& desc, const RenderingLimits& limits) :
    GLPipelineState { true, desc.pipelineLayout, desc.shaderProgram }
{
    /* Convert input-assembler state */
    drawMode_       = GLTypes::ToDrawMode(desc.primitiveTopology);
    primitiveMode_  = GLTypes::ToPrimitiveMode(desc.primitiveTopology);

    if (IsPrimitiveTopologyPatches(desc.primitiveTopology))
    {
        /* Store patch vertices and check limit */
        const auto patchSize = GetPrimitiveTopologyPatchSize(desc.primitiveTopology);
        if (patchSize > limits.maxPatchVertices)
        {
            throw std::runtime_error(
                "renderer does not support " + std::to_string(patchVertices_) +
                " control points for patches (limit is " + std::to_string(limits.maxPatchVertices) + ")"
            );
        }
        else
            patchVertices_ = static_cast<GLint>(patchSize);
    }
    else
        patchVertices_ = 0;

    /* Create depth-stencil state */
    depthStencilState_ = GLStatePool::Get().CreateDepthStencilState(desc.depth, desc.stencil);

    /* Create rasterizer state */
    rasterizerState_ = GLStatePool::Get().CreateRasterizerState(desc.rasterizer);

    /* Create blend state */
    if (auto renderPass = desc.renderPass)
    {
        auto renderPassGL = LLGL_CAST(const GLRenderPass*, renderPass);
        blendState_ = GLStatePool::Get().CreateBlendState(desc.blend, renderPassGL->GetNumColorAttachments());
    }
    else
        blendState_ = GLStatePool::Get().CreateBlendState(desc.blend, 1);

    /* Build static state buffer for viewports and scissors */
    if (!desc.viewports.empty() || !desc.scissors.empty())
        BuildStaticStateBuffer(desc);
}

GLGraphicsPSO::~GLGraphicsPSO()
{
    GLStatePool::Get().ReleaseDepthStencilState(std::move(depthStencilState_));
    GLStatePool::Get().ReleaseRasterizerState(std::move(rasterizerState_));
    GLStatePool::Get().ReleaseBlendState(std::move(blendState_));
}

void GLGraphicsPSO::Bind(GLStateManager& stateMngr)
{
    /* Bind shader program and binding layout from base class */
    GLPipelineState::Bind(stateMngr);

    /* Set input-assembler state */
    if (patchVertices_ > 0)
        stateMngr.SetPatchVertices(patchVertices_);

    /* Bind depth-stencil, rasterizer, and blend states */
    stateMngr.BindDepthStencilState(depthStencilState_.get());
    stateMngr.BindRasterizerState(rasterizerState_.get());
    stateMngr.BindBlendState(blendState_.get());

    /* Set static viewports and scissors */
    if (staticStateBuffer_)
    {
        ByteBufferIterator byteBufferIter { staticStateBuffer_.get() };
        if (numStaticViewports_ > 0)
            SetStaticViewports(stateMngr, byteBufferIter);
        if (numStaticScissors_ > 0)
            SetStaticScissors(stateMngr, byteBufferIter);
    }
}

/*
 * ======= Private: =======
 */

void GLGraphicsPSO::BuildStaticStateBuffer(const GraphicsPipelineDescriptor& desc)
{
    /* Allocate packed raw buffer */
    const std::size_t bufferSize =
    (
        desc.viewports.size() * (sizeof(GLViewport) + sizeof(GLDepthRange)) +
        desc.scissors.size()  * (sizeof(GLScissor))
    );
    staticStateBuffer_ = MakeUniqueArray<char>(bufferSize);

    ByteBufferIterator byteBufferIter { staticStateBuffer_.get() };

    /* Build static viewports in raw buffer */
    if (!desc.viewports.empty())
        BuildStaticViewports(desc.viewports.size(), desc.viewports.data(), byteBufferIter);

    /* Build static scissors in raw buffer */
    if (!desc.scissors.empty())
        BuildStaticScissors(desc.scissors.size(), desc.scissors.data(), byteBufferIter);
}

void GLGraphicsPSO::BuildStaticViewports(std::size_t numViewports, const Viewport* viewports, ByteBufferIterator& byteBufferIter)
{
    /* Store number of viewports and validate limit */
    numStaticViewports_ = static_cast<GLsizei>(numViewports);

    if (numStaticViewports_ > LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS)
    {
        throw std::invalid_argument(
            "too many viewports in graphics pipeline state (" + std::to_string(numStaticViewports_) +
            " specified, but limit is " + std::to_string(LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS) + ")"
        );
    }

    /* Build <GLViewport> entries */
    for (std::size_t i = 0; i < numViewports; ++i)
    {
        auto dst = byteBufferIter.Next<GLViewport>();
        {
            dst->x      = static_cast<GLfloat>(viewports[i].x);
            dst->y      = static_cast<GLfloat>(viewports[i].y);
            dst->width  = static_cast<GLfloat>(viewports[i].width);
            dst->height = static_cast<GLfloat>(viewports[i].height);
        }
    }

    /* Build <GLDepthRange> entries */
    for (std::size_t i = 0; i < numViewports; ++i)
    {
        auto dst = byteBufferIter.Next<GLDepthRange>();
        {
            dst->minDepth = static_cast<GLclamp_t>(viewports[i].minDepth);
            dst->maxDepth = static_cast<GLclamp_t>(viewports[i].maxDepth);
        }
    }
}

void GLGraphicsPSO::BuildStaticScissors(std::size_t numScissors, const Scissor* scissors, ByteBufferIterator& byteBufferIter)
{
    /* Store number of scissors and validate limit */
    numStaticScissors_ = static_cast<GLsizei>(numScissors);

    if (numStaticScissors_ > LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS)
    {
        throw std::invalid_argument(
            "too many scissors in graphics pipeline state (" + std::to_string(numStaticScissors_) +
            " specified, but limit is " + std::to_string(LLGL_MAX_NUM_VIEWPORTS_AND_SCISSORS) + ")"
        );
    }

    /* Build <GLScissor> entries */
    for (std::size_t i = 0; i < numScissors; ++i)
    {
        auto dst = byteBufferIter.Next<GLScissor>();
        {
            dst->x      = static_cast<GLint>(scissors[i].x);
            dst->y      = static_cast<GLint>(scissors[i].y);
            dst->width  = static_cast<GLsizei>(scissors[i].width);
            dst->height = static_cast<GLsizei>(scissors[i].height);
        }
    }
}

void GLGraphicsPSO::SetStaticViewports(GLStateManager& stateMngr, ByteBufferIterator& byteBufferIter)
{
    stateMngr.SetViewportArray(0, numStaticViewports_, byteBufferIter.Next<GLViewport>(numStaticViewports_));
    stateMngr.SetDepthRangeArray(0, numStaticViewports_, byteBufferIter.Next<GLDepthRange>(numStaticViewports_));
}

void GLGraphicsPSO::SetStaticScissors(GLStateManager& stateMngr, ByteBufferIterator& byteBufferIter)
{
    stateMngr.SetScissorArray(0, numStaticScissors_, byteBufferIter.Next<GLScissor>(numStaticScissors_));
}

} // /namespace LLGL

// ================================================================================
<|endoftext|>


<commit_before>
#include <cstdio>
#include <sstream>
#include "DecimalConverter.h"
using namespace std;

namespace NumberBaseConverter
{
    string DecimalConverter::convertToBinary(int number)
    {
        string binRep("");
        if(number / 2 != 0)
        {
            binRep.append(convertToBinary(number / 2));
        } // end if

        char temp[1];
        sprintf(temp, "%d", number % 2);
        binRep.append(temp);

        return binRep;
    }

    string DecimalConverter::ConvertToBinary(string decStr)
    {
        int number;
        stringstream ss;
        ss << std::dec << decStr;
        ss >> number;

        return convertToBinary(number);
    } // end method

    string DecimalConverter::convertToHexadecimal(int number)
    {
        string hexRep("");
        if(number / 16 != 0)
        {
            hexRep.append(convertToHexadecimal(number / 16));
        } // end if

        char temp[1];
        sprintf(temp, "%x", number % 16);
        hexRep.append(temp);

        return hexRep;
    } // end method

    string DecimalConverter::ConvertToHexadecimal(string decStr)
    {
        int number;
        stringstream ss;
        ss << std::dec << decStr;
        ss >> number;

        return convertToHexadecimal(number);
    } // end method
} // end namespace<commit_msg> rearranging the private/public methods<commit_after>
#include <cstdio>
#include <sstream>
#include "DecimalConverter.h"
using namespace std;

namespace NumberBaseConverter
{
    string DecimalConverter::ConvertToBinary(string decStr)
    {
        int number;
        stringstream ss;
        ss << std::dec << decStr;
        ss >> number;

        return convertToBinary(number);
    } // end method

    string DecimalConverter::ConvertToHexadecimal(string decStr)
    {
        int number;
        stringstream ss;
        ss << std::dec << decStr;
        ss >> number;

        return convertToHexadecimal(number);
    } // end method

    string DecimalConverter::convertToBinary(int number)
    {
        string binRep("");
        if(number / 2 != 0)
        {
            binRep.append(convertToBinary(number / 2));
        } // end if

        char temp[1];
        sprintf(temp, "%d", number % 2);
        binRep.append(temp);

        return binRep;
    } // end method

    string DecimalConverter::convertToHexadecimal(int number)
    {
        string hexRep("");
        if(number / 16 != 0)
        {
            hexRep.append(convertToHexadecimal(number / 16));
        } // end if

        char temp[1];
        sprintf(temp, "%x", number % 16);
        hexRep.append(temp);

        return hexRep;
    } // end method
} // end namespace<|endoftext|>


<commit_before>#include "StorageArchiveLogSegmentJob.h"
#include "System/FileSystem.h"
#include "System/Config.h"
#include "System/Stopwatch.h"
#include "StorageEnvironment.h"

StorageArchiveLogSegmentJob::StorageArchiveLogSegmentJob(StorageEnvironment* env_,
 StorageLogSegment* logSegment_, const char* script_)
{
    env = env_;
    logSegment = logSegment_;
    script = script_;
}

void StorageArchiveLogSegmentJob::Execute()
{
    Buffer  dest;
    Buffer  cmdline;

    if (ReadBuffer::Cmp(script, "$archive") == 0)
    {
        Log_Debug("Archiving log segment %U...", logSegment->GetLogSegmentID());

        dest.Write(env->archivePath);
        dest.Appendf("log.%020U", logSegment->GetLogSegmentID());
        dest.NullTerminate();

        FS_Rename(logSegment->filename.GetBuffer(), dest.GetBuffer());
    }
    else if (ReadBuffer::Cmp(script, "$delete") == 0)
    {
        Log_Debug("Deleting archive log segment %U...", logSegment->GetLogSegmentID());
        FS_Delete(logSegment->filename.GetBuffer());
    }
    else
    {
        Log_Debug("Executing script on archive log segment %U (%s)...",
         logSegment->GetLogSegmentID(), script);

        EvalScriptVariables();
        ShellExec(command.GetBuffer());
    }
}

void StorageArchiveLogSegmentJob::EvalScriptVariables()
{
    Buffer      var;
    const char* p;
    bool        inVar;

    p = script;
    inVar = false;
    while (*p)
    {
        // Replace $(variableName) in the script to the value of a config variable
        if (p[0] == '$' && p[1] == '(')
        {
            inVar = true;
            p += 2;         // skip "$("
        }

        if (inVar && p[0] == ')')
        {
            var.NullTerminate();
            command.Append(GetVarValue(var.GetBuffer()));
            var.Reset();
            inVar = false;
            p += 1;         // skip ")"
        }

        if (*p == 0)
            break;

        if (inVar)
            var.Append(*p);
        else
            command.Append(*p);

        p++;
    }

    command.NullTerminate();
}

const char* StorageArchiveLogSegmentJob::GetVarValue(const char* var)
{
    if (strcmp(var, "archiveFile") == 0)
        return logSegment->filename.GetBuffer();
    else
        return configFile.GetValue(var, "");
}

void StorageArchiveLogSegmentJob::OnComplete()
{
    env->OnLogArchive(this); // deletes this
}
<commit_msg>Improved Log_Debug message.<commit_after>#include "StorageArchiveLogSegmentJob.h"
#include "System/FileSystem.h"
#include "System/Config.h"
#include "System/Stopwatch.h"
#include "StorageEnvironment.h"

StorageArchiveLogSegmentJob::StorageArchiveLogSegmentJob(StorageEnvironment* env_,
 StorageLogSegment* logSegment_, const char* script_)
{
    env = env_;
    logSegment = logSegment_;
    script = script_;
}

void StorageArchiveLogSegmentJob::Execute()
{
    Buffer  dest;
    Buffer  cmdline;

    if (ReadBuffer::Cmp(script, "$archive") == 0)
    {
        Log_Debug("Archiving log segment %U...", logSegment->GetLogSegmentID());

        dest.Write(env->archivePath);
        dest.Appendf("log.%020U", logSegment->GetLogSegmentID());
        dest.NullTerminate();

        FS_Rename(logSegment->filename.GetBuffer(), dest.GetBuffer());
    }
    else if (ReadBuffer::Cmp(script, "$delete") == 0)
    {
        Log_Debug("Deleting archive log segment %U/%U...",
         logSegment->GetTrackID(), logSegment->GetLogSegmentID());
        FS_Delete(logSegment->filename.GetBuffer());
    }
    else
    {
        Log_Debug("Executing script on archive log segment %U (%s)...",
         logSegment->GetLogSegmentID(), script);

        EvalScriptVariables();
        ShellExec(command.GetBuffer());
    }
}

void StorageArchiveLogSegmentJob::EvalScriptVariables()
{
    Buffer      var;
    const char* p;
    bool        inVar;

    p = script;
    inVar = false;
    while (*p)
    {
        // Replace $(variableName) in the script to the value of a config variable
        if (p[0] == '$' && p[1] == '(')
        {
            inVar = true;
            p += 2;         // skip "$("
        }

        if (inVar && p[0] == ')')
        {
            var.NullTerminate();
            command.Append(GetVarValue(var.GetBuffer()));
            var.Reset();
            inVar = false;
            p += 1;         // skip ")"
        }

        if (*p == 0)
            break;

        if (inVar)
            var.Append(*p);
        else
            command.Append(*p);

        p++;
    }

    command.NullTerminate();
}

const char* StorageArchiveLogSegmentJob::GetVarValue(const char* var)
{
    if (strcmp(var, "archiveFile") == 0)
        return logSegment->filename.GetBuffer();
    else
        return configFile.GetValue(var, "");
}

void StorageArchiveLogSegmentJob::OnComplete()
{
    env->OnLogArchive(this); // deletes this
}
<|endoftext|>