<commit_before>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_COMPLEX_HPP
#define EIGENJS_COMPLEX_HPP

#include <node.h>
#include <v8.h>

#include <nan.h>

#include <complex>
#include <sstream>

#define EIGENJS_COMPLEX_CLASS_METHOD( NAME )                                  \
  static NAN_METHOD( NAME ) {                                                 \
    NanScope();                                                               \
                                                                              \
    if (args.Length() == 1 && HasInstance(args[0])) {                         \
      const Complex* obj =                                                    \
          node::ObjectWrap::Unwrap<Complex>(args[0]->ToObject());             \
                                                                              \
      const complex_type& NAME = std::NAME(obj->complex_);                    \
      const element_type& real = NAME.real();                                 \
      const element_type& imag = NAME.imag();                                 \
                                                                              \
      v8::Local<v8::Function> ctor = NanNew(constructor);                     \
      v8::Local<v8::Value> argv[] = {                                         \
          NanNew<v8::Number>(real)                                            \
        , NanNew<v8::Number>(imag)                                            \
      };                                                                      \
                                                                              \
      v8::Local<v8::Object> new_complex = ctor->NewInstance(                  \
          sizeof(argv) / sizeof(v8::Local<v8::Value>)                         \
        , argv                                                                \
      );                                                                      \
                                                                              \
      NanReturnValue(new_complex);                                            \
    }                                                                         \
                                                                              \
    NanReturnUndefined();                                                     \
  }                                                                           \
/**/

namespace EigenJS {

template <typename ValueType>
class Complex : public node::ObjectWrap {
  typedef ValueType element_type;
  typedef std::complex<element_type> complex_type;

 public:
  static void Init(v8::Handle<v8::Object> exports) {
    NanScope();

    v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
    tpl->SetClassName(NanNew("Complex"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    NODE_SET_PROTOTYPE_METHOD(tpl, "abs", abs);
    NODE_SET_PROTOTYPE_METHOD(tpl, "arg", arg);
    NODE_SET_PROTOTYPE_METHOD(tpl, "norm", norm);
    NODE_SET_PROTOTYPE_METHOD(tpl, "conj", conj);

    NODE_SET_METHOD(tpl, "polar", polar);
    NODE_SET_METHOD(tpl, "proj", proj);

    NODE_SET_METHOD(tpl, "cos", cos);
    NODE_SET_METHOD(tpl, "cosh", cosh);
    NODE_SET_METHOD(tpl, "exp", exp);
    NODE_SET_METHOD(tpl, "log", log);
    NODE_SET_METHOD(tpl, "log10", log10);

    NODE_SET_PROTOTYPE_METHOD(tpl, "toString", toString);

    v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
    proto->SetAccessor(NanNew("real"), get_real, set_real);
    proto->SetAccessor(NanNew("imag"), get_imag, set_imag);

    NanAssignPersistent(constructor, tpl->GetFunction());
    exports->Set(NanNew("Complex"), tpl->GetFunction());

    NanAssignPersistent(function_template, tpl);
  }

  static NAN_METHOD(abs) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::abs(obj->complex_)));
  }

  static NAN_METHOD(arg) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::arg(obj->complex_)));
  }

  static NAN_METHOD(norm) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::norm(obj->complex_)));
  }

  static NAN_METHOD(conj) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    const complex_type& c = std::conj(obj->complex_);
    const element_type& real = c.real();
    const element_type& imag = c.imag();
    NanScope();

    v8::Local<v8::Function> ctor = NanNew(constructor);
    v8::Local<v8::Value> argv[] = {
        NanNew<v8::Number>(real)
      , NanNew<v8::Number>(imag)
    };

    v8::Local<v8::Object> new_complex = ctor->NewInstance(
        sizeof(argv) / sizeof(v8::Local<v8::Value>)
      , argv
    );

    NanReturnValue(new_complex);
  }

  static NAN_METHOD(polar) {
    NanScope();

    if (args.Length() == 2 &&
        args[0]->IsNumber() &&
        args[1]->IsNumber()) {
      const element_type& rho = args[0]->NumberValue();
      const element_type& theta = args[1]->NumberValue();

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(rho)
        , NanNew<v8::Number>(theta)
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  EIGENJS_COMPLEX_CLASS_METHOD(proj)
  EIGENJS_COMPLEX_CLASS_METHOD(cos)
  EIGENJS_COMPLEX_CLASS_METHOD(cosh)
  EIGENJS_COMPLEX_CLASS_METHOD(exp)
  EIGENJS_COMPLEX_CLASS_METHOD(log)
  EIGENJS_COMPLEX_CLASS_METHOD(log10)

  static NAN_METHOD(toString) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    std::ostringstream result;
    result << obj->complex_;

    NanReturnValue(NanNew(result.str().c_str()));

    NanReturnUndefined();
  }

  static NAN_GETTER(get_real) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.real()));
  }

  static NAN_SETTER(set_real) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          value->NumberValue()
        , obj->complex_.imag()
      );
    }
  }

  static NAN_GETTER(get_imag) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.imag()));
  }

  static NAN_SETTER(set_imag) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          obj->complex_.real()
        , value->NumberValue()
      );
    }
  }

 private:
  Complex(const element_type& real, const element_type& imag)
    : complex_(real, imag)
  {}
  ~Complex() {}

  static NAN_METHOD(New) {
    NanScope();

    if (args.Length() < 2) {
      NanThrowError("Tried creating complex without real and imag arguments");
      NanReturnUndefined();
    }

    if (args.IsConstructCall()) {
      const element_type& real = args[0]->NumberValue();
      const element_type& imag = args[1]->NumberValue();
      Complex* obj = new Complex(real, imag);
      obj->Wrap(args.This());
      NanReturnValue(args.This());
    } else {
      v8::Local<v8::Function> ctr = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {args[0], args[1]};
      NanReturnValue(
        ctr->NewInstance(
            sizeof(argv) / sizeof(v8::Local<v8::Value>)
          , argv
        )
      );
    }
  }

  static bool HasInstance(const v8::Handle<v8::Value>& value) {
    NanScope();
    v8::Local<v8::FunctionTemplate> tpl = NanNew(function_template);
    return tpl->HasInstance(value);
  }

 private:
  static v8::Persistent<v8::FunctionTemplate> function_template;
  static v8::Persistent<v8::Function> constructor;

 private:
  complex_type complex_;
};

template<typename ValueType>
v8::Persistent<v8::FunctionTemplate> Complex<ValueType>::function_template;

template<typename ValueType>
v8::Persistent<v8::Function> Complex<ValueType>::constructor;

}  // namespace EigenJS

#undef EIGENJS_COMPLEX_CLASS_METHOD

#endif  // EIGENJS_COMPLEX_HPP
<commit_msg>src: improved readable<commit_after>//
// EigenJS.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_COMPLEX_HPP
#define EIGENJS_COMPLEX_HPP

#include <node.h>
#include <v8.h>

#include <nan.h>

#include <complex>
#include <sstream>

#define EIGENJS_COMPLEX_CLASS_METHOD( NAME )                                  \
  static NAN_METHOD( NAME ) {                                                 \
    NanScope();                                                               \
                                                                              \
    if ( args.Length() == 1 && HasInstance(args[0]) ) {                       \
      const Complex* obj =                                                    \
          node::ObjectWrap::Unwrap<Complex>( args[0]->ToObject() );           \
                                                                              \
      const complex_type& NAME = std::NAME( obj->complex_ );                  \
      const element_type& real = NAME.real();                                 \
      const element_type& imag = NAME.imag();                                 \
                                                                              \
      v8::Local<v8::Function> ctor = NanNew( constructor );                   \
      v8::Local<v8::Value> argv[] = {                                         \
          NanNew<v8::Number>( real )                                          \
        , NanNew<v8::Number>( imag )                                          \
      };                                                                      \
                                                                              \
      v8::Local<v8::Object> new_complex = ctor->NewInstance(                  \
          sizeof( argv ) / sizeof( v8::Local<v8::Value> )                     \
        , argv                                                                \
      );                                                                      \
                                                                              \
      NanReturnValue( new_complex );                                          \
    }                                                                         \
                                                                              \
    NanReturnUndefined();                                                     \
  }                                                                           \
