<commit_before>#ifndef BLOCKUNTILKEYUP_HPP
#define BLOCKUNTILKEYUP_HPP

#include "FromEvent.hpp"
#include "ParamsUnion.hpp"
#include "Types.hpp"

namespace org_pqrs_Karabiner {
  namespace RemapFunc {
    class BlockUntilKeyUp {
    public:
      void add(AddDataType datatype, AddValue newval);
      const FromEvent& getFromEvent(void) const { return fromEvent_; }

    private:
      FromEvent fromEvent_;
    };
  }
}

#endif
<commit_msg>use RemapFuncBase<commit_after>#ifndef BLOCKUNTILKEYUP_HPP
#define BLOCKUNTILKEYUP_HPP

#include "RemapFuncBase.hpp"

namespace org_pqrs_Karabiner {
  namespace RemapFunc {
    class BlockUntilKeyUp : RemapFuncBase {
    public:
      BlockUntilKeyUp(void) :
        RemapFuncBase(BRIDGE_REMAPTYPE_BLOCKUNTILKEYUP)
      {}

      void add(AddDataType datatype, AddValue newval);
      const FromEvent& getFromEvent(void) const { return fromEvent_; }

    private:
      FromEvent fromEvent_;
    };
  }
}

#endif
<|endoftext|>


<commit_before>#ifndef KEYUPEVENTTOKEY_HPP
#define KEYUPEVENTTOKEY_HPP

#include "KeyToKey.hpp"
#include "List.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  namespace RemapFunc {
    class KeyUpEventToKey {
    public:
      static void static_initialize(void);
      static void static_terminate(void);

      KeyUpEventToKey(void) : preserveKeyDownOrder_(false) {}

      bool remap(RemapParams& remapParams);

      // ========================================
      // __KeyUpEventToKey__ syntax
      //
      // <autogen>
      //   __KeyUpEventToKey__
      //   @begin
      //   FromEvent, FromFlags,
      //   ToKeys_when_KeyDown,
      //   @end
      //
      //   @begin
      //   KeyUpFlags,
      //   ToKeys_when_KeyUp,
      //   @end
      //
      //   ...
      //
      //   @begin
      //   KeyUpFlags,
      //   ToKeys_when_KeyUp,
      //   @end
      //
      // </autogen>
      //
      //
      // * You can omit FromFlags, ToKeys_when_KeyDown, KeyUpFlags.
      //
      // ========================================
      // Example:
      //
      // <autogen>
      //   __KeyUpEventToKey__
      //   @begin
      //   KeyCode::A, ModifierFlag::SHIFT_L,    (effective when A key is pressed with left shift key.)
      //   @end
      //
      //   @begin
      //   ModifierFlag::SHIFT_L                 (when A key is released with left shift key.)
      //   KeyCode::ESCAPE,                      (send escape key.)
      //   @end
      //
      //   @begin
      //   KeyCode::A                            (when A key is released, send A key.)
      //   @end
      // </autogen>
      //

      void add(AddDataType datatype, AddValue newval);

      class Item : public List::Item {
      public:
        Item(KeyUpEventToKey& k) : keyUpEventToKey_(k) {}
        KeyUpEventToKey& get(void) { return keyUpEventToKey_; }

      private:
        KeyUpEventToKey& keyUpEventToKey_;
      };

    private:
      void doKeyUp(void);

      KeyToKey fromKeyToKey_;
      Vector_KeyToKey toKeyToKeys_;
      bool preserveKeyDownOrder_;

      // Queue for Option::KEYUPEVENTTOKEY_PRESERVE_KEYDOWN_ORDER.
      static List queue_;
    };
  }
}

#endif
<commit_msg>add ~Item<commit_after>#ifndef KEYUPEVENTTOKEY_HPP
#define KEYUPEVENTTOKEY_HPP

#include "KeyToKey.hpp"
#include "List.hpp"

namespace org_pqrs_KeyRemap4MacBook {
  namespace RemapFunc {
    class KeyUpEventToKey {
    public:
      static void static_initialize(void);
      static void static_terminate(void);

      KeyUpEventToKey(void) : preserveKeyDownOrder_(false) {}

      bool remap(RemapParams& remapParams);

      // ========================================
      // __KeyUpEventToKey__ syntax
      //
      // <autogen>
      //   __KeyUpEventToKey__
      //   @begin
      //   FromEvent, FromFlags,
      //   ToKeys_when_KeyDown,
      //   @end
      //
      //   @begin
      //   KeyUpFlags,
      //   ToKeys_when_KeyUp,
      //   @end
      //
      //   ...
      //
      //   @begin
      //   KeyUpFlags,
      //   ToKeys_when_KeyUp,
      //   @end
      //
      // </autogen>
      //
      //
      // * You can omit FromFlags, ToKeys_when_KeyDown, KeyUpFlags.
      //
      // ========================================
      // Example:
      //
      // <autogen>
      //   __KeyUpEventToKey__
      //   @begin
      //   KeyCode::A, ModifierFlag::SHIFT_L,    (effective when A key is pressed with left shift key.)
      //   @end
      //
      //   @begin
      //   ModifierFlag::SHIFT_L                 (when A key is released with left shift key.)
      //   KeyCode::ESCAPE,                      (send escape key.)
      //   @end
      //
      //   @begin
      //   KeyCode::A                            (when A key is released, send A key.)
      //   @end
      // </autogen>
      //

      void add(AddDataType datatype, AddValue newval);

      class Item : public List::Item {
      public:
        Item(KeyUpEventToKey& k) : keyUpEventToKey_(k) {}
        virtual ~Item(void) {}

        KeyUpEventToKey& get(void) { return keyUpEventToKey_; }

      private:
        KeyUpEventToKey& keyUpEventToKey_;
      };

    private:
      void doKeyUp(void);

      KeyToKey fromKeyToKey_;
      Vector_KeyToKey toKeyToKeys_;
      bool preserveKeyDownOrder_;

      // Queue for Option::KEYUPEVENTTOKEY_PRESERVE_KEYDOWN_ORDER.
      static List queue_;
    };
  }
}

#endif
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2016 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 <grpc/support/port_platform.h>

#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/memory.h"

#include <string.h>
#include <algorithm>

#include <grpc/support/alloc.h>

//
// grpc_handshaker_factory_list
//

namespace grpc_core {

namespace {

class HandshakerFactoryList {
 public:
  void Register(bool at_start, UniquePtr<HandshakerFactory> factory);
  void AddHandshakers(const grpc_channel_args* args,
                      grpc_pollset_set* interested_parties,
                      HandshakeManager* handshake_mgr);

 private:
  InlinedVector<UniquePtr<HandshakerFactory>, 2> factories_;
};

HandshakerFactoryList* g_handshaker_factory_lists = nullptr;

}  // namespace

void HandshakerFactoryList::Register(bool at_start,
                                     UniquePtr<HandshakerFactory> factory) {
  factories_.push_back(std::move(factory));
  if (at_start) {
    auto* end = &factories_[factories_.size() - 1];
    std::rotate(&factories_[0], end, end + 1);
  }
}

void HandshakerFactoryList::AddHandshakers(const grpc_channel_args* args,
                                           grpc_pollset_set* interested_parties,
                                           HandshakeManager* handshake_mgr) {
  for (size_t idx = 0; idx < factories_.size(); ++idx) {
    auto& handshaker_factory = factories_[idx];
    handshaker_factory->AddHandshakers(args, interested_parties, handshake_mgr);
  }
}

//
// plugin
//

void HandshakerRegistry::Init() {
  GPR_ASSERT(g_handshaker_factory_lists == nullptr);
  g_handshaker_factory_lists = static_cast<HandshakerFactoryList*>(
      gpr_malloc(sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES));
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) {
    auto factory_list = g_handshaker_factory_lists + idx;
    new (factory_list) HandshakerFactoryList();
  }
}

void HandshakerRegistry::Shutdown() {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) {
    auto factory_list = g_handshaker_factory_lists + idx;
    factory_list->~HandshakerFactoryList();
  }
  gpr_free(g_handshaker_factory_lists);
  g_handshaker_factory_lists = nullptr;
}

void HandshakerRegistry::RegisterHandshakerFactory(
    bool at_start, HandshakerType handshaker_type,
    UniquePtr<HandshakerFactory> factory) {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  auto& factory_list = g_handshaker_factory_lists[handshaker_type];
  factory_list.Register(at_start, std::move(factory));
}

void HandshakerRegistry::AddHandshakers(HandshakerType handshaker_type,
                                        const grpc_channel_args* args,
                                        grpc_pollset_set* interested_parties,
                                        HandshakeManager* handshake_mgr) {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  auto& factory_list = g_handshaker_factory_lists[handshaker_type];
  factory_list.AddHandshakers(args, interested_parties, handshake_mgr);
}

}  // namespace grpc_core
<commit_msg>grpc: aligned creation of handshaker factory lists<commit_after>/*
 *
 * Copyright 2016 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 <grpc/support/port_platform.h>

#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/memory.h"

#include <string.h>
#include <algorithm>

#include <grpc/support/alloc.h>

//
// grpc_handshaker_factory_list
//

namespace grpc_core {

namespace {

class HandshakerFactoryList {
 public:
  void Register(bool at_start, UniquePtr<HandshakerFactory> factory);
  void AddHandshakers(const grpc_channel_args* args,
                      grpc_pollset_set* interested_parties,
                      HandshakeManager* handshake_mgr);

 private:
  InlinedVector<UniquePtr<HandshakerFactory>, 2> factories_;
};

HandshakerFactoryList* g_handshaker_factory_lists = nullptr;

}  // namespace

void HandshakerFactoryList::Register(bool at_start,
                                     UniquePtr<HandshakerFactory> factory) {
  factories_.push_back(std::move(factory));
  if (at_start) {
    auto* end = &factories_[factories_.size() - 1];
    std::rotate(&factories_[0], end, end + 1);
  }
}

void HandshakerFactoryList::AddHandshakers(const grpc_channel_args* args,
                                           grpc_pollset_set* interested_parties,
                                           HandshakeManager* handshake_mgr) {
  for (size_t idx = 0; idx < factories_.size(); ++idx) {
    auto& handshaker_factory = factories_[idx];
    handshaker_factory->AddHandshakers(args, interested_parties, handshake_mgr);
  }
}

//
// plugin
//

void HandshakerRegistry::Init() {
  GPR_ASSERT(g_handshaker_factory_lists == nullptr);
  g_handshaker_factory_lists =
      static_cast<HandshakerFactoryList*>(gpr_malloc_aligned(
          sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES,
          GPR_MAX_ALIGNMENT));

  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) {
    auto factory_list = g_handshaker_factory_lists + idx;
    new (factory_list) HandshakerFactoryList();
  }
}

void HandshakerRegistry::Shutdown() {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) {
    auto factory_list = g_handshaker_factory_lists + idx;
    factory_list->~HandshakerFactoryList();
  }
  gpr_free_aligned(g_handshaker_factory_lists);
  g_handshaker_factory_lists = nullptr;
}

void HandshakerRegistry::RegisterHandshakerFactory(
    bool at_start, HandshakerType handshaker_type,
    UniquePtr<HandshakerFactory> factory) {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  auto& factory_list = g_handshaker_factory_lists[handshaker_type];
  factory_list.Register(at_start, std::move(factory));
}

void HandshakerRegistry::AddHandshakers(HandshakerType handshaker_type,
                                        const grpc_channel_args* args,
                                        grpc_pollset_set* interested_parties,
                                        HandshakeManager* handshake_mgr) {
  GPR_ASSERT(g_handshaker_factory_lists != nullptr);
  auto& factory_list = g_handshaker_factory_lists[handshaker_type];
  factory_list.AddHandshakers(args, interested_parties, handshake_mgr);
}

}  // namespace grpc_core
<|endoftext|>


<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 <grpc/support/port_platform.h>

#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET_RESOLVE_ADDRESS

#include <string.h>
#include <sys/types.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>

#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resolve_address_posix.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/transport/error_utils.h"

namespace grpc_core {
namespace {

void NativeDNSRequest(
    std::string name, std::string default_port,
    std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
        on_done) {
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run(
      [name = std::move(name), default_port = std::move(default_port),
       on_done = std::move(on_done)]() mutable {
        ApplicationCallbackExecCtx callback_exec_ctx;
        ExecCtx exec_ctx;
        auto result =
            GetDNSResolver()->LookupHostnameBlocking(name, default_port);
        // running inline is safe since we've already been scheduled on the
        // executor
        on_done(std::move(result));
      });
}

}  // namespace

DNSResolver::TaskHandle NativeDNSResolver::LookupHostname(
    std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
        on_done,
    absl::string_view name, absl::string_view default_port,
    Duration /* timeout */, grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  NativeDNSRequest(std::string(name), std::string(default_port),
                   std::move(on_done));
  return kNullHandle;
}

