<commit_before>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA
*/
#include <algorithm>
#include <plugin.h>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f) {
                       return f.amp() >= thrsh ? f : csnd::pv_bin();
                     });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct binamp {
  int bin;
  float amp;
};

struct PVTrace2 : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  csnd::AuxMem<binamp> binlist;
  static constexpr char const *otypes = "fk[]";
  static constexpr char const *itypes = "fk";

  int init() {
    csnd::Vector<MYFLT> &bins = outargs.vector_data<MYFLT>(1);
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    binlist.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));

    bins.init(csound, inargs.fsig_data(0).nbins());

    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);
    csnd::Vector<MYFLT> &bins = outargs.vector_data<MYFLT>(1);
    csnd::AuxMem<binamp> &mbins = binlist;

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      int cnt = 0;
      int bin = 0;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh, &mbins, &cnt, &bin](csnd::pv_bin f) {
                       if(f.amp() >= thrsh) {
                       mbins[cnt].bin = bin++;
                       mbins[cnt++].amp = f.amp();
                       return f;
                       }
                       else {
                        bin++;
                        return csnd::pv_bin();
                       }
                     });
      std::sort(binlist.begin(), binlist.begin()+cnt, [](binamp &a, binamp &b) {
          return (a.amp > b.amp);
      });
      std::transform(binlist.begin(), binlist.begin()+cnt, bins.begin(),
                     [](binamp a) { return (MYFLT) a.bin;});

      std::fill(bins.begin()+cnt, bins.end(), FL(0.0));

      framecount = fout.count(fin.count());
    }

    return OK;
  }
};

struct TVConv : csnd::Plugin<1, 6> {
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
  csnd::AuxMem<MYFLT> insp;
  csnd::AuxMem<MYFLT> irsp;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  csnd::AuxMem<MYFLT>::iterator itn;
  csnd::AuxMem<MYFLT>::iterator itr;
  csnd::AuxMem<MYFLT>::iterator itnsp;
  csnd::AuxMem<MYFLT>::iterator itrsp;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  csnd::fftp fwd, inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
    uint32_t v = 2;
    while (v <= n)
      v <<= 1;
    if ((n - (v >> 1)) < (v - n))
      return v >> 1;
    else
      return v;
  }

  cmplx *to_cmplx(MYFLT *f) { return reinterpret_cast<cmplx *>(f); }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real() * b.real(), a.imag() * b.imag());
  }

  int init() {
    pars = inargs[4];
    fils = inargs[5];
    if (pars > fils)
      std::swap(pars, fils);
    if (pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils) * 2;
      ffts = pars * 2;
      fwd = csound->fft_setup(ffts, FFT_FWD);
      inv = csound->fft_setup(ffts, FFT_INV);
      out.allocate(csound, ffts);
      insp.allocate(csound, fils);
      irsp.allocate(csound, fils);
      saved.allocate(csound, pars);
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
      itnsp = insp.begin();
      itrsp = insp.begin();
      n = 0;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    itn = in.begin();
    itr = ir.begin();
    return OK;
  }

  int pconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto *frz1 = inargs(2);
    auto *frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        itn[n] = *inp;
      if (*frz2 > 0)
        itr[n] = *irp;

      s = out[n] + saved[n];
      saved[n] = out[n + pars];
      if (++n == pars) {
        cmplx *ins, *irs, *ous = to_cmplx(out.data());
        std::copy(itn, itn + ffts, itnsp);
        std::copy(itr, itr + ffts, itrsp);
        std::fill(out.begin(), out.end(), 0.);
        // FFT
        csound->rfft(fwd, itnsp);
        csound->rfft(fwd, itrsp);
        // increment iterators
        itnsp += ffts, itrsp += ffts;
        itn += ffts, itr += ffts;
        if (itnsp == insp.end()) {
          itnsp = insp.begin();
          itrsp = irsp.begin();
          itn = in.begin();
          itr = ir.begin();
        }
        // spectral delay line
        for (csnd::AuxMem<MYFLT>::iterator it1 = itnsp, it2 = irsp.end() - ffts;
             it2 >= irsp.begin(); it1 += ffts, it2 -= ffts) {
          if (it1 == insp.end())
            it1 = insp.begin();
          ins = to_cmplx(it1);
          irs = to_cmplx(it2);
          // spectral product
          for (uint32_t i = 1; i < pars; i++)
            ous[i] += ins[i] * irs[i];
          ous[0] += real_prod(ins[0], irs[0]);
        }
        // IFFT
        csound->rfft(inv, out.data());
        n = 0;
      }
      frz1 += inc1, frz2 += inc2;
      irp++, inp++;
    }
    return OK;
  }

  int dconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto frz1 = inargs(2);
    auto frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        *itn = *inp;
      if (*frz2 > 0)
        *itr = *irp;
      itn++, itr++;
      if (itn == in.end()) {
        itn = in.begin();
        itr = ir.begin();
      }
      s = 0.;
      for (csnd::AuxMem<MYFLT>::iterator it1 = itn, it2 = ir.end() - 1;
           it2 >= ir.begin(); it1++, it2--) {
        if (it1 == in.end())
          it1 = in.begin();
        s += *it1 * *it2;
      }
      frz1 += inc1, frz2 += inc2;
      inp++, irp++;
    }
    return OK;
  }

  int aperf() {
    if (pars > 1)
      return pconv();
    else
      return dconv();
  }
};

/*
class PrintThread : public csnd::Thread {
  std::atomic_bool splock;
  std::atomic_bool on;
  std::string message;

  void lock() {
    bool tmp = false;
    while(!splock.compare_exchange_weak(tmp,true))
      tmp = false;
  }

  void unlock() {
    splock = false;
  }

  uintptr_t run() {
    std::string old;
    while(on) {
      lock();
      if(old.compare(message)) {
       csound->message(message.c_str());
       old = message;
      }
      unlock();
    }
    return 0;
  }

public:
  PrintThread(csnd::Csound *csound)
    : Thread(csound), splock(false), on(true), message("") {};

  ~PrintThread(){
    on = false;
    join();
  }

  void set_message(const char *m) {
    lock();
    message = m;
    unlock();
  }

};

struct TPrint : csnd::Plugin<0, 1> {
  static constexpr char const *otypes = "";
  static constexpr char const *itypes = "S";
  PrintThread t;

  int init() {
    csound->plugin_deinit(this);
    csnd::constr(&t, csound);
    return OK;
  }

  int deinit() {
    csnd::destr(&t);
    return OK;
  }

  int kperf() {
    t.set_message(inargs.str_data(0).data);
    return OK;
  }
};
*/

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<PVTrace2>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaxxii", csnd::thread::ia);
}
<commit_msg>params<commit_after>/*
  pvsops.c: pvs and other spectral-based opcodes

  Copyright (C) 2017 Victor Lazzarini
  This file is part of Csound.

  The Csound Library is free software; you can redistribute it
  and/or modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Csound 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 Csound; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA
*/
#include <algorithm>
#include <plugin.h>

struct PVTrace : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  static constexpr char const *otypes = "f";
  static constexpr char const *itypes = "fk";

  int init() {
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));
    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh](csnd::pv_bin f) {
                       return f.amp() >= thrsh ? f : csnd::pv_bin();
                     });
      framecount = fout.count(fin.count());
    }
    return OK;
  }
};

struct binamp {
  int bin;
  float amp;
};

struct PVTrace2 : csnd::FPlugin<1, 2> {
  csnd::AuxMem<float> amps;
  csnd::AuxMem<binamp> binlist;
  static constexpr char const *otypes = "fk[]";
  static constexpr char const *itypes = "fk";

  int init() {
    csnd::Vector<MYFLT> &bins = outargs.vector_data<MYFLT>(1);
    if (inargs.fsig_data(0).isSliding())
      return csound->init_error("sliding not supported");

    if (inargs.fsig_data(0).fsig_format() != csnd::fsig_format::pvs &&
        inargs.fsig_data(0).fsig_format() != csnd::fsig_format::polar)
      return csound->init_error("fsig format not supported");

    amps.allocate(csound, inargs.fsig_data(0).nbins());
    binlist.allocate(csound, inargs.fsig_data(0).nbins());
    csnd::Fsig &fout = outargs.fsig_data(0);
    fout.init(csound, inargs.fsig_data(0));

    bins.init(csound, inargs.fsig_data(0).nbins());

    framecount = 0;
    return OK;
  }

  int kperf() {
    csnd::pv_frame &fin = inargs.fsig_data(0);
    csnd::pv_frame &fout = outargs.fsig_data(0);
    csnd::Vector<MYFLT> &bins = outargs.vector_data<MYFLT>(1);
    csnd::AuxMem<binamp> &mbins = binlist;

    if (framecount < fin.count()) {
      int n = fin.len() - (int)inargs[1];
      float thrsh;
      int cnt = 0;
      int bin = 0;
      std::transform(fin.begin(), fin.end(), amps.begin(),
                     [](csnd::pv_bin f) { return f.amp(); });
      std::nth_element(amps.begin(), amps.begin() + n, amps.end());
      thrsh = amps[n];
      std::transform(fin.begin(), fin.end(), fout.begin(),
                     [thrsh, &mbins, &cnt, &bin](csnd::pv_bin f) {
                       if(f.amp() >= thrsh) {
                       mbins[cnt].bin = bin++;
                       mbins[cnt++].amp = f.amp();
                       return f;
                       }
                       else {
                        bin++;
                        return csnd::pv_bin();
                       }
                     });
      std::sort(binlist.begin(), binlist.begin()+cnt, [](binamp a, binamp b) {
          return (a.amp > b.amp);
      });
      std::transform(binlist.begin(), binlist.begin()+cnt, bins.begin(),
                     [](binamp a) { return (MYFLT) a.bin;});

      std::fill(bins.begin()+cnt, bins.end(), FL(0.0));

      framecount = fout.count(fin.count());
    }

    return OK;
  }
};

struct TVConv : csnd::Plugin<1, 6> {
  csnd::AuxMem<MYFLT> ir;
  csnd::AuxMem<MYFLT> in;
  csnd::AuxMem<MYFLT> insp;
  csnd::AuxMem<MYFLT> irsp;
  csnd::AuxMem<MYFLT> out;
  csnd::AuxMem<MYFLT> saved;
  csnd::AuxMem<MYFLT>::iterator itn;
  csnd::AuxMem<MYFLT>::iterator itr;
  csnd::AuxMem<MYFLT>::iterator itnsp;
  csnd::AuxMem<MYFLT>::iterator itrsp;
  uint32_t n;
  uint32_t fils;
  uint32_t pars;
  uint32_t ffts;
  csnd::fftp fwd, inv;
  typedef std::complex<MYFLT> cmplx;

