<commit_before>/*
 * Copyright (C) 2011-2014 Red Hat, Inc.
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: tasleson
 */

#ifndef LSM_IPC_H
#define LSM_IPC_H

#include "libstoragemgmt/libstoragemgmt_common.h"
#include <map>
#include <sstream>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

// Common serialization

/**
 * Sends and receives payloads, unaware of the contents.
 * Notes:   Not thread safe. i.e. you cannot share the same object with two or
 * more threads.
 */
class LSM_DLL_LOCAL Transport {
  public:
    /**
     * Size of the header which immediately proceeds the payload.
     */
    const static int HDR_LEN = 10;

    /**
     * Empty ctor.
     * @return
     */
    Transport();

    /**
     * Class ctor
     * @param socket_desc   Connected socket descriptor.
     */
    Transport(int socket_desc);

    /**
     * Class dtor
     */
    ~Transport();

    /**
     * Sends a message over the transport.
     * @param[in]   msg         The message to be sent.
     * @param[out]  error_code  Errno (only valid if we return -1)
     * @return 0 on success, else -1
     */
    int msg_send(const std::string &msg, int &error_code);

    /**
     * Received a message over the transport.
     * Note: A zero read indicates that the transport was closed by other side,
     *       no error code will be set in that case.
     * @param error_code    (0 on success, else errno)
     * @return Message on success else 0 size with error_code set (not if EOF)
     */
    std::string msg_recv(int &error_code);

    /**
     * Creates a connected socket (AF_UNIX) to the specified path
     * @param path of the AF_UNIX file to be used for IPC
     * @param error_code    Error reason for the failure (errno)
     * @return -1 on error, else connected socket.
     */
    static int socket_get(const std::string &path, int &error_code);

    /**
     * Closes the transport, called in the destructor if not done in advance.
     * @return 0 on success, else EBADF, EINTR, EIO.
     */
    void close();

  private:
    int s; // Socket descriptor
};

/**
 * Generic function to convert Type v into a string.
 * @param v Template type T
 * @return string representation
 */
template <class Type> static std::string to_string(Type v) {
    std::stringstream out;
    out << v;
    return out.str();
}

/**
 * Class that represents an EOF condition
 * @param m     Message
 */
class LSM_DLL_LOCAL EOFException : public std::runtime_error {
  public:
    EOFException(std::string m);
};

/**
 * User defined class for Value errors during serialize / de-serialize.
 */
class LSM_DLL_LOCAL ValueException : public std::runtime_error {
  public:
    /**
     * Constructor
     * @param m Exception message
     */
    ValueException(std::string m);
};

/**
 * User defined class for errors
 */
class LSM_DLL_LOCAL LsmException : public std::runtime_error {
  public:
    /**
     * Constructor
     * @param code      Error code
     * @param msg       Error message
     */
    LsmException(int code, std::string &msg);

    /**
     * Constructor
     * @param code          Error code
     * @param msg           Error message
     * @param debug_addl    Additional debug data
     */
    LsmException(int code, std::string &msg, const std::string &debug_addl);

    /**
     * Constructor
     * @param code              Error code
     * @param msg               Error message
     * @param debug_addl        Additional debug
     * @param debug_data_addl   Additional debug data
     */
    LsmException(int code, std::string &msg, const std::string &debug_addl,
                 const std::string &debug_data_addl);

    /**
     * Destructor
     */
    ~LsmException() throw();

    int error_code;
    std::string debug;
    std::string debug_data;
};

/**
 * Represents a value in the serialization.
 */
class LSM_DLL_LOCAL Value {
  public:
    /**
     * Different types this class can hold.
     */
    enum value_type {
        null_t,
        boolean_t,
        string_t,
        numeric_t,
        object_t,
        array_t
    };

    /**
     * Default constructor creates a "null" type
     */
    Value(void);

    /**
     * Boolean constructor
     * @param v value
     */
    Value(bool v);

    /**
     * Numeric unsigned 32 constructor
     * @param v value
     */
    Value(uint32_t v);

    /**
     * Numeric signed 32 constructor
     * @param v value
     */
    Value(int32_t v);

    /**
     * Numeric unsigned 64 constructor.
     * @param v value
     */
    Value(uint64_t v);

    /**
     * Numeric signed 64 constructor.
     * @param v value
     */
    Value(int64_t v);

    /**
     * Constructor in which you specify type and initial value as string.
     * @param type  Type this object will hold.
     * @param v value
     */
    Value(value_type type, const std::string &v);

    /**
     * Constructor for char * i.e. string.
     * @param v value
     */
    Value(const char *v);

    /**
     * Constructor for std::string
     * @param v value
     */
    Value(const std::string &v);

    /**
     * Constructor for object type
     * @param v values
     */
    Value(const std::map<std::string, Value> &v);

    /**
     * Constructor for array type
     * @param v array values
     */
    Value(const std::vector<Value> &v);

    /**
     * Serialize Value to json
     * @return
     */
    std::string serialize(void);

    /**
     * Returns the enumerated type represented by object
     * @return enumerated type
     */
    value_type valueType() const;

    /**
     * Overloaded operator for map access
     * @param key
     * @return Value
     */
    Value &operator[](const std::string &key);

    /**
     * Overloaded operator for vector(array) access
     * @param i
     * @return Value
     */
    Value &operator[](uint32_t i);

    /**
     * Returns true if value has a key in key/value pair
     * @return true if key exists, else false.
     */
    bool hasKey(const std::string &k);

    /**
     * Checks to see if a Value contains a valid request
     * @return True if it is a request, else false
     */
    bool isValidRequest(void);

    /**
     * Given a key returns the value.
     * @param key
     * @return Value
     */
    Value getValue(const char *key);

    /**
     * Boolean value represented by object.
     * @return true, false ValueException on error
     */
    bool asBool();

    /**
     * Signed 32 integer value represented by object.
     * @return integer value else ValueException on error
     */
    int32_t asInt32_t();

    /**
     * Signed 64 integer value represented by object.
     * @return integer value else ValueException on error
     */
    int64_t asInt64_t();

    /**
     * Unsigned 32 integer value represented by object.
     * @return integer value else ValueException on error
     */
    uint32_t asUint32_t();

    /**
     * Unsigned 64 integer value represented by object.
     * @return integer value else ValueException on error
     */
    uint64_t asUint64_t();

    /**
     * String value represented by object.
     * @return string value else ValueException on error
     */
    std::string asString();

    /**
     * Return string as a pointer to a character array
     * @return
     */
    const char *asC_str();

    /**
     * key/value represented by object.
     * @return map of key and values else ValueException on error
     */
    std::map<std::string, Value> asObject();

    /**
     * vector of values represented by object.
     * @return vector of array values else ValueException on error
     */
    std::vector<Value> asArray();

  private:
    value_type t;
    std::vector<Value> array;
    std::map<std::string, Value> obj;
    std::string s;
};

/**
 * Serialize, de-serialize methods.
 */
class LSM_DLL_LOCAL Payload {
  public:
    /**
     * Given a Value returns json representation.
     * @param v Value to serialize
     * @return String representation
     */
    static std::string serialize(Value &v);

    /**
     * Given a json string return a Value
     * @param json  String to de-serialize
     * @return Value
     */
    static Value deserialize(const std::string &json);
};

class LSM_DLL_LOCAL Ipc {
  public:
    /**
     * Constructor
     */
    Ipc();

    /**
     * Constructor that takes a file descriptor
     * @param fd    File descriptor to use
     */
    Ipc(int fd);

    /**
     * Constructor that takes a socket path
     * @param socket_path   Unix domain socket
     */
    Ipc(std::string socket_path);

    /**
     * Destructor
     */
    ~Ipc();

    /**
     * Send a request over IPC
     * @param request       IPC function name
     * @param params        Parameters
     * @param id            Request ID
     */
    void requestSend(const std::string request, const Value &params,
                     int32_t id = 100);
    /**
     * Reads a request
     * @returns Value
     */
    Value readRequest(void);

    /**
     * Send a response to a request
     * @param response      Response value
     * @param id            Id that matches request
     */
    void responseSend(const Value &response, uint32_t id = 100);

    /**
     * Read a response
     * @return Value of response
     */
    Value responseRead();

    /**
     * Send an error
     * @param error_code        Error code
     * @param msg               Error message
     * @param debug             Debug data
     * @param id                Id that matches request
     */
    void errorSend(int error_code, std::string msg, std::string debug,
                   uint32_t id = 100);

    /**
     * Do a remote procedure call (Request with a returned response
     * @param request           Function method
     * @param params            Function parameters
     * @param id                Id of request
     * @return Result of the operation.
     */
    Value rpc(const std::string &request, const Value &params,
              int32_t id = 100);

  private:
    Transport t;
};

#endif
<commit_msg>Correct Transport header comment<commit_after>/*
 * Copyright (C) 2011-2014 Red Hat, Inc.
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: tasleson
 */

#ifndef LSM_IPC_H
#define LSM_IPC_H

#include "libstoragemgmt/libstoragemgmt_common.h"
#include <map>
#include <sstream>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

// Common serialization

/**
 * Sends and receives payloads, unaware of the contents.
 * Notes:   Not thread safe. i.e. you cannot share the same object with two or
 * more threads.
 */
class LSM_DLL_LOCAL Transport {
  public:
    /**
     * Size of the header which immediately precedes the payload.
     */
    const static int HDR_LEN = 10;

    /**
     * Empty ctor.
     * @return
     */
    Transport();

