<commit_before>#include <mpi.h>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <unistd.h>
#include <sstream>
#include <cmath>
#include "IDType.h"
#include "BonsaiSharedData.h"
#include "BonsaiIO.h"
#include "SharedMemory.h"
#ifndef BONSAI_CATALYST_CLANG
 #include <omp.h>
#endif
#include <functional>

#include "anyoption.h"
#include "RendererData.h"

using ShmQHeader = SharedMemoryServer<BonsaiSharedQuickHeader>;
using ShmQData   = SharedMemoryServer<BonsaiSharedQuickData>;
static ShmQHeader *shmQHeader = NULL;
static ShmQData   *shmQData   = NULL;

static void lTerminateIO()
{
  auto &header = *shmQHeader;
  header.acquireLock();
  header[0].tCurrent = -1;
  header[0].done_writing = false;
  header.releaseLock();
}

struct data_t
{
  float posx,posy,posz, mass;
  float velx,vely,velz;
  float rho,h;
  IDType ID;
};
using DataVec = std::vector<data_t>;

static void sendSharedData(
    const bool sync,
    const double t_current,
    const DataVec &rdata,
    const char fileName[],
    const int rank,
    const int nrank,
    const MPI_Comm &comm)
{
  if (shmQHeader == NULL)
  {
    const size_t capacity  = rdata.size()*2;
    shmQHeader = new ShmQHeader(ShmQHeader::type::sharedFile(rank), 1);
    shmQData   = new ShmQData  (ShmQData  ::type::sharedFile(rank), capacity);
  }

  auto &header = *shmQHeader;
  auto &data   = *shmQData;

  static bool handShake = false;
  if (sync && !handShake)
  {
    /* handshake */

    header[0].tCurrent = t_current;
    header[0].done_writing = true;

    header.acquireLock();
    header[0].handshake = false;
    header.releaseLock();

    while (!header[0].handshake)
      usleep(100);

    header.acquireLock();
    header[0].handshake = false;
    header.releaseLock();

    /* handshake complete */
    handShake = true;
  }

  if (sync)
    while (!header[0].done_writing);

  const size_t np = rdata.size();

  header.acquireLock();
  header[0].tCurrent = t_current;
  header[0].nBodies  = np;
  for (int i = 0; i < 1024; i++)
  {
    header[0].fileName[i] = fileName[i];
    if (fileName[i] == 0)
      break;
  }

  data.acquireLock();
  if (!data.resize(np))
  {
    std::cerr << "rank= " << rank << ": failed to resize. ";
    std::cerr << "Request " << np << " but capacity is  " << data.capacity() << "." << std::endl;
    data.releaseLock();
    header.releaseLock();
    MPI_Finalize();
    ::exit(0);
  }

  for (size_t i = 0; i < np; i++)
  {
    auto &p       =  data[i];
    const auto &d = rdata[i];
    p.x    = d.posx;
    p.y    = d.posy;
    p.z    = d.posz;
    p.mass = d.mass;
    p.vx   = d.velx;
    p.vy   = d.vely;
    p.vz   = d.velz;
    p.vw   = 0.0;
    p.rho  = d.rho;
    p.h    = d.h;
    p.ID   = d.ID;
  }
  data.releaseLock();

  header[0].done_writing = false;
  header.releaseLock();
}

static std::tuple<double,DataVec> readBonsai(
    const int rank, const int nranks, const MPI_Comm &comm,
    const std::string &fileName,
    const int reduceDM,
    const int reduceS,
    const bool print_header = false)
{
  const double t0 = MPI_Wtime();
  BonsaiIO::Core in(rank, nranks, comm, BonsaiIO::READ, fileName);
  if (rank == 0 && print_header)
  {
    fprintf(stderr, "---- Bonsai header info ----\n");
    in.getHeader().printFields();
    fprintf(stderr, "----------------------------\n");
  }
  typedef float float4[4];
  typedef float float3[3];
  typedef float float2[2];

  BonsaiIO::DataType<IDType> IDListS("Stars:IDType");
  BonsaiIO::DataType<float4> posS("Stars:POS:real4");
  BonsaiIO::DataType<float3> velS("Stars:VEL:float[3]");
  BonsaiIO::DataType<float2> rhohS("Stars:RHOH:float[2]");

  DataVec rdata;
  if (reduceS > 0)
  {
    if (!in.read(IDListS, true, reduceS)) return std::make_tuple(-1.0,rdata);
    if (rank  == 0)
      fprintf(stderr, " Reading star data \n");
    assert(in.read(posS,    true, reduceS));
    assert(in.read(velS,    true, reduceS));
    bool renderDensity = true;
    if (!in.read(rhohS,  true, reduceS))
    {
      if (rank == 0)
      {
        fprintf(stderr , " -- Stars RHOH data is found \n");
        fprintf(stderr , " -- rendering stars w/o density info \n");
      }
      renderDensity = false;
    }
    assert(IDListS.getNumElements() == posS.getNumElements());
    assert(IDListS.getNumElements() == velS.getNumElements());
    if (renderDensity)
      assert(IDListS.getNumElements() == posS.getNumElements());
  }

  BonsaiIO::DataType<IDType> IDListDM("DM:IDType");
  BonsaiIO::DataType<float4> posDM("DM:POS:real4");
  BonsaiIO::DataType<float3> velDM("DM:VEL:float[3]");
  BonsaiIO::DataType<float2> rhohDM("DM:RHOH:float[2]");
  if (reduceDM > 0)
  {
    if (rank  == 0)
      fprintf(stderr, " Reading DM data \n");
    if(!in.read(IDListDM, true, reduceDM)) return std::make_tuple(-1.0,rdata);
    assert(in.read(posDM,    true, reduceDM));
    assert(in.read(velDM,    true, reduceDM));
    bool renderDensity = true;
    if (!in.read(rhohDM,  true, reduceDM))
    {
      if (rank == 0)
      {
        fprintf(stderr , " -- DM RHOH data is found \n");
        fprintf(stderr , " -- rendering stars w/o density info \n");
      }
      renderDensity = false;
    }
    assert(IDListS.getNumElements() == posS.getNumElements());
    assert(IDListS.getNumElements() == velS.getNumElements());
    if (renderDensity)
      assert(IDListS.getNumElements() == posS.getNumElements());
  }

  const double t1 = MPI_Wtime();

  const int nS  = IDListS.getNumElements();
  const int nDM = IDListDM.getNumElements();
  long long int nSloc = nS, nSglb;
  long long int nDMloc = nDM, nDMglb;

  MPI_Allreduce(&nSloc, &nSglb, 1, MPI_LONG, MPI_SUM, comm);
  MPI_Allreduce(&nDMloc, &nDMglb, 1, MPI_LONG, MPI_SUM, comm);
  if (rank == 0)
  {
    fprintf(stderr, "nStars = %lld\n", nSglb);
    fprintf(stderr, "nDM    = %lld\n", nDMglb);
  }

  rdata.resize(nS+nDM);
  for (int i = 0; i < nS; i++)
  {
    auto &d = rdata[i];
    d.posx = posS[i][0];
    d.posy = posS[i][1];
    d.posz = posS[i][2];
    d.mass = posS[i][3];
    d.ID   = IDListS[i];
    assert(d.ID.getType() > 0); /* sanity check */
    d.velx = velS[i][0];
    d.vely = velS[i][1];
    d.velz = velS[i][2];
    if (rhohS.size() > 0)
    {
      d.rho = rhohS[i][0];
      d.h   = rhohS[i][1];
    }
    else
    {
      d.rho = 0.0;
      d.h   = 0.0;
    }
  }

  const double bw = in.computeBandwidth()/1e6;
  const double dtRead = t1-t0;
  if (rank == 0)
    fprintf(stderr, " :: dtRead= %g  sec readBW= %g MB/s \n", dtRead, bw);
  const double t = in.getTime();
  in.close();
  return std::make_tuple(t,rdata);
}

static std::vector<std::string> lParseList(const std::string fileNameList)
{
  std::ifstream fin(fileNameList);

  std::string item;
  std::vector<std::string> fileList;
  while (std::getline(fin, item))
    if (!item.empty())
      fileList.push_back(item);

  fin.close();
  return fileList;
}

