<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include "session_context.h"

#include <algorithm>

#include "curl/curl.h"
#include "cvmfs_config.h"
#include "gateway_util.h"
#include "json_document.h"
#include "swissknife_lease_curl.h"
#include "util/string.h"

namespace upload {

size_t SendCB(void* ptr, size_t size, size_t nmemb, void* userp) {
  CurlSendPayload* payload = static_cast<CurlSendPayload*>(userp);

  size_t max_chunk_size = size * nmemb;
  if (max_chunk_size < 1) {
    return 0;
  }

  size_t current_chunk_size = 0;
  while (current_chunk_size < max_chunk_size) {
    if (payload->index < payload->json_message->size()) {
      // Can add a chunk from the JSON message
      const size_t read_size =
          std::min(max_chunk_size - current_chunk_size,
                   payload->json_message->size() - payload->index);
      current_chunk_size += read_size;
      std::memcpy(ptr, payload->json_message->data() + payload->index,
                  read_size);
      payload->index += read_size;
    } else {
      // Can add a chunk from the payload
      const size_t max_read_size = max_chunk_size - current_chunk_size;
      const unsigned nbytes = payload->pack_serializer->ProduceNext(
          max_read_size, static_cast<unsigned char*>(ptr) + current_chunk_size);
      current_chunk_size += nbytes;

      if (!nbytes) {
        break;
      }
    }
  }

  return current_chunk_size;
}

size_t RecvCB(void* buffer, size_t size, size_t nmemb, void* userp) {
  std::string* my_buffer = static_cast<std::string*>(userp);

  if (size * nmemb < 1) {
    return 0;
  }

  *my_buffer = static_cast<char*>(buffer);

  return my_buffer->size();
}

SessionContextBase::SessionContextBase()
    : upload_results_(1000, 1000),
      api_url_(),
      session_token_(),
      key_id_(),
      secret_(),
      queue_was_flushed_(1, 1),
      max_pack_size_(ObjectPack::kDefaultLimit),
      active_handles_(),
      current_pack_(NULL),
      current_pack_mtx_(),
      objects_dispatched_(0),
      bytes_committed_(0),
      bytes_dispatched_(0) {}

SessionContextBase::~SessionContextBase() {}

bool SessionContextBase::Initialize(const std::string& api_url,
                                    const std::string& session_token,
                                    const std::string& key_id,
                                    const std::string& secret,
                                    uint64_t max_pack_size) {
  bool ret = true;

  // Initialize session context lock
  pthread_mutexattr_t attr;
  if (pthread_mutexattr_init(&attr) ||
      pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) ||
      pthread_mutex_init(&current_pack_mtx_, &attr) ||
      pthread_mutexattr_destroy(&attr)) {
    LogCvmfs(kLogUploadGateway, kLogStderr,
             "Could not initialize SessionContext lock.");
    return false;
  }

  // Set upstream URL and session token
  api_url_ = api_url;
  session_token_ = session_token;
  key_id_ = key_id;
  secret_ = secret;
  max_pack_size_ = max_pack_size;

  atomic_init64(&objects_dispatched_);
  bytes_committed_ = 0u;
  bytes_dispatched_ = 0u;

  // Ensure that the upload job and result queues are empty
  upload_results_.Drop();

  queue_was_flushed_.Drop();
  queue_was_flushed_.Enqueue(true);

  // Ensure that there are not open object packs
  if (current_pack_) {
    LogCvmfs(
        kLogUploadGateway, kLogStderr,
        "Could not initialize SessionContext - Existing open object packs.");
    ret = false;
  }

  ret = InitializeDerived() && ret;

  return ret;
}

bool SessionContextBase::Finalize(bool commit, const std::string& old_root_hash,
                                  const std::string& new_root_hash) {
  assert(active_handles_.empty());
  {
    MutexLockGuard lock(current_pack_mtx_);

    if (current_pack_ && current_pack_->GetNoObjects() > 0) {
      Dispatch();
      current_pack_ = NULL;
    }
  }

  bool results = true;
  int64_t jobs_finished = 0;
  while (!upload_results_.IsEmpty() || (jobs_finished < NumJobsSubmitted())) {
    Future<bool>* future = upload_results_.Dequeue();
    results = future->Get() && results;
    delete future;
    jobs_finished++;
  }

  if (commit) {
    if (old_root_hash.empty() || new_root_hash.empty()) {
      return false;
    }
    results &= Commit(old_root_hash, new_root_hash);
  }

  results &= FinalizeDerived() && (bytes_committed_ == bytes_dispatched_);

  pthread_mutex_destroy(&current_pack_mtx_);
  return results;
}

void SessionContextBase::WaitForUpload() {
  if (!upload_results_.IsEmpty()) {
    queue_was_flushed_.Dequeue();
  }
}

ObjectPack::BucketHandle SessionContextBase::NewBucket() {
  MutexLockGuard lock(current_pack_mtx_);
  if (!current_pack_) {
    current_pack_ = new ObjectPack(max_pack_size_);
  }
  ObjectPack::BucketHandle hd = current_pack_->NewBucket();
  active_handles_.push_back(hd);
  return hd;
}

bool SessionContextBase::CommitBucket(const ObjectPack::BucketContentType type,
                                      const shash::Any& id,
                                      const ObjectPack::BucketHandle handle,
                                      const std::string& name,
                                      const bool force_dispatch) {
  MutexLockGuard lock(current_pack_mtx_);

  if (!current_pack_) {
    LogCvmfs(kLogUploadGateway, kLogStderr,
             "Error: Called SessionBaseContext::CommitBucket without an open "
             "ObjectPack.");
    return false;
  }

  uint64_t size0 = current_pack_->size();
  bool committed = current_pack_->CommitBucket(type, id, handle, name);

  if (committed) {  // Current pack is still not full
    active_handles_.erase(
        std::remove(active_handles_.begin(), active_handles_.end(), handle),
        active_handles_.end());
    uint64_t size1 = current_pack_->size();
    bytes_committed_ += size1 - size0;
    if (force_dispatch) {
      Dispatch();
      current_pack_ = NULL;
    }
  } else {  // Current pack is full and can be dispatched
    uint64_t new_size = 0;
    if (handle->capacity > max_pack_size_) {
      new_size = handle->capacity + 1;
    } else {
      new_size = max_pack_size_;
    }
    ObjectPack* new_pack = new ObjectPack(new_size);
    for (size_t i = 0u; i < active_handles_.size(); ++i) {
      current_pack_->TransferBucket(active_handles_[i], new_pack);
    }

    if (current_pack_->GetNoObjects() > 0) {
      Dispatch();
    }
    current_pack_ = new_pack;

    CommitBucket(type, id, handle, name, false);
  }

  return true;
}

int64_t SessionContextBase::NumJobsSubmitted() const {
  return atomic_read64(&objects_dispatched_);
}

void SessionContextBase::Dispatch() {
  MutexLockGuard lock(current_pack_mtx_);

  if (!current_pack_) {
    return;
  }

  atomic_inc64(&objects_dispatched_);
  bytes_dispatched_ += current_pack_->size();
  upload_results_.Enqueue(DispatchObjectPack(current_pack_));
}

SessionContext::SessionContext()
    : SessionContextBase(),
      upload_jobs_(1000, 900),
      worker_terminate_(),
      worker_() {}

bool SessionContext::InitializeDerived() {
  // Start worker thread
  atomic_init32(&worker_terminate_);
  atomic_write32(&worker_terminate_, 0);

  upload_jobs_.Drop();

  int retval =
      pthread_create(&worker_, NULL, UploadLoop, reinterpret_cast<void*>(this));

  return !retval;
}

bool SessionContext::FinalizeDerived() {
  atomic_write32(&worker_terminate_, 1);

  pthread_join(worker_, NULL);

  return true;
}

bool SessionContext::Commit(const std::string& old_root_hash,
                            const std::string& new_root_hash) {
  std::string request;
  JsonStringInput request_input;
  request_input.push_back(
      std::make_pair("old_root_hash", old_root_hash.c_str()));
  request_input.push_back(
      std::make_pair("new_root_hash", new_root_hash.c_str()));
  ToJsonString(request_input, &request);
  CurlBuffer buffer;
  return MakeEndRequest("POST", key_id_, secret_, session_token_, api_url_,
                        request, &buffer);
}

Future<bool>* SessionContext::DispatchObjectPack(ObjectPack* pack) {
  UploadJob* job = new UploadJob;
  job->pack = pack;
  job->result = new Future<bool>();
  upload_jobs_.Enqueue(job);
  return job->result;
}