    /**
     * Class ctor
     * @param socket_desc   Connected socket descriptor.
     */
    Transport(int socket_desc);

    /**
     * Class dtor
     */
    ~Transport();

    /**
     * Sends a message over the transport.
     * @param[in]   msg         The message to be sent.
     * @param[out]  error_code  Errno (only valid if we return -1)
     * @return 0 on success, else -1
     */
    int msg_send(const std::string &msg, int &error_code);

    /**
     * Received a message over the transport.
     * Note: A zero read indicates that the transport was closed by other side,
     *       no error code will be set in that case.
     * @param error_code    (0 on success, else errno)
     * @return Message on success else 0 size with error_code set (not if EOF)
     */
    std::string msg_recv(int &error_code);

    /**
     * Creates a connected socket (AF_UNIX) to the specified path
     * @param path of the AF_UNIX file to be used for IPC
     * @param error_code    Error reason for the failure (errno)
     * @return -1 on error, else connected socket.
     */
    static int socket_get(const std::string &path, int &error_code);

    /**
     * Closes the transport, called in the destructor if not done in advance.
     * @return 0 on success, else EBADF, EINTR, EIO.
     */
    void close();

  private:
    int s; // Socket descriptor
};

/**
 * Generic function to convert Type v into a string.
 * @param v Template type T
 * @return string representation
 */
template <class Type> static std::string to_string(Type v) {
    std::stringstream out;
    out << v;
    return out.str();
}

/**
 * Class that represents an EOF condition
 * @param m     Message
 */
class LSM_DLL_LOCAL EOFException : public std::runtime_error {
  public:
    EOFException(std::string m);
};

/**
 * User defined class for Value errors during serialize / de-serialize.
 */
class LSM_DLL_LOCAL ValueException : public std::runtime_error {
  public:
    /**
     * Constructor
     * @param m Exception message
     */
    ValueException(std::string m);
};

/**
 * User defined class for errors
 */
class LSM_DLL_LOCAL LsmException : public std::runtime_error {
  public:
    /**
     * Constructor
     * @param code      Error code
     * @param msg       Error message
     */
    LsmException(int code, std::string &msg);

    /**
     * Constructor
     * @param code          Error code
     * @param msg           Error message
     * @param debug_addl    Additional debug data
     */
    LsmException(int code, std::string &msg, const std::string &debug_addl);

    /**
     * Constructor
     * @param code              Error code
     * @param msg               Error message
     * @param debug_addl        Additional debug
     * @param debug_data_addl   Additional debug data
     */
    LsmException(int code, std::string &msg, const std::string &debug_addl,
                 const std::string &debug_data_addl);

    /**
     * Destructor
     */
    ~LsmException() throw();

    int error_code;
    std::string debug;
    std::string debug_data;
};

/**
 * Represents a value in the serialization.
 */
class LSM_DLL_LOCAL Value {
  public:
    /**
     * Different types this class can hold.
     */
    enum value_type {
        null_t,
        boolean_t,
        string_t,
        numeric_t,
        object_t,
        array_t
    };

    /**
     * Default constructor creates a "null" type
     */
    Value(void);

    /**
     * Boolean constructor
     * @param v value
     */
    Value(bool v);

    /**
     * Numeric unsigned 32 constructor
     * @param v value
     */
    Value(uint32_t v);

    /**
     * Numeric signed 32 constructor
     * @param v value
     */
    Value(int32_t v);

    /**
     * Numeric unsigned 64 constructor.
     * @param v value
     */
    Value(uint64_t v);

    /**
     * Numeric signed 64 constructor.
     * @param v value
     */
    Value(int64_t v);

    /**
     * Constructor in which you specify type and initial value as string.
     * @param type  Type this object will hold.
     * @param v value
     */
    Value(value_type type, const std::string &v);

    /**
     * Constructor for char * i.e. string.
     * @param v value
     */
    Value(const char *v);

    /**
     * Constructor for std::string
     * @param v value
     */
    Value(const std::string &v);

    /**
     * Constructor for object type
     * @param v values
     */
    Value(const std::map<std::string, Value> &v);

    /**
     * Constructor for array type
     * @param v array values
     */
    Value(const std::vector<Value> &v);

    /**
     * Serialize Value to json
     * @return
     */
    std::string serialize(void);

    /**
     * Returns the enumerated type represented by object
     * @return enumerated type
     */
    value_type valueType() const;

    /**
     * Overloaded operator for map access
     * @param key
     * @return Value
     */
    Value &operator[](const std::string &key);

    /**
     * Overloaded operator for vector(array) access
     * @param i
     * @return Value
     */
    Value &operator[](uint32_t i);

    /**
     * Returns true if value has a key in key/value pair
     * @return true if key exists, else false.
     */
    bool hasKey(const std::string &k);

    /**
     * Checks to see if a Value contains a valid request
     * @return True if it is a request, else false
     */
    bool isValidRequest(void);

    /**
     * Given a key returns the value.
     * @param key
     * @return Value
     */
    Value getValue(const char *key);

    /**
     * Boolean value represented by object.
     * @return true, false ValueException on error
     */
    bool asBool();

    /**
     * Signed 32 integer value represented by object.
     * @return integer value else ValueException on error
     */
    int32_t asInt32_t();

    /**
     * Signed 64 integer value represented by object.
     * @return integer value else ValueException on error
     */
    int64_t asInt64_t();

    /**
     * Unsigned 32 integer value represented by object.
     * @return integer value else ValueException on error
     */
    uint32_t asUint32_t();

    /**
     * Unsigned 64 integer value represented by object.
     * @return integer value else ValueException on error
     */
    uint64_t asUint64_t();

    /**
     * String value represented by object.
     * @return string value else ValueException on error
     */
    std::string asString();

    /**
     * Return string as a pointer to a character array
     * @return
     */
    const char *asC_str();

    /**
     * key/value represented by object.
     * @return map of key and values else ValueException on error
     */
    std::map<std::string, Value> asObject();

    /**
     * vector of values represented by object.
     * @return vector of array values else ValueException on error
     */
    std::vector<Value> asArray();

  private:
    value_type t;
    std::vector<Value> array;
    std::map<std::string, Value> obj;
    std::string s;
};

/**
 * Serialize, de-serialize methods.
 */
class LSM_DLL_LOCAL Payload {
  public:
    /**
     * Given a Value returns json representation.
     * @param v Value to serialize
     * @return String representation
     */
    static std::string serialize(Value &v);

    /**
     * Given a json string return a Value
     * @param json  String to de-serialize
     * @return Value
     */
    static Value deserialize(const std::string &json);
};

class LSM_DLL_LOCAL Ipc {
  public:
    /**
     * Constructor
     */
    Ipc();

    /**
     * Constructor that takes a file descriptor
     * @param fd    File descriptor to use
     */
    Ipc(int fd);

    /**
     * Constructor that takes a socket path
     * @param socket_path   Unix domain socket
     */
    Ipc(std::string socket_path);

    /**
     * Destructor
     */
    ~Ipc();

    /**
     * Send a request over IPC
     * @param request       IPC function name
     * @param params        Parameters
     * @param id            Request ID
     */
    void requestSend(const std::string request, const Value &params,
                     int32_t id = 100);
    /**
     * Reads a request
     * @returns Value
     */
    Value readRequest(void);

    /**
     * Send a response to a request
     * @param response      Response value
     * @param id            Id that matches request
     */
    void responseSend(const Value &response, uint32_t id = 100);

    /**
     * Read a response
     * @return Value of response
     */
    Value responseRead();

    /**
     * Send an error
     * @param error_code        Error code
     * @param msg               Error message
     * @param debug             Debug data
     * @param id                Id that matches request
     */
    void errorSend(int error_code, std::string msg, std::string debug,
                   uint32_t id = 100);

    /**
     * Do a remote procedure call (Request with a returned response
     * @param request           Function method
     * @param params            Function parameters
     * @param id                Id of request
     * @return Result of the operation.
     */
    Value rpc(const std::string &request, const Value &params,
              int32_t id = 100);

  private:
    Transport t;
};

#endif
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2019 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/executor/mpmcqueue.h"

namespace grpc_core {

DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool");

inline void* InfLenFIFOQueue::PopFront() {
  // Caller should already check queue is not empty and has already held the
  // mutex. This function will only do the job of removal.
  void* result = queue_head_->content;
  Node* head_to_remove = queue_head_;
  queue_head_ = queue_head_->next;

  count_.FetchSub(1, MemoryOrder::RELAXED);

  if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
    gpr_timespec wait_time =
        gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), head_to_remove->insert_time);

    // Updates Stats info
    stats_.num_completed++;
    stats_.total_queue_time = gpr_time_add(stats_.total_queue_time, wait_time);
    stats_.max_queue_time = gpr_time_max(
        gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), wait_time);

    if (count_.Load(MemoryOrder::RELAXED) == 0) {
      stats_.busy_queue_time =
          gpr_time_add(stats_.busy_queue_time,
                       gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), busy_time));
    }

    gpr_log(GPR_INFO,
            "[InfLenFIFOQueue PopFront] num_completed:        %" PRIu64
            " total_queue_time: %f max_queue_time:   %f busy_queue_time:   %f",
            stats_.num_completed,
            gpr_timespec_to_micros(stats_.total_queue_time),
            gpr_timespec_to_micros(stats_.max_queue_time),
            gpr_timespec_to_micros(stats_.busy_queue_time));
  }

  Delete(head_to_remove);
  // Singal waiting thread
  if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) {
    wait_nonempty_.Signal();
  }

  return result;
}