#ifndef BONSAI_CATALYST_CLANG
int main(int argc, char * argv[], MPI_Comm commWorld)
{
#else
int main(int argc, char * argv[])
{
 MPI_Comm commWorld;
#endif

  std::string fileNameList;
  int nloop    = 1;
  bool quickSync = true;
  int reduceDM = 10;
  int reduceS  = 1;
  int delay = 0;

  {
    AnyOption opt;

#define ADDUSAGE(line) {{std::stringstream oss; oss << line; opt.addUsage(oss.str());}}

    ADDUSAGE(" ");
    ADDUSAGE("Usage:");
    ADDUSAGE(" ");
    ADDUSAGE(" -h  --help             Prints this help ");
    ADDUSAGE(" -i  --inlist #         Input list with snapshot filenames");
    ADDUSAGE(" -l  --loop   #         Loop count through file list [1]");
    ADDUSAGE(" -d  --delay  #         Delay between new shapshots in ms [0/none]");
    ADDUSAGE("     --noquicksync      disable syncing with the client ");
    ADDUSAGE("     --reduceDM    #    cut down DM dataset by # factor [10]. 0-disable DM");
    ADDUSAGE("     --reduceS     #    cut down stars dataset by # factor [1]. 0-disable S");

    opt.setFlag  ( "help" ,        'h');
    opt.setOption( "inlist",       'i');
    opt.setOption( "loop",         'l');
    opt.setOption( "delay",        'd');
    opt.setFlag  ( "noquicksync");
    opt.setOption( "reduceDM");
    opt.setOption( "reduceS");

    opt.processCommandArgs( argc, argv );

    if( ! opt.hasOptions() ||  opt.getFlag( "help" ) || opt.getFlag( 'h' ) )
    {
      /* print usage if no options or requested help */
      opt.printUsage();
      ::exit(0);
    }

    char *optarg = NULL;
    if ((optarg = opt.getValue("inlist")))    fileNameList       = std::string(optarg);
    if ((optarg = opt.getValue("loop")))      nloop              = atoi(optarg);
    if ((optarg = opt.getValue("reduceDM"))) reduceDM       = atoi(optarg);
    if ((optarg = opt.getValue("reduceS"))) reduceS       = atoi(optarg);
    if ((optarg = opt.getValue("delay"))) delay       = atoi(optarg);
    if (opt.getFlag("noquicksync")) quickSync = false;

    if (fileNameList.empty() ||
        reduceDM < 0 || reduceS < 0)
    {
      opt.printUsage();
      ::exit(0);
    }

#undef ADDUSAGE
  }

  MPI_Comm comm = MPI_COMM_WORLD;
  int mpiInitialized = 0;
  MPI_Initialized(&mpiInitialized);
  if (!mpiInitialized)
    MPI_Init(&argc, &argv);
  else
    comm = commWorld;

  int nranks, rank;
  MPI_Comm_size(comm, &nranks);
  MPI_Comm_rank(comm, &rank);

  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int namelen;
  MPI_Get_processor_name(processor_name,&namelen);
  fprintf(stderr, "bonsai_snapServe:: Proc id: %d @ %s , total processes: %d (mpiInit) \n", rank, processor_name, nranks);

  if (rank == 0)
  {
    fprintf(stderr , " quickSync= %s \n", quickSync ? "true" : "false");
    fprintf(stderr , " delay= %d msec \n", delay);
  }

  const auto &fileList = lParseList(fileNameList);

  for (int i = 0; i < nloop; i++)
    for (const auto &file : fileList)
    {
      if (rank == 0)
        fprintf(stderr, "loop= %3d: filename= %s \n", i, file.c_str());
      const auto &data = readBonsai(rank, nranks, comm,
          file, reduceDM, reduceS);
      fprintf(stderr, "rank= %d : time= %g np= %d \n",
          rank, std::get<0>(data), std::get<1>(data).size());
      sendSharedData(quickSync, std::get<0>(data), std::get<1>(data), file.c_str(), rank, nranks, comm);
      if (delay > 0)
        usleep(1000*delay);
    }

  lTerminateIO();

  MPI_Finalize();

  return 0;
}

<commit_msg>fix warrning<commit_after>#include <mpi.h>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <unistd.h>
#include <sstream>
#include <cmath>
#include "IDType.h"
#include "BonsaiSharedData.h"
#include "BonsaiIO.h"
#include "SharedMemory.h"
#ifndef BONSAI_CATALYST_CLANG
 #include <omp.h>
#endif
#include <functional>

#include "anyoption.h"
#include "RendererData.h"

using ShmQHeader = SharedMemoryServer<BonsaiSharedQuickHeader>;
using ShmQData   = SharedMemoryServer<BonsaiSharedQuickData>;
static ShmQHeader *shmQHeader = NULL;
static ShmQData   *shmQData   = NULL;

static void lTerminateIO()
{
  auto &header = *shmQHeader;
  header.acquireLock();
  header[0].tCurrent = -1;
  header[0].done_writing = false;
  header.releaseLock();
}

struct data_t
{
  float posx,posy,posz, mass;
  float velx,vely,velz;
  float rho,h;
  IDType ID;
};
using DataVec = std::vector<data_t>;

static void sendSharedData(
    const bool sync,
    const double t_current,
    const DataVec &rdata,
    const char fileName[],
    const int rank,
    const int nrank,
    const MPI_Comm &comm)
{
  if (shmQHeader == NULL)
  {
    const size_t capacity  = rdata.size()*2;
    shmQHeader = new ShmQHeader(ShmQHeader::type::sharedFile(rank), 1);
    shmQData   = new ShmQData  (ShmQData  ::type::sharedFile(rank), capacity);
  }

  auto &header = *shmQHeader;
  auto &data   = *shmQData;

  static bool handShake = false;
  if (sync && !handShake)
  {
    /* handshake */

    header[0].tCurrent = t_current;
    header[0].done_writing = true;

    header.acquireLock();
    header[0].handshake = false;
    header.releaseLock();

    while (!header[0].handshake)
      usleep(100);

    header.acquireLock();
    header[0].handshake = false;
    header.releaseLock();

    /* handshake complete */
    handShake = true;
  }

  if (sync)
    while (!header[0].done_writing);

  const size_t np = rdata.size();

  header.acquireLock();
  header[0].tCurrent = t_current;
  header[0].nBodies  = np;
  for (int i = 0; i < 1024; i++)
  {
    header[0].fileName[i] = fileName[i];
    if (fileName[i] == 0)
      break;
  }

  data.acquireLock();
  if (!data.resize(np))
  {
    std::cerr << "rank= " << rank << ": failed to resize. ";
    std::cerr << "Request " << np << " but capacity is  " << data.capacity() << "." << std::endl;
    data.releaseLock();
    header.releaseLock();
    MPI_Finalize();
    ::exit(0);
  }

  for (size_t i = 0; i < np; i++)
  {
    auto &p       =  data[i];
    const auto &d = rdata[i];
    p.x    = d.posx;
    p.y    = d.posy;
    p.z    = d.posz;
    p.mass = d.mass;
    p.vx   = d.velx;
    p.vy   = d.vely;
    p.vz   = d.velz;
    p.vw   = 0.0;
    p.rho  = d.rho;
    p.h    = d.h;
    p.ID   = d.ID;
  }
  data.releaseLock();

  header[0].done_writing = false;
  header.releaseLock();
}

static std::tuple<double,DataVec> readBonsai(
    const int rank, const int nranks, const MPI_Comm &comm,
    const std::string &fileName,
    const int reduceDM,
    const int reduceS,
    const bool print_header = false)
{
  const double t0 = MPI_Wtime();
  BonsaiIO::Core in(rank, nranks, comm, BonsaiIO::READ, fileName);
  if (rank == 0 && print_header)
  {
    fprintf(stderr, "---- Bonsai header info ----\n");
    in.getHeader().printFields();
    fprintf(stderr, "----------------------------\n");
  }
  typedef float float4[4];
  typedef float float3[3];
  typedef float float2[2];

  BonsaiIO::DataType<IDType> IDListS("Stars:IDType");
  BonsaiIO::DataType<float4> posS("Stars:POS:real4");
  BonsaiIO::DataType<float3> velS("Stars:VEL:float[3]");
  BonsaiIO::DataType<float2> rhohS("Stars:RHOH:float[2]");

  DataVec rdata;
  if (reduceS > 0)
  {
    if (!in.read(IDListS, true, reduceS)) return std::make_tuple(-1.0,rdata);
    if (rank  == 0)
      fprintf(stderr, " Reading star data \n");
    assert(in.read(posS,    true, reduceS));
    assert(in.read(velS,    true, reduceS));
    bool renderDensity = true;
    if (!in.read(rhohS,  true, reduceS))
    {
      if (rank == 0)
      {
        fprintf(stderr , " -- Stars RHOH data is found \n");
        fprintf(stderr , " -- rendering stars w/o density info \n");
      }
      renderDensity = false;
    }
    assert(IDListS.getNumElements() == posS.getNumElements());
    assert(IDListS.getNumElements() == velS.getNumElements());
    if (renderDensity)
      assert(IDListS.getNumElements() == posS.getNumElements());
  }

  BonsaiIO::DataType<IDType> IDListDM("DM:IDType");
  BonsaiIO::DataType<float4> posDM("DM:POS:real4");
  BonsaiIO::DataType<float3> velDM("DM:VEL:float[3]");
  BonsaiIO::DataType<float2> rhohDM("DM:RHOH:float[2]");
  if (reduceDM > 0)
  {
    if (rank  == 0)
      fprintf(stderr, " Reading DM data \n");
    if(!in.read(IDListDM, true, reduceDM)) return std::make_tuple(-1.0,rdata);
    assert(in.read(posDM,    true, reduceDM));
    assert(in.read(velDM,    true, reduceDM));
    bool renderDensity = true;
    if (!in.read(rhohDM,  true, reduceDM))
    {
      if (rank == 0)
      {
        fprintf(stderr , " -- DM RHOH data is found \n");
        fprintf(stderr , " -- rendering stars w/o density info \n");
      }
      renderDensity = false;
    }
    assert(IDListS.getNumElements() == posS.getNumElements());
    assert(IDListS.getNumElements() == velS.getNumElements());
    if (renderDensity)
      assert(IDListS.getNumElements() == posS.getNumElements());
  }

  const double t1 = MPI_Wtime();

  const int nS  = IDListS.getNumElements();
  const int nDM = IDListDM.getNumElements();
  long long int nSloc = nS, nSglb;
  long long int nDMloc = nDM, nDMglb;

  MPI_Allreduce(&nSloc, &nSglb, 1, MPI_LONG, MPI_SUM, comm);
  MPI_Allreduce(&nDMloc, &nDMglb, 1, MPI_LONG, MPI_SUM, comm);
  if (rank == 0)
  {
    fprintf(stderr, "nStars = %lld\n", nSglb);
    fprintf(stderr, "nDM    = %lld\n", nDMglb);
  }

  rdata.resize(nS+nDM);
  for (int i = 0; i < nS; i++)
  {
    auto &d = rdata[i];
    d.posx = posS[i][0];
    d.posy = posS[i][1];
    d.posz = posS[i][2];
    d.mass = posS[i][3];
    d.ID   = IDListS[i];
    assert(d.ID.getType() > 0); /* sanity check */
    d.velx = velS[i][0];
    d.vely = velS[i][1];
    d.velz = velS[i][2];
    if (rhohS.size() > 0)
    {
      d.rho = rhohS[i][0];
      d.h   = rhohS[i][1];
    }
    else
    {
      d.rho = 0.0;
      d.h   = 0.0;
    }
  }

  const double bw = in.computeBandwidth()/1e6;
  const double dtRead = t1-t0;
  if (rank == 0)
    fprintf(stderr, " :: dtRead= %g  sec readBW= %g MB/s \n", dtRead, bw);
  const double t = in.getTime();
  in.close();
  return std::make_tuple(t,rdata);
}

static std::vector<std::string> lParseList(const std::string fileNameList)
{
  std::ifstream fin(fileNameList);

  std::string item;
  std::vector<std::string> fileList;
  while (std::getline(fin, item))
    if (!item.empty())
      fileList.push_back(item);

  fin.close();
  return fileList;
}

#ifndef BONSAI_CATALYST_CLANG
int main(int argc, char * argv[], MPI_Comm commWorld)
{
#else
int main(int argc, char * argv[])
{
 MPI_Comm commWorld;
#endif

  std::string fileNameList;
  int nloop    = 1;
  bool quickSync = true;
  int reduceDM = 10;
  int reduceS  = 1;
  int delay = 0;

  {
    AnyOption opt;

#define ADDUSAGE(line) {{std::stringstream oss; oss << line; opt.addUsage(oss.str());}}

    ADDUSAGE(" ");
    ADDUSAGE("Usage:");
    ADDUSAGE(" ");
    ADDUSAGE(" -h  --help             Prints this help ");
    ADDUSAGE(" -i  --inlist #         Input list with snapshot filenames");
    ADDUSAGE(" -l  --loop   #         Loop count through file list [1]");
    ADDUSAGE(" -d  --delay  #         Delay between new shapshots in ms [0/none]");
    ADDUSAGE("     --noquicksync      disable syncing with the client ");
    ADDUSAGE("     --reduceDM    #    cut down DM dataset by # factor [10]. 0-disable DM");
    ADDUSAGE("     --reduceS     #    cut down stars dataset by # factor [1]. 0-disable S");

    opt.setFlag  ( "help" ,        'h');
    opt.setOption( "inlist",       'i');
    opt.setOption( "loop",         'l');
    opt.setOption( "delay",        'd');
    opt.setFlag  ( "noquicksync");
    opt.setOption( "reduceDM");
    opt.setOption( "reduceS");

    opt.processCommandArgs( argc, argv );

    if( ! opt.hasOptions() ||  opt.getFlag( "help" ) || opt.getFlag( 'h' ) )
    {
      /* print usage if no options or requested help */
      opt.printUsage();
      ::exit(0);
    }

    char *optarg = NULL;
    if ((optarg = opt.getValue("inlist")))    fileNameList       = std::string(optarg);
    if ((optarg = opt.getValue("loop")))      nloop              = atoi(optarg);
    if ((optarg = opt.getValue("reduceDM"))) reduceDM       = atoi(optarg);
    if ((optarg = opt.getValue("reduceS"))) reduceS       = atoi(optarg);
    if ((optarg = opt.getValue("delay"))) delay       = atoi(optarg);
    if (opt.getFlag("noquicksync")) quickSync = false;

    if (fileNameList.empty() ||
        reduceDM < 0 || reduceS < 0)
    {
      opt.printUsage();
      ::exit(0);
    }

#undef ADDUSAGE
  }

  MPI_Comm comm = MPI_COMM_WORLD;
  int mpiInitialized = 0;
  MPI_Initialized(&mpiInitialized);
  if (!mpiInitialized)
    MPI_Init(&argc, &argv);
  else
    comm = commWorld;

  int nranks, rank;
  MPI_Comm_size(comm, &nranks);
  MPI_Comm_rank(comm, &rank);

  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int namelen;
  MPI_Get_processor_name(processor_name,&namelen);
  fprintf(stderr, "bonsai_snapServe:: Proc id: %d @ %s , total processes: %d (mpiInit) \n", rank, processor_name, nranks);

  if (rank == 0)
  {
    fprintf(stderr , " quickSync= %s \n", quickSync ? "true" : "false");
    fprintf(stderr , " delay= %d msec \n", delay);
  }

  const auto &fileList = lParseList(fileNameList);

  for (int i = 0; i < nloop; i++)
    for (const auto &file : fileList)
    {
      if (rank == 0)
        fprintf(stderr, "loop= %3d: filename= %s \n", i, file.c_str());
      const auto &data = readBonsai(rank, nranks, comm,
          file, reduceDM, reduceS);
      fprintf(stderr, "rank= %d : time= %g np= %zu \n",
          rank, std::get<0>(data), std::get<1>(data).size());
      sendSharedData(quickSync, std::get<0>(data), std::get<1>(data), file.c_str(), rank, nranks, comm);
      if (delay > 0)
        usleep(1000*delay);
    }

  lTerminateIO();

  MPI_Finalize();

  return 0;
}

<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2015 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/kernel/xiocompletion.h"

namespace xe {
namespace kernel {

XIOCompletion::XIOCompletion(KernelState* kernel_state)
    : XObject(kernel_state, kObjectType) {
  notification_semaphore_ = threading::Semaphore::Create(0, kMaxNotifications);
}

XIOCompletion::~XIOCompletion() = default;

void XIOCompletion::QueueNotification(IONotification& notification) {
  std::unique_lock<std::mutex> lock(notification_lock_);

  notifications_.push(notification);
  notification_semaphore_->Release(1, nullptr);
}

bool XIOCompletion::WaitForNotification(uint64_t wait_ticks,
                                        IONotification* notify) {
  auto ms = std::chrono::milliseconds(TimeoutTicksToMs(wait_ticks));
  auto res = threading::Wait(notification_semaphore_.get(), false, ms);
  if (res == threading::WaitResult::kSuccess) {
    std::unique_lock<std::mutex> lock(notification_lock_);
    assert_false(notifications_.empty());

    std::memcpy(notify, &notifications_.front(), sizeof(IONotification));
    notifications_.pop();

    return true;
  }

  return false;
}

}  // namespace kernel
}  // namespace xe
<commit_msg>[Kernel] WaitForNotification skip wait w/o wait_ticks<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2015 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/kernel/xiocompletion.h"

namespace xe {
namespace kernel {

XIOCompletion::XIOCompletion(KernelState* kernel_state)
    : XObject(kernel_state, kObjectType) {
  notification_semaphore_ = threading::Semaphore::Create(0, kMaxNotifications);
}

XIOCompletion::~XIOCompletion() = default;

void XIOCompletion::QueueNotification(IONotification& notification) {
  std::unique_lock<std::mutex> lock(notification_lock_);

  notifications_.push(notification);
  notification_semaphore_->Release(1, nullptr);
}

bool XIOCompletion::WaitForNotification(uint64_t wait_ticks,
                                        IONotification* notify) {
  auto ms = std::chrono::milliseconds(TimeoutTicksToMs(wait_ticks));
  auto res = threading::Wait(notification_semaphore_.get(), false, ms);
  if (res == threading::WaitResult::kSuccess || !wait_ticks) {
    std::unique_lock<std::mutex> lock(notification_lock_);
    assert_false(notifications_.empty());

    std::memcpy(notify, &notifications_.front(), sizeof(IONotification));
    notifications_.pop();

    return true;
  }

  return false;
}

}  // namespace kernel
}  // namespace xe
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLException.hpp>
#include <xercesc/util/Mutexes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local, static data
// ---------------------------------------------------------------------------
static XMLMsgLoader* sMsgLoader = 0;
static XMLRegisterCleanup msgLoaderCleanup;
static bool sScannerMutexRegistered = false;
static XMLMutex* sMsgMutex = 0;
static XMLRegisterCleanup msgMutexCleanup;

// ---------------------------------------------------------------------------
//  Local, static functions
// ---------------------------------------------------------------------------

//
//  We need to fault in this mutex. But, since its used for synchronization
//  itself, we have to do this the low level way using a compare and swap.
//
static XMLMutex& gMsgMutex()
{
    if (!sScannerMutexRegistered)
    {
        XMLMutexLock lockInit(XMLPlatformUtils::fgAtomicMutex);

        if (!sScannerMutexRegistered)
        {
            sMsgMutex = new XMLMutex;
            msgMutexCleanup.registerCleanup(XMLException::reinitMsgMutex);
            sScannerMutexRegistered = true;
        }
    }

    return *sMsgMutex;
}

//
//  This method is a lazy evaluator for the message loader for exception
//  messages.
//
static XMLMsgLoader& gGetMsgLoader()
{
    if (!sMsgLoader)
    {
        // Lock the message loader mutex and load the text
	    XMLMutexLock lockInit(&gMsgMutex());

        // Fault it in on first request
        if (!sMsgLoader)
        {
            sMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgExceptDomain);
            if (!sMsgLoader)
                XMLPlatformUtils::panic(PanicHandler::Panic_CantLoadMsgDomain);

            //
            // Register this XMLMsgLoader for cleanup at Termination.
            //
            msgLoaderCleanup.registerCleanup(XMLException::reinitMsgLoader);
        }
    }

    // We got it, so return it
    return *sMsgLoader;
}

// ---------------------------------------------------------------------------
//  XMLException: Virtual destructor
// ---------------------------------------------------------------------------
XMLException::~XMLException()
{
    fMemoryManager->deallocate(fMsg);
    fMemoryManager->deallocate(fSrcFile);
}

// ---------------------------------------------------------------------------
//  XMLException: Setter methods
// ---------------------------------------------------------------------------
void XMLException::setPosition(const char* const file, const unsigned int line)
{
    fSrcLine = line;
	fMemoryManager->deallocate(fSrcFile);
    fSrcFile = XMLString::replicate(file, fMemoryManager);
}

// ---------------------------------------------------------------------------
//  XMLException: Hidden constructors and operators
// ---------------------------------------------------------------------------
XMLException::XMLException() :

    fCode(XMLExcepts::NoError)
    , fSrcFile(0)
    , fSrcLine(0)
    , fMsg(0)
    , fMemoryManager(0)
{
}

XMLException::XMLException( const   char* const     srcFile
                            , const unsigned int    srcLine
                            , MemoryManager* const  memoryManager) :

    fCode(XMLExcepts::NoError)
    , fSrcFile(0)
    , fSrcLine(srcLine)
    , fMsg(0)
    , fMemoryManager(memoryManager)
{
    if (!memoryManager)
        fMemoryManager = XMLPlatformUtils::fgMemoryManager;
    fSrcFile = XMLString::replicate(srcFile, fMemoryManager);
}

XMLException::XMLException(const XMLException& toCopy) :

    fCode(toCopy.fCode)
    , fSrcFile(0)
    , fSrcLine(toCopy.fSrcLine)
    , fMsg(XMLString::replicate(toCopy.fMsg, toCopy.fMemoryManager))
    , fMemoryManager(toCopy.fMemoryManager)
{
    if (toCopy.fSrcFile) {
        fSrcFile = XMLString::replicate
        (
            toCopy.fSrcFile
            , fMemoryManager
        );
    }
}

XMLException& XMLException::operator=(const XMLException& toAssign)
{
    if (this != &toAssign)
    {
        //use the original memory manager to deallocate
        fMemoryManager->deallocate(fSrcFile);
        fSrcFile = 0;
        fMemoryManager->deallocate(fMsg);
        fMsg = 0;

        fMemoryManager = toAssign.fMemoryManager;
        fSrcLine = toAssign.fSrcLine;
        fCode = toAssign.fCode;

        if (toAssign.fMsg) {
            fMsg = XMLString::replicate
            (
                toAssign.fMsg
                , fMemoryManager
            );
        }

        if (toAssign.fSrcFile) {
            fSrcFile = XMLString::replicate
            (
                toAssign.fSrcFile
                , fMemoryManager
            );
        }
    }
    return *this;
}

// ---------------------------------------------------------------------------
//  XMLException: Protected methods
// ---------------------------------------------------------------------------
void XMLException::loadExceptText(const XMLExcepts::Codes toLoad)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 2047;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

void
XMLException::loadExceptText(const  XMLExcepts::Codes toLoad
                            , const XMLCh* const        text1
                            , const XMLCh* const        text2
                            , const XMLCh* const        text3
                            , const XMLCh* const        text4)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 4095;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize, text1, text2, text3, text4, fMemoryManager))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