bool SessionContext::DoUpload(const SessionContext::UploadJob* job) {
  // Set up the object pack serializer
  ObjectPackProducer serializer(job->pack);

  shash::Any payload_digest(shash::kSha1);
  serializer.GetDigest(&payload_digest);
  const std::string json_msg =
      "{\"session_token\" : \"" + session_token_ +
      "\", \"payload_digest\" : \"" + Base64(payload_digest.ToString(false)) +
      "\", \"header_size\" : \"" + StringifyInt(serializer.GetHeaderSize()) +
      "\", \"api_version\" : \"" + StringifyInt(gateway::APIVersion()) + "\"}";

  // Compute HMAC
  shash::Any hmac(shash::kSha1);
  shash::HmacString(secret_, json_msg, &hmac);

  CurlSendPayload payload;
  payload.json_message = &json_msg;
  payload.pack_serializer = &serializer;
  payload.index = 0;

  const size_t payload_size =
      json_msg.size() + serializer.GetHeaderSize() + job->pack->size();

  // Prepare the Curl POST request
  CURL* h_curl = curl_easy_init();

  if (!h_curl) {
    return false;
  }

  // Set HTTP headers (Authorization and Message-Size)
  std::string header_str = std::string("Authorization: ") + key_id_ + " " +
                           Base64(hmac.ToString(false));
  struct curl_slist* auth_header = NULL;
  auth_header = curl_slist_append(auth_header, header_str.c_str());
  header_str = std::string("Message-Size: ") + StringifyInt(json_msg.size());
  auth_header = curl_slist_append(auth_header, header_str.c_str());
  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);

  std::string reply;
  curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(h_curl, CURLOPT_USERAGENT, "cvmfs/" VERSION);
  curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(h_curl, CURLOPT_TCP_KEEPALIVE, 1L);
  curl_easy_setopt(h_curl, CURLOPT_URL, (api_url_ + "/payloads").c_str());
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
                   static_cast<curl_off_t>(payload_size));
  curl_easy_setopt(h_curl, CURLOPT_READDATA, &payload);
  curl_easy_setopt(h_curl, CURLOPT_READFUNCTION, SendCB);
  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, &reply);

  // Perform the Curl POST request
  CURLcode ret = curl_easy_perform(h_curl);

  const bool ok = (reply == "{\"status\":\"ok\"}");

  curl_easy_cleanup(h_curl);
  h_curl = NULL;

  return ok && !ret;
}

void* SessionContext::UploadLoop(void* data) {
  SessionContext* ctx = reinterpret_cast<SessionContext*>(data);

  int64_t jobs_processed = 0;
  while (!ctx->ShouldTerminate()) {
    while (jobs_processed < ctx->NumJobsSubmitted()) {
      UploadJob* job = ctx->upload_jobs_.Dequeue();
      ctx->DoUpload(job);
      job->result->Set(true);
      delete job->pack;
      delete job;
      jobs_processed++;
    }
    if (ctx->queue_was_flushed_.IsEmpty()) {
      ctx->queue_was_flushed_.Enqueue(true);
    }
  }

  return NULL;
}

bool SessionContext::ShouldTerminate() {
  return atomic_read32(&worker_terminate_);
}

}  // namespace upload
<commit_msg>Gateway uploader: abort transaction on payload submission error<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include "session_context.h"

#include <algorithm>

#include "curl/curl.h"
#include "cvmfs_config.h"
#include "gateway_util.h"
#include "json_document.h"
#include "swissknife_lease_curl.h"
#include "util/string.h"

namespace upload {

size_t SendCB(void* ptr, size_t size, size_t nmemb, void* userp) {
  CurlSendPayload* payload = static_cast<CurlSendPayload*>(userp);

  size_t max_chunk_size = size * nmemb;
  if (max_chunk_size < 1) {
    return 0;
  }

  size_t current_chunk_size = 0;
  while (current_chunk_size < max_chunk_size) {
    if (payload->index < payload->json_message->size()) {
      // Can add a chunk from the JSON message
      const size_t read_size =
          std::min(max_chunk_size - current_chunk_size,
                   payload->json_message->size() - payload->index);
      current_chunk_size += read_size;
      std::memcpy(ptr, payload->json_message->data() + payload->index,
                  read_size);
      payload->index += read_size;
    } else {
      // Can add a chunk from the payload
      const size_t max_read_size = max_chunk_size - current_chunk_size;
      const unsigned nbytes = payload->pack_serializer->ProduceNext(
          max_read_size, static_cast<unsigned char*>(ptr) + current_chunk_size);
      current_chunk_size += nbytes;

      if (!nbytes) {
        break;
      }
    }
  }

  return current_chunk_size;
}

size_t RecvCB(void* buffer, size_t size, size_t nmemb, void* userp) {
  std::string* my_buffer = static_cast<std::string*>(userp);

  if (size * nmemb < 1) {
    return 0;
  }

  *my_buffer = static_cast<char*>(buffer);

  return my_buffer->size();
}

SessionContextBase::SessionContextBase()
    : upload_results_(1000, 1000),
      api_url_(),
      session_token_(),
      key_id_(),
      secret_(),
      queue_was_flushed_(1, 1),
      max_pack_size_(ObjectPack::kDefaultLimit),
      active_handles_(),
      current_pack_(NULL),
      current_pack_mtx_(),
      objects_dispatched_(0),
      bytes_committed_(0),
      bytes_dispatched_(0) {}

SessionContextBase::~SessionContextBase() {}

bool SessionContextBase::Initialize(const std::string& api_url,
                                    const std::string& session_token,
                                    const std::string& key_id,
                                    const std::string& secret,
                                    uint64_t max_pack_size) {
  bool ret = true;

  // Initialize session context lock
  pthread_mutexattr_t attr;
  if (pthread_mutexattr_init(&attr) ||
      pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) ||
      pthread_mutex_init(&current_pack_mtx_, &attr) ||
      pthread_mutexattr_destroy(&attr)) {
    LogCvmfs(kLogUploadGateway, kLogStderr,
             "Could not initialize SessionContext lock.");
    return false;
  }

  // Set upstream URL and session token
  api_url_ = api_url;
  session_token_ = session_token;
  key_id_ = key_id;
  secret_ = secret;
  max_pack_size_ = max_pack_size;

  atomic_init64(&objects_dispatched_);
  bytes_committed_ = 0u;
  bytes_dispatched_ = 0u;

  // Ensure that the upload job and result queues are empty
  upload_results_.Drop();

  queue_was_flushed_.Drop();
  queue_was_flushed_.Enqueue(true);

  // Ensure that there are not open object packs
  if (current_pack_) {
    LogCvmfs(
        kLogUploadGateway, kLogStderr,
        "Could not initialize SessionContext - Existing open object packs.");
    ret = false;
  }

  ret = InitializeDerived() && ret;

  return ret;
}

bool SessionContextBase::Finalize(bool commit, const std::string& old_root_hash,
                                  const std::string& new_root_hash) {
  assert(active_handles_.empty());
  {
    MutexLockGuard lock(current_pack_mtx_);

    if (current_pack_ && current_pack_->GetNoObjects() > 0) {
      Dispatch();
      current_pack_ = NULL;
    }
  }

  bool results = true;
  int64_t jobs_finished = 0;
  while (!upload_results_.IsEmpty() || (jobs_finished < NumJobsSubmitted())) {
    Future<bool>* future = upload_results_.Dequeue();
    results = future->Get() && results;
    delete future;
    jobs_finished++;
  }

  if (commit) {
    if (old_root_hash.empty() || new_root_hash.empty()) {
      return false;
    }
    results &= Commit(old_root_hash, new_root_hash);
  }

  results &= FinalizeDerived() && (bytes_committed_ == bytes_dispatched_);

  pthread_mutex_destroy(&current_pack_mtx_);
  return results;
}

void SessionContextBase::WaitForUpload() {
  if (!upload_results_.IsEmpty()) {
    queue_was_flushed_.Dequeue();
  }
}

ObjectPack::BucketHandle SessionContextBase::NewBucket() {
  MutexLockGuard lock(current_pack_mtx_);
  if (!current_pack_) {
    current_pack_ = new ObjectPack(max_pack_size_);
  }
  ObjectPack::BucketHandle hd = current_pack_->NewBucket();
  active_handles_.push_back(hd);
  return hd;
}

bool SessionContextBase::CommitBucket(const ObjectPack::BucketContentType type,
                                      const shash::Any& id,
                                      const ObjectPack::BucketHandle handle,
                                      const std::string& name,
                                      const bool force_dispatch) {
  MutexLockGuard lock(current_pack_mtx_);

  if (!current_pack_) {
    LogCvmfs(kLogUploadGateway, kLogStderr,
             "Error: Called SessionBaseContext::CommitBucket without an open "
             "ObjectPack.");
    return false;
  }

  uint64_t size0 = current_pack_->size();
  bool committed = current_pack_->CommitBucket(type, id, handle, name);

  if (committed) {  // Current pack is still not full
    active_handles_.erase(
        std::remove(active_handles_.begin(), active_handles_.end(), handle),
        active_handles_.end());
    uint64_t size1 = current_pack_->size();
    bytes_committed_ += size1 - size0;
    if (force_dispatch) {
      Dispatch();
      current_pack_ = NULL;
    }
  } else {  // Current pack is full and can be dispatched
    uint64_t new_size = 0;
    if (handle->capacity > max_pack_size_) {
      new_size = handle->capacity + 1;
    } else {
      new_size = max_pack_size_;
    }
    ObjectPack* new_pack = new ObjectPack(new_size);
    for (size_t i = 0u; i < active_handles_.size(); ++i) {
      current_pack_->TransferBucket(active_handles_[i], new_pack);
    }

    if (current_pack_->GetNoObjects() > 0) {
      Dispatch();
    }
    current_pack_ = new_pack;

    CommitBucket(type, id, handle, name, false);
  }

  return true;
}

int64_t SessionContextBase::NumJobsSubmitted() const {
  return atomic_read64(&objects_dispatched_);
}

void SessionContextBase::Dispatch() {
  MutexLockGuard lock(current_pack_mtx_);

  if (!current_pack_) {
    return;
  }

  atomic_inc64(&objects_dispatched_);
  bytes_dispatched_ += current_pack_->size();
  upload_results_.Enqueue(DispatchObjectPack(current_pack_));
}

SessionContext::SessionContext()
    : SessionContextBase(),
      upload_jobs_(1000, 900),
      worker_terminate_(),
      worker_() {}