InfLenFIFOQueue::~InfLenFIFOQueue() {
  GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0);
  GPR_ASSERT(num_waiters_ == 0);
}

void InfLenFIFOQueue::Put(void* elem) {
  MutexLock l(&mu_);

  Node* new_node = New<Node>(elem);
  if (count_.FetchAdd(1, MemoryOrder::RELAXED) == 0) {
    if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
      busy_time = gpr_now(GPR_CLOCK_MONOTONIC);
    }
    queue_head_ = queue_tail_ = new_node;
  } else {
    queue_tail_->next = new_node;
    queue_tail_ = queue_tail_->next;
  }

  // Updates Stats info
  if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
    stats_.num_started++;
    gpr_log(GPR_INFO, "[InfLenFIFOQueue Put] num_started:        %" PRIu64,
            stats_.num_started);
  }

  if (num_waiters_ > 0) {
    wait_nonempty_.Signal();
  }
}

void* InfLenFIFOQueue::Get() {
  MutexLock l(&mu_);
  if (count_.Load(MemoryOrder::RELAXED) == 0) {
    num_waiters_++;
    do {
      wait_nonempty_.Wait(&mu_);
    } while (count_.Load(MemoryOrder::RELAXED) == 0);
    num_waiters_--;
  }
  GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0);
  return PopFront();
}

}  // namespace grpc_core
<commit_msg>Change FetchAdd/Sub to Load-Add/Sub-Store<commit_after>/*
 *
 * Copyright 2019 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/executor/mpmcqueue.h"

namespace grpc_core {

DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool");

inline void* InfLenFIFOQueue::PopFront() {
  // Caller should already check queue is not empty and has already held the
  // mutex. This function will only do the job of removal.
  void* result = queue_head_->content;
  Node* head_to_remove = queue_head_;
  queue_head_ = queue_head_->next;

  count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED);

  if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
    gpr_timespec wait_time =
        gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), head_to_remove->insert_time);

    // Updates Stats info
    stats_.num_completed++;
    stats_.total_queue_time = gpr_time_add(stats_.total_queue_time, wait_time);
    stats_.max_queue_time = gpr_time_max(
        gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), wait_time);

    if (count_.Load(MemoryOrder::RELAXED) == 0) {
      stats_.busy_queue_time =
          gpr_time_add(stats_.busy_queue_time,
                       gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), busy_time));
    }

    gpr_log(GPR_INFO,
            "[InfLenFIFOQueue PopFront] num_completed:        %" PRIu64
            " total_queue_time: %f max_queue_time:   %f busy_queue_time:   %f",
            stats_.num_completed,
            gpr_timespec_to_micros(stats_.total_queue_time),
            gpr_timespec_to_micros(stats_.max_queue_time),
            gpr_timespec_to_micros(stats_.busy_queue_time));
  }

  Delete(head_to_remove);
  // Singal waiting thread
  if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) {
    wait_nonempty_.Signal();
  }

  return result;
}

InfLenFIFOQueue::~InfLenFIFOQueue() {
  GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0);
  GPR_ASSERT(num_waiters_ == 0);
}

void InfLenFIFOQueue::Put(void* elem) {
  MutexLock l(&mu_);

  Node* new_node = New<Node>(elem);
  if (count_.Load(MemoryOrder::RELAXED) == 0) {
    if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
      busy_time = gpr_now(GPR_CLOCK_MONOTONIC);
    }
    queue_head_ = queue_tail_ = new_node;
  } else {
    queue_tail_->next = new_node;
    queue_tail_ = queue_tail_->next;
  }
  count_.Store(count_.Load(MemoryOrder::RELAXED) + 1, MemoryOrder::RELAXED);
  // Updates Stats info
  if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) {
    stats_.num_started++;
    gpr_log(GPR_INFO, "[InfLenFIFOQueue Put] num_started:        %" PRIu64,
            stats_.num_started);
  }

  if (num_waiters_ > 0) {
    wait_nonempty_.Signal();
  }
}

void* InfLenFIFOQueue::Get() {
  MutexLock l(&mu_);
  if (count_.Load(MemoryOrder::RELAXED) == 0) {
    num_waiters_++;
    do {
      wait_nonempty_.Wait(&mu_);
    } while (count_.Load(MemoryOrder::RELAXED) == 0);
    num_waiters_--;
  }
  GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0);
  return PopFront();
}

}  // namespace grpc_core
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
    @brief  RX24T EEPROM サンプル @n
			・P00(4) ピンに赤色LED（VF:1.9V）を吸い込みで接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/cmt_io.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/command.hpp"

namespace {

	class cmt_task {
	public:
		void operator() () {
		}
	};

	device::cmt_io<device::CMT0, cmt_task>  cmt_;

	typedef utils::fixed_fifo<char, 128> fifo128;
	device::sci_io<device::SCI1, fifo128, fifo128> sci_;

	utils::command<256> command_;
}

extern "C" {

	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	device::SYSTEM::PRCR = 0xA50B;	// クロック、低消費電力、関係書き込み許可

	device::SYSTEM::MEMWAIT = 0b10; // 80MHz 動作 wait 設定

	while(device::SYSTEM::OPCCR.OPCMTSF() != 0) asm("nop");
	device::SYSTEM::OPCCR = 0;  // 高速モード選択
	while(device::SYSTEM::OPCCR.OPCMTSF() != 0) asm("nop");

	// clock osc 10MHz
	device::SYSTEM::MOSCWTCR = 9;	// 4ms wait
	// メインクロック・ドライブ能力設定、内部発信
	device::SYSTEM::MOFCR = device::SYSTEM::MOFCR.MODRV21.b(1);
	device::SYSTEM::MOSCCR.MOSTP = 0;  // メインクロック発振器動作
	while(device::SYSTEM::OSCOVFSR.MOOVF() == 0) asm("nop");

	device::SYSTEM::PLLCR.STC = 0b001111;		// PLL input: 1, PLL 8 倍(80MHz)
	device::SYSTEM::PLLCR2.PLLEN = 0;			// PLL 動作
	while(device::SYSTEM::OSCOVFSR.PLOVF() == 0) asm("nop");

	device::SYSTEM::SCKCR = device::SYSTEM::SCKCR.FCK.b(2)		// 1/4 (80/4=20)
						  | device::SYSTEM::SCKCR.ICK.b(0)		// 1/1 (80/1=80)
						  | device::SYSTEM::SCKCR.PCKA.b(0)		// 1/1 (80/1=80)
						  | device::SYSTEM::SCKCR.PCKB.b(1)		// 1/2 (80/2=40)
						  | device::SYSTEM::SCKCR.PCKD.b(1);	// 1/2 (80/2=40)
	device::SYSTEM::SCKCR3.CKSEL = 0b100;	///< PLL 選択

	// タイマー設定（６０Ｈｚ）
	uint8_t cmt_irq_level = 4;
	cmt_.start(60, cmt_irq_level);

	// SCI 設定
	static const uint8_t sci_level = 2;
	sci_.start(115200, sci_level);

	utils::format("RX24T EEPROM sample\n");

	command_.set_prompt("# ");

	device::PORT0::PDR.B0 = 1; // output

	uint32_t cnt = 0;
	while(1) {
		cmt_.sync();

		// コマンド入力と、コマンド解析
		if(command_.service()) {

		}

		++cnt;
		if(cnt >= 30) {
			cnt = 0;
		}
		device::PORT0::PODR.B0 = (cnt < 10) ? 0 : 1;
	}
}
<commit_msg>Rename: cmt_io to cmt_mgr<commit_after>//=====================================================================//
/*! @file
    @brief  RX24T EEPROM サンプル @n
			・P00(4) ピンに赤色LED（VF:1.9V）を吸い込みで接続する
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/renesas.hpp"
#include "common/cmt_mgr.hpp"
#include "common/fixed_fifo.hpp"
#include "common/sci_io.hpp"
#include "common/format.hpp"
#include "common/command.hpp"

namespace {

	class cmt_task {
	public:
		void operator() () {
		}
	};

	device::cmt_mgr<device::CMT0, cmt_task>  cmt_;

	typedef utils::fixed_fifo<char, 128> fifo128;
	device::sci_io<device::SCI1, fifo128, fifo128> sci_;

	utils::command<256> command_;
}

extern "C" {

	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	void sci_puts(const char* str)
	{
		sci_.puts(str);
	}

	char sci_getch(void)
	{
		return sci_.getch();
	}

	uint16_t sci_length()
	{
		return sci_.recv_length();
	}

}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	device::SYSTEM::PRCR = 0xA50B;	// クロック、低消費電力、関係書き込み許可

	device::SYSTEM::MEMWAIT = 0b10; // 80MHz 動作 wait 設定

	while(device::SYSTEM::OPCCR.OPCMTSF() != 0) asm("nop");
	device::SYSTEM::OPCCR = 0;  // 高速モード選択
	while(device::SYSTEM::OPCCR.OPCMTSF() != 0) asm("nop");

	// clock osc 10MHz
	device::SYSTEM::MOSCWTCR = 9;	// 4ms wait
	// メインクロック・ドライブ能力設定、内部発信
	device::SYSTEM::MOFCR = device::SYSTEM::MOFCR.MODRV21.b(1);
	device::SYSTEM::MOSCCR.MOSTP = 0;  // メインクロック発振器動作
	while(device::SYSTEM::OSCOVFSR.MOOVF() == 0) asm("nop");

	device::SYSTEM::PLLCR.STC = 0b001111;		// PLL input: 1, PLL 8 倍(80MHz)
	device::SYSTEM::PLLCR2.PLLEN = 0;			// PLL 動作
	while(device::SYSTEM::OSCOVFSR.PLOVF() == 0) asm("nop");

	device::SYSTEM::SCKCR = device::SYSTEM::SCKCR.FCK.b(2)		// 1/4 (80/4=20)
						  | device::SYSTEM::SCKCR.ICK.b(0)		// 1/1 (80/1=80)
						  | device::SYSTEM::SCKCR.PCKA.b(0)		// 1/1 (80/1=80)
						  | device::SYSTEM::SCKCR.PCKB.b(1)		// 1/2 (80/2=40)
						  | device::SYSTEM::SCKCR.PCKD.b(1);	// 1/2 (80/2=40)
	device::SYSTEM::SCKCR3.CKSEL = 0b100;	///< PLL 選択

	// タイマー設定（６０Ｈｚ）
	uint8_t cmt_irq_level = 4;
	cmt_.start(60, cmt_irq_level);

	// SCI 設定
	static const uint8_t sci_level = 2;
	sci_.start(115200, sci_level);

	utils::format("RX24T EEPROM sample\n");

	command_.set_prompt("# ");

	device::PORT0::PDR.B0 = 1; // output

	uint32_t cnt = 0;
	while(1) {
		cmt_.sync();

		// コマンド入力と、コマンド解析
		if(command_.service()) {

		}

		++cnt;
		if(cnt >= 30) {
			cnt = 0;
		}
		device::PORT0::PODR.B0 = (cnt < 10) ? 0 : 1;
	}
}
<|endoftext|>


<commit_before>/************************************
** No Bullsh*t Command Line Parser **
** nbcl.cpp                        **
** Copyright 2011-2012 OmegaSDG    **
************************************/

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

