<commit_before>#include <iostream>
#include <memory>
#include <cmath>

#include "parse_arguments.h"

using namespace std;

struct Unit
{
  using value_type = double;
  value_type value_{0}, grad_{0};
  Unit(value_type value, value_type grad) : value_(value), grad_(grad) {}
};

static auto make_unit(Unit::value_type value, Unit::value_type gradient = 0)
{
  return std::make_unique<Unit>(value, gradient);
}

struct UnaryGate
{
  Unit* u0_;
  unique_ptr<Unit> utop_;
  virtual Unit* forward(Unit*) = 0;
  virtual void backward() = 0;
};
struct BinaryGate
{
  Unit *u0_,*u1_;
  unique_ptr<Unit> utop_;
  virtual Unit* forward (Unit*, Unit*) = 0;
  virtual void backward() = 0;
};

struct Multiply : BinaryGate
{
  virtual Unit* forward(Unit* u0, Unit* u1) override
  {
    u0_   = u0;
    u1_   = u1;
    utop_ = make_unit(u0_->value_ * u1_->value_, 0);
    return utop_.get();
  }
  virtual void backward() override
  {
    u0_->grad_ += u1_->value_ * utop_->grad_;
    u1_->grad_ += u0_->value_ * utop_->grad_;
  }
};

struct Add : BinaryGate
{
  virtual Unit* forward(Unit* u0, Unit* u1) override
  {
    u0_   = u0;
    u1_   = u1;
    utop_ = make_unit(u0_->value_ + u1_->value_,0);
    return utop_.get();
  }
  virtual void backward() override
  {
    u0_->grad_ += 1 * utop_->grad_;
    u1_->grad_ += 1 * utop_->grad_;
  }
};

struct Sigmoid : UnaryGate
{
  static auto sig(Unit::value_type x)
  {
    return 1/(1 + std::exp(-x));
  }
  static auto grad_sig(Unit::value_type x)
  {
    auto s = sig(x);
    return s*(1-s);
  }
  virtual Unit* forward(Unit* u0) override
  {
    u0_   = u0;
    utop_ = make_unit(sig(u0_->value_), 0);
    return utop_.get();
  }
  virtual void backward() override
  {
    u0_->grad_ += grad_sig(u0_->value_) * utop_->grad_;
  }
};

int main(int argc, char * argv[])
{
  using namespace std;

  auto a0 = make_unit( 1,0);
  auto b0 = make_unit( 2,0);
  auto c0 = make_unit(-3,0);
  auto x0 = make_unit(-1,0);
  auto y0 = make_unit( 3,0);

  auto a = a0.get();
  auto b = b0.get();
  auto c = c0.get();
  auto x = x0.get();
  auto y = y0.get();

  auto mulg0 = Multiply{};
  auto mulg1 = Multiply{};
  auto addg0 = Add{};
  auto addg1 = Add{};
  auto sg0   = Sigmoid{};

  auto forwardNeuron = [&]()
  {
    auto ax      = mulg0.forward(a,x);       // a*x
    auto by      = mulg1.forward(b,y);       // b*y;
    auto axpby   = addg0.forward(ax,by);     // a*x + b*y
    auto axpbypc = addg1.forward(axpby,c);   // a*x + b*y + c
    auto s       = sg0 .forward(axpbypc);   // sig(a*x + b*y + c);
    return s;
  };

  auto s = forwardNeuron();
  cout << "circuit output: "  << s->value_ << endl;

  s->grad_ = 1.0;

  sg0  .backward();
  addg1.backward();
  addg0.backward();
  mulg1.backward();
  mulg0.backward();

  auto step_size = 0.01;
  a->value_ += step_size * a->grad_;
  b->value_ += step_size * b->grad_;
  c->value_ += step_size * c->grad_;
  x->value_ += step_size * x->grad_;
  y->value_ += step_size * y->grad_;

  auto s1 = forwardNeuron();
  cout << "circuit output after one backprop: "  << s1->value_ << endl;

  return 0;
}
<commit_msg>backprop works<commit_after>#include <iostream>
#include <memory>
#include <cmath>

#include "parse_arguments.h"

using namespace std;

struct Unit
{
  using value_type = double;
  value_type value_{0}, grad_{0};
  Unit(value_type value, value_type grad) : value_(value), grad_(grad) {}
};

static auto make_unit(Unit::value_type value, Unit::value_type gradient = 0)
{
  return std::make_unique<Unit>(value, gradient);
}

struct UnaryGate
{
  Unit* u0_;
  unique_ptr<Unit> utop_;
  virtual Unit* forward(Unit*) = 0;
  virtual Unit* forward(Unit &u0)
  {
    return forward(&u0);
  }
  virtual void backward() = 0;
};
struct BinaryGate
{
  Unit *u0_,*u1_;
  unique_ptr<Unit> utop_;
  virtual Unit* forward (Unit*, Unit*) = 0;
  virtual Unit* forward (Unit &u0, Unit &u1)  {    return forward(&u0, &u1); }
  virtual Unit* forward (Unit &u0, Unit *u1)  {    return forward(&u0,  u1); }
  virtual Unit* forward (Unit *u0, Unit &u1)  {    return forward( u0, &u1); }
  virtual void backward() = 0;
};

struct Multiply : BinaryGate
{
  virtual Unit* forward(Unit* u0, Unit* u1) override
  {
    u0_   = u0;
    u1_   = u1;
    utop_ = make_unit(u0_->value_ * u1_->value_, 0);
    return utop_.get();
  }
  using BinaryGate::forward;
  virtual void backward() override
  {
    u0_->grad_ += u1_->value_ * utop_->grad_;
    u1_->grad_ += u0_->value_ * utop_->grad_;
  }
};

struct Add : BinaryGate
{
  virtual Unit* forward(Unit* u0, Unit* u1) override
  {
    u0_   = u0;
    u1_   = u1;
    utop_ = make_unit(u0_->value_ + u1_->value_,0);
    return utop_.get();
  }
  using BinaryGate::forward;
  virtual void backward() override
  {
    u0_->grad_ += 1 * utop_->grad_;
    u1_->grad_ += 1 * utop_->grad_;
  }
};

struct Sigmoid : UnaryGate
{
  static auto sig(Unit::value_type x)
  {
    return 1/(1 + std::exp(-x));
  }
  static auto grad_sig(Unit::value_type x)
  {
    auto s = sig(x);
    return s*(1-s);
  }
  virtual Unit* forward(Unit* u0) override
  {
    u0_   = u0;
    utop_ = make_unit(sig(u0_->value_), 0);
    return utop_.get();
  }
  virtual void backward() override
  {
    u0_->grad_ += grad_sig(u0_->value_) * utop_->grad_;
  }
};

int main(int argc, char * argv[])
{
  using namespace std;

  auto a = Unit{ 1,0};
  auto b = Unit{ 2,0};
  auto c = Unit{-3,0};
  auto x = Unit{-1,0};
  auto y = Unit{ 3,0};

  auto mulg0 = Multiply{};
  auto mulg1 = Multiply{};
  auto addg0 = Add{};
  auto addg1 = Add{};
  auto sg0   = Sigmoid{};

  auto forwardNeuron = [&]()
  {
    auto ax      = mulg0.forward(a,x);       // a*x
    auto by      = mulg1.forward(b,y);       // b*y;
    auto axpby   = addg0.forward(ax,by);     // a*x + b*y
    auto axpbypc = addg1.forward(axpby,c);   // a*x + b*y + c
    auto s       = sg0 .forward(axpbypc);   // sig(a*x + b*y + c);
    return s;
  };

  auto s = forwardNeuron();
  cout << "circuit output: "  << s->value_ << endl;

  s->grad_ = 1.0;

  sg0  .backward();
  addg1.backward();
  addg0.backward();
  mulg1.backward();
  mulg0.backward();

  auto step_size = 0.01;
  a.value_ += step_size * a.grad_;
  b.value_ += step_size * b.grad_;
  c.value_ += step_size * c.grad_;
  x.value_ += step_size * x.grad_;
  y.value_ += step_size * y.grad_;

  auto s1 = forwardNeuron();
  cout << "circuit output after one backprop: "  << s1->value_ << endl;

  return 0;
}
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TEST_COMPASS
#include "boost/test/unit_test.hpp"

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>

#include "compass.hpp"
#include "compass_fixture.hpp"

BOOST_AUTO_TEST_SUITE( compass_fundamentals )

BOOST_AUTO_TEST_CASE( compass_works_at_runtime ){

  auto value = compass::runtime::works();

  BOOST_CHECK(value);

}

BOOST_AUTO_TEST_CASE( compass_yields_vendor_name ){

  auto value = compass::runtime::vendor();
  BOOST_CHECK_NE(value.size(),0u);

}
BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE( machine_specific, host_reference )