  uint32_t rpow2(uint32_t n) {
    uint32_t v = 2;
    while (v <= n)
      v <<= 1;
    if ((n - (v >> 1)) < (v - n))
      return v >> 1;
    else
      return v;
  }

  cmplx *to_cmplx(MYFLT *f) { return reinterpret_cast<cmplx *>(f); }

  cmplx real_prod(cmplx &a, cmplx &b) {
    return cmplx(a.real() * b.real(), a.imag() * b.imag());
  }

  int init() {
    pars = inargs[4];
    fils = inargs[5];
    if (pars > fils)
      std::swap(pars, fils);
    if (pars > 1) {
      pars = rpow2(pars);
      fils = rpow2(fils) * 2;
      ffts = pars * 2;
      fwd = csound->fft_setup(ffts, FFT_FWD);
      inv = csound->fft_setup(ffts, FFT_INV);
      out.allocate(csound, ffts);
      insp.allocate(csound, fils);
      irsp.allocate(csound, fils);
      saved.allocate(csound, pars);
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
      itnsp = insp.begin();
      itrsp = insp.begin();
      n = 0;
    } else {
      ir.allocate(csound, fils);
      in.allocate(csound, fils);
    }
    itn = in.begin();
    itr = ir.begin();
    return OK;
  }

  int pconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto *frz1 = inargs(2);
    auto *frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        itn[n] = *inp;
      if (*frz2 > 0)
        itr[n] = *irp;

      s = out[n] + saved[n];
      saved[n] = out[n + pars];
      if (++n == pars) {
        cmplx *ins, *irs, *ous = to_cmplx(out.data());
        std::copy(itn, itn + ffts, itnsp);
        std::copy(itr, itr + ffts, itrsp);
        std::fill(out.begin(), out.end(), 0.);
        // FFT
        csound->rfft(fwd, itnsp);
        csound->rfft(fwd, itrsp);
        // increment iterators
        itnsp += ffts, itrsp += ffts;
        itn += ffts, itr += ffts;
        if (itnsp == insp.end()) {
          itnsp = insp.begin();
          itrsp = irsp.begin();
          itn = in.begin();
          itr = ir.begin();
        }
        // spectral delay line
        for (csnd::AuxMem<MYFLT>::iterator it1 = itnsp, it2 = irsp.end() - ffts;
             it2 >= irsp.begin(); it1 += ffts, it2 -= ffts) {
          if (it1 == insp.end())
            it1 = insp.begin();
          ins = to_cmplx(it1);
          irs = to_cmplx(it2);
          // spectral product
          for (uint32_t i = 1; i < pars; i++)
            ous[i] += ins[i] * irs[i];
          ous[0] += real_prod(ins[0], irs[0]);
        }
        // IFFT
        csound->rfft(inv, out.data());
        n = 0;
      }
      frz1 += inc1, frz2 += inc2;
      irp++, inp++;
    }
    return OK;
  }

  int dconv() {
    csnd::AudioSig insig(this, inargs(0));
    csnd::AudioSig irsig(this, inargs(1));
    csnd::AudioSig outsig(this, outargs(0));
    auto irp = irsig.begin();
    auto inp = insig.begin();
    auto frz1 = inargs(2);
    auto frz2 = inargs(3);
    auto inc1 = csound->is_asig(frz1);
    auto inc2 = csound->is_asig(frz2);

    for (auto &s : outsig) {
      if (*frz1 > 0)
        *itn = *inp;
      if (*frz2 > 0)
        *itr = *irp;
      itn++, itr++;
      if (itn == in.end()) {
        itn = in.begin();
        itr = ir.begin();
      }
      s = 0.;
      for (csnd::AuxMem<MYFLT>::iterator it1 = itn, it2 = ir.end() - 1;
           it2 >= ir.begin(); it1++, it2--) {
        if (it1 == in.end())
          it1 = in.begin();
        s += *it1 * *it2;
      }
      frz1 += inc1, frz2 += inc2;
      inp++, irp++;
    }
    return OK;
  }

  int aperf() {
    if (pars > 1)
      return pconv();
    else
      return dconv();
  }
};

/*
class PrintThread : public csnd::Thread {
  std::atomic_bool splock;
  std::atomic_bool on;
  std::string message;

  void lock() {
    bool tmp = false;
    while(!splock.compare_exchange_weak(tmp,true))
      tmp = false;
  }

  void unlock() {
    splock = false;
  }

  uintptr_t run() {
    std::string old;
    while(on) {
      lock();
      if(old.compare(message)) {
       csound->message(message.c_str());
       old = message;
      }
      unlock();
    }
    return 0;
  }

public:
  PrintThread(csnd::Csound *csound)
    : Thread(csound), splock(false), on(true), message("") {};

  ~PrintThread(){
    on = false;
    join();
  }

  void set_message(const char *m) {
    lock();
    message = m;
    unlock();
  }

};

struct TPrint : csnd::Plugin<0, 1> {
  static constexpr char const *otypes = "";
  static constexpr char const *itypes = "S";
  PrintThread t;

  int init() {
    csound->plugin_deinit(this);
    csnd::constr(&t, csound);
    return OK;
  }

  int deinit() {
    csnd::destr(&t);
    return OK;
  }

  int kperf() {
    t.set_message(inargs.str_data(0).data);
    return OK;
  }
};
*/

#include <modload.h>
void csnd::on_load(Csound *csound) {
  csnd::plugin<PVTrace>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<PVTrace2>(csound, "pvstrace", csnd::thread::ik);
  csnd::plugin<TVConv>(csound, "tvconv", "a", "aaxxii", csnd::thread::ia);
}
<|endoftext|>


<commit_before>/*
contact: Boris.Polishchuk@cern.ch
link: http://aliceinfo.cern.ch/static/phpBB3/viewtopic.php?f=4&t=17
reference run: /castor/cern.ch/alice/phos/2007/10/02/13/07000008232001.10.root
run type: STANDALONE
DA type: MON
number of events needed: 1000
input files: RCU0.data  RCU1.data  RCU2.data  RCU3.data
Output files: PHOS_Module2_BCM.root
Trigger types used: CALIBRATION_EVENT or PHYSICS
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSDA2.h"
#include "AliPHOSRawFitterv1.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                                        "*",
                                        "TStreamerInfo",
                                        "RIO",
                                        "TStreamerInfo()");

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[4] = {"RCU0.data","RCU1.data","RCU2.data","RCU3.data"};

  for(Int_t iFile=0; iFile<4; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = "./";
  path += "RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("DA2 (bad channels search) started.\n");

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;

  AliPHOSDA2* da2 = new AliPHOSDA2(2); // DA2 ("Checking for bad channels") for module2

  Float_t q[64][56][2];

  Int_t gain     = -1;
  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t nFired   = -1;
  Int_t sigStart, sigLength;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT || eventT==CALIBRATION_EVENT) {

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    q[iX][iZ][iGain] = 0.;
	  }
	}
      }

      nFired = 0;

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv0 fitter();
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  // In case of oscillating signals with ZS, a channel can have several bunches
	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    if (nBunches > 1) continue;
	    sigStart  = fRawStream.GetStartTimeBin();
	    sigLength = fRawStream.GetBunchLength();
	    fitter.SetSamples(fRawStream->GetSignals(),sigStart,sigLength);
	  } // End of NextBunch()

	  fitter.SetNBunches(nBunches);
	  fitter.SetChannelGeo(module,cellX,cellZ,caloFlag);
	  fitter.Eval();

	  if (nBunches>1 || caloFlag!=0 || caloFlag!=1 || fitter.GetSignalQuality()>1) continue;

	  q[cellX][cellZ][caloFlag] = fitter.GetSignalQuality();

	  if(gain && dc.GetEnergy()>40)
	    nFired++;
	}
      }

      da2->FillQualityHistograms(q);
      da2->FillFiredCellsHistogram(nFired);
      //da1.UpdateHistoFile();

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* Be sure that all histograms are saved */
  delete da2;

  /* Store output files to the File Exchange Server */
  daqDA_FES_storeFile("PHOS_Module2_BCM.root","BAD_CHANNELS");

  return status;
}
<commit_msg>Updated to use new mapping scheme, new CaloRawStreamV3, reading of the ZS parameters from data etc..<commit_after>/*
contact: Boris.Polishchuk@cern.ch
link: http://aliceinfo.cern.ch/static/phpBB3/viewtopic.php?f=4&t=17
reference run: /castor/cern.ch/alice/phos/2007/10/02/13/07000008232001.10.root
run type: LED
DA type: MON
number of events needed: 1000
number of events needed: 1000
input files: Mod0RCU0.data Mod0RCU1.data Mod0RCU2.data Mod0RCU3.data Mod1RCU0.data Mod1RCU1.data Mod1RCU2.data Mod1RCU3.data Mod2RCU0.data Mod2RCU1.data Mod2RCU2.data Mod2RCU3.data Mod3RCU0.data Mod3RCU1.data Mod3RCU2.data Mod3RCU3.data Mod4RCU0.data Mod4RCU1.data Mod4RCU2.data Mod4RCU3.data
Output files: PHOS_Module2_BCM.root
Trigger types used: CALIBRATION_EVENT
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSDA2.h"
#include "AliPHOSRawFitterv1.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"
#include "AliLog.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                                        "*",
                                        "TStreamerInfo",
                                        "RIO",
                                        "TStreamerInfo()");

  AliLog::SetGlobalDebugLevel(0) ;
  AliLog::SetGlobalLogLevel(AliLog::kFatal);

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  short offset, threshold;

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[20] = {
    "Mod0RCU0.data",
    "Mod0RCU1.data",
    "Mod0RCU2.data",
    "Mod0RCU3.data",
    "Mod1RCU0.data",
    "Mod1RCU1.data",
    "Mod1RCU2.data",
    "Mod1RCU3.data",
    "Mod2RCU0.data",
    "Mod2RCU1.data",
    "Mod2RCU2.data",
    "Mod2RCU3.data",
    "Mod3RCU0.data",
    "Mod3RCU1.data",
    "Mod3RCU2.data",
    "Mod3RCU3.data",
    "Mod4RCU0.data",
    "Mod4RCU1.data",
    "Mod4RCU2.data",
    "Mod4RCU3.data"
  };

  for(Int_t iFile=0; iFile<20; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[20];
  TString path = "./";

  path += "Mod";
  TString path2;
  TString path3;
  Int_t iMap = 0;

  for(Int_t iMod = 0; iMod < 5; iMod++) {
    path2 = path;
    path2 += iMod;
    path2 += "RCU";

    for(Int_t iRCU=0; iRCU<4; iRCU++) {
      path3 = path2;
      path3 += iRCU;
      path3 += ".data";
      mapping[iMap] = new AliCaloAltroMapping(path3.Data());
      iMap++;
    }
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* log start of process */
  printf("DA2 (bad channels search) started.\n");

  /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;

  AliPHOSDA2* da2 = new AliPHOSDA2(2); // DA2 ("Checking for bad channels") for module2

  Float_t q[64][56][2];

  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t nFired   = -1;
  Int_t sigStart, sigLength;
  Int_t caloFlag;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT || eventT==CALIBRATION_EVENT) {

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    q[iX][iZ][iGain] = 0.;
	  }
	}
      }

      nFired = 0;

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv1 fitter;
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  /* Retrieve ZS parameters from data*/
	  short value = stream.GetAltroCFG1();
	  bool ZeroSuppressionEnabled = (value >> 15) & 0x1;
	  bool AutomaticBaselineSubtraction = (value >> 14) & 0x1;
	  if(ZeroSuppressionEnabled) {
	    offset = (value >> 10) & 0xf;
	    threshold = value & 0x3ff;
	    fitter.SubtractPedestals(kFALSE);
	    fitter.SetAmpOffset(offset);
	    fitter.SetAmpThreshold(threshold);
	  }

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  if(caloFlag!=0 && caloFlag!=1) continue; //TRU data!

	  // In case of oscillating signals with ZS, a channel can have several bunches
	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    sigStart  = stream.GetStartTimeBin();
	    sigLength = stream.GetBunchLength();
	    fitter.SetChannelGeo(stream.GetModule(),cellX,cellZ,caloFlag);
	    fitter.Eval(stream.GetSignals(),sigStart,sigLength);
	    q[cellX][cellZ][caloFlag] = fitter.GetSignalQuality();
	    printf("q[%d][%d][%d] = %.3f\n",cellX,cellZ,caloFlag,q[cellX][cellZ][caloFlag]);
	  } // End of NextBunch()

	  if(caloFlag==1 && fitter.GetEnergy()>40)
	    nFired++;
	}
      }

      da2->FillQualityHistograms(q);
      da2->FillFiredCellsHistogram(nFired);
      //da1.UpdateHistoFile();

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 20; i++) delete mapping[i];

  /* Be sure that all histograms are saved */
  delete da2;

  /* Store output files to the File Exchange Server */
  daqDA_FES_storeFile("PHOS_Module2_BCM.root","BAD_CHANNELS");

  return status;
}
<|endoftext|>