#include "nbcl.h"

NBCL::NBCL(int argc, char** argv) :
	argc(argc), argv(argv), strayArgsDesc("")
{
}

NBCL::~NBCL()
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++)
		delete OptList[opt];
}

void NBCL::insert(std::string shortopt, std::string longopt,
	std::string arg, std::string desc)
{
	Option* opt = new Option;
	opt->shortopt = shortopt;
	opt->longopt = longopt;
	opt->arg = arg;
	opt->desc = desc;
	opt->present = false;
	opt->value = "";
	OptList.push_back(opt);
}

void NBCL::setStrayArgsDesc(std::string desc)
{
	strayArgsDesc = desc;
}

bool NBCL::parse()
{
	int argn;
	int opt;

	for (argn = 1; argn < argc; argn++) { /* Read command line. */
		opt = findOpt(argv[argn]);
		if (opt!=-1) { /* This argument is an option switch. */
			if (!OptList[opt]->arg.empty()) { /* It takes an argument. */
				if (argn + 1 < argc) {
					OptList[opt]->value = argv[argn+1]; /* Add next argument as the option value. */
					argn++;
				}
				else
					return false;
			}
			OptList[opt]->present = true; /* Tell the option it exists. */
		}
		else /* This argument is a stray. */
			strayArgsList.push_back(argv[argn]);
	}
	return true;
}

bool NBCL::check(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->present;
	else
		return false;
}

std::string NBCL::get(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->value;
	else
		return "";
}

void NBCL::usage()
{
	int optmax = 0;
	int argmax = 0;

	usageSize(&optmax, &argmax);
	usagePrintShort();
	usagePrintLong(optmax, argmax);
}

std::vector<std::string> NBCL::getStrayArgsList()
{
	return strayArgsList;
}

/* Makes width calculations needed for formatting usage output. */
void NBCL::usageSize(int* optmax, int* argmax)
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++) {
		if (OptList[opt]->shortopt.size() + OptList[opt]->longopt.size() > (unsigned)*optmax)
			*optmax = (int)OptList[opt]->shortopt.size() + (int)OptList[opt]->longopt.size() + 1;

		if ((int)OptList[opt]->arg.size() > *argmax)
			*argmax = (int)OptList[opt]->arg.size();
	}
}

void NBCL::usagePrintShort()
{
	#ifdef _WIN32
		char fname[_MAX_FNAME];
		char ext[_MAX_EXT];
		_splitpath(argv[0], NULL, NULL, fname, ext);
		if (ext[strlen(ext)-1] == ' ') /* Windows thinks I want a space at the end. It's wrong. */
			ext[strlen(ext)-1] = 0;
		fprintf(stderr, "Usage: %s%s [OPTIONS] ", fname, ext);
	#else
		fprintf(stderr, "Usage: %s [OPTIONS] ", argv[0]);
	#endif
	fprintf(stderr, strayArgsDesc.c_str());
}

/* Lots of ugly formatting code. */
void NBCL::usagePrintLong(int optmax, int argmax)
{
	unsigned int opt;

	fprintf(stderr, "\n\nAvailable options:\n");

	for (opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.empty())
			fprintf(stderr, "  %s,", OptList[opt]->shortopt.c_str());
		else
			fprintf(stderr, "     ");

		fprintf(stderr, (std::string("%-")+itostr(optmax+1)+"s").c_str(), OptList[opt]->longopt.c_str());

		if (!OptList[opt]->arg.empty())
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"s").c_str(), OptList[opt]->arg.c_str());
		else
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"c").c_str(), ' ');

		fprintf(stderr, "%s\n", OptList[opt]->desc.c_str());
	}
}

std::string NBCL::itostr(int in)
{
	std::stringstream out;
	out << in;
	return out.str();
}

int NBCL::findOpt(std::string name)
{
	for (unsigned int opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.compare(name) ||
			!OptList[opt]->longopt.compare(name))
				return opt;
	}
	return -1;
}

/* Thanks to:
 * http://stackoverflow.com/questions/1022957
 * http://stackoverflow.com/questions/6812224
*/
/* TODO: Use for breaking lines on small consoles. */
unsigned int NBCL::getConsoleWidth()
{
	#if defined __unix__ || defined __APPLE__
		struct winsize w;
		ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
		return (unsigned int)w.ws_col;
	#elif _WIN32
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		int ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
		if (ret)
			return (unsigned int)csbi.dwSize.X;
		else
			return 0; /* Failure */
	#else
		return 0; /* Failure */
	#endif
}

<commit_msg>Anything starting with a dash is traditionally assumed to be an option switch.<commit_after>/************************************
** No Bullsh*t Command Line Parser **
** nbcl.cpp                        **
** Copyright 2011-2012 OmegaSDG    **
************************************/

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

#include "nbcl.h"

NBCL::NBCL(int argc, char** argv) :
	argc(argc), argv(argv), strayArgsDesc("")
{
}

NBCL::~NBCL()
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++)
		delete OptList[opt];
}

void NBCL::insert(std::string shortopt, std::string longopt,
	std::string arg, std::string desc)
{
	Option* opt = new Option;
	opt->shortopt = shortopt;
	opt->longopt = longopt;
	opt->arg = arg;
	opt->desc = desc;
	opt->present = false;
	opt->value = "";
	OptList.push_back(opt);
}

void NBCL::setStrayArgsDesc(std::string desc)
{
	strayArgsDesc = desc;
}

bool NBCL::parse()
{
	int argn;
	int opt;

	for (argn = 1; argn < argc; argn++) { /* Read command line. */
		opt = findOpt(argv[argn]);
		if (opt!=-1) { /* This argument is an option switch. */
			if (!OptList[opt]->arg.empty()) { /* It takes an argument. */
				if (argn + 1 < argc) {
					OptList[opt]->value = argv[argn+1]; /* Add next argument as the option value. */
					argn++;
				}
				else
					return false;
			}
			OptList[opt]->present = true; /* Tell the option it exists. */
		}
		else if (argv[argn][0] == '-') /* Nonexistent option. */
			return false;
		else /* This argument is a stray. */
			strayArgsList.push_back(argv[argn]);
	}
	return true;
}

bool NBCL::check(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->present;
	else
		return false;
}

std::string NBCL::get(std::string longopt)
{
	int opt = findOpt(longopt);
	if (opt!=-1)
		return OptList[opt]->value;
	else
		return "";
}

void NBCL::usage()
{
	int optmax = 0;
	int argmax = 0;

	usageSize(&optmax, &argmax);
	usagePrintShort();
	usagePrintLong(optmax, argmax);
}

std::vector<std::string> NBCL::getStrayArgsList()
{
	return strayArgsList;
}

/* Makes width calculations needed for formatting usage output. */
void NBCL::usageSize(int* optmax, int* argmax)
{
	unsigned int opt;

	for (opt = 0; opt < OptList.size(); opt++) {
		if (OptList[opt]->shortopt.size() + OptList[opt]->longopt.size() > (unsigned)*optmax)
			*optmax = (int)OptList[opt]->shortopt.size() + (int)OptList[opt]->longopt.size() + 1;

		if ((int)OptList[opt]->arg.size() > *argmax)
			*argmax = (int)OptList[opt]->arg.size();
	}
}

void NBCL::usagePrintShort()
{
	#ifdef _WIN32
		char fname[_MAX_FNAME];
		char ext[_MAX_EXT];
		_splitpath(argv[0], NULL, NULL, fname, ext);
		if (ext[strlen(ext)-1] == ' ') /* Windows thinks I want a space at the end. It's wrong. */
			ext[strlen(ext)-1] = 0;
		fprintf(stderr, "Usage: %s%s [OPTIONS] ", fname, ext);
	#else
		fprintf(stderr, "Usage: %s [OPTIONS] ", argv[0]);
	#endif
	fprintf(stderr, strayArgsDesc.c_str());
}