BOOST_AUTO_TEST_CASE( vendor_right  ){

  auto value = compass::runtime::vendor();

  BOOST_CHECK_NE(value.size(),0u);

  std::transform(value.begin(), value.end(),
         value.begin(),
         ::tolower);

  //  std::cout << "vendor " << value << " =?= "<<  expected_vendor << "\n";
  BOOST_CHECK(value.find(expected_vendor)!=std::string::npos);

}

BOOST_AUTO_TEST_CASE( ncores_right  ){

  auto value = compass::runtime::ncores();

  BOOST_CHECK_NE(value,0);
  BOOST_CHECK_EQUAL(value,expected_ncores);
}

BOOST_AUTO_TEST_CASE( has_sse_right  ){

  auto value = compass::runtime::has(compass::feature::sse());

  BOOST_CHECK_EQUAL(value,expected_has_sse);

}

BOOST_AUTO_TEST_CASE( has_sse2_right  ){

  auto value = compass::runtime::has(compass::feature::sse2());

  BOOST_CHECK_EQUAL(value,expected_has_sse2);

}

BOOST_AUTO_TEST_CASE( has_sse3_right  ){

  auto value = compass::runtime::has(compass::feature::sse3());

  BOOST_CHECK_EQUAL(value,expected_has_sse3);

}

BOOST_AUTO_TEST_CASE( has_sse4_right  ){

  auto value = compass::runtime::has(compass::feature::sse4());

  BOOST_CHECK_EQUAL(value,expected_has_sse4);

}

BOOST_AUTO_TEST_CASE( has_avx_right  ){

  auto value = compass::runtime::has(compass::feature::avx());

  BOOST_CHECK_EQUAL(value,expected_has_avx);

}

BOOST_AUTO_TEST_CASE( has_avx2_right  ){

  auto value = compass::runtime::has(compass::feature::avx2());

  BOOST_CHECK_EQUAL(value,expected_has_avx2);

}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>removed obsolete comment<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TEST_COMPASS
#include "boost/test/unit_test.hpp"

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>

#include "compass.hpp"
#include "compass_fixture.hpp"

BOOST_AUTO_TEST_SUITE( compass_fundamentals )

BOOST_AUTO_TEST_CASE( compass_works_at_runtime ){

  auto value = compass::runtime::works();

  BOOST_CHECK(value);

}

BOOST_AUTO_TEST_CASE( compass_yields_vendor_name ){

  auto value = compass::runtime::vendor();
  BOOST_CHECK_NE(value.size(),0u);

}
BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE( machine_specific, host_reference )

BOOST_AUTO_TEST_CASE( vendor_right  ){

  auto value = compass::runtime::vendor();

  BOOST_CHECK_NE(value.size(),0u);

  std::transform(value.begin(), value.end(),
         value.begin(),
         ::tolower);

  BOOST_CHECK(value.find(expected_vendor)!=std::string::npos);

}

BOOST_AUTO_TEST_CASE( ncores_right  ){

  auto value = compass::runtime::ncores();

  BOOST_CHECK_NE(value,0);
  BOOST_CHECK_EQUAL(value,expected_ncores);
}

BOOST_AUTO_TEST_CASE( has_sse_right  ){

  auto value = compass::runtime::has(compass::feature::sse());

  BOOST_CHECK_EQUAL(value,expected_has_sse);

}

BOOST_AUTO_TEST_CASE( has_sse2_right  ){

  auto value = compass::runtime::has(compass::feature::sse2());

  BOOST_CHECK_EQUAL(value,expected_has_sse2);

}

BOOST_AUTO_TEST_CASE( has_sse3_right  ){

  auto value = compass::runtime::has(compass::feature::sse3());

  BOOST_CHECK_EQUAL(value,expected_has_sse3);

}

BOOST_AUTO_TEST_CASE( has_sse4_right  ){

  auto value = compass::runtime::has(compass::feature::sse4());

  BOOST_CHECK_EQUAL(value,expected_has_sse4);

}

BOOST_AUTO_TEST_CASE( has_avx_right  ){

  auto value = compass::runtime::has(compass::feature::avx());

  BOOST_CHECK_EQUAL(value,expected_has_avx);

}

BOOST_AUTO_TEST_CASE( has_avx2_right  ){

  auto value = compass::runtime::has(compass::feature::avx2());

  BOOST_CHECK_EQUAL(value,expected_has_avx2);

}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#ifndef __PROCESS_LIMITER_HPP__
#define __PROCESS_LIMITER_HPP__

#include <deque>

#include <process/delay.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>
#include <process/future.hpp>
#include <process/process.hpp>
#include <process/timeout.hpp>

#include <stout/duration.hpp>
#include <stout/foreach.hpp>
#include <stout/nothing.hpp>

namespace process {

// Forward declaration.
class RateLimiterProcess;

// Provides an abstraction that rate limits the number of "permits"
// that can be acquired over some duration.
// NOTE: Currently, each libprocess Process should use a separate
// RateLimiter instance. This is because if multiple processes share
// a RateLimiter instance, by the time a process acts on the Future
// returned by 'acquire()' another process might have acquired the
// next permit and do its rate limited operation.
class RateLimiter
{
public:
  RateLimiter(int permits, const Duration& duration);
  explicit RateLimiter(double permitsPerSecond);
  ~RateLimiter();

  // Returns a future that becomes ready when the permit is acquired.
  Future<Nothing> acquire();

private:
  // Not copyable, not assignable.
  RateLimiter(const RateLimiter&);
  RateLimiter& operator = (const RateLimiter&);

  RateLimiterProcess* process;
};

class RateLimiterProcess : public Process<RateLimiterProcess>
{
public:
  RateLimiterProcess(int permits, const Duration& duration)
    : ProcessBase(ID::generate("__limiter__"))
  {
    CHECK_GT(permits, 0);
    CHECK_GT(duration.secs(), 0);
    permitsPerSecond = permits / duration.secs();
  }

  explicit RateLimiterProcess(double _permitsPerSecond)
    : ProcessBase(ID::generate("__limiter__")),
      permitsPerSecond(_permitsPerSecond)
  {
    CHECK_GT(permitsPerSecond, 0);
  }

  virtual void finalize()
  {
    foreach (Promise<Nothing>* promise, promises) {
      promise->future().discard();
      delete promise;
    }
    promises.clear();
  }

  Future<Nothing> acquire()
  {
    if (!promises.empty()) {
      // Need to wait for others to get permits first.
      Promise<Nothing>* promise = new Promise<Nothing>();
      promises.push_back(promise);
      return promise->future();
    } if (timeout.remaining() > Seconds(0)) {
      // Need to wait a bit longer, but first one in the queue.
      Promise<Nothing>* promise = new Promise<Nothing>();
      promises.push_back(promise);
      delay(timeout.remaining(), self(), &Self::_acquire);
      return promise->future();
    }

    // No need to wait!
    timeout = Seconds(1) / permitsPerSecond;
    return Nothing();
  }

private:
  // Not copyable, not assignable.
  RateLimiterProcess(const RateLimiterProcess&);
  RateLimiterProcess& operator = (const RateLimiterProcess&);

  void _acquire()
  {
    CHECK(!promises.empty());

    Promise<Nothing>* promise = promises.front();
    promises.pop_front();

    promise->set(Nothing());

    timeout = Seconds(1) / permitsPerSecond;

    // Repeat if necessary.
    if (!promises.empty()) {
      delay(timeout.remaining(), self(), &Self::_acquire);
    }
  }

  double permitsPerSecond;

  Timeout timeout;

  std::deque<Promise<Nothing>*> promises;
};

inline RateLimiter::RateLimiter(int permits, const Duration& duration)
{
  process = new RateLimiterProcess(permits, duration);
  spawn(process);
}

inline RateLimiter::RateLimiter(double permitsPerSecond)
{
  process = new RateLimiterProcess(permitsPerSecond);
  spawn(process);
}

inline RateLimiter::~RateLimiter()
{
  terminate(process);
  wait(process);
  delete process;
}

inline Future<Nothing> RateLimiter::acquire()
{
  return dispatch(process, &RateLimiterProcess::acquire);
}

} // namespace process {

#endif // __PROCESS_LIMITER_HPP__
<commit_msg>Fixed a memory leak in limiter.hpp.<commit_after>#ifndef __PROCESS_LIMITER_HPP__
#define __PROCESS_LIMITER_HPP__

#include <deque>

#include <process/delay.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>
#include <process/future.hpp>
#include <process/process.hpp>
#include <process/timeout.hpp>

#include <stout/duration.hpp>
#include <stout/foreach.hpp>
#include <stout/nothing.hpp>

namespace process {

// Forward declaration.
class RateLimiterProcess;

// Provides an abstraction that rate limits the number of "permits"
// that can be acquired over some duration.
// NOTE: Currently, each libprocess Process should use a separate
// RateLimiter instance. This is because if multiple processes share
// a RateLimiter instance, by the time a process acts on the Future
// returned by 'acquire()' another process might have acquired the
// next permit and do its rate limited operation.
class RateLimiter
{
public:
  RateLimiter(int permits, const Duration& duration);
  explicit RateLimiter(double permitsPerSecond);
  ~RateLimiter();

