<commit_before>/*
 * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
 */
extern "C" {
#include <ovsdb_wrapper.h>
}
#include <ovsdb_object.h>
#include <ovsdb_entry.h>
#include <ovsdb_types.h>

using OVSDB::OvsdbEntry;
using OVSDB::OvsdbDBEntry;
using OVSDB::OvsdbObject;
using OVSDB::OvsdbDBObject;

OvsdbEntry::OvsdbEntry(OvsdbObject *table) : KSyncEntry(), table_(table),
    ovs_entry_(NULL) {
}

OvsdbEntry::OvsdbEntry(OvsdbObject *table, uint32_t index) : KSyncEntry(index),
    table_(table), ovs_entry_(NULL) {
}

OvsdbEntry::~OvsdbEntry() {
}

bool OvsdbEntry::Add() {
    return true;
}

bool OvsdbEntry::Change() {
    return true;
}

bool OvsdbEntry::Delete() {
    return true;
}

KSyncObject *OvsdbEntry::GetObject() {
    return table_;
}

void OvsdbEntry::Ack(bool success) {
    // TODO we don't handle failures for these entries
    if (!success) {
        OVSDB_TRACE(Error, "Transaction failed for " + ToString());
    }

    OvsdbObject *object = static_cast<OvsdbObject*>(GetObject());
    object->NotifyEvent(this, ack_event_);
}

OvsdbDBEntry::OvsdbDBEntry(OvsdbDBObject *table) : KSyncDBEntry(), table_(table),
    ovs_entry_(NULL) {
}

OvsdbDBEntry::OvsdbDBEntry(OvsdbDBObject *table, struct ovsdb_idl_row *ovs_entry) : KSyncDBEntry(),
    table_(table), ovs_entry_(ovs_entry) {
}

OvsdbDBEntry::~OvsdbDBEntry() {
}

bool OvsdbDBEntry::Add() {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    // trigger pre add/change only if idl is not marked deleted.
    // we should not update KSync references as, these references eventually
    // need to be released as part of delete trigger due to cleanup.
    if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
        PreAddChange();
    }

    if (IsNoTxnEntry()) {
        // trigger AddMsg with NULL pointer and return true to complete
        // KSync state
        AddMsg(NULL);
        return true;
    }

    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::ADD_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::ADD_ACK);
    }

    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    AddMsg(txn);
    return object->client_idl_->EncodeSendTxn(txn, this);
}

bool OvsdbDBEntry::Change() {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    // trigger pre add/change only if idl is not marked deleted.
    // we should not update KSync references as, these references eventually
    // need to be released as part of delete trigger due to cleanup.
    if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
        PreAddChange();
    }

    if (IsNoTxnEntry()) {
        // trigger ChangeMsg with NULL pointer and return true to complete
        // KSync state
        ChangeMsg(NULL);
        return true;
    }

    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::CHANGE_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::CHANGE_ACK);
    }

    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    ChangeMsg(txn);
    return object->client_idl_->EncodeSendTxn(txn, this);
}

bool OvsdbDBEntry::Delete() {
    if (IsNoTxnEntry()) {
        // trigger DeleteMsg with NULL pointer
        DeleteMsg(NULL);
        // trigger Post Delete, to allow post delete processing
        PostDelete();
        // return true to complete KSync State
        return true;
    }

    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::DEL_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::DEL_ACK);
    }
    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    DeleteMsg(txn);
    bool ret = object->client_idl_->EncodeSendTxn(txn, this);
    // trigger post delete if we are not waiting for Ack
    // otherwise trigger post delete on Ack
    if (ret) {
        // current transaction send completed trigger post delete
        PostDelete();
    }
    return ret;
}

bool OvsdbDBEntry::IsDataResolved() {
    return (ovs_entry_ == NULL) ? false : true;
}

bool OvsdbDBEntry::IsDelAckWaiting() {
    KSyncState state = GetState();
    return (state >= DEL_DEFER_DEL_ACK && state <= RENEW_WAIT);
}

bool OvsdbDBEntry::IsAddChangeAckWaiting() {
    KSyncState state = GetState();
    return (state == SYNC_WAIT || state == NEED_SYNC ||
            state == DEL_DEFER_SYNC);
}

void OvsdbDBEntry::NotifyAdd(struct ovsdb_idl_row *row) {
    if (ovs_entry_ == NULL) {
        ovs_entry_ = row;
    } else {
        // ovs_entry should never change from Non-NULL value to
        // another Non-NULL value.
        assert(ovs_entry_ == row);
    }
    OvsdbChange();
}

void OvsdbDBEntry::NotifyDelete(struct ovsdb_idl_row *row) {
    ovs_entry_ = NULL;
}

KSyncObject *OvsdbDBEntry::GetObject() {
    return table_;
}

void OvsdbDBEntry::Ack(bool success) {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());

    // trigger post delete for Del Ack
    if (ack_event_ == KSyncEntry::DEL_ACK) {
        // current transaction send completed trigger post delete
        PostDelete();
    }

    if (success) {
        if (IsDelAckWaiting())
            object->NotifyEvent(this, KSyncEntry::DEL_ACK);
        else if (IsAddChangeAckWaiting())
            object->NotifyEvent(this, KSyncEntry::ADD_ACK);
        else
            delete this;
    } else {
        bool trigger_ack = false;
        // On Failure try again
        if (IsDelAckWaiting()) {
            OVSDB_TRACE(Error, "Delete Transaction failed for " + ToString());
            // if we are waiting to renew, dont retry delete.
            if (GetState() != RENEW_WAIT) {
                // trigger ack when if no message to send, on calling delete
                trigger_ack = Delete();
            } else {
                trigger_ack = true;
            }

            if (trigger_ack) {
                object->NotifyEvent(this, KSyncEntry::DEL_ACK);
            }
        } else if (IsAddChangeAckWaiting()) {
            OVSDB_TRACE(Error, "Add Transaction failed for " + ToString());
            // if we are waiting to delete, dont retry add.
            if (GetState() != DEL_DEFER_SYNC) {
                // Enqueue a change before generating an ADD_ACK to keep
                // the entry in a not sync'd state.
                object->Change(this);
            }

            object->NotifyEvent(this, KSyncEntry::ADD_ACK);
        } else {
            // should never happen
            assert(0);
        }
    }
}

void OvsdbDBEntry::TriggerDeleteAdd() {
    GetObject()->SafeNotifyEvent(this, KSyncEntry::DEL_ADD_REQ);
}
<commit_msg>Fix ToR agent DELADD operation usage<commit_after>/*
 * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
 */
extern "C" {
#include <ovsdb_wrapper.h>
}
#include <ovsdb_object.h>
#include <ovsdb_entry.h>
#include <ovsdb_types.h>

using OVSDB::OvsdbEntry;
using OVSDB::OvsdbDBEntry;
using OVSDB::OvsdbObject;
using OVSDB::OvsdbDBObject;

OvsdbEntry::OvsdbEntry(OvsdbObject *table) : KSyncEntry(), table_(table),
    ovs_entry_(NULL) {
}

OvsdbEntry::OvsdbEntry(OvsdbObject *table, uint32_t index) : KSyncEntry(index),
    table_(table), ovs_entry_(NULL) {
}

OvsdbEntry::~OvsdbEntry() {
}

bool OvsdbEntry::Add() {
    return true;
}

bool OvsdbEntry::Change() {
    return true;
}

bool OvsdbEntry::Delete() {
    return true;
}

KSyncObject *OvsdbEntry::GetObject() {
    return table_;
}

void OvsdbEntry::Ack(bool success) {
    // TODO we don't handle failures for these entries
    if (!success) {
        OVSDB_TRACE(Error, "Transaction failed for " + ToString());
    }

    OvsdbObject *object = static_cast<OvsdbObject*>(GetObject());
    object->NotifyEvent(this, ack_event_);
}

OvsdbDBEntry::OvsdbDBEntry(OvsdbDBObject *table) : KSyncDBEntry(), table_(table),
    ovs_entry_(NULL) {
}

OvsdbDBEntry::OvsdbDBEntry(OvsdbDBObject *table, struct ovsdb_idl_row *ovs_entry) : KSyncDBEntry(),
    table_(table), ovs_entry_(ovs_entry) {
}

OvsdbDBEntry::~OvsdbDBEntry() {
}

bool OvsdbDBEntry::Add() {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    // trigger pre add/change only if idl is not marked deleted.
    // we should not update KSync references as, these references eventually
    // need to be released as part of delete trigger due to cleanup.
    if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
        PreAddChange();
    }

    if (IsNoTxnEntry()) {
        // trigger AddMsg with NULL pointer and return true to complete
        // KSync state
        AddMsg(NULL);
        return true;
    }

    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::ADD_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::ADD_ACK);
    }

    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    AddMsg(txn);
    return object->client_idl_->EncodeSendTxn(txn, this);
}

bool OvsdbDBEntry::Change() {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    // trigger pre add/change only if idl is not marked deleted.
    // we should not update KSync references as, these references eventually
    // need to be released as part of delete trigger due to cleanup.
    if (object->client_idl_ != NULL && !object->client_idl_->deleted()) {
        PreAddChange();
    }

    if (IsNoTxnEntry()) {
        // trigger ChangeMsg with NULL pointer and return true to complete
        // KSync state
        ChangeMsg(NULL);
        return true;
    }

    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::CHANGE_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::CHANGE_ACK);
    }

    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    ChangeMsg(txn);
    return object->client_idl_->EncodeSendTxn(txn, this);
}

bool OvsdbDBEntry::Delete() {
    if (IsNoTxnEntry()) {
        // trigger DeleteMsg with NULL pointer
        DeleteMsg(NULL);
        // trigger Post Delete, to allow post delete processing
        PostDelete();
        // return true to complete KSync State
        return true;
    }

    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
    struct ovsdb_idl_txn *txn;
    if (UseBulkTxn()) {
        txn = object->client_idl_->CreateBulkTxn(this, KSyncEntry::DEL_ACK);
    } else {
        txn = object->client_idl_->CreateTxn(this, KSyncEntry::DEL_ACK);
    }
    if (txn == NULL) {
        // failed to create transaction because of idl marked for
        // deletion return from here.
        TxnDoneNoMessage();
        return true;
    }
    DeleteMsg(txn);
    bool ret = object->client_idl_->EncodeSendTxn(txn, this);
    // trigger post delete if we are not waiting for Ack
    // otherwise trigger post delete on Ack
    if (ret) {
        // current transaction send completed trigger post delete
        PostDelete();
    }
    return ret;
}