/**/

namespace EigenJS {

template <typename ValueType>
class Complex : public node::ObjectWrap {
  typedef ValueType element_type;
  typedef std::complex<element_type> complex_type;

 public:
  static void Init(v8::Handle<v8::Object> exports) {
    NanScope();

    v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
    tpl->SetClassName(NanNew("Complex"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    NODE_SET_PROTOTYPE_METHOD(tpl, "abs", abs);
    NODE_SET_PROTOTYPE_METHOD(tpl, "arg", arg);
    NODE_SET_PROTOTYPE_METHOD(tpl, "norm", norm);
    NODE_SET_PROTOTYPE_METHOD(tpl, "conj", conj);

    NODE_SET_METHOD(tpl, "polar", polar);
    NODE_SET_METHOD(tpl, "proj", proj);

    NODE_SET_METHOD(tpl, "cos", cos);
    NODE_SET_METHOD(tpl, "cosh", cosh);
    NODE_SET_METHOD(tpl, "exp", exp);
    NODE_SET_METHOD(tpl, "log", log);
    NODE_SET_METHOD(tpl, "log10", log10);

    NODE_SET_PROTOTYPE_METHOD(tpl, "toString", toString);

    v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
    proto->SetAccessor(NanNew("real"), get_real, set_real);
    proto->SetAccessor(NanNew("imag"), get_imag, set_imag);

    NanAssignPersistent(constructor, tpl->GetFunction());
    exports->Set(NanNew("Complex"), tpl->GetFunction());

    NanAssignPersistent(function_template, tpl);
  }

  static NAN_METHOD(abs) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::abs(obj->complex_)));
  }

  static NAN_METHOD(arg) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::arg(obj->complex_)));
  }

  static NAN_METHOD(norm) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    NanReturnValue(NanNew(std::norm(obj->complex_)));
  }

  static NAN_METHOD(conj) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    const complex_type& c = std::conj(obj->complex_);
    const element_type& real = c.real();
    const element_type& imag = c.imag();
    NanScope();

    v8::Local<v8::Function> ctor = NanNew(constructor);
    v8::Local<v8::Value> argv[] = {
        NanNew<v8::Number>(real)
      , NanNew<v8::Number>(imag)
    };

    v8::Local<v8::Object> new_complex = ctor->NewInstance(
        sizeof(argv) / sizeof(v8::Local<v8::Value>)
      , argv
    );

    NanReturnValue(new_complex);
  }

  static NAN_METHOD(polar) {
    NanScope();

    if (args.Length() == 2 &&
        args[0]->IsNumber() &&
        args[1]->IsNumber()) {
      const element_type& rho = args[0]->NumberValue();
      const element_type& theta = args[1]->NumberValue();

      v8::Local<v8::Function> ctor = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {
          NanNew<v8::Number>(rho)
        , NanNew<v8::Number>(theta)
      };

      v8::Local<v8::Object> new_complex = ctor->NewInstance(
          sizeof(argv) / sizeof(v8::Local<v8::Value>)
        , argv
      );

      NanReturnValue(new_complex);
    }

    NanReturnUndefined();
  }

  EIGENJS_COMPLEX_CLASS_METHOD(proj)
  EIGENJS_COMPLEX_CLASS_METHOD(cos)
  EIGENJS_COMPLEX_CLASS_METHOD(cosh)
  EIGENJS_COMPLEX_CLASS_METHOD(exp)
  EIGENJS_COMPLEX_CLASS_METHOD(log)
  EIGENJS_COMPLEX_CLASS_METHOD(log10)

  static NAN_METHOD(toString) {
    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
    NanScope();

    std::ostringstream result;
    result << obj->complex_;

    NanReturnValue(NanNew(result.str().c_str()));

    NanReturnUndefined();
  }

  static NAN_GETTER(get_real) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.real()));
  }

  static NAN_SETTER(set_real) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          value->NumberValue()
        , obj->complex_.imag()
      );
    }
  }

  static NAN_GETTER(get_imag) {
    NanScope();

    if (!NanGetInternalFieldPointer(args.This(), 0))
      NanReturnValue(args.This());

    const Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());

    NanReturnValue(NanNew(obj->complex_.imag()));
  }

  static NAN_SETTER(set_imag) {
    if (value->IsNumber()) {
      Complex* obj = node::ObjectWrap::Unwrap<Complex>(args.This());
      obj->complex_ = complex_type(
          obj->complex_.real()
        , value->NumberValue()
      );
    }
  }

 private:
  Complex(const element_type& real, const element_type& imag)
    : complex_(real, imag)
  {}
  ~Complex() {}

  static NAN_METHOD(New) {
    NanScope();

    if (args.Length() < 2) {
      NanThrowError("Tried creating complex without real and imag arguments");
      NanReturnUndefined();
    }

    if (args.IsConstructCall()) {
      const element_type& real = args[0]->NumberValue();
      const element_type& imag = args[1]->NumberValue();
      Complex* obj = new Complex(real, imag);
      obj->Wrap(args.This());
      NanReturnValue(args.This());
    } else {
      v8::Local<v8::Function> ctr = NanNew(constructor);
      v8::Local<v8::Value> argv[] = {args[0], args[1]};
      NanReturnValue(
        ctr->NewInstance(
            sizeof(argv) / sizeof(v8::Local<v8::Value>)
          , argv
        )
      );
    }
  }

  static bool HasInstance(const v8::Handle<v8::Value>& value) {
    NanScope();
    v8::Local<v8::FunctionTemplate> tpl = NanNew(function_template);
    return tpl->HasInstance(value);
  }

 private:
  static v8::Persistent<v8::FunctionTemplate> function_template;
  static v8::Persistent<v8::Function> constructor;

 private:
  complex_type complex_;
};

template<typename ValueType>
v8::Persistent<v8::FunctionTemplate> Complex<ValueType>::function_template;

template<typename ValueType>
v8::Persistent<v8::Function> Complex<ValueType>::constructor;

}  // namespace EigenJS

#undef EIGENJS_COMPLEX_CLASS_METHOD

#endif  // EIGENJS_COMPLEX_HPP
<|endoftext|>