  // Returns a future that becomes ready when the permit is acquired.
  Future<Nothing> acquire();

private:
  // Not copyable, not assignable.
  RateLimiter(const RateLimiter&);
  RateLimiter& operator = (const RateLimiter&);

  RateLimiterProcess* process;
};

class RateLimiterProcess : public Process<RateLimiterProcess>
{
public:
  RateLimiterProcess(int permits, const Duration& duration)
    : ProcessBase(ID::generate("__limiter__"))
  {
    CHECK_GT(permits, 0);
    CHECK_GT(duration.secs(), 0);
    permitsPerSecond = permits / duration.secs();
  }

  explicit RateLimiterProcess(double _permitsPerSecond)
    : ProcessBase(ID::generate("__limiter__")),
      permitsPerSecond(_permitsPerSecond)
  {
    CHECK_GT(permitsPerSecond, 0);
  }

  virtual void finalize()
  {
    foreach (Promise<Nothing>* promise, promises) {
      promise->future().discard();
      delete promise;
    }
    promises.clear();
  }

  Future<Nothing> acquire()
  {
    if (!promises.empty()) {
      // Need to wait for others to get permits first.
      Promise<Nothing>* promise = new Promise<Nothing>();
      promises.push_back(promise);
      return promise->future();
    } if (timeout.remaining() > Seconds(0)) {
      // Need to wait a bit longer, but first one in the queue.
      Promise<Nothing>* promise = new Promise<Nothing>();
      promises.push_back(promise);
      delay(timeout.remaining(), self(), &Self::_acquire);
      return promise->future();
    }

    // No need to wait!
    timeout = Seconds(1) / permitsPerSecond;
    return Nothing();
  }

private:
  // Not copyable, not assignable.
  RateLimiterProcess(const RateLimiterProcess&);
  RateLimiterProcess& operator = (const RateLimiterProcess&);

  void _acquire()
  {
    CHECK(!promises.empty());

    Promise<Nothing>* promise = promises.front();
    promises.pop_front();

    promise->set(Nothing());
    delete promise;

    timeout = Seconds(1) / permitsPerSecond;

    // Repeat if necessary.
    if (!promises.empty()) {
      delay(timeout.remaining(), self(), &Self::_acquire);
    }
  }

  double permitsPerSecond;

  Timeout timeout;

  std::deque<Promise<Nothing>*> promises;
};

inline RateLimiter::RateLimiter(int permits, const Duration& duration)
{
  process = new RateLimiterProcess(permits, duration);
  spawn(process);
}

inline RateLimiter::RateLimiter(double permitsPerSecond)
{
  process = new RateLimiterProcess(permitsPerSecond);
  spawn(process);
}

inline RateLimiter::~RateLimiter()
{
  terminate(process);
  wait(process);
  delete process;
}

inline Future<Nothing> RateLimiter::acquire()
{
  return dispatch(process, &RateLimiterProcess::acquire);
}

} // namespace process {

#endif // __PROCESS_LIMITER_HPP__
<|endoftext|>


<commit_before><commit_msg>VKSC check offline pipeline compiler result.<commit_after><|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "packager/media/formats/mp4/encrypting_fragmenter.h"

#include <limits>

#include "packager/media/base/aes_encryptor.h"
#include "packager/media/base/aes_pattern_cryptor.h"
#include "packager/media/base/buffer_reader.h"
#include "packager/media/base/key_source.h"
#include "packager/media/base/media_sample.h"
#include "packager/media/filters/nalu_reader.h"
#include "packager/media/filters/vp8_parser.h"
#include "packager/media/filters/vp9_parser.h"
#include "packager/media/formats/mp4/box_definitions.h"