bool SessionContext::InitializeDerived() {
  // Start worker thread
  atomic_init32(&worker_terminate_);
  atomic_write32(&worker_terminate_, 0);

  upload_jobs_.Drop();

  int retval =
      pthread_create(&worker_, NULL, UploadLoop, reinterpret_cast<void*>(this));

  return !retval;
}

bool SessionContext::FinalizeDerived() {
  atomic_write32(&worker_terminate_, 1);

  pthread_join(worker_, NULL);

  return true;
}

bool SessionContext::Commit(const std::string& old_root_hash,
                            const std::string& new_root_hash) {
  std::string request;
  JsonStringInput request_input;
  request_input.push_back(
      std::make_pair("old_root_hash", old_root_hash.c_str()));
  request_input.push_back(
      std::make_pair("new_root_hash", new_root_hash.c_str()));
  ToJsonString(request_input, &request);
  CurlBuffer buffer;
  return MakeEndRequest("POST", key_id_, secret_, session_token_, api_url_,
                        request, &buffer);
}

Future<bool>* SessionContext::DispatchObjectPack(ObjectPack* pack) {
  UploadJob* job = new UploadJob;
  job->pack = pack;
  job->result = new Future<bool>();
  upload_jobs_.Enqueue(job);
  return job->result;
}

bool SessionContext::DoUpload(const SessionContext::UploadJob* job) {
  // Set up the object pack serializer
  ObjectPackProducer serializer(job->pack);

  shash::Any payload_digest(shash::kSha1);
  serializer.GetDigest(&payload_digest);
  const std::string json_msg =
      "{\"session_token\" : \"" + session_token_ +
      "\", \"payload_digest\" : \"" + Base64(payload_digest.ToString(false)) +
      "\", \"header_size\" : \"" + StringifyInt(serializer.GetHeaderSize()) +
      "\", \"api_version\" : \"" + StringifyInt(gateway::APIVersion()) + "\"}";

  // Compute HMAC
  shash::Any hmac(shash::kSha1);
  shash::HmacString(secret_, json_msg, &hmac);

  CurlSendPayload payload;
  payload.json_message = &json_msg;
  payload.pack_serializer = &serializer;
  payload.index = 0;

  const size_t payload_size =
      json_msg.size() + serializer.GetHeaderSize() + job->pack->size();

  // Prepare the Curl POST request
  CURL* h_curl = curl_easy_init();

  if (!h_curl) {
    return false;
  }

  // Set HTTP headers (Authorization and Message-Size)
  std::string header_str = std::string("Authorization: ") + key_id_ + " " +
                           Base64(hmac.ToString(false));
  struct curl_slist* auth_header = NULL;
  auth_header = curl_slist_append(auth_header, header_str.c_str());
  header_str = std::string("Message-Size: ") + StringifyInt(json_msg.size());
  auth_header = curl_slist_append(auth_header, header_str.c_str());
  curl_easy_setopt(h_curl, CURLOPT_HTTPHEADER, auth_header);

  std::string reply;
  curl_easy_setopt(h_curl, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(h_curl, CURLOPT_USERAGENT, "cvmfs/" VERSION);
  curl_easy_setopt(h_curl, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(h_curl, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(h_curl, CURLOPT_TCP_KEEPALIVE, 1L);
  curl_easy_setopt(h_curl, CURLOPT_URL, (api_url_ + "/payloads").c_str());
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDS, NULL);
  curl_easy_setopt(h_curl, CURLOPT_POSTFIELDSIZE_LARGE,
                   static_cast<curl_off_t>(payload_size));
  curl_easy_setopt(h_curl, CURLOPT_READDATA, &payload);
  curl_easy_setopt(h_curl, CURLOPT_READFUNCTION, SendCB);
  curl_easy_setopt(h_curl, CURLOPT_WRITEFUNCTION, RecvCB);
  curl_easy_setopt(h_curl, CURLOPT_WRITEDATA, &reply);

  // Perform the Curl POST request
  CURLcode ret = curl_easy_perform(h_curl);

  const bool ok = (reply == "{\"status\":\"ok\"}");

  curl_easy_cleanup(h_curl);
  h_curl = NULL;

  return ok && !ret;
}

void* SessionContext::UploadLoop(void* data) {
  SessionContext* ctx = reinterpret_cast<SessionContext*>(data);

  int64_t jobs_processed = 0;
  while (!ctx->ShouldTerminate()) {
    while (jobs_processed < ctx->NumJobsSubmitted()) {
      UploadJob* job = ctx->upload_jobs_.Dequeue();
      if (!ctx->DoUpload(job)) {
        LogCvmfs(kLogUploadGateway, kLogStderr,
                 "SessionContext: could not submit payload. Aborting.");
        abort();
      }
      job->result->Set(true);
      delete job->pack;
      delete job;
      jobs_processed++;
    }
    if (ctx->queue_was_flushed_.IsEmpty()) {
      ctx->queue_was_flushed_.Enqueue(true);
    }
  }

  return NULL;
}

bool SessionContext::ShouldTerminate() {
  return atomic_read32(&worker_terminate_);
}

}  // namespace upload
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include <string>

#include "cvmfs_config.h"

#include <cassert>

#include "logging.h"
#include "swissknife.h"

#include "swissknife_check.h"
#include "swissknife_diff.h"
#include "swissknife_gc.h"
#include "swissknife_graft.h"
#include "swissknife_hash.h"
#include "swissknife_history.h"
#include "swissknife_info.h"
#include "swissknife_ingest.h"
#include "swissknife_lease.h"
#include "swissknife_letter.h"
#include "swissknife_lsrepo.h"
#include "swissknife_migrate.h"
#include "swissknife_pull.h"
#include "swissknife_reflog.h"
#include "swissknife_scrub.h"
#include "swissknife_sign.h"
#include "swissknife_sync.h"
#include "swissknife_zpipe.h"
#include "util/string.h"

using namespace std;  // NOLINT

typedef vector<swissknife::Command *> Commands;
Commands command_list;

void Usage() {
  LogCvmfs(kLogCvmfs, kLogStdout,
    "CernVM-FS repository storage management commands\n"
    "Version %s\n"
    "Usage (normally called from cvmfs_server):\n"
    "  cvmfs_swissknife <command> [options]\n",
    VERSION);

  for (unsigned i = 0; i < command_list.size(); ++i) {
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"
             "Command %s\n"
             "--------", command_list[i]->GetName().c_str());
    for (unsigned j = 0; j < command_list[i]->GetName().length(); ++j) {
      LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "-");
    }
    LogCvmfs(kLogCvmfs, kLogStdout, "");
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
             command_list[i]->GetDescription().c_str());
    swissknife::ParameterList params = command_list[i]->GetParams();
    if (!params.empty()) {
      LogCvmfs(kLogCvmfs, kLogStdout, "Options:");
      for (unsigned j = 0; j < params.size(); ++j) {
        LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "  -%c    %s",
                 params[j].key(), params[j].description().c_str());
        if (params[j].optional())
          LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " (optional)");
        LogCvmfs(kLogCvmfs, kLogStdout, "");
      }
    }  // Parameter list
  }  // Command list

  LogCvmfs(kLogCvmfs, kLogStdout, "");
}