<commit_before>#include <Pith/Config.hpp>
#include <Pith/LockGuard.hpp>
#include <Pith/SharedLock.hpp>
#include <gtest/gtest.h>

using namespace Pith;

TEST(SharedLock, multipleShared) {
	SharedLock lock;
	SharedLockGuard<SharedLock> shared1(lock);
	EXPECT_TRUE(trySharedLock(lock));
}

TEST(SharedLock, failToTakeExclusive) {
	SharedLock lock;
	SharedLockGuard<SharedLock> shared(lock);
	EXPECT_FALSE(tryExclusiveLock(lock));
}

TEST(SharedLock, exclusiveThenShared) {
	SharedLock lock;
	{
		ExclusiveLockGuard<SharedLock> exclusive(lock);
		EXPECT_TRUE(lock.isLocked<Access::EXCLUSIVE>());
	}
	EXPECT_FALSE(lock.isLocked<Access::EXCLUSIVE>());
	{
		SharedLockGuard<SharedLock> shared(lock);
		EXPECT_TRUE(lock.isLocked<Access::SHARED>());
	}
	EXPECT_FALSE(lock.isLocked<Access::SHARED>());
}<commit_msg>Disable some shared lock tests<commit_after>#include <Pith/Config.hpp>
#include <Pith/LockGuard.hpp>
#include <Pith/SharedLock.hpp>
#include <gtest/gtest.h>

using namespace Pith;

TEST(SharedLock, multipleShared) {
	SharedLock lock;
	SharedLockGuard<SharedLock> shared1(lock);
	EXPECT_TRUE(trySharedLock(lock));
}

TEST(SharedLock, DISABLED_failToTakeExclusive) {
	SharedLock lock;
	SharedLockGuard<SharedLock> shared(lock);
	EXPECT_FALSE(tryExclusiveLock(lock));
}

TEST(SharedLock, DISABLED_exclusiveThenShared) {
	SharedLock lock;
	{
		ExclusiveLockGuard<SharedLock> exclusive(lock);
		EXPECT_TRUE(lock.isLocked<Access::EXCLUSIVE>());
	}
	EXPECT_FALSE(lock.isLocked<Access::EXCLUSIVE>());
	{
		SharedLockGuard<SharedLock> shared(lock);
		EXPECT_TRUE(lock.isLocked<Access::SHARED>());
	}
	EXPECT_FALSE(lock.isLocked<Access::SHARED>());
}<|endoftext|>


<commit_before>#ifndef SD_UNO_DRAW_VIEW_HXX
#define SD_UNO_DRAW_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWVIEW_HPP_
#include <com/sun/star/drawing/XDrawView.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XLAYER_HPP_
#include <com/sun/star/drawing/XLayer.hpp>
#endif

#ifndef _SFX_SFXBASECONTROLLER_HXX_
#include <sfx2/sfxbasecontroller.hxx>
#endif

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif

#ifndef _CPPUHELPER_PROPTYPEHLP_HXX
#include <cppuhelper/proptypehlp.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#ifndef _SVX_UNOSHAPE_HXX
#include <svx/unoshape.hxx>
#endif

class SdXImpressDocument;
class SdPage;