namespace edash_packager {
namespace media {
namespace mp4 {

namespace {
const size_t kCencBlockSize = 16u;

// Adds one or more subsamples to |*subsamples|.  This may add more than one
// if one of the values overflows the integer in the subsample.
void AddSubsamples(uint64_t clear_bytes,
                   uint64_t cipher_bytes,
                   std::vector<SubsampleEntry>* subsamples) {
  CHECK_LT(cipher_bytes, std::numeric_limits<uint32_t>::max());
  const uint64_t kUInt16Max = std::numeric_limits<uint16_t>::max();
  while (clear_bytes > kUInt16Max) {
    subsamples->push_back(SubsampleEntry(kUInt16Max, 0));
    clear_bytes -= kUInt16Max;
  }

  if (clear_bytes > 0 || cipher_bytes > 0)
    subsamples->push_back(SubsampleEntry(clear_bytes, cipher_bytes));
}

VideoCodec GetVideoCodec(const StreamInfo& stream_info) {
  if (stream_info.stream_type() != kStreamVideo)
    return kUnknownVideoCodec;
  const VideoStreamInfo& video_stream_info =
      static_cast<const VideoStreamInfo&>(stream_info);
  return video_stream_info.codec();
}

uint8_t GetNaluLengthSize(const StreamInfo& stream_info) {
  if (stream_info.stream_type() != kStreamVideo)
    return 0;

  const VideoStreamInfo& video_stream_info =
      static_cast<const VideoStreamInfo&>(stream_info);
  return video_stream_info.nalu_length_size();
}
}  // namespace

EncryptingFragmenter::EncryptingFragmenter(
    scoped_refptr<StreamInfo> info,
    TrackFragment* traf,
    scoped_ptr<EncryptionKey> encryption_key,
    int64_t clear_time,
    FourCC protection_scheme,
    uint8_t crypt_byte_block,
    uint8_t skip_byte_block)
    : Fragmenter(traf),
      info_(info),
      encryption_key_(encryption_key.Pass()),
      nalu_length_size_(GetNaluLengthSize(*info)),
      video_codec_(GetVideoCodec(*info)),
      clear_time_(clear_time),
      protection_scheme_(protection_scheme),
      crypt_byte_block_(crypt_byte_block),
      skip_byte_block_(skip_byte_block) {
  DCHECK(encryption_key_);
  switch (video_codec_) {
    case kCodecVP8:
      vpx_parser_.reset(new VP8Parser);
      break;
    case kCodecVP9:
      vpx_parser_.reset(new VP9Parser);
      break;
    case kCodecH264:
      header_parser_.reset(new H264VideoSliceHeaderParser);
      break;
    case kCodecHVC1:
      FALLTHROUGH_INTENDED;
    case kCodecHEV1:
      header_parser_.reset(new H265VideoSliceHeaderParser);
      break;
    default:
      LOG(WARNING) << "Unknown video codec '" << video_codec_
                   << "', whole subsamples will be encrypted.";
  }
}

EncryptingFragmenter::~EncryptingFragmenter() {}

Status EncryptingFragmenter::AddSample(scoped_refptr<MediaSample> sample) {
  DCHECK(sample);
  if (!fragment_initialized()) {
    Status status = InitializeFragment(sample->dts());
    if (!status.ok())
      return status;
  }
  if (encryptor_) {
    Status status = EncryptSample(sample);
    if (!status.ok())
      return status;
  }
  return Fragmenter::AddSample(sample);
}

Status EncryptingFragmenter::InitializeFragment(int64_t first_sample_dts) {
  Status status = Fragmenter::InitializeFragment(first_sample_dts);
  if (!status.ok())
    return status;

  if (header_parser_ && !header_parser_->Initialize(info_->extra_data()))
    return Status(error::MUXER_FAILURE, "Fail to read SPS and PPS data.");

  traf()->auxiliary_size.sample_info_sizes.clear();
  traf()->auxiliary_offset.offsets.clear();
  if (IsSubsampleEncryptionRequired()) {
    traf()->sample_encryption.flags |=
        SampleEncryption::kUseSubsampleEncryption;
  }
  traf()->sample_encryption.sample_encryption_entries.clear();

  const bool enable_encryption = clear_time_ <= 0;
  if (!enable_encryption) {
    // This fragment should be in clear text.
    // At most two sample description entries, an encrypted entry and a clear
    // entry, are generated. The 1-based clear entry index is always 2.
    const uint32_t kClearSampleDescriptionIndex = 2;

    traf()->header.flags |=
        TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
    traf()->header.sample_description_index = kClearSampleDescriptionIndex;
  }
  return PrepareFragmentForEncryption(enable_encryption);
}

void EncryptingFragmenter::FinalizeFragment() {
  if (encryptor_) {
    DCHECK_LE(clear_time_, 0);
    FinalizeFragmentForEncryption();
  } else {
    DCHECK_GT(clear_time_, 0);
    clear_time_ -= fragment_duration();
  }
  Fragmenter::FinalizeFragment();
}

Status EncryptingFragmenter::PrepareFragmentForEncryption(
    bool enable_encryption) {
  return (!enable_encryption || encryptor_) ? Status::OK : CreateEncryptor();
}

void EncryptingFragmenter::FinalizeFragmentForEncryption() {
  // The offset will be adjusted in Segmenter after knowing moof size.
  traf()->auxiliary_offset.offsets.push_back(0);

  // For 'cbcs' scheme, Constant IVs SHALL be used.
  const size_t per_sample_iv_size =
      (protection_scheme_ == FOURCC_cbcs) ? 0 : encryptor_->iv().size();
  traf()->sample_encryption.iv_size = per_sample_iv_size;

  // Optimize saiz box.
  SampleAuxiliaryInformationSize& saiz = traf()->auxiliary_size;
  saiz.sample_count = traf()->runs[0].sample_sizes.size();
  if (!saiz.sample_info_sizes.empty()) {
    if (!OptimizeSampleEntries(&saiz.sample_info_sizes,
                               &saiz.default_sample_info_size)) {
      saiz.default_sample_info_size = 0;
    }
  } else {
    // |sample_info_sizes| table is filled in only for subsample encryption,
    // otherwise |sample_info_size| is just the IV size.
    DCHECK(!IsSubsampleEncryptionRequired());
    saiz.default_sample_info_size = per_sample_iv_size;
  }
  // It should only happen with full sample encryption + constant iv, which is
  // not a legal combination.
  CHECK(!saiz.sample_info_sizes.empty() || saiz.default_sample_info_size != 0);
}

Status EncryptingFragmenter::CreateEncryptor() {
  DCHECK(encryption_key_);
  scoped_ptr<AesCryptor> encryptor;
  switch (protection_scheme_) {
    case FOURCC_cenc:
      encryptor.reset(new AesCtrEncryptor);
      break;
    case FOURCC_cbc1:
      encryptor.reset(new AesCbcEncryptor(kNoPadding));
      break;
    case FOURCC_cens:
      encryptor.reset(new AesPatternCryptor(
          crypt_byte_block(), skip_byte_block(), AesCryptor::kDontUseConstantIv,
          scoped_ptr<AesCryptor>(new AesCtrEncryptor)));
      break;
    case FOURCC_cbcs:
      encryptor.reset(new AesPatternCryptor(
          crypt_byte_block(), skip_byte_block(), AesCryptor::kUseConstantIv,
          scoped_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
      break;
    default:
      return Status(error::MUXER_FAILURE, "Unsupported protection scheme.");
  }

  DCHECK(!encryption_key_->iv.empty());
  const bool initialized =
      encryptor->InitializeWithIv(encryption_key_->key, encryption_key_->iv);
  if (!initialized)
    return Status(error::MUXER_FAILURE, "Failed to create the encryptor.");
  encryptor_ = encryptor.Pass();
  return Status::OK;
}

void EncryptingFragmenter::EncryptBytes(uint8_t* data, uint32_t size) {
  DCHECK(encryptor_);
  CHECK(encryptor_->Crypt(data, size, data));
}

Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
  DCHECK(encryptor_);

  SampleEncryptionEntry sample_encryption_entry;
  // For 'cbcs' scheme, Constant IVs SHALL be used.
  if (protection_scheme_ != FOURCC_cbcs)
    sample_encryption_entry.initialization_vector = encryptor_->iv();
  uint8_t* data = sample->writable_data();
  if (IsSubsampleEncryptionRequired()) {
    if (vpx_parser_) {
      std::vector<VPxFrameInfo> vpx_frames;
      if (!vpx_parser_->Parse(sample->data(), sample->data_size(),
                              &vpx_frames)) {
        return Status(error::MUXER_FAILURE, "Failed to parse vpx frame.");
      }

      const bool is_superframe = vpx_frames.size() > 1;
      for (const VPxFrameInfo& frame : vpx_frames) {
        SubsampleEntry subsample;
        subsample.clear_bytes = frame.uncompressed_header_size;
        subsample.cipher_bytes =
            frame.frame_size - frame.uncompressed_header_size;

        // "VP Codec ISO Media File Format Binding" document requires that the
        // encrypted bytes of each frame within the superframe must be block
        // aligned so that the counter state can be computed for each frame
        // within the superframe.
        // For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately so
        // that the cipher data is block aligned.
        if (is_superframe || protection_scheme_ == FOURCC_cbc1) {
          const uint16_t misalign_bytes =
              subsample.cipher_bytes % kCencBlockSize;
          subsample.clear_bytes += misalign_bytes;
          subsample.cipher_bytes -= misalign_bytes;
        }

        sample_encryption_entry.subsamples.push_back(subsample);
        if (subsample.cipher_bytes > 0)
          EncryptBytes(data + subsample.clear_bytes, subsample.cipher_bytes);
        data += frame.frame_size;
      }
    } else {
      const NaluReader::CodecType nalu_type =
          (video_codec_ == kCodecHVC1 || video_codec_ == kCodecHEV1)
              ? NaluReader::kH265
              : NaluReader::kH264;
      NaluReader reader(nalu_type, nalu_length_size_, data,
                        sample->data_size());

      // Store the current length of clear data.  This is used to squash
      // multiple unencrypted NAL units into fewer subsample entries.
      uint64_t accumulated_clear_bytes = 0;

      Nalu nalu;
      NaluReader::Result result;
      while ((result = reader.Advance(&nalu)) == NaluReader::kOk) {
        if (nalu.is_video_slice()) {
          // For video-slice NAL units, encrypt the video slice.  This skips
          // the frame header.  If this is an unrecognized codec (e.g. H.265),
          // the whole NAL unit will be encrypted.
          const int64_t video_slice_header_size =
              header_parser_ ? header_parser_->GetHeaderSize(nalu) : 0;
          if (video_slice_header_size < 0)
            return Status(error::MUXER_FAILURE, "Failed to read slice header.");

          uint64_t current_clear_bytes =
              nalu.header_size() + video_slice_header_size;
          uint64_t cipher_bytes = nalu.payload_size() - video_slice_header_size;

          // For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately
          // so that the cipher data is block aligned.
          if (protection_scheme_ == FOURCC_cbc1) {
            const uint16_t misalign_bytes = cipher_bytes % kCencBlockSize;
            current_clear_bytes += misalign_bytes;
            cipher_bytes -= misalign_bytes;
          }

          const uint8_t* nalu_data = nalu.data() + current_clear_bytes;
          EncryptBytes(const_cast<uint8_t*>(nalu_data), cipher_bytes);

          AddSubsamples(
              accumulated_clear_bytes + nalu_length_size_ + current_clear_bytes,
              cipher_bytes, &sample_encryption_entry.subsamples);
          accumulated_clear_bytes = 0;
        } else {
          // For non-video-slice NAL units, don't encrypt.
          accumulated_clear_bytes +=
              nalu_length_size_ + nalu.header_size() + nalu.payload_size();
        }
      }
      if (result != NaluReader::kEOStream)
        return Status(error::MUXER_FAILURE, "Failed to parse NAL units.");
      AddSubsamples(accumulated_clear_bytes, 0,
                    &sample_encryption_entry.subsamples);
    }

    // The length of per-sample auxiliary datum, defined in CENC ch. 7.
    traf()->auxiliary_size.sample_info_sizes.push_back(
        sample_encryption_entry.ComputeSize());
  } else {
    EncryptBytes(data, sample->data_size());
  }

  traf()->sample_encryption.sample_encryption_entries.push_back(
      sample_encryption_entry);
  encryptor_->UpdateIv();
  return Status::OK;
}

bool EncryptingFragmenter::IsSubsampleEncryptionRequired() {
  return vpx_parser_ || nalu_length_size_ != 0;
}

}  // namespace mp4
}  // namespace media
}  // namespace edash_packager
<commit_msg>Fix an unintended warning message<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "packager/media/formats/mp4/encrypting_fragmenter.h"

#include <limits>

#include "packager/media/base/aes_encryptor.h"
#include "packager/media/base/aes_pattern_cryptor.h"
#include "packager/media/base/buffer_reader.h"
#include "packager/media/base/key_source.h"
#include "packager/media/base/media_sample.h"
#include "packager/media/filters/nalu_reader.h"
#include "packager/media/filters/vp8_parser.h"
#include "packager/media/filters/vp9_parser.h"
#include "packager/media/formats/mp4/box_definitions.h"

namespace edash_packager {
namespace media {
namespace mp4 {

namespace {
const size_t kCencBlockSize = 16u;

// Adds one or more subsamples to |*subsamples|.  This may add more than one
// if one of the values overflows the integer in the subsample.
void AddSubsamples(uint64_t clear_bytes,
                   uint64_t cipher_bytes,
                   std::vector<SubsampleEntry>* subsamples) {
  CHECK_LT(cipher_bytes, std::numeric_limits<uint32_t>::max());
  const uint64_t kUInt16Max = std::numeric_limits<uint16_t>::max();
  while (clear_bytes > kUInt16Max) {
    subsamples->push_back(SubsampleEntry(kUInt16Max, 0));
    clear_bytes -= kUInt16Max;
  }

  if (clear_bytes > 0 || cipher_bytes > 0)
    subsamples->push_back(SubsampleEntry(clear_bytes, cipher_bytes));
}

VideoCodec GetVideoCodec(const StreamInfo& stream_info) {
  if (stream_info.stream_type() != kStreamVideo)
    return kUnknownVideoCodec;
  const VideoStreamInfo& video_stream_info =
      static_cast<const VideoStreamInfo&>(stream_info);
  return video_stream_info.codec();
}

uint8_t GetNaluLengthSize(const StreamInfo& stream_info) {
  if (stream_info.stream_type() != kStreamVideo)
    return 0;

  const VideoStreamInfo& video_stream_info =
      static_cast<const VideoStreamInfo&>(stream_info);
  return video_stream_info.nalu_length_size();
}
}  // namespace

EncryptingFragmenter::EncryptingFragmenter(
    scoped_refptr<StreamInfo> info,
    TrackFragment* traf,
    scoped_ptr<EncryptionKey> encryption_key,
    int64_t clear_time,
    FourCC protection_scheme,
    uint8_t crypt_byte_block,
    uint8_t skip_byte_block)
    : Fragmenter(traf),
      info_(info),
      encryption_key_(encryption_key.Pass()),
      nalu_length_size_(GetNaluLengthSize(*info)),
      video_codec_(GetVideoCodec(*info)),
      clear_time_(clear_time),
      protection_scheme_(protection_scheme),
      crypt_byte_block_(crypt_byte_block),
      skip_byte_block_(skip_byte_block) {
  DCHECK(encryption_key_);
  switch (video_codec_) {
    case kCodecVP8:
      vpx_parser_.reset(new VP8Parser);
      break;
    case kCodecVP9:
      vpx_parser_.reset(new VP9Parser);
      break;
    case kCodecH264:
      header_parser_.reset(new H264VideoSliceHeaderParser);
      break;
    case kCodecHVC1:
      FALLTHROUGH_INTENDED;
    case kCodecHEV1:
      header_parser_.reset(new H265VideoSliceHeaderParser);
      break;
    default:
      if (nalu_length_size_ > 0) {
        LOG(WARNING) << "Unknown video codec '" << video_codec_
                     << "', whole subsamples will be encrypted.";
      }
  }
}

EncryptingFragmenter::~EncryptingFragmenter() {}

Status EncryptingFragmenter::AddSample(scoped_refptr<MediaSample> sample) {
  DCHECK(sample);
  if (!fragment_initialized()) {
    Status status = InitializeFragment(sample->dts());
    if (!status.ok())
      return status;
  }
  if (encryptor_) {
    Status status = EncryptSample(sample);
    if (!status.ok())
      return status;
  }
  return Fragmenter::AddSample(sample);
}

Status EncryptingFragmenter::InitializeFragment(int64_t first_sample_dts) {
  Status status = Fragmenter::InitializeFragment(first_sample_dts);
  if (!status.ok())
    return status;

  if (header_parser_ && !header_parser_->Initialize(info_->extra_data()))
    return Status(error::MUXER_FAILURE, "Fail to read SPS and PPS data.");

  traf()->auxiliary_size.sample_info_sizes.clear();
  traf()->auxiliary_offset.offsets.clear();
  if (IsSubsampleEncryptionRequired()) {
    traf()->sample_encryption.flags |=
        SampleEncryption::kUseSubsampleEncryption;
  }
  traf()->sample_encryption.sample_encryption_entries.clear();

  const bool enable_encryption = clear_time_ <= 0;
  if (!enable_encryption) {
    // This fragment should be in clear text.
    // At most two sample description entries, an encrypted entry and a clear
    // entry, are generated. The 1-based clear entry index is always 2.
    const uint32_t kClearSampleDescriptionIndex = 2;

    traf()->header.flags |=
        TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
    traf()->header.sample_description_index = kClearSampleDescriptionIndex;
  }
  return PrepareFragmentForEncryption(enable_encryption);
}

void EncryptingFragmenter::FinalizeFragment() {
  if (encryptor_) {
    DCHECK_LE(clear_time_, 0);
    FinalizeFragmentForEncryption();
  } else {
    DCHECK_GT(clear_time_, 0);
    clear_time_ -= fragment_duration();
  }
  Fragmenter::FinalizeFragment();
}

Status EncryptingFragmenter::PrepareFragmentForEncryption(
    bool enable_encryption) {
  return (!enable_encryption || encryptor_) ? Status::OK : CreateEncryptor();
}

void EncryptingFragmenter::FinalizeFragmentForEncryption() {
  // The offset will be adjusted in Segmenter after knowing moof size.
  traf()->auxiliary_offset.offsets.push_back(0);

  // For 'cbcs' scheme, Constant IVs SHALL be used.
  const size_t per_sample_iv_size =
      (protection_scheme_ == FOURCC_cbcs) ? 0 : encryptor_->iv().size();
  traf()->sample_encryption.iv_size = per_sample_iv_size;

  // Optimize saiz box.
  SampleAuxiliaryInformationSize& saiz = traf()->auxiliary_size;
  saiz.sample_count = traf()->runs[0].sample_sizes.size();
  if (!saiz.sample_info_sizes.empty()) {
    if (!OptimizeSampleEntries(&saiz.sample_info_sizes,
                               &saiz.default_sample_info_size)) {
      saiz.default_sample_info_size = 0;
    }
  } else {
    // |sample_info_sizes| table is filled in only for subsample encryption,
    // otherwise |sample_info_size| is just the IV size.
    DCHECK(!IsSubsampleEncryptionRequired());
    saiz.default_sample_info_size = per_sample_iv_size;
  }
  // It should only happen with full sample encryption + constant iv, which is
  // not a legal combination.
  CHECK(!saiz.sample_info_sizes.empty() || saiz.default_sample_info_size != 0);
}

Status EncryptingFragmenter::CreateEncryptor() {
  DCHECK(encryption_key_);
  scoped_ptr<AesCryptor> encryptor;
  switch (protection_scheme_) {
    case FOURCC_cenc:
      encryptor.reset(new AesCtrEncryptor);
      break;
    case FOURCC_cbc1:
      encryptor.reset(new AesCbcEncryptor(kNoPadding));
      break;
    case FOURCC_cens:
      encryptor.reset(new AesPatternCryptor(
          crypt_byte_block(), skip_byte_block(), AesCryptor::kDontUseConstantIv,
          scoped_ptr<AesCryptor>(new AesCtrEncryptor)));
      break;
    case FOURCC_cbcs:
      encryptor.reset(new AesPatternCryptor(
          crypt_byte_block(), skip_byte_block(), AesCryptor::kUseConstantIv,
          scoped_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
      break;
    default:
      return Status(error::MUXER_FAILURE, "Unsupported protection scheme.");
  }

  DCHECK(!encryption_key_->iv.empty());
  const bool initialized =
      encryptor->InitializeWithIv(encryption_key_->key, encryption_key_->iv);
  if (!initialized)
    return Status(error::MUXER_FAILURE, "Failed to create the encryptor.");
  encryptor_ = encryptor.Pass();
  return Status::OK;
}

void EncryptingFragmenter::EncryptBytes(uint8_t* data, uint32_t size) {
  DCHECK(encryptor_);
  CHECK(encryptor_->Crypt(data, size, data));
}

Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
  DCHECK(encryptor_);

  SampleEncryptionEntry sample_encryption_entry;
  // For 'cbcs' scheme, Constant IVs SHALL be used.
  if (protection_scheme_ != FOURCC_cbcs)
    sample_encryption_entry.initialization_vector = encryptor_->iv();
  uint8_t* data = sample->writable_data();
  if (IsSubsampleEncryptionRequired()) {
    if (vpx_parser_) {
      std::vector<VPxFrameInfo> vpx_frames;
      if (!vpx_parser_->Parse(sample->data(), sample->data_size(),
                              &vpx_frames)) {
        return Status(error::MUXER_FAILURE, "Failed to parse vpx frame.");
      }

      const bool is_superframe = vpx_frames.size() > 1;
      for (const VPxFrameInfo& frame : vpx_frames) {
        SubsampleEntry subsample;
        subsample.clear_bytes = frame.uncompressed_header_size;
        subsample.cipher_bytes =
            frame.frame_size - frame.uncompressed_header_size;

        // "VP Codec ISO Media File Format Binding" document requires that the
        // encrypted bytes of each frame within the superframe must be block
        // aligned so that the counter state can be computed for each frame
        // within the superframe.
        // For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately so
        // that the cipher data is block aligned.
        if (is_superframe || protection_scheme_ == FOURCC_cbc1) {
          const uint16_t misalign_bytes =
              subsample.cipher_bytes % kCencBlockSize;
          subsample.clear_bytes += misalign_bytes;
          subsample.cipher_bytes -= misalign_bytes;
        }

        sample_encryption_entry.subsamples.push_back(subsample);
        if (subsample.cipher_bytes > 0)
          EncryptBytes(data + subsample.clear_bytes, subsample.cipher_bytes);
        data += frame.frame_size;
      }
    } else {
      const NaluReader::CodecType nalu_type =
          (video_codec_ == kCodecHVC1 || video_codec_ == kCodecHEV1)
              ? NaluReader::kH265
              : NaluReader::kH264;
      NaluReader reader(nalu_type, nalu_length_size_, data,
                        sample->data_size());

      // Store the current length of clear data.  This is used to squash
      // multiple unencrypted NAL units into fewer subsample entries.
      uint64_t accumulated_clear_bytes = 0;

      Nalu nalu;
      NaluReader::Result result;
      while ((result = reader.Advance(&nalu)) == NaluReader::kOk) {
        if (nalu.is_video_slice()) {
          // For video-slice NAL units, encrypt the video slice.  This skips
          // the frame header.  If this is an unrecognized codec (e.g. H.265),
          // the whole NAL unit will be encrypted.
          const int64_t video_slice_header_size =
              header_parser_ ? header_parser_->GetHeaderSize(nalu) : 0;
          if (video_slice_header_size < 0)
            return Status(error::MUXER_FAILURE, "Failed to read slice header.");

          uint64_t current_clear_bytes =
              nalu.header_size() + video_slice_header_size;
          uint64_t cipher_bytes = nalu.payload_size() - video_slice_header_size;

          // For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately
          // so that the cipher data is block aligned.
          if (protection_scheme_ == FOURCC_cbc1) {
            const uint16_t misalign_bytes = cipher_bytes % kCencBlockSize;
            current_clear_bytes += misalign_bytes;
            cipher_bytes -= misalign_bytes;
          }

          const uint8_t* nalu_data = nalu.data() + current_clear_bytes;
          EncryptBytes(const_cast<uint8_t*>(nalu_data), cipher_bytes);

          AddSubsamples(
              accumulated_clear_bytes + nalu_length_size_ + current_clear_bytes,
              cipher_bytes, &sample_encryption_entry.subsamples);
          accumulated_clear_bytes = 0;
        } else {
          // For non-video-slice NAL units, don't encrypt.
          accumulated_clear_bytes +=
              nalu_length_size_ + nalu.header_size() + nalu.payload_size();
        }
      }
      if (result != NaluReader::kEOStream)
        return Status(error::MUXER_FAILURE, "Failed to parse NAL units.");
      AddSubsamples(accumulated_clear_bytes, 0,
                    &sample_encryption_entry.subsamples);
    }

    // The length of per-sample auxiliary datum, defined in CENC ch. 7.
    traf()->auxiliary_size.sample_info_sizes.push_back(
        sample_encryption_entry.ComputeSize());
  } else {
    EncryptBytes(data, sample->data_size());
  }

  traf()->sample_encryption.sample_encryption_entries.push_back(
      sample_encryption_entry);
  encryptor_->UpdateIv();
  return Status::OK;
}

bool EncryptingFragmenter::IsSubsampleEncryptionRequired() {
  return vpx_parser_ || nalu_length_size_ != 0;
}

}  // namespace mp4
}  // namespace media
}  // namespace edash_packager
<|endoftext|>


<commit_before>#include "ConnectionNonBlocking.h"
#include <iostream>

namespace ThorsAnvil
{
    namespace NisseSQL
    {

class MySQLConnectionHandler: public ThorsAnvil::Nisse::NisseHandler
{
    CoRoutine               worker;
    public:
        MySQLConnectionHandler(ThorsAnvil::Nisse::NisseService& service,
                               ConnectionNonBlocking& connection,
                               ThorsAnvil::MySQL::MySQLStream& stream,
                               std::string const& username,
                               std::string const& password,
                               std::string const& database,
                               ThorsAnvil::SQL::Options const& options)
            : NisseHandler(service, stream.getSocketId(), EV_READ | EV_WRITE)
            , worker([&connection, &stream, &username, &password, &database, &options](Yield& yield)
                {
                    std::cerr << "MySQLConnectionHandler: Worker\n";
                    yield(EV_WRITE);
                    std::cerr << "MySQLConnectionHandler: Worder: Setting Yield\n";
                    ThorsAnvil::MySQL::YieldSetter  setter(stream, [&yield](){yield(EV_READ);}, [&yield](){yield(EV_WRITE);});
                    std::cerr << "MySQLConnectionHandler: Worder: Setting Connecting to server\n";
                    connection.doConectToServer(username, password, database, options);
                    std::cerr << "MySQLConnectionHandler: Worder: DONE\n";
                })
        {
            std::cerr << "MySQLConnectionHandler: CONSTRUCTOR\n";
        }
        virtual short eventActivate(ThorsAnvil::Nisse::LibSocketId /*sockId*/, short /*eventType*/)
        {
            std::cerr << "We Can Write To DB\n";
            if (!worker())
            {
                std::cerr << "event Activate Finished\n";
                dropHandler();
                return 0;
            }
            short x = worker.get();
            std::cerr << "DB connection Blocked: " << (x & EV_READ ? "READ" : "NR") << " : " << (x & EV_WRITE ? "WRITE" : "NW") << "\n";
            return worker.get();
        }
};

    }
}

using namespace ThorsAnvil::NisseSQL;

ConnectionNonBlocking::ConnectionNonBlocking(
        ThorsAnvil::MySQL::MySQLStream& stream,
        std::string const& username,
        std::string const& password,
        std::string const& database,
        ThorsAnvil::SQL::Options const& options,
        ThorsAnvil::MySQL::ConectReader& packageReader,
        ThorsAnvil::MySQL::ConectWriter& packageWriter
)
    : Connection(username, password, database, options, packageReader, packageWriter)
    , stream(stream)
{
std::cerr << "ConnectionNonBlocking::ConnectionNonBlocking\n";
    auto& service = ThorsAnvil::Nisse::NisseService::getCurrentHandler();
std::cerr << "ConnectionNonBlocking: Service: " << &service << "\n";
    service.transferHandler<MySQLConnectionHandler>(*this, stream, username, password, database, options);
std::cerr << "Transfer Returned\n";
}

void ConnectionNonBlocking::doConectToServer(
        std::string const& username,
        std::string const& password,
        std::string const& database,
        ThorsAnvil::SQL::Options const& options
)
{
    std::cerr << "doConectToServer: " << username << " : " << password << " : " << database << "\n";
    conectToServer(username, password, database, options);
}
<commit_msg>Remove print statements<commit_after>#include "ConnectionNonBlocking.h"
#include <iostream>

namespace ThorsAnvil
{
    namespace NisseSQL
    {

class MySQLConnectionHandler: public ThorsAnvil::Nisse::NisseHandler
{
    CoRoutine               worker;
    public:
        MySQLConnectionHandler(ThorsAnvil::Nisse::NisseService& service,
                               ConnectionNonBlocking& connection,
                               ThorsAnvil::MySQL::MySQLStream& stream,
                               std::string const& username,
                               std::string const& password,
                               std::string const& database,
                               ThorsAnvil::SQL::Options const& options)
            : NisseHandler(service, stream.getSocketId(), EV_READ | EV_WRITE)
            , worker([&connection, &stream, &username, &password, &database, &options](Yield& yield)
                {
                    yield(EV_WRITE);
                    ThorsAnvil::MySQL::YieldSetter  setter(stream, [&yield](){yield(EV_READ);}, [&yield](){yield(EV_WRITE);});
                    connection.doConectToServer(username, password, database, options);
                })
        {
        }
        virtual short eventActivate(ThorsAnvil::Nisse::LibSocketId /*sockId*/, short /*eventType*/)
        {
            if (!worker())
            {
                dropHandler();
                return 0;
            }
            return worker.get();
        }
};

    }
}

using namespace ThorsAnvil::NisseSQL;

ConnectionNonBlocking::ConnectionNonBlocking(
        ThorsAnvil::MySQL::MySQLStream& stream,
        std::string const& username,
        std::string const& password,
        std::string const& database,
        ThorsAnvil::SQL::Options const& options,
        ThorsAnvil::MySQL::ConectReader& packageReader,
        ThorsAnvil::MySQL::ConectWriter& packageWriter
)
    : Connection(username, password, database, options, packageReader, packageWriter)
    , stream(stream)
{
    auto& service = ThorsAnvil::Nisse::NisseService::getCurrentHandler();
    service.transferHandler<MySQLConnectionHandler>(*this, stream, username, password, database, options);
}

void ConnectionNonBlocking::doConectToServer(
        std::string const& username,
        std::string const& password,
        std::string const& database,
        ThorsAnvil::SQL::Options const& options
)
{
    conectToServer(username, password, database, options);
}
<|endoftext|>


<commit_before>

#include <tclap/CmdLine.h>
#include <iostream>
#include <string>

using namespace TCLAP;
using namespace std;

string _orTest;
string _orTest2;
string _testc;
bool _testd;

void parseOptions(int argc, char** argv);

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