absl::StatusOr<std::vector<grpc_resolved_address>>
NativeDNSResolver::LookupHostnameBlocking(absl::string_view name,
                                          absl::string_view default_port) {
  ExecCtx exec_ctx;
  struct addrinfo hints;
  struct addrinfo *result = nullptr, *resp;
  int s;
  size_t i;
  grpc_error_handle err;
  std::vector<grpc_resolved_address> addresses;
  std::string host;
  std::string port;
  // parse name, splitting it into host and port parts
  SplitHostPort(name, &host, &port);
  if (host.empty()) {
    err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
                             StatusStrProperty::kTargetAddress, name);
    goto done;
  }
  if (port.empty()) {
    if (default_port.empty()) {
      err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
                               StatusStrProperty::kTargetAddress, name);
      goto done;
    }
    port = std::string(default_port);
  }
  // Call getaddrinfo
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;     /* ipv4 or ipv6 */
  hints.ai_socktype = SOCK_STREAM; /* stream socket */
  hints.ai_flags = AI_PASSIVE;     /* for wildcard IP address */
  GRPC_SCHEDULING_START_BLOCKING_REGION;
  s = getaddrinfo(host.c_str(), port.c_str(), &hints, &result);
  GRPC_SCHEDULING_END_BLOCKING_REGION;
  if (s != 0) {
    // Retry if well-known service name is recognized
    const char* svc[][2] = {{"http", "80"}, {"https", "443"}};
    for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
      if (port == svc[i][0]) {
        GRPC_SCHEDULING_START_BLOCKING_REGION;
        s = getaddrinfo(host.c_str(), svc[i][1], &hints, &result);
        GRPC_SCHEDULING_END_BLOCKING_REGION;
        break;
      }
    }
  }
  if (s != 0) {
    err = grpc_error_set_str(
        grpc_error_set_str(
            grpc_error_set_str(
                grpc_error_set_int(GRPC_ERROR_CREATE(gai_strerror(s)),
                                   StatusIntProperty::kErrorNo, s),
                StatusStrProperty::kOsError, gai_strerror(s)),
            StatusStrProperty::kSyscall, "getaddrinfo"),
        StatusStrProperty::kTargetAddress, name);
    goto done;
  }
  // Success path: fill in addrs
  for (resp = result; resp != nullptr; resp = resp->ai_next) {
    grpc_resolved_address addr;
    memcpy(&addr.addr, resp->ai_addr, resp->ai_addrlen);
    addr.len = resp->ai_addrlen;
    addresses.push_back(addr);
  }
  err = absl::OkStatus();
done:
  if (result) {
    freeaddrinfo(result);
  }
  if (err.ok()) {
    return addresses;
  }
  auto error_result = grpc_error_to_absl_status(err);
  return error_result;
}

DNSResolver::TaskHandle NativeDNSResolver::LookupSRV(
    std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
        on_resolved,
    absl::string_view /* name */, Duration /* timeout */,
    grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run([on_resolved] {
    ApplicationCallbackExecCtx app_exec_ctx;
    ExecCtx exec_ctx;
    on_resolved(absl::UnimplementedError(
        "The Native resolver does not support looking up SRV records"));
  });
  return {-1, -1};
};

DNSResolver::TaskHandle NativeDNSResolver::LookupTXT(
    std::function<void(absl::StatusOr<std::string>)> on_resolved,
    absl::string_view /* name */, Duration /* timeout */,
    grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  // Not supported
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run([on_resolved] {
    ApplicationCallbackExecCtx app_exec_ctx;
    ExecCtx exec_ctx;
    on_resolved(absl::UnimplementedError(
        "The Native resolver does not support looking up TXT records"));
  });
  return {-1, -1};
};

bool NativeDNSResolver::Cancel(TaskHandle /*handle*/) { return false; }

}  // namespace grpc_core

#endif
<commit_msg>Revert "[event_engine] Move DNS resolution executor usage to event engine (#31230)" (#31307)<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 <grpc/support/port_platform.h>

#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET_RESOLVE_ADDRESS

#include <string.h>
#include <sys/types.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>

#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/resolve_address_posix.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/transport/error_utils.h"

namespace grpc_core {
namespace {

class NativeDNSRequest {
 public:
  NativeDNSRequest(
      absl::string_view name, absl::string_view default_port,
      std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
          on_done)
      : name_(name), default_port_(default_port), on_done_(std::move(on_done)) {
    GRPC_CLOSURE_INIT(&request_closure_, DoRequestThread, this, nullptr);
    Executor::Run(&request_closure_, absl::OkStatus(), ExecutorType::RESOLVER);
  }

 private:
  // Callback to be passed to grpc Executor to asynch-ify
  // LookupHostnameBlocking
  static void DoRequestThread(void* rp, grpc_error_handle /*error*/) {
    NativeDNSRequest* r = static_cast<NativeDNSRequest*>(rp);
    auto result =
        GetDNSResolver()->LookupHostnameBlocking(r->name_, r->default_port_);
    // running inline is safe since we've already been scheduled on the executor
    r->on_done_(std::move(result));
    delete r;
  }

  const std::string name_;
  const std::string default_port_;
  const std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
      on_done_;
  grpc_closure request_closure_;
};

}  // namespace

DNSResolver::TaskHandle NativeDNSResolver::LookupHostname(
    std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
        on_done,
    absl::string_view name, absl::string_view default_port,
    Duration /* timeout */, grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  // self-deleting class
  new NativeDNSRequest(name, default_port, std::move(on_done));
  return kNullHandle;
}

absl::StatusOr<std::vector<grpc_resolved_address>>
NativeDNSResolver::LookupHostnameBlocking(absl::string_view name,
                                          absl::string_view default_port) {
  ExecCtx exec_ctx;
  struct addrinfo hints;
  struct addrinfo *result = nullptr, *resp;
  int s;
  size_t i;
  grpc_error_handle err;
  std::vector<grpc_resolved_address> addresses;
  std::string host;
  std::string port;
  // parse name, splitting it into host and port parts
  SplitHostPort(name, &host, &port);
  if (host.empty()) {
    err = grpc_error_set_str(GRPC_ERROR_CREATE("unparseable host:port"),
                             StatusStrProperty::kTargetAddress, name);
    goto done;
  }
  if (port.empty()) {
    if (default_port.empty()) {
      err = grpc_error_set_str(GRPC_ERROR_CREATE("no port in name"),
                               StatusStrProperty::kTargetAddress, name);
      goto done;
    }
    port = std::string(default_port);
  }
  // Call getaddrinfo
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;     /* ipv4 or ipv6 */
  hints.ai_socktype = SOCK_STREAM; /* stream socket */
  hints.ai_flags = AI_PASSIVE;     /* for wildcard IP address */
  GRPC_SCHEDULING_START_BLOCKING_REGION;
  s = getaddrinfo(host.c_str(), port.c_str(), &hints, &result);
  GRPC_SCHEDULING_END_BLOCKING_REGION;
  if (s != 0) {
    // Retry if well-known service name is recognized
    const char* svc[][2] = {{"http", "80"}, {"https", "443"}};
    for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
      if (port == svc[i][0]) {
        GRPC_SCHEDULING_START_BLOCKING_REGION;
        s = getaddrinfo(host.c_str(), svc[i][1], &hints, &result);
        GRPC_SCHEDULING_END_BLOCKING_REGION;
        break;
      }
    }
  }
  if (s != 0) {
    err = grpc_error_set_str(
        grpc_error_set_str(
            grpc_error_set_str(
                grpc_error_set_int(GRPC_ERROR_CREATE(gai_strerror(s)),
                                   StatusIntProperty::kErrorNo, s),
                StatusStrProperty::kOsError, gai_strerror(s)),
            StatusStrProperty::kSyscall, "getaddrinfo"),
        StatusStrProperty::kTargetAddress, name);
    goto done;
  }
  // Success path: fill in addrs
  for (resp = result; resp != nullptr; resp = resp->ai_next) {
    grpc_resolved_address addr;
    memcpy(&addr.addr, resp->ai_addr, resp->ai_addrlen);
    addr.len = resp->ai_addrlen;
    addresses.push_back(addr);
  }
  err = absl::OkStatus();
done:
  if (result) {
    freeaddrinfo(result);
  }
  if (err.ok()) {
    return addresses;
  }
  auto error_result = grpc_error_to_absl_status(err);
  return error_result;
}

DNSResolver::TaskHandle NativeDNSResolver::LookupSRV(
    std::function<void(absl::StatusOr<std::vector<grpc_resolved_address>>)>
        on_resolved,
    absl::string_view /* name */, Duration /* timeout */,
    grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run([on_resolved] {
    ApplicationCallbackExecCtx app_exec_ctx;
    ExecCtx exec_ctx;
    on_resolved(absl::UnimplementedError(
        "The Native resolver does not support looking up SRV records"));
  });
  return {-1, -1};
};

DNSResolver::TaskHandle NativeDNSResolver::LookupTXT(
    std::function<void(absl::StatusOr<std::string>)> on_resolved,
    absl::string_view /* name */, Duration /* timeout */,
    grpc_pollset_set* /* interested_parties */,
    absl::string_view /* name_server */) {
  // Not supported
  grpc_event_engine::experimental::GetDefaultEventEngine()->Run([on_resolved] {
    ApplicationCallbackExecCtx app_exec_ctx;
    ExecCtx exec_ctx;
    on_resolved(absl::UnimplementedError(
        "The Native resolver does not support looking up TXT records"));
  });
  return {-1, -1};
};

bool NativeDNSResolver::Cancel(TaskHandle /*handle*/) { return false; }

}  // namespace grpc_core