/* Lots of ugly formatting code. */
void NBCL::usagePrintLong(int optmax, int argmax)
{
	unsigned int opt;

	fprintf(stderr, "\n\nAvailable options:\n");

	for (opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.empty())
			fprintf(stderr, "  %s,", OptList[opt]->shortopt.c_str());
		else
			fprintf(stderr, "     ");

		fprintf(stderr, (std::string("%-")+itostr(optmax+1)+"s").c_str(), OptList[opt]->longopt.c_str());

		if (!OptList[opt]->arg.empty())
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"s").c_str(), OptList[opt]->arg.c_str());
		else
			fprintf(stderr, (std::string("%-")+itostr(argmax+3)+"c").c_str(), ' ');

		fprintf(stderr, "%s\n", OptList[opt]->desc.c_str());
	}
}

std::string NBCL::itostr(int in)
{
	std::stringstream out;
	out << in;
	return out.str();
}

int NBCL::findOpt(std::string name)
{
	for (unsigned int opt = 0; opt < OptList.size(); opt++) {
		if (!OptList[opt]->shortopt.compare(name) ||
			!OptList[opt]->longopt.compare(name))
				return opt;
	}
	return -1;
}

/* Thanks to:
 * http://stackoverflow.com/questions/1022957
 * http://stackoverflow.com/questions/6812224
*/
/* TODO: Use for breaking lines on small consoles. */
unsigned int NBCL::getConsoleWidth()
{
	#if defined __unix__ || defined __APPLE__
		struct winsize w;
		ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
		return (unsigned int)w.ws_col;
	#elif _WIN32
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		int ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
		if (ret)
			return (unsigned int)csbi.dwSize.X;
		else
			return 0; /* Failure */
	#else
		return 0; /* Failure */
	#endif
}

<|endoftext|>


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

#include "chrome/browser/autofill/autofill_manager.h"

#include <string>

#include "base/command_line.h"
#include "chrome/browser/autofill/autofill_dialog.h"
#include "chrome/browser/autofill/autofill_infobar_delegate.h"
#include "chrome/browser/autofill/form_structure.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/form_field_values.h"

AutoFillManager::AutoFillManager(TabContents* tab_contents)
    : tab_contents_(tab_contents),
      personal_data_(NULL),
      infobar_(NULL) {
  DCHECK(tab_contents);
  personal_data_ = tab_contents_->profile()->GetPersonalDataManager();
}

AutoFillManager::~AutoFillManager() {
  if (personal_data_)
    personal_data_->RemoveObserver(this);
}

// static
void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) {
  prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement);
}

// static
void AutoFillManager::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kAutoFillInfoBarShown, false);
  prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, false);
}

void AutoFillManager::FormFieldValuesSubmitted(
    const webkit_glue::FormFieldValues& form) {
  if (!personal_data_)
    return;

  // Grab a copy of the form data.
  upload_form_structure_.reset(new FormStructure(form));

  if (!upload_form_structure_->IsAutoFillable())
    return;

  // Determine the possible field types.
  DeterminePossibleFieldTypes(upload_form_structure_.get());

  PrefService* prefs = tab_contents_->profile()->GetPrefs();
  bool infobar_shown = prefs->GetBoolean(prefs::kAutoFillInfoBarShown);
  if (!infobar_shown) {
    // Ask the user for permission to save form information.
    infobar_.reset(new AutoFillInfoBarDelegate(tab_contents_, this));
  } else if (IsAutoFillEnabled()) {
    HandleSubmit();
  }
}

void AutoFillManager::FormsSeen(
    const std::vector<webkit_glue::FormFieldValues>& forms) {
  if (!IsAutoFillEnabled())
    return;

  form_structures_.reset();
  for (std::vector<webkit_glue::FormFieldValues>::const_iterator iter =
           forms.begin();
       iter != forms.end(); ++iter) {
    FormStructure* form_structure = new FormStructure(*iter);
    DeterminePossibleFieldTypes(form_structure);
    form_structures_.push_back(form_structure);
  }
}

bool AutoFillManager::GetAutoFillSuggestions(
    int query_id, const webkit_glue::FormField& field) {
  if (!IsAutoFillEnabled())
    return false;

  RenderViewHost* host = tab_contents_->render_view_host();
  if (!host)
    return false;

  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
  if (profiles.empty())
    return false;

  AutoFillFieldType type = UNKNOWN_TYPE;
  for (std::vector<FormStructure*>::iterator form = form_structures_.begin();
       form != form_structures_.end(); ++form) {
    for (std::vector<AutoFillField*>::const_iterator iter = (*form)->begin();
         iter != (*form)->end(); ++iter) {
      // The field list is terminated with a NULL AutoFillField, so don't try to
      // dereference it.
      if (!*iter)
        break;

      AutoFillField* form_field = *iter;
      if (*form_field != field)
        continue;

      if (form_field->possible_types().find(NAME_FIRST) !=
          form_field->possible_types().end() ||
          form_field->heuristic_type() == NAME_FIRST) {
        type = NAME_FIRST;
        break;
      }

      if (form_field->possible_types().find(NAME_FULL) !=
          form_field->possible_types().end() ||
          form_field->heuristic_type() == NAME_FULL) {
        type = NAME_FULL;
        break;
      }
    }
  }

  if (type == UNKNOWN_TYPE)
    return false;

  std::vector<string16> names;
  std::vector<string16> labels;
  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
       iter != profiles.end(); ++iter) {
    string16 name = (*iter)->GetFieldText(AutoFillType(type));
    string16 label = (*iter)->Label();

    // TODO(jhawkins): What if name.length() == 0?
    if (StartsWith(name, field.value(), false)) {
      names.push_back(name);
      labels.push_back(label);
    }
  }

  // No suggestions.
  if (names.empty())
    return false;

  // TODO(jhawkins): If the default profile is in this list, set it as the
  // default suggestion index.
  host->AutoFillSuggestionsReturned(query_id, names, labels, -1);
  return true;
}

bool AutoFillManager::FillAutoFillFormData(int query_id,
                                           const FormData& form,
                                           const string16& name,
                                           const string16& label) {
  if (!IsAutoFillEnabled())
    return false;

  RenderViewHost* host = tab_contents_->render_view_host();
  if (!host)
    return false;

  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
  if (profiles.empty())
    return false;

  const AutoFillProfile* profile = NULL;
  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
       iter != profiles.end(); ++iter) {
    if ((*iter)->Label() != label)
      continue;

    if ((*iter)->GetFieldText(AutoFillType(NAME_FIRST)) != name &&
        (*iter)->GetFieldText(AutoFillType(NAME_FULL)) != name)
      continue;

    profile = *iter;
    break;
  }

  if (!profile)
    return false;

  FormData result = form;
  for (std::vector<FormStructure*>::const_iterator iter =
           form_structures_.begin();
       iter != form_structures_.end(); ++iter) {
    const FormStructure* form_structure = *iter;
    if (*form_structure != form)
      continue;

    for (size_t i = 0; i < form_structure->field_count(); ++i) {
      const AutoFillField* field = form_structure->field(i);

      for (size_t j = 0; j < result.values.size(); ++j) {
        if (field->name() == result.elements[j]) {
          result.values[j] =
              profile->GetFieldText(AutoFillType(field->heuristic_type()));
          break;
        }
      }
    }
  }

  host->AutoFillFormDataFilled(query_id, result);
  return true;
}

void AutoFillManager::OnAutoFillDialogApply(
    std::vector<AutoFillProfile>* profiles,
    std::vector<CreditCard>* credit_cards) {
  DCHECK(personal_data_);

  // Save the personal data.
  personal_data_->SetProfiles(profiles);
  personal_data_->SetCreditCards(credit_cards);

  HandleSubmit();
}

void AutoFillManager::OnPersonalDataLoaded() {
  DCHECK(personal_data_);

  // We might have been alerted that the PersonalDataManager has loaded, so
  // remove ourselves as observer.
  personal_data_->RemoveObserver(this);

  ShowAutoFillDialog(
      this, personal_data_->profiles(), personal_data_->credit_cards());
}

void AutoFillManager::OnInfoBarAccepted() {
  DCHECK(personal_data_);

  PrefService* prefs = tab_contents_->profile()->GetPrefs();
  prefs->SetBoolean(prefs::kAutoFillEnabled, true);

  // If the personal data manager has not loaded the data yet, set ourselves as
  // its observer so that we can listen for the OnPersonalDataLoaded signal.
  if (!personal_data_->IsDataLoaded())
    personal_data_->SetObserver(this);
  else
    OnPersonalDataLoaded();
}

void AutoFillManager::Reset() {
  upload_form_structure_.reset();
}

void AutoFillManager::DeterminePossibleFieldTypes(
    FormStructure* form_structure) {
  DCHECK(personal_data_);

  // TODO(jhawkins): Update field text.

  form_structure->GetHeuristicAutoFillTypes();

  for (size_t i = 0; i < form_structure->field_count(); i++) {
    const AutoFillField* field = form_structure->field(i);
    FieldTypeSet field_types;
    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
    form_structure->set_possible_types(i, field_types);
  }
}

void AutoFillManager::HandleSubmit() {
  DCHECK(personal_data_);

  // If there wasn't enough data to import then we don't want to send an upload
  // to the server.
  if (!personal_data_->ImportFormData(form_structures_.get(), this))
    return;

  UploadFormData();
}