	parseOptions(argc,argv);

	cout << "for A OR B we got : " << _orTest<< endl
		 << "for string C we got : " << _testc << endl
		 << "for string D we got : " << _testd << endl
		 << "for E or F or G we got: " << _orTest2 << endl;

}

void parseOptions(int argc, char** argv)
{
	try {

	CmdLine cmd("this is a message", ' ', "0.99" );

	//
	// Define arguments
	//

	ValueArg<string> atest("a", "aaa", "or test a", true, "homer", "string");
	ValueArg<string> btest("b", "bbb", "or test b", true, "homer", "string");
	cmd.xorAdd( atest, btest );

	ValueArg<string> ctest("c", "ccc", "c test", true, "homer", "string");
	cmd.add( ctest );

	SwitchArg dtest("", "ddd", "d test", false);
	cmd.add( dtest );

	ValueArg<string> etest("", "eee", "e test", false, "homer", "string");
	ValueArg<string> ftest("", "fff", "f test", false, "homer", "string");
	ValueArg<string> gtest("g", "ggg", "g test", false, "homer", "string");
	vector<Arg*> xorlist;
	xorlist.push_back(&etest);
	xorlist.push_back(&ftest);
	xorlist.push_back(&gtest);
	cmd.xorAdd( xorlist );

	//
	// Parse the command line.
	//
	cmd.parse(argc,argv);

	//
	// Set variables
	//

	if ( atest.isSet() )
		_orTest = atest.getValue();
	else if ( btest.isSet() )
		_orTest = btest.getValue();
	else
		// Should never get here because TCLAP will note that one of the
		// required args above has not been set.
		throw("very bad things...");

	_testc = ctest.getValue();
	_testd = dtest.getValue();

	if ( etest.isSet() )
		_orTest2 = etest.getValue();
	else if ( ftest.isSet() )
		_orTest2 = ftest.getValue();
	else if ( gtest.isSet() )
		_orTest2 = gtest.getValue();
	else
		throw("still bad");

	} catch ( ArgException& e )
	{ cout << "ERROR: " << e.error() << " " << e.argId() << endl; }
}

<commit_msg>change for xor bug<commit_after>

#include <tclap/CmdLine.h>
#include <iostream>
#include <string>

using namespace TCLAP;
using namespace std;

string _orTest;
string _orTest2;
string _testc;
bool _testd;

void parseOptions(int argc, char** argv);

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