bool OvsdbDBEntry::IsDataResolved() {
    return (ovs_entry_ == NULL) ? false : true;
}

bool OvsdbDBEntry::IsDelAckWaiting() {
    KSyncState state = GetState();
    return (state >= DEL_DEFER_DEL_ACK && state <= RENEW_WAIT);
}

bool OvsdbDBEntry::IsAddChangeAckWaiting() {
    KSyncState state = GetState();
    return (state == SYNC_WAIT || state == NEED_SYNC ||
            state == DEL_DEFER_SYNC);
}

void OvsdbDBEntry::NotifyAdd(struct ovsdb_idl_row *row) {
    if (ovs_entry_ == NULL) {
        ovs_entry_ = row;
    } else {
        // ovs_entry should never change from Non-NULL value to
        // another Non-NULL value.
        assert(ovs_entry_ == row);
    }
    OvsdbChange();
}

void OvsdbDBEntry::NotifyDelete(struct ovsdb_idl_row *row) {
    ovs_entry_ = NULL;
}

KSyncObject *OvsdbDBEntry::GetObject() {
    return table_;
}

void OvsdbDBEntry::Ack(bool success) {
    OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());

    // trigger post delete for Del Ack
    if (ack_event_ == KSyncEntry::DEL_ACK) {
        // current transaction send completed trigger post delete
        PostDelete();
    }

    if (success) {
        if (IsDelAckWaiting())
            object->NotifyEvent(this, KSyncEntry::DEL_ACK);
        else if (IsAddChangeAckWaiting())
            object->NotifyEvent(this, KSyncEntry::ADD_ACK);
        else
            delete this;
    } else {
        bool trigger_ack = false;
        // On Failure try again
        if (IsDelAckWaiting()) {
            OVSDB_TRACE(Error, "Delete Transaction failed for " + ToString());
            // if we are waiting to renew, dont retry delete.
            if (GetState() != RENEW_WAIT) {
                // trigger ack when if no message to send, on calling delete
                trigger_ack = Delete();
            } else {
                trigger_ack = true;
            }

            if (trigger_ack) {
                object->NotifyEvent(this, KSyncEntry::DEL_ACK);
            }
        } else if (IsAddChangeAckWaiting()) {
            OVSDB_TRACE(Error, "Add Transaction failed for " + ToString());
            // if we are waiting to delete, dont retry add.
            if (GetState() != DEL_DEFER_SYNC) {
                // Enqueue a change before generating an ADD_ACK to keep
                // the entry in a not sync'd state.
                object->Change(this);
            }

            object->NotifyEvent(this, KSyncEntry::ADD_ACK);
        } else {
            // should never happen
            assert(0);
        }
    }
}

void OvsdbDBEntry::TriggerDeleteAdd() {
    if (IsDeleted() || stale()) {
        // skip this operation for Deleted/stale Entry, After this operation
        // Deleted/Stale entry would become active/non-stale which is not
        // intended use of this API, caller must ensure the entry to be Active
        // if this operation is required
        return;
    }
    GetObject()->SafeNotifyEvent(this, KSyncEntry::DEL_ADD_REQ);
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_coding/neteq/tools/fake_decode_from_file.h"

#include "modules/rtp_rtcp/source/byte_io.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"

namespace webrtc {
namespace test {

int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
                                       size_t encoded_len,
                                       int sample_rate_hz,
                                       int16_t* decoded,
                                       SpeechType* speech_type) {
  if (encoded_len == 0) {
    // Decoder is asked to produce codec-internal comfort noise.
    RTC_DCHECK(!encoded);  // NetEq always sends nullptr in this case.
    RTC_DCHECK(cng_mode_);
    RTC_DCHECK_GT(last_decoded_length_, 0);
    std::fill_n(decoded, last_decoded_length_, 0);
    *speech_type = kComfortNoise;
    return rtc::dchecked_cast<int>(last_decoded_length_);
  }

  RTC_CHECK_GE(encoded_len, 12);
  uint32_t timestamp_to_decode =
      ByteReader<uint32_t>::ReadLittleEndian(encoded);
  uint32_t samples_to_decode =
      ByteReader<uint32_t>::ReadLittleEndian(&encoded[4]);
  if (samples_to_decode == 0) {
    // Number of samples in packet is unknown.
    if (last_decoded_length_ > 0) {
      // Use length of last decoded packet, but since this is the total for all
      // channels, we have to divide by 2 in the stereo case.
      samples_to_decode = rtc::dchecked_cast<int>(rtc::CheckedDivExact(
          last_decoded_length_, static_cast<size_t>(stereo_ ? 2uL : 1uL)));
    } else {
      // This is the first packet to decode, and we do not know the length of
      // it. Set it to 10 ms.
      samples_to_decode = rtc::CheckedDivExact(sample_rate_hz, 100);
    }
  }

  if (next_timestamp_from_input_ &&
      timestamp_to_decode != *next_timestamp_from_input_) {
    // A gap in the timestamp sequence is detected. Skip the same number of
    // samples from the file.
    uint32_t jump = timestamp_to_decode - *next_timestamp_from_input_;
    RTC_CHECK(input_->Seek(jump));
  }

  next_timestamp_from_input_ = timestamp_to_decode + samples_to_decode;

  uint32_t original_payload_size_bytes =
      ByteReader<uint32_t>::ReadLittleEndian(&encoded[8]);
  if (original_payload_size_bytes == 1) {
    // This is a comfort noise payload.
    RTC_DCHECK_GT(last_decoded_length_, 0);
    std::fill_n(decoded, last_decoded_length_, 0);
    *speech_type = kComfortNoise;
    cng_mode_ = true;
    return rtc::dchecked_cast<int>(last_decoded_length_);
  }

  cng_mode_ = false;
  RTC_CHECK(input_->Read(static_cast<size_t>(samples_to_decode), decoded));

  if (stereo_) {
    InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2,
                                         decoded);
    samples_to_decode *= 2;
  }

  *speech_type = kSpeech;
  last_decoded_length_ = samples_to_decode;
  return rtc::dchecked_cast<int>(last_decoded_length_);
}

void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp,
                                        size_t samples,
                                        size_t original_payload_size_bytes,
                                        rtc::ArrayView<uint8_t> encoded) {
  RTC_CHECK_GE(encoded.size(), 12);
  ByteWriter<uint32_t>::WriteLittleEndian(&encoded[0], timestamp);
  ByteWriter<uint32_t>::WriteLittleEndian(&encoded[4],
                                          rtc::checked_cast<uint32_t>(samples));
  ByteWriter<uint32_t>::WriteLittleEndian(
      &encoded[8], rtc::checked_cast<uint32_t>(original_payload_size_bytes));
}

}  // namespace test
}  // namespace webrtc
<commit_msg>Limiting increment in timestamps with neteq simulation.<commit_after>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_coding/neteq/tools/fake_decode_from_file.h"

#include "modules/rtp_rtcp/source/byte_io.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"

namespace webrtc {
namespace test {

int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded,
                                       size_t encoded_len,
                                       int sample_rate_hz,
                                       int16_t* decoded,
                                       SpeechType* speech_type) {
  if (encoded_len == 0) {
    // Decoder is asked to produce codec-internal comfort noise.
    RTC_DCHECK(!encoded);  // NetEq always sends nullptr in this case.
    RTC_DCHECK(cng_mode_);
    RTC_DCHECK_GT(last_decoded_length_, 0);
    std::fill_n(decoded, last_decoded_length_, 0);
    *speech_type = kComfortNoise;
    return rtc::dchecked_cast<int>(last_decoded_length_);
  }

  RTC_CHECK_GE(encoded_len, 12);
  uint32_t timestamp_to_decode =
      ByteReader<uint32_t>::ReadLittleEndian(encoded);
  uint32_t samples_to_decode =
      ByteReader<uint32_t>::ReadLittleEndian(&encoded[4]);
  if (samples_to_decode == 0 ||
      samples_to_decode % rtc::CheckedDivExact(sample_rate_hz, 100) != 0) {
    // Number of samples being zero or non-multiple of 10ms is considered
    // erroneous.
    if (last_decoded_length_ > 0) {
      // Use length of last decoded packet, but since this is the total for all
      // channels, we have to divide by 2 in the stereo case.
      samples_to_decode = rtc::dchecked_cast<int>(rtc::CheckedDivExact(
          last_decoded_length_, static_cast<size_t>(stereo_ ? 2uL : 1uL)));
    } else {
      // This is the first packet to decode, and we do not know the length of
      // it. Set it to 10 ms.
      samples_to_decode = rtc::CheckedDivExact(sample_rate_hz, 100);
    }
  }

  if (next_timestamp_from_input_ &&
      timestamp_to_decode != *next_timestamp_from_input_) {
    // A gap in the timestamp sequence is detected. Skip the same number of
    // samples from the file.
    uint32_t jump = timestamp_to_decode - *next_timestamp_from_input_;
    RTC_CHECK(input_->Seek(jump));
  }

  next_timestamp_from_input_ = timestamp_to_decode + samples_to_decode;

  uint32_t original_payload_size_bytes =
      ByteReader<uint32_t>::ReadLittleEndian(&encoded[8]);
  if (original_payload_size_bytes == 1) {
    // This is a comfort noise payload.
    RTC_DCHECK_GT(last_decoded_length_, 0);
    std::fill_n(decoded, last_decoded_length_, 0);
    *speech_type = kComfortNoise;
    cng_mode_ = true;
    return rtc::dchecked_cast<int>(last_decoded_length_);
  }

  cng_mode_ = false;
  RTC_CHECK(input_->Read(static_cast<size_t>(samples_to_decode), decoded));

  if (stereo_) {
    InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2,
                                         decoded);
    samples_to_decode *= 2;
  }

  *speech_type = kSpeech;
  last_decoded_length_ = samples_to_decode;
  return rtc::dchecked_cast<int>(last_decoded_length_);
}

void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp,
                                        size_t samples,
                                        size_t original_payload_size_bytes,
                                        rtc::ArrayView<uint8_t> encoded) {
  RTC_CHECK_GE(encoded.size(), 12);
  ByteWriter<uint32_t>::WriteLittleEndian(&encoded[0], timestamp);
  ByteWriter<uint32_t>::WriteLittleEndian(&encoded[4],
                                          rtc::checked_cast<uint32_t>(samples));
  ByteWriter<uint32_t>::WriteLittleEndian(
      &encoded[8], rtc::checked_cast<uint32_t>(original_payload_size_bytes));
}

}  // namespace test
}  // namespace webrtc
<|endoftext|>


<commit_before>#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pearson.h"