void
XMLException::loadExceptText(const  XMLExcepts::Codes toLoad
                            , const char* const         text1
                            , const char* const         text2
                            , const char* const         text3
                            , const char* const         text4)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 4095;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize, text1, text2, text3, text4, fMemoryManager))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

// -----------------------------------------------------------------------
//  Reinitialise the message mutex
// -----------------------------------------------------------------------
void XMLException::reinitMsgMutex()
{
    delete sMsgMutex;
    sMsgMutex = 0;
    sScannerMutexRegistered = false;
}

// -----------------------------------------------------------------------
//  Reinitialise the message loader
// -----------------------------------------------------------------------
void XMLException::reinitMsgLoader()
{
    delete sMsgLoader;
    sMsgLoader = 0;
}

XERCES_CPP_NAMESPACE_END
<commit_msg>Initialize memory manager to default.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLException.hpp>
#include <xercesc/util/Mutexes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

// ---------------------------------------------------------------------------
//  Local, static data
// ---------------------------------------------------------------------------
static XMLMsgLoader* sMsgLoader = 0;
static XMLRegisterCleanup msgLoaderCleanup;
static bool sScannerMutexRegistered = false;
static XMLMutex* sMsgMutex = 0;
static XMLRegisterCleanup msgMutexCleanup;