void AutoFillManager::UploadFormData() {
  std::string xml;
  bool ok = upload_form_structure_->EncodeUploadRequest(false, &xml);
  DCHECK(ok);

  // TODO(jhawkins): Initiate the upload request thread.
}

bool AutoFillManager::IsAutoFillEnabled() {
  // The PersonalDataManager is NULL in OTR.
  if (!personal_data_)
    return false;

  PrefService* prefs = tab_contents_->profile()->GetPrefs();

  // Migrate obsolete autofill pref.
  if (prefs->HasPrefPath(prefs::kFormAutofillEnabled)) {
    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
    prefs->ClearPref(prefs::kFormAutofillEnabled);
    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
    return enabled;
  }

  return prefs->GetBoolean(prefs::kAutoFillEnabled);
}
<commit_msg>Enable AutoFill++ by default for new profiles.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autofill/autofill_manager.h"

#include <string>

#include "base/command_line.h"
#include "chrome/browser/autofill/autofill_dialog.h"
#include "chrome/browser/autofill/autofill_infobar_delegate.h"
#include "chrome/browser/autofill/form_structure.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
#include "webkit/glue/form_field_values.h"

AutoFillManager::AutoFillManager(TabContents* tab_contents)
    : tab_contents_(tab_contents),
      personal_data_(NULL),
      infobar_(NULL) {
  DCHECK(tab_contents);
  personal_data_ = tab_contents_->profile()->GetPersonalDataManager();
}

AutoFillManager::~AutoFillManager() {
  if (personal_data_)
    personal_data_->RemoveObserver(this);
}

// static
void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) {
  prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement);
}

// static
void AutoFillManager::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterBooleanPref(prefs::kAutoFillInfoBarShown, false);
  prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true);
}

void AutoFillManager::FormFieldValuesSubmitted(
    const webkit_glue::FormFieldValues& form) {
  if (!personal_data_)
    return;

  // Grab a copy of the form data.
  upload_form_structure_.reset(new FormStructure(form));

  if (!upload_form_structure_->IsAutoFillable())
    return;

  // Determine the possible field types.
  DeterminePossibleFieldTypes(upload_form_structure_.get());

  PrefService* prefs = tab_contents_->profile()->GetPrefs();
  bool infobar_shown = prefs->GetBoolean(prefs::kAutoFillInfoBarShown);
  if (!infobar_shown) {
    // Ask the user for permission to save form information.
    infobar_.reset(new AutoFillInfoBarDelegate(tab_contents_, this));
  } else if (IsAutoFillEnabled()) {
    HandleSubmit();
  }
}

void AutoFillManager::FormsSeen(
    const std::vector<webkit_glue::FormFieldValues>& forms) {
  if (!IsAutoFillEnabled())
    return;

  form_structures_.reset();
  for (std::vector<webkit_glue::FormFieldValues>::const_iterator iter =
           forms.begin();
       iter != forms.end(); ++iter) {
    FormStructure* form_structure = new FormStructure(*iter);
    DeterminePossibleFieldTypes(form_structure);
    form_structures_.push_back(form_structure);
  }
}

bool AutoFillManager::GetAutoFillSuggestions(
    int query_id, const webkit_glue::FormField& field) {
  if (!IsAutoFillEnabled())
    return false;

  RenderViewHost* host = tab_contents_->render_view_host();
  if (!host)
    return false;

  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
  if (profiles.empty())
    return false;

  AutoFillFieldType type = UNKNOWN_TYPE;
  for (std::vector<FormStructure*>::iterator form = form_structures_.begin();
       form != form_structures_.end(); ++form) {
    for (std::vector<AutoFillField*>::const_iterator iter = (*form)->begin();
         iter != (*form)->end(); ++iter) {
      // The field list is terminated with a NULL AutoFillField, so don't try to
      // dereference it.
      if (!*iter)
        break;

      AutoFillField* form_field = *iter;
      if (*form_field != field)
        continue;

      if (form_field->possible_types().find(NAME_FIRST) !=
          form_field->possible_types().end() ||
          form_field->heuristic_type() == NAME_FIRST) {
        type = NAME_FIRST;
        break;
      }

      if (form_field->possible_types().find(NAME_FULL) !=
          form_field->possible_types().end() ||
          form_field->heuristic_type() == NAME_FULL) {
        type = NAME_FULL;
        break;
      }
    }
  }

  if (type == UNKNOWN_TYPE)
    return false;

  std::vector<string16> names;
  std::vector<string16> labels;
  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
       iter != profiles.end(); ++iter) {
    string16 name = (*iter)->GetFieldText(AutoFillType(type));
    string16 label = (*iter)->Label();

    // TODO(jhawkins): What if name.length() == 0?
    if (StartsWith(name, field.value(), false)) {
      names.push_back(name);
      labels.push_back(label);
    }
  }

  // No suggestions.
  if (names.empty())
    return false;

  // TODO(jhawkins): If the default profile is in this list, set it as the
  // default suggestion index.
  host->AutoFillSuggestionsReturned(query_id, names, labels, -1);
  return true;
}

bool AutoFillManager::FillAutoFillFormData(int query_id,
                                           const FormData& form,
                                           const string16& name,
                                           const string16& label) {
  if (!IsAutoFillEnabled())
    return false;

  RenderViewHost* host = tab_contents_->render_view_host();
  if (!host)
    return false;

  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
  if (profiles.empty())
    return false;

  const AutoFillProfile* profile = NULL;
  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
       iter != profiles.end(); ++iter) {
    if ((*iter)->Label() != label)
      continue;

    if ((*iter)->GetFieldText(AutoFillType(NAME_FIRST)) != name &&
        (*iter)->GetFieldText(AutoFillType(NAME_FULL)) != name)
      continue;

    profile = *iter;
    break;
  }

  if (!profile)
    return false;

  FormData result = form;
  for (std::vector<FormStructure*>::const_iterator iter =
           form_structures_.begin();
       iter != form_structures_.end(); ++iter) {
    const FormStructure* form_structure = *iter;
    if (*form_structure != form)
      continue;

    for (size_t i = 0; i < form_structure->field_count(); ++i) {
      const AutoFillField* field = form_structure->field(i);

      for (size_t j = 0; j < result.values.size(); ++j) {
        if (field->name() == result.elements[j]) {
          result.values[j] =
              profile->GetFieldText(AutoFillType(field->heuristic_type()));
          break;
        }
      }
    }
  }

  host->AutoFillFormDataFilled(query_id, result);
  return true;
}

void AutoFillManager::OnAutoFillDialogApply(
    std::vector<AutoFillProfile>* profiles,
    std::vector<CreditCard>* credit_cards) {
  DCHECK(personal_data_);

  // Save the personal data.
  personal_data_->SetProfiles(profiles);
  personal_data_->SetCreditCards(credit_cards);

  HandleSubmit();
}

void AutoFillManager::OnPersonalDataLoaded() {
  DCHECK(personal_data_);

  // We might have been alerted that the PersonalDataManager has loaded, so
  // remove ourselves as observer.
  personal_data_->RemoveObserver(this);

  ShowAutoFillDialog(
      this, personal_data_->profiles(), personal_data_->credit_cards());
}

void AutoFillManager::OnInfoBarAccepted() {
  DCHECK(personal_data_);

  PrefService* prefs = tab_contents_->profile()->GetPrefs();
  prefs->SetBoolean(prefs::kAutoFillEnabled, true);

  // If the personal data manager has not loaded the data yet, set ourselves as
  // its observer so that we can listen for the OnPersonalDataLoaded signal.
  if (!personal_data_->IsDataLoaded())
    personal_data_->SetObserver(this);
  else
    OnPersonalDataLoaded();
}

void AutoFillManager::Reset() {
  upload_form_structure_.reset();
}

void AutoFillManager::DeterminePossibleFieldTypes(
    FormStructure* form_structure) {
  DCHECK(personal_data_);

  // TODO(jhawkins): Update field text.

  form_structure->GetHeuristicAutoFillTypes();

  for (size_t i = 0; i < form_structure->field_count(); i++) {
    const AutoFillField* field = form_structure->field(i);
    FieldTypeSet field_types;
    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
    form_structure->set_possible_types(i, field_types);
  }
}

void AutoFillManager::HandleSubmit() {
  DCHECK(personal_data_);

  // If there wasn't enough data to import then we don't want to send an upload
  // to the server.
  if (!personal_data_->ImportFormData(form_structures_.get(), this))
    return;

  UploadFormData();
}

void AutoFillManager::UploadFormData() {
  std::string xml;
  bool ok = upload_form_structure_->EncodeUploadRequest(false, &xml);
  DCHECK(ok);

  // TODO(jhawkins): Initiate the upload request thread.
}

bool AutoFillManager::IsAutoFillEnabled() {
  // The PersonalDataManager is NULL in OTR.
  if (!personal_data_)
    return false;

  PrefService* prefs = tab_contents_->profile()->GetPrefs();

  // Migrate obsolete autofill pref.
  if (prefs->HasPrefPath(prefs::kFormAutofillEnabled)) {
    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
    prefs->ClearPref(prefs::kFormAutofillEnabled);
    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
    return enabled;
  }

  return prefs->GetBoolean(prefs::kAutoFillEnabled);
}
<|endoftext|>


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

#include "chrome/browser/extensions/startup_helper.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/webstore_standalone_installer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/i18n/default_locale_handler.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message.h"

namespace {

void PrintPackExtensionMessage(const std::string& message) {
  printf("%s\n", message.c_str());
}

}  // namespace