int T_MAX;
int mpi_my_rank;

extern Formura_Navigator navi;

float frand() {
  return rand() / float(RAND_MAX);
}

void init() {
  for(int x = navi.lower_x; x < navi.upper_x; ++x) {
    for(int y = navi.lower_y; y < navi.upper_y; ++y) {
      int x1 = x + navi.offset_x;
      int y1 = y + navi.offset_y;
      U[x][y] = 1;
      V[x][y] = 0;
    }
  }
  if(mpi_my_rank==0){
    for (int x = 18; x < 38; ++x) {
      for (int y = 58; y < 78; ++y) {
        U[x][y] = 0.5+0.01*frand();
        V[x][y] = 0.25+0.01*frand();
      }
    }
  }
}

int main (int argc, char **argv) {
  srand(time(NULL));
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);

  if (argc <= 1) {
    T_MAX=10000;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  init();

  while(navi.time_step < T_MAX) {
    if(navi.time_step % 1000 == 0) {
      printf("t = %d\n", navi.time_step);
      char fn[256];
      sprintf(fn, "frames/%06d-%d.txt", navi.time_step, mpi_my_rank);
      FILE *fp = fopen(fn,"w");
      for(int x = navi.lower_x; x < navi.upper_x; ++x) {
        for(int y = navi.lower_y; y < navi.upper_y; ++y) {
          int x1 = x + navi.offset_x;
          int y1 = y + navi.offset_y;
          fprintf(fp, "%d %d %f\n", x1, y1, U[x][y]);
        }
        fprintf(fp, "\n");
      }
      fclose(fp);
    }
    Formura_Forward(&navi);
  }
  MPI_Finalize();
}
<commit_msg>Update sampleo<commit_after>#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pearson-2d.h"

int T_MAX;
int mpi_my_rank;

extern Formura_Navigator navi;

float frand() {
  return rand() / float(RAND_MAX);
}

void init() {
  for(int x = navi.lower_x; x < navi.upper_x; ++x) {
    for(int y = navi.lower_y; y < navi.upper_y; ++y) {
      int x1 = x + navi.offset_x;
      int y1 = y + navi.offset_y;
      U[x][y] = 1;
      V[x][y] = 0;
    }
  }
  if(mpi_my_rank==0){
    for (int x = 18; x < 38; ++x) {
      for (int y = 58; y < 78; ++y) {
        U[x][y] = 0.5+0.01*frand();
        V[x][y] = 0.25+0.01*frand();
      }
    }
  }
}

int main (int argc, char **argv) {
  srand(time(NULL));
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);

  if (argc <= 1) {
    T_MAX=10000;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  init();

  while(navi.time_step < T_MAX) {
    if(navi.time_step % 1000 == 0) {
      printf("t = %d\n", navi.time_step);
      char fn[256];
      sprintf(fn, "frames/%06d-%d.txt", navi.time_step, mpi_my_rank);
      FILE *fp = fopen(fn,"w");
      for(int x = navi.lower_x; x < navi.upper_x; ++x) {
        for(int y = navi.lower_y; y < navi.upper_y; ++y) {
          int x1 = x + navi.offset_x;
          int y1 = y + navi.offset_y;
          fprintf(fp, "%d %d %f\n", x1, y1, U[x][y]);
        }
        fprintf(fp, "\n");
      }
      fclose(fp);
    }
    Formura_Forward(&navi);
  }
  MPI_Finalize();
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        double x = double(navi.offset_x + ix)/NX;
        double y = double(navi.offset_y + iy)/NY;
        double z = double(navi.offset_z + iz)/NZ;
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
}*/

typedef pair<int,pair<int,int> > Key;
void init() {
  map<Key ,double> seeds;
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
    for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
      for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
        Key k (ix/16, pair<int,int>(iy/16, iz/16));
        U[ix][iy][iz] = 1.0;
        V[ix][iy][iz] = 0.0;
        double s = seeds[k];
        if (s==0) {
          s = frand();
          seeds[k]=s;
        }
        if (s < 0.1 ) {
          U[ix][iy][iz] = 0.5;
          V[ix][iy][iz] = 0.25;
        }
      }
    }
  }
  }