namespace sd {

class DrawViewShell;

/**
 * This class implements the view component for a SdDrawViewShell
 */
class SdUnoDrawView
    : public DrawController
{
public:
    enum properties
    {
        PROPERTY__BEGIN = DrawController::PROPERTY__BEGIN,
        PROPERTY_CURRENTPAGE = PROPERTY__BEGIN,
        PROPERTY_MASTERPAGEMODE,
        PROPERTY_LAYERMODE,
        PROPERTY_ACTIVE_LAYER,
        PROPERTY_ZOOMTYPE,
        PROPERTY_ZOOMVALUE,
        PROPERTY_VIEWOFFSET,
        PROPERTY__END
    };

    SdUnoDrawView (
        ViewShellBase& rBase,
        ViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoDrawView (void) throw();

    virtual void FireChangeEditMode (bool bMasterPageMode) throw();
    virtual void FireChangeLayerMode (bool bLayerMode) throw();
    virtual void FireSwitchCurrentPage (SdPage* pCurrentPage) throw();

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSelectionSupplier
    virtual sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& aSelection ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getSelection(  ) throw(::com::sun::star::uno::RuntimeException);

    // XDrawView
    virtual void SAL_CALL setCurrentPage( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > SAL_CALL getCurrentPage(  ) throw(::com::sun::star::uno::RuntimeException);

protected:
    virtual void FillPropertyTable (
        ::std::vector< ::com::sun::star::beans::Property>& rProperties);

    /**
     * Converted the value rValue and return the result in rConvertedValue and the
     * old value in rOldValue. A IllegalArgumentException is thrown.
     * The method is not implemented in this class. After this call the vetoable
     * listeners are notified.
     *
     * @param rConvertedValue the converted value. Only set if return is true.
     * @param rOldValue the old value. Only set if return is true.
     * @param nHandle the handle of the proberty.
     * @return true if the value converted.
     */
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
        ::com::sun::star::uno::Any & rConvertedValue,
        ::com::sun::star::uno::Any & rOldValue,
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);
    /**
     * The same as setFastProperyValue, but no exception is thrown and nHandle
     * is always valid. You must not broadcast the changes in this method.

     * You type is correct you need't test it.
     */
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);
    /**
     * The same as getFastProperyValue, but return the value through
     * rValue and nHandle is always valid.
     */
    virtual void SAL_CALL getFastPropertyValue(
        ::com::sun::star::uno::Any& rValue,
        sal_Int32 nHandle ) const;

    sal_Bool getMasterPageMode(void) const throw();
    void setMasterPageMode(sal_Bool MasterPageMode_) throw();
    sal_Bool getLayerMode(void) const throw();
    void setLayerMode(sal_Bool LayerMode_) throw();

    /** Return a reference to the active layer object.
        @return
            The returned value may be empty when the internal state of this
            view is not valid (like during destruction.)
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XLayer> getActiveLayer (void) throw ();

    /** Make the specified object the active layer.
        @param rxLayer
            The new layer object.
    */
    void setActiveLayer (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XLayer>& rxLayer) throw ();

    void SetZoom( sal_Int16 nZoom );
    sal_Int16 GetZoom(void) const;

    void SetViewOffset(const com::sun::star::awt::Point& rWinPos );
    com::sun::star::awt::Point GetViewOffset() const;

    void SetZoomType( sal_Int16 nType );

private:
    bool mbOldMasterPageMode;
    bool mbOldLayerMode;
    SdPage* mpCurrentPage;

    /** This is a shortcut for accessing the view shell data member of
        the base class casted to the correct class.
    */
    DrawViewShell& GetDrawViewShell (void) const;
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS impress20ea (1.9.68); FILE MERGED 2004/09/15 07:49:34 af 1.9.68.1: #117500# Corrected the use property indices.<commit_after>#ifndef SD_UNO_DRAW_VIEW_HXX
#define SD_UNO_DRAW_VIEW_HXX

#ifndef SD_DRAW_CONTROLLER_HXX
#include "DrawController.hxx"
#endif
#ifndef _COM_SUN_STAR_DRAWING_XDRAWVIEW_HPP_
#include <com/sun/star/drawing/XDrawView.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XLAYER_HPP_
#include <com/sun/star/drawing/XLayer.hpp>
#endif

#ifndef _SFX_SFXBASECONTROLLER_HXX_
#include <sfx2/sfxbasecontroller.hxx>
#endif

#ifndef _CPPUHELPER_PROPSHLP_HXX
#include <cppuhelper/propshlp.hxx>
#endif

#ifndef _CPPUHELPER_PROPTYPEHLP_HXX
#include <cppuhelper/proptypehlp.hxx>
#endif

#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#ifndef _SVX_UNOSHAPE_HXX
#include <svx/unoshape.hxx>
#endif

class SdXImpressDocument;
class SdPage;

namespace sd {

class DrawViewShell;

/**
 * This class implements the view component for a SdDrawViewShell
 */
class SdUnoDrawView
    : public DrawController
{
public:
    enum properties
    {
        PROPERTY__BEGIN = DrawController::PROPERTY__END,
        PROPERTY_CURRENTPAGE = PROPERTY__BEGIN,
        PROPERTY_MASTERPAGEMODE,
        PROPERTY_LAYERMODE,
        PROPERTY_ACTIVE_LAYER,
        PROPERTY_ZOOMTYPE,
        PROPERTY_ZOOMVALUE,
        PROPERTY_VIEWOFFSET,
        PROPERTY__END
    };

    SdUnoDrawView (
        ViewShellBase& rBase,
        ViewShell& rViewShell,
        View& rView) throw();
    virtual ~SdUnoDrawView (void) throw();

    virtual void FireChangeEditMode (bool bMasterPageMode) throw();
    virtual void FireChangeLayerMode (bool bLayerMode) throw();
    virtual void FireSwitchCurrentPage (SdPage* pCurrentPage) throw();

    // XTypeProvider
    virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(::com::sun::star::uno::RuntimeException);

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XSelectionSupplier
    virtual sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& aSelection ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getSelection(  ) throw(::com::sun::star::uno::RuntimeException);

    // XDrawView
    virtual void SAL_CALL setCurrentPage( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& xPage ) throw(::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > SAL_CALL getCurrentPage(  ) throw(::com::sun::star::uno::RuntimeException);

protected:
    virtual void FillPropertyTable (
        ::std::vector< ::com::sun::star::beans::Property>& rProperties);

    /**
     * Converted the value rValue and return the result in rConvertedValue and the
     * old value in rOldValue. A IllegalArgumentException is thrown.
     * The method is not implemented in this class. After this call the vetoable
     * listeners are notified.
     *
     * @param rConvertedValue the converted value. Only set if return is true.
     * @param rOldValue the old value. Only set if return is true.
     * @param nHandle the handle of the proberty.
     * @return true if the value converted.
     */
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
        ::com::sun::star::uno::Any & rConvertedValue,
        ::com::sun::star::uno::Any & rOldValue,
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::lang::IllegalArgumentException);
    /**
     * The same as setFastProperyValue, but no exception is thrown and nHandle
     * is always valid. You must not broadcast the changes in this method.

     * You type is correct you need't test it.
     */
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
        sal_Int32 nHandle,
        const ::com::sun::star::uno::Any& rValue )
        throw (::com::sun::star::uno::Exception);
    /**
     * The same as getFastProperyValue, but return the value through
     * rValue and nHandle is always valid.
     */
    virtual void SAL_CALL getFastPropertyValue(
        ::com::sun::star::uno::Any& rValue,
        sal_Int32 nHandle ) const;

    sal_Bool getMasterPageMode(void) const throw();
    void setMasterPageMode(sal_Bool MasterPageMode_) throw();
    sal_Bool getLayerMode(void) const throw();
    void setLayerMode(sal_Bool LayerMode_) throw();

    /** Return a reference to the active layer object.
        @return
            The returned value may be empty when the internal state of this
            view is not valid (like during destruction.)
    */
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XLayer> getActiveLayer (void) throw ();

    /** Make the specified object the active layer.
        @param rxLayer
            The new layer object.
    */
    void setActiveLayer (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XLayer>& rxLayer) throw ();

    void SetZoom( sal_Int16 nZoom );
    sal_Int16 GetZoom(void) const;

    void SetViewOffset(const com::sun::star::awt::Point& rWinPos );
    com::sun::star::awt::Point GetViewOffset() const;

    void SetZoomType( sal_Int16 nType );

private:
    bool mbOldMasterPageMode;
    bool mbOldLayerMode;
    SdPage* mpCurrentPage;

    /** This is a shortcut for accessing the view shell data member of
        the base class casted to the correct class.
    */
    DrawViewShell& GetDrawViewShell (void) const;
};

} // end of namespace sd

#endif
<|endoftext|>


<commit_before>#ifndef _SDD_HOM_SATURATION_INTERSECTION_HH_
#define _SDD_HOM_SATURATION_INTERSECTION_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument

#include <boost/container/flat_set.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/evaluation_error.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/intersection.hh"
#include "sdd/hom/local.hh"
#include "sdd/hom/optional_homomorphism.hh"
#include "sdd/order/order.hh"
#include "sdd/util/packed.hh"

namespace sdd { namespace hom {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Saturation Sum homomorphism.
template <typename C>
class LIBSDD_ATTRIBUTE_PACKED saturation_intersection
{
public:

  /// @brief The variable type.
  using variable_type = typename C::variable_type;

  /// @brief The type of the homomorphism G part.
  using g_type = boost::container::flat_set<homomorphism<C>>;

private:

  /// @brief The variable on which this intersection works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const optional_homomorphism<C> F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const optional_homomorphism<C> L_;

public:

  /// @brief Constructor.
  saturation_intersection( variable_type var, optional_homomorphism<C>&& f, g_type&& g
                         , optional_homomorphism<C>&& l)
    : variable_(var), F_(std::move(f)), G_(std::move(g)), L_(std::move(l))
  {}

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const order<C>& o, const SDD<C>& s)
  const
  {
    dd::intersection_builder<C, SDD<C>> operands;
    operands.reserve(G_.size() + 2);

    if (F_)
    {
      operands.add((*F_)(cxt, o, s));
    }

    for (const auto& g : G_)
    {
      operands.add(g(cxt, o, s));
    }

    if (L_)
    {
      operands.add((*L_)(cxt, o, s));
    }

    try
    {
      return dd::intersection(cxt.sdd_context(), std::move(operands));
    }
    catch (top<C>& t)
    {
      evaluation_error<C> e(s);
      e.add_top(t);
      throw e;
    }
  }