<commit_before>/*
 *
 *    Copyright (c) 2021 Project CHIP 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 "GenericOTARequestorDriver.h"

#include <platform/CHIPDeviceLayer.h>
#include <platform/OTAImageProcessor.h>
#include <platform/OTARequestorInterface.h>

namespace chip {
namespace DeviceLayer {
namespace {

using namespace app::Clusters::OtaSoftwareUpdateRequestor;

GenericOTARequestorDriver * ToDriver(void * context)
{
    return static_cast<GenericOTARequestorDriver *>(context);
}

} // namespace

bool GenericOTARequestorDriver::CanConsent()
{
    return false;
}

uint16_t GenericOTARequestorDriver::GetMaxDownloadBlockSize()
{
    return 1024;
}

void GenericOTARequestorDriver::HandleError(UpdateFailureState state, CHIP_ERROR error)
{
    // TODO: Schedule the next QueryImage
}

void GenericOTARequestorDriver::UpdateAvailable(const UpdateDescription & update, System::Clock::Seconds32 delay)
{
    VerifyOrDie(mRequestor != nullptr);
    ScheduleDelayedAction(UpdateFailureState::kDownloading, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mRequestor->DownloadUpdate(); });
}

void GenericOTARequestorDriver::UpdateNotFound(UpdateNotFoundReason reason, System::Clock::Seconds32 delay)
{
    // TODO: Schedule the next QueryImage
}

void GenericOTARequestorDriver::UpdateDownloaded()
{
    VerifyOrDie(mRequestor != nullptr);
    mRequestor->ApplyUpdate();
}

void GenericOTARequestorDriver::UpdateConfirmed(System::Clock::Seconds32 delay)
{
    VerifyOrDie(mImageProcessor != nullptr);
    ScheduleDelayedAction(UpdateFailureState::kApplying, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mImageProcessor->Apply(); });
}

void GenericOTARequestorDriver::UpdateSuspended(System::Clock::Seconds32 delay)
{
    VerifyOrDie(mRequestor != nullptr);
    ScheduleDelayedAction(UpdateFailureState::kAwaitingNextAction, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mRequestor->ApplyUpdate(); });
}

void GenericOTARequestorDriver::UpdateDiscontinued()
{
    VerifyOrDie(mImageProcessor != nullptr);
    mImageProcessor->Abort();
}

void GenericOTARequestorDriver::ScheduleDelayedAction(UpdateFailureState state, System::Clock::Seconds32 delay,
                                                      System::TimerCompleteCallback action)
{
    CHIP_ERROR error = SystemLayer().StartTimer(std::chrono::duration_cast<System::Clock::Timeout>(delay), action, this);

    if (error != CHIP_NO_ERROR)
    {
        HandleError(state, error);
    }
}

} // namespace DeviceLayer
} // namespace chip
<commit_msg>ota-requestor: Handle QueryImageResponse status and ApplyUpdateResponse status (#13770)<commit_after>/*
 *
 *    Copyright (c) 2021 Project CHIP 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 "GenericOTARequestorDriver.h"

#include <platform/CHIPDeviceLayer.h>
#include <platform/OTAImageProcessor.h>
#include <platform/OTARequestorInterface.h>

namespace chip {
namespace DeviceLayer {
namespace {

using namespace app::Clusters::OtaSoftwareUpdateRequestor;

GenericOTARequestorDriver * ToDriver(void * context)
{
    return static_cast<GenericOTARequestorDriver *>(context);
}

constexpr System::Clock::Seconds32 kDefaultDelayedActionTime = System::Clock::Seconds32(120);

} // namespace

bool GenericOTARequestorDriver::CanConsent()
{
    return false;
}

uint16_t GenericOTARequestorDriver::GetMaxDownloadBlockSize()
{
    return 1024;
}

void GenericOTARequestorDriver::HandleError(UpdateFailureState state, CHIP_ERROR error)
{
    // TODO: Schedule the next QueryImage
}

void GenericOTARequestorDriver::UpdateAvailable(const UpdateDescription & update, System::Clock::Seconds32 delay)
{
    VerifyOrDie(mRequestor != nullptr);
    ScheduleDelayedAction(UpdateFailureState::kDownloading, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mRequestor->DownloadUpdate(); });
}

void GenericOTARequestorDriver::UpdateNotFound(UpdateNotFoundReason reason, System::Clock::Seconds32 delay)
{
    VerifyOrDie(mRequestor != nullptr);

    if (delay < kDefaultDelayedActionTime)
    {
        delay = kDefaultDelayedActionTime;
    }

    ScheduleDelayedAction(UpdateFailureState::kQuerying, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mRequestor->TriggerImmediateQuery(); });
}

void GenericOTARequestorDriver::UpdateDownloaded()
{
    VerifyOrDie(mRequestor != nullptr);
    mRequestor->ApplyUpdate();
}

void GenericOTARequestorDriver::UpdateConfirmed(System::Clock::Seconds32 delay)
{
    VerifyOrDie(mImageProcessor != nullptr);
    ScheduleDelayedAction(UpdateFailureState::kApplying, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mImageProcessor->Apply(); });
}

void GenericOTARequestorDriver::UpdateSuspended(System::Clock::Seconds32 delay)
{
    VerifyOrDie(mRequestor != nullptr);

    if (delay < kDefaultDelayedActionTime)
    {
        delay = kDefaultDelayedActionTime;
    }

    ScheduleDelayedAction(UpdateFailureState::kAwaitingNextAction, delay,
                          [](System::Layer *, void * context) { ToDriver(context)->mRequestor->ApplyUpdate(); });
}

void GenericOTARequestorDriver::UpdateDiscontinued()
{
    VerifyOrDie(mImageProcessor != nullptr);
    mImageProcessor->Abort();
}

void GenericOTARequestorDriver::ScheduleDelayedAction(UpdateFailureState state, System::Clock::Seconds32 delay,
                                                      System::TimerCompleteCallback action)
{
    CHIP_ERROR error = SystemLayer().StartTimer(std::chrono::duration_cast<System::Clock::Timeout>(delay), action, this);

    if (error != CHIP_NO_ERROR)
    {
        HandleError(state, error);
    }
}

} // namespace DeviceLayer
} // namespace chip
<|endoftext|>


<commit_before>#pragma once
/*
 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */

#ifndef _QI_DETAILS_TRACKABLE_HXX_
#define _QI_DETAILS_TRACKABLE_HXX_

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/function_types/result_type.hpp>

namespace qi
{
  template<typename T>
  inline Trackable<T>::Trackable(T* ptr)
  : _wasDestroyed(false)
  {
    _ptr = boost::shared_ptr<T>(ptr, boost::bind(&Trackable::_destroyed, _1));
  }

  template<typename T>
  inline void Trackable<T>::destroy()
  {
    _ptr.reset();
    wait();
  }

  template<typename T>
  inline void Trackable<T>::wait()
  {
    boost::mutex::scoped_lock lock(_mutex);
    while (!_wasDestroyed)
    {
      _cond.wait(lock);
    }
  }

  template<typename T>
  inline void Trackable<T>::_destroyed()
  {
    // unblock
    boost::mutex::scoped_lock lock(_mutex);
    _wasDestroyed = true;
    _cond.notify_all();
  }

  template<typename T>
  inline Trackable<T>::~Trackable()
  {
    // We expect destroy() to have been called from parent destructor, so from
    // this thread.
    if (!_wasDestroyed)
    {
      qiLogError("qi.Trackable") << "Trackable destroyed without calling destroy()";
      // do it to mitigate the effect, but it's too late
      destroy();
    }
  }

  template<typename T>
  inline boost::shared_ptr<T> Trackable<T>::lock()
  {
    return _ptr;
  }

  template<typename T>
  inline boost::weak_ptr<T> Trackable<T>::weakPtr()
  {
    return boost::weak_ptr<T>(_ptr);
  }

  namespace detail
  {
    // Functor that locks a weak ptr and make a call if successful
    // Generalize on shared_ptr and weak_ptr types in case we ever have
    // other types with their semantics
    template<typename WT, typename ST, typename F>
    class LockAndCall
    {
    public:
      typedef typename boost::function_types::result_type<F>::type Result;
      LockAndCall(const WT& arg, boost::function<F> func, boost::function<void()> onFail)
      : _wptr(arg)
      , _f(func)
      , _onFail(onFail)
      {}

#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
     QI_GEN_MAYBE_TEMPLATE_OPEN(comma)                    \
     ATYPEDECL                                            \
     QI_GEN_MAYBE_TEMPLATE_CLOSE(comma)                   \
     Result operator()(ADECL) {                           \
       ST s = _wptr.lock();                               \
       if (s)                                             \
         return _f(AUSE);                                 \
       else                                               \
         if (_onFail)                                     \
           _onFail();                                     \
         else                                             \
           return Result();                               \
      }
      QI_GEN(genCall)
#undef genCall
      WT _wptr;
      boost::function<F> _f;
      boost::function<void()> _onFail;
    };

    template<typename T, bool IS_TRACKABLE> struct BindTransform
    {
      typedef const T& type;
      static type transform(const T& arg)
      {
        return arg;
      }
      template<typename F>
      static boost::function<F> wrap(const T& arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return func;
      }
    };

    template<typename T> struct BindTransform<boost::weak_ptr<T>, false >
    {
      typedef T* type;
      static T* transform(const boost::weak_ptr<T>& arg)
      {
        // Note that we assume that lock if successful always return the same pointer
        // And that if lock fails once, it will fail forever from that point
        return arg.lock().get();
      }
      template<typename F>
      static boost::function<F> wrap(const boost::weak_ptr<T>& arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg, func, onFail);
      }
    };