// ---------------------------------------------------------------------------
//  Local, static functions
// ---------------------------------------------------------------------------

//
//  We need to fault in this mutex. But, since its used for synchronization
//  itself, we have to do this the low level way using a compare and swap.
//
static XMLMutex& gMsgMutex()
{
    if (!sScannerMutexRegistered)
    {
        XMLMutexLock lockInit(XMLPlatformUtils::fgAtomicMutex);

        if (!sScannerMutexRegistered)
        {
            sMsgMutex = new XMLMutex;
            msgMutexCleanup.registerCleanup(XMLException::reinitMsgMutex);
            sScannerMutexRegistered = true;
        }
    }

    return *sMsgMutex;
}

//
//  This method is a lazy evaluator for the message loader for exception
//  messages.
//
static XMLMsgLoader& gGetMsgLoader()
{
    if (!sMsgLoader)
    {
        // Lock the message loader mutex and load the text
	    XMLMutexLock lockInit(&gMsgMutex());

        // Fault it in on first request
        if (!sMsgLoader)
        {
            sMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgExceptDomain);
            if (!sMsgLoader)
                XMLPlatformUtils::panic(PanicHandler::Panic_CantLoadMsgDomain);

            //
            // Register this XMLMsgLoader for cleanup at Termination.
            //
            msgLoaderCleanup.registerCleanup(XMLException::reinitMsgLoader);
        }
    }

    // We got it, so return it
    return *sMsgLoader;
}

// ---------------------------------------------------------------------------
//  XMLException: Virtual destructor
// ---------------------------------------------------------------------------
XMLException::~XMLException()
{
    fMemoryManager->deallocate(fMsg);
    fMemoryManager->deallocate(fSrcFile);
}

// ---------------------------------------------------------------------------
//  XMLException: Setter methods
// ---------------------------------------------------------------------------
void XMLException::setPosition(const char* const file, const unsigned int line)
{
    fSrcLine = line;
	fMemoryManager->deallocate(fSrcFile);
    fSrcFile = XMLString::replicate(file, fMemoryManager);
}

// ---------------------------------------------------------------------------
//  XMLException: Hidden constructors and operators
// ---------------------------------------------------------------------------
XMLException::XMLException() :

    fCode(XMLExcepts::NoError)
    , fSrcFile(0)
    , fSrcLine(0)
    , fMsg(0)
    , fMemoryManager(XMLPlatformUtils::fgMemoryManager)
{
}

XMLException::XMLException( const   char* const     srcFile
                            , const unsigned int    srcLine
                            , MemoryManager* const  memoryManager) :

    fCode(XMLExcepts::NoError)
    , fSrcFile(0)
    , fSrcLine(srcLine)
    , fMsg(0)
    , fMemoryManager(memoryManager)
{
    if (!memoryManager)
        fMemoryManager = XMLPlatformUtils::fgMemoryManager;
    fSrcFile = XMLString::replicate(srcFile, fMemoryManager);
}

XMLException::XMLException(const XMLException& toCopy) :

    fCode(toCopy.fCode)
    , fSrcFile(0)
    , fSrcLine(toCopy.fSrcLine)
    , fMsg(XMLString::replicate(toCopy.fMsg, toCopy.fMemoryManager))
    , fMemoryManager(toCopy.fMemoryManager)
{
    if (toCopy.fSrcFile) {
        fSrcFile = XMLString::replicate
        (
            toCopy.fSrcFile
            , fMemoryManager
        );
    }
}