  /// @brief Skip variable predicate.
  bool
  skip(const order<C>& o)
  const noexcept
  {
    return variable_ != o.variable();
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return (F_ ? F_->selector() : true)
       and (L_ ? L_->selector() : true)
       and std::all_of( G_.begin(), G_.end()
                      , [&](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  variable_type
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  const optional_homomorphism<C>&
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  const optional_homomorphism<C>&
  L()
  const noexcept
  {
    return L_;
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Equality of two saturation_intersection.
/// @related saturation_intersection
template <typename C>
inline
bool
operator==(const saturation_intersection<C>& lhs, const saturation_intersection<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable() and lhs.F() == rhs.F() and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @internal
/// @related saturation_intersection
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_intersection<C>& s)
{
  os << "SatInter(@" << +s.variable() << ", F=";
  if (s.F())
  {
    os << *s.F();
  }
  os << ", G=";
  if (not s.G().empty())
  {
    std::copy( s.G().begin(), std::prev(s.G().end())
             , std::ostream_iterator<homomorphism<C>>(os, " & "));
    os << *std::prev(s.G().end()) << ")";
  }
  os << ", L=";
  if (s.L())
  {
    os << *s.L();
  }
  return os;
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Create the Saturation Intersection homomorphism.
/// @related sdd::homomorphism
///
/// We suppose that a saturation intersection is created in the rewriting process. Thus, we assume
/// that operands are already optimized (local merged, etc.).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationIntersection( typename C::variable_type var
                      , optional_homomorphism<C>&& f
                      , InputIterator gbegin, InputIterator gend
                      , optional_homomorphism<C>&& l)
{
  if (std::distance(gbegin, gend) == 0)
  {
    if (f and not l)
    {
      return *f;
    }
    if (not f and l)
    {
      return *l;
    }
  }

  return homomorphism<C>::create( mem::construct<saturation_intersection<C>>()
                                , var
                                , std::move(f)
                                , typename saturation_intersection<C>::g_type(gbegin, gend)
                                , std::move(l));
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Hash specialization for sdd::hom::saturation_intersection.
template <typename C>
struct hash<sdd::hom::saturation_intersection<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_intersection<C>& s)
  const
  {
    std::size_t seed = sdd::util::hash(s.variable());
    if (s.F())
    {
      sdd::util::hash_combine(seed, *s.F());
    }
    if (s.L())
    {
      sdd::util::hash_combine(seed, *s.L());
    }
    sdd::util::hash_combine(seed, s.G().begin(), s.G().end());
    return seed;
  }
};

/*------------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_INTERSECTION_HH_
<commit_msg>Fix saturation_intersection textual output.<commit_after>#ifndef _SDD_HOM_SATURATION_INTERSECTION_HH_
#define _SDD_HOM_SATURATION_INTERSECTION_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument

#include <boost/container/flat_set.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/evaluation_error.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/intersection.hh"
#include "sdd/hom/local.hh"
#include "sdd/hom/optional_homomorphism.hh"
#include "sdd/order/order.hh"
#include "sdd/util/packed.hh"

namespace sdd { namespace hom {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Saturation Sum homomorphism.
template <typename C>
class LIBSDD_ATTRIBUTE_PACKED saturation_intersection
{
public:

  /// @brief The variable type.
  using variable_type = typename C::variable_type;

  /// @brief The type of the homomorphism G part.
  using g_type = boost::container::flat_set<homomorphism<C>>;

private:

  /// @brief The variable on which this intersection works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const optional_homomorphism<C> F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const optional_homomorphism<C> L_;

public:

  /// @brief Constructor.
  saturation_intersection( variable_type var, optional_homomorphism<C>&& f, g_type&& g
                         , optional_homomorphism<C>&& l)
    : variable_(var), F_(std::move(f)), G_(std::move(g)), L_(std::move(l))
  {}

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const order<C>& o, const SDD<C>& s)
  const
  {
    dd::intersection_builder<C, SDD<C>> operands;
    operands.reserve(G_.size() + 2);

    if (F_)
    {
      operands.add((*F_)(cxt, o, s));
    }

    for (const auto& g : G_)
    {
      operands.add(g(cxt, o, s));
    }

    if (L_)
    {
      operands.add((*L_)(cxt, o, s));
    }

    try
    {
      return dd::intersection(cxt.sdd_context(), std::move(operands));
    }
    catch (top<C>& t)
    {
      evaluation_error<C> e(s);
      e.add_top(t);
      throw e;
    }
  }

  /// @brief Skip variable predicate.
  bool
  skip(const order<C>& o)
  const noexcept
  {
    return variable_ != o.variable();
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return (F_ ? F_->selector() : true)
       and (L_ ? L_->selector() : true)
       and std::all_of( G_.begin(), G_.end()
                      , [&](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  variable_type
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  const optional_homomorphism<C>&
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  const optional_homomorphism<C>&
  L()
  const noexcept
  {
    return L_;
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Equality of two saturation_intersection.
/// @related saturation_intersection
template <typename C>
inline
bool
operator==(const saturation_intersection<C>& lhs, const saturation_intersection<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable() and lhs.F() == rhs.F() and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @internal
/// @related saturation_intersection
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_intersection<C>& s)
{
  os << "SatInter(@" << +s.variable() << ", F=";
  if (s.F())
  {
    os << *s.F();
  }
  os << ", G=";
  if (not s.G().empty())
  {
    std::copy( s.G().begin(), std::prev(s.G().end())
             , std::ostream_iterator<homomorphism<C>>(os, " & "));
    os << *std::prev(s.G().end()) << ")";
  }
  os << ", L=";
  if (s.L())
  {
    os << *s.L();
  }
  return os << ")";
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Create the Saturation Intersection homomorphism.
/// @related sdd::homomorphism
///
/// We suppose that a saturation intersection is created in the rewriting process. Thus, we assume
/// that operands are already optimized (local merged, etc.).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationIntersection( typename C::variable_type var
                      , optional_homomorphism<C>&& f
                      , InputIterator gbegin, InputIterator gend
                      , optional_homomorphism<C>&& l)
{
  if (std::distance(gbegin, gend) == 0)
  {
    if (f and not l)
    {
      return *f;
    }
    if (not f and l)
    {
      return *l;
    }
  }

  return homomorphism<C>::create( mem::construct<saturation_intersection<C>>()
                                , var
                                , std::move(f)
                                , typename saturation_intersection<C>::g_type(gbegin, gend)
                                , std::move(l));
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Hash specialization for sdd::hom::saturation_intersection.
template <typename C>
struct hash<sdd::hom::saturation_intersection<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_intersection<C>& s)
  const
  {
    std::size_t seed = sdd::util::hash(s.variable());
    if (s.F())
    {
      sdd::util::hash_combine(seed, *s.F());
    }
    if (s.L())
    {
      sdd::util::hash_combine(seed, *s.L());
    }
    sdd::util::hash_combine(seed, s.G().begin(), s.G().end());
    return seed;
  }
};

/*------------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_INTERSECTION_HH_
<|endoftext|>


<commit_before>#include "JsV8InspectorClient.h"
//#include "V8GlobalHelpers.h"
//#include "ArgConverter.h"
//#include "JniLocalRef.h"
//#include "NativeScriptException.h"
//#include "NativeScriptAssert.h"
#include <sstream>
#include <assert.h>
#include <include/libplatform/libplatform.h>
#include "Runtime.h"
#include "src/inspector/string-16.h"

#include "ArgConverter.h"

using namespace std;
using namespace tns;
using namespace v8;

using namespace v8_inspector;

JsV8InspectorClient::JsV8InspectorClient(v8::Isolate *isolate)
        : isolate_(isolate),
          inspector_(nullptr),
          session_(nullptr),
          connection(nullptr),
          context_()
{
    JEnv env;

    inspectorClass = env.FindClass("com/tns/AndroidJsV8Inspector");
    assert(inspectorClass != nullptr);

    sendMethod = env.GetStaticMethodID(inspectorClass, "send", "(Ljava/lang/Object;Ljava/lang/String;)V");
    assert(sendMethod != nullptr);

    getInspectorMessageMethod = env.GetStaticMethodID(inspectorClass, "getInspectorMessage", "(Ljava/lang/Object;)Ljava/lang/String;");
    assert(getInspectorMessageMethod != nullptr);
}

void JsV8InspectorClient::connect(jobject connection)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

    //v8::base_copied::Semaphore ready_semaphore(0);

    JEnv env;
    this->connection = env.NewGlobalRef(connection);

    //this->backend_runner->Append(new ConnectTask(this, &ready_semaphore));

    //ready_semaphore.Wait();

    this->doConnect(isolate_, JsV8InspectorClient::PersistentToLocal(isolate_, context_));

    //inspector_ = V8Inspector::create(isolate_, this);

    //session_ = inspector_->connect(1, this, v8_inspector::StringView());

    //inspector_->contextCreated(v8_inspector::V8ContextInfo(isolate_->GetCurrentContext(), 1, v8_inspector::StringView()));

}

void JsV8InspectorClient::doConnect(v8::Isolate *isolate, const v8::Local<v8::Context> &context)
{
//    Isolate::Scope isolate_scope(isolate_);
//    v8::HandleScope handleScope(isolate_);

    //inspector_ = V8Inspector::create(isolate, this);

    session_ = inspector_->connect(0, this, v8_inspector::StringView());

    //inspector_->contextCreated(v8_inspector::V8ContextInfo(/*isolate->GetCurrentContext()*/ context, 1, v8_inspector::StringView()));
}

void JsV8InspectorClient::disconnect()
{
    if (this->connection == nullptr)
    {
        return;
    }

    Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handleScope(isolate_);

    session_.reset();

    JEnv env;
    env.DeleteGlobalRef(this->connection);
    this->connection = nullptr;
}

void JsV8InspectorClient::dispatchMessage(const std::string &message)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

//    assert(session_ != nullptr);
//
//    const String16 msg(message.c_str());
//    v8_inspector::StringView message_view(reinterpret_cast<const uint16_t *>(msg.characters16()), msg.length());
//    session_->dispatchProtocolMessage(message_view);

    //this->backend_runner->Append(new SendMessageToBackendTask(this, message));

    this->doDispatchMessage(isolate_, message);

}

//void JsV8InspectorClient::runMessageLoopOnPause(int context_group_id) override
//{
//    if (running_nested_loop_)
//    {
//        return;
//    }
//
//    terminated_ = false;
//    running_nested_loop_ = true;
//    while (!terminated_)
//    {
//        agent_->WaitForFrontendMessage();
//        while (v8::platform::PumpMessageLoop(platform_, env_->isolate()))
//        {
//
//        }
//    }
//    terminated_ = false;
//    running_nested_loop_ = false;
//}

void JsV8InspectorClient::runMessageLoopOnPause(int context_group_id)
{

    if (running_nested_loop_)
    {
        return;
    }

    JEnv env;

    terminated_ = false;
    running_nested_loop_ = true;
    while (!terminated_)
    {
        //agent_->WaitForFrontendMessage();

//        string errMsg;
//        JniLocalRef msg(env.CallStaticObjectMethod(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID, exception));
//
//        const char* msgStr = env.GetStringUTFChars(msg, nullptr);
//
//        errMsg.append(msgStr);
//
//        env.ReleaseStringUTFChars(msg, msgStr);
//
//        return errMsg;

        JniLocalRef msg(env.CallStaticObjectMethod(inspectorClass, getInspectorMessageMethod, this->connection));
        if (!msg.IsNull())
        {
            auto inspectorMessage = ArgConverter::jstringToString(msg);
            this->doDispatchMessage(this->isolate_, inspectorMessage);
        }

        while (v8::platform::PumpMessageLoop(Runtime::platform, isolate_))
        {
        }
    }
    terminated_ = false;
    running_nested_loop_ = false;
}

void JsV8InspectorClient::quitMessageLoopOnPause()
{
    terminated_ = true;
}

v8::Local<v8::Context> JsV8InspectorClient::ensureDefaultContextInGroup(int contextGroupId)
{
    v8::Local<v8::Context> context = PersistentToLocal(isolate_, context_);
    return context;
    //return env_->context();
    //return v8::Local<v8::Context>();
}

void JsV8InspectorClient::doDispatchMessage(v8::Isolate *isolate, const std::string &message)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

    assert(session_ != nullptr);