int main(int argc, char **argv) {
  // FILE *f = fopen("/home/ddosaru/cvmfs/build/log_dbg", "w");  // used for debugging
  // if (f == NULL) {
  //     printf("Error opening file!\n");
  //     return -1;
  // }

  command_list.push_back(new swissknife::CommandCreate());
  command_list.push_back(new swissknife::CommandUpload());
  command_list.push_back(new swissknife::CommandRemove());
  command_list.push_back(new swissknife::CommandPeek());
  command_list.push_back(new swissknife::CommandSync());
  command_list.push_back(new swissknife::CommandApplyDirtab());
  command_list.push_back(new swissknife::CommandEditTag());
  command_list.push_back(new swissknife::CommandListTags());
  command_list.push_back(new swissknife::CommandInfoTag());
  command_list.push_back(new swissknife::CommandRollbackTag());
  command_list.push_back(new swissknife::CommandEmptyRecycleBin());
  command_list.push_back(new swissknife::CommandSign());
  command_list.push_back(new swissknife::CommandLetter());
  command_list.push_back(new swissknife::CommandCheck());
  command_list.push_back(new swissknife::CommandListCatalogs());
  command_list.push_back(new swissknife::CommandDiff());
  command_list.push_back(new swissknife::CommandPull());
  command_list.push_back(new swissknife::CommandZpipe());
  command_list.push_back(new swissknife::CommandGraft());
  command_list.push_back(new swissknife::CommandHash());
  command_list.push_back(new swissknife::CommandInfo());
  command_list.push_back(new swissknife::CommandVersion());
  command_list.push_back(new swissknife::CommandMigrate());
  command_list.push_back(new swissknife::CommandScrub());
  command_list.push_back(new swissknife::CommandGc());
  command_list.push_back(new swissknife::CommandReconstructReflog());
  command_list.push_back(new swissknife::CommandLease());
  command_list.push_back(new swissknife::Ingest());

  if (argc < 2) {
    Usage();
    return 1;
  }
  if ((string(argv[1]) == "--help")) {
    Usage();
    return 0;
  }
  if ((string(argv[1]) == "--version")) {
    swissknife::CommandVersion().Main(swissknife::ArgumentList());
    return 0;
  }

  // find the command to be run
  swissknife::Command *command = NULL;
  for (unsigned i = 0; i < command_list.size(); ++i) {
    if (command_list[i]->GetName() == string(argv[1])) {
      command = command_list[i];
      break;
    }
  }

  if (NULL == command) {
    Usage();
    return 1;
  }

  bool display_statistics = false;

  // parse the command line arguments for the Command
  swissknife::ArgumentList args;
  optind = 1;
  string option_string = "";
  swissknife::ParameterList params = command->GetParams();
  for (unsigned j = 0; j < params.size(); ++j) {
    option_string.push_back(params[j].key());
    if (!params[j].switch_only())
      option_string.push_back(':');
  }
  // Now adding the generic -+ extra option command
  option_string.push_back(swissknife::Command::kGenericParam);
  option_string.push_back(':');
  int c;
  while ((c = getopt(argc, argv, option_string.c_str())) != -1) {
    //fprintf(f, "getopt --> %c\n", c);
    bool valid_option = false;
    for (unsigned j = 0; j < params.size(); ++j) {
      if (c == params[j].key()) {
        assert(c != swissknife::Command::kGenericParam);
        valid_option = true;
        string *argument = NULL;
        if (!params[j].switch_only()) {
          argument = new string(optarg);
        }
        args[c] = argument;
        break;
      }
    }
    if (c == swissknife::Command::kGenericParam) {
      valid_option = true;
      vector<string> flags = SplitString(optarg,
                                         swissknife::
                                         Command::kGenericParamSeparator);
      for (unsigned i = 0; i < flags.size(); ++i) {
        if (flags[i] == "stats") {
          display_statistics = true;
        }
      }
    }
    if (!valid_option) {
      Usage();
      return 1;
    }
  }
  for (unsigned j = 0; j < params.size(); ++j) {
    if (!params[j].optional()) {
      if (args.find(params[j].key()) == args.end()) {
        LogCvmfs(kLogCvmfs, kLogStderr, "parameter -%c missing",
                 params[j].key());
        return 1;
      }
    }
  }

  // run the command
  const int retval = command->Main(args);
  if (display_statistics) {
    LogCvmfs(kLogCvmfs, kLogStdout, "Command statistics");
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
             command->statistics()
             ->PrintList(perf::Statistics::kPrintHeader).c_str());
  }

  // delete the command list
        Commands::const_iterator i    = command_list.begin();
  const Commands::const_iterator iend = command_list.end();
  for (; i != iend; ++i) {
    delete *i;
  }
  command_list.clear();
  //fclose(f);
  return retval;
}
<commit_msg>Solved cpplint errors.<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include <string>

#include "cvmfs_config.h"

#include <cassert>

#include "logging.h"
#include "swissknife.h"

#include "swissknife_check.h"
#include "swissknife_diff.h"
#include "swissknife_gc.h"
#include "swissknife_graft.h"
#include "swissknife_hash.h"
#include "swissknife_history.h"
#include "swissknife_info.h"
#include "swissknife_ingest.h"
#include "swissknife_lease.h"
#include "swissknife_letter.h"
#include "swissknife_lsrepo.h"
#include "swissknife_migrate.h"
#include "swissknife_pull.h"
#include "swissknife_reflog.h"
#include "swissknife_scrub.h"
#include "swissknife_sign.h"
#include "swissknife_sync.h"
#include "swissknife_zpipe.h"
#include "util/string.h"

using namespace std;  // NOLINT

typedef vector<swissknife::Command *> Commands;
Commands command_list;

void Usage() {
  LogCvmfs(kLogCvmfs, kLogStdout,
    "CernVM-FS repository storage management commands\n"
    "Version %s\n"
    "Usage (normally called from cvmfs_server):\n"
    "  cvmfs_swissknife <command> [options]\n",
    VERSION);

  for (unsigned i = 0; i < command_list.size(); ++i) {
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "\n"
             "Command %s\n"
             "--------", command_list[i]->GetName().c_str());
    for (unsigned j = 0; j < command_list[i]->GetName().length(); ++j) {
      LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "-");
    }
    LogCvmfs(kLogCvmfs, kLogStdout, "");
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
             command_list[i]->GetDescription().c_str());
    swissknife::ParameterList params = command_list[i]->GetParams();
    if (!params.empty()) {
      LogCvmfs(kLogCvmfs, kLogStdout, "Options:");
      for (unsigned j = 0; j < params.size(); ++j) {
        LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "  -%c    %s",
                 params[j].key(), params[j].description().c_str());
        if (params[j].optional())
          LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, " (optional)");
        LogCvmfs(kLogCvmfs, kLogStdout, "");
      }
    }  // Parameter list
  }  // Command list

  LogCvmfs(kLogCvmfs, kLogStdout, "");
}

int main(int argc, char **argv) {
  //  // used for debugging
  //  FILE *f = fopen("/home/ddosaru/cvmfs/build/log_dbg", "w");
  //  if (f == NULL) {
  //      printf("Error opening file!\n");
  //      return -1;
  //  }

  command_list.push_back(new swissknife::CommandCreate());
  command_list.push_back(new swissknife::CommandUpload());
  command_list.push_back(new swissknife::CommandRemove());
  command_list.push_back(new swissknife::CommandPeek());
  command_list.push_back(new swissknife::CommandSync());
  command_list.push_back(new swissknife::CommandApplyDirtab());
  command_list.push_back(new swissknife::CommandEditTag());
  command_list.push_back(new swissknife::CommandListTags());
  command_list.push_back(new swissknife::CommandInfoTag());
  command_list.push_back(new swissknife::CommandRollbackTag());
  command_list.push_back(new swissknife::CommandEmptyRecycleBin());
  command_list.push_back(new swissknife::CommandSign());
  command_list.push_back(new swissknife::CommandLetter());
  command_list.push_back(new swissknife::CommandCheck());
  command_list.push_back(new swissknife::CommandListCatalogs());
  command_list.push_back(new swissknife::CommandDiff());
  command_list.push_back(new swissknife::CommandPull());
  command_list.push_back(new swissknife::CommandZpipe());
  command_list.push_back(new swissknife::CommandGraft());
  command_list.push_back(new swissknife::CommandHash());
  command_list.push_back(new swissknife::CommandInfo());
  command_list.push_back(new swissknife::CommandVersion());
  command_list.push_back(new swissknife::CommandMigrate());
  command_list.push_back(new swissknife::CommandScrub());
  command_list.push_back(new swissknife::CommandGc());
  command_list.push_back(new swissknife::CommandReconstructReflog());
  command_list.push_back(new swissknife::CommandLease());
  command_list.push_back(new swissknife::Ingest());

  if (argc < 2) {
    Usage();
    return 1;
  }
  if ((string(argv[1]) == "--help")) {
    Usage();
    return 0;
  }
  if ((string(argv[1]) == "--version")) {
    swissknife::CommandVersion().Main(swissknife::ArgumentList());
    return 0;
  }

  // find the command to be run
  swissknife::Command *command = NULL;
  for (unsigned i = 0; i < command_list.size(); ++i) {
    if (command_list[i]->GetName() == string(argv[1])) {
      command = command_list[i];
      break;
    }
  }

  if (NULL == command) {
    Usage();
    return 1;
  }

  bool display_statistics = false;

  // parse the command line arguments for the Command
  swissknife::ArgumentList args;
  optind = 1;
  string option_string = "";
  swissknife::ParameterList params = command->GetParams();
  for (unsigned j = 0; j < params.size(); ++j) {
    option_string.push_back(params[j].key());
    if (!params[j].switch_only())
      option_string.push_back(':');
  }
  // Now adding the generic -+ extra option command
  option_string.push_back(swissknife::Command::kGenericParam);
  option_string.push_back(':');
  int c;
  while ((c = getopt(argc, argv, option_string.c_str())) != -1) {
    //  fprintf(f, "getopt --> %c\n", c);
    bool valid_option = false;
    for (unsigned j = 0; j < params.size(); ++j) {
      if (c == params[j].key()) {
        assert(c != swissknife::Command::kGenericParam);
        valid_option = true;
        string *argument = NULL;
        if (!params[j].switch_only()) {
          argument = new string(optarg);
        }
        args[c] = argument;
        break;
      }
    }
    if (c == swissknife::Command::kGenericParam) {
      valid_option = true;
      vector<string> flags = SplitString(optarg,
                                         swissknife::
                                         Command::kGenericParamSeparator);
      for (unsigned i = 0; i < flags.size(); ++i) {
        if (flags[i] == "stats") {
          display_statistics = true;
        }
      }
    }
    if (!valid_option) {
      Usage();
      return 1;
    }
  }
  for (unsigned j = 0; j < params.size(); ++j) {
    if (!params[j].optional()) {
      if (args.find(params[j].key()) == args.end()) {
        LogCvmfs(kLogCvmfs, kLogStderr, "parameter -%c missing",
                 params[j].key());
        return 1;
      }
    }
  }

  // run the command
  const int retval = command->Main(args);
  if (display_statistics) {
    LogCvmfs(kLogCvmfs, kLogStdout, "Command statistics");
    LogCvmfs(kLogCvmfs, kLogStdout, "%s",
             command->statistics()
             ->PrintList(perf::Statistics::kPrintHeader).c_str());
  }

  // delete the command list
        Commands::const_iterator i    = command_list.begin();
  const Commands::const_iterator iend = command_list.end();
  for (; i != iend; ++i) {
    delete *i;
  }
  command_list.clear();
  // fclose(f);
  return retval;
}
<|endoftext|>


<commit_before><commit_msg>check TRG_HasMasterPage before TRG_GetMasterPage<commit_after><|endoftext|>