	parseOptions(argc,argv);

	cout << "for A OR B we got : " << _orTest<< endl
		 << "for string C we got : " << _testc << endl
		 << "for string D we got : " << _testd << endl
		 << "for E or F or G we got: " << _orTest2 << endl;

}

void parseOptions(int argc, char** argv)
{
	try {

	CmdLine cmd("this is a message", ' ', "0.99" );

	//
	// Define arguments
	//

	ValueArg<string> atest("a", "aaa", "or test a", true, "homer", "string");
	ValueArg<string> btest("b", "bbb", "or test b", true, "homer", "string");
	cmd.xorAdd( atest, btest );

	ValueArg<string> ctest("c", "ccc", "c test", true, "homer", "string");
	cmd.add( ctest );

	SwitchArg dtest("", "ddd", "d test", false);
	cmd.add( dtest );

	ValueArg<string> etest("", "eee", "e test", false, "homer", "string");
	ValueArg<string> ftest("", "fff", "f test", false, "homer", "string");
	ValueArg<string> gtest("g", "ggg", "g test", false, "homer", "string");
	vector<Arg*> xorlist;
	xorlist.push_back(&etest);
	xorlist.push_back(&ftest);
	xorlist.push_back(&gtest);
	cmd.xorAdd( xorlist );

	MultiArg<string> itest("i", "iii", "or test i", true, "string");
	MultiArg<string> jtest("j", "jjj", "or test j", true, "string");
	cmd.xorAdd( itest, jtest );

	//
	// Parse the command line.
	//
	cmd.parse(argc,argv);

	//
	// Set variables
	//

	if ( atest.isSet() )
		_orTest = atest.getValue();
	else if ( btest.isSet() )
		_orTest = btest.getValue();
	else
		// Should never get here because TCLAP will note that one of the
		// required args above has not been set.
		throw("very bad things...");

	_testc = ctest.getValue();
	_testd = dtest.getValue();

	if ( etest.isSet() )
		_orTest2 = etest.getValue();
	else if ( ftest.isSet() )
		_orTest2 = ftest.getValue();
	else if ( gtest.isSet() )
		_orTest2 = gtest.getValue();
	else
		throw("still bad");

    if ( jtest.isSet() )
    {
        cout << "for J:" << endl;
        vector<string> v = jtest.getValue();
        for ( int z = 0; (unsigned int)z < v.size(); z++ )
            cout << " " << z << "  " << v[z] << endl;
    }
    else if ( itest.isSet() )
    {
        cout << "for I:" << endl;
        vector<string> v = itest.getValue();
        for ( int z = 0; (unsigned int)z < v.size(); z++ )
            cout << " " << z << "  " << v[z] << endl;
    }
    else
		throw("yup, still bad");

	} catch ( ArgException& e )
	{ cout << "ERROR: " << e.error() << " " << e.argId() << endl; }
}