#endif
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "servo_msgs/KrsServoDegree.h"

#include <string>

#include "krs_servo_driver.hpp"

class KrsServoNode {
public:
  KrsServoNode();
  explicit KrsServoNode(ros::NodeHandle& nh, const char* path);

private:
  void krsServoDegreeCallback(const servo_msgs::KrsServoDegree::ConstPtr& msg);

  ros::Subscriber sub;
  KrsServoDriver krs;
};

int main(int argc, char** argv) {
  ros::init(argc, argv, "krs_servo_node");
  ros::NodeHandle nh;

  std::string path;
  nh.param<std::string>("serial_path", path, "/dev/ttyUSB0");

  KrsServoNode ksn(nh, path.c_str());

  ros::spin();
  return 0;
}

KrsServoNode::KrsServoNode()
  : krs()
{}

KrsServoNode::KrsServoNode(ros::NodeHandle& nh, const char* path)
  : krs(path)
{
  sub = nh.subscribe("cmd_krs", 16, &KrsServoNode::krsServoDegreeCallback, this);
}

void KrsServoNode::krsServoDegreeCallback(const servo_msgs::KrsServoDegree::ConstPtr& msg) {
  krs.sendAngle(msg->id, msg->angle);
}
<commit_msg>Remove explicit by constructor has too many args.<commit_after>#include "ros/ros.h"
#include "servo_msgs/KrsServoDegree.h"

#include <string>

#include "krs_servo_driver.hpp"

class KrsServoNode {
public:
  KrsServoNode();
  KrsServoNode(ros::NodeHandle& nh, const char* path);

private:
  void krsServoDegreeCallback(const servo_msgs::KrsServoDegree::ConstPtr& msg);

  ros::Subscriber sub;
  KrsServoDriver krs;
};

int main(int argc, char** argv) {
  ros::init(argc, argv, "krs_servo_node");
  ros::NodeHandle nh;

  std::string path;
  nh.param<std::string>("serial_path", path, "/dev/ttyUSB0");

  KrsServoNode ksn(nh, path.c_str());

  ros::spin();
  return 0;
}

KrsServoNode::KrsServoNode()
  : krs()
{}

KrsServoNode::KrsServoNode(ros::NodeHandle& nh, const char* path)
  : krs(path)
{
  sub = nh.subscribe("cmd_krs", 16, &KrsServoNode::krsServoDegreeCallback, this);
}

void KrsServoNode::krsServoDegreeCallback(const servo_msgs::KrsServoDegree::ConstPtr& msg) {
  krs.sendAngle(msg->id, msg->angle);
}
<|endoftext|>


<commit_before>#include "drivers/ublox_neo7.hpp"

#include <cstdlib>
#include <cstring>

#include "chprintf.h"
#include "unit_config.hpp"

const char NMEA_LF = '\n';
const char *NMEA_DELIMS = ",\0";

struct GPGLLMessage {
  float lon;
  char lonDir;
  float lat;
  char latDir;
  float utc;
  char valid;
};

void UBloxNEO7::init() {
}

GPSReading UBloxNEO7::readGPS() {
  // Read all available bytes until the newline character. NMEA dictates that
  // messages should end with a CRLF, but we'll only look for the LF.
  std::size_t len = readUntil(NMEA_LF);

  // Check if a full line is ready to be processed
  if(len > 0) {
    char *start = reinterpret_cast<char *>(rxbuf.data());

    // Skip over the leading "$"
    start += 1;

    char *token = std::strtok(start, NMEA_DELIMS);

    // Only care about GPGLL messages
    if(std::strcmp("GPGLL", token) == 0) {
      GPGLLMessage message;
      int position = 0;

      while(token != nullptr) {
        token = std::strtok(nullptr, NMEA_DELIMS);

        switch(position++) {
          case 0:
            message.lon = atof(token);
            break;
          case 1:
            message.lonDir = token[0];
            break;
          case 2:
            message.lat = atof(token);
            break;
          case 3:
            message.latDir = token[0];
            break;
          case 4:
            message.utc = atof(token);
            break;
          case 5:
            message.valid = token[0];
            break;
        };
      }

      return GPSReading {
        .valid = true,
        .lat = message.lat,
        .lon = message.lon
      };
    }
  } else {
    // TODO: Return previous message with old timestamp.
      return GPSReading {
        .valid = false,
        .lat = 0.0,
        .lon = 0.0
      };
  }
}
<commit_msg>refs #7 Swap lat/lon.<commit_after>#include "drivers/ublox_neo7.hpp"

#include <cstdlib>
#include <cstring>

#include "chprintf.h"
#include "unit_config.hpp"

const char NMEA_LF = '\n';
const char *NMEA_DELIMS = ",\0";

struct GPGLLMessage {
  float lon;
  char lonDir;
  float lat;
  char latDir;
  float utc;
  char valid;
};

void UBloxNEO7::init() {
}

GPSReading UBloxNEO7::readGPS() {
  // Read all available bytes until the newline character. NMEA dictates that
  // messages should end with a CRLF, but we'll only look for the LF.
  std::size_t len = readUntil(NMEA_LF);

  // Check if a full line is ready to be processed
  if(len > 0) {
    char *start = reinterpret_cast<char *>(rxbuf.data());

    // Skip over the leading "$"
    start += 1;

    char *token = std::strtok(start, NMEA_DELIMS);

    // Only care about GPGLL messages
    if(std::strcmp("GPGLL", token) == 0) {
      GPGLLMessage message;
      int position = 0;

      while(token != nullptr) {
        token = std::strtok(nullptr, NMEA_DELIMS);

        switch(position++) {
          case 0:
            message.lat = atof(token);
            break;
          case 1:
            message.latDir = token[0];
            break;
          case 2:
            message.lon = atof(token);
            break;
          case 3:
            message.lonDir = token[0];
            break;
          case 4:
            message.utc = atof(token);
            break;
          case 5:
            message.valid = token[0];
            break;
        };
      }

      return GPSReading {
        .valid = true,
        .lat = message.lat,
        .lon = message.lon
      };
    }
  } else {
    // TODO: Return previous message with old timestamp.
      return GPSReading {
        .valid = false,
        .lat = 0.0,
        .lon = 0.0
      };
  }
}
<|endoftext|>


<commit_before>/*
 * colormapwidget.cpp
 *
 *  Created on: Jan 29, 2013
 *      Author: schurade
 */
#include <QtGui/QtGui>

#include "colormapwidget.h"