XMLException& XMLException::operator=(const XMLException& toAssign)
{
    if (this != &toAssign)
    {
        //use the original memory manager to deallocate
        fMemoryManager->deallocate(fSrcFile);
        fSrcFile = 0;
        fMemoryManager->deallocate(fMsg);
        fMsg = 0;

        fMemoryManager = toAssign.fMemoryManager;
        fSrcLine = toAssign.fSrcLine;
        fCode = toAssign.fCode;

        if (toAssign.fMsg) {
            fMsg = XMLString::replicate
            (
                toAssign.fMsg
                , fMemoryManager
            );
        }

        if (toAssign.fSrcFile) {
            fSrcFile = XMLString::replicate
            (
                toAssign.fSrcFile
                , fMemoryManager
            );
        }
    }
    return *this;
}

// ---------------------------------------------------------------------------
//  XMLException: Protected methods
// ---------------------------------------------------------------------------
void XMLException::loadExceptText(const XMLExcepts::Codes toLoad)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 2047;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

void
XMLException::loadExceptText(const  XMLExcepts::Codes toLoad
                            , const XMLCh* const        text1
                            , const XMLCh* const        text2
                            , const XMLCh* const        text3
                            , const XMLCh* const        text4)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 4095;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize, text1, text2, text3, text4, fMemoryManager))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

void
XMLException::loadExceptText(const  XMLExcepts::Codes toLoad
                            , const char* const         text1
                            , const char* const         text2
                            , const char* const         text3
                            , const char* const         text4)
{
    // Store the error code
    fCode = toLoad;

    // Load up the text into a local buffer
    const unsigned int msgSize = 4095;
    XMLCh errText[msgSize + 1];

    // load the text
	if (!gGetMsgLoader().loadMsg(toLoad, errText, msgSize, text1, text2, text3, text4, fMemoryManager))
	{
		fMsg = XMLString::replicate
        (
        XMLUni::fgDefErrMsg
            , fMemoryManager
        );
		return;
	}

    // We got the text so replicate it into the message member
    fMsg = XMLString::replicate(errText, fMemoryManager);
}

// -----------------------------------------------------------------------
//  Reinitialise the message mutex
// -----------------------------------------------------------------------
void XMLException::reinitMsgMutex()
{
    delete sMsgMutex;
    sMsgMutex = 0;
    sScannerMutexRegistered = false;
}

// -----------------------------------------------------------------------
//  Reinitialise the message loader
// -----------------------------------------------------------------------
void XMLException::reinitMsgLoader()
{
    delete sMsgLoader;
    sMsgLoader = 0;
}

XERCES_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: tagtest.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-12-10 17:16:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif

typedef USHORT TokenId;

struct TokenInfo
{
    ByteString aName;
    TokenId nId;

    TokenInfo():nId( 0 ){;}
explicit    TokenInfo( TokenId pnId ):nId( pnId ){;}
explicit    TokenInfo( TokenId pnId, ByteString paStr ):nId( pnId ), aName( paStr ){;}
    BOOL operator == ( const TokenInfo& rInfo ) const
    { return nId == rInfo.nId  && aName.Equals( rInfo.aName ); }
};

#define TAG_GROUPMASK               0xF000
#define TAG_GROUPSHIFT              12

#define TAG_GROUP( nTag )           (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
#define TAG_NOGROUP( nTag )         ( nTag & ~TAG_GROUPMASK )   // ~ = Bitweises NOT

#define TAG_NOMORETAGS              0x0

#define TAG_GROUP_FORMAT            0x1
#define TAG_ON                      0x100
#define TAG_BOLDON                  ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
#define TAG_BOLDOFF                 ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x001 )
#define TAG_ITALICON                ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
#define TAG_ITALICOFF               ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x002 )
#define TAG_UNDERLINEON             ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
#define TAG_UNDERLINEOFF            ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x004 )

#define TAG_GROUP_NOTALLOWED        0x2
#define TAG_HELPID                  ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
#define TAG_MODIFY                  ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
#define TAG_REFNR                   ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )

#define TAG_GROUP_STRUCTURE         0x3
#define TAG_NAME                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
#define TAG_HREF                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
#define TAG_AVIS                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
#define TAG_AHID                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )

#define TAG_TITEL                   ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
#define TAG_KEY                     ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
#define TAG_INDEX                   ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )

#define TAG_REFSTART                ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )

#define TAG_GRAPHIC                 ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
#define TAG_NEXTVERSION             ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )

#define TAG_GROUP_SYSSWITCH         0x4
#define TAG_WIN                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
#define TAG_UNIX                    ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
#define TAG_MAC                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
#define TAG_OS2                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )

#define TAG_GROUP_PROGSWITCH        0x5
#define TAG_WRITER                  ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
#define TAG_CALC                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
#define TAG_DRAW                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
#define TAG_IMPRESS                 ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
#define TAG_SCHEDULE                ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
#define TAG_IMAGE                   ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
#define TAG_MATH                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
#define TAG_CHART                   ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
#define TAG_OFFICE                  ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_META              0x6
#define TAG_OFFICEFULLNAME          ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
#define TAG_OFFICENAME              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
#define TAG_OFFICEPATH              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
#define TAG_OFFICEVERSION           ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
#define TAG_PORTALNAME              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
#define TAG_PORTALFULLNAME          ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
#define TAG_PORTALPATH              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
#define TAG_PORTALVERSION           ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
#define TAG_PORTALSHORTNAME         ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_SINGLE            0x7
#define TAG_REFINSERT               ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )

#define TAG_GROUP_MULTI             0x8
#define TAG_END                     ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
#define TAG_ELSE                    ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
#define TAG_AEND                    ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
#define TAG_VERSIONEND              ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
#define TAG_ENDGRAPHIC              ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_MISC              0x9
#define TAG_COMMONSTART             ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
#define TAG_COMMONEND               ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )

#define TAG_UNKNOWN_TAG             ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )

DECLARE_LIST( TokenListImpl, TokenInfo* );

class TokenList : private TokenListImpl
{
private:

    TokenList&   operator =( const TokenList& rList )
                { TokenListImpl::operator =( rList ); return *this; }

public:
    TokenListImpl::Count;

    TokenList() : TokenListImpl(){};

    void        Clear()
        {
            for ( ULONG i = 0 ; i < Count() ; i++ )
                delete TokenListImpl::GetObject( i );
            TokenListImpl::Clear();
        }
    void        Insert( TokenInfo p, ULONG nIndex )
        { TokenListImpl::Insert( new TokenInfo(p), nIndex ); }
    TokenInfo       Remove( ULONG nIndex )
        {
            TokenInfo aT = GetObject( nIndex );
            delete TokenListImpl::GetObject( nIndex );
            TokenListImpl::Remove( nIndex );
            return aT;
        }
    TokenInfo       Remove( TokenInfo p ){ return Remove( GetPos( p ) ); }
//    TokenInfo     GetCurObject() const { return *TokenListImpl::GetCurObject(); }
    TokenInfo       GetObject( ULONG nIndex ) const
        {
            if ( TokenListImpl::GetObject(nIndex) )
                return *TokenListImpl::GetObject(nIndex);
            else
                return TokenInfo();
        }
    ULONG       GetPos( const TokenInfo p ) const
        {
            for ( ULONG i = 0 ; i < Count() ; i++ )
                if ( p == GetObject( i ) )
                    return i;
            return LIST_ENTRY_NOTFOUND;
        }

    TokenList( const TokenList& rList )
        {
            for ( ULONG i = 0 ; i < rList.Count() ; i++ )
            {
                Insert( rList.GetObject( i ), LIST_APPEND );
            }
        }
};

class ParserMessage
{
    USHORT nErrorNr;
    ByteString aErrorText;
    USHORT nTagBegin,nTagLength;
public:
    ParserMessage( USHORT PnErrorNr, const ByteString &PaErrorText, USHORT PnTagBegin = STRING_NOTFOUND, USHORT PnTagLength = 0)
        : nErrorNr( PnErrorNr )
        , aErrorText( PaErrorText )
        , nTagBegin( PnTagBegin )
        , nTagLength( PnTagLength )
    {}

    USHORT GetErrorNr() { return nErrorNr; }
    ByteString GetErrorText() { return aErrorText; }

    USHORT GetTagBegin() { return nTagBegin; }
    USHORT GetTagLength() { return nTagLength; }
};

DECLARE_LIST( ParserMessageList, ParserMessage* );

class SimpleParser
{
private:
    USHORT nPos;
    ByteString aSource;
    ByteString aLastToken;
//  static ByteString aLastUnknownToken;
    TokenList aTokenList;

    TokenInfo aNextTag;     // to store closetag in case of combined tags like <br/>

    ByteString GetNextTokenString( ParserMessageList &rErrorList );

public:
    SimpleParser();
    void Parse( ByteString PaSource );
    TokenInfo GetNextToken( ParserMessageList &rErrorList );
    ByteString GetTokenText();
    static ByteString GetLexem( TokenInfo const &aToken );
    USHORT GetScanningPosition(){ return nPos; }
    TokenList GetTokenList(){ return aTokenList; }
};