    const String16 msg(message.c_str());
    v8_inspector::StringView message_view(reinterpret_cast<const uint16_t *>(msg.characters16()), msg.length());
    session_->dispatchProtocolMessage(message_view);
}

void JsV8InspectorClient::sendProtocolResponse(int callId, const v8_inspector::StringView &message)
{
    //frontend_channel_->SendMessageToFrontend(message);
    sendProtocolNotification(message);
}

static v8_inspector::String16 ToString16(const v8_inspector::StringView &string)
{
    if (string.is8Bit())
    {
        return v8_inspector::String16(reinterpret_cast<const char *>(string.characters8()), string.length());
    }

    return v8_inspector::String16(reinterpret_cast<const uint16_t *>(string.characters16()), string.length());
}

void JsV8InspectorClient::sendProtocolNotification(const v8_inspector::StringView &message)
{
    //frontend_channel_->SendMessageToFrontend(message);

    if (inspectorClass == nullptr || this->connection == nullptr)
    {
        return;
    }

    v8_inspector::String16 msg = ToString16(message);

    JEnv env;
    const char *msss = msg.utf8().c_str();
    JniLocalRef string(env.NewStringUTF(msg.utf8().c_str()));
    env.CallStaticVoidMethod(inspectorClass, sendMethod, this->connection, (jstring) string);
}

void JsV8InspectorClient::flushProtocolNotifications()
{
}

template<class TypeName>
inline v8::Local<TypeName> StrongPersistentToLocal(const v8::Persistent<TypeName> &persistent)
{
    return *reinterpret_cast<v8::Local<TypeName> *>(const_cast<v8::Persistent<TypeName> *>(&persistent));
}

template<class TypeName>
inline v8::Local<TypeName> WeakPersistentToLocal(v8::Isolate *isolate, const v8::Persistent<TypeName> &persistent)
{
    return v8::Local<TypeName>::New(isolate, persistent);
}

template<class TypeName>
inline v8::Local<TypeName> JsV8InspectorClient::PersistentToLocal(v8::Isolate *isolate, const v8::Persistent<TypeName> &persistent)
{
    if (persistent.IsWeak())
    {
        return WeakPersistentToLocal(isolate, persistent);
    }
    else
    {
        return StrongPersistentToLocal(persistent);
    }
}

void JsV8InspectorClient::init()
{
    if (inspector_ != nullptr)
    {
        return;
    }

    v8::HandleScope handle_scope(isolate_);

    v8::Local<Context> context = Context::New(isolate_);
    v8::Context::Scope context_scope(context);

    inspector_ = V8Inspector::create(isolate_, this);

    inspector_->contextCreated(v8_inspector::V8ContextInfo(context, 0, v8_inspector::StringView()));

    v8::Persistent<v8::Context> persistentContext(context->GetIsolate(), context);
    context_.Reset(isolate_, persistentContext);
}

JsV8InspectorClient *JsV8InspectorClient::GetInstance()
{
    if (instance == nullptr)
    {
        instance = new JsV8InspectorClient(Runtime::GetRuntime(0)->GetIsolate());
    }

    return instance;
}

void MessageHandler(v8::Local<v8::Message> message,
                    v8::Local<v8::Value> exception)
{
    v8::Isolate *isolate = v8::Isolate::GetCurrent();
    v8::Local<v8::Context> context = isolate->GetEnteredContext();
//    if (context.IsEmpty()) return;
//    v8_inspector::V8Inspector *inspector = InspectorClientImpl::InspectorFromContext(context);
//
//    v8::Local<v8::StackTrace> stack = message->GetStackTrace();
//    int script_id = message->GetScriptOrigin().ScriptID()->Value();
//    if (!stack.IsEmpty() && stack->GetFrameCount() > 0)
//    {
//        int top_script_id = stack->GetFrame(0)->GetScriptId();
//        if (top_script_id == script_id) script_id = 0;
//    }
//    int line_number = message->GetLineNumber(context).FromMaybe(0);
//    int column_number = 0;
//    if (message->GetStartColumn(context).IsJust())
//        column_number = message->GetStartColumn(context).FromJust() + 1;
//
//    v8_inspector::StringView detailed_message;
//    v8_inspector::String16 message_text_string = ToString16(message->Get());
//    v8_inspector::StringView message_text(message_text_string.characters16(),
//                                          message_text_string.length());
//    v8_inspector::String16 url_string;
//    if (message->GetScriptOrigin().ResourceName()->IsString())
//    {
//        url_string =
//                ToString16(message->GetScriptOrigin().ResourceName().As<v8::String>());
//    }
//    v8_inspector::StringView url(url_string.characters16(), url_string.length());
//
//    inspector->exceptionThrown(context, message_text, exception, detailed_message,
//                               url, line_number, column_number,
//                               inspector->createStackTrace(stack), script_id);
}

JsV8InspectorClient *JsV8InspectorClient::instance = nullptr;
jclass JsV8InspectorClient::inspectorClass = nullptr;
jmethodID JsV8InspectorClient::sendMethod = nullptr;
jmethodID JsV8InspectorClient::getInspectorMessageMethod = nullptr;

<commit_msg>travis rebuild<commit_after>#include "JsV8InspectorClient.h"
//#include "V8GlobalHelpers.h"
//#include "ArgConverter.h"
//#include "JniLocalRef.h"
//#include "NativeScriptException.h"
//#include "NativeScriptAssert.h"
#include <sstream>
#include <assert.h>
#include <include/libplatform/libplatform.h>
#include "Runtime.h"
#include "src/inspector/string-16.h"

#include "ArgConverter.h"

using namespace std;
using namespace tns;
using namespace v8;

using namespace v8_inspector;

JsV8InspectorClient::JsV8InspectorClient(v8::Isolate *isolate)
        : isolate_(isolate),
          inspector_(nullptr),
          session_(nullptr),
          connection(nullptr),
          context_()
{
    JEnv env;

    inspectorClass = env.FindClass("com/tns/AndroidJsV8Inspector");
    assert(inspectorClass != nullptr);

    sendMethod = env.GetStaticMethodID(inspectorClass, "send", "(Ljava/lang/Object;Ljava/lang/String;)V");
    assert(sendMethod != nullptr);

    getInspectorMessageMethod = env.GetStaticMethodID(inspectorClass, "getInspectorMessage", "(Ljava/lang/Object;)Ljava/lang/String;");
    assert(getInspectorMessageMethod != nullptr);
}

void JsV8InspectorClient::connect(jobject connection)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

    //v8::base_copied::Semaphore ready_semaphore(0);

    JEnv env;
    this->connection = env.NewGlobalRef(connection);

    //this->backend_runner->Append(new ConnectTask(this, &ready_semaphore));

    //ready_semaphore.Wait();

    this->doConnect(isolate_, JsV8InspectorClient::PersistentToLocal(isolate_, context_));

    //inspector_ = V8Inspector::create(isolate_, this);

    //session_ = inspector_->connect(1, this, v8_inspector::StringView());

    //inspector_->contextCreated(v8_inspector::V8ContextInfo(isolate_->GetCurrentContext(), 1, v8_inspector::StringView()));

}

void JsV8InspectorClient::doConnect(v8::Isolate *isolate, const v8::Local<v8::Context> &context)
{
//    Isolate::Scope isolate_scope(isolate_);
//    v8::HandleScope handleScope(isolate_);

    //inspector_ = V8Inspector::create(isolate, this);

    session_ = inspector_->connect(0, this, v8_inspector::StringView());

    //inspector_->contextCreated(v8_inspector::V8ContextInfo(/*isolate->GetCurrentContext()*/ context, 1, v8_inspector::StringView()));
}

void JsV8InspectorClient::disconnect()
{
    if (this->connection == nullptr)
    {
        return;
    }

    Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope handleScope(isolate_);

    session_.reset();

    JEnv env;
    env.DeleteGlobalRef(this->connection);
    this->connection = nullptr;
}

void JsV8InspectorClient::dispatchMessage(const std::string &message)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

//    assert(session_ != nullptr);
//
//    const String16 msg(message.c_str());
//    v8_inspector::StringView message_view(reinterpret_cast<const uint16_t *>(msg.characters16()), msg.length());
//    session_->dispatchProtocolMessage(message_view);

    //this->backend_runner->Append(new SendMessageToBackendTask(this, message));

    this->doDispatchMessage(isolate_, message);

}

//void JsV8InspectorClient::runMessageLoopOnPause(int context_group_id) override
//{
//    if (running_nested_loop_)
//    {
//        return;
//    }
//
//    terminated_ = false;
//    running_nested_loop_ = true;
//    while (!terminated_)
//    {
//        agent_->WaitForFrontendMessage();
//        while (v8::platform::PumpMessageLoop(platform_, env_->isolate()))
//        {
//
//        }
//    }
//    terminated_ = false;
//    running_nested_loop_ = false;
//}

void JsV8InspectorClient::runMessageLoopOnPause(int context_group_id)
{

    if (running_nested_loop_)
    {
        return;
    }

    JEnv env;

    terminated_ = false;
    running_nested_loop_ = true;
    while (!terminated_)
    {
        //agent_->WaitForFrontendMessage();

//        string errMsg;
//        JniLocalRef msg(env.CallStaticObjectMethod(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID, exception));
//
//        const char* msgStr = env.GetStringUTFChars(msg, nullptr);
//
//        errMsg.append(msgStr);
//
//        env.ReleaseStringUTFChars(msg, msgStr);
//
//        return errMsg;

        JniLocalRef msg(env.CallStaticObjectMethod(inspectorClass, getInspectorMessageMethod, this->connection));
        if (!msg.IsNull())
        {
            auto inspectorMessage = ArgConverter::jstringToString(msg);
            this->doDispatchMessage(this->isolate_, inspectorMessage);
        }

        while (v8::platform::PumpMessageLoop(Runtime::platform, isolate_))
        {
        }
    }
    terminated_ = false;
    running_nested_loop_ = false;
}

void JsV8InspectorClient::quitMessageLoopOnPause()
{
    terminated_ = true;
}

v8::Local<v8::Context> JsV8InspectorClient::ensureDefaultContextInGroup(int contextGroupId)
{
    v8::Local<v8::Context> context = PersistentToLocal(isolate_, context_);
    return context;
    //return env_->context();
    //return v8::Local<v8::Context>();
}

void JsV8InspectorClient::doDispatchMessage(v8::Isolate *isolate, const std::string &message)
{
    //Isolate::Scope isolate_scope(isolate_);
    //v8::HandleScope handleScope(isolate_);

    assert(session_ != nullptr);

    const String16 msg(message.c_str());
    v8_inspector::StringView message_view(reinterpret_cast<const uint16_t *>(msg.characters16()), msg.length());
    session_->dispatchProtocolMessage(message_view);
}

void JsV8InspectorClient::sendProtocolResponse(int callId, const v8_inspector::StringView &message)
{
    //frontend_channel_->SendMessageToFrontend(message);
    sendProtocolNotification(message);
}

static v8_inspector::String16 ToString16(const v8_inspector::StringView &string)
{
    if (string.is8Bit())
    {
        return v8_inspector::String16(reinterpret_cast<const char *>(string.characters8()), string.length());
    }

    return v8_inspector::String16(reinterpret_cast<const uint16_t *>(string.characters16()), string.length());
}

void JsV8InspectorClient::sendProtocolNotification(const v8_inspector::StringView &message)
{
    //frontend_channel_->SendMessageToFrontend(message);

    if (inspectorClass == nullptr || this->connection == nullptr)
    {
        return;
    }

    v8_inspector::String16 msg = ToString16(message);

    JEnv env;
    const char *msss = msg.utf8().c_str();
    JniLocalRef string(env.NewStringUTF(msg.utf8().c_str()));
    env.CallStaticVoidMethod(inspectorClass, sendMethod, this->connection, (jstring) string);
}

void JsV8InspectorClient::flushProtocolNotifications()
{
}

template<class TypeName>
inline v8::Local<TypeName> StrongPersistentToLocal(const v8::Persistent<TypeName> &persistent)
{
    return *reinterpret_cast<v8::Local<TypeName> *>(const_cast<v8::Persistent<TypeName> *>(&persistent));
}