ColormapWidget::ColormapWidget( int width ) :
    m_colormap( FNCM_GRAY ),
    m_width( width ),
    m_lowerThreshold( 0.0 ),
    m_upperThreshold( 1.0 )
{
    QVBoxLayout* vLayout = new QVBoxLayout();

//    QHBoxLayout* hLayout = new QHBoxLayout();
//    m_nlabel = new QLabel( QString("colormap"), this );
//    hLayout->addWidget( m_nlabel );
//    hLayout->addStretch();

    QHBoxLayout* hLayout2 = new QHBoxLayout();
    m_nlabel = new QLabel( this );

    m_image = createImage( width );
    QPixmap pix( width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
    hLayout2->addWidget( m_nlabel );

    //vLayout->addLayout( hLayout );
    vLayout->addLayout( hLayout2 );
    vLayout->setContentsMargins( 1,1,1,1 );

    setLayout( vLayout );

    setFrameStyle( QFrame::Panel | QFrame::Raised );

    setStyleSheet( "QLabel { font:  bold 12px; margin-bottom: -1px }"
                     "QLineEdit { font: 12px; max-height: 14px; margin-top: -1px }"
                   );
}

ColormapWidget::~ColormapWidget()
{
}

QImage* ColormapWidget::createImage( int width )
{
    QImage* image = new QImage( width, 20, QImage::Format_RGB32 );

    for ( int i = 0; i < width; ++i )
    {
        QColor c;
        int g = 0;
        switch ( m_colormap )
        {
            case FNCM_RAINBOW1:
                c = colormap1( (float)i / (float)width );
                break;
            case FNCM_RAINBOW2:
                c = colormap2( (float)i / (float)width );
                break;
            case FNCM_BLUEWHITERED:
                c = colormap3( (float)i / (float)width );
                break;
            default:
                g = (float)i / (float)width * 255;
                c = QColor( g, g, g );
                break;
        }
        for ( int k = 0; k < 20; ++k )
        {
            image->setPixel( i, k, c.rgba() );
        }
    }

    return image;
}

QColor ColormapWidget::colormap1( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 5.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 1.0 )
    {
        g = value;
        b = 1.0f;
    }
    else if( value < 2.0 )
    {
        g = 1.0;
        b = 2.0 -value;
    }
    else if( value < 3.0 )
    {
        r = value-2.0;
        g = 1.0;
    }
    else if( value < 4.0 )
    {
        r = 1.0;
        g = 4.0-value;
    }
    else
    {
        r = 1.0;
        b = value-4.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

QColor ColormapWidget::colormap2( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 6.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 2.0 )
    {
        g = value * 0.5f;
        b = 1.0f;
    }
    else if( value < 3.0 )
    {
        g = 1.0;
        b = 3.0 -value;
    }
    else if( value < 4.0 )
    {
        r = value-3.0;
        g = 1.0;
    }
    else if( value < 6.0 )
    {
        r = 1.0;
        g = 0.5f * ( 6.0-value );
    }
    else
    {
        r = 1.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

QColor ColormapWidget::colormap3( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 2.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 1.0 )
    {
        r = value;
        g = value;
        b = 1.0;
    }
    else if( value <= 2.0 )
    {
        r = 1.0;
        g = 2.0-value;
        b = 2.0-value;
    }
    else
    {
        r = 1.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

void ColormapWidget::setLowerThreshold( float value )
{
    value = qMax( 0.0f, qMin( 1.0f, value ) );
    m_lowerThreshold = value;
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}

void ColormapWidget::setUpperThreshold( float value )
{
    value = qMax( 0.0f, qMin( 1.0f, value ) );
    m_upperThreshold = value;
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}

void ColormapWidget::setColormap( int value )
{
    m_colormap = qMin( (FN_COLORMAP)value, FNCM_NOCOLORMAP );
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}
<commit_msg>change colormapwidget for grayscale too<commit_after>/*
 * colormapwidget.cpp
 *
 *  Created on: Jan 29, 2013
 *      Author: schurade
 */
#include <QtGui/QtGui>

#include "colormapwidget.h"

ColormapWidget::ColormapWidget( int width ) :
    m_colormap( FNCM_GRAY ),
    m_width( width ),
    m_lowerThreshold( 0.0 ),
    m_upperThreshold( 1.0 )
{
    QVBoxLayout* vLayout = new QVBoxLayout();

//    QHBoxLayout* hLayout = new QHBoxLayout();
//    m_nlabel = new QLabel( QString("colormap"), this );
//    hLayout->addWidget( m_nlabel );
//    hLayout->addStretch();

    QHBoxLayout* hLayout2 = new QHBoxLayout();
    m_nlabel = new QLabel( this );

    m_image = createImage( width );
    QPixmap pix( width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
    hLayout2->addWidget( m_nlabel );

    //vLayout->addLayout( hLayout );
    vLayout->addLayout( hLayout2 );
    vLayout->setContentsMargins( 1,1,1,1 );

    setLayout( vLayout );

    setFrameStyle( QFrame::Panel | QFrame::Raised );

    setStyleSheet( "QLabel { font:  bold 12px; margin-bottom: -1px }"
                     "QLineEdit { font: 12px; max-height: 14px; margin-top: -1px }"
                   );
}

ColormapWidget::~ColormapWidget()
{
}

QImage* ColormapWidget::createImage( int width )
{
    QImage* image = new QImage( width, 20, QImage::Format_RGB32 );

    for ( int i = 0; i < width; ++i )
    {
        QColor c;
        int g = 0;
        switch ( m_colormap )
        {
            case FNCM_RAINBOW1:
                c = colormap1( (float)i / (float)width );
                break;
            case FNCM_RAINBOW2:
                c = colormap2( (float)i / (float)width );
                break;
            case FNCM_BLUEWHITERED:
                c = colormap3( (float)i / (float)width );
                break;
            default:
                g = qMin( 255.0f, qMax( 0.0f, ( (float)i / (float)width - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold ) * 255 ) );
                c = QColor( g, g, g );
                break;
        }
        for ( int k = 0; k < 20; ++k )
        {
            image->setPixel( i, k, c.rgba() );
        }
    }

    return image;
}

QColor ColormapWidget::colormap1( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 5.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 1.0 )
    {
        g = value;
        b = 1.0f;
    }
    else if( value < 2.0 )
    {
        g = 1.0;
        b = 2.0 -value;
    }
    else if( value < 3.0 )
    {
        r = value-2.0;
        g = 1.0;
    }
    else if( value < 4.0 )
    {
        r = 1.0;
        g = 4.0-value;
    }
    else
    {
        r = 1.0;
        b = value-4.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

QColor ColormapWidget::colormap2( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 6.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 2.0 )
    {
        g = value * 0.5f;
        b = 1.0f;
    }
    else if( value < 3.0 )
    {
        g = 1.0;
        b = 3.0 -value;
    }
    else if( value < 4.0 )
    {
        r = value-3.0;
        g = 1.0;
    }
    else if( value < 6.0 )
    {
        r = 1.0;
        g = 0.5f * ( 6.0-value );
    }
    else
    {
        r = 1.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

QColor ColormapWidget::colormap3( float value )
{
    value = ( value - m_lowerThreshold ) / ( m_upperThreshold - m_lowerThreshold );

    value = qMax( 0.0f, qMin( 1.0f, value ) );
    value *= 2.0;
    float r = 0.0;
    float g = 0.0;
    float b = 0.0;
    if( value < 1.0 )
    {
        r = value;
        g = value;
        b = 1.0;
    }
    else if( value <= 2.0 )
    {
        r = 1.0;
        g = 2.0-value;
        b = 2.0-value;
    }
    else
    {
        r = 1.0;
    }
    return QColor( 255 * r, 255 * g, 255 * b );
}

void ColormapWidget::setLowerThreshold( float value )
{
    value = qMax( 0.0f, qMin( 1.0f, value ) );
    m_lowerThreshold = value;
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}

void ColormapWidget::setUpperThreshold( float value )
{
    value = qMax( 0.0f, qMin( 1.0f, value ) );
    m_upperThreshold = value;
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}

void ColormapWidget::setColormap( int value )
{
    m_colormap = qMin( (FN_COLORMAP)value, FNCM_NOCOLORMAP );
    m_image = createImage( m_width );
    QPixmap pix( m_width, 20 );
    pix.convertFromImage( *m_image );
    m_nlabel->setPixmap( pix );
}
<|endoftext|>


<commit_before>#include "h264.h"
#include <cstdlib>
#include <cstring>
#include "bitfields.h"
#include "bitstream.h"
#include "defines.h"

namespace h264 {
  std::deque<nalu::nalData> analysePackets(const char * data, unsigned long len){
    std::deque<nalu::nalData> res;

    int offset = 0;
    //Make sure entire packet is within len
    while (offset+5 < len && Bit::btohl(data + offset)+offset+4 <= len){
      nalu::nalData entry;
      entry.nalSize = Bit::btohl(data + offset);
      entry.nalType = (data + offset)[4] & 0x1F;
      res.push_back(entry);
      offset += entry.nalSize + 4;
    }
    return res;
  }

  unsigned long toAnnexB(const char * data, unsigned long dataSize, char *& result){
    //toAnnexB keeps the same size.
    if (!result){
      result = (char *)malloc(dataSize);
    }
    int offset = 0;
    while (offset < dataSize){
      //Read unit size
      unsigned long unitSize = Bit::btohl(data + offset);
      //Write annex b header
      memset(result + offset, 0x00, 3);
      result[offset + 3] = 0x01;
      //Copy the nal unit
      memcpy(result + offset + 4, data + offset + 4, unitSize);
      //Update the offset
      offset += 4 + unitSize;
    }
    return dataSize;
  }

  unsigned long fromAnnexB(const char * data, unsigned long dataSize, char *& result){
    const char * lastCheck = data + dataSize - 3;
    if (!result){
      FAIL_MSG("No output buffer given to FromAnnexB");
      return 0;
    }
    int offset = 0;
    int newOffset = 0;
    while (offset < dataSize){
      const char * begin = data + offset;
      while ( begin < lastCheck && !(!begin[0] && !begin[1] && begin[2] == 0x01)){
        begin++;
        if (begin < lastCheck && begin[0]){
          begin++;
        }
      }
      begin += 3;//Initialize begin after the first 0x000001 pattern.
      if (begin > data + dataSize){
        offset = dataSize;
        continue;
      }
      const char * end = (const char*)memmem(begin, dataSize - (begin - data), "\000\000\001", 3);
      if (!end) {
        end = data + dataSize;
      }
      //Check for 4-byte lead in's. Yes, we access -1 here
      if (end > begin && end[-1] == 0x00){
        end--;
      }
      unsigned int nalSize = end - begin;
      Bit::htobl(result + newOffset, nalSize);
      memcpy(result + newOffset + 4, begin, nalSize);

      newOffset += 4 + nalSize;
      offset = end - data;
    }
    return newOffset;
  }

  sequenceParameterSet::sequenceParameterSet(const char * _data, unsigned long _dataLen) : data(_data), dataLen(_dataLen) {}

  //DTSC Initdata is the payload for an avcc box. init[8+] is data, init[6-7] is a network-encoded length
  void sequenceParameterSet::fromDTSCInit(const std::string & dtscInit){
    data = dtscInit.data() + 8;
    dataLen = Bit::btohs(dtscInit.data() + 6);
  }

  SPSMeta sequenceParameterSet::getCharacteristics()  const {
    SPSMeta result;

    //For calculating width
    unsigned int widthInMbs = 0;
    unsigned int cropHorizontal = 0;

    //For calculating height
    bool mbsOnlyFlag = 0;
    unsigned int heightInMapUnits = 0;
    unsigned int cropVertical = 0;

    //Fill the bitstream
    Utils::bitstream bs;
    for (unsigned int i = 1; i < dataLen; i++) {
      if (i + 2 < dataLen && (memcmp(data + i, "\000\000\003", 3) == 0)){//Emulation prevention bytes
        //Yes, we increase i here
        bs.append(data + i, 2);
        i += 2;
      } else {
        //No we don't increase i here
        bs.append(data + i, 1);
      }
    }

    char profileIdc = bs.get(8);
    result.profile = profileIdc;
    //Start skipping unused data
    bs.skip(8);
    result.level = bs.get(8);
    bs.getUExpGolomb();
    if (profileIdc == 100 || profileIdc == 110 || profileIdc == 122 || profileIdc == 244 || profileIdc == 44 || profileIdc == 83 || profileIdc == 86 || profileIdc == 118 || profileIdc == 128) {
      //chroma format idc
      if (bs.getUExpGolomb() == 3) {
        bs.skip(1);
      }
      bs.getUExpGolomb();
      bs.getUExpGolomb();
      bs.skip(1);
      if (bs.get(1)) {
        DEBUG_MSG(DLVL_DEVEL, "Scaling matrix not implemented yet");
      }
    }
    bs.getUExpGolomb();
    unsigned int pic_order_cnt_type = bs.getUExpGolomb();
    if (!pic_order_cnt_type) {
      bs.getUExpGolomb();
    } else if (pic_order_cnt_type == 1) {
      DEBUG_MSG(DLVL_DEVEL, "This part of the implementation is incomplete(2), to be continued. If this message is shown, contact developers immediately.");
    }
    bs.getUExpGolomb();
    bs.skip(1);
    //Stop skipping data and start doing usefull stuff

    widthInMbs = bs.getUExpGolomb() + 1;
    heightInMapUnits = bs.getUExpGolomb() + 1;

    mbsOnlyFlag = bs.get(1);//Gets used in height calculation
    if (!mbsOnlyFlag) {
      bs.skip(1);
    }
    bs.skip(1);
    //cropping flag
    if (bs.get(1)) {
      cropHorizontal = bs.getUExpGolomb();//leftOffset
      cropHorizontal += bs.getUExpGolomb();//rightOffset
      cropVertical = bs.getUExpGolomb();//topOffset
      cropVertical += bs.getUExpGolomb();//bottomOffset
    }

    //vuiParameters
    if (bs.get(1)) {
      //Skipping all the paramters we dont use
      if (bs.get(1)) {
        if (bs.get(8) == 255) {
          bs.skip(32);
        }
      }
      if (bs.get(1)) {
        bs.skip(1);
      }
      if (bs.get(1)) {
        bs.skip(4);
        if (bs.get(1)) {
          bs.skip(24);
        }
      }
      if (bs.get(1)) {
        bs.getUExpGolomb();
        bs.getUExpGolomb();
      }

      //Decode timing info
      if (bs.get(1)) {
        unsigned int unitsInTick = bs.get(32);
        unsigned int timeScale = bs.get(32);
        result.fps = (double)timeScale / (2 * unitsInTick);
        bs.skip(1);
      }
    }

    result.width = (widthInMbs * 16) - (cropHorizontal * 2);
    result.height = ((mbsOnlyFlag ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2);
    return result;
  }

}

<commit_msg>Skip over the h264 scaling list when it is present.<commit_after>#include "h264.h"
#include <cstdlib>
#include <cstring>
#include "bitfields.h"
#include "bitstream.h"
#include "defines.h"

namespace h264 {
  std::deque<nalu::nalData> analysePackets(const char * data, unsigned long len){
    std::deque<nalu::nalData> res;

    int offset = 0;
    //Make sure entire packet is within len
    while (offset+5 < len && Bit::btohl(data + offset)+offset+4 <= len){
      nalu::nalData entry;
      entry.nalSize = Bit::btohl(data + offset);
      entry.nalType = (data + offset)[4] & 0x1F;
      res.push_back(entry);
      offset += entry.nalSize + 4;
    }
    return res;
  }

  unsigned long toAnnexB(const char * data, unsigned long dataSize, char *& result){
    //toAnnexB keeps the same size.
    if (!result){
      result = (char *)malloc(dataSize);
    }
    int offset = 0;
    while (offset < dataSize){
      //Read unit size
      unsigned long unitSize = Bit::btohl(data + offset);
      //Write annex b header
      memset(result + offset, 0x00, 3);
      result[offset + 3] = 0x01;
      //Copy the nal unit
      memcpy(result + offset + 4, data + offset + 4, unitSize);
      //Update the offset
      offset += 4 + unitSize;
    }
    return dataSize;
  }

  unsigned long fromAnnexB(const char * data, unsigned long dataSize, char *& result){
    const char * lastCheck = data + dataSize - 3;
    if (!result){
      FAIL_MSG("No output buffer given to FromAnnexB");
      return 0;
    }
    int offset = 0;
    int newOffset = 0;
    while (offset < dataSize){
      const char * begin = data + offset;
      while ( begin < lastCheck && !(!begin[0] && !begin[1] && begin[2] == 0x01)){
        begin++;
        if (begin < lastCheck && begin[0]){
          begin++;
        }
      }
      begin += 3;//Initialize begin after the first 0x000001 pattern.
      if (begin > data + dataSize){
        offset = dataSize;
        continue;
      }
      const char * end = (const char*)memmem(begin, dataSize - (begin - data), "\000\000\001", 3);
      if (!end) {
        end = data + dataSize;
      }
      //Check for 4-byte lead in's. Yes, we access -1 here
      if (end > begin && end[-1] == 0x00){
        end--;
      }
      unsigned int nalSize = end - begin;
      Bit::htobl(result + newOffset, nalSize);
      memcpy(result + newOffset + 4, begin, nalSize);

      newOffset += 4 + nalSize;
      offset = end - data;
    }
    return newOffset;
  }

  sequenceParameterSet::sequenceParameterSet(const char * _data, unsigned long _dataLen) : data(_data), dataLen(_dataLen) {}

  //DTSC Initdata is the payload for an avcc box. init[8+] is data, init[6-7] is a network-encoded length
  void sequenceParameterSet::fromDTSCInit(const std::string & dtscInit){
    data = dtscInit.data() + 8;
    dataLen = Bit::btohs(dtscInit.data() + 6);
  }

  void skipScalingList(Utils::bitstream & bs, size_t listSize){
    size_t lastScale = 8;
    size_t nextScale = 8;
    for (size_t i = 0; i < listSize; i++){
      if (nextScale){
        uint64_t deltaScale = bs.getExpGolomb();
        nextScale = (lastScale + deltaScale + 256) % 256;
      }
      lastScale = (nextScale ? nextScale : lastScale);
    }
  }

  SPSMeta sequenceParameterSet::getCharacteristics()  const {
    SPSMeta result;

    //For calculating width
    unsigned int widthInMbs = 0;
    unsigned int cropHorizontal = 0;

    //For calculating height
    bool mbsOnlyFlag = 0;
    unsigned int heightInMapUnits = 0;
    unsigned int cropVertical = 0;

    //Fill the bitstream
    Utils::bitstream bs;
    for (unsigned int i = 1; i < dataLen; i++) {
      if (i + 2 < dataLen && (memcmp(data + i, "\000\000\003", 3) == 0)){//Emulation prevention bytes
        //Yes, we increase i here
        bs.append(data + i, 2);
        i += 2;
      } else {
        //No we don't increase i here
        bs.append(data + i, 1);
      }
    }

    char profileIdc = bs.get(8);
    result.profile = profileIdc;
    //Start skipping unused data
    bs.skip(8);
    result.level = bs.get(8);
    bs.getUExpGolomb();
    if (profileIdc == 100 || profileIdc == 110 || profileIdc == 122 || profileIdc == 244 || profileIdc == 44 || profileIdc == 83 || profileIdc == 86 || profileIdc == 118 || profileIdc == 128) {
      //chroma format idc
      char chromaFormatIdc = bs.getUExpGolomb();
      if (chromaFormatIdc == 3) {
        bs.skip(1);
      }
      bs.getUExpGolomb();
      bs.getUExpGolomb();
      bs.skip(1);
      if (bs.get(1)) {//Scaling matrix is present
        char listSize = (chromaFormatIdc == 3 ? 12 : 8);
        for (size_t i = 0; i < listSize; i++){
          bool thisListPresent = bs.get(1);
          if (thisListPresent){
            if (i < 6){
              skipScalingList(bs, 16);
            }else{
              skipScalingList(bs, 64);
            }
          }
        }
      }
    }
    bs.getUExpGolomb();
    unsigned int pic_order_cnt_type = bs.getUExpGolomb();
    if (!pic_order_cnt_type) {
      bs.getUExpGolomb();
    } else if (pic_order_cnt_type == 1) {
      DEBUG_MSG(DLVL_DEVEL, "This part of the implementation is incomplete(2), to be continued. If this message is shown, contact developers immediately.");
    }
    bs.getUExpGolomb();
    bs.skip(1);
    //Stop skipping data and start doing usefull stuff

    widthInMbs = bs.getUExpGolomb() + 1;
    heightInMapUnits = bs.getUExpGolomb() + 1;

    mbsOnlyFlag = bs.get(1);//Gets used in height calculation
    if (!mbsOnlyFlag) {
      bs.skip(1);
    }
    bs.skip(1);
    //cropping flag
    if (bs.get(1)) {
      cropHorizontal = bs.getUExpGolomb();//leftOffset
      cropHorizontal += bs.getUExpGolomb();//rightOffset
      cropVertical = bs.getUExpGolomb();//topOffset
      cropVertical += bs.getUExpGolomb();//bottomOffset
    }

    //vuiParameters
    if (bs.get(1)) {
      //Skipping all the paramters we dont use
      if (bs.get(1)) {
        if (bs.get(8) == 255) {
          bs.skip(32);
        }
      }
      if (bs.get(1)) {
        bs.skip(1);
      }
      if (bs.get(1)) {
        bs.skip(4);
        if (bs.get(1)) {
          bs.skip(24);
        }
      }
      if (bs.get(1)) {
        bs.getUExpGolomb();
        bs.getUExpGolomb();
      }

      //Decode timing info
      if (bs.get(1)) {
        unsigned int unitsInTick = bs.get(32);
        unsigned int timeScale = bs.get(32);
        result.fps = (double)timeScale / (2 * unitsInTick);
        bs.skip(1);
      }
    }

    result.width = (widthInMbs * 16) - (cropHorizontal * 2);
    result.height = ((mbsOnlyFlag ? 1 : 2) * heightInMapUnits * 16) - (cropVertical * 2);
    return result;
  }

}

<|endoftext|>


<commit_before>#pragma once
#include "ipaddress.hpp"
#include "neighbor.hpp"
#include "types.hpp"
#include "xyz/openbmc_project/Network/IP/Create/server.hpp"
#include "xyz/openbmc_project/Network/Neighbor/CreateStatic/server.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <stdplus/zstring.hpp>
#include <stdplus/zstring_view.hpp>
#include <string>
#include <vector>
#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
#include <xyz/openbmc_project/Network/MACAddress/server.hpp>

namespace phosphor
{
namespace network
{

using Ifaces = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface,
    sdbusplus::xyz::openbmc_project::Network::server::MACAddress,
    sdbusplus::xyz::openbmc_project::Network::IP::server::Create,
    sdbusplus::xyz::openbmc_project::Network::Neighbor::server::CreateStatic,
    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;

using IP = sdbusplus::xyz::openbmc_project::Network::server::IP;

using EthernetInterfaceIntf =
    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
using MacAddressIntf =
    sdbusplus::xyz::openbmc_project::Network::server::MACAddress;

using ServerList = std::vector<std::string>;
using ObjectPath = sdbusplus::message::object_path;

class Manager;

class TestEthernetInterface;

class VlanInterface;

namespace config
{
class Parser;
}

using LinkSpeed = uint16_t;
using DuplexMode = uint8_t;
using Autoneg = uint8_t;
using LinkUp = bool;
using NICEnabled = bool;
using MTU = size_t;
using VlanId = uint32_t;
using InterfaceName = std::string;
using InterfaceInfo =
    std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp, NICEnabled, MTU>;

/** @class EthernetInterface
 *  @brief OpenBMC Ethernet Interface implementation.
 *  @details A concrete implementation for the
 *  xyz.openbmc_project.Network.EthernetInterface DBus API.
 */
class EthernetInterface : public Ifaces
{
  public:
    EthernetInterface() = delete;
    EthernetInterface(const EthernetInterface&) = delete;
    EthernetInterface& operator=(const EthernetInterface&) = delete;
    EthernetInterface(EthernetInterface&&) = delete;
    EthernetInterface& operator=(EthernetInterface&&) = delete;
    virtual ~EthernetInterface() = default;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] objPath - Path to attach at.
     *  @param[in] config - The parsed configuation file.
     *  @param[in] parent - parent object.
     *  @param[in] emitSignal - true if the object added signal needs to be
     *                          send.
     *  @param[in] enabled - Override the lookup of nicEnabled
     */
    EthernetInterface(sdbusplus::bus_t& bus, stdplus::zstring_view objPath,
                      const config::Parser& config, Manager& parent,
                      bool emitSignal = true,
                      std::optional<bool> enabled = std::nullopt);

    /** @brief Function used to load the nameservers.
     */
    void loadNameServers(const config::Parser& config);

    /** @brief Function to create ipAddress dbus object.
     *  @param[in] addressType - Type of ip address.
     *  @param[in] ipAddress- IP address.
     *  @param[in] prefixLength - Length of prefix.
     */

    ObjectPath ip(IP::Protocol addressType, std::string ipAddress,
                  uint8_t prefixLength, std::string) override;

    /** @brief Function to create static neighbor dbus object.
     *  @param[in] ipAddress - IP address.
     *  @param[in] macAddress - Low level MAC address.
     */
    ObjectPath neighbor(std::string ipAddress, std::string macAddress) override;

    /* @brief delete the dbus object of the given ipAddress.
     * @param[in] ipAddress - IP address.
     */
    void deleteObject(std::string_view ipAddress);

    /* @brief delete the dbus object of the given ipAddress.
     * @param[in] ipAddress - IP address.
     */
    void deleteStaticNeighborObject(std::string_view ipAddress);

    /* @brief delete the vlan dbus object of the given interface.
     *        Also deletes the device file and the network file.
     * @param[in] interface - VLAN Interface.
     */
    void deleteVLANObject(stdplus::zstring_view interface);

    /* @brief creates the dbus object(IPaddres) given in the address list.
     * @param[in] addrs - address list for which dbus objects needs
     *                    to create.
     */
    void createIPAddressObjects();

    /* @brief creates the dbus object(Neighbor) given in the neighbor list.
     */
    void createStaticNeighborObjects();

    /* @brief Gets the index of the interface on the system
     */
    unsigned ifIndex() const;

    /* @brief Gets all the ip addresses.
     * @returns the list of ipAddress.
     */
    inline const auto& getAddresses() const
    {
        return addrs;
    }

    /* @brief Gets all the static neighbor entries.
     * @returns Static neighbor map.
     */
    inline const auto& getStaticNeighbors() const
    {
        return staticNeighbors;
    }

    /** Set value of DHCPEnabled */
    DHCPConf dhcpEnabled() const override;
    DHCPConf dhcpEnabled(DHCPConf value) override;
    using EthernetInterfaceIntf::dhcp4;
    bool dhcp4(bool value) override;
    using EthernetInterfaceIntf::dhcp6;
    bool dhcp6(bool value) override;

    /** Retrieve Link State */
    bool linkUp() const override;

    /** Retrieve MTU Size */
    size_t mtu() const override;

    /** Set size of MTU */
    size_t mtu(size_t value) override;

    /** Set value of NICEnabled */
    bool nicEnabled(bool value) override;

    /** @brief sets the MAC address.
     *  @param[in] value - MAC address which needs to be set on the system.
     *  @returns macAddress of the interface or throws an error.
     */
    std::string macAddress(std::string value) override;

    /** @brief check conf file for Router Advertisements
     *
     */
    bool ipv6AcceptRA(bool value) override;
    using EthernetInterfaceIntf::ipv6AcceptRA;

    /** @brief sets the NTP servers.
     *  @param[in] value - vector of NTP servers.
     */
    ServerList ntpServers(ServerList value) override;

    /** @brief sets the Static DNS/nameservers.
     *  @param[in] value - vector of DNS servers.
     */

    ServerList staticNameServers(ServerList value) override;

    /** @brief create Vlan interface.
     *  @param[in] id- VLAN identifier.
     */
    ObjectPath createVLAN(VlanId id);

    /** @brief load the vlan info from the system
     *         and creates the ip address dbus objects.
     *  @param[in] vlanID- VLAN identifier.
     */
    void loadVLAN(VlanId vlanID);

    /** @brief write the network conf file with the in-memory objects.
     */
    void writeConfigurationFile();

    /** @brief delete all dbus objects.
     */
    void deleteAll();

    /** @brief set the default v4 gateway of the interface.
     *  @param[in] gateway - default v4 gateway of the interface.
     */
    std::string defaultGateway(std::string gateway) override;

    /** @brief set the default v6 gateway of the interface.
     *  @param[in] gateway - default v6 gateway of the interface.
     */
    std::string defaultGateway6(std::string gateway) override;

    using EthernetInterfaceIntf::interfaceName;
    using EthernetInterfaceIntf::linkUp;
    using EthernetInterfaceIntf::mtu;
    using EthernetInterfaceIntf::nicEnabled;
    using MacAddressIntf::macAddress;

    using EthernetInterfaceIntf::defaultGateway;
    using EthernetInterfaceIntf::defaultGateway6;
    /** @brief Absolute path of the resolv conf file */
    static constexpr auto resolvConfFile = "/etc/resolv.conf";

  protected:
    /** @brief get the info of the ethernet interface.
     *  @return tuple having the link speed,autonegotiation,duplexmode .
     */
    InterfaceInfo getInterfaceInfo() const;

    /* @brief delete the vlan interface from system.
     * @param[in] interface - vlan Interface.
     */
    void deleteVLANFromSystem(stdplus::zstring_view interface);

    /** @brief get the mac address of the interface.
     *  @param[in] interfaceName - Network interface name.
     *  @return macaddress on success
     */

    std::string getMACAddress(stdplus::const_zstring interfaceName) const;

    /** @brief construct the ip address dbus object path.
     *  @param[in] addressType - Type of ip address.
     *  @param[in] ipAddress - IP address.
     *  @param[in] prefixLength - Length of prefix.
     *  @param[in] origin - The origin entry of the IP::Address

     *  @return path of the address object.
     */
    std::string generateObjectPath(IP::Protocol addressType,
                                   std::string_view ipAddress,
                                   uint8_t prefixLength,
                                   IP::AddressOrigin origin) const;

    std::string
        generateStaticNeighborObjectPath(std::string_view ipAddress,
                                         std::string_view macAddress) const;

    /** @brief get the NTP server list from the network conf
     *
     */
    ServerList getNTPServersFromConf();

    /** @brief get the name server details from the network conf
     *
     */
    virtual ServerList getNameServerFromResolvd();

    /** @brief Persistent sdbusplus DBus bus connection. */
    sdbusplus::bus_t& bus;

    /** @brief Network Manager object. */
    Manager& manager;

    /** @brief Persistent map of IPAddress dbus objects and their names */
    string_umap<std::unique_ptr<IPAddress>> addrs;

    /** @brief Persistent map of Neighbor dbus objects and their names */
    string_umap<std::unique_ptr<Neighbor>> staticNeighbors;

    /** @brief Persistent map of VLAN interface dbus objects and their names */
    string_umap<std::unique_ptr<VlanInterface>> vlanInterfaces;

    /** @brief Dbus object path */
    std::string objPath;

    friend class TestEthernetInterface;

  private:
    /** @brief Determines if DHCP is active for the IP::Protocol supplied.
     *  @param[in] protocol - Either IPv4 or IPv6
     *  @returns true/false value if DHCP is active for the input protocol
     */
    bool dhcpIsEnabled(IP::Protocol protocol);

    /** @brief Determines if the address is manually assigned
     *  @param[in] origin - The origin entry of the IP::Address
     *  @returns true/false value if the address is static
     */
    bool originIsManuallyAssigned(IP::AddressOrigin origin);

    /** @brief Determines if the NIC is enabled in systemd
     *  @returns true/false value if the NIC is enabled
     */
    bool queryNicEnabled() const;

    std::string vlanIntfName(VlanId id) const;
    std::string vlanObjPath(VlanId id) const;
};

} // namespace network
} // namespace phosphor
<commit_msg>ethernet_interface: Remove unused resolvconf file<commit_after>#pragma once
#include "ipaddress.hpp"
#include "neighbor.hpp"
#include "types.hpp"
#include "xyz/openbmc_project/Network/IP/Create/server.hpp"
#include "xyz/openbmc_project/Network/Neighbor/CreateStatic/server.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <stdplus/zstring.hpp>
#include <stdplus/zstring_view.hpp>
#include <string>
#include <vector>
#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
#include <xyz/openbmc_project/Network/MACAddress/server.hpp>

namespace phosphor
{
namespace network
{

using Ifaces = sdbusplus::server::object_t<
    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface,
    sdbusplus::xyz::openbmc_project::Network::server::MACAddress,
    sdbusplus::xyz::openbmc_project::Network::IP::server::Create,
    sdbusplus::xyz::openbmc_project::Network::Neighbor::server::CreateStatic,
    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;

using IP = sdbusplus::xyz::openbmc_project::Network::server::IP;

using EthernetInterfaceIntf =
    sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
using MacAddressIntf =
    sdbusplus::xyz::openbmc_project::Network::server::MACAddress;

using ServerList = std::vector<std::string>;
using ObjectPath = sdbusplus::message::object_path;

class Manager;

class TestEthernetInterface;

class VlanInterface;

namespace config
{
class Parser;
}

using LinkSpeed = uint16_t;
using DuplexMode = uint8_t;
using Autoneg = uint8_t;
using LinkUp = bool;
using NICEnabled = bool;
using MTU = size_t;
using VlanId = uint32_t;
using InterfaceName = std::string;
using InterfaceInfo =
    std::tuple<LinkSpeed, DuplexMode, Autoneg, LinkUp, NICEnabled, MTU>;

/** @class EthernetInterface
 *  @brief OpenBMC Ethernet Interface implementation.
 *  @details A concrete implementation for the
 *  xyz.openbmc_project.Network.EthernetInterface DBus API.
 */
class EthernetInterface : public Ifaces
{
  public:
    EthernetInterface() = delete;
    EthernetInterface(const EthernetInterface&) = delete;
    EthernetInterface& operator=(const EthernetInterface&) = delete;
    EthernetInterface(EthernetInterface&&) = delete;
    EthernetInterface& operator=(EthernetInterface&&) = delete;
    virtual ~EthernetInterface() = default;

    /** @brief Constructor to put object onto bus at a dbus path.
     *  @param[in] bus - Bus to attach to.
     *  @param[in] objPath - Path to attach at.
     *  @param[in] config - The parsed configuation file.
     *  @param[in] parent - parent object.
     *  @param[in] emitSignal - true if the object added signal needs to be
     *                          send.
     *  @param[in] enabled - Override the lookup of nicEnabled
     */
    EthernetInterface(sdbusplus::bus_t& bus, stdplus::zstring_view objPath,
                      const config::Parser& config, Manager& parent,
                      bool emitSignal = true,
                      std::optional<bool> enabled = std::nullopt);

    /** @brief Function used to load the nameservers.
     */
    void loadNameServers(const config::Parser& config);

    /** @brief Function to create ipAddress dbus object.
     *  @param[in] addressType - Type of ip address.
     *  @param[in] ipAddress- IP address.
     *  @param[in] prefixLength - Length of prefix.
     */

    ObjectPath ip(IP::Protocol addressType, std::string ipAddress,
                  uint8_t prefixLength, std::string) override;

    /** @brief Function to create static neighbor dbus object.
     *  @param[in] ipAddress - IP address.
     *  @param[in] macAddress - Low level MAC address.
     */
    ObjectPath neighbor(std::string ipAddress, std::string macAddress) override;

    /* @brief delete the dbus object of the given ipAddress.
     * @param[in] ipAddress - IP address.
     */
    void deleteObject(std::string_view ipAddress);

    /* @brief delete the dbus object of the given ipAddress.
     * @param[in] ipAddress - IP address.
     */
    void deleteStaticNeighborObject(std::string_view ipAddress);

    /* @brief delete the vlan dbus object of the given interface.
     *        Also deletes the device file and the network file.
     * @param[in] interface - VLAN Interface.
     */
    void deleteVLANObject(stdplus::zstring_view interface);

    /* @brief creates the dbus object(IPaddres) given in the address list.
     * @param[in] addrs - address list for which dbus objects needs
     *                    to create.
     */
    void createIPAddressObjects();

    /* @brief creates the dbus object(Neighbor) given in the neighbor list.
     */
    void createStaticNeighborObjects();

    /* @brief Gets the index of the interface on the system
     */
    unsigned ifIndex() const;

    /* @brief Gets all the ip addresses.
     * @returns the list of ipAddress.
     */
    inline const auto& getAddresses() const
    {
        return addrs;
    }

    /* @brief Gets all the static neighbor entries.
     * @returns Static neighbor map.
     */
    inline const auto& getStaticNeighbors() const
    {
        return staticNeighbors;
    }

    /** Set value of DHCPEnabled */
    DHCPConf dhcpEnabled() const override;
    DHCPConf dhcpEnabled(DHCPConf value) override;
    using EthernetInterfaceIntf::dhcp4;
    bool dhcp4(bool value) override;
    using EthernetInterfaceIntf::dhcp6;
    bool dhcp6(bool value) override;

    /** Retrieve Link State */
    bool linkUp() const override;

    /** Retrieve MTU Size */
    size_t mtu() const override;

    /** Set size of MTU */
    size_t mtu(size_t value) override;

    /** Set value of NICEnabled */
    bool nicEnabled(bool value) override;

    /** @brief sets the MAC address.
     *  @param[in] value - MAC address which needs to be set on the system.
     *  @returns macAddress of the interface or throws an error.
     */
    std::string macAddress(std::string value) override;

    /** @brief check conf file for Router Advertisements
     *
     */
    bool ipv6AcceptRA(bool value) override;
    using EthernetInterfaceIntf::ipv6AcceptRA;

    /** @brief sets the NTP servers.
     *  @param[in] value - vector of NTP servers.
     */
    ServerList ntpServers(ServerList value) override;

    /** @brief sets the Static DNS/nameservers.
     *  @param[in] value - vector of DNS servers.
     */

    ServerList staticNameServers(ServerList value) override;

    /** @brief create Vlan interface.
     *  @param[in] id- VLAN identifier.
     */
    ObjectPath createVLAN(VlanId id);

    /** @brief load the vlan info from the system
     *         and creates the ip address dbus objects.
     *  @param[in] vlanID- VLAN identifier.
     */
    void loadVLAN(VlanId vlanID);

    /** @brief write the network conf file with the in-memory objects.
     */
    void writeConfigurationFile();

    /** @brief delete all dbus objects.
     */
    void deleteAll();

    /** @brief set the default v4 gateway of the interface.
     *  @param[in] gateway - default v4 gateway of the interface.
     */
    std::string defaultGateway(std::string gateway) override;

    /** @brief set the default v6 gateway of the interface.
     *  @param[in] gateway - default v6 gateway of the interface.
     */
    std::string defaultGateway6(std::string gateway) override;

    using EthernetInterfaceIntf::interfaceName;
    using EthernetInterfaceIntf::linkUp;
    using EthernetInterfaceIntf::mtu;
    using EthernetInterfaceIntf::nicEnabled;
    using MacAddressIntf::macAddress;

    using EthernetInterfaceIntf::defaultGateway;
    using EthernetInterfaceIntf::defaultGateway6;

  protected:
    /** @brief get the info of the ethernet interface.
     *  @return tuple having the link speed,autonegotiation,duplexmode .
     */
    InterfaceInfo getInterfaceInfo() const;

    /* @brief delete the vlan interface from system.
     * @param[in] interface - vlan Interface.
     */
    void deleteVLANFromSystem(stdplus::zstring_view interface);

    /** @brief get the mac address of the interface.
     *  @param[in] interfaceName - Network interface name.
     *  @return macaddress on success
     */

    std::string getMACAddress(stdplus::const_zstring interfaceName) const;

    /** @brief construct the ip address dbus object path.
     *  @param[in] addressType - Type of ip address.
     *  @param[in] ipAddress - IP address.
     *  @param[in] prefixLength - Length of prefix.
     *  @param[in] origin - The origin entry of the IP::Address

     *  @return path of the address object.
     */
    std::string generateObjectPath(IP::Protocol addressType,
                                   std::string_view ipAddress,
                                   uint8_t prefixLength,
                                   IP::AddressOrigin origin) const;

    std::string
        generateStaticNeighborObjectPath(std::string_view ipAddress,
                                         std::string_view macAddress) const;

    /** @brief get the NTP server list from the network conf
     *
     */
    ServerList getNTPServersFromConf();

    /** @brief get the name server details from the network conf
     *
     */
    virtual ServerList getNameServerFromResolvd();

    /** @brief Persistent sdbusplus DBus bus connection. */
    sdbusplus::bus_t& bus;

    /** @brief Network Manager object. */
    Manager& manager;

    /** @brief Persistent map of IPAddress dbus objects and their names */
    string_umap<std::unique_ptr<IPAddress>> addrs;

    /** @brief Persistent map of Neighbor dbus objects and their names */
    string_umap<std::unique_ptr<Neighbor>> staticNeighbors;

    /** @brief Persistent map of VLAN interface dbus objects and their names */
    string_umap<std::unique_ptr<VlanInterface>> vlanInterfaces;

    /** @brief Dbus object path */
    std::string objPath;

    friend class TestEthernetInterface;

  private:
    /** @brief Determines if DHCP is active for the IP::Protocol supplied.
     *  @param[in] protocol - Either IPv4 or IPv6
     *  @returns true/false value if DHCP is active for the input protocol
     */
    bool dhcpIsEnabled(IP::Protocol protocol);

    /** @brief Determines if the address is manually assigned
     *  @param[in] origin - The origin entry of the IP::Address
     *  @returns true/false value if the address is static
     */
    bool originIsManuallyAssigned(IP::AddressOrigin origin);

    /** @brief Determines if the NIC is enabled in systemd
     *  @returns true/false value if the NIC is enabled
     */
    bool queryNicEnabled() const;

    std::string vlanIntfName(VlanId id) const;
    std::string vlanObjPath(VlanId id) const;
};

} // namespace network
} // namespace phosphor
<|endoftext|>


<commit_before>#include <exception>
#include <sstream>

extern "C" {
    #include "ft2build.h"
    #include FT_FREETYPE_H
}

#include "freetype_interface.h"
#include "grayscale_bitmap.h"

class FreetypeMaintainer {
public:
    FreetypeMaintainer() : library(nullptr), fontFace(nullptr) {
        int error = FT_Init_FreeType(&library);
        if (error) {
            throw std::runtime_error("Unable to initalize Freetype library");
        }
    };

    virtual ~FreetypeMaintainer() {
        if (fontFace != nullptr) {
            FT_Done_Face(fontFace);
        }

        FT_Done_FreeType(library);
    }

    FT_Library library;
    FT_Face fontFace;

private:
    FreetypeMaintainer(const FreetypeMaintainer&);
};

static FreetypeMaintainer ft;

#define FIXED_POINT_26_6_COEFF 2^6

void setFontFile(const std::string& newFilePath) {
    #define SAME_AS_NEXT_ARG 0
    static const FT_UInt DEFAULT_HORIZ_RES          = 72;
    static const FT_UInt DEFAULT_VERTICAL_RES       = DEFAULT_HORIZ_RES;
    static const FT_Long FIRST_FACE_IN_FONT_INDEX   = 0;

    int error = FT_New_Face(ft.library, newFilePath.c_str(),
                            FIRST_FACE_IN_FONT_INDEX, &ft.fontFace);

    if (error == FT_Err_Unknown_File_Format) {
        std::stringstream err;
        err << "The font file '" << newFilePath << "' could be opened and read, "
            << "but it appears that its font format is unsupported";
        throw std::runtime_error(err.str());
    }
    else if (error) {
        std::stringstream err;
        err << "The font file '" << newFilePath << "' either could not "
            << "be opened and read, or it is simply broken";
        throw std::runtime_error(err.str());
    }

    if (!FT_IS_FIXED_WIDTH(ft.fontFace)) {
        throw std::runtime_error("Loaded font face must be monospaced");
    }

    if (!FT_IS_SCALABLE(ft.fontFace)) {
        throw std::runtime_error("Loaded font face must be scaleble");
    }

    error = FT_Set_Char_Size(ft.fontFace,   SAME_AS_NEXT_ARG,
                                            16 * FIXED_POINT_26_6_COEFF,
                                            DEFAULT_HORIZ_RES,
                                            DEFAULT_VERTICAL_RES);

    if (error) {
        throw std::runtime_error("Error while setting char size");
    }
}

uint16_t getFontHeight() {
    return ft.fontFace->size->metrics.height / FIXED_POINT_26_6_COEFF;
}

uint16_t getFontWidth() {
    return ft.fontFace->size->metrics.max_advance / FIXED_POINT_26_6_COEFF;
}

GrayscaleBitmap getBitmapForAsciiSymbol(char symbol) {
    int error = FT_Load_Char(   ft.fontFace, static_cast<FT_ULong>(symbol),
                                FT_LOAD_RENDER);

    if (error) {
        throw std::runtime_error("Error while loading char");
    }

    if (ft.fontFace->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
        throw std::runtime_error("Freetype symbol glyph must have bitmap format");
    }

    if (ft.fontFace->glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) {
        throw std::runtime_error("Given Freetype bitmap is not 8-bit grayscale");
    }

    return GrayscaleBitmap(ft.fontFace);
}
<commit_msg>typed const<commit_after>#include <exception>
#include <sstream>

extern "C" {
    #include "ft2build.h"
    #include FT_FREETYPE_H
}

#include "freetype_interface.h"
#include "grayscale_bitmap.h"

class FreetypeMaintainer {
public:
    FreetypeMaintainer() : library(nullptr), fontFace(nullptr) {
        int error = FT_Init_FreeType(&library);
        if (error) {
            throw std::runtime_error("Unable to initalize Freetype library");
        }
    };

    virtual ~FreetypeMaintainer() {
        if (fontFace != nullptr) {
            FT_Done_Face(fontFace);
        }

        FT_Done_FreeType(library);
    }

    FT_Library library;
    FT_Face fontFace;

private:
    FreetypeMaintainer(const FreetypeMaintainer&);
};

static FreetypeMaintainer ft;

static const uint32_t FIXED_POINT_26_6_COEFF = 2^6;

void setFontFile(const std::string& newFilePath) {
    #define SAME_AS_NEXT_ARG 0
    static const FT_UInt DEFAULT_HORIZ_RES          = 72;
    static const FT_UInt DEFAULT_VERTICAL_RES       = DEFAULT_HORIZ_RES;
    static const FT_Long FIRST_FACE_IN_FONT_INDEX   = 0;

    int error = FT_New_Face(ft.library, newFilePath.c_str(),
                            FIRST_FACE_IN_FONT_INDEX, &ft.fontFace);

    if (error == FT_Err_Unknown_File_Format) {
        std::stringstream err;
        err << "The font file '" << newFilePath << "' could be opened and read, "
            << "but it appears that its font format is unsupported";
        throw std::runtime_error(err.str());
    }
    else if (error) {
        std::stringstream err;
        err << "The font file '" << newFilePath << "' either could not "
            << "be opened and read, or it is simply broken";
        throw std::runtime_error(err.str());
    }

    if (!FT_IS_FIXED_WIDTH(ft.fontFace)) {
        throw std::runtime_error("Loaded font face must be monospaced");
    }

    if (!FT_IS_SCALABLE(ft.fontFace)) {
        throw std::runtime_error("Loaded font face must be scaleble");
    }

    error = FT_Set_Char_Size(ft.fontFace,   SAME_AS_NEXT_ARG,
                                            16 * FIXED_POINT_26_6_COEFF,
                                            DEFAULT_HORIZ_RES,
                                            DEFAULT_VERTICAL_RES);

    if (error) {
        throw std::runtime_error("Error while setting char size");
    }
}

uint16_t getFontHeight() {
    return ft.fontFace->size->metrics.height / FIXED_POINT_26_6_COEFF;
}

uint16_t getFontWidth() {
    return ft.fontFace->size->metrics.max_advance / FIXED_POINT_26_6_COEFF;
}

GrayscaleBitmap getBitmapForAsciiSymbol(char symbol) {
    int error = FT_Load_Char(   ft.fontFace, static_cast<FT_ULong>(symbol),
                                FT_LOAD_RENDER);

    if (error) {
        throw std::runtime_error("Error while loading char");
    }

    if (ft.fontFace->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
        throw std::runtime_error("Freetype symbol glyph must have bitmap format");
    }

    if (ft.fontFace->glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) {
        throw std::runtime_error("Given Freetype bitmap is not 8-bit grayscale");
    }

    return GrayscaleBitmap(ft.fontFace);
}
<|endoftext|>


<commit_before>#include "gamelib/utils/json.hpp"
#include "gamelib/utils/conversions.hpp"
#include "gamelib/core/geometry/GroupTransform.hpp"
#include <fstream>

namespace gamelib
{
    bool diffJson(const Json::Value& node, const Json::Value& compare, Json::Value* out_)
    {
        auto& out = *out_;

        if (node.type() != compare.type())
        {
            if (node.isIntegral() && compare.isIntegral() && node.asInt() == compare.asInt())
                return false;
            else if (node.isIntegral() && compare.isDouble() && math::almostEquals((double)node.asInt(), compare.asDouble()))
                return false;
            else if (compare.isIntegral() && node.isDouble() && math::almostEquals((double)compare.asInt(), node.asDouble()))
                return false;
        }
        else if (node.isObject())
        {
            bool diff = false;
            for (auto it = node.begin(), end = node.end(); it != end; ++it)
            {
                auto key = it.key().asString();
                if (!compare.isMember(key))
                {
                    out[key] = *it;
                    diff = true;
                }
                else
                {
                    Json::Value val;
                    if (diffJson(*it, compare[key], &val))
                    {
                        out[key] = val;
                        diff = true;
                    }
                }
            }
            return diff;
        }
        else if (node.isArray())
        {
            if (node.size() == compare.size())
            {
                for (Json::ArrayIndex i = 0; i < node.size(); ++i)
                {
                    Json::Value tmp;
                    if (diffJson(node[i], compare[i], &tmp))
                    {
                        out = node;
                        return true;
                    }
                }
                return false;
            }
        }
        else if (node.compare(compare) == 0)
            return false;

        out = node;
        return true;
    }

    bool loadJsonFromFile(const std::string& fname, Json::Value& node)
    {
        LOG("(Re)Loading ", fname, "...");
        std::ifstream f;
        f.open(fname.c_str());
        if (f.is_open())
        {
            f >> node;
            f.close();
            return true;
        }
        LOG_ERROR("Failed to load json from file ", fname);
        return false;
    }

    bool writeJsonToFile(const std::string& fname, const Json::Value& node)
    {
        LOG("Writing to file ", fname, "...");
        std::ofstream f;
        f.open(fname.c_str());
        if (f.is_open())
        {
            f << node.toStyledString();
            f.close();
            return true;
        }
        LOG_ERROR("Failed to write json to file ", fname);
        return false;
    }

    bool loadFromJson(const Json::Value& node, Transformable& transform)
    {
        math::Point2f pos = transform.getPosition();
        math::Vec2f scale = transform.getScale();
        float angle = transform.getRotation();
        auto parent = transform.getParent();

        if (parent)
        {
            pos -= parent->getPosition().asVector();
            scale /= parent->getScale();
            angle -= parent->getRotation();
        }

        if (!loadFromJson(node, &pos, &scale, &angle, false))
            return false;

        if (parent)
        {
            pos += parent->getPosition().asVector();
            scale *= parent->getScale();
            angle += parent->getRotation();
        }

        transform.setPosition(pos);
        transform.setScale(scale);
        transform.setRotation(angle);
        return true;
    }

    bool loadFromJson(const Json::Value& node, math::Point2f* pos, math::Vec2f* scale, float* angle, bool clear)
    {
        // NOTE: It can't load but uses default, so no fail
        // if (!node.isObject())
        //     return false;

        if (pos)
            loadFromJson(node["pos"], pos->asVector(), clear);
        if (scale)
            loadFromJson(node["scale"], *scale, clear);
        if (angle)
            *angle = node.get("angle", clear ? 0 : *angle).asFloat();

        return true;
    }

    bool loadFromJson(const Json::Value& node, math::Point2f& p, bool clear)
    {
        return loadFromJson(node, p.asVector(), clear);
    }

    bool loadFromJson(const Json::Value& node, sf::Vector2f& p, bool clear)
    {
        return loadFromJson(node, convert(p), clear);
    }

    void writeToJson(Json::Value& node, const Transformable& transform)
    {
        auto pos = transform.getPosition();
        auto scale = transform.getScale();
        auto angle = transform.getRotation();
        auto parent = transform.getParent();

        if (parent)
        {
            pos -= parent->getPosition().asVector();
            scale /= parent->getScale();
            angle -= parent->getRotation();
        }

        writeToJson(node, pos, scale, angle);
    }

    void writeToJson(Json::Value& node, const math::Point2f& pos, const math::Vec2f& scale, float angle)
    {
        writeToJson(node["pos"], pos);
        writeToJson(node["scale"], scale);
        node["angle"] = angle;
    }

    void writeToJson(Json::Value& node, const math::Point2f& p)
    {
        writeToJson(node, p.asVector());
    }

    void writeToJson(Json::Value& node, const sf::Vector2f& vec)
    {
        writeToJson(node, convert(vec));
    }
}
<commit_msg>Fix incorrect scale value<commit_after>#include "gamelib/utils/json.hpp"
#include "gamelib/utils/conversions.hpp"
#include "gamelib/core/geometry/GroupTransform.hpp"
#include <fstream>

namespace gamelib
{
    bool diffJson(const Json::Value& node, const Json::Value& compare, Json::Value* out_)
    {
        auto& out = *out_;

        if (node.type() != compare.type())
        {
            if (node.isIntegral() && compare.isIntegral() && node.asInt() == compare.asInt())
                return false;
            else if (node.isIntegral() && compare.isDouble() && math::almostEquals((double)node.asInt(), compare.asDouble()))
                return false;
            else if (compare.isIntegral() && node.isDouble() && math::almostEquals((double)compare.asInt(), node.asDouble()))
                return false;
        }
        else if (node.isObject())
        {
            bool diff = false;
            for (auto it = node.begin(), end = node.end(); it != end; ++it)
            {
                auto key = it.key().asString();
                if (!compare.isMember(key))
                {
                    out[key] = *it;
                    diff = true;
                }
                else
                {
                    Json::Value val;
                    if (diffJson(*it, compare[key], &val))
                    {
                        out[key] = val;
                        diff = true;
                    }
                }
            }
            return diff;
        }
        else if (node.isArray())
        {
            if (node.size() == compare.size())
            {
                for (Json::ArrayIndex i = 0; i < node.size(); ++i)
                {
                    Json::Value tmp;
                    if (diffJson(node[i], compare[i], &tmp))
                    {
                        out = node;
                        return true;
                    }
                }
                return false;
            }
        }
        else if (node.compare(compare) == 0)
            return false;

        out = node;
        return true;
    }

    bool loadJsonFromFile(const std::string& fname, Json::Value& node)
    {
        LOG("(Re)Loading ", fname, "...");
        std::ifstream f;
        f.open(fname.c_str());
        if (f.is_open())
        {
            f >> node;
            f.close();
            return true;
        }
        LOG_ERROR("Failed to load json from file ", fname);
        return false;
    }

    bool writeJsonToFile(const std::string& fname, const Json::Value& node)
    {
        LOG("Writing to file ", fname, "...");
        std::ofstream f;
        f.open(fname.c_str());
        if (f.is_open())
        {
            f << node.toStyledString();
            f.close();
            return true;
        }
        LOG_ERROR("Failed to write json to file ", fname);
        return false;
    }

    bool loadFromJson(const Json::Value& node, Transformable& transform)
    {
        math::Point2f pos = transform.getPosition();
        math::Vec2f scale = transform.getScale();
        float angle = transform.getRotation();
        auto parent = transform.getParent();

        if (parent)
        {
            pos -= parent->getPosition().asVector();
            scale /= parent->getScale();
            angle -= parent->getRotation();
        }

        if (!loadFromJson(node, &pos, &scale, &angle, false))
            return false;

        if (parent)
        {
            pos += parent->getPosition().asVector();
            scale *= parent->getScale();
            angle += parent->getRotation();
        }

        transform.setPosition(pos);
        transform.setScale(scale);
        transform.setRotation(angle);
        return true;
    }

    bool loadFromJson(const Json::Value& node, math::Point2f* pos, math::Vec2f* scale, float* angle, bool clear)
    {
        // NOTE: It can't load but uses default, so no fail
        // if (!node.isObject())
        //     return false;

        if (scale && clear)
            scale->fill(1);

        if (pos)
            loadFromJson(node["pos"], pos->asVector(), clear);
        if (scale)
            loadFromJson(node["scale"], *scale, false);
        if (angle)
            *angle = node.get("angle", clear ? 0 : *angle).asFloat();

        return true;
    }

    bool loadFromJson(const Json::Value& node, math::Point2f& p, bool clear)
    {
        return loadFromJson(node, p.asVector(), clear);
    }

    bool loadFromJson(const Json::Value& node, sf::Vector2f& p, bool clear)
    {
        return loadFromJson(node, convert(p), clear);
    }

    void writeToJson(Json::Value& node, const Transformable& transform)
    {
        auto pos = transform.getPosition();
        auto scale = transform.getScale();
        auto angle = transform.getRotation();
        auto parent = transform.getParent();

        if (parent)
        {
            pos -= parent->getPosition().asVector();
            scale /= parent->getScale();
            angle -= parent->getRotation();
        }

        writeToJson(node, pos, scale, angle);
    }

    void writeToJson(Json::Value& node, const math::Point2f& pos, const math::Vec2f& scale, float angle)
    {
        writeToJson(node["pos"], pos);
        writeToJson(node["scale"], scale);
        node["angle"] = angle;
    }

    void writeToJson(Json::Value& node, const math::Point2f& p)
    {
        writeToJson(node, p.asVector());
    }

    void writeToJson(Json::Value& node, const sf::Vector2f& vec)
    {
        writeToJson(node, convert(vec));
    }
}
<|endoftext|>