<commit_before><commit_msg>sd: fix gcc-4.7 build<commit_after><|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "fuconarc.hxx"

#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif
#ifndef _SVDOCIRC_HXX //autogen
#include <svx/svdocirc.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX //autogen
#include <sfx2/viewfrm.hxx>
#endif

#include <svx/svxids.hrc>
#include <math.h>

#include "app.hrc"

#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "drawdoc.hxx"
#include "res_bmp.hrc"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif
#ifndef SD_TOOL_BAR_MANAGER_HXX
#include "ToolBarManager.hxx"
#endif

// #97016#
#ifndef _SXCIAITM_HXX
#include <svx/sxciaitm.hxx>
#endif

namespace sd {

TYPEINIT1( FuConstructArc, FuConstruct );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuConstructArc::FuConstructArc (
    ViewShell*  pViewSh,
    ::sd::Window*       pWin,
    ::sd::View*         pView,
    SdDrawDocument* pDoc,
    SfxRequest&     rReq )
    : FuConstruct( pViewSh, pWin, pView, pDoc, rReq )
{
}

FunctionReference FuConstructArc::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent  )
{
    FuConstructArc* pFunc;
    FunctionReference xFunc( pFunc = new FuConstructArc( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    pFunc->SetPermanent(bPermanent);
    return xFunc;
}

void FuConstructArc::DoExecute( SfxRequest& rReq )
{
    FuConstruct::DoExecute( rReq );

    pViewShell->GetViewShellBase().GetToolBarManager().SetToolBar(
        ToolBarManager::TBG_FUNCTION,
        ToolBarManager::msDrawingObjectToolBar);

    const SfxItemSet *pArgs = rReq.GetArgs ();

    if (pArgs)
    {
        SFX_REQUEST_ARG (rReq, pCenterX, SfxUInt32Item, ID_VAL_CENTER_X, FALSE);
        SFX_REQUEST_ARG (rReq, pCenterY, SfxUInt32Item, ID_VAL_CENTER_Y, FALSE);
        SFX_REQUEST_ARG (rReq, pAxisX, SfxUInt32Item, ID_VAL_AXIS_X, FALSE);
        SFX_REQUEST_ARG (rReq, pAxisY, SfxUInt32Item, ID_VAL_AXIS_Y, FALSE);
        SFX_REQUEST_ARG (rReq, pPhiStart, SfxUInt32Item, ID_VAL_ANGLESTART, FALSE);
        SFX_REQUEST_ARG (rReq, pPhiEnd, SfxUInt32Item, ID_VAL_ANGLEEND, FALSE);

        Rectangle   aNewRectangle (pCenterX->GetValue () - pAxisX->GetValue () / 2,
                                   pCenterY->GetValue () - pAxisY->GetValue () / 2,
                                   pCenterX->GetValue () + pAxisX->GetValue () / 2,
                                   pCenterY->GetValue () + pAxisY->GetValue () / 2);

        Activate();  // Setzt aObjKind
        SdrCircObj* pNewCircle =
        new SdrCircObj((SdrObjKind) pView->GetCurrentObjIdentifier(),
                       aNewRectangle,
                       (long) (pPhiStart->GetValue () * 10.0),
                       (long) (pPhiEnd->GetValue () * 10.0));
        SdrPageView *pPV = pView->GetSdrPageView();

        pView->InsertObjectAtView(pNewCircle, *pPV, SDRINSERT_SETDEFLAYER);
    }
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseButtonDown( const MouseEvent& rMEvt )
{
    BOOL bReturn = FuConstruct::MouseButtonDown( rMEvt );

    if ( rMEvt.IsLeft() && !pView->IsAction() )
    {
        Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
        pWindow->CaptureMouse();
        USHORT nDrgLog = USHORT ( pWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
        pView->BegCreateObj(aPnt, (OutputDevice*) NULL, nDrgLog);

        SdrObject* pObj = pView->GetCreateObj();

        if (pObj)
        {
            SfxItemSet aAttr(pDoc->GetPool());
            SetStyleSheet(aAttr, pObj);

//-/            pObj->NbcSetAttributes(aAttr, FALSE);
            pObj->SetMergedItemSet(aAttr);
        }

        bReturn = TRUE;
    }
    return bReturn;
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseMove( const MouseEvent& rMEvt )
{
    return FuConstruct::MouseMove(rMEvt);
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseButtonUp( const MouseEvent& rMEvt )
{
    BOOL bReturn = FALSE;
    BOOL bCreated = FALSE;

    if ( pView->IsCreateObj() && rMEvt.IsLeft() )
    {
        Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );

        ULONG nCount = pView->GetSdrPageView()->GetObjList()->GetObjCount();

        if (pView->EndCreateObj(SDRCREATE_NEXTPOINT) )
        {
            if (nCount != pView->GetSdrPageView()->GetObjList()->GetObjCount())
            {
                bCreated = TRUE;
            }
        }

        bReturn = TRUE;
    }

    bReturn = FuConstruct::MouseButtonUp (rMEvt) || bReturn;

    if (!bPermanent && bCreated)
        pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);

    return bReturn;
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
|* FALSE.
|*
\************************************************************************/

BOOL FuConstructArc::KeyInput(const KeyEvent& rKEvt)
{
    BOOL bReturn = FuConstruct::KeyInput(rKEvt);
    return(bReturn);
}

/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuConstructArc::Activate()
{
    SdrObjKind aObjKind;

    switch( nSlotId )
    {
        case SID_DRAW_ARC      :
        case SID_DRAW_CIRCLEARC:
        {
            aObjKind = OBJ_CARC;
        }
        break;

        case SID_DRAW_PIE             :
        case SID_DRAW_PIE_NOFILL      :
        case SID_DRAW_CIRCLEPIE       :
        case SID_DRAW_CIRCLEPIE_NOFILL:
        {
            aObjKind = OBJ_SECT;
        }
        break;

        case SID_DRAW_ELLIPSECUT       :
        case SID_DRAW_ELLIPSECUT_NOFILL:
        case SID_DRAW_CIRCLECUT        :
        case SID_DRAW_CIRCLECUT_NOFILL :
        {
            aObjKind = OBJ_CCUT;
        }
        break;

        default:
        {
            aObjKind = OBJ_CARC;
        }
        break;
    }

    pView->SetCurrentObj(aObjKind);

    FuConstruct::Activate();
//  FuDraw::Activate();
}

/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuConstructArc::Deactivate()
{
    FuConstruct::Deactivate();
//  FuDraw::Deactivate();
}

// #97016#
SdrObject* FuConstructArc::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
{
    // case SID_DRAW_ARC:
    // case SID_DRAW_CIRCLEARC:
    // case SID_DRAW_PIE:
    // case SID_DRAW_PIE_NOFILL:
    // case SID_DRAW_CIRCLEPIE:
    // case SID_DRAW_CIRCLEPIE_NOFILL:
    // case SID_DRAW_ELLIPSECUT:
    // case SID_DRAW_ELLIPSECUT_NOFILL:
    // case SID_DRAW_CIRCLECUT:
    // case SID_DRAW_CIRCLECUT_NOFILL:

    SdrObject* pObj = SdrObjFactory::MakeNewObject(
        pView->GetCurrentObjInventor(), pView->GetCurrentObjIdentifier(),
        0L, pDoc);

    if(pObj)
    {
        if(pObj->ISA(SdrCircObj))
        {
            Rectangle aRect(rRectangle);

            if(SID_DRAW_ARC == nID ||
                SID_DRAW_CIRCLEARC == nID ||
                SID_DRAW_CIRCLEPIE == nID ||
                SID_DRAW_CIRCLEPIE_NOFILL == nID ||
                SID_DRAW_CIRCLECUT == nID ||
                SID_DRAW_CIRCLECUT_NOFILL == nID)
            {
                // force quadratic
                ImpForceQuadratic(aRect);
            }

            pObj->SetLogicRect(aRect);

            SfxItemSet aAttr(pDoc->GetPool());
            aAttr.Put(SdrCircStartAngleItem(9000));
            aAttr.Put(SdrCircEndAngleItem(0));

            if(SID_DRAW_PIE_NOFILL == nID ||
                SID_DRAW_CIRCLEPIE_NOFILL == nID ||
                SID_DRAW_ELLIPSECUT_NOFILL == nID ||
                SID_DRAW_CIRCLECUT_NOFILL == nID)
            {
                aAttr.Put(XFillStyleItem(XFILL_NONE));
            }

            pObj->SetMergedItemSet(aAttr);
        }
        else
        {
            DBG_ERROR("Object is NO circle object");
        }
    }

    return pObj;
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS sdwarningsbegone (1.13.36); FILE MERGED 2006/11/27 13:48:01 cl 1.13.36.3: #i69285# warning free code changes for sd project 2006/11/22 15:03:44 cl 1.13.36.2: RESYNC: (1.13-1.14); FILE MERGED 2006/11/22 12:41:51 cl 1.13.36.1: #i69285# warning free code changes for unxlngi6.pro<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuconarc.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 17:14:53 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "fuconarc.hxx"

#ifndef _SVDPAGV_HXX //autogen
#include <svx/svdpagv.hxx>
#endif
#ifndef _SVDOCIRC_HXX //autogen
#include <svx/svdocirc.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <sfx2/request.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _AEITEM_HXX //autogen
#include <svtools/aeitem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX //autogen
#include <sfx2/viewfrm.hxx>
#endif

#include <svx/svxids.hrc>
#include <math.h>

#include "app.hrc"

#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "drawdoc.hxx"
#include "res_bmp.hrc"
#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_VIEW_SHELL_BASE_HXX
#include "ViewShellBase.hxx"
#endif
#ifndef SD_TOOL_BAR_MANAGER_HXX
#include "ToolBarManager.hxx"
#endif

// #97016#
#ifndef _SXCIAITM_HXX
#include <svx/sxciaitm.hxx>
#endif

namespace sd {

TYPEINIT1( FuConstructArc, FuConstruct );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuConstructArc::FuConstructArc (
    ViewShell*  pViewSh,
    ::sd::Window*       pWin,
    ::sd::View*         pView,
    SdDrawDocument* pDoc,
    SfxRequest&     rReq )
    : FuConstruct( pViewSh, pWin, pView, pDoc, rReq )
{
}

FunctionReference FuConstructArc::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent  )
{
    FuConstructArc* pFunc;
    FunctionReference xFunc( pFunc = new FuConstructArc( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    pFunc->SetPermanent(bPermanent);
    return xFunc;
}

void FuConstructArc::DoExecute( SfxRequest& rReq )
{
    FuConstruct::DoExecute( rReq );

    mpViewShell->GetViewShellBase().GetToolBarManager().SetToolBar(
        ToolBarManager::TBG_FUNCTION,
        ToolBarManager::msDrawingObjectToolBar);

    const SfxItemSet *pArgs = rReq.GetArgs ();

    if (pArgs)
    {
        SFX_REQUEST_ARG (rReq, pCenterX, SfxUInt32Item, ID_VAL_CENTER_X, FALSE);
        SFX_REQUEST_ARG (rReq, pCenterY, SfxUInt32Item, ID_VAL_CENTER_Y, FALSE);
        SFX_REQUEST_ARG (rReq, pAxisX, SfxUInt32Item, ID_VAL_AXIS_X, FALSE);
        SFX_REQUEST_ARG (rReq, pAxisY, SfxUInt32Item, ID_VAL_AXIS_Y, FALSE);
        SFX_REQUEST_ARG (rReq, pPhiStart, SfxUInt32Item, ID_VAL_ANGLESTART, FALSE);
        SFX_REQUEST_ARG (rReq, pPhiEnd, SfxUInt32Item, ID_VAL_ANGLEEND, FALSE);

        Rectangle   aNewRectangle (pCenterX->GetValue () - pAxisX->GetValue () / 2,
                                   pCenterY->GetValue () - pAxisY->GetValue () / 2,
                                   pCenterX->GetValue () + pAxisX->GetValue () / 2,
                                   pCenterY->GetValue () + pAxisY->GetValue () / 2);

        Activate();  // Setzt aObjKind
        SdrCircObj* pNewCircle =
        new SdrCircObj((SdrObjKind) mpView->GetCurrentObjIdentifier(),
                       aNewRectangle,
                       (long) (pPhiStart->GetValue () * 10.0),
                       (long) (pPhiEnd->GetValue () * 10.0));
        SdrPageView *pPV = mpView->GetSdrPageView();

        mpView->InsertObjectAtView(pNewCircle, *pPV, SDRINSERT_SETDEFLAYER);
    }
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseButtonDown( const MouseEvent& rMEvt )
{
    BOOL bReturn = FuConstruct::MouseButtonDown( rMEvt );

    if ( rMEvt.IsLeft() && !mpView->IsAction() )
    {
        Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
        mpWindow->CaptureMouse();
        USHORT nDrgLog = USHORT ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
        mpView->BegCreateObj(aPnt, (OutputDevice*) NULL, nDrgLog);

        SdrObject* pObj = mpView->GetCreateObj();

        if (pObj)
        {
            SfxItemSet aAttr(mpDoc->GetPool());
            SetStyleSheet(aAttr, pObj);

//-/            pObj->NbcSetAttributes(aAttr, FALSE);
            pObj->SetMergedItemSet(aAttr);
        }

        bReturn = TRUE;
    }
    return bReturn;
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseMove( const MouseEvent& rMEvt )
{
    return FuConstruct::MouseMove(rMEvt);
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

BOOL FuConstructArc::MouseButtonUp( const MouseEvent& rMEvt )
{
    BOOL bReturn = FALSE;
    BOOL bCreated = FALSE;

    if ( mpView->IsCreateObj() && rMEvt.IsLeft() )
    {
        Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );

        ULONG nCount = mpView->GetSdrPageView()->GetObjList()->GetObjCount();

        if (mpView->EndCreateObj(SDRCREATE_NEXTPOINT) )
        {
            if (nCount != mpView->GetSdrPageView()->GetObjList()->GetObjCount())
            {
                bCreated = TRUE;
            }
        }

        bReturn = TRUE;
    }

    bReturn = FuConstruct::MouseButtonUp (rMEvt) || bReturn;

    if (!bPermanent && bCreated)
        mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);

    return bReturn;
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
|* FALSE.
|*
\************************************************************************/

BOOL FuConstructArc::KeyInput(const KeyEvent& rKEvt)
{
    BOOL bReturn = FuConstruct::KeyInput(rKEvt);
    return(bReturn);
}

/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuConstructArc::Activate()
{
    SdrObjKind aObjKind;

    switch( nSlotId )
    {
        case SID_DRAW_ARC      :
        case SID_DRAW_CIRCLEARC:
        {
            aObjKind = OBJ_CARC;
        }
        break;

        case SID_DRAW_PIE             :
        case SID_DRAW_PIE_NOFILL      :
        case SID_DRAW_CIRCLEPIE       :
        case SID_DRAW_CIRCLEPIE_NOFILL:
        {
            aObjKind = OBJ_SECT;
        }
        break;

        case SID_DRAW_ELLIPSECUT       :
        case SID_DRAW_ELLIPSECUT_NOFILL:
        case SID_DRAW_CIRCLECUT        :
        case SID_DRAW_CIRCLECUT_NOFILL :
        {
            aObjKind = OBJ_CCUT;
        }
        break;

        default:
        {
            aObjKind = OBJ_CARC;
        }
        break;
    }

    mpView->SetCurrentObj((UINT16)aObjKind);

    FuConstruct::Activate();
//  FuDraw::Activate();
}

/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuConstructArc::Deactivate()
{
    FuConstruct::Deactivate();
//  FuDraw::Deactivate();
}

// #97016#
SdrObject* FuConstructArc::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
{
    // case SID_DRAW_ARC:
    // case SID_DRAW_CIRCLEARC:
    // case SID_DRAW_PIE:
    // case SID_DRAW_PIE_NOFILL:
    // case SID_DRAW_CIRCLEPIE:
    // case SID_DRAW_CIRCLEPIE_NOFILL:
    // case SID_DRAW_ELLIPSECUT:
    // case SID_DRAW_ELLIPSECUT_NOFILL:
    // case SID_DRAW_CIRCLECUT:
    // case SID_DRAW_CIRCLECUT_NOFILL:

    SdrObject* pObj = SdrObjFactory::MakeNewObject(
        mpView->GetCurrentObjInventor(), mpView->GetCurrentObjIdentifier(),
        0L, mpDoc);

    if(pObj)
    {
        if(pObj->ISA(SdrCircObj))
        {
            Rectangle aRect(rRectangle);

            if(SID_DRAW_ARC == nID ||
                SID_DRAW_CIRCLEARC == nID ||
                SID_DRAW_CIRCLEPIE == nID ||
                SID_DRAW_CIRCLEPIE_NOFILL == nID ||
                SID_DRAW_CIRCLECUT == nID ||
                SID_DRAW_CIRCLECUT_NOFILL == nID)
            {
                // force quadratic
                ImpForceQuadratic(aRect);
            }

            pObj->SetLogicRect(aRect);

            SfxItemSet aAttr(mpDoc->GetPool());
            aAttr.Put(SdrCircStartAngleItem(9000));
            aAttr.Put(SdrCircEndAngleItem(0));

            if(SID_DRAW_PIE_NOFILL == nID ||
                SID_DRAW_CIRCLEPIE_NOFILL == nID ||
                SID_DRAW_ELLIPSECUT_NOFILL == nID ||
                SID_DRAW_CIRCLECUT_NOFILL == nID)
            {
                aAttr.Put(XFillStyleItem(XFILL_NONE));
            }

            pObj->SetMergedItemSet(aAttr);
        }
        else
        {
            DBG_ERROR("Object is NO circle object");
        }
    }

    return pObj;
}

} // end of namespace sd
<|endoftext|>


<commit_before>#include <TimerOne.h> //Needed to make this file compile because hibike compiler bugs.

#include "ui.h"
#include "motor.h"
#include "pid.h"
#include "encoder.h"
//Code here that helps deal with the human-readable UI.
//Will contain code that will do the following:

//Let the user set State: Disabled, Enabled (open loop), Enabled (PID velocity), Enabled (PID position).
//Let the user set the setpoint.
//Let the user set the current limit stuff?
//Let the user enable/disable printing of various outputs (Position, current, etc)

//This code will be called by void loop in Integrated.  It will NOT use timers or interrupts.

void manual_ui()
{

  if (heartbeat > heartbeatLimit) {
    disable();
    Serial.println("We ded");
  }
  if (continualPrint) {
    Serial.print("PWM: ");
    Serial.print(pwmPID,5);
    Serial.print("  |  Encoder Pos: ");
    Serial.print(pos);
    Serial.print("  |  Encoder Vel: ");
    Serial.println(vel);
  }
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    if ( (c == 10) || (c == 13)) //if c is \n or \r
    {
      //do nothing.
    }
    else if (c == 's')
    {
      pwmInput = Serial.parseFloat();
      Serial.print("New Speed: ");
      Serial.println(pwmInput);
    }
    else if (c == 'c') {
      Serial.println("Clearing Fault");
      clearFault();
    }
    else if (c == 'p') {
      Serial.read();
      char val = Serial.read();
      if (val == 'p') {
        driveMode = 2;
        enablePos();
        Serial.println("Turning on PID Position mode");
      }
      else if (val == 'v') {
        driveMode = 1;
        enableVel();
        Serial.println("Turning on PID Position mode");
      }
    }
    else if (c == 'm') {
      Serial.println("Turning on manual mode");
      disablePID();
      driveMode = 0;
    }
    else if (c == 'e') {
      Serial.println("Enabled");
      enable();
    }
    else if (c == 'd') {
      Serial.println("Disabled");
      disable();
    }
    else if (c == 'r') {
      Serial.print("Encoder Pos: ");
      Serial.println(encoder());
      Serial.print("Encoder Vel: ");
      Serial.println(vel);
      Serial.print("Current: ");
      Serial.println(readCurrent());
    }
    else if (c == 't') {
      continualPrint = !continualPrint;
      Serial.println("Toggling readout prints");
    }
    else if (c == 'w') {
      Serial.read();
      char val1 = Serial.read();
      char val2 = Serial.read();

      if (val1 == 'c') {
        current_threshold = Serial.parseFloat();
        Serial.print("New current threshold: ");
        Serial.println(current_threshold);
      }
      else if (val1 == 'p') {
        if (val2 == 'p'){
          PIDPosKP = Serial.parseFloat();
          Serial.print("New PID position KP value: ");
          Serial.println(PIDPosKP);
        }
        else if (val2 == 'i'){
          PIDPosKI = Serial.parseFloat();
          Serial.print("New PID position KI value: ");
          Serial.println(PIDPosKI);
        }
        else if (val2 == 'd'){
          PIDPosKD = Serial.parseFloat();
          Serial.print("New PID position KD value: ");
          Serial.println(PIDPosKD);
        }
        else {
          PIDPos = Serial.parseFloat();
          Serial.print("New PID position: ");
          Serial.println(PIDPos);
        }
        updatePosPID();

    }
    else if (val1 == 'v') {
      if (val2 == 'p') {
        PIDVelKP = Serial.parseFloat();
        Serial.print("New PID velocity KP value: ");
        Serial.println(PIDVelKP);
      }
      else if (val2 == 'i') {
        PIDVelKI = Serial.parseFloat();
        Serial.print("New PID velocity KI value: ");
        Serial.println(PIDVelKI);
      }
      else if (val2 == 'd') {
        PIDVelKD = Serial.parseFloat();
        Serial.print("New PID velocity KD value: ");
        Serial.println(PIDVelKD);
      }
      else {
        PIDVel = Serial.parseFloat();
        Serial.print("New PID velocity: ");
        Serial.println(PIDVel);
      }
      updateVelPID();
    }

    else {
      Serial.println("Cannot write to that");
    }
  }
  else if (c == 'b') {
    Serial.println("Heartbeat");
    heartbeat = 0;
  }
  else if (c == 'h') {
    hibike = true;
    heartbeatLimit = 500;
    Serial.println("Going to hibike mode");
  }
  else if (c == 'z') {
    hibike = false;
    heartbeatLimit = 30000;
    Serial.println("Turning off hibike");
  }
  else if (c == '?') {
    Serial.println("Manual Controls: \ns <x> - sets pwm to x \nc     - clears faults \np <x> - turns on PID mode, velocity if x = v, position if x = p \nm     - turns on manual input mode \ne     - enables motor \nd     - disables motor \nr     - displays 1 print of all readable values \nt     - toggles continual printing of pos and vel \nb     - send heartbeat \nh     - switch hibike mode \nz     - switch human controls \nw <x> <y> - writes the value y to the variable x");
  }
  else {
    Serial.println("Bad input");
  }
}
delay(10);
}

<commit_msg>Figured out that weird bug where I had to pull in unrelated library.<commit_after>#include "Arduino.h" //to get digital write, etc.

#include "ui.h"
#include "motor.h"
#include "pid.h"
#include "encoder.h"
//Code here that helps deal with the human-readable UI.
//Will contain code that will do the following:

//Let the user set State: Disabled, Enabled (open loop), Enabled (PID velocity), Enabled (PID position).
//Let the user set the setpoint.
//Let the user set the current limit stuff?
//Let the user enable/disable printing of various outputs (Position, current, etc)

//This code will be called by void loop in Integrated.  It will NOT use timers or interrupts.

void manual_ui()
{

  if (heartbeat > heartbeatLimit) {
    disable();
    Serial.println("We ded");
  }
  if (continualPrint) {
    Serial.print("PWM: ");
    Serial.print(pwmPID,5);
    Serial.print("  |  Encoder Pos: ");
    Serial.print(pos);
    Serial.print("  |  Encoder Vel: ");
    Serial.println(vel);
  }
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    if ( (c == 10) || (c == 13)) //if c is \n or \r
    {
      //do nothing.
    }
    else if (c == 's')
    {
      pwmInput = Serial.parseFloat();
      Serial.print("New Speed: ");
      Serial.println(pwmInput);
    }
    else if (c == 'c') {
      Serial.println("Clearing Fault");
      clearFault();
    }
    else if (c == 'p') {
      Serial.read();
      char val = Serial.read();
      if (val == 'p') {
        driveMode = 2;
        enablePos();
        Serial.println("Turning on PID Position mode");
      }
      else if (val == 'v') {
        driveMode = 1;
        enableVel();
        Serial.println("Turning on PID Position mode");
      }
    }
    else if (c == 'm') {
      Serial.println("Turning on manual mode");
      disablePID();
      driveMode = 0;
    }
    else if (c == 'e') {
      Serial.println("Enabled");
      enable ();
    }
    else if (c == 'd') {
      Serial.println("Disabled");
      disable();
    }
    else if (c == 'r') {
      Serial.print("Encoder Pos: ");
      Serial.println(encoder());
      Serial.print("Encoder Vel: ");
      Serial.println(vel);
      Serial.print("Current: ");
      Serial.println(readCurrent());
    }
    else if (c == 't') {
      continualPrint = !continualPrint;
      Serial.println("Toggling readout prints");
    }
    else if (c == 'w') {
      Serial.read();
      char val1 = Serial.read();
      char val2 = Serial.read();

      if (val1 == 'c') {
        current_threshold = Serial.parseFloat();
        Serial.print("New current threshold: ");
        Serial.println(current_threshold);
      }
      else if (val1 == 'p') {
        if (val2 == 'p'){
          PIDPosKP = Serial.parseFloat();
          Serial.print("New PID position KP value: ");
          Serial.println(PIDPosKP);
        }
        else if (val2 == 'i'){
          PIDPosKI = Serial.parseFloat();
          Serial.print("New PID position KI value: ");
          Serial.println(PIDPosKI);
        }
        else if (val2 == 'd'){
          PIDPosKD = Serial.parseFloat();
          Serial.print("New PID position KD value: ");
          Serial.println(PIDPosKD);
        }
        else {
          PIDPos = Serial.parseFloat();
          Serial.print("New PID position: ");
          Serial.println(PIDPos);
        }
        updatePosPID();

    }
    else if (val1 == 'v') {
      if (val2 == 'p') {
        PIDVelKP = Serial.parseFloat();
        Serial.print("New PID velocity KP value: ");
        Serial.println(PIDVelKP);
      }
      else if (val2 == 'i') {
        PIDVelKI = Serial.parseFloat();
        Serial.print("New PID velocity KI value: ");
        Serial.println(PIDVelKI);
      }
      else if (val2 == 'd') {
        PIDVelKD = Serial.parseFloat();
        Serial.print("New PID velocity KD value: ");
        Serial.println(PIDVelKD);
      }
      else {
        PIDVel = Serial.parseFloat();
        Serial.print("New PID velocity: ");
        Serial.println(PIDVel);
      }
      updateVelPID();
    }

    else {
      Serial.println("Cannot write to that");
    }
  }
  else if (c == 'b') {
    Serial.println("Heartbeat");
    heartbeat = 0;
  }
  else if (c == 'h') {
    hibike = true;
    heartbeatLimit = 500;
    Serial.println("Going to hibike mode");
  }
  else if (c == 'z') {
    hibike = false;
    heartbeatLimit = 30000;
    Serial.println("Turning off hibike");
  }
  else if (c == '?') {
    Serial.println("Manual Controls: \ns <x> - sets pwm to x \nc     - clears faults \np <x> - turns on PID mode, velocity if x = v, position if x = p \nm     - turns on manual input mode \ne     - enables motor \nd     - disables motor \nr     - displays 1 print of all readable values \nt     - toggles continual printing of pos and vel \nb     - send heartbeat \nh     - switch hibike mode \nz     - switch human controls \nw <x> <y> - writes the value y to the variable x");
  }
  else {
    Serial.println("Bad input");
  }
}
delay(10);
}

<|endoftext|>


<commit_before>/*************************************************************************/
/*  audio_stream.cpp                                                     */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "audio_stream.h"

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

void AudioStreamPlaybackResampled::_begin_resample() {

	//clear cubic interpolation history
	internal_buffer[0] = AudioFrame(0.0, 0.0);
	internal_buffer[1] = AudioFrame(0.0, 0.0);
	internal_buffer[2] = AudioFrame(0.0, 0.0);
	internal_buffer[3] = AudioFrame(0.0, 0.0);
	//mix buffer
	_mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
	mix_offset = 0;
}

void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {

	float target_rate = AudioServer::get_singleton()->get_mix_rate() * p_rate_scale;

	uint64_t mix_increment = uint64_t((get_stream_sampling_rate() / double(target_rate)) * double(FP_LEN));

	for (int i = 0; i < p_frames; i++) {

		uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
		//standard cubic interpolation (great quality/performance ratio)
		//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
		float mu = (mix_offset & FP_MASK) / float(FP_LEN);
		AudioFrame y0 = internal_buffer[idx - 3];
		AudioFrame y1 = internal_buffer[idx - 2];
		AudioFrame y2 = internal_buffer[idx - 1];
		AudioFrame y3 = internal_buffer[idx - 0];

		float mu2 = mu * mu;
		AudioFrame a0 = y3 - y2 - y0 + y1;
		AudioFrame a1 = y0 - y1 - a0;
		AudioFrame a2 = y2 - y0;
		AudioFrame a3 = y1;

		p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);

		mix_offset += mix_increment;

		while ((mix_offset >> FP_BITS) >= INTERNAL_BUFFER_LEN) {

			internal_buffer[0] = internal_buffer[INTERNAL_BUFFER_LEN + 0];
			internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
			internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
			internal_buffer[3] = internal_buffer[INTERNAL_BUFFER_LEN + 3];
			if (!is_playing()) {
				for (int i = 4; i < INTERNAL_BUFFER_LEN; ++i) {
					internal_buffer[i] = AudioFrame(0, 0);
				}

				return;
			}
			_mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
			mix_offset -= (INTERNAL_BUFFER_LEN << FP_BITS);
		}
	}
}
////////////////////////////////

void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {

	audio_stream = p_audio_stream;
	if (audio_stream.is_valid()) {
		for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
			E->get()->playback = audio_stream->instance_playback();
		}
	}
}

Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {

	return audio_stream;
}

void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {

	if (p_pitch < 1)
		p_pitch = 1;
	random_pitch = p_pitch;
}

float AudioStreamRandomPitch::get_random_pitch() const {
	return random_pitch;
}

Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
	Ref<AudioStreamPlaybackRandomPitch> playback;
	playback.instance();
	if (audio_stream.is_valid())
		playback->playback = audio_stream->instance_playback();

	playbacks.insert(playback.ptr());
	playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
	return playback;
}

String AudioStreamRandomPitch::get_stream_name() const {

	if (audio_stream.is_valid()) {
		return "Random: " + audio_stream->get_name();
	}
	return "RandomPitch";
}

void AudioStreamRandomPitch::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
	ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);

	ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomPitch::set_random_pitch);
	ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomPitch::get_random_pitch);

	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_audio_stream", "get_audio_stream");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
}