template<class TypeName>
inline v8::Local<TypeName> WeakPersistentToLocal(v8::Isolate *isolate, const v8::Persistent<TypeName> &persistent)
{
    return v8::Local<TypeName>::New(isolate, persistent);
}

template<class TypeName>
inline v8::Local<TypeName> JsV8InspectorClient::PersistentToLocal(v8::Isolate *isolate, const v8::Persistent<TypeName> &persistent)
{
    if (persistent.IsWeak())
    {
        return WeakPersistentToLocal(isolate, persistent);
    }
    else
    {
        return StrongPersistentToLocal(persistent);
    }
}

void JsV8InspectorClient::init()
{
    if (inspector_ != nullptr)
    {
        return;
    }

    v8::HandleScope handle_scope(isolate_);

    v8::Local<Context> context = Context::New(isolate_);
    v8::Context::Scope context_scope(context);

    inspector_ = V8Inspector::create(isolate_, this);

    inspector_->contextCreated(v8_inspector::V8ContextInfo(context, 0, v8_inspector::StringView()));

    v8::Persistent<v8::Context> persistentContext(context->GetIsolate(), context);
    context_.Reset(isolate_, persistentContext);
}

JsV8InspectorClient *JsV8InspectorClient::GetInstance()
{
    if (instance == nullptr)
    {
        instance = new JsV8InspectorClient(Runtime::GetRuntime(0)->GetIsolate());
    }

    return instance;
}

void MessageHandler(v8::Local<v8::Message> message,
                    v8::Local<v8::Value> exception)
{
    v8::Isolate *isolate = v8::Isolate::GetCurrent();
    v8::Local<v8::Context> context = isolate->GetEnteredContext();
//    if (context.IsEmpty()) return;
//    v8_inspector::V8Inspector *inspector = InspectorClientImpl::InspectorFromContext(context);
//
//    v8::Local<v8::StackTrace> stack = message->GetStackTrace();
//    int script_id = message->GetScriptOrigin().ScriptID()->Value();
//    if (!stack.IsEmpty() && stack->GetFrameCount() > 0)
//    {
//        int top_script_id = stack->GetFrame(0)->GetScriptId();
//        if (top_script_id == script_id) script_id = 0;
//    }
//    int line_number = message->GetLineNumber(context).FromMaybe(0);
//    int column_number = 0;
//    if (message->GetStartColumn(context).IsJust())
//        column_number = message->GetStartColumn(context).FromJust() + 1;
//
//    v8_inspector::StringView detailed_message;
//    v8_inspector::String16 message_text_string = ToString16(message->Get());
//    v8_inspector::StringView message_text(message_text_string.characters16(),
//                                          message_text_string.length());
//    v8_inspector::String16 url_string;
//    if (message->GetScriptOrigin().ResourceName()->IsString())
//    {
//        url_string =
//                ToString16(message->GetScriptOrigin().ResourceName().As<v8::String>());
//    }
//    v8_inspector::StringView url(url_string.characters16(), url_string.length());
//
//    inspector->exceptionThrown(context, message_text, exception, detailed_message,
//                               url, line_number, column_number,
//                               inspector->createStackTrace(stack), script_id);
}

JsV8InspectorClient *JsV8InspectorClient::instance = nullptr;
jclass JsV8InspectorClient::inspectorClass = nullptr;
jmethodID JsV8InspectorClient::sendMethod = nullptr;
jmethodID JsV8InspectorClient::getInspectorMessageMethod = nullptr;

<|endoftext|>


<commit_before>#include <tchar.h>
#include "RCReader.h"
#include "RCVersion.h"
#include <locale.h>
#include <xl/Containers/xlArray.h>
#include <xl/Containers/xlMap.h>
#include <xl/Objects/xlString.h>
#include <Loki/ScopeGuard.h>

#define RC_VERSION_SUCCEESS 0
#define RC_VERSION_FAILURE  -1

struct VersionInfo
{
    WORD wMajor;
    WORD wMinor;
    WORD wBuild;
    WORD wRevision;
};

struct PathFile
{
    xl::String strPattern;
    bool bRecursion;
};

struct CommandLineInfo
{
    bool bFileVersion;
    bool bProductVersion;
    VersionInfo viFile;
    VersionInfo viProduct;
    xl::Map<xl::String, xl::String> mapStrings;
    xl::Array<PathFile> arrPaths;
};

void ShowCopyright()
{

}

void ShowHelp()
{
    _T("Comments")
    _T("CompanyName")
    _T("FileDescription")
    _T("FileVersion")
    _T("InternalName")
    _T("LegalCopyright")
    _T("LegalTrademarks")
    _T("OriginalFilename")
    _T("PrivateBuild")
    _T("ProductName")
    _T("ProductVersion")
    _T("SpecialBuild");
}

bool ParseVersion(const xl::String &strVerison, VersionInfo *pVI)
{
    xl::Array<xl::String> arrVersion = strVerison.Split(_T(","));

    if (arrVersion.Size() != 4)
    {
        return false;
    }

    pVI->wMajor = _ttoi(arrVersion[0].GetAddress());
    pVI->wMinor = _ttoi(arrVersion[1].GetAddress());
    pVI->wBuild = _ttoi(arrVersion[2].GetAddress());
    pVI->wRevision = _ttoi(arrVersion[3].GetAddress());

    return true;
}

bool ParseCommandLine(int argc, TCHAR *argv[], CommandLineInfo *pCLI)
{
    if (argc <= 1)
    {
        ShowHelp();
        return false;
    }

    pCLI->bFileVersion = false;
    pCLI->bProductVersion = false;
    pCLI->mapStrings.Clear();
    pCLI->arrPaths.Clear();

    const xl::String strFileVersion = _T("/fileversion:");
    const xl::String strPruductVersion = _T("/productversion:");
    const xl::String strStringProperty = _T("/string:");
    const xl::String strRecursion = _T("/r");

    for (int i = 1; i < argc; ++i)
    {
        xl::String strCommand = argv[i];
        xl::String strCommandLower = strCommand.ToLower();

        if (strCommandLower.IndexOf(strFileVersion) == 0)
        {
            xl::String strVersion = strCommand.Right(strCommand.Length() - strFileVersion.Length());

            if (!ParseVersion(strVersion, &pCLI->viFile))
            {
                return false;
            }

            pCLI->bFileVersion = true;
        }
        else if (strCommandLower.IndexOf(strPruductVersion) == 0)
        {
            xl::String strVersion = strCommand.Right(strCommand.Length() - strPruductVersion.Length());

            if (!ParseVersion(strVersion, &pCLI->viProduct))
            {
                return false;
            }

            pCLI->bProductVersion = true;
        }
        else if (strCommandLower.IndexOf(strStringProperty) == 0)
        {
            xl::String strProperty = strCommand.Right(strCommand.Length() - strStringProperty.Length());
            xl::Array<xl::String> arrKeyValue = strProperty.Split(_T("="), 2);

            if (arrKeyValue.Size() != 2)
            {
                return false;
            }

            pCLI->mapStrings.Insert(arrKeyValue[0], arrKeyValue[1]);
        }
        else
        {
            PathFile pf;
            pf.strPattern = strCommand;
            pf.bRecursion = false;

            if (i + 1 < argc)
            {
                xl::String strExtra = argv[i + 1];
                strExtra.MakeLower();

                if (strExtra == strRecursion)
                {
                    pf.bRecursion = true;
                    ++i;
                }
            }

            pCLI->arrPaths.PushBack(pf);
        }
    }

    return true;
}

bool ModifyRCFile(const CommandLineInfo &cli, const xl::String strFile)
{
    _tprintf(_T("Modifying file %s...\n"), strFile.GetAddress());

    xl::String strRCData;

    if (!ReadRC(strFile.GetAddress(), &strRCData))
    {
        _tprintf(_T("Error: Failed to read RC file.\n"));
        return false;
    }

    if (cli.bFileVersion)
    {
        strRCData = RCModifyVersion(strRCData, VERSION_TYPE_FILE,
            cli.viFile.wMajor, cli.viFile.wMinor, cli.viFile.wBuild, cli.viFile.wRevision);
    }

    if (cli.bProductVersion)
    {
        strRCData = RCModifyVersion(strRCData, VERSION_TYPE_PRODUCT,
            cli.viProduct.wMajor, cli.viProduct.wMinor, cli.viProduct.wBuild, cli.viProduct.wRevision);
    }

    for (auto it = cli.mapStrings.Begin(); it != cli.mapStrings.End(); ++it)
    {
        strRCData = RCModifyVersionString(strRCData, it->Key.GetAddress(), it->Value.GetAddress());
    }

    if (!WriteRC(strRCData, strFile.GetAddress()))
    {
        _tprintf(_T("Error: Failed to write RC file.\n"));
        return false;
    }

    return true;
}

bool ModifyRCFiles(const CommandLineInfo &cli, const xl::String strSearch, bool bRecursion)
{
    WIN32_FIND_DATA wfd = {};

    xl::String strPath;
    xl::String strPattern;

    int nPos = strSearch.LastIndexOf(_T("\\"));

    if (nPos == -1)
    {
        strPattern = strSearch;
    }
    else
    {
        strPath = strSearch.Left(nPos + 1);
        strPattern = strSearch.Right(strSearch.Length() - nPos - 1);
    }

    bool bSuccess = true;

    while (true)
    {
        HANDLE hFind = FindFirstFile(strSearch.GetAddress(), &wfd);

        if (hFind == INVALID_HANDLE_VALUE)
        {
            break;
        }

        LOKI_ON_BLOCK_EXIT(FindClose, hFind);

        do
        {
            xl::String strFile = wfd.cFileName;

            if (strFile == _T(".") || strFile == _T(".."))
            {
                continue;
            }

            if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                continue;
            }

            if (!ModifyRCFile(cli, strPath + strFile))
            {
                bSuccess = false;
            }

        } while (FindNextFile(hFind, &wfd));

        break;
    }

    if (bRecursion)
    {
        HANDLE hFind = FindFirstFile((strPath + _T("*")).GetAddress(), &wfd);

        if (hFind == INVALID_HANDLE_VALUE)
        {
            return false;
        }

        LOKI_ON_BLOCK_EXIT(FindClose, hFind);

        bool bSuccess = true;

        do
        {
            xl::String strFile = wfd.cFileName;

            if (strFile == _T(".") || strFile == _T(".."))
            {
                continue;
            }

            if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
            {
                continue;
            }

            ModifyRCFiles(cli, strPath + strFile + _T("\\") + strPattern, true);

        } while (FindNextFile(hFind, &wfd));
    }

    return bSuccess;
}