void write_monitor() {
  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x == 0) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y == 0) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char benchmark_name[256];
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      if(mpi_my_rank==0){
        printf("marked %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      write_monitor();
      if(mpi_my_rank==0){
        printf("monitor %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        //start_collection(benchmark_name);
        fapp_start(benchmark_name, 0,0);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      //start_collection(benchmark_name);
      fapp_start(benchmark_name, 0,0);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      //stop_collection(benchmark_name);
      fapp_stop(benchmark_name, 0,0);
    }
  }
  printf("total wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<commit_msg>Neat initial condition for demonstration purpose run.<commit_after>#include <algorithm>
#include <map>
#include <math.h>
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>

#include <fj_tool/fapp.h>
#include <fjcoll.h>

using namespace std;

#include "pearson-3d.h"

bool EXTEND_MISSION=false;
int T_MAX;
int T_MONITOR;
int mpi_my_rank;
const double PI=3.14159265358979323846;

float frand() {
  return rand() / float(RAND_MAX);
}

double wctime() {
  struct timeval tv;
  gettimeofday(&tv,NULL);
  return (double)tv.tv_sec + (double)tv.tv_usec*1e-6;
}
/*
  void init() {
  for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
  for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
  for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
  double x = double(navi.offset_x + ix)/NX;
  double y = double(navi.offset_y + iy)/NY;
  double z = double(navi.offset_z + iz)/NZ;
  U[ix][iy][iz] = 1.0;
  V[ix][iy][iz] = 0.0;
  if (z > 0.49 && z < 0.51 && x > 0.4 && x < 0.6) {
  U[ix][iy][iz] = 0.5;
  V[ix][iy][iz] = 0.25;
  }
  }
  }
  }
  }*/

typedef pair<int,pair<int,int> > Key;
void init() {
  if (NZ<500){
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          int kx=ix/5*5, ky=iy/5*5, kz=iz/5*5;
          if(ky==125){
            if(kz==75 && kx==220 ||
               kz==100 && kx == 80 ||
               kz==150 && kx==150){
              U[ix][iy][iz] = 0.5;
              V[ix][iy][iz] = 0.5;
            }
          }
        }
      }
    }
  }else{
    map<Key ,double> seeds;
    for(int ix = navi.lower_x; ix < navi.upper_x; ++ix) {
      for(int iy = navi.lower_y; iy < navi.upper_y; ++iy) {
        for(int iz = navi.lower_z; iz < navi.upper_z; ++iz) {
          Key k (ix/16, pair<int,int>(iy/16, iz/16));
          U[ix][iy][iz] = 1.0;
          V[ix][iy][iz] = 0.0;
          double s = seeds[k];
          if (s==0) {
            s = frand();
            seeds[k]=s;
          }
          if (s < 0.1 ) {
            U[ix][iy][iz] = 0.5;
            V[ix][iy][iz] = 0.25;
          }
        }
      }
    }
  }
}
void write_monitor() {
  int global_position[6];
  global_position[0] = navi.offset_x + navi.lower_x;
  global_position[1] = navi.offset_y + navi.lower_y;
  global_position[2] = navi.offset_z + navi.lower_z;
  global_position[3] = navi.upper_x - navi.lower_x;
  global_position[4] = navi.upper_y - navi.lower_y;
  global_position[5] = navi.upper_z - navi.lower_z;
  int x_size = navi.upper_x - navi.lower_x;
  int y_size = navi.upper_y - navi.lower_y;
  int z_size = navi.upper_z - navi.lower_z;

  if (navi.offset_x + navi.lower_x == 0) {
    char fn[256];
    sprintf(fn, "out/monitorX-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int x=navi.lower_x + x_size/2;
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int y = navi.lower_y; y < navi.upper_y; ++y) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

  if (navi.offset_y + navi.lower_y == 0) {
    char fn[256];
    sprintf(fn, "out/monitorY-%06d-%d.txt", navi.time_step, mpi_my_rank);

    FILE *fp = fopen(fn,"wb");
    fwrite(global_position, sizeof(int), 6, fp);
    {
      const int y=navi.lower_y + y_size/2;
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(U[x][y]+navi.lower_z, sizeof(double),z_size, fp);
      for(int x = navi.lower_x; x < navi.upper_x; ++x) fwrite(V[x][y]+navi.lower_z, sizeof(double),z_size, fp);
    }
    fclose(fp);
  }

}

int main (int argc, char **argv) {
  MPI_Init(&argc, &argv);
  Formura_Init(&navi, MPI_COMM_WORLD);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_my_rank);
  srand(time(NULL)+mpi_my_rank*65537);

  if (argc <= 1) {
    T_MAX=8192;
  }else{
    sscanf(argv[1], "%d",  &T_MAX);
  }
  if (argc <= 2) {
    T_MONITOR=8192;
  }else{
    sscanf(argv[2], "%d",  &T_MONITOR);
  }
  if (argc >= 4) {
    EXTEND_MISSION = true;
  }

  init();

  double t_begin = wctime(), t_end;

  int last_monitor_t = -T_MONITOR;
  char benchmark_name[256];
  sprintf(benchmark_name,"main");
  for(;;){
    double t = wctime();
    bool monitor_flag = navi.time_step >= last_monitor_t + T_MONITOR;
    if(monitor_flag || navi.time_step <= 3 * T_MONITOR ) {
      if(mpi_my_rank==0){
        printf("marked %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      write_monitor();
      if(mpi_my_rank==0){
        printf("monitor %d step @ %lf sec\n", navi.time_step, t-t_begin);
      }
    }
    if(monitor_flag) {
      last_monitor_t += T_MONITOR;
    }

    if (navi.time_step >= T_MAX) {
      if (EXTEND_MISSION){
        T_MAX*=2;
        T_MONITOR*=2;
        sprintf(benchmark_name,"extend-%d",T_MAX);
        //start_collection(benchmark_name);
        fapp_start(benchmark_name, 0,0);
      }else{
        break;
      }

    }
    if (navi.time_step == 0) {
      t_begin = wctime();
      //start_collection(benchmark_name);
      fapp_start(benchmark_name, 0,0);
    }

    Formura_Forward(&navi); // navi.time_step increases
    MPI_Barrier(MPI_COMM_WORLD); // TODO: test the effect of synchronization

    if (navi.time_step >= T_MAX) {
      t_end = wctime();
      //stop_collection(benchmark_name);
      fapp_stop(benchmark_name, 0,0);
    }
  }
  printf("total wct = %lf sec\n",t_end - t_begin);

  MPI_Barrier(MPI_COMM_WORLD);
  MPI_Finalize();
}
<|endoftext|>


<commit_before>
/* ========================================

   * File Name : 16.cpp

   * Creation Date : 09-08-2020

   * Last Modified : Út 11. srpna 2020, 14:05:18

   * Created By : Karel Ha <mathemage@gmail.com>

   * URL : https://www.facebook.com/codingcompetitions/hacker-cup/2019/round-1/problems/B

   * Points Gained (in case of online contest) :

   ==========================================*/

#include <bits/stdc++.h>

using namespace std;

#define REP(I,N)   FOR(I,0,N)
#define FOR(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define ALL(A)     (A).begin(), (A).end()
#define MSG(a) cout << #a << " == " << (a) << endl;

const int CLEAN = -1;

template <typename T>
string NumberToString ( T Number ) {
  ostringstream ss;
  ss << Number;
  return ss.str();
}

#define ERR(args...) { vector<string> _v = split(#args, ','); err(_v.begin(), args); }
vector<string> split(const string& s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
void err(vector<string>::iterator it) {}
template<typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cout << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << endl;
  err(++it, args...);
}

#define MOD 1000000007
#define UNDEF MOD
#define N_MAX 1000000

vector<int> powers(N_MAX + 1, UNDEF);

int mod_power(int base, int exp) {
  powers[0] = 1;
  FOR(i, 1, exp + 1) {
    if (powers[i] == UNDEF) {
      powers[i] = (powers[i-1] * base) % MOD;
//       cout << endl; MSG(i) MSG(powers[i])
    }
  }
  return powers[exp + 1];
}

int get_result(const string & V, int K) {
  int N = V.size();

  int init_balance = 0;    // n_B - n_A
  int balance = -2 * N;    // i.e. -INF
  FOR(i, N-K, N) {
    init_balance += (V[i] == 'A') ? (-1) : 1;
    balance = max(balance, init_balance);
  }
//   MSG(balance)

  int result = 0;
  FOR(j, N-K, 0) {
//     MSG(j)
    balance += (V[j] == 'A') ? (-1) : 1;

    if (balance > K) {                  // over threshold
      balance -= 2;                     // swap 'B' for 'A'
      result += mod_power(2, j + 1);    // pay the charge
      result %= MOD;                    // TODO: use memo table of pows
    }
  }

  return result;
}

int main() {
  int T;
  cin >> T;
//   MSG(T)

  REP(t,T) {
    int N, K;
    cin >> N >> K;
//     MSG(N) MSG(K)

    string V;
    V.reserve(N);
    cin >> V;
//     MSG(V) cout << endl;

    cout << "Case #" << t+1 << ": " << get_result(V, K) << endl;
  }

  return 0;
}
<commit_msg>Fix: Off-1 error in return of mod_power()<commit_after>
/* ========================================

   * File Name : 16.cpp

   * Creation Date : 09-08-2020

   * Last Modified : Út 11. srpna 2020, 19:06:09

   * Created By : Karel Ha <mathemage@gmail.com>

   * URL : https://www.facebook.com/codingcompetitions/hacker-cup/2019/round-1/problems/B

   * Points Gained (in case of online contest) :

   ==========================================*/

#include <bits/stdc++.h>

using namespace std;

#define REP(I,N)   FOR(I,0,N)
#define FOR(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define ALL(A)     (A).begin(), (A).end()
#define MSG(a) cout << #a << " == " << (a) << endl;

const int CLEAN = -1;

template <typename T>
string NumberToString ( T Number ) {
  ostringstream ss;
  ss << Number;
  return ss.str();
}

#define ERR(args...) { vector<string> _v = split(#args, ','); err(_v.begin(), args); }
vector<string> split(const string& s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
void err(vector<string>::iterator it) {}
template<typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cout << it -> substr((*it)[0] == ' ', it -> length()) << " = " << a << endl;
  err(++it, args...);
}

#define MOD 1000000007
#define UNDEF MOD
#define N_MAX 1000000

vector<int> powers(N_MAX + 1, UNDEF);

int mod_power(int base, int exp) {
  powers[0] = 1;
  FOR(i, 1, exp + 1) {
    if (powers[i] == UNDEF) {
      powers[i] = (powers[i-1] * base) % MOD;
//       cout << endl; MSG(i) MSG(powers[i])
    }
  }
  return powers[exp];
}

int get_result(const string & V, int K) {
  int N = V.size();

  int init_balance = 0;    // n_B - n_A
  int balance = 0;
  FOR(i, N-K, N) {
    init_balance += (V[i] == 'A') ? (-1) : 1;
    balance = max(balance, init_balance);
//     MSG(init_balance)
  }
//   cout << endl << "inital balance: "; MSG(balance)

  int result = 0;
  FOR(j, N-K, 0) {
//     MSG(j) MSG(V[j])
//     cout << "0: "; MSG(balance)
    balance = max(balance, 0);
    balance += (V[j] == 'A') ? (-1) : 1;
//     cout << "1: "; MSG(balance) MSG(result)

    if (balance > K) {                  // over threshold
      balance -= 2;                     // swap 'B' for 'A'
      result += mod_power(2, j + 1);    // pay the charge
//       MSG(mod_power(2, j + 1))
      result %= MOD;                    // TODO: use memo table of pows
    }
//     cout << "2: "; MSG(balance) MSG(result)
  }

  return result;
}

int main() {
  int T;
  cin >> T;
//   MSG(T)

  REP(t,T) {
    int N, K;
    cin >> N >> K;
//     MSG(N) MSG(K)

    string V;
    V.reserve(N);
    cin >> V;
//     MSG(V) cout << endl;

    cout << "Case #" << t+1 << ": " << get_result(V, K) << endl;
  }

  return 0;
}
<|endoftext|>


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

#ifndef _SDR_CONTACT_OBJECTCONTACTOFOBJLISTPAINTER_HXX
#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
#endif

#ifndef _SDR_CONTACT_DISPLAYINFO_HXX
#include <svx/sdr/contact/displayinfo.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#include <svx/sdr/contact/viewobjectcontact.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

#ifndef _SVDOBJ_HXX
#include <svdobj.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SVDMODEL_HXX
#include <svdmodel.hxx>
#endif

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

namespace sdr
{
    namespace contact
    {
        ObjectContactPainter::ObjectContactPainter(sal_Bool bBufferingAllowed)
        :   mbIsInitialized(sal_False),
            mbBufferingAllowed(bBufferingAllowed)
        {
        }

        // The destructor.
        ObjectContactPainter::~ObjectContactPainter()
        {
        }

        // Update Draw Hierarchy data
        void ObjectContactPainter::EnsureValidDrawHierarchy(DisplayInfo& rDisplayInfo)
        {
            const sal_uInt32 nCount(maDrawHierarchy.Count());

            // #i35614#
            if(mbIsInitialized && !nCount)
            {
                // DrawHierarchy is not only invalid, but also completely
                // removed. Thus, we need to change the mbIsInitialized flag
                // to express that state.
                mbIsInitialized = sal_False;
            }

            if(mbIsInitialized)
            {
                // no new StartPoint, is the invalid flag set which means
                // somewhere the sub-hierarchy is invalid?
                if(!IsDrawHierarchyValid())
                {
                    // Yes, check the sub-hierarchies

                    for(sal_uInt32 a(0L); a < nCount; a++)
                    {
                        ViewObjectContact& rVOContact = *(maDrawHierarchy.GetObject(a));

                        rVOContact.CheckDrawHierarchy(*this);
                    }
                }
            }
            else
            {
                // build new hierarchy
                const sal_uInt32 nCount(GetPaintObjectCount());

                for(sal_uInt32 a(0L); a < nCount; a++)
                {
                    ViewContact& rViewContact = GetPaintObjectViewContact(a);
                    ViewObjectContact& rViewObjectContact = rViewContact.GetViewObjectContact(*this);

                    // set parent at ViewObjectContact
                    rViewObjectContact.SetParent(0L);

                    // build sub-hierarchy
                    if(rViewContact.GetObjectCount())
                    {
                        rViewObjectContact.BuildDrawHierarchy(*this, rViewContact);
                    }

                    // Add to list
                    maDrawHierarchy.Append(&rViewObjectContact);
                }

                // remember to be initialized
                mbIsInitialized = sal_True;
            }

            // set DrawHierarchy valid
            mbDrawHierarchyValid = sal_True;
        }

        // Process the whole displaying
        void ObjectContactPainter::ProcessDisplay(DisplayInfo& rDisplayInfo)
        {
            if( mbIsInitialized
                && IsDrawHierarchyValid()
                && rDisplayInfo.GetPaintInfoRec()
                && rDisplayInfo.GetOutputDevice()
                && GetPaintObjectCount())
            {
                // This class is normally used for producing a single output. Thus,
                // buffering makes no sense and is switched off here.
                rDisplayInfo.SetBufferingAllowed(mbBufferingAllowed);

                // Paint Hierarchy
                for(sal_uInt32 a(0L); a < maDrawHierarchy.Count(); a++)
                {
                    ViewObjectContact& rViewObjectContact = *(maDrawHierarchy.GetObject(a));

                    // paint Hierarchy
                    rViewObjectContact.PaintObjectHierarchy(rDisplayInfo);
                }
            }
        }
    } // end of namespace contact
} // end of namespace sdr

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

namespace sdr
{
    namespace contact
    {
        sal_uInt32 ObjectContactOfObjListPainter::GetPaintObjectCount() const
        {
            return maStartObjects.size();
        }

        ViewContact& ObjectContactOfObjListPainter::GetPaintObjectViewContact(sal_uInt32 nIndex) const
        {
            SdrObject* pObj = maStartObjects[nIndex];
            DBG_ASSERT(pObj, "ObjectContactOfObjListPainter::EnsureValidDrawHierarchy: Corrupt SdrObjectVector (!)");
            return pObj->GetViewContact();
        }

        ObjectContactOfObjListPainter::ObjectContactOfObjListPainter(
            const SdrObjectVector& rObjects,
            sal_Bool bBufferingAllowed)
        :   ObjectContactPainter(bBufferingAllowed),
            maStartObjects(rObjects)
        {
        }

        ObjectContactOfObjListPainter::~ObjectContactOfObjListPainter()
        {
        }
    } // end of namespace contact
} // end of namespace sdr

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

namespace sdr
{
    namespace contact
    {
        sal_uInt32 ObjectContactOfPagePainter::GetPaintObjectCount() const
        {
            return 1L;
        }

        ViewContact& ObjectContactOfPagePainter::GetPaintObjectViewContact(sal_uInt32 nIndex) const
        {
            DBG_ASSERT(mpStartPage,
                "ObjectContactOfPagePainter::GetPaintObjectViewContact: no mpStartPage set (!)");
            return mpStartPage->GetViewContact();
        }

        ObjectContactOfPagePainter::ObjectContactOfPagePainter(
            const SdrPage* pPage,
            sal_Bool bBufferingAllowed)
        :   ObjectContactPainter(bBufferingAllowed),
            mpStartPage(pPage)
        {
        }

        ObjectContactOfPagePainter::~ObjectContactOfPagePainter()
        {
        }

        void ObjectContactOfPagePainter::SetStartPage(const SdrPage* pPage)
        {
            if(pPage && pPage != mpStartPage)
            {
                ClearDrawHierarchy();
                mpStartPage = pPage;
                mbIsInitialized = sal_False;
            }
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS warnings01 (1.5.220); FILE MERGED 2006/02/21 16:41:10 aw 1.5.220.1: #i55991# Adaptions to warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objectcontactofobjlistpainter.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 16:25:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_OBJECTCONTACTOFOBJLISTPAINTER_HXX
#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
#endif

#ifndef _SDR_CONTACT_DISPLAYINFO_HXX
#include <svx/sdr/contact/displayinfo.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#include <svx/sdr/contact/viewobjectcontact.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

#ifndef _SVDOBJ_HXX
#include <svdobj.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SVDMODEL_HXX
#include <svdmodel.hxx>
#endif

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

namespace sdr
{
    namespace contact
    {
        ObjectContactPainter::ObjectContactPainter(sal_Bool bBufferingAllowed)
        :   mbIsInitialized(sal_False),
            mbBufferingAllowed(bBufferingAllowed)
        {
        }

        // The destructor.
        ObjectContactPainter::~ObjectContactPainter()
        {
        }

        // Update Draw Hierarchy data
        void ObjectContactPainter::EnsureValidDrawHierarchy(DisplayInfo& /*rDisplayInfo*/)
        {
            const sal_uInt32 nCount(maDrawHierarchy.Count());

            // #i35614#
            if(mbIsInitialized && !nCount)
            {
                // DrawHierarchy is not only invalid, but also completely
                // removed. Thus, we need to change the mbIsInitialized flag
                // to express that state.
                mbIsInitialized = sal_False;
            }

            if(mbIsInitialized)
            {
                // no new StartPoint, is the invalid flag set which means
                // somewhere the sub-hierarchy is invalid?
                if(!IsDrawHierarchyValid())
                {
                    // Yes, check the sub-hierarchies

                    for(sal_uInt32 a(0L); a < nCount; a++)
                    {
                        ViewObjectContact& rVOContact = *(maDrawHierarchy.GetObject(a));

                        rVOContact.CheckDrawHierarchy(*this);
                    }
                }
            }
            else
            {
                // build new hierarchy
                const sal_uInt32 nCount2(GetPaintObjectCount());

                for(sal_uInt32 a(0L); a < nCount2; a++)
                {
                    ViewContact& rViewContact = GetPaintObjectViewContact(a);
                    ViewObjectContact& rViewObjectContact = rViewContact.GetViewObjectContact(*this);

                    // set parent at ViewObjectContact
                    rViewObjectContact.SetParent(0L);

                    // build sub-hierarchy
                    if(rViewContact.GetObjectCount())
                    {
                        rViewObjectContact.BuildDrawHierarchy(*this, rViewContact);
                    }

                    // Add to list
                    maDrawHierarchy.Append(&rViewObjectContact);
                }

                // remember to be initialized
                mbIsInitialized = sal_True;
            }

            // set DrawHierarchy valid
            mbDrawHierarchyValid = sal_True;
        }

        // Process the whole displaying
        void ObjectContactPainter::ProcessDisplay(DisplayInfo& rDisplayInfo)
        {
            if( mbIsInitialized
                && IsDrawHierarchyValid()
                && rDisplayInfo.GetPaintInfoRec()
                && rDisplayInfo.GetOutputDevice()
                && GetPaintObjectCount())
            {
                // This class is normally used for producing a single output. Thus,
                // buffering makes no sense and is switched off here.
                rDisplayInfo.SetBufferingAllowed(mbBufferingAllowed);

                // Paint Hierarchy
                for(sal_uInt32 a(0L); a < maDrawHierarchy.Count(); a++)
                {
                    ViewObjectContact& rViewObjectContact = *(maDrawHierarchy.GetObject(a));

                    // paint Hierarchy
                    rViewObjectContact.PaintObjectHierarchy(rDisplayInfo);
                }
            }
        }
    } // end of namespace contact
} // end of namespace sdr

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

namespace sdr
{
    namespace contact
    {
        sal_uInt32 ObjectContactOfObjListPainter::GetPaintObjectCount() const
        {
            return maStartObjects.size();
        }

        ViewContact& ObjectContactOfObjListPainter::GetPaintObjectViewContact(sal_uInt32 nIndex) const
        {
            SdrObject* pObj = maStartObjects[nIndex];
            DBG_ASSERT(pObj, "ObjectContactOfObjListPainter::EnsureValidDrawHierarchy: Corrupt SdrObjectVector (!)");
            return pObj->GetViewContact();
        }

        ObjectContactOfObjListPainter::ObjectContactOfObjListPainter(
            const SdrObjectVector& rObjects,
            sal_Bool bBufferingAllowed)
        :   ObjectContactPainter(bBufferingAllowed),
            maStartObjects(rObjects)
        {
        }

        ObjectContactOfObjListPainter::~ObjectContactOfObjListPainter()
        {
        }
    } // end of namespace contact
} // end of namespace sdr

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

namespace sdr
{
    namespace contact
    {
        sal_uInt32 ObjectContactOfPagePainter::GetPaintObjectCount() const
        {
            return 1L;
        }

        ViewContact& ObjectContactOfPagePainter::GetPaintObjectViewContact(sal_uInt32 /*nIndex*/) const
        {
            DBG_ASSERT(mpStartPage,
                "ObjectContactOfPagePainter::GetPaintObjectViewContact: no mpStartPage set (!)");
            return mpStartPage->GetViewContact();
        }

        ObjectContactOfPagePainter::ObjectContactOfPagePainter(
            const SdrPage* pPage,
            sal_Bool bBufferingAllowed)
        :   ObjectContactPainter(bBufferingAllowed),
            mpStartPage(pPage)
        {
        }

        ObjectContactOfPagePainter::~ObjectContactOfPagePainter()
        {
        }

        void ObjectContactOfPagePainter::SetStartPage(const SdrPage* pPage)
        {
            if(pPage && pPage != mpStartPage)
            {
                ClearDrawHierarchy();
                mpStartPage = pPage;
                mbIsInitialized = sal_False;
            }
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>/*
    Copyright (c) 2008 Bertjan Broeksema <b.broeksema@kdemail.org>
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "singlefileresourceconfigdialogbase.h"

#include <KConfigDialogManager>
#include <KFileItem>
#include <KIO/Job>
#include <KWindowSystem>

#include <QTimer>

using namespace Akonadi;

SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase( WId windowId ) :
    KDialog(), mStatJob( 0 ), mDirUrlChecked( false )
{
  ui.setupUi( mainWidget() );
  ui.kcfg_Path->setMode( KFile::File );
  ui.statusLabel->setVisible( false );
  setButtons( Ok | Cancel );

  if ( windowId )
    KWindowSystem::setMainWindow( this, windowId );

  connect( this, SIGNAL(okClicked()), SLOT(save()) );

  connect( ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(validate()) );
  connect( ui.kcfg_ReadOnly, SIGNAL(toggled(bool)), SLOT(validate()) );
  connect( ui.kcfg_MonitorFile, SIGNAL(toggled(bool)), SLOT(validate()) );

  QTimer::singleShot( 0, this, SLOT(validate()) );
}

void SingleFileResourceConfigDialogBase::addPage( const QString &title, QWidget *page )
{
  ui.ktabwidget->addTab( page, title );
  mManager->updateWidgets();
}

void SingleFileResourceConfigDialogBase::setFilter(const QString & filter)
{
  ui.kcfg_Path->setFilter( filter );
}

void SingleFileResourceConfigDialogBase::validate()
{
  const KUrl currentUrl = ui.kcfg_Path->url();
  if ( currentUrl.isEmpty() ) {
    enableButton( Ok, false );
    return;
  }

  if ( currentUrl.isLocalFile() ) {
    ui.kcfg_MonitorFile->setEnabled( true );
    ui.statusLabel->setVisible( false );

    const QFileInfo file( currentUrl.path() );
    if ( file.exists() && !file.isWritable() ) {
      ui.kcfg_ReadOnly->setEnabled( false );
      ui.kcfg_ReadOnly->setChecked( true );
    } else {
      ui.kcfg_ReadOnly->setEnabled( true );
    }
    enableButton( Ok, true );
  } else {
    ui.kcfg_MonitorFile->setEnabled( false );
    ui.statusLabel->setText( i18nc( "@info:status", "Checking file information..." ) );
    ui.statusLabel->setVisible( true );

    if ( mStatJob )
      mStatJob->kill();

    mStatJob = KIO::stat( currentUrl, KIO::DefaultFlags | KIO::HideProgressInfo );
    mStatJob->setDetails( 2 ); // All details.
    mStatJob->setSide( KIO::StatJob::SourceSide );

    connect( mStatJob, SIGNAL( result( KJob * ) ),
             SLOT( slotStatJobResult( KJob * ) ) );

    // Disable the button until the MetaJob is finished.
    enableButton( Ok, false );
  }
}

void SingleFileResourceConfigDialogBase::slotStatJobResult( KJob* job )
{
  if ( job->error() == KIO::ERR_DOES_NOT_EXIST && !mDirUrlChecked ) {
    // The file did not exists, so let's see if the directory the file should
    // reside supports writing.
    const KUrl dirUrl = ui.kcfg_Path->url().upUrl();

    mStatJob = KIO::stat( dirUrl, KIO::DefaultFlags | KIO::HideProgressInfo );
    mStatJob->setDetails( 2 ); // All details.
    mStatJob->setSide( KIO::StatJob::SourceSide );

    connect( mStatJob, SIGNAL( result( KJob * ) ),
             SLOT( slotStatJobResult( KJob * ) ) );

    // Make sure we don't check the whole path upwards.
    mDirUrlChecked = true;
    return;
  } else if ( job->error() ) {
    // It doesn't seem possible to read nor write from the location so leave the
    // ok button disabled
    ui.statusLabel->setVisible( false );
    enableButton( Ok, false );
    mDirUrlChecked = false;
    mStatJob = 0;
    return;
  }

  KIO::StatJob* statJob = qobject_cast<KIO::StatJob *>( job );
  const KFileItem item( statJob->statResult(), KUrl() );

  if ( item.isWritable() ) {
    ui.kcfg_ReadOnly->setEnabled( true );
  } else {
    ui.kcfg_ReadOnly->setEnabled( false );
    ui.kcfg_ReadOnly->setChecked( true );
  }

  ui.statusLabel->setVisible( false );
  enableButton( Ok, true );

  mDirUrlChecked = false;
  mStatJob = 0;
}
<commit_msg>Make the manager aware of the added page.<commit_after>/*
    Copyright (c) 2008 Bertjan Broeksema <b.broeksema@kdemail.org>
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "singlefileresourceconfigdialogbase.h"

#include <KConfigDialogManager>
#include <KFileItem>
#include <KIO/Job>
#include <KWindowSystem>

#include <QTimer>

using namespace Akonadi;

SingleFileResourceConfigDialogBase::SingleFileResourceConfigDialogBase( WId windowId ) :
    KDialog(), mStatJob( 0 ), mDirUrlChecked( false )
{
  ui.setupUi( mainWidget() );
  ui.kcfg_Path->setMode( KFile::File );
  ui.statusLabel->setVisible( false );
  setButtons( Ok | Cancel );

  if ( windowId )
    KWindowSystem::setMainWindow( this, windowId );

  connect( this, SIGNAL(okClicked()), SLOT(save()) );

  connect( ui.kcfg_Path, SIGNAL(textChanged(QString)), SLOT(validate()) );
  connect( ui.kcfg_ReadOnly, SIGNAL(toggled(bool)), SLOT(validate()) );
  connect( ui.kcfg_MonitorFile, SIGNAL(toggled(bool)), SLOT(validate()) );

  QTimer::singleShot( 0, this, SLOT(validate()) );
}

void SingleFileResourceConfigDialogBase::addPage( const QString &title, QWidget *page )
{
  ui.ktabwidget->addTab( page, title );
  mManager->addWidget( page );
  mManager->updateWidgets();
}

void SingleFileResourceConfigDialogBase::setFilter(const QString & filter)
{
  ui.kcfg_Path->setFilter( filter );
}

void SingleFileResourceConfigDialogBase::validate()
{
  const KUrl currentUrl = ui.kcfg_Path->url();
  if ( currentUrl.isEmpty() ) {
    enableButton( Ok, false );
    return;
  }

  if ( currentUrl.isLocalFile() ) {
    ui.kcfg_MonitorFile->setEnabled( true );
    ui.statusLabel->setVisible( false );

    const QFileInfo file( currentUrl.path() );
    if ( file.exists() && !file.isWritable() ) {
      ui.kcfg_ReadOnly->setEnabled( false );
      ui.kcfg_ReadOnly->setChecked( true );
    } else {
      ui.kcfg_ReadOnly->setEnabled( true );
    }
    enableButton( Ok, true );
  } else {
    ui.kcfg_MonitorFile->setEnabled( false );
    ui.statusLabel->setText( i18nc( "@info:status", "Checking file information..." ) );
    ui.statusLabel->setVisible( true );

    if ( mStatJob )
      mStatJob->kill();

    mStatJob = KIO::stat( currentUrl, KIO::DefaultFlags | KIO::HideProgressInfo );
    mStatJob->setDetails( 2 ); // All details.
    mStatJob->setSide( KIO::StatJob::SourceSide );

    connect( mStatJob, SIGNAL( result( KJob * ) ),
             SLOT( slotStatJobResult( KJob * ) ) );

    // Disable the button until the MetaJob is finished.
    enableButton( Ok, false );
  }
}

void SingleFileResourceConfigDialogBase::slotStatJobResult( KJob* job )
{
  if ( job->error() == KIO::ERR_DOES_NOT_EXIST && !mDirUrlChecked ) {
    // The file did not exists, so let's see if the directory the file should
    // reside supports writing.
    const KUrl dirUrl = ui.kcfg_Path->url().upUrl();

    mStatJob = KIO::stat( dirUrl, KIO::DefaultFlags | KIO::HideProgressInfo );
    mStatJob->setDetails( 2 ); // All details.
    mStatJob->setSide( KIO::StatJob::SourceSide );

    connect( mStatJob, SIGNAL( result( KJob * ) ),
             SLOT( slotStatJobResult( KJob * ) ) );

    // Make sure we don't check the whole path upwards.
    mDirUrlChecked = true;
    return;
  } else if ( job->error() ) {
    // It doesn't seem possible to read nor write from the location so leave the
    // ok button disabled
    ui.statusLabel->setVisible( false );
    enableButton( Ok, false );
    mDirUrlChecked = false;
    mStatJob = 0;
    return;
  }

  KIO::StatJob* statJob = qobject_cast<KIO::StatJob *>( job );
  const KFileItem item( statJob->statResult(), KUrl() );

  if ( item.isWritable() ) {
    ui.kcfg_ReadOnly->setEnabled( true );
  } else {
    ui.kcfg_ReadOnly->setEnabled( false );
    ui.kcfg_ReadOnly->setChecked( true );
  }

  ui.statusLabel->setVisible( false );
  enableButton( Ok, true );

  mDirUrlChecked = false;
  mStatJob = 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/common/trajectory/trajectory_stitcher.h"

#include <algorithm>
#include <list>
#include <utility>

#include "cyber/common/log.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/math/angle.h"
#include "modules/common/math/quaternion.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::TrajectoryPoint;
using apollo::common::VehicleState;
using apollo::common::math::Vec2d;
using apollo::common::util::DistanceXY;

std::vector<TrajectoryPoint>
TrajectoryStitcher::ComputeReinitStitchingTrajectory(
    const VehicleState& vehicle_state) {
  TrajectoryPoint init_point;
  init_point.mutable_path_point()->set_s(0.0);
  init_point.mutable_path_point()->set_x(vehicle_state.x());
  init_point.mutable_path_point()->set_y(vehicle_state.y());
  init_point.mutable_path_point()->set_z(vehicle_state.z());
  init_point.mutable_path_point()->set_theta(vehicle_state.heading());
  init_point.mutable_path_point()->set_kappa(vehicle_state.kappa());
  init_point.set_v(vehicle_state.linear_velocity());
  init_point.set_a(vehicle_state.linear_acceleration());
  init_point.set_relative_time(0.0);

  return std::vector<TrajectoryPoint>(1, init_point);
}

// only used in navigation mode
void TrajectoryStitcher::TransformLastPublishedTrajectory(
    const double x_diff, const double y_diff, const double theta_diff,
    PublishableTrajectory* prev_trajectory) {
  if (!prev_trajectory) {
    return;
  }

  // R^-1
  double cos_theta = std::cos(theta_diff);
  double sin_theta = -std::sin(theta_diff);

  // -R^-1 * t
  auto tx = -(cos_theta * x_diff - sin_theta * y_diff);
  auto ty = -(sin_theta * x_diff + cos_theta * y_diff);

  std::for_each(prev_trajectory->trajectory_points().begin(),
                prev_trajectory->trajectory_points().end(),
                [&cos_theta, &sin_theta, &tx, &ty,
                 &theta_diff](common::TrajectoryPoint& p) {
                  auto x = p.path_point().x();
                  auto y = p.path_point().y();
                  auto theta = p.path_point().theta();

                  auto x_new = cos_theta * x - sin_theta * y + tx;
                  auto y_new = sin_theta * x + cos_theta * y + ty;
                  auto theta_new = common::math::WrapAngle(theta - theta_diff);

                  p.mutable_path_point()->set_x(x_new);
                  p.mutable_path_point()->set_y(y_new);
                  p.mutable_path_point()->set_theta(theta_new);
                });
}

/* Planning from current vehicle state if:
   1. the auto-driving mode is off
   (or) 2. we don't have the trajectory from last planning cycle
   (or) 3. the position deviation from actual and target is too high
*/
std::vector<TrajectoryPoint> TrajectoryStitcher::ComputeStitchingTrajectory(
    const VehicleState& vehicle_state, const double current_timestamp,
    const double planning_cycle_time,
    const PublishableTrajectory* prev_trajectory) {
  if (!FLAGS_enable_trajectory_stitcher) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }
  if (!prev_trajectory) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  if (vehicle_state.driving_mode() != canbus::Chassis::COMPLETE_AUTO_DRIVE) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  std::size_t prev_trajectory_size = prev_trajectory->NumOfPoints();

  if (prev_trajectory_size == 0) {
    ADEBUG << "Projected trajectory at time [" << prev_trajectory->header_time()
           << "] size is zero! Previous planning not exist or failed. Use "
              "origin car status instead.";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  const double veh_rel_time =
      current_timestamp - prev_trajectory->header_time();

  std::size_t time_matched_index =
      prev_trajectory->QueryLowerBoundPoint(veh_rel_time);

  if (time_matched_index == 0 &&
      veh_rel_time < prev_trajectory->StartPoint().relative_time()) {
    AWARN << "current time smaller than the previous trajectory's first time";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }
  if (time_matched_index + 1 >= prev_trajectory_size) {
    AWARN << "current time beyond the previous trajectory's last time";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  auto time_matched_point =
      prev_trajectory->TrajectoryPointAt(time_matched_index);

  if (!time_matched_point.has_path_point()) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  std::size_t position_matched_index =
      prev_trajectory->QueryNearestPointWithBuffer(
          {vehicle_state.x(), vehicle_state.y()}, 1.0e-6);

  auto frenet_sd = ComputePositionProjection(
      vehicle_state.x(), vehicle_state.y(),
      prev_trajectory->TrajectoryPointAt(position_matched_index));

  auto lon_diff = time_matched_point.path_point().s() - frenet_sd.first;
  auto lat_diff = frenet_sd.second;

  ADEBUG << "Control lateral diff: " << lat_diff
         << ", longitudinal diff: " << lon_diff;

  if (std::fabs(lat_diff) > FLAGS_replan_lateral_distance_threshold ||
      std::fabs(lon_diff) > FLAGS_replan_longitudinal_distance_threshold) {
    AERROR << "the distance between matched point and actual position is too "
              "large. Replan is triggered. lat_diff = "
           << lat_diff << ", lon_diff = " << lon_diff;
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  double forward_rel_time =
      prev_trajectory->TrajectoryPointAt(time_matched_index).relative_time() +
      planning_cycle_time;

  std::size_t forward_time_index =
      prev_trajectory->QueryLowerBoundPoint(forward_rel_time);

  ADEBUG << "Position matched index:\t" << position_matched_index;
  ADEBUG << "Time matched index:\t" << time_matched_index;

  auto matched_index = std::min(time_matched_index, position_matched_index);

  constexpr size_t kNumPreCyclePoint = 20;
  std::vector<TrajectoryPoint> stitching_trajectory(
      prev_trajectory->trajectory_points().begin() +
          std::max(0, static_cast<int>(matched_index - kNumPreCyclePoint)),
      prev_trajectory->trajectory_points().begin() + forward_time_index + 1);
  ADEBUG << "stitching_trajectory size: " << stitching_trajectory.size();

  const double zero_s = stitching_trajectory.back().path_point().s();
  for (auto& tp : stitching_trajectory) {
    if (!tp.has_path_point()) {
      return ComputeReinitStitchingTrajectory(vehicle_state);
    }
    tp.set_relative_time(tp.relative_time() + prev_trajectory->header_time() -
                         current_timestamp);
    tp.mutable_path_point()->set_s(tp.path_point().s() - zero_s);
  }
  return stitching_trajectory;
}

std::pair<double, double> TrajectoryStitcher::ComputePositionProjection(
    const double x, const double y, const TrajectoryPoint& p) {
  Vec2d v(x - p.path_point().x(), y - p.path_point().y());
  Vec2d n(common::math::cos(
              common::math::Angle16::from_rad(p.path_point().theta())),
          common::math::sin(
              common::math::Angle16::from_rad(p.path_point().theta())));

  std::pair<double, double> frenet_sd;
  frenet_sd.first = v.InnerProd(n) + p.path_point().s();
  frenet_sd.second = v.CrossProd(n);
  return frenet_sd;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: fix compile warning. (#2047)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/common/trajectory/trajectory_stitcher.h"

#include <algorithm>
#include <list>
#include <utility>

#include "cyber/common/log.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/math/angle.h"
#include "modules/common/math/quaternion.h"
#include "modules/common/util/util.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::TrajectoryPoint;
using apollo::common::VehicleState;
using apollo::common::math::Vec2d;
using apollo::common::util::DistanceXY;

std::vector<TrajectoryPoint>
TrajectoryStitcher::ComputeReinitStitchingTrajectory(
    const VehicleState& vehicle_state) {
  TrajectoryPoint init_point;
  init_point.mutable_path_point()->set_s(0.0);
  init_point.mutable_path_point()->set_x(vehicle_state.x());
  init_point.mutable_path_point()->set_y(vehicle_state.y());
  init_point.mutable_path_point()->set_z(vehicle_state.z());
  init_point.mutable_path_point()->set_theta(vehicle_state.heading());
  init_point.mutable_path_point()->set_kappa(vehicle_state.kappa());
  init_point.set_v(vehicle_state.linear_velocity());
  init_point.set_a(vehicle_state.linear_acceleration());
  init_point.set_relative_time(0.0);

  return std::vector<TrajectoryPoint>(1, init_point);
}

// only used in navigation mode
void TrajectoryStitcher::TransformLastPublishedTrajectory(
    const double x_diff, const double y_diff, const double theta_diff,
    PublishableTrajectory* prev_trajectory) {
  if (!prev_trajectory) {
    return;
  }

  // R^-1
  double cos_theta = std::cos(theta_diff);
  double sin_theta = -std::sin(theta_diff);

  // -R^-1 * t
  auto tx = -(cos_theta * x_diff - sin_theta * y_diff);
  auto ty = -(sin_theta * x_diff + cos_theta * y_diff);

  std::for_each(prev_trajectory->trajectory_points().begin(),
                prev_trajectory->trajectory_points().end(),
                [&cos_theta, &sin_theta, &tx, &ty,
                 &theta_diff](common::TrajectoryPoint& p) {
                  auto x = p.path_point().x();
                  auto y = p.path_point().y();
                  auto theta = p.path_point().theta();

                  auto x_new = cos_theta * x - sin_theta * y + tx;
                  auto y_new = sin_theta * x + cos_theta * y + ty;
                  auto theta_new = common::math::WrapAngle(theta - theta_diff);

                  p.mutable_path_point()->set_x(x_new);
                  p.mutable_path_point()->set_y(y_new);
                  p.mutable_path_point()->set_theta(theta_new);
                });
}

/* Planning from current vehicle state if:
   1. the auto-driving mode is off
   (or) 2. we don't have the trajectory from last planning cycle
   (or) 3. the position deviation from actual and target is too high
*/
std::vector<TrajectoryPoint> TrajectoryStitcher::ComputeStitchingTrajectory(
    const VehicleState& vehicle_state, const double current_timestamp,
    const double planning_cycle_time,
    const PublishableTrajectory* prev_trajectory) {
  if (!FLAGS_enable_trajectory_stitcher) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }
  if (!prev_trajectory) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  if (vehicle_state.driving_mode() != canbus::Chassis::COMPLETE_AUTO_DRIVE) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  std::size_t prev_trajectory_size = prev_trajectory->NumOfPoints();

  if (prev_trajectory_size == 0) {
    ADEBUG << "Projected trajectory at time [" << prev_trajectory->header_time()
           << "] size is zero! Previous planning not exist or failed. Use "
              "origin car status instead.";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  const double veh_rel_time =
      current_timestamp - prev_trajectory->header_time();

  std::size_t time_matched_index =
      prev_trajectory->QueryLowerBoundPoint(veh_rel_time);

  if (time_matched_index == 0 &&
      veh_rel_time < prev_trajectory->StartPoint().relative_time()) {
    AWARN << "current time smaller than the previous trajectory's first time";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }
  if (time_matched_index + 1 >= prev_trajectory_size) {
    AWARN << "current time beyond the previous trajectory's last time";
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  auto time_matched_point = prev_trajectory->TrajectoryPointAt(
      static_cast<uint32_t>(time_matched_index));

  if (!time_matched_point.has_path_point()) {
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  std::size_t position_matched_index =
      prev_trajectory->QueryNearestPointWithBuffer(
          {vehicle_state.x(), vehicle_state.y()}, 1.0e-6);

  auto frenet_sd = ComputePositionProjection(
      vehicle_state.x(), vehicle_state.y(),
      prev_trajectory->TrajectoryPointAt(
          static_cast<uint32_t>(position_matched_index)));

  auto lon_diff = time_matched_point.path_point().s() - frenet_sd.first;
  auto lat_diff = frenet_sd.second;

  ADEBUG << "Control lateral diff: " << lat_diff
         << ", longitudinal diff: " << lon_diff;

  if (std::fabs(lat_diff) > FLAGS_replan_lateral_distance_threshold ||
      std::fabs(lon_diff) > FLAGS_replan_longitudinal_distance_threshold) {
    AERROR << "the distance between matched point and actual position is too "
              "large. Replan is triggered. lat_diff = "
           << lat_diff << ", lon_diff = " << lon_diff;
    return ComputeReinitStitchingTrajectory(vehicle_state);
  }

  double forward_rel_time =
      prev_trajectory
          ->TrajectoryPointAt(static_cast<uint32_t>(time_matched_index))
          .relative_time() +
      planning_cycle_time;

  std::size_t forward_time_index =
      prev_trajectory->QueryLowerBoundPoint(forward_rel_time);

  ADEBUG << "Position matched index:\t" << position_matched_index;
  ADEBUG << "Time matched index:\t" << time_matched_index;

  auto matched_index = std::min(time_matched_index, position_matched_index);

  constexpr size_t kNumPreCyclePoint = 20;
  std::vector<TrajectoryPoint> stitching_trajectory(
      prev_trajectory->trajectory_points().begin() +
          std::max(0, static_cast<int>(matched_index - kNumPreCyclePoint)),
      prev_trajectory->trajectory_points().begin() + forward_time_index + 1);
  ADEBUG << "stitching_trajectory size: " << stitching_trajectory.size();

  const double zero_s = stitching_trajectory.back().path_point().s();
  for (auto& tp : stitching_trajectory) {
    if (!tp.has_path_point()) {
      return ComputeReinitStitchingTrajectory(vehicle_state);
    }
    tp.set_relative_time(tp.relative_time() + prev_trajectory->header_time() -
                         current_timestamp);
    tp.mutable_path_point()->set_s(tp.path_point().s() - zero_s);
  }
  return stitching_trajectory;
}

std::pair<double, double> TrajectoryStitcher::ComputePositionProjection(
    const double x, const double y, const TrajectoryPoint& p) {
  Vec2d v(x - p.path_point().x(), y - p.path_point().y());
  Vec2d n(common::math::cos(
              common::math::Angle16::from_rad(p.path_point().theta())),
          common::math::sin(
              common::math::Angle16::from_rad(p.path_point().theta())));

  std::pair<double, double> frenet_sd;
  frenet_sd.first = v.InnerProd(n) + p.path_point().s();
  frenet_sd.second = v.CrossProd(n);
  return frenet_sd;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>#include <sndfile.h>
#include <string>

namespace DG {
namespace Sound {

class WAV {
public:
  struct Invalid_format_exception : public std::exception {
    virtual const char* what() const throw() {
      return "WAV: Invalid_format_exception";
    }
  } invalid_format;

  struct Inaccessible_file_exception : public std::exception {
    virtual const char* what() const throw() {
      return "WAV: Inaccessible_file_exception";
    }
  } inaccessible_file;

  WAV(const std::string& fname) { open(fname); }

  void open(const std::string& fname);

  // write wav out to the file fname
  void write(const std::string& fname);
private:
};

}
}
<commit_msg>Removed unnecessary exception definitions [ci skip]<commit_after>#include <sndfile.h>
#include <string>

namespace DG {
namespace Sound {

class WAV {
public:
  struct Invalid_format_exception : public std::exception {

  WAV(const std::string& fname) { open(fname); }

  void open(const std::string& fname);

  // write wav out to the file fname
  void write(const std::string& fname);
private:
};

}
}
<|endoftext|>


<commit_before>// Copyright 2012 Software Freedom Conservancy
// 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 "stdafx.h"
#include "resource.h"
#include "IEServer.h"

// TODO(JimEvans): Change the prototypes of these functions in the
// IEDriver project to match the prototype specified here.
typedef void (__cdecl *STARTSERVERPROC)(int);
typedef void (__cdecl *STOPSERVERPROC)(void);

#define ERR_DLL_EXTRACT_FAIL 1
#define ERR_DLL_LOAD_FAIL 2
#define ERR_FUNCTION_NOT_FOUND 3

#define RESOURCE_TYPE L"BINARY"
#define TEMP_FILE_PREFIX L"IEDriver"
#define START_SERVER_API_NAME "StartServer"
#define STOP_SERVER_API_NAME "StopServer"

bool ExtractResource(unsigned short resource_id,
                     const std::wstring& output_file_name) {
  bool success = false;
  try {
    // First find and load the required resource
    HRSRC resource_handle = ::FindResource(NULL,
                                           MAKEINTRESOURCE(resource_id),
                                           RESOURCE_TYPE);
    HGLOBAL global_resouce_handle = ::LoadResource(NULL, resource_handle);

    // Now open and map this to a disk file
    LPVOID file_pointer = ::LockResource(global_resouce_handle);
    DWORD resource_size = ::SizeofResource(NULL, resource_handle);

    // Open the file and filemap
    HANDLE file_handle = ::CreateFile(output_file_name.c_str(),
                                      GENERIC_READ | GENERIC_WRITE,
                                      0,
                                      NULL,
                                      CREATE_ALWAYS,
                                      FILE_ATTRIBUTE_NORMAL,
                                      NULL);
    HANDLE file_mapping_handle = ::CreateFileMapping(file_handle,
                                                     NULL,
                                                     PAGE_READWRITE,
                                                     0,
                                                     resource_size,
                                                     NULL);
    LPVOID base_address_pointer = ::MapViewOfFile(file_mapping_handle,
                                                  FILE_MAP_WRITE,
                                                  0,
                                                  0,
                                                  0);

    // Write the file
    ::CopyMemory(base_address_pointer, file_pointer, resource_size);

    // Unmap the file and close the handles
    ::UnmapViewOfFile(base_address_pointer);
    ::CloseHandle(file_mapping_handle);
    ::CloseHandle(file_handle);
    success = true;
  } catch(...) {
    // Ignore all type of errors
  }
  return success;
}

int GetPort(int argc, _TCHAR* argv[]) {
  int port = 5555;
  if (argc >= 2) {
    for (int i = 1; i < argc; i++) {
      std::wstring arg(argv[i]);
      if (arg.find(L"--port=") == 0 ||
          arg.find(L"-port=") == 0 ||
          arg.find(L"/port=") == 0) {
        int equal_pos = arg.find(L"=");
        std::wstring port_string = arg.substr(equal_pos + 1);
        int port_value = _wtoi(port_string.c_str());
        if (port_value > 0) {
          port = port_value;
        }
        break;
      }
    }
  }
  return port;
}

int _tmain(int argc, _TCHAR* argv[]) {
  vector<TCHAR> temp_file_name_buffer(MAX_PATH);
  vector<TCHAR> temp_path_buffer(MAX_PATH);

  //  Gets the temp path env string (no guarantee it's a valid path).
  unsigned long temp_path_length = ::GetTempPath(MAX_PATH,
                                                 &temp_path_buffer[0]);

  unsigned int error_code = ::GetTempFileName(&temp_path_buffer[0],
                                              TEMP_FILE_PREFIX,
                                              0,
                                              &temp_file_name_buffer[0]);

  std::wstring temp_file_name(&temp_file_name_buffer[0]);
  if (!ExtractResource(IDR_DRIVER_LIBRARY, temp_file_name)) {
    return ERR_DLL_EXTRACT_FAIL;
  }

  HMODULE module_handle = ::LoadLibrary(temp_file_name.c_str());
  if (module_handle == NULL) {
    return ERR_DLL_LOAD_FAIL;
  }

  STARTSERVERPROC start_server_proc = reinterpret_cast<STARTSERVERPROC>(
      ::GetProcAddress(module_handle, START_SERVER_API_NAME));
  STOPSERVERPROC stop_server_proc = reinterpret_cast<STOPSERVERPROC>(
      ::GetProcAddress(module_handle, STOP_SERVER_API_NAME));
  if (start_server_proc == NULL || stop_server_proc == NULL) {
    return ERR_FUNCTION_NOT_FOUND;
  }

  int port = GetPort(argc, argv);
  start_server_proc(port);
  std::cout << "Started InternetExplorerDriver" << std::endl;
  std::cout << "Listening on port " << port << std::endl;

  // Create the shutdown event and wait for it to be signaled.
  DWORD process_id = ::GetCurrentProcessId();
  vector<wchar_t> process_id_buffer(10);
  _ltow_s(process_id, &process_id_buffer[0], process_id_buffer.size(), 10);
  std::wstring process_id_string(&process_id_buffer[0]);
  std::wstring event_name = IESERVER_SHUTDOWN_EVENT_NAME + process_id_string;
  HANDLE event_handle = ::CreateEvent(NULL,
                                      TRUE,
                                      FALSE,
                                      event_name.c_str());
  ::WaitForSingleObject(event_handle, INFINITE);
  ::CloseHandle(event_handle);
  stop_server_proc();

  ::FreeLibrary(module_handle);
  ::DeleteFile(temp_file_name.c_str());
  return 0;
}

<commit_msg>JimEvans: Quieting compiler warning on x64 builds of InternetExplorerDriver.exe<commit_after>// Copyright 2012 Software Freedom Conservancy
// 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 "stdafx.h"
#include "resource.h"
#include "IEServer.h"

// TODO(JimEvans): Change the prototypes of these functions in the
// IEDriver project to match the prototype specified here.
typedef void (__cdecl *STARTSERVERPROC)(int);
typedef void (__cdecl *STOPSERVERPROC)(void);

#define ERR_DLL_EXTRACT_FAIL 1
#define ERR_DLL_LOAD_FAIL 2
#define ERR_FUNCTION_NOT_FOUND 3

#define RESOURCE_TYPE L"BINARY"
#define TEMP_FILE_PREFIX L"IEDriver"
#define START_SERVER_API_NAME "StartServer"
#define STOP_SERVER_API_NAME "StopServer"

bool ExtractResource(unsigned short resource_id,
                     const std::wstring& output_file_name) {
  bool success = false;
  try {
    // First find and load the required resource
    HRSRC resource_handle = ::FindResource(NULL,
                                           MAKEINTRESOURCE(resource_id),
                                           RESOURCE_TYPE);
    HGLOBAL global_resouce_handle = ::LoadResource(NULL, resource_handle);

    // Now open and map this to a disk file
    LPVOID file_pointer = ::LockResource(global_resouce_handle);
    DWORD resource_size = ::SizeofResource(NULL, resource_handle);

    // Open the file and filemap
    HANDLE file_handle = ::CreateFile(output_file_name.c_str(),
                                      GENERIC_READ | GENERIC_WRITE,
                                      0,
                                      NULL,
                                      CREATE_ALWAYS,
                                      FILE_ATTRIBUTE_NORMAL,
                                      NULL);
    HANDLE file_mapping_handle = ::CreateFileMapping(file_handle,
                                                     NULL,
                                                     PAGE_READWRITE,
                                                     0,
                                                     resource_size,
                                                     NULL);
    LPVOID base_address_pointer = ::MapViewOfFile(file_mapping_handle,
                                                  FILE_MAP_WRITE,
                                                  0,
                                                  0,
                                                  0);

    // Write the file
    ::CopyMemory(base_address_pointer, file_pointer, resource_size);

    // Unmap the file and close the handles
    ::UnmapViewOfFile(base_address_pointer);
    ::CloseHandle(file_mapping_handle);
    ::CloseHandle(file_handle);
    success = true;
  } catch(...) {
    // Ignore all type of errors
  }
  return success;
}

int GetPort(int argc, _TCHAR* argv[]) {
  int port = 5555;
  if (argc >= 2) {
    for (int i = 1; i < argc; i++) {
      std::wstring arg(argv[i]);
      if (arg.find(L"--port=") == 0 ||
          arg.find(L"-port=") == 0 ||
          arg.find(L"/port=") == 0) {
        size_t equal_pos = arg.find(L"=");
        std::wstring port_string = arg.substr(equal_pos + 1);
        int port_value = _wtoi(port_string.c_str());
        if (port_value > 0) {
          port = port_value;
        }
        break;
      }
    }
  }
  return port;
}

int _tmain(int argc, _TCHAR* argv[]) {
  vector<TCHAR> temp_file_name_buffer(MAX_PATH);
  vector<TCHAR> temp_path_buffer(MAX_PATH);

  //  Gets the temp path env string (no guarantee it's a valid path).
  unsigned long temp_path_length = ::GetTempPath(MAX_PATH,
                                                 &temp_path_buffer[0]);

  unsigned int error_code = ::GetTempFileName(&temp_path_buffer[0],
                                              TEMP_FILE_PREFIX,
                                              0,
                                              &temp_file_name_buffer[0]);

  std::wstring temp_file_name(&temp_file_name_buffer[0]);
  if (!ExtractResource(IDR_DRIVER_LIBRARY, temp_file_name)) {
    return ERR_DLL_EXTRACT_FAIL;
  }

  HMODULE module_handle = ::LoadLibrary(temp_file_name.c_str());
  if (module_handle == NULL) {
    return ERR_DLL_LOAD_FAIL;
  }

  STARTSERVERPROC start_server_proc = reinterpret_cast<STARTSERVERPROC>(
      ::GetProcAddress(module_handle, START_SERVER_API_NAME));
  STOPSERVERPROC stop_server_proc = reinterpret_cast<STOPSERVERPROC>(
      ::GetProcAddress(module_handle, STOP_SERVER_API_NAME));
  if (start_server_proc == NULL || stop_server_proc == NULL) {
    return ERR_FUNCTION_NOT_FOUND;
  }

  int port = GetPort(argc, argv);
  start_server_proc(port);
  std::cout << "Started InternetExplorerDriver" << std::endl;
  std::cout << "Listening on port " << port << std::endl;

  // Create the shutdown event and wait for it to be signaled.
  DWORD process_id = ::GetCurrentProcessId();
  vector<wchar_t> process_id_buffer(10);
  _ltow_s(process_id, &process_id_buffer[0], process_id_buffer.size(), 10);
  std::wstring process_id_string(&process_id_buffer[0]);
  std::wstring event_name = IESERVER_SHUTDOWN_EVENT_NAME + process_id_string;
  HANDLE event_handle = ::CreateEvent(NULL,
                                      TRUE,
                                      FALSE,
                                      event_name.c_str());
  ::WaitForSingleObject(event_handle, INFINITE);
  ::CloseHandle(event_handle);
  stop_server_proc();

  ::FreeLibrary(module_handle);
  ::DeleteFile(temp_file_name.c_str());
  return 0;
}

<|endoftext|>