class TokenParser
{
    BOOL match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken );
    BOOL match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken );
    void ParseError( USHORT nErrNr, const ByteString &aErrMsg );
    void Paragraph();
    void PfCase();
    void PfCaseBegin();
    void AppCase();
    void AppCaseBegin();
    void CaseEnd();
    void SimpleTag();
    void TagPair();
    void TagRef();
    void Error( const ByteString &aMsg );

    SimpleParser aParser;
    TokenInfo aTag;

    TokenId nPfCaseOptions;
    TokenId nAppCaseOptions;
    BOOL bPfCaseActive ,bAppCaseActive;

    TokenId nActiveRefTypes;

    ParserMessageList aErrorList;

public:
    TokenParser();
    void Parse( const ByteString &aCode );
    ParserMessageList& GetErrors(){ return aErrorList; }
    BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); }
    TokenList GetTokenList(){ return aParser.GetTokenList(); }
};

class LingTest
{
private:
    TokenParser aReferenceParser;
    TokenParser aTesteeParser;
    ParserMessageList aCompareWarningList;
    void CheckMandatoryTag( TokenList aReference, TokenList aTestee, ParserMessageList &rErrorList, TokenInfo aToken );
    void CheckTags( TokenList aReference, TokenList aTestee, ParserMessageList &rErrorList );
    BOOL IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens );
public:
    BOOL ReferenceOK( const ByteString &aReference );
    BOOL TesteeOK( const ByteString &aTestee, BOOL bHasSourceLine );

    ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); }
    BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); }

    ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); }
    BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); }

    ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; }
    BOOL HasCompareWarnings(){ return ( aCompareWarningList.Count() > 0 ); }
};