bool ModifyRC(const CommandLineInfo &cli)
{
    bool bSuccess = true;

    for (auto it = cli.arrPaths.Begin(); it != cli.arrPaths.End(); ++it)
    {
        bSuccess = ModifyRCFiles(cli, it->strPattern, it->bRecursion) && bSuccess;
    }

    return true;
}

int _tmain(int argc, TCHAR *argv[])
{
    setlocale(LC_ALL, "");

    ShowCopyright();

    CommandLineInfo cli = {};

    if (!ParseCommandLine(argc, argv, &cli))
    {
        return RC_VERSION_FAILURE;
    }

    if (!ModifyRC(cli))
    {
        return RC_VERSION_FAILURE;
    }

    return RC_VERSION_SUCCEESS;
}

<commit_msg>add prompt<commit_after>#include <tchar.h>
#include "RCReader.h"
#include "RCVersion.h"
#include <locale.h>
#include <xl/Containers/xlArray.h>
#include <xl/Containers/xlMap.h>
#include <xl/Objects/xlString.h>
#include <Loki/ScopeGuard.h>

#define RC_VERSION_SUCCEESS 0
#define RC_VERSION_FAILURE  -1

struct VersionInfo
{
    WORD wMajor;
    WORD wMinor;
    WORD wBuild;
    WORD wRevision;
};

struct PathFile
{
    xl::String strPattern;
    bool bRecursion;
};

struct CommandLineInfo
{
    bool bFileVersion;
    bool bProductVersion;
    VersionInfo viFile;
    VersionInfo viProduct;
    xl::Map<xl::String, xl::String> mapStrings;
    xl::Array<PathFile> arrPaths;
};

void ShowCopyright()
{
    _tprintf(_T("RCVersion v1.0 by Streamlet\n"));
    _tprintf(_T("\n"));
}

void ShowHelp()
{
    _tprintf(_T("Usage: RCVersion[ /FileVersion:<N>,<N>,<N>,<N>]\n"));
    _tprintf(_T("                [ /ProductVersion:<N>,<N>,<N>,<N>]\n"));
    _tprintf(_T("                [ /String:<Property>=<Value>[ /String:<Property>=<Value>[...]]]\n"));
    _tprintf(_T("                <File>[ /r][ <File>[ /r][ ...]]\n"));
    _tprintf(_T("\n"));
    _tprintf(_T("       N        : An decimal integer from 0 to 65535.\n"));
    _tprintf(_T("       Property : Could be one of the following strings:\n"));
    _tprintf(_T("                      Comments\n"));
    _tprintf(_T("                      CompanyName\n"));
    _tprintf(_T("                      FileDescription\n"));
    _tprintf(_T("                      FileVersion\n"));
    _tprintf(_T("                      InternalName\n"));
    _tprintf(_T("                      LegalCopyright\n"));
    _tprintf(_T("                      LegalTrademarks\n"));
    _tprintf(_T("                      OriginalFilename\n"));
    _tprintf(_T("                      PrivateBuild\n"));
    _tprintf(_T("                      ProductName\n"));
    _tprintf(_T("                      ProductVersion\n"));
    _tprintf(_T("                      SpecialBuild\n"));
    _tprintf(_T("       Value    : Could be any string.\n"));
    _tprintf(_T("       File     : Path of target file. Wildcard is supported.\n"));
    _tprintf(_T("                  Use /r to search files recursively.\n"));
    _tprintf(_T("\n"));
}

bool ParseVersion(const xl::String &strVerison, VersionInfo *pVI)
{
    xl::Array<xl::String> arrVersion = strVerison.Split(_T(","));

    if (arrVersion.Size() != 4)
    {
        return false;
    }

    pVI->wMajor = _ttoi(arrVersion[0].GetAddress());
    pVI->wMinor = _ttoi(arrVersion[1].GetAddress());
    pVI->wBuild = _ttoi(arrVersion[2].GetAddress());
    pVI->wRevision = _ttoi(arrVersion[3].GetAddress());

    return true;
}

bool ParseCommandLine(int argc, TCHAR *argv[], CommandLineInfo *pCLI)
{
    if (argc <= 1)
    {
        ShowHelp();
        return false;
    }

    pCLI->bFileVersion = false;
    pCLI->bProductVersion = false;
    pCLI->mapStrings.Clear();
    pCLI->arrPaths.Clear();

    const xl::String strFileVersion = _T("/fileversion:");
    const xl::String strPruductVersion = _T("/productversion:");
    const xl::String strStringProperty = _T("/string:");
    const xl::String strRecursion = _T("/r");

    for (int i = 1; i < argc; ++i)
    {
        xl::String strCommand = argv[i];
        xl::String strCommandLower = strCommand.ToLower();

        if (strCommandLower.IndexOf(strFileVersion) == 0)
        {
            xl::String strVersion = strCommand.Right(strCommand.Length() - strFileVersion.Length());

            if (!ParseVersion(strVersion, &pCLI->viFile))
            {
                return false;
            }

            pCLI->bFileVersion = true;
        }
        else if (strCommandLower.IndexOf(strPruductVersion) == 0)
        {
            xl::String strVersion = strCommand.Right(strCommand.Length() - strPruductVersion.Length());

            if (!ParseVersion(strVersion, &pCLI->viProduct))
            {
                return false;
            }

            pCLI->bProductVersion = true;
        }
        else if (strCommandLower.IndexOf(strStringProperty) == 0)
        {
            xl::String strProperty = strCommand.Right(strCommand.Length() - strStringProperty.Length());
            xl::Array<xl::String> arrKeyValue = strProperty.Split(_T("="), 2);

            if (arrKeyValue.Size() != 2)
            {
                return false;
            }

            pCLI->mapStrings.Insert(arrKeyValue[0], arrKeyValue[1]);
        }
        else
        {
            PathFile pf;
            pf.strPattern = strCommand;
            pf.bRecursion = false;

            if (i + 1 < argc)
            {
                xl::String strExtra = argv[i + 1];
                strExtra.MakeLower();

                if (strExtra == strRecursion)
                {
                    pf.bRecursion = true;
                    ++i;
                }
            }

            pCLI->arrPaths.PushBack(pf);
        }
    }

    return true;
}

bool ModifyRCFile(const CommandLineInfo &cli, const xl::String strFile)
{
    _tprintf(_T("Modifying file %s...\n"), strFile.GetAddress());

    xl::String strRCData;

    if (!ReadRC(strFile.GetAddress(), &strRCData))
    {
        _tprintf(_T("Error: Failed to read RC file.\n"));
        return false;
    }

    if (cli.bFileVersion)
    {
        strRCData = RCModifyVersion(strRCData, VERSION_TYPE_FILE,
            cli.viFile.wMajor, cli.viFile.wMinor, cli.viFile.wBuild, cli.viFile.wRevision);
    }

    if (cli.bProductVersion)
    {
        strRCData = RCModifyVersion(strRCData, VERSION_TYPE_PRODUCT,
            cli.viProduct.wMajor, cli.viProduct.wMinor, cli.viProduct.wBuild, cli.viProduct.wRevision);
    }

    for (auto it = cli.mapStrings.Begin(); it != cli.mapStrings.End(); ++it)
    {
        strRCData = RCModifyVersionString(strRCData, it->Key.GetAddress(), it->Value.GetAddress());
    }

    if (!WriteRC(strRCData, strFile.GetAddress()))
    {
        _tprintf(_T("Error: Failed to write RC file.\n"));
        return false;
    }

    return true;
}

bool ModifyRCFiles(const CommandLineInfo &cli, const xl::String strSearch, bool bRecursion)
{
    WIN32_FIND_DATA wfd = {};

    xl::String strPath;
    xl::String strPattern;

    int nPos = strSearch.LastIndexOf(_T("\\"));

    if (nPos == -1)
    {
        strPattern = strSearch;
    }
    else
    {
        strPath = strSearch.Left(nPos + 1);
        strPattern = strSearch.Right(strSearch.Length() - nPos - 1);
    }

    bool bSuccess = true;

    while (true)
    {
        HANDLE hFind = FindFirstFile(strSearch.GetAddress(), &wfd);

        if (hFind == INVALID_HANDLE_VALUE)
        {
            break;
        }

        LOKI_ON_BLOCK_EXIT(FindClose, hFind);

        do
        {
            xl::String strFile = wfd.cFileName;

            if (strFile == _T(".") || strFile == _T(".."))
            {
                continue;
            }

            if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                continue;
            }

            if (!ModifyRCFile(cli, strPath + strFile))
            {
                bSuccess = false;
            }

        } while (FindNextFile(hFind, &wfd));

        break;
    }

    if (bRecursion)
    {
        HANDLE hFind = FindFirstFile((strPath + _T("*")).GetAddress(), &wfd);

        if (hFind == INVALID_HANDLE_VALUE)
        {
            return false;
        }

        LOKI_ON_BLOCK_EXIT(FindClose, hFind);

        bool bSuccess = true;

        do
        {
            xl::String strFile = wfd.cFileName;

            if (strFile == _T(".") || strFile == _T(".."))
            {
                continue;
            }

            if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
            {
                continue;
            }

            ModifyRCFiles(cli, strPath + strFile + _T("\\") + strPattern, true);

        } while (FindNextFile(hFind, &wfd));
    }

    return bSuccess;
}

bool ModifyRC(const CommandLineInfo &cli)
{
    bool bSuccess = true;

    for (auto it = cli.arrPaths.Begin(); it != cli.arrPaths.End(); ++it)
    {
        bSuccess = ModifyRCFiles(cli, it->strPattern, it->bRecursion) && bSuccess;
    }

    return true;
}

int _tmain(int argc, TCHAR *argv[])
{
    setlocale(LC_ALL, "");

    ShowCopyright();

    CommandLineInfo cli = {};

    if (!ParseCommandLine(argc, argv, &cli))
    {
        return RC_VERSION_FAILURE;
    }

    if (!ModifyRC(cli))
    {
        return RC_VERSION_FAILURE;
    }

    return RC_VERSION_SUCCEESS;
}

<|endoftext|>