AudioStreamRandomPitch::AudioStreamRandomPitch() {
	random_pitch = 1.1;
}

void AudioStreamPlaybackRandomPitch::start(float p_from_pos) {
	playing = playback;
	float range_from = 1.0 / random_pitch->random_pitch;
	float range_to = random_pitch->random_pitch;

	pitch_scale = range_from + Math::randf() * (range_to - range_from);

	if (playing.is_valid()) {
		playing->start(p_from_pos);
	}
}

void AudioStreamPlaybackRandomPitch::stop() {
	if (playing.is_valid()) {
		playing->stop();
		;
	}
}
bool AudioStreamPlaybackRandomPitch::is_playing() const {
	if (playing.is_valid()) {
		return playing->is_playing();
	}

	return false;
}

int AudioStreamPlaybackRandomPitch::get_loop_count() const {
	if (playing.is_valid()) {
		return playing->get_loop_count();
	}

	return 0;
}

float AudioStreamPlaybackRandomPitch::get_playback_position() const {
	if (playing.is_valid()) {
		return playing->get_playback_position();
	}

	return 0;
}
void AudioStreamPlaybackRandomPitch::seek(float p_time) {
	if (playing.is_valid()) {
		playing->seek(p_time);
	}
}

void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
	if (playing.is_valid()) {
		playing->mix(p_buffer, p_rate_scale * pitch_scale, p_frames);
	} else {
		for (int i = 0; i < p_frames; i++) {
			p_buffer[i] = AudioFrame(0, 0);
		}
	}
}