namespace extensions {

StartupHelper::StartupHelper() : pack_job_succeeded_(false) {
  (new DefaultLocaleHandler)->Register();
}

void StartupHelper::OnPackSuccess(
    const base::FilePath& crx_path,
    const base::FilePath& output_private_key_path) {
  pack_job_succeeded_ = true;
  PrintPackExtensionMessage(
      UTF16ToUTF8(
          PackExtensionJob::StandardSuccessMessage(crx_path,
                                                   output_private_key_path)));
}

void StartupHelper::OnPackFailure(const std::string& error_message,
                                  ExtensionCreator::ErrorType type) {
  PrintPackExtensionMessage(error_message);
}

bool StartupHelper::PackExtension(const CommandLine& cmd_line) {
  if (!cmd_line.HasSwitch(switches::kPackExtension))
    return false;

  // Input Paths.
  base::FilePath src_dir =
      cmd_line.GetSwitchValuePath(switches::kPackExtension);
  base::FilePath private_key_path;
  if (cmd_line.HasSwitch(switches::kPackExtensionKey)) {
    private_key_path = cmd_line.GetSwitchValuePath(switches::kPackExtensionKey);
  }

  // Launch a job to perform the packing on the file thread.  Ignore warnings
  // from the packing process. (e.g. Overwrite any existing crx file.)
  pack_job_ = new PackExtensionJob(this, src_dir, private_key_path,
                                   ExtensionCreator::kOverwriteCRX);
  pack_job_->set_asynchronous(false);
  pack_job_->Start();

  return pack_job_succeeded_;
}

bool StartupHelper::UninstallExtension(const CommandLine& cmd_line,
                                       Profile* profile) {
  DCHECK(profile);

  if (!cmd_line.HasSwitch(switches::kUninstallExtension))
    return false;

  ExtensionService* extension_service = profile->GetExtensionService();
  if (!extension_service)
    return false;

  std::string extension_id = cmd_line.GetSwitchValueASCII(
      switches::kUninstallExtension);
  return ExtensionService::UninstallExtensionHelper(extension_service,
                                                    extension_id);
}

namespace {

class AppInstallHelper {
 public:
  // A callback for when the install process is done.
  typedef base::Callback<void()> DoneCallback;

  AppInstallHelper();
  virtual ~AppInstallHelper();
  bool success() { return success_; }
  const std::string& error() { return error_; }
  void BeginInstall(Profile* profile,
                    const std::string& id,
                    WebstoreStandaloneInstaller::PromptType prompt_type,
                    DoneCallback callback);

 private:
  WebstoreStandaloneInstaller::Callback Callback();
  void OnAppInstallComplete(bool success, const std::string& error);

  DoneCallback done_callback_;

  // These hold on to the result of the app install when it is complete.
  bool success_;
  std::string error_;

  scoped_ptr<content::WebContents> web_contents_;
  scoped_refptr<WebstoreStandaloneInstaller> installer_;
};

AppInstallHelper::AppInstallHelper() : success_(false) {}

AppInstallHelper::~AppInstallHelper() {}

WebstoreStandaloneInstaller::Callback AppInstallHelper::Callback() {
  return base::Bind(&AppInstallHelper::OnAppInstallComplete,
                    base::Unretained(this));
}

void AppInstallHelper::BeginInstall(
    Profile* profile,
    const std::string& id,
    WebstoreStandaloneInstaller::PromptType prompt_type,
    DoneCallback done_callback) {
  done_callback_ = done_callback;

  WebstoreStandaloneInstaller::Callback callback =
      base::Bind(&AppInstallHelper::OnAppInstallComplete,
                 base::Unretained(this));
  installer_ = new WebstoreStandaloneInstaller(
      id,
      WebstoreStandaloneInstaller::DO_NOT_REQUIRE_VERIFIED_SITE,
      prompt_type,
      GURL(),
      profile,
      NULL,
      callback);
  installer_->BeginInstall();
}

void AppInstallHelper::OnAppInstallComplete(bool success,
                                            const std::string& error) {
  success_ = success;
  error_= error;
  done_callback_.Run();
}

void DeleteHelperAndRunCallback(AppInstallHelper* helper,
                                base::Callback<void()> callback) {
  delete helper;
  callback.Run();
}

}  // namespace

bool StartupHelper::InstallFromWebstore(const CommandLine& cmd_line,
                                        Profile* profile) {
  std::string id = cmd_line.GetSwitchValueASCII(switches::kInstallFromWebstore);
  if (!Extension::IdIsValid(id)) {
    LOG(ERROR) << "Invalid id for " << switches::kInstallFromWebstore
               << " : '" << id << "'";
    return false;
  }

  AppInstallHelper helper;
  helper.BeginInstall(profile, id,
      WebstoreStandaloneInstaller::STANDARD_PROMPT,
      MessageLoop::QuitWhenIdleClosure());

  MessageLoop::current()->Run();
  if (!helper.success())
    LOG(ERROR) << "InstallFromWebstore failed with error: " << helper.error();
  return helper.success();
}

void StartupHelper::LimitedInstallFromWebstore(
    const CommandLine& cmd_line,
    Profile* profile,
    base::Callback<void()> done_callback) {
  std::string id = WebStoreIdFromLimitedInstallCmdLine(cmd_line);
  if (!Extension::IdIsValid(id)) {
    LOG(ERROR) << "Invalid index for " << switches::kLimitedInstallFromWebstore;
    done_callback.Run();
    return;
  }

  AppInstallHelper* helper = new AppInstallHelper();
  helper->BeginInstall(profile, id,
      WebstoreStandaloneInstaller::STANDARD_PROMPT,
      base::Bind(&DeleteHelperAndRunCallback, helper, done_callback));
}

std::string StartupHelper::WebStoreIdFromLimitedInstallCmdLine(
    const CommandLine& cmd_line) {
  std::string index = cmd_line.GetSwitchValueASCII(
      switches::kLimitedInstallFromWebstore);
  std::string id;
  if (index == "1") {
    id = "nckgahadagoaajjgafhacjanaoiihapd";
  } else if (index == "2") {
    id = "ecglahbcnmdpdciemllbhojghbkagdje";
  }
  return id;
}

StartupHelper::~StartupHelper() {
  if (pack_job_.get())
    pack_job_->ClearClient();
}

}  // namespace extensions
<commit_msg>Fix --pack-extension for platform apps<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/startup_helper.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/webstore_standalone_installer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/i18n/default_locale_handler.h"
#include "chrome/common/extensions/background_info.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message.h"

namespace {

void PrintPackExtensionMessage(const std::string& message) {
  printf("%s\n", message.c_str());
}

}  // namespace

namespace extensions {

StartupHelper::StartupHelper() : pack_job_succeeded_(false) {
  (new DefaultLocaleHandler)->Register();
  (new BackgroundManifestHandler)->Register();
}

void StartupHelper::OnPackSuccess(
    const base::FilePath& crx_path,
    const base::FilePath& output_private_key_path) {
  pack_job_succeeded_ = true;
  PrintPackExtensionMessage(
      UTF16ToUTF8(
          PackExtensionJob::StandardSuccessMessage(crx_path,
                                                   output_private_key_path)));
}

void StartupHelper::OnPackFailure(const std::string& error_message,
                                  ExtensionCreator::ErrorType type) {
  PrintPackExtensionMessage(error_message);
}

bool StartupHelper::PackExtension(const CommandLine& cmd_line) {
  if (!cmd_line.HasSwitch(switches::kPackExtension))
    return false;

  // Input Paths.
  base::FilePath src_dir =
      cmd_line.GetSwitchValuePath(switches::kPackExtension);
  base::FilePath private_key_path;
  if (cmd_line.HasSwitch(switches::kPackExtensionKey)) {
    private_key_path = cmd_line.GetSwitchValuePath(switches::kPackExtensionKey);
  }

  // Launch a job to perform the packing on the file thread.  Ignore warnings
  // from the packing process. (e.g. Overwrite any existing crx file.)
  pack_job_ = new PackExtensionJob(this, src_dir, private_key_path,
                                   ExtensionCreator::kOverwriteCRX);
  pack_job_->set_asynchronous(false);
  pack_job_->Start();

  return pack_job_succeeded_;
}

bool StartupHelper::UninstallExtension(const CommandLine& cmd_line,
                                       Profile* profile) {
  DCHECK(profile);

  if (!cmd_line.HasSwitch(switches::kUninstallExtension))
    return false;

  ExtensionService* extension_service = profile->GetExtensionService();
  if (!extension_service)
    return false;

  std::string extension_id = cmd_line.GetSwitchValueASCII(
      switches::kUninstallExtension);
  return ExtensionService::UninstallExtensionHelper(extension_service,
                                                    extension_id);
}

namespace {

class AppInstallHelper {
 public:
  // A callback for when the install process is done.
  typedef base::Callback<void()> DoneCallback;

  AppInstallHelper();
  virtual ~AppInstallHelper();
  bool success() { return success_; }
  const std::string& error() { return error_; }
  void BeginInstall(Profile* profile,
                    const std::string& id,
                    WebstoreStandaloneInstaller::PromptType prompt_type,
                    DoneCallback callback);

 private:
  WebstoreStandaloneInstaller::Callback Callback();
  void OnAppInstallComplete(bool success, const std::string& error);

  DoneCallback done_callback_;

  // These hold on to the result of the app install when it is complete.
  bool success_;
  std::string error_;