<|endoftext|>


<commit_before><commit_msg>Enable lossless colour by default.<commit_after><|endoftext|>


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

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

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_
#include <pattern/window.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_PERSISTENTWINDOWSTATE_HXX_
#include <helper/persistentwindowstate.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
#include <comphelper/configurationhelper.hxx>
#endif

#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _SV_SYSWIN_HXX
#include <vcl/syswin.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace

namespace framework{

namespace fpw = ::framework::pattern::window;

//_________________________________________________________________________________________________________________
//  definitions

//*****************************************************************************************************************
//  XInterface, XTypeProvider

DEFINE_XINTERFACE_4(PersistentWindowState                                                       ,
                    OWeakObject                                                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider                                  ),
                    DIRECT_INTERFACE (css::lang::XInitialization                                ),
                    DIRECT_INTERFACE (css::frame::XFrameActionListener                          ),
                    DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))

DEFINE_XTYPEPROVIDER_4(PersistentWindowState           ,
                       css::lang::XTypeProvider        ,
                       css::lang::XInitialization      ,
                       css::frame::XFrameActionListener,
                       css::lang::XEventListener       )

//*****************************************************************************************************************
PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase          (&Application::GetSolarMutex())
    , m_xSMGR                 (xSMGR                        )
    , m_bWindowStateAlreadySet(sal_False                    )
{
}

//*****************************************************************************************************************
PersistentWindowState::~PersistentWindowState()
{
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // check arguments
    css::uno::Reference< css::frame::XFrame > xFrame;
    if (lArguments.getLength() < 1)
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("Empty argument list!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    lArguments[0] >>= xFrame;
    if (!xFrame.is())
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("No valid frame specified!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    // hold the frame as weak reference(!) so it can die everytimes :-)
    m_xFrame = xFrame;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    // start listening
    xFrame->addFrameActionListener(this);
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
    css::uno::Reference< css::frame::XFrame >              xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
//    sal_Bool                                               bRestoreWindowState = !m_bWindowStateAlreadySet;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // frame already gone ? We hold it weak only ...
    if (!xFrame.is())
        return;

    // no window -> no position and size available
    css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
    if (!xWindow.is())
        return;

    // unknown module -> no configuration available!
    ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
    if (!sModuleName.getLength())
        return;

    switch(aEvent.Action)
    {
        /*
        case css::frame::FrameAction_COMPONENT_ATTACHED :
            {
                if (bRestoreWindowState)
                {
                    ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
                    PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
                    // SAFE -> ----------------------------------
                    WriteGuard aWriteLock(m_aLock);
                    m_bWindowStateAlreadySet = sal_True;
                    aWriteLock.unlock();
                    // <- SAFE ----------------------------------
                }
            }
            break;
        */

        case css::frame::FrameAction_COMPONENT_REATTACHED :
            {
                // nothing todo here, because its not allowed to change position and size
                // of an alredy existing frame!
            }
            break;

        case css::frame::FrameAction_COMPONENT_DETACHING :
            {
                ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
                PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
            }
            break;
        default:
            break;
    }
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
    throw(css::uno::RuntimeException)
{
    // nothing todo here - because we hold the frame as weak reference only
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
                                                             const css::uno::Reference< css::frame::XFrame >&              xFrame)
{
    ::rtl::OUString sModuleName;

    css::uno::Reference< css::frame::XModuleManager > xModuleManager(
        xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
        css::uno::UNO_QUERY_THROW);

    try
    {
        sModuleName = xModuleManager->identify(xFrame);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sModuleName = ::rtl::OUString(); }

    return sModuleName;
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR      ,
                                                                       const ::rtl::OUString&                                        sModuleName)
{
    ::rtl::OUString sWindowState;

    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        css::uno::Any aWindowState = ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
                                                                                sPackage,
                                                                                sRelPath,
                                                                                sKey,
                                                                                ::comphelper::ConfigurationHelper::E_READONLY);
        aWindowState >>= sWindowState;
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sWindowState = ::rtl::OUString(); }

    return sWindowState;
}

//*****************************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR       ,
                                                          const ::rtl::OUString&                                        sModuleName ,
                                                          const ::rtl::OUString&                                        sWindowState)
{
    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
                                                          sPackage,
                                                          sRelPath,
                                                          sKey,
                                                          css::uno::makeAny(sWindowState),
                                                          ::comphelper::ConfigurationHelper::E_STANDARD);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
{
    ::rtl::OUString sWindowState;

    if (xWindow.is())
    {
        // SOLAR SAFE -> ------------------------
        ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

        Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
        // check for system window is neccessary to guarantee correct pointer cast!
        if (
            (pWindow                  ) &&
            (pWindow->IsSystemWindow())
           )
        {
            ULONG nMask  =   WINDOWSTATE_MASK_ALL;
                  nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
            sWindowState = B2U_ENC(
                            ((SystemWindow*)pWindow)->GetWindowState(nMask),
                            RTL_TEXTENCODING_UTF8);
        }

        aSolarLock.clear();
        // <- SOLAR SAFE ------------------------
    }

    return sWindowState;
}