float AudioStreamPlaybackRandomPitch::get_length() const {
	if (playing.is_valid()) {
		return playing->get_length();
	}

	return 0;
}

AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
	random_pitch->playbacks.erase(this);
}
<commit_msg>Properly silence buffer while not in use, fixes #14866<commit_after>/*************************************************************************/
/*  audio_stream.cpp                                                     */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "audio_stream.h"

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

void AudioStreamPlaybackResampled::_begin_resample() {

	//clear cubic interpolation history
	internal_buffer[0] = AudioFrame(0.0, 0.0);
	internal_buffer[1] = AudioFrame(0.0, 0.0);
	internal_buffer[2] = AudioFrame(0.0, 0.0);
	internal_buffer[3] = AudioFrame(0.0, 0.0);
	//mix buffer
	_mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
	mix_offset = 0;
}

void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {

	float target_rate = AudioServer::get_singleton()->get_mix_rate() * p_rate_scale;

	uint64_t mix_increment = uint64_t((get_stream_sampling_rate() / double(target_rate)) * double(FP_LEN));

	for (int i = 0; i < p_frames; i++) {

		uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
		//standard cubic interpolation (great quality/performance ratio)
		//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
		float mu = (mix_offset & FP_MASK) / float(FP_LEN);
		AudioFrame y0 = internal_buffer[idx - 3];
		AudioFrame y1 = internal_buffer[idx - 2];
		AudioFrame y2 = internal_buffer[idx - 1];
		AudioFrame y3 = internal_buffer[idx - 0];

		float mu2 = mu * mu;
		AudioFrame a0 = y3 - y2 - y0 + y1;
		AudioFrame a1 = y0 - y1 - a0;
		AudioFrame a2 = y2 - y0;
		AudioFrame a3 = y1;

		p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);

		mix_offset += mix_increment;

		while ((mix_offset >> FP_BITS) >= INTERNAL_BUFFER_LEN) {

			internal_buffer[0] = internal_buffer[INTERNAL_BUFFER_LEN + 0];
			internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
			internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
			internal_buffer[3] = internal_buffer[INTERNAL_BUFFER_LEN + 3];
			if (is_playing()) {
				_mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
			} else {
				//fill with silence, not playing
				for (int i = 0; i < INTERNAL_BUFFER_LEN; ++i) {
					internal_buffer[i + 4] = AudioFrame(0, 0);
				}
			}
			mix_offset -= (INTERNAL_BUFFER_LEN << FP_BITS);
		}
	}
}
////////////////////////////////