    template<typename T> struct BindTransform<T*, true>
    {
      typedef T* type;
      static T* transform(T* const & arg)
      {
        // Note that we assume that lock if successful always return the same pointer
        return arg;
      }
      template<typename F>
      static boost::function<F> wrap(T*const & arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg->weakPtr(), func, onFail);
      }
    };

    inline void throwPointerLockException()
    {
      throw PointerLockException();
    }
  }

#ifndef DOXYGEN
  template<typename RF, typename AF>
  boost::function<RF> bind(const AF& fun)
  {
    return fun;
  }
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bind(const AF& fun, const ARG0& arg0 comma ADECL)                                  \
  {                                                                                \
    typedef typename detail::BindTransform<                                                              \
        ARG0,                                                                                \
        boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;  \
    typename Transform::type transformed = Transform::transform(arg0);                                   \
    boost::function<RF> f = boost::bind(fun, transformed comma AUSE);                                    \
    return Transform::wrap(arg0, f, detail::throwPointerLockException);                                  \
  }                                                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bindWithFallback(const boost::function<void()>& onFail,                            \
                                       const AF& fun,                                                    \
                                       const ARG0& arg0 comma ADECL)                                     \
  {                                                                                \
    typedef typename detail::BindTransform<                                                              \
        ARG0,                                                                                \
        boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;  \
    typename Transform::type transformed = Transform::transform(arg0);                                   \
    boost::function<RF> f = boost::bind(fun, transformed comma AUSE);                                    \
    return Transform::wrap(arg0, f, onFail);                                                             \
  }                                                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bindSilent(const AF& fun, const ARG0& arg0 comma ADECL)                            \
  {                                                                                \
    return bindWithFallback<RF, AF, ARG0 comma ATYPES>(boost::function<void()>(), fun, arg0 comma AUSE); \
  }
  QI_GEN(genCall)
#undef genCall
#endif // DOXYGEN
  template<typename F, typename ARG0>
  boost::function<F> track(const boost::function<F>& f, const ARG0& arg0)
  {
    typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
    return Transform::wrap(arg0, f, detail::throwPointerLockException);
  }
  template<typename F, typename ARG0>
  boost::function<F> trackWithFallback(boost::function<void()> onFail,
      const boost::function<F>& f, const ARG0& arg0)
  {
    typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
    return Transform::wrap(arg0, f, onFail);
  }
  template<typename F, typename ARG0>
  boost::function<F> trackSilent(const boost::function<F>& f, const ARG0& arg0)
  {
    return trackWithFallback<F, ARG0>(boost::function<void()>(), f, arg0);
  }
}

#endif  // _QI_DETAILS_TRACKABLE_HXX_
<commit_msg>Fix return value in QI_GEN macro<commit_after>#pragma once
/*
 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the COPYING file.
 */

#ifndef _QI_DETAILS_TRACKABLE_HXX_
#define _QI_DETAILS_TRACKABLE_HXX_

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/function_types/result_type.hpp>

namespace qi
{
  template<typename T>
  inline Trackable<T>::Trackable(T* ptr)
  : _wasDestroyed(false)
  {
    _ptr = boost::shared_ptr<T>(ptr, boost::bind(&Trackable::_destroyed, _1));
  }

  template<typename T>
  inline void Trackable<T>::destroy()
  {
    _ptr.reset();
    wait();
  }

  template<typename T>
  inline void Trackable<T>::wait()
  {
    boost::mutex::scoped_lock lock(_mutex);
    while (!_wasDestroyed)
    {
      _cond.wait(lock);
    }
  }

  template<typename T>
  inline void Trackable<T>::_destroyed()
  {
    // unblock
    boost::mutex::scoped_lock lock(_mutex);
    _wasDestroyed = true;
    _cond.notify_all();
  }

  template<typename T>
  inline Trackable<T>::~Trackable()
  {
    // We expect destroy() to have been called from parent destructor, so from
    // this thread.
    if (!_wasDestroyed)
    {
      qiLogError("qi.Trackable") << "Trackable destroyed without calling destroy()";
      // do it to mitigate the effect, but it's too late
      destroy();
    }
  }

  template<typename T>
  inline boost::shared_ptr<T> Trackable<T>::lock()
  {
    return _ptr;
  }

  template<typename T>
  inline boost::weak_ptr<T> Trackable<T>::weakPtr()
  {
    return boost::weak_ptr<T>(_ptr);
  }

  namespace detail
  {
    // Functor that locks a weak ptr and make a call if successful
    // Generalize on shared_ptr and weak_ptr types in case we ever have
    // other types with their semantics
    template<typename WT, typename ST, typename F>
    class LockAndCall
    {
    public:
      typedef typename boost::function_types::result_type<F>::type Result;
      LockAndCall(const WT& arg, boost::function<F> func, boost::function<void()> onFail)
      : _wptr(arg)
      , _f(func)
      , _onFail(onFail)
      {}

#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
      QI_GEN_MAYBE_TEMPLATE_OPEN(comma)                   \
      ATYPEDECL                                           \
      QI_GEN_MAYBE_TEMPLATE_CLOSE(comma)                  \
      Result operator()(ADECL)                            \
      {                                                   \
        ST s = _wptr.lock();                              \
        if (s)                                            \
          return _f(AUSE);                                \
        else                                              \
        {                                                 \
          if (_onFail)                                    \
            _onFail();                                    \
          return Result();                                \
        }                                                 \
      }
      QI_GEN(genCall)
#undef genCall
      WT _wptr;
      boost::function<F> _f;
      boost::function<void()> _onFail;
    };

    template<typename T, bool IS_TRACKABLE> struct BindTransform
    {
      typedef const T& type;
      static type transform(const T& arg)
      {
        return arg;
      }
      template<typename F>
      static boost::function<F> wrap(const T& arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return func;
      }
    };

    template<typename T> struct BindTransform<boost::weak_ptr<T>, false >
    {
      typedef T* type;
      static T* transform(const boost::weak_ptr<T>& arg)
      {
        // Note that we assume that lock if successful always return the same pointer
        // And that if lock fails once, it will fail forever from that point
        return arg.lock().get();
      }
      template<typename F>
      static boost::function<F> wrap(const boost::weak_ptr<T>& arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg, func, onFail);
      }
    };

    template<typename T> struct BindTransform<T*, true>
    {
      typedef T* type;
      static T* transform(T* const & arg)
      {
        // Note that we assume that lock if successful always return the same pointer
        return arg;
      }
      template<typename F>
      static boost::function<F> wrap(T*const & arg, boost::function<F> func, boost::function<void()> onFail)
      {
        return LockAndCall<boost::weak_ptr<T>, boost::shared_ptr<T>, F>(arg->weakPtr(), func, onFail);
      }
    };

    inline void throwPointerLockException()
    {
      throw PointerLockException();
    }
  }

#ifndef DOXYGEN
  template<typename RF, typename AF>
  boost::function<RF> bind(const AF& fun)
  {
    return fun;
  }
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bind(const AF& fun, const ARG0& arg0 comma ADECL)                                  \
  {                                                                                \
    typedef typename detail::BindTransform<                                                              \
        ARG0,                                                                                \
        boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;  \
    typename Transform::type transformed = Transform::transform(arg0);                                   \
    boost::function<RF> f = boost::bind(fun, transformed comma AUSE);                                    \
    return Transform::wrap(arg0, f, detail::throwPointerLockException);                                  \
  }                                                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bindWithFallback(const boost::function<void()>& onFail,                            \
                                       const AF& fun,                                                    \
                                       const ARG0& arg0 comma ADECL)                                     \
  {                                                                                \
    typedef typename detail::BindTransform<                                                              \
        ARG0,                                                                                \
        boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;  \
    typename Transform::type transformed = Transform::transform(arg0);                                   \
    boost::function<RF> f = boost::bind(fun, transformed comma AUSE);                                    \
    return Transform::wrap(arg0, f, onFail);                                                             \
  }                                                                                \
  template <typename RF, typename AF, typename ARG0 comma ATYPEDECL>                                     \
  boost::function<RF> bindSilent(const AF& fun, const ARG0& arg0 comma ADECL)                            \
  {                                                                                \
    return bindWithFallback<RF, AF, ARG0 comma ATYPES>(boost::function<void()>(), fun, arg0 comma AUSE); \
  }
  QI_GEN(genCall)