<commit_msg>INTEGRATION: CWS gh10 (1.6.2); FILE MERGED 2005/03/22 16:06:07 gh 1.6.2.3: improve tagchecking and replace -i option 2005/02/23 14:39:00 gh 1.6.2.2: implement new switches for different modes of gsicheck 2005/01/31 16:03:33 gh 1.6.2.1: add column information to errormessages<commit_after>/*************************************************************************
 *
 *  $RCSfile: tagtest.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-23 15:52:57 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif

typedef USHORT TokenId;

#define TOK_INVALIDPOS  USHORT( 0xFFFF )

class ParserMessage;

DECLARE_LIST( ParserMessageList, ParserMessage* );

class TokenInfo
{
private:
    void SplitTag( ParserMessageList &rErrorList );

    String aTagName;

public:

    String aTokenString;
    TokenId nId;
    USHORT nPos;            // Position in String

    String aName;

    TokenInfo():nId( 0 ){;}
explicit    TokenInfo( TokenId pnId, USHORT nP ):nId( pnId ),nPos(nP){;}
explicit    TokenInfo( TokenId pnId, USHORT nP, String paStr ):nId( pnId ), nPos(nP), aTokenString( paStr ){;}
explicit    TokenInfo( TokenId pnId, USHORT nP, String paStr, ParserMessageList &rErrorList );

    String GetTagName() const;

    BOOL operator == ( const TokenInfo& rInfo ) const
    { return nId == rInfo.nId  && aTokenString.Equals( rInfo.aTokenString ); }
};

#define TAG_GROUPMASK               0xF000
#define TAG_GROUPSHIFT              12

#define TAG_GROUP( nTag )           (( nTag & TAG_GROUPMASK ) >> TAG_GROUPSHIFT )
#define TAG_NOGROUP( nTag )         ( nTag & ~TAG_GROUPMASK )   // ~ = Bitweises NOT

#define TAG_NOMORETAGS              0x0

#define TAG_GROUP_FORMAT            0x1
#define TAG_ON                      0x100
#define TAG_BOLDON                  ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x001 )
#define TAG_BOLDOFF                 ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x001 )
#define TAG_ITALICON                ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x002 )
#define TAG_ITALICOFF               ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x002 )
#define TAG_UNDERLINEON             ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT | TAG_ON | 0x004 )
#define TAG_UNDERLINEOFF            ( TAG_GROUP_FORMAT << TAG_GROUPSHIFT |          0x004 )

#define TAG_GROUP_NOTALLOWED        0x2
#define TAG_HELPID                  ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x001 )
#define TAG_MODIFY                  ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x002 )
#define TAG_REFNR                   ( TAG_GROUP_NOTALLOWED << TAG_GROUPSHIFT | 0x004 )

#define TAG_GROUP_STRUCTURE         0x3
#define TAG_NAME                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x001 )
#define TAG_HREF                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x002 )
#define TAG_AVIS                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x004 )
#define TAG_AHID                    ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x008 )

#define TAG_TITEL                   ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x020 )
#define TAG_KEY                     ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x040 )
#define TAG_INDEX                   ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x080 )

#define TAG_REFSTART                ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x100 )

#define TAG_GRAPHIC                 ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x200 )
#define TAG_NEXTVERSION             ( TAG_GROUP_STRUCTURE << TAG_GROUPSHIFT | 0x400 )

#define TAG_GROUP_SYSSWITCH         0x4
#define TAG_WIN                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x001 )
#define TAG_UNIX                    ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x002 )
#define TAG_MAC                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x004 )
#define TAG_OS2                     ( TAG_GROUP_SYSSWITCH << TAG_GROUPSHIFT | 0x008 )

#define TAG_GROUP_PROGSWITCH        0x5
#define TAG_WRITER                  ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x001 )
#define TAG_CALC                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x002 )
#define TAG_DRAW                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x004 )
#define TAG_IMPRESS                 ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x008 )
#define TAG_SCHEDULE                ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x010 )
#define TAG_IMAGE                   ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x020 )
#define TAG_MATH                    ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x040 )
#define TAG_CHART                   ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x080 )
#define TAG_OFFICE                  ( TAG_GROUP_PROGSWITCH << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_META              0x6
#define TAG_OFFICEFULLNAME          ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x001 )
#define TAG_OFFICENAME              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x002 )
#define TAG_OFFICEPATH              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x004 )
#define TAG_OFFICEVERSION           ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x008 )
#define TAG_PORTALNAME              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x010 )
#define TAG_PORTALFULLNAME          ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x020 )
#define TAG_PORTALPATH              ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x040 )
#define TAG_PORTALVERSION           ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x080 )
#define TAG_PORTALSHORTNAME         ( TAG_GROUP_META << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_SINGLE            0x7
#define TAG_REFINSERT               ( TAG_GROUP_SINGLE << TAG_GROUPSHIFT | 0x001 )

#define TAG_GROUP_MULTI             0x8
#define TAG_END                     ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x010 )
#define TAG_ELSE                    ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x020 )
#define TAG_AEND                    ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x040 )
#define TAG_VERSIONEND              ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x080 )
#define TAG_ENDGRAPHIC              ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x100 )

#define TAG_GROUP_MISC              0x9
#define TAG_COMMONSTART             ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x001 )
#define TAG_COMMONEND               ( TAG_GROUP_MISC << TAG_GROUPSHIFT | 0x002 )

#define TAG_UNKNOWN_TAG             ( TAG_GROUP_MULTI << TAG_GROUPSHIFT | 0x800 )

DECLARE_LIST( TokenListImpl, TokenInfo* );

class TokenList : private TokenListImpl
{
private:

    TokenList&   operator =( const TokenList& rList )
                { TokenListImpl::operator =( rList ); return *this; }

public:
    TokenListImpl::Count;

    TokenList() : TokenListImpl(){};

    void        Clear()
        {
            for ( ULONG i = 0 ; i < Count() ; i++ )
                delete TokenListImpl::GetObject( i );
            TokenListImpl::Clear();
        }
    void        Insert( TokenInfo p, ULONG nIndex )
        { TokenListImpl::Insert( new TokenInfo(p), nIndex ); }
    TokenInfo       Remove( ULONG nIndex )
        {
            TokenInfo aT = GetObject( nIndex );
            delete TokenListImpl::GetObject( nIndex );
            TokenListImpl::Remove( nIndex );
            return aT;
        }
    TokenInfo       Remove( TokenInfo p ){ return Remove( GetPos( p ) ); }
//    TokenInfo     GetCurObject() const { return *TokenListImpl::GetCurObject(); }
    TokenInfo       GetObject( ULONG nIndex ) const
        {
            if ( TokenListImpl::GetObject(nIndex) )
                return *TokenListImpl::GetObject(nIndex);
            else
                return TokenInfo();
        }
    ULONG       GetPos( const TokenInfo p ) const
        {
            for ( ULONG i = 0 ; i < Count() ; i++ )
                if ( p == GetObject( i ) )
                    return i;
            return LIST_ENTRY_NOTFOUND;
        }

    TokenList( const TokenList& rList )
        {
            for ( ULONG i = 0 ; i < rList.Count() ; i++ )
            {
                Insert( rList.GetObject( i ), LIST_APPEND );
            }
        }
};

class ParserMessage
{
    USHORT nErrorNr;
    ByteString aErrorText;
    USHORT nTagBegin,nTagLength;
public:
    ParserMessage( USHORT PnErrorNr, ByteString PaErrorText, const TokenInfo &rTag );

    USHORT GetErrorNr() { return nErrorNr; }
    ByteString GetErrorText() { return aErrorText; }

    USHORT GetTagBegin() { return nTagBegin; }
    USHORT GetTagLength() { return nTagLength; }
};

class SimpleParser
{
private:
    USHORT nPos;
    String aSource;
    String aLastToken;
    TokenList aTokenList;

    TokenInfo aNextTag;     // to store closetag in case of combined tags like <br/>

    String GetNextTokenString( ParserMessageList &rErrorList, USHORT &rTokeStartPos );

public:
    SimpleParser();
    void Parse( String PaSource );
    TokenInfo GetNextToken( ParserMessageList &rErrorList );
    static String GetLexem( TokenInfo const &aToken );
    TokenList GetTokenList(){ return aTokenList; }
};

class TokenParser
{
    BOOL match( const TokenInfo &aCurrentToken, const TokenId &aExpectedToken );
    BOOL match( const TokenInfo &aCurrentToken, const TokenInfo &aExpectedToken );
    void ParseError( USHORT nErrNr, ByteString aErrMsg, const TokenInfo &rTag );
    void Paragraph();
    void PfCase();
    void PfCaseBegin();
    void AppCase();
    void AppCaseBegin();
    void CaseEnd();
    void SimpleTag();
    void TagPair();
    void TagRef();

    SimpleParser aParser;
    TokenInfo aTag;

    TokenId nPfCaseOptions;
    TokenId nAppCaseOptions;
    BOOL bPfCaseActive ,bAppCaseActive;

    TokenId nActiveRefTypes;

    ParserMessageList aErrorList;

public:
    TokenParser();
    void Parse( const String &aCode );
    ParserMessageList& GetErrors(){ return aErrorList; }
    BOOL HasErrors(){ return ( aErrorList.Count() > 0 ); }
    TokenList GetTokenList(){ return aParser.GetTokenList(); }
};

class LingTest
{
private:
    TokenParser aReferenceParser;
    TokenParser aTesteeParser;
    ParserMessageList aCompareWarningList;
    void CheckTags( TokenList aReference, TokenList aTestee, ParserMessageList &rErrorList );
    BOOL IsTagMandatory( TokenInfo const &aToken, TokenId &aMetaTokens );
public:
    BOOL ReferenceOK( const String &aReference );
    BOOL TesteeOK( const String &aTestee, BOOL bHasSourceLine );

    ParserMessageList& GetReferenceErrors(){ return aReferenceParser.GetErrors(); }
    BOOL HasReferenceErrors(){ return aReferenceParser.HasErrors(); }

    ParserMessageList& GetTesteeErrors(){ return aTesteeParser.GetErrors(); }
    BOOL HasTesteeErrors(){ return aTesteeParser.HasErrors(); }

    ParserMessageList& GetCompareWarnings(){ return aCompareWarningList; }
    BOOL HasCompareWarnings(){ return ( aCompareWarningList.Count() > 0 ); }
};

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuconcustomshape.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-10-12 17:58:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FUCONCUSTOMSHAPE_HXX
#define SC_FUCONCUSTOMSHAPE_HXX

#ifndef SC_FUCONSTR_HXX
#include "fuconstr.hxx"
#endif

class FuConstCustomShape : public FuConstruct
{
    rtl::OUString aCustomShape;

    void SetAttributes( SdrObject* pObj );

public:
    FuConstCustomShape(ScTabViewShell* pViewSh, Window* pWin, SdrView* pView,
                       SdrModel* pDoc, SfxRequest& rReq);

    virtual ~FuConstCustomShape();
                                       // Mouse- & Key-Events
    virtual BOOL KeyInput(const KeyEvent& rKEvt);
    virtual BOOL MouseMove(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    // #98185# Create default drawing objects via keyboard
    virtual SdrObject* CreateDefaultObject( const sal_uInt16 nID, const Rectangle& rRectangle );
};

#endif

<commit_msg>INTEGRATION: CWS aw020 (1.2.18); FILE MERGED 2004/10/26 13:11:54 aw 1.2.18.1: #i33136#<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuconcustomshape.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-17 09:28:34 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FUCONCUSTOMSHAPE_HXX
#define SC_FUCONCUSTOMSHAPE_HXX

#ifndef SC_FUCONSTR_HXX
#include "fuconstr.hxx"
#endif

class FuConstCustomShape : public FuConstruct
{
    rtl::OUString aCustomShape;

    void SetAttributes( SdrObject* pObj );

public:
    FuConstCustomShape(ScTabViewShell* pViewSh, Window* pWin, SdrView* pView,
                       SdrModel* pDoc, SfxRequest& rReq);

    virtual ~FuConstCustomShape();
                                       // Mouse- & Key-Events
    virtual BOOL KeyInput(const KeyEvent& rKEvt);
    virtual BOOL MouseMove(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL MouseButtonDown(const MouseEvent& rMEvt);

    virtual void Activate();           // Function aktivieren
    virtual void Deactivate();         // Function deaktivieren

    // #98185# Create default drawing objects via keyboard
    virtual SdrObject* CreateDefaultObject( const sal_uInt16 nID, const Rectangle& rRectangle );

    // #i33136#
    virtual bool doConstructOrthogonal() const;
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sharedocdlg.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

//-----------------------------------------------------------------------------

#include <osl/security.hxx>
#include <svtools/sharecontrolfile.hxx>
#include <svtools/useroptions.hxx>

#include <docsh.hxx>

#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>

#include "sharedocdlg.hxx"
#include "sharedocdlg.hrc"
#include "scresid.hxx"
#include "docsh.hxx"
#include "viewdata.hxx"

using namespace ::com::sun::star;

//=============================================================================
// class ScShareDocumentDlg
//=============================================================================

ScShareDocumentDlg::ScShareDocumentDlg( Window* pParent, ScViewData* pViewData )
    :ModalDialog( pParent, ScResId( RID_SCDLG_SHAREDOCUMENT ) )
    ,maCbShare            ( this, ScResId( CB_SHARE ) )
    ,maFtWarning          ( this, ScResId( FT_WARNING ) )
    ,maFlUsers            ( this, ScResId( FL_USERS ) )
    ,maFtUsers            ( this, ScResId( FT_USERS ) )
    ,maLbUsers            ( this, ScResId( LB_USERS ) )
    ,maFlEnd              ( this, ScResId( FL_END ) )
    ,maBtnHelp            ( this, ScResId( BTN_HELP ) )
    ,maBtnOK              ( this, ScResId( BTN_OK ) )
    ,maBtnCancel          ( this, ScResId( BTN_CANCEL ) )
    ,maStrTitleName       ( ScResId( STR_TITLE_NAME ) )
    ,maStrTitleAccessed   ( ScResId( STR_TITLE_ACCESSED ) )
    ,maStrNoUserData      ( ScResId( STR_NO_USER_DATA ) )
    ,maStrUnkownUser      ( ScResId( STR_UNKNOWN_USER ) )
    ,maStrExclusiveAccess ( ScResId( STR_EXCLUSIVE_ACCESS ) )
    ,mpViewData           ( pViewData )
    ,mpDocShell           ( NULL )
{
    DBG_ASSERT( mpViewData, "ScShareDocumentDlg CTOR: mpViewData is null!" );
    mpDocShell = ( mpViewData ? mpViewData->GetDocShell() : NULL );
    DBG_ASSERT( mpDocShell, "ScShareDocumentDlg CTOR: mpDocShell is null!" );

    FreeResource();

    bool bIsDocShared = ( mpDocShell ? mpDocShell->IsDocShared() : false );
    maCbShare.Check( bIsDocShared );
    maCbShare.SetToggleHdl( LINK( this, ScShareDocumentDlg, ToggleHandle ) );
    maFtWarning.Enable( bIsDocShared );

    long nTabs[] = { 2, 10, 122 };
    maLbUsers.SetTabs( nTabs );

    String aHeader( maStrTitleName );
    aHeader += '\t';
    aHeader += maStrTitleAccessed;
    maLbUsers.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER );
    maLbUsers.SetSelectionMode( NO_SELECTION );

    UpdateView();
}

ScShareDocumentDlg::~ScShareDocumentDlg()
{
}

IMPL_LINK( ScShareDocumentDlg, ToggleHandle, void*, EMPTYARG )
{
    maFtWarning.Enable( maCbShare.IsChecked() );

    return 0;
}

bool ScShareDocumentDlg::IsShareDocumentChecked() const
{
    return maCbShare.IsChecked();
}

void ScShareDocumentDlg::UpdateView()
{
    if ( !mpDocShell )
    {
        return;
    }

    if ( mpDocShell->IsDocShared() )
    {
        try
        {
            ::svt::ShareControlFile aControlFile( mpDocShell->GetSharedFileUrl() );
            uno::Sequence< uno::Sequence< ::rtl::OUString > > aUsersData = aControlFile.GetUsersData();
            const uno::Sequence< ::rtl::OUString >* pUsersData = aUsersData.getConstArray();
            sal_Int32 nLength = aUsersData.getLength();

            if ( nLength > 0 )
            {
                sal_Int32 nUnknownUser = 1;

                for ( sal_Int32 i = 0; i < nLength; ++i )
                {
                    if ( pUsersData[i].getLength() != SHARED_ENTRYSIZE )
                    {
                        continue;
                    }

                    String aUser = pUsersData[i][SHARED_OOOUSERNAME_ID];
                    aUser.EraseLeadingAndTrailingChars();
                    if ( aUser.Len() == 0 )
                    {
                        aUser = pUsersData[i][SHARED_SYSUSERNAME_ID];
                        aUser.EraseLeadingAndTrailingChars();
                    }
                    if ( aUser.Len() == 0 )
                    {
                        aUser = maStrUnkownUser;
                        aUser += ' ';
                        aUser += String::CreateFromInt32( nUnknownUser++ );
                    }

                    String aDateTime = pUsersData[i][SHARED_EDITTIME_ID];

                    String aString( aUser );
                    aString += '\t';
                    aString += aDateTime;
                    maLbUsers.InsertEntry( aString, NULL );
                }
            }
            else
            {
                maLbUsers.InsertEntry( maStrNoUserData, NULL );
            }
        }
        catch ( uno::Exception& )
        {
            DBG_ERROR( "ScShareDocumentDlg::UpdateView(): caught exception\n" );
            maLbUsers.Clear();
            maLbUsers.InsertEntry( maStrNoUserData, NULL );
        }
    }
    else
    {
        // get OOO user name
        SvtUserOptions aUserOpt;
        String aUser = aUserOpt.GetFirstName();
        aUser += ' ';
        aUser += aUserOpt.GetLastName();
        aUser.EraseLeadingAndTrailingChars();
        if ( aUser.Len() == 0 )
        {
            // get sys user name
            ::rtl::OUString aUserName;
            ::osl::Security aSecurity;
            aSecurity.getUserName( aUserName );
            aUser = aUserName;
            aUser.EraseLeadingAndTrailingChars();
        }
        if ( aUser.Len() == 0 )
        {
            // unknown user name
            aUser = maStrUnkownUser;
        }
        aUser += ' ';
        aUser += maStrExclusiveAccess;
        String aString( aUser );
        aString += '\t';

        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
        uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();

        util::DateTime uDT(xDocProps->getModificationDate());
        Date d(uDT.Day, uDT.Month, uDT.Year);
        Time t(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
        DateTime aDateTime(d,t);

        aString += ScGlobal::pLocaleData->getDate( aDateTime );
        aString += ' ';
        aString += ScGlobal::pLocaleData->getTime( aDateTime, FALSE );

        maLbUsers.InsertEntry( aString, NULL );
    }
}
<commit_msg>INTEGRATION: CWS calcshare2 (1.3.8); FILE MERGED 2008/03/25 15:59:25 tbe 1.3.8.2: #i86681# [Collaboration] 'Locked due to a merge' message box shows 'unknown user' instead of username 2008/03/14 20:13:37 mav 1.3.8.1: #i85794# new file locking prototype<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sharedocdlg.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

//-----------------------------------------------------------------------------

#include <osl/security.hxx>
#include <svtools/sharecontrolfile.hxx>
#include <svtools/useroptions.hxx>

#include <docsh.hxx>

#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>

#include "sharedocdlg.hxx"
#include "sharedocdlg.hrc"
#include "scresid.hxx"
#include "docsh.hxx"
#include "viewdata.hxx"

using namespace ::com::sun::star;

//=============================================================================
// class ScShareDocumentDlg
//=============================================================================

ScShareDocumentDlg::ScShareDocumentDlg( Window* pParent, ScViewData* pViewData )
    :ModalDialog( pParent, ScResId( RID_SCDLG_SHAREDOCUMENT ) )
    ,maCbShare            ( this, ScResId( CB_SHARE ) )
    ,maFtWarning          ( this, ScResId( FT_WARNING ) )
    ,maFlUsers            ( this, ScResId( FL_USERS ) )
    ,maFtUsers            ( this, ScResId( FT_USERS ) )
    ,maLbUsers            ( this, ScResId( LB_USERS ) )
    ,maFlEnd              ( this, ScResId( FL_END ) )
    ,maBtnHelp            ( this, ScResId( BTN_HELP ) )
    ,maBtnOK              ( this, ScResId( BTN_OK ) )
    ,maBtnCancel          ( this, ScResId( BTN_CANCEL ) )
    ,maStrTitleName       ( ScResId( STR_TITLE_NAME ) )
    ,maStrTitleAccessed   ( ScResId( STR_TITLE_ACCESSED ) )
    ,maStrNoUserData      ( ScResId( STR_NO_USER_DATA ) )
    ,maStrUnkownUser      ( ScResId( STR_UNKNOWN_USER ) )
    ,maStrExclusiveAccess ( ScResId( STR_EXCLUSIVE_ACCESS ) )
    ,mpViewData           ( pViewData )
    ,mpDocShell           ( NULL )
{
    DBG_ASSERT( mpViewData, "ScShareDocumentDlg CTOR: mpViewData is null!" );
    mpDocShell = ( mpViewData ? mpViewData->GetDocShell() : NULL );
    DBG_ASSERT( mpDocShell, "ScShareDocumentDlg CTOR: mpDocShell is null!" );

    FreeResource();

    bool bIsDocShared = ( mpDocShell ? mpDocShell->IsDocShared() : false );
    maCbShare.Check( bIsDocShared );
    maCbShare.SetToggleHdl( LINK( this, ScShareDocumentDlg, ToggleHandle ) );
    maFtWarning.Enable( bIsDocShared );

    long nTabs[] = { 2, 10, 122 };
    maLbUsers.SetTabs( nTabs );

    String aHeader( maStrTitleName );
    aHeader += '\t';
    aHeader += maStrTitleAccessed;
    maLbUsers.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER );
    maLbUsers.SetSelectionMode( NO_SELECTION );

    UpdateView();
}

ScShareDocumentDlg::~ScShareDocumentDlg()
{
}

IMPL_LINK( ScShareDocumentDlg, ToggleHandle, void*, EMPTYARG )
{
    maFtWarning.Enable( maCbShare.IsChecked() );

    return 0;
}

bool ScShareDocumentDlg::IsShareDocumentChecked() const
{
    return maCbShare.IsChecked();
}

void ScShareDocumentDlg::UpdateView()
{
    if ( !mpDocShell )
    {
        return;
    }

    if ( mpDocShell->IsDocShared() )
    {
        try
        {
            ::svt::ShareControlFile aControlFile( mpDocShell->GetSharedFileURL() );
            uno::Sequence< uno::Sequence< ::rtl::OUString > > aUsersData = aControlFile.GetUsersData();
            const uno::Sequence< ::rtl::OUString >* pUsersData = aUsersData.getConstArray();
            sal_Int32 nLength = aUsersData.getLength();

            if ( nLength > 0 )
            {
                sal_Int32 nUnknownUser = 1;

                for ( sal_Int32 i = 0; i < nLength; ++i )
                {
                    if ( pUsersData[i].getLength() > SHARED_EDITTIME_ID )
                    {
                        String aUser;
                        if ( pUsersData[i][SHARED_OOOUSERNAME_ID].getLength() )
                        {
                            aUser = pUsersData[i][SHARED_OOOUSERNAME_ID];
                        }
                        else if ( pUsersData[i][SHARED_SYSUSERNAME_ID].getLength() )
                        {
                            aUser = pUsersData[i][SHARED_SYSUSERNAME_ID];
                        }
                        else
                        {
                            aUser = maStrUnkownUser;
                            aUser += ' ';
                            aUser += String::CreateFromInt32( nUnknownUser++ );
                        }

                        String aDateTime = pUsersData[i][SHARED_EDITTIME_ID];

                        String aString( aUser );
                        aString += '\t';
                        aString += aDateTime;
                        maLbUsers.InsertEntry( aString, NULL );
                    }
                }
            }
            else
            {
                maLbUsers.InsertEntry( maStrNoUserData, NULL );
            }
        }
        catch ( uno::Exception& )
        {
            DBG_ERROR( "ScShareDocumentDlg::UpdateView(): caught exception\n" );
            maLbUsers.Clear();
            maLbUsers.InsertEntry( maStrNoUserData, NULL );
        }
    }
    else
    {
        // get OOO user name
        SvtUserOptions aUserOpt;
        String aUser = aUserOpt.GetFirstName();
        if ( aUser.Len() > 0 )
        {
            aUser += ' ';
        }
        aUser += aUserOpt.GetLastName();
        if ( aUser.Len() == 0 )
        {
            // get sys user name
            ::rtl::OUString aUserName;
            ::osl::Security aSecurity;
            aSecurity.getUserName( aUserName );
            aUser = aUserName;
        }
        if ( aUser.Len() == 0 )
        {
            // unknown user name
            aUser = maStrUnkownUser;
        }
        aUser += ' ';
        aUser += maStrExclusiveAccess;
        String aString( aUser );
        aString += '\t';

        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(mpDocShell->GetModel(), uno::UNO_QUERY_THROW);
        uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();

        util::DateTime uDT(xDocProps->getModificationDate());
        Date d(uDT.Day, uDT.Month, uDT.Year);
        Time t(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
        DateTime aDateTime(d,t);

        aString += ScGlobal::pLocaleData->getDate( aDateTime );
        aString += ' ';
        aString += ScGlobal::pLocaleData->getTime( aDateTime, FALSE );

        maLbUsers.InsertEntry( aString, NULL );
    }
}
<|endoftext|>