void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {

	audio_stream = p_audio_stream;
	if (audio_stream.is_valid()) {
		for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
			E->get()->playback = audio_stream->instance_playback();
		}
	}
}

Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {

	return audio_stream;
}

void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {

	if (p_pitch < 1)
		p_pitch = 1;
	random_pitch = p_pitch;
}

float AudioStreamRandomPitch::get_random_pitch() const {
	return random_pitch;
}

Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
	Ref<AudioStreamPlaybackRandomPitch> playback;
	playback.instance();
	if (audio_stream.is_valid())
		playback->playback = audio_stream->instance_playback();

	playbacks.insert(playback.ptr());
	playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
	return playback;
}

String AudioStreamRandomPitch::get_stream_name() const {

	if (audio_stream.is_valid()) {
		return "Random: " + audio_stream->get_name();
	}
	return "RandomPitch";
}

void AudioStreamRandomPitch::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
	ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);

	ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomPitch::set_random_pitch);
	ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomPitch::get_random_pitch);

	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_audio_stream", "get_audio_stream");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
}

AudioStreamRandomPitch::AudioStreamRandomPitch() {
	random_pitch = 1.1;
}

void AudioStreamPlaybackRandomPitch::start(float p_from_pos) {
	playing = playback;
	float range_from = 1.0 / random_pitch->random_pitch;
	float range_to = random_pitch->random_pitch;

	pitch_scale = range_from + Math::randf() * (range_to - range_from);

	if (playing.is_valid()) {
		playing->start(p_from_pos);
	}
}

void AudioStreamPlaybackRandomPitch::stop() {
	if (playing.is_valid()) {
		playing->stop();
		;
	}
}
bool AudioStreamPlaybackRandomPitch::is_playing() const {
	if (playing.is_valid()) {
		return playing->is_playing();
	}

	return false;
}

int AudioStreamPlaybackRandomPitch::get_loop_count() const {
	if (playing.is_valid()) {
		return playing->get_loop_count();
	}

	return 0;
}

float AudioStreamPlaybackRandomPitch::get_playback_position() const {
	if (playing.is_valid()) {
		return playing->get_playback_position();
	}

	return 0;
}
void AudioStreamPlaybackRandomPitch::seek(float p_time) {
	if (playing.is_valid()) {
		playing->seek(p_time);
	}
}

void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
	if (playing.is_valid()) {
		playing->mix(p_buffer, p_rate_scale * pitch_scale, p_frames);
	} else {
		for (int i = 0; i < p_frames; i++) {
			p_buffer[i] = AudioFrame(0, 0);
		}
	}
}

float AudioStreamPlaybackRandomPitch::get_length() const {
	if (playing.is_valid()) {
		return playing->get_length();
	}

	return 0;
}

AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
	random_pitch->playbacks.erase(this);
}
<|endoftext|>