#undef genCall
#endif // DOXYGEN
  template<typename F, typename ARG0>
  boost::function<F> track(const boost::function<F>& f, const ARG0& arg0)
  {
    typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
    return Transform::wrap(arg0, f, detail::throwPointerLockException);
  }
  template<typename F, typename ARG0>
  boost::function<F> trackWithFallback(boost::function<void()> onFail,
      const boost::function<F>& f, const ARG0& arg0)
  {
    typedef typename detail::BindTransform<ARG0, boost::is_base_of<TrackableBase, typename boost::remove_pointer<ARG0>::type>::value> Transform;
    return Transform::wrap(arg0, f, onFail);
  }
  template<typename F, typename ARG0>
  boost::function<F> trackSilent(const boost::function<F>& f, const ARG0& arg0)
  {
    return trackWithFallback<F, ARG0>(boost::function<void()>(), f, arg0);
  }
}

#endif  // _QI_DETAILS_TRACKABLE_HXX_
<|endoftext|>


<commit_before><commit_msg>Add D3DTEXTURESTAGESTATETYPE enum decoder to trace.cpp<commit_after><|endoftext|>


<commit_before>#include <QFile>
#include <QLabel>
#include <QTextBrowser>
#include <QVBoxLayout>
#include <QMessageBox>
#include "parser.hpp"

namespace qtreports {
    namespace detail {

        Parser::Parser() {}

        Parser::~Parser() {}

        bool	Parser::parse( const QString & path ) {
            if( !QFile::exists( path ) ) {
                m_lastError = "The file not exists";
                return false;
            }

            QFile file( path );
            file.open( QIODevice::OpenModeFlag::ReadOnly | QIODevice::Text );
            if( !file.isOpen() ) {
                m_lastError = "The file can not be opened";
                return false;
            }

            return parseReport( file.readAll() );
        }

        bool	Parser::parseReport( const QString & text ) {
            QXmlStreamReader reader( text );
            QString message;
            while( !reader.atEnd() ) {
                reader.readNextStartElement();
                if( !reader.isStartElement() ) {
                    continue;
                }

                auto name = reader.name().toString();
                auto attributes = reader.attributes();
                reader.readNext();
                auto data = reader.text().toString();
                message += name + ": " + data + "\n";
                if( name == "detail" ) {
                    if( !parseDetail( data ) ) {
                        break;
                    }
                }
                else if( name == "field" ) {
                    for( auto && attribute : attributes ) {
                        //QMessageBox::warning( 0, "attributes", attribute.name().toString() + ": " + attribute.value().toString() );
                    }
                    if( !parseField( data ) ) {
                        break;
                    }
                }
                //}
            }
            QMessageBox::warning( 0, "", message );

            if( reader.hasError() ) {
                m_lastError = reader.errorString();
                return false;
            }

            createWidget();
            return true;
        }

        bool Parser::parseField( const QString & text ) {
            //QXmlStreamReader reader( text );
            //QMessageBox::warning( 0, "", text );
            //while( !reader.atEnd() ) {
            //    reader.readNext();
            //    auto attributes = reader.attributes();
            //    reader.readNext();
            //}

            return true;
        }

        bool	Parser::parseDetail( const QString & text ) {
            //QXmlStreamReader reader( text );
            //while( !reader.atEnd() ) {
            //reader.readNext();
            //if( reader.isStartElement() ) {
            //auto name = reader.name();
            //if( name == "band" ) {
            //m_data += reader.readElementText();
            //return true;
            //}
            //}
            //reader.readNext();
            //}
            //reader.readNext();
            //text += reader.text().toString();
            //reader.text().toString();

            return true;
        }

        void	Parser::createWidget() {
            m_widget = QWidgetPtr( new QWidget() );
            m_widget->resize( 600, 400 );

            QTextBrowser * browser = new QTextBrowser();
            browser->setText( m_report->asHTML() );

            QVBoxLayout * layout = new QVBoxLayout( m_widget.data() );
            layout->setMargin( 0 );
            layout->addWidget( browser );
        }

        const ReportPtr			Parser::getReport() const {
            return m_report;
        }

        const QString			Parser::getLastError() const {
            return m_lastError;
        }

        const QWidgetPtr		Parser::getWidget() const {
            return m_widget;
        }

        const QVector< Style >	Parser::getStyles() const {
            return m_styles;
        }

    }
}
<commit_msg>Fix Parser<commit_after>#include <QFile>
#include <QLabel>
#include <QTextBrowser>
#include <QVBoxLayout>
#include <QMessageBox>
#include "parser.hpp"

namespace qtreports {
    namespace detail {

        Parser::Parser() {}

        Parser::~Parser() {}

        bool	Parser::parse( const QString & path ) {
            if( !QFile::exists( path ) ) {
                m_lastError = "The file not exists";
                return false;
            }

            QFile file( path );
            file.open( QIODevice::OpenModeFlag::ReadOnly | QIODevice::Text );
            if( !file.isOpen() ) {
                m_lastError = "The file can not be opened";
                return false;
            }

            return parseReport( file.readAll() );
        }

        void     readElement( QXmlStreamReader & reader, QString & message ) {
            QString name( reader.name().toString() ), data;
            while( !reader.atEnd() && !reader.isEndElement() ) {
                reader.readNext();
                if( reader.isStartElement() ) {
                    readElement( reader, message );
                }
                data += reader.text().toString();
            }
            message += name + ": " + data + "1";
        }

        bool	Parser::parseReport( const QString & text ) {
            QXmlStreamReader reader( text );
            /*
            QString message;
            while( !reader.atEnd() ) {
                reader.readNext();
                if( reader.isStartElement() ) {
                    readElement( reader, message );
                    continue;
                }

                auto name = reader.name().toString();
                auto attributes = reader.attributes();
                QString data;
                while( !reader.atEnd() && !reader.isEndElement() && !reader.isStartElement() ) {
                    reader.readNext();
                    data += reader.text().toString();
                }

                //message += name + ": " + data + "\n";
                if( name == "detail" ) {
                    if( !parseDetail( data ) ) {
                        break;
                    }
                }
                else if( name == "field" ) {
                    for( auto && attribute : attributes ) {
                        //QMessageBox::warning( 0, "attributes", attribute.name().toString() + ": " + attribute.value().toString() );
                    }
                    if( !parseField( data ) ) {
                        break;
                    }
                }
            }
            QMessageBox::warning( 0, "", message );
            */
            if( reader.hasError() ) {
                m_lastError = reader.errorString();
                return false;
            }

            createWidget();
            return true;
        }

        bool Parser::parseField( const QString & text ) {
            QXmlStreamReader reader( text );
            //QMessageBox::warning( 0, "", text );
            //while( !reader.atEnd() ) {
            //    reader.readNext();
            //    auto attributes = reader.attributes();
            //    reader.readNext();
            //}

            return true;
        }

        bool	Parser::parseDetail( const QString & text ) {
            QXmlStreamReader reader( text );
            //while( !reader.atEnd() ) {
            //reader.readNext();
            //if( reader.isStartElement() ) {
            //auto name = reader.name();
            //if( name == "band" ) {
            //m_data += reader.readElementText();
            //return true;
            //}
            //}
            //reader.readNext();
            //}
            //reader.readNext();
            //text += reader.text().toString();
            //reader.text().toString();

            return true;
        }

        void	Parser::createWidget() {
            m_widget = QWidgetPtr( new QWidget() );
            m_widget->resize( 600, 400 );

            QTextBrowser * browser = new QTextBrowser();
            browser->setText( m_report->asHTML() );

            QVBoxLayout * layout = new QVBoxLayout( m_widget.data() );
            layout->setMargin( 0 );
            layout->addWidget( browser );
        }