//*********************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& /*xWindow*/     ,
                                                          const ::rtl::OUString&                          /*sWindowState*/)
{
    /*
    if (
        (!xWindow.is()                ) ||
        ( sWindowState.getLength() < 1)
       )
        return;

    // SOLAR SAFE -> ------------------------
    ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

    Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
    if (!pWindow)
        return;

    // check for system and work window - its neccessary to guarantee correct pointer cast!
    sal_Bool bSystemWindow = pWindow->IsSystemWindow();
    sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);

    if (!bSystemWindow && !bWorkWindow)
        return;

    SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
    WorkWindow*   pWorkWindow   = (WorkWindow*  )pWindow;

    // dont save this special state!
    if (pWorkWindow->IsMinimized())
        return;

    pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));

    aSolarLock.clear();
    // <- SOLAR SAFE ------------------------
    */
}

} // namespace framework
<commit_msg>INTEGRATION: CWS fwkdbdesign01 (1.12.84); FILE MERGED 2007/02/19 10:58:45 as 1.12.84.1: #i74541# make framework ready for real sub frames<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: persistentwindowstate.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: ihi $ $Date: 2007-04-16 16:41:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_
#include <pattern/window.hxx>
#endif

#ifndef __FRAMEWORK_HELPER_PERSISTENTWINDOWSTATE_HXX_
#include <helper/persistentwindowstate.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICXEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
#include <com/sun/star/frame/XModuleManager.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_
#include <comphelper/configurationhelper.hxx>
#endif

#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _SV_SYSWIN_HXX
#include <vcl/syswin.hxx>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

//_________________________________________________________________________________________________________________
//  namespace

namespace framework{

namespace fpw = ::framework::pattern::window;

//_________________________________________________________________________________________________________________
//  definitions

//*****************************************************************************************************************
//  XInterface, XTypeProvider

DEFINE_XINTERFACE_4(PersistentWindowState                                                       ,
                    OWeakObject                                                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider                                  ),
                    DIRECT_INTERFACE (css::lang::XInitialization                                ),
                    DIRECT_INTERFACE (css::frame::XFrameActionListener                          ),
                    DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))

DEFINE_XTYPEPROVIDER_4(PersistentWindowState           ,
                       css::lang::XTypeProvider        ,
                       css::lang::XInitialization      ,
                       css::frame::XFrameActionListener,
                       css::lang::XEventListener       )

//*****************************************************************************************************************
PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase          (&Application::GetSolarMutex())
    , m_xSMGR                 (xSMGR                        )
    , m_bWindowStateAlreadySet(sal_False                    )
{
}

//*****************************************************************************************************************
PersistentWindowState::~PersistentWindowState()
{
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
    throw(css::uno::Exception       ,
          css::uno::RuntimeException)
{
    // check arguments
    css::uno::Reference< css::frame::XFrame > xFrame;
    if (lArguments.getLength() < 1)
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("Empty argument list!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    lArguments[0] >>= xFrame;
    if (!xFrame.is())
        throw css::lang::IllegalArgumentException(
                DECLARE_ASCII("No valid frame specified!"),
                static_cast< ::cppu::OWeakObject* >(this),
                1);

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    // hold the frame as weak reference(!) so it can die everytimes :-)
    m_xFrame = xFrame;
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    // start listening
    xFrame->addFrameActionListener(this);
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
    css::uno::Reference< css::frame::XFrame >              xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
    sal_Bool                                               bRestoreWindowState = !m_bWindowStateAlreadySet;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // frame already gone ? We hold it weak only ...
    if (!xFrame.is())
        return;

    // no window -> no position and size available
    css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
    if (!xWindow.is())
        return;

    // unknown module -> no configuration available!
    ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
    if (!sModuleName.getLength())
        return;

    switch(aEvent.Action)
    {
        case css::frame::FrameAction_COMPONENT_ATTACHED :
            {
                if (bRestoreWindowState)
                {
                    ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
                    PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
                    // SAFE -> ----------------------------------
                    WriteGuard aWriteLock(m_aLock);
                    m_bWindowStateAlreadySet = sal_True;
                    aWriteLock.unlock();
                    // <- SAFE ----------------------------------
                }
            }
            break;

        case css::frame::FrameAction_COMPONENT_REATTACHED :
            {
                // nothing todo here, because its not allowed to change position and size
                // of an alredy existing frame!
            }
            break;

        case css::frame::FrameAction_COMPONENT_DETACHING :
            {
                ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
                PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
            }
            break;
        default:
            break;
    }
}

//*****************************************************************************************************************
void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
    throw(css::uno::RuntimeException)
{
    // nothing todo here - because we hold the frame as weak reference only
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
                                                             const css::uno::Reference< css::frame::XFrame >&              xFrame)
{
    ::rtl::OUString sModuleName;

    css::uno::Reference< css::frame::XModuleManager > xModuleManager(
        xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
        css::uno::UNO_QUERY_THROW);

    try
    {
        sModuleName = xModuleManager->identify(xFrame);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sModuleName = ::rtl::OUString(); }

    return sModuleName;
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR      ,
                                                                       const ::rtl::OUString&                                        sModuleName)
{
    ::rtl::OUString sWindowState;

    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        css::uno::Any aWindowState = ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
                                                                                sPackage,
                                                                                sRelPath,
                                                                                sKey,
                                                                                ::comphelper::ConfigurationHelper::E_READONLY);
        aWindowState >>= sWindowState;
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { sWindowState = ::rtl::OUString(); }

    return sWindowState;
}

//*****************************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR       ,
                                                          const ::rtl::OUString&                                        sModuleName ,
                                                          const ::rtl::OUString&                                        sWindowState)
{
    ::rtl::OUStringBuffer sRelPathBuf(256);
    sRelPathBuf.appendAscii("Office/Factories/*[\"");
    sRelPathBuf.append     (sModuleName            );
    sRelPathBuf.appendAscii("\"]"                  );

    ::rtl::OUString sPackage = ::rtl::OUString::createFromAscii("org.openoffice.Setup/");
    ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
    ::rtl::OUString sKey     = ::rtl::OUString::createFromAscii("ooSetupFactoryWindowAttributes");

    try
    {
        ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
                                                          sPackage,
                                                          sRelPath,
                                                          sKey,
                                                          css::uno::makeAny(sWindowState),
                                                          ::comphelper::ConfigurationHelper::E_STANDARD);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

//*****************************************************************************************************************
::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
{
    ::rtl::OUString sWindowState;

    if (xWindow.is())
    {
        // SOLAR SAFE -> ------------------------
        ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

        Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
        // check for system window is neccessary to guarantee correct pointer cast!
        if (
            (pWindow                  ) &&
            (pWindow->IsSystemWindow())
           )
        {
            ULONG nMask  =   WINDOWSTATE_MASK_ALL;
                  nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
            sWindowState = B2U_ENC(
                            ((SystemWindow*)pWindow)->GetWindowState(nMask),
                            RTL_TEXTENCODING_UTF8);
        }

        aSolarLock.clear();
        // <- SOLAR SAFE ------------------------
    }

    return sWindowState;
}

//*********************************************************************************************************
void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow     ,
                                                          const ::rtl::OUString&                          sWindowState)
{
    if (
        (!xWindow.is()                ) ||
        ( sWindowState.getLength() < 1)
       )
        return;

    // SOLAR SAFE -> ------------------------
    ::vos::OClearableGuard aSolarLock(Application::GetSolarMutex());

    Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
    if (!pWindow)
        return;

    // check for system and work window - its neccessary to guarantee correct pointer cast!
    sal_Bool bSystemWindow = pWindow->IsSystemWindow();
    sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);

    if (!bSystemWindow && !bWorkWindow)
        return;

    SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
    WorkWindow*   pWorkWindow   = (WorkWindow*  )pWindow;

    // dont save this special state!
    if (pWorkWindow->IsMinimized())
        return;

    pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));

    aSolarLock.clear();
    // <- SOLAR SAFE ------------------------
}

} // namespace framework
<|endoftext|>