  scoped_ptr<content::WebContents> web_contents_;
  scoped_refptr<WebstoreStandaloneInstaller> installer_;
};

AppInstallHelper::AppInstallHelper() : success_(false) {}

AppInstallHelper::~AppInstallHelper() {}

WebstoreStandaloneInstaller::Callback AppInstallHelper::Callback() {
  return base::Bind(&AppInstallHelper::OnAppInstallComplete,
                    base::Unretained(this));
}

void AppInstallHelper::BeginInstall(
    Profile* profile,
    const std::string& id,
    WebstoreStandaloneInstaller::PromptType prompt_type,
    DoneCallback done_callback) {
  done_callback_ = done_callback;

  WebstoreStandaloneInstaller::Callback callback =
      base::Bind(&AppInstallHelper::OnAppInstallComplete,
                 base::Unretained(this));
  installer_ = new WebstoreStandaloneInstaller(
      id,
      WebstoreStandaloneInstaller::DO_NOT_REQUIRE_VERIFIED_SITE,
      prompt_type,
      GURL(),
      profile,
      NULL,
      callback);
  installer_->BeginInstall();
}

void AppInstallHelper::OnAppInstallComplete(bool success,
                                            const std::string& error) {
  success_ = success;
  error_= error;
  done_callback_.Run();
}

void DeleteHelperAndRunCallback(AppInstallHelper* helper,
                                base::Callback<void()> callback) {
  delete helper;
  callback.Run();
}

}  // namespace

bool StartupHelper::InstallFromWebstore(const CommandLine& cmd_line,
                                        Profile* profile) {
  std::string id = cmd_line.GetSwitchValueASCII(switches::kInstallFromWebstore);
  if (!Extension::IdIsValid(id)) {
    LOG(ERROR) << "Invalid id for " << switches::kInstallFromWebstore
               << " : '" << id << "'";
    return false;
  }

  AppInstallHelper helper;
  helper.BeginInstall(profile, id,
      WebstoreStandaloneInstaller::STANDARD_PROMPT,
      MessageLoop::QuitWhenIdleClosure());

  MessageLoop::current()->Run();
  if (!helper.success())
    LOG(ERROR) << "InstallFromWebstore failed with error: " << helper.error();
  return helper.success();
}

void StartupHelper::LimitedInstallFromWebstore(
    const CommandLine& cmd_line,
    Profile* profile,
    base::Callback<void()> done_callback) {
  std::string id = WebStoreIdFromLimitedInstallCmdLine(cmd_line);
  if (!Extension::IdIsValid(id)) {
    LOG(ERROR) << "Invalid index for " << switches::kLimitedInstallFromWebstore;
    done_callback.Run();
    return;
  }

  AppInstallHelper* helper = new AppInstallHelper();
  helper->BeginInstall(profile, id,
      WebstoreStandaloneInstaller::STANDARD_PROMPT,
      base::Bind(&DeleteHelperAndRunCallback, helper, done_callback));
}

std::string StartupHelper::WebStoreIdFromLimitedInstallCmdLine(
    const CommandLine& cmd_line) {
  std::string index = cmd_line.GetSwitchValueASCII(
      switches::kLimitedInstallFromWebstore);
  std::string id;
  if (index == "1") {
    id = "nckgahadagoaajjgafhacjanaoiihapd";
  } else if (index == "2") {
    id = "ecglahbcnmdpdciemllbhojghbkagdje";
  }
  return id;
}

StartupHelper::~StartupHelper() {
  if (pack_job_.get())
    pack_job_->ClearClient();
}

}  // namespace extensions
<|endoftext|>


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

#include "iceoryx_dds/dds/dds_types.hpp"
#include "iceoryx_dds/gateway/channel.hpp"
#include "iceoryx_posh/capro/service_description.hpp"

#include "test.hpp"

using namespace ::testing;
using ::testing::_;

// ======================================== Helpers ======================================== //
// We do not need real channel terminals to test the base class.
struct StubbedIceoryxTerminal
{
    StubbedIceoryxTerminal(iox::capro::ServiceDescription sd){};
};

struct StubbedDDSTerminal
{
    StubbedDDSTerminal(iox::dds::IdString sid, iox::dds::IdString iid, iox::dds::IdString eid){};
};

using TestChannel = iox::dds::Channel<StubbedIceoryxTerminal, StubbedDDSTerminal>;

// ======================================== Fixture ======================================== //
class ChannelTest : public Test
{
  public:
    void SetUp(){};
    void TearDown(){};
};

// ======================================== Tests ======================================== //
TEST_F(ChannelTest, ReturnsEmptyOptionalIfObjectPoolExhausted)
{
    auto channel = iox::dds::Channel<StubbedIceoryxTerminal, StubbedDDSTerminal>::create({"", "", ""});
}
<commit_msg>iox-#273 fix warning in dds test<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iceoryx_dds/dds/dds_types.hpp"
#include "iceoryx_dds/gateway/channel.hpp"
#include "iceoryx_posh/capro/service_description.hpp"

#include "test.hpp"

using namespace ::testing;
using ::testing::_;

// ======================================== Helpers ======================================== //
// We do not need real channel terminals to test the base class.
struct StubbedIceoryxTerminal
{
    StubbedIceoryxTerminal(iox::capro::ServiceDescription){};
};

struct StubbedDDSTerminal
{
    StubbedDDSTerminal(iox::dds::IdString, iox::dds::IdString, iox::dds::IdString){};
};

using TestChannel = iox::dds::Channel<StubbedIceoryxTerminal, StubbedDDSTerminal>;

// ======================================== Fixture ======================================== //
class ChannelTest : public Test
{
  public:
    void SetUp(){};
    void TearDown(){};
};

// ======================================== Tests ======================================== //
TEST_F(ChannelTest, ReturnsEmptyOptionalIfObjectPoolExhausted)
{
    auto channel = iox::dds::Channel<StubbedIceoryxTerminal, StubbedDDSTerminal>::create({"", "", ""});
}
<|endoftext|>


<commit_before>#include "fof_brute.hpp"

#include <algorithm>
#include <vector>
#include <cmath>

namespace {

typedef std::pair<size_t, double*> Point;

double dist(double *p1, double *p2, size_t ndim) {
    double d2 = 0.;
    for(size_t i = 0 ; i < ndim ; ++i) {
        d2 += pow(p1[i] - p2[i], 2);
    }
    return sqrt(d2);
}

} // anonymous namespace

// A brute force friends of friends finder without the Rtree accelerator.
std::vector< std::vector<size_t> > friends_of_friends_brute(
	double *data,
	size_t npts,
	size_t ndim,
	double linking_length
) {
    //Create list of unused points with indices
    std::vector<Point> unused;
    std::vector< std::vector< size_t > > groups;
    for(size_t i=0 ; i<npts ; ++i) {
        unused.push_back(std::make_pair(i, data + i*ndim));
    }

    //If there are unused points try to create a new group
    while( !unused.empty() ) {
    	auto group = std::vector<size_t>();
    	auto toadd = std::vector<Point>();
        toadd.push_back(unused.back());
        unused.pop_back();

        while (!toadd.empty()) {
        	auto point = toadd.back();
        	toadd.pop_back();
        	group.push_back(point.first);

        	for (auto i = 0; i < unused.size(); ++i) {
        		if(dist(unused[i].second, point.second, ndim) < linking_length) {
                    toadd.push_back(unused[i]);
                    unused[i].second = nullptr;  // Mark the unused point to be deleted
                }
        	}

            // Remove any deleted points
        	unused.erase(
                std::remove_if(unused.begin(), unused.end(), [](Point p){return p.second == nullptr;}),
                unused.end()
            );
        }
        groups.push_back(group);
    }
    return groups;
}
<commit_msg>Range based for loop<commit_after>#include "fof_brute.hpp"

#include <algorithm>
#include <vector>
#include <cmath>

namespace {

typedef std::pair<size_t, double*> Point;

double dist(double *p1, double *p2, size_t ndim) {
    double d2 = 0.;
    for(size_t i = 0 ; i < ndim ; ++i) {
        d2 += pow(p1[i] - p2[i], 2);
    }
    return sqrt(d2);
}

} // anonymous namespace

// A brute force friends of friends finder without the Rtree accelerator.
std::vector< std::vector<size_t> > friends_of_friends_brute(
	double *data,
	size_t npts,
	size_t ndim,
	double linking_length
) {
    //Create list of unused points with indices
    std::vector<Point> unused;
    std::vector< std::vector< size_t > > groups;
    for(size_t i=0 ; i<npts ; ++i) {
        unused.push_back(std::make_pair(i, data + i*ndim));
    }

    //If there are unused points try to create a new group
    while( !unused.empty() ) {
    	auto group = std::vector<size_t>();
    	auto toadd = std::vector<Point>();
        toadd.push_back(unused.back());
        unused.pop_back();

        while (!toadd.empty()) {
        	auto point = toadd.back();
        	toadd.pop_back();
        	group.push_back(point.first);

            for (auto& unused_point: unused) {
                if(dist(unused_point.second, point.second, ndim) < linking_length) {
                    toadd.push_back(unused_point);
                    unused_point.second = nullptr;  // Mark the unused point to be deleted
                }
            }

            // Remove any deleted points
        	unused.erase(
                std::remove_if(unused.begin(), unused.end(), [](Point p){return p.second == nullptr;}),
                unused.end()
            );
        }
        groups.push_back(group);
    }
    return groups;
}
<|endoftext|>


<commit_before><commit_msg>Add test for derived usage of reflector_init<commit_after><|endoftext|>