        const ReportPtr			Parser::getReport() const {
            return m_report;
        }

        const QString			Parser::getLastError() const {
            return m_lastError;
        }

        const QWidgetPtr		Parser::getWidget() const {
            return m_widget;
        }

        const QVector< Style >	Parser::getStyles() const {
            return m_styles;
        }

    }
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 - 2013 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "mersdkkitinformation.h"
#include "merconstants.h"
#include "mersdkmanager.h"
#include "meroptionspage.h"
#include "merdevicefactory.h"
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <QPushButton>
#include <QComboBox>
#include <QDir>

namespace Mer {
namespace Internal {

MerSdkKitInformation::MerSdkKitInformation()
{
}

Core::Id MerSdkKitInformation::dataId() const
{
    return Core::Id(Constants::MER_KIT_INFORMATION);
}

unsigned int MerSdkKitInformation::priority() const
{
    return 24;
}

QVariant MerSdkKitInformation::defaultValue(ProjectExplorer::Kit *kit) const
{
    const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
    if (sdk)
        return sdk->virtualMachineName();
    return QVariant();
}

QList<ProjectExplorer::Task> MerSdkKitInformation::validate(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        const QString &vmName = kit->value(Core::Id(Constants::VM_NAME)).toString();
        if (!MerSdkManager::instance()->sdk(vmName)) {
            const QString message = QCoreApplication::translate("MerSdk",
                                                                "No valid MerSdk virtual machine %1 found").arg(vmName);
            return QList<ProjectExplorer::Task>() << ProjectExplorer::Task(ProjectExplorer::Task::Error, message, Utils::FileName(), -1,
                                                                           Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
        }
    }
    return QList<ProjectExplorer::Task>();
}

MerSdk* MerSdkKitInformation::sdk(const ProjectExplorer::Kit *kit)
{
    if (!kit)
        return 0;
    return MerSdkManager::instance()->sdk(kit->value(Core::Id(Constants::VM_NAME)).toString());
}

ProjectExplorer::KitInformation::ItemList MerSdkKitInformation::toUserOutput(ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        QString vmName;
        MerSdk* sdk = MerSdkKitInformation::sdk(kit);
        if (sdk)
            vmName = sdk->virtualMachineName();
        return ProjectExplorer::KitInformation::ItemList()
                << qMakePair(tr("MerSdk"),vmName);
    }
    return ProjectExplorer::KitInformation::ItemList();
}

ProjectExplorer::KitConfigWidget *MerSdkKitInformation::createConfigWidget(ProjectExplorer::Kit *kit) const
{
    return new MerSdkKitInformationWidget(kit);
}

void MerSdkKitInformation::setSdk(ProjectExplorer::Kit *kit, const MerSdk* sdk)
{
    kit->setValue(Core::Id(Constants::VM_NAME),sdk->virtualMachineName());
}

void MerSdkKitInformation::addToEnvironment(const ProjectExplorer::Kit *kit, Utils::Environment &env) const
{
    const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
    if (sdk) {
	const QString sshPort = QString::number(sdk->sshPort());
	const QString sharedHome = QDir::fromNativeSeparators(sdk->sharedHomePath());
	const QString sharedTarget = QDir::fromNativeSeparators(sdk->sharedTargetsPath());

	env.appendOrSet(QLatin1String(Constants::MER_SSH_USERNAME),
	                QLatin1String(Constants::MER_SDK_DEFAULTUSER));
	env.appendOrSet(QLatin1String(Constants::MER_SSH_PORT), sshPort);
	env.appendOrSet(QLatin1String(Constants::MER_SSH_PRIVATE_KEY), sdk->privateKeyFile());
	env.appendOrSet(QLatin1String(Constants::MER_SSH_SHARED_HOME), sharedHome);
	env.appendOrSet(QLatin1String(Constants::MER_SSH_SHARED_TARGET), sharedTarget);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////

MerSdkKitInformationWidget::MerSdkKitInformationWidget(ProjectExplorer::Kit *kit)
    : ProjectExplorer::KitConfigWidget(kit),
      m_combo(new QComboBox),
      m_manageButton(new QPushButton(tr("Manage...")))
{
    m_combo->addItem(tr("None"), -1);
    handleSdksUpdated();
    refresh();
    connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged()));
    connect(MerSdkManager::instance(), SIGNAL(sdksUpdated()), this, SLOT(handleSdksUpdated()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(handleManageClicked()));
}

QString MerSdkKitInformationWidget::displayName() const
{
    return tr("Mer SDK:");
}

QString MerSdkKitInformationWidget::toolTip() const
{
    return tr("Name of virtual machine used as Mer SDK.");
}

void MerSdkKitInformationWidget::makeReadOnly()
{
    m_combo->setEnabled(false);
}

void MerSdkKitInformationWidget::refresh()
{
    m_combo->setCurrentIndex(findMerSdk(MerSdkKitInformation::sdk(m_kit)));
}

bool MerSdkKitInformationWidget::visibleInKit()
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(m_kit));
}

QWidget *MerSdkKitInformationWidget::mainWidget() const
{
    return m_combo;
}

QWidget *MerSdkKitInformationWidget::buttonWidget() const
{
    return m_manageButton;
}

int MerSdkKitInformationWidget::findMerSdk(const MerSdk *sdk) const
{
    if (sdk) {
        for (int i = 0; i < m_combo->count(); ++i) {
            if (sdk->virtualMachineName() == m_combo->currentText())
                return i;
        }
    }
    return -1;
}

void MerSdkKitInformationWidget::handleSdksUpdated()
{
    const QList<MerSdk*>& sdks = MerSdkManager::instance()->sdks();
    m_combo->clear();
    foreach (const MerSdk *sdk, sdks)
        m_combo->addItem(sdk->virtualMachineName());
}

void MerSdkKitInformationWidget::handleManageClicked()
{
    MerOptionsPage *page = ExtensionSystem::PluginManager::getObject<MerOptionsPage>();
    if (page)
        page->setSdk(m_combo->currentText());
    Core::ICore::showOptionsDialog(Constants::MER_OPTIONS_CATEGORY,Constants::MER_OPTIONS_ID);
}

void MerSdkKitInformationWidget::handleCurrentIndexChanged()
{
    const MerSdk* sdk = MerSdkManager::instance()->sdk(m_combo->currentText());
    if (sdk)
        MerSdkKitInformation::setSdk(m_kit, sdk);
}

}
}
<commit_msg>Jolla: Change tabs to spaces<commit_after>/****************************************************************************
**
** Copyright (C) 2012 - 2013 Jolla Ltd.
** Contact: http://jolla.com/
**
** This file is part of Qt Creator.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Digia.
**
****************************************************************************/

#include "mersdkkitinformation.h"
#include "merconstants.h"
#include "mersdkmanager.h"
#include "meroptionspage.h"
#include "merdevicefactory.h"
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <QPushButton>
#include <QComboBox>
#include <QDir>

namespace Mer {
namespace Internal {

MerSdkKitInformation::MerSdkKitInformation()
{
}

Core::Id MerSdkKitInformation::dataId() const
{
    return Core::Id(Constants::MER_KIT_INFORMATION);
}

unsigned int MerSdkKitInformation::priority() const
{
    return 24;
}

QVariant MerSdkKitInformation::defaultValue(ProjectExplorer::Kit *kit) const
{
    const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
    if (sdk)
        return sdk->virtualMachineName();
    return QVariant();
}

QList<ProjectExplorer::Task> MerSdkKitInformation::validate(const ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        const QString &vmName = kit->value(Core::Id(Constants::VM_NAME)).toString();
        if (!MerSdkManager::instance()->sdk(vmName)) {
            const QString message = QCoreApplication::translate("MerSdk",
                                                                "No valid MerSdk virtual machine %1 found").arg(vmName);
            return QList<ProjectExplorer::Task>() << ProjectExplorer::Task(ProjectExplorer::Task::Error, message, Utils::FileName(), -1,
                                                                           Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
        }
    }
    return QList<ProjectExplorer::Task>();
}

MerSdk* MerSdkKitInformation::sdk(const ProjectExplorer::Kit *kit)
{
    if (!kit)
        return 0;
    return MerSdkManager::instance()->sdk(kit->value(Core::Id(Constants::VM_NAME)).toString());
}

ProjectExplorer::KitInformation::ItemList MerSdkKitInformation::toUserOutput(ProjectExplorer::Kit *kit) const
{
    if (MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(kit))) {
        QString vmName;
        MerSdk* sdk = MerSdkKitInformation::sdk(kit);
        if (sdk)
            vmName = sdk->virtualMachineName();
        return ProjectExplorer::KitInformation::ItemList()
                << qMakePair(tr("MerSdk"),vmName);
    }
    return ProjectExplorer::KitInformation::ItemList();
}

ProjectExplorer::KitConfigWidget *MerSdkKitInformation::createConfigWidget(ProjectExplorer::Kit *kit) const
{
    return new MerSdkKitInformationWidget(kit);
}

void MerSdkKitInformation::setSdk(ProjectExplorer::Kit *kit, const MerSdk* sdk)
{
    kit->setValue(Core::Id(Constants::VM_NAME),sdk->virtualMachineName());
}

void MerSdkKitInformation::addToEnvironment(const ProjectExplorer::Kit *kit, Utils::Environment &env) const
{
    const MerSdk *sdk = MerSdkKitInformation::sdk(kit);
    if (sdk) {
        const QString sshPort = QString::number(sdk->sshPort());
        const QString sharedHome = QDir::fromNativeSeparators(sdk->sharedHomePath());
        const QString sharedTarget = QDir::fromNativeSeparators(sdk->sharedTargetsPath());

        env.appendOrSet(QLatin1String(Constants::MER_SSH_USERNAME),
                        QLatin1String(Constants::MER_SDK_DEFAULTUSER));
        env.appendOrSet(QLatin1String(Constants::MER_SSH_PORT), sshPort);
        env.appendOrSet(QLatin1String(Constants::MER_SSH_PRIVATE_KEY), sdk->privateKeyFile());
        env.appendOrSet(QLatin1String(Constants::MER_SSH_SHARED_HOME), sharedHome);
        env.appendOrSet(QLatin1String(Constants::MER_SSH_SHARED_TARGET), sharedTarget);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////

MerSdkKitInformationWidget::MerSdkKitInformationWidget(ProjectExplorer::Kit *kit)
    : ProjectExplorer::KitConfigWidget(kit),
      m_combo(new QComboBox),
      m_manageButton(new QPushButton(tr("Manage...")))
{
    m_combo->addItem(tr("None"), -1);
    handleSdksUpdated();
    refresh();
    connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged()));
    connect(MerSdkManager::instance(), SIGNAL(sdksUpdated()), this, SLOT(handleSdksUpdated()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(handleManageClicked()));
}

QString MerSdkKitInformationWidget::displayName() const
{
    return tr("Mer SDK:");
}

QString MerSdkKitInformationWidget::toolTip() const
{
    return tr("Name of virtual machine used as Mer SDK.");
}

void MerSdkKitInformationWidget::makeReadOnly()
{
    m_combo->setEnabled(false);
}

void MerSdkKitInformationWidget::refresh()
{
    m_combo->setCurrentIndex(findMerSdk(MerSdkKitInformation::sdk(m_kit)));
}

bool MerSdkKitInformationWidget::visibleInKit()
{
    return MerDeviceFactory::canCreate(ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(m_kit));
}

QWidget *MerSdkKitInformationWidget::mainWidget() const
{
    return m_combo;
}

QWidget *MerSdkKitInformationWidget::buttonWidget() const
{
    return m_manageButton;
}

int MerSdkKitInformationWidget::findMerSdk(const MerSdk *sdk) const
{
    if (sdk) {
        for (int i = 0; i < m_combo->count(); ++i) {
            if (sdk->virtualMachineName() == m_combo->currentText())
                return i;
        }
    }
    return -1;
}

void MerSdkKitInformationWidget::handleSdksUpdated()
{
    const QList<MerSdk*>& sdks = MerSdkManager::instance()->sdks();
    m_combo->clear();
    foreach (const MerSdk *sdk, sdks)
        m_combo->addItem(sdk->virtualMachineName());
}

void MerSdkKitInformationWidget::handleManageClicked()
{
    MerOptionsPage *page = ExtensionSystem::PluginManager::getObject<MerOptionsPage>();
    if (page)
        page->setSdk(m_combo->currentText());
    Core::ICore::showOptionsDialog(Constants::MER_OPTIONS_CATEGORY,Constants::MER_OPTIONS_ID);
}

void MerSdkKitInformationWidget::handleCurrentIndexChanged()
{
    const MerSdk* sdk = MerSdkManager::instance()->sdk(m_combo->currentText());
    if (sdk)
        MerSdkKitInformation::setSdk(m_kit, sdk);
}

}
}
<|endoftext|>


<commit_before>/*
  Copyright (C) 2008-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "commandverifier.h"
#include <IrcConnection>
#include <IrcCommand>
#include <IrcMessage>

int CommandVerifier::Private::id = 1;

CommandVerifier::CommandVerifier(IrcConnection* connection) : QObject(connection)
{
    d.connection = connection;
    connection->installMessageFilter(this);
    connection->installCommandFilter(this);
}

int CommandVerifier::identify(IrcMessage* message) const
{
    if (message->type() == IrcMessage::Private) {
        QMapIterator<int, IrcCommand*> it(d.commands);
        while (it.hasNext()) {
            IrcMessage* cmd = it.next().value()->toMessage(message->prefix(), message->connection());
            if (cmd) {
                cmd->deleteLater();
                if (cmd->toData() == QString::fromUtf8(message->toData()))
                    return it.key();
            }
        }
    }
    return 0;
}

bool CommandVerifier::messageFilter(IrcMessage* message)
{
    if (message->type() == IrcMessage::Pong) {
        QString arg = static_cast<IrcPongMessage*>(message)->argument();
        if (arg.startsWith("communi/")) {
            bool ok = false;
            int id = arg.mid(8).toInt(&ok);
            if (ok) {
                IrcCommand* command = d.commands.take(id);
                if (command) {
                    emit verified(id);
                    command->deleteLater();
                    return true;
                }
            }
        }
    }
    return false;
}

bool CommandVerifier::commandFilter(IrcCommand* command)
{
    if (!command->parent() && command->type() == IrcCommand::Message) {
        command->setParent(this); // take ownership
        d.id = qMax(1, d.id + 1); // overflow -> 1
        d.commands.insert(d.id, command);
        d.connection->sendCommand(command);
        d.connection->sendData("PING communi/" + QByteArray::number(d.id));
        return true;
    }
    return false;
}
<commit_msg>CommandVerifier::messageFilter(): bail out early<commit_after>/*
  Copyright (C) 2008-2015 The Communi Project

  You may use this file under the terms of BSD license as follows:

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the copyright holder nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "commandverifier.h"
#include <IrcConnection>
#include <IrcCommand>
#include <IrcMessage>

int CommandVerifier::Private::id = 1;

CommandVerifier::CommandVerifier(IrcConnection* connection) : QObject(connection)
{
    d.connection = connection;
    connection->installMessageFilter(this);
    connection->installCommandFilter(this);
}

int CommandVerifier::identify(IrcMessage* message) const
{
    if (message->type() == IrcMessage::Private) {
        QMapIterator<int, IrcCommand*> it(d.commands);
        while (it.hasNext()) {
            IrcMessage* cmd = it.next().value()->toMessage(message->prefix(), message->connection());
            if (cmd) {
                cmd->deleteLater();
                if (cmd->toData() == QString::fromUtf8(message->toData()))
                    return it.key();
            }
        }
    }
    return 0;
}

bool CommandVerifier::messageFilter(IrcMessage* message)
{
    if (d.commands.isEmpty())
        return false;

    if (message->type() == IrcMessage::Pong) {
        QString arg = static_cast<IrcPongMessage*>(message)->argument();
        if (arg.startsWith("communi/")) {
            bool ok = false;
            int id = arg.mid(8).toInt(&ok);
            if (ok) {
                IrcCommand* command = d.commands.take(id);
                if (command) {
                    emit verified(id);
                    command->deleteLater();
                    return true;
                }
            }
        }
    }
    return false;
}

bool CommandVerifier::commandFilter(IrcCommand* command)
{
    if (!command->parent() && command->type() == IrcCommand::Message) {
        command->setParent(this); // take ownership
        d.id = qMax(1, d.id + 1); // overflow -> 1
        d.commands.insert(d.id, command);
        d.connection->sendCommand(command);
        d.connection->sendData("PING communi/" + QByteArray::number(d.id));
        return true;
    }
    return false;
}
<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_NETWORK_ABSTRACT_SOCKET_HPP_
#define POSEIDON_NETWORK_ABSTRACT_SOCKET_HPP_

#include "../fwd.hpp"

namespace poseidon {

class Abstract_Socket
  : public virtual ::asteria::Rcbase
  {
    friend Network_Driver;

  public:
    enum IO_Result
      {
        io_result_end_of_stream  = 0,
        io_result_would_block    = 1,
        io_result_interrupted    = 2,
      };

  private:
    unique_posix_fd m_fd;

  public:
    explicit
    Abstract_Socket(unique_posix_fd&& fd)
      : m_fd(::std::move(fd))
      { this->do_set_common_options();  }

    ASTERIA_NONCOPYABLE_DESTRUCTOR(Abstract_Socket);

  private:
    // Enables non-blocking mode, etc.
    void
    do_set_common_options();

  protected:
    // The network driver notifies incoming data via this callback.
    // `lock` shall lock `*this` after the call if locking is supported.
    // `hint` points to a temporary buffer of `size` bytes that may be used by this
    // function for any purpose.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    IO_Result
    do_on_async_read(::rocket::mutex::unique_lock& lock, void* hint, size_t size)
      = 0;

    // This function shall return the number of bytes that are pending for writing.
    // `lock` shall lock `*this` after the call if locking is supported.
    virtual
    size_t
    do_write_queue_size(::rocket::mutex::unique_lock& lock)
    const
      = 0;

    // The network driver notifies possibility of outgoing data via this callback.
    // `lock` shall lock `*this` after the call if locking is supported.
    // `hint` points to a temporary buffer of `size` bytes that may be used by this
    // function for any purpose.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    IO_Result
    do_on_async_write(::rocket::mutex::unique_lock& lock, void* hint, size_t size)
      = 0;

    // The network driver notifies closure via this callback.
    // `err` is zero for graceful shutdown.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    void
    do_on_async_shutdown(int err)
      = 0;

  public:
    // Returns the stream descriptor.
    // This is used to query and adjust stream flags. You shall not perform I/O
    // operations on it.
    ROCKET_PURE_FUNCTION
    int
    get_fd()
    const noexcept
      { return this->m_fd;  }

    // Causes abnormal termination of this stream.
    // Any data that have not been delivered to the other peer are discarded.
    // The other peer is likely to see a 'connection reset by peer' error.
    void
    terminate()
    noexcept;

    // Gets the (bound) address of the local peer.
    Socket_Address
    get_local_address()
    const;

    // Gets the (connected) address of the remote peer.
    // This function throws an exception if no peer has connected.
    Socket_Address
    get_remote_address()
    const;
  };

}  // namespace poseidon

#endif
<commit_msg>network/accept_socket: Update `IO_Result`<commit_after>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_NETWORK_ABSTRACT_SOCKET_HPP_
#define POSEIDON_NETWORK_ABSTRACT_SOCKET_HPP_

#include "../fwd.hpp"

namespace poseidon {

class Abstract_Socket
  : public virtual ::asteria::Rcbase
  {
    friend Network_Driver;

  public:
    enum IO_Result
      {
        io_result_success        = 0,
        io_result_end_of_stream  = 1,
        io_result_would_block    = 2,
        io_result_interrupted    = 3,
      };

  private:
    unique_posix_fd m_fd;

  public:
    explicit
    Abstract_Socket(unique_posix_fd&& fd)
      : m_fd(::std::move(fd))
      { this->do_set_common_options();  }

    ASTERIA_NONCOPYABLE_DESTRUCTOR(Abstract_Socket);

  private:
    // Enables non-blocking mode, etc.
    void
    do_set_common_options();

  protected:
    // The network driver notifies incoming data via this callback.
    // `lock` shall lock `*this` after the call if locking is supported.
    // `hint` points to a temporary buffer of `size` bytes that may be used by this
    // function for any purpose.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    IO_Result
    do_on_async_read(::rocket::mutex::unique_lock& lock, void* hint, size_t size)
      = 0;

    // This function shall return the number of bytes that are pending for writing.
    // `lock` shall lock `*this` after the call if locking is supported.
    virtual
    size_t
    do_write_queue_size(::rocket::mutex::unique_lock& lock)
    const
      = 0;

    // The network driver notifies possibility of outgoing data via this callback.
    // `lock` shall lock `*this` after the call if locking is supported.
    // `hint` points to a temporary buffer of `size` bytes that may be used by this
    // function for any purpose.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    IO_Result
    do_on_async_write(::rocket::mutex::unique_lock& lock, void* hint, size_t size)
      = 0;

    // The network driver notifies closure via this callback.
    // `err` is zero for graceful shutdown.
    // Please mind thread safety, as this function is called by the network thread.
    virtual
    void
    do_on_async_shutdown(int err)
      = 0;

  public:
    // Returns the stream descriptor.
    // This is used to query and adjust stream flags. You shall not perform I/O
    // operations on it.
    ROCKET_PURE_FUNCTION
    int
    get_fd()
    const noexcept
      { return this->m_fd;  }

    // Causes abnormal termination of this stream.
    // Any data that have not been delivered to the other peer are discarded.
    // The other peer is likely to see a 'connection reset by peer' error.
    void
    terminate()
    noexcept;

    // Gets the (bound) address of the local peer.
    Socket_Address
    get_local_address()
    const;

    // Gets the (connected) address of the remote peer.
    // This function throws an exception if no peer has connected.
    Socket_Address
    get_remote_address()
    const;
  };

}  // namespace poseidon

#endif
<|endoftext|>


<commit_before>
#include "cg-operator-common.h"
#include <binpac/autogen/operators/function.h>

using namespace binpac;
using namespace binpac::codegen;

void CodeBuilder::visit(expression::operator_::function::Call* i)
{
    auto func = ast::checkedCast<expression::Function>(i->op1());
    auto args = callParameters(i->op2());

    shared_ptr<hilti::Expression> cookie = nullptr;

    if ( in<declaration::Function>() || in<declaration::Hook>() )
        cookie = hilti::builder::id::create("__cookie", i->location());
    else
        cookie = hilti::builder::reference::createNull(i->location());

    auto result = cg()->hiltiCall(func, args, cookie);
    setResult(result);
}
<commit_msg>Fix for in-unit hooks not passing the cookie on to C.<commit_after>
#include "cg-operator-common.h"
#include <binpac/autogen/operators/function.h>

using namespace binpac;
using namespace binpac::codegen;

void CodeBuilder::visit(expression::operator_::function::Call* i)
{
    auto func = ast::checkedCast<expression::Function>(i->op1());
    auto args = callParameters(i->op2());

    shared_ptr<hilti::Expression> cookie = nullptr;

    if ( in<declaration::Function>() || in<declaration::Hook>() || in<declaration::Type>() )
        cookie = hilti::builder::id::create("__cookie", i->location());
    else
        cookie = hilti::builder::reference::createNull(i->location());

    auto result = cg()->hiltiCall(func, args, cookie);
    setResult(result);
}
<|endoftext|>