<commit_before>//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*-
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These tablegen backends emit Clang diagnostics tables.
//
//===----------------------------------------------------------------------===//

#include "ClangDiagnosticsEmitter.h"
#include "Record.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Streams.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/ADT/DenseSet.h"
#include <set>
#include <map>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Generic routines for all Clang TableGen backens.
//===----------------------------------------------------------------------===//

typedef std::vector<Record*> RecordVector;
typedef std::vector<Record*> SuperClassVector;
typedef std::vector<RecordVal> RecordValVector;

static const RecordVal* findRecordVal(const Record& R, const std::string &key) {
  const RecordValVector &Vals = R.getValues();
  for (RecordValVector::const_iterator I=Vals.begin(), E=Vals.end(); I!=E; ++I)
    if ((*I).getName() == key)
      return &*I;

  return 0;
}

static const Record* getDiagKind(const Record* DiagClass, const Record &R) {
  const SuperClassVector &SC = R.getSuperClasses();
  for (SuperClassVector::const_iterator I=SC.begin(), E=SC.end(); I!=E; ++I)
    if ((*I)->isSubClassOf(DiagClass))
      return *I;

  return 0;
}

static void EmitEscaped(std::ostream& OS, const std::string &s) {
  for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I)
    switch (*I) {
      default: OS << *I; break;
      case '\"': OS << "\\" << *I; break;
      case '\\': OS << "\\\\"; break;
    }
}

static void EmitAllCaps(std::ostream& OS, const std::string &s) {
  for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I)
    OS << char(toupper(*I));
}

//===----------------------------------------------------------------------===//
// Warning Tables (.inc file) generation.
//===----------------------------------------------------------------------===//

static void ProcessDiag(std::ostream& OS, const Record* DiagClass,
                        const Record& R) {

  const Record* DiagKind = getDiagKind(DiagClass, R);
  if (!DiagKind)
    return;

  OS << "DIAG(" << R.getName() << ", ";
  EmitAllCaps(OS, DiagKind->getName());

  const RecordVal* Text = findRecordVal(R, "Text");
  assert(Text && "No 'Text' entry in Diagnostic.");
  const StringInit* TextVal = dynamic_cast<const StringInit*>(Text->getValue());
  assert(TextVal && "Value 'Text' must be a string.");
  OS << ", \"";
  EmitEscaped(OS, TextVal->getValue());
  OS << "\")\n";
}

void ClangDiagsDefsEmitter::run(std::ostream &OS) {
  const RecordVector &Diags = Records.getAllDerivedDefinitions("Diagnostic");

  const Record* DiagClass = Records.getClass("Diagnostic");
  assert(DiagClass && "No Diagnostic class defined.");

  // Write the #if guard
  if (!Component.empty()) {
    OS << "#ifdef ";
    EmitAllCaps(OS, Component);
    OS << "START\n__";
    EmitAllCaps(OS, Component);
    OS << "START = DIAG_START_";
    EmitAllCaps(OS, Component);
    OS << ",\n#undef ";
    EmitAllCaps(OS, Component);
    OS << "START\n#endif\n";
  }

  for (RecordVector::const_iterator I=Diags.begin(), E=Diags.end(); I!=E; ++I) {
    if (!Component.empty()) {
      const RecordVal* V = findRecordVal(**I, "Component");
      if (!V)
        continue;

      const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
      if (SV->getValue() != Component)
        continue;
    }

    ProcessDiag(OS, DiagClass, **I);
  }
}

//===----------------------------------------------------------------------===//
// Warning Group Tables generation.
//===----------------------------------------------------------------------===//

typedef std::set<const Record*> DiagnosticSet;
typedef std::map<const Record*, DiagnosticSet> OptionMap;
typedef llvm::DenseSet<const ListInit*> VisitedLists;

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, const Init* X);

static void BuildGroup(DiagnosticSet &DS, VisitedLists &Visited,
                       const ListInit* LV) {

  // Simple hack to prevent including a list multiple times.  This may be useful
  // if one declares an Option by including a bunch of other Options that
  // include other Options, etc.
  if (Visited.count(LV))
    return;

  Visited.insert(LV);

  // Iterate through the list and grab all DiagnosticControlled.
  for (ListInit::const_iterator I = LV->begin(), E = LV->end(); I!=E; ++I)
    BuildGroup(DS, Visited, *I);
}

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
                       const Record *Def) {

  // If an Option includes another Option, inline the Diagnostics of the
  // included Option.
  if (Def->isSubClassOf("Option")) {
    if (const RecordVal* V = findRecordVal(*Def, "Members"))
      if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue()))
        BuildGroup(DS, Visited, LV);

    return;
  }

  if (Def->isSubClassOf("DiagnosticControlled"))
    DS.insert(Def);
}

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
                       const Init* X) {

  if (const DefInit *D = dynamic_cast<const DefInit*>(X))
    BuildGroup(DS, Visited, D->getDef());

  // We may have some other cases here in the future.
}

void ClangOptionsEmitter::run(std::ostream &OS) {
  // Build up a map from options to controlled diagnostics.
  OptionMap OM;

  const RecordVector &Opts = Records.getAllDerivedDefinitions("Option");
  for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I!=E; ++I)
    if (const RecordVal* V = findRecordVal(**I, "Members"))
      if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue())) {
        VisitedLists Visited;
        BuildGroup(OM[*I], Visited, LV);
      }

  // Iterate through the OptionMap and emit the declarations.
  for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {
    // Output the option.
    OS << "static const diag::kind " << I->first->getName() << "[] = { ";

    DiagnosticSet &DS = I->second;
    bool first = true;
    for (DiagnosticSet::iterator I2 = DS.begin(), E2 = DS.end(); I2!=E2; ++I2) {
      if (first)
        first = false;
      else
        OS << ", ";

      OS << "diag::" << (*I2)->getName();
    }
    OS << " };\n";
  }

  // Now emit the OptionTable table.
  OS << "\nstatic const WarningOption OptionTable[] = {";
  bool first = true;
  for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {
    const RecordVal *V = findRecordVal(*I->first, "Name");
    assert(V && "Options must have a 'Name' value.");
    const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
    assert(SV && "'Name' entry must be a string.");

    if (first)
      first = false;
    else
      OS << ',';

    OS << "\n  {\"" << SV->getValue()
       << "\", DIAGS(" << I->first->getName() << ")}";
  }
  OS << "\n};\n";
}
<commit_msg>tblgen -gen-clang-diags-options: Output OptionTable entries in lexicographic order.<commit_after>//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*-
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These tablegen backends emit Clang diagnostics tables.
//
//===----------------------------------------------------------------------===//

#include "ClangDiagnosticsEmitter.h"
#include "Record.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Streams.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/ADT/DenseSet.h"
#include <set>
#include <map>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Generic routines for all Clang TableGen backens.
//===----------------------------------------------------------------------===//

typedef std::vector<Record*> RecordVector;
typedef std::vector<Record*> SuperClassVector;
typedef std::vector<RecordVal> RecordValVector;

static const RecordVal* findRecordVal(const Record& R, const std::string &key) {
  const RecordValVector &Vals = R.getValues();
  for (RecordValVector::const_iterator I=Vals.begin(), E=Vals.end(); I!=E; ++I)
    if ((*I).getName() == key)
      return &*I;

  return 0;
}

static const Record* getDiagKind(const Record* DiagClass, const Record &R) {
  const SuperClassVector &SC = R.getSuperClasses();
  for (SuperClassVector::const_iterator I=SC.begin(), E=SC.end(); I!=E; ++I)
    if ((*I)->isSubClassOf(DiagClass))
      return *I;

  return 0;
}

static void EmitEscaped(std::ostream& OS, const std::string &s) {
  for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I)
    switch (*I) {
      default: OS << *I; break;
      case '\"': OS << "\\" << *I; break;
      case '\\': OS << "\\\\"; break;
    }
}

static void EmitAllCaps(std::ostream& OS, const std::string &s) {
  for (std::string::const_iterator I=s.begin(), E=s.end(); I!=E; ++I)
    OS << char(toupper(*I));
}

//===----------------------------------------------------------------------===//
// Warning Tables (.inc file) generation.
//===----------------------------------------------------------------------===//

static void ProcessDiag(std::ostream& OS, const Record* DiagClass,
                        const Record& R) {

  const Record* DiagKind = getDiagKind(DiagClass, R);
  if (!DiagKind)
    return;

  OS << "DIAG(" << R.getName() << ", ";
  EmitAllCaps(OS, DiagKind->getName());

  const RecordVal* Text = findRecordVal(R, "Text");
  assert(Text && "No 'Text' entry in Diagnostic.");
  const StringInit* TextVal = dynamic_cast<const StringInit*>(Text->getValue());
  assert(TextVal && "Value 'Text' must be a string.");
  OS << ", \"";
  EmitEscaped(OS, TextVal->getValue());
  OS << "\")\n";
}

void ClangDiagsDefsEmitter::run(std::ostream &OS) {
  const RecordVector &Diags = Records.getAllDerivedDefinitions("Diagnostic");

  const Record* DiagClass = Records.getClass("Diagnostic");
  assert(DiagClass && "No Diagnostic class defined.");

  // Write the #if guard
  if (!Component.empty()) {
    OS << "#ifdef ";
    EmitAllCaps(OS, Component);
    OS << "START\n__";
    EmitAllCaps(OS, Component);
    OS << "START = DIAG_START_";
    EmitAllCaps(OS, Component);
    OS << ",\n#undef ";
    EmitAllCaps(OS, Component);
    OS << "START\n#endif\n";
  }

  for (RecordVector::const_iterator I=Diags.begin(), E=Diags.end(); I!=E; ++I) {
    if (!Component.empty()) {
      const RecordVal* V = findRecordVal(**I, "Component");
      if (!V)
        continue;

      const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
      if (SV->getValue() != Component)
        continue;
    }

    ProcessDiag(OS, DiagClass, **I);
  }
}

//===----------------------------------------------------------------------===//
// Warning Group Tables generation.
//===----------------------------------------------------------------------===//

static const std::string &getOptName(const Record *R) {
  const RecordVal *V = findRecordVal(*R, "Name");
  assert(V && "Options must have a 'Name' value.");
  const StringInit* SV = dynamic_cast<const StringInit*>(V->getValue());
  assert(SV && "'Name' entry must be a string.");
  return SV->getValue();
}

namespace {
struct VISIBILITY_HIDDEN CompareOptName {
  bool operator()(const Record* A, const Record* B) {
    return getOptName(A) < getOptName(B);
  }
};
}

typedef std::set<const Record*> DiagnosticSet;
typedef std::map<const Record*, DiagnosticSet, CompareOptName> OptionMap;
typedef llvm::DenseSet<const ListInit*> VisitedLists;

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited, const Init* X);

static void BuildGroup(DiagnosticSet &DS, VisitedLists &Visited,
                       const ListInit* LV) {

  // Simple hack to prevent including a list multiple times.  This may be useful
  // if one declares an Option by including a bunch of other Options that
  // include other Options, etc.
  if (Visited.count(LV))
    return;

  Visited.insert(LV);

  // Iterate through the list and grab all DiagnosticControlled.
  for (ListInit::const_iterator I = LV->begin(), E = LV->end(); I!=E; ++I)
    BuildGroup(DS, Visited, *I);
}

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
                       const Record *Def) {

  // If an Option includes another Option, inline the Diagnostics of the
  // included Option.
  if (Def->isSubClassOf("Option")) {
    if (const RecordVal* V = findRecordVal(*Def, "Members"))
      if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue()))
        BuildGroup(DS, Visited, LV);

    return;
  }

  if (Def->isSubClassOf("DiagnosticControlled"))
    DS.insert(Def);
}

static void BuildGroup(DiagnosticSet& DS, VisitedLists &Visited,
                       const Init* X) {

  if (const DefInit *D = dynamic_cast<const DefInit*>(X))
    BuildGroup(DS, Visited, D->getDef());

  // We may have some other cases here in the future.
}

void ClangOptionsEmitter::run(std::ostream &OS) {
  // Build up a map from options to controlled diagnostics.
  OptionMap OM;

  const RecordVector &Opts = Records.getAllDerivedDefinitions("Option");
  for (RecordVector::const_iterator I=Opts.begin(), E=Opts.end(); I!=E; ++I)
    if (const RecordVal* V = findRecordVal(**I, "Members"))
      if (const ListInit* LV = dynamic_cast<const ListInit*>(V->getValue())) {
        VisitedLists Visited;
        BuildGroup(OM[*I], Visited, LV);
      }

  // Iterate through the OptionMap and emit the declarations.
  for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {
    // Output the option.
    OS << "static const diag::kind " << I->first->getName() << "[] = { ";

    DiagnosticSet &DS = I->second;
    bool first = true;
    for (DiagnosticSet::iterator I2 = DS.begin(), E2 = DS.end(); I2!=E2; ++I2) {
      if (first)
        first = false;
      else
        OS << ", ";

      OS << "diag::" << (*I2)->getName();
    }
    OS << " };\n";
  }

  // Now emit the OptionTable table.
  OS << "\nstatic const WarningOption OptionTable[] = {";
  bool first = true;
  for (OptionMap::iterator I = OM.begin(), E = OM.end(); I!=E; ++I) {
    if (first)
      first = false;
    else
      OS << ',';

    OS << "\n  {\"" << getOptName(I->first)
       << "\", DIAGS(" << I->first->getName() << ")}";
  }
  OS << "\n};\n";
}
<|endoftext|>


<commit_before>// Copyright 2016,xiong feng.

#include "RpcConnection.h"

#include <map>
#include <list>
#include <string>
#include <memory>
#include "glog/logging.h"

#include "Event.h"
#include "ReactorLoop.h"
#include "Buffer.h"

using namespace minirpc;

class closeConnection :public Task
{
 public:
  explicit closeConnection(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  std::string taskName()
  {
    return "closeConnection";
  }

  void handle()const override;

 private:
  RpcConnection::Impl* impl_;
};

class writeConnection :public Task
{
 public:
  writeConnection(RpcConnection::Impl* impl, uint32_t opcode,
                  const ::google::protobuf::Message *message)
    :impl_(impl),
     opcode_(opcode),
     message_(message)
  {
  }

  std::string taskName()
  {
    return "writeConnection";
  }
  void handle() const override;

 private:
  RpcConnection::Impl* impl_;
  uint32_t opcode_;
  const ::google::protobuf::Message *message_;
};

class readEventHandler:public EventHandler
{
 public:
  explicit readEventHandler(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  virtual ~readEventHandler()
  {
  }

  void handlePacket()  override;

 private:
  RpcConnection::Impl* impl_;
};

class writeEventHandler:public EventHandler
{
 public:
  explicit writeEventHandler(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  virtual ~writeEventHandler()
  {
  }

  void handlePacket() override;

 private:
  RpcConnection::Impl* impl_;
};

class RpcConnection::Impl
{
 public:
  Impl(RpcConnection *connection, RpcConnectionFactory *manager,
         ReactorLoop* loop, int fd);

  ~Impl();

  void setFd(int fd);
  int  getFd();

  void setAddress(const NetAddress &address);
  void setReactorLoop(ReactorLoop* loop);
  void setHandler(MessageHandler *handler);

  void sendPacket(uint32_t opcode,
                  const ::google::protobuf::Message *message);
  void sendTreadSafe(uint32_t opcode,
                  const ::google::protobuf::Message *message);
  void start();
  void close();

  void handleCloseTreadSafe();
  void handleRead();
  void handleWrite();

 private:
  RpcConnection *connection_;
  RpcConnectionFactory *connection_manager_;
  ReactorLoop *loop_;
  ReadMessageState state_;
  int fd_;
  NetAddress address_;

  std::unique_ptr<Event> event_;
  MessageHeader messageHeader_;
  Buffer input_buffer_;
  Buffer output_buffer_;
  std::shared_ptr<MessageHandler> message_handler_;
};

RpcConnection::Impl::Impl(RpcConnection *connection,
                              RpcConnectionFactory *manager,
                              ReactorLoop* loop, int fd)
  : connection_(connection),
    connection_manager_(manager),
    loop_(loop),
    state_(READ_HEADER),
    fd_(fd)
{

}

RpcConnection::Impl::~Impl()
{
  //handleCloseTreadSafe();
  LOG(INFO)<< "delete rpc connection "<<connection_;
  //unique ptr event will delete another times
}

void RpcConnection::Impl::start()
{

  event_.reset(new Event(fd_));
  event_->setReadHandler(new readEventHandler(this));
  event_->setWriteHandler(new writeEventHandler(this));
  event_->disableWriting();
  loop_->addEvent(event_.get());

}

void RpcConnection::Impl::close()
{
  if (fd_ > 0)
  {
    input_buffer_.clear();
    output_buffer_.clear();
    state_ = READ_HEADER;
    event_->disableAll();
    LOG(INFO) << "delete event from rpc_connection "<<event_->eventsToString();
    loop_->deleteEvent(event_.get());
    connection_manager_->putConnection(connection_);//error will delete twice
    ::close(this->fd_);
    fd_ = -1;
  }
}

void RpcConnection::Impl::handleRead()
{
  int buffer_read = input_buffer_.Read(fd_);
  if (buffer_read == -1)
  {
    LOG(ERROR) << "recv message from "<<address_.DebugString() << " error";
    close();
    return;
  }
  else if (buffer_read == 0)
  {
    LOG(INFO) << "recv message from "<<address_.DebugString() << " close";
    close();
    return;
  }
  //LOG(INFO)<< " Handle Read "<< fd_;
  while (!input_buffer_.isReadComplete())
  {
    uint32_t result = decodeMessage(&input_buffer_, &messageHeader_, &state_);
    if (result == kRecvMessageNotCompleted)
    {
      return;
    }

    if (!message_handler_->handlePacket(messageHeader_, &input_buffer_))
    {
      LOG(ERROR) << "handle message from "<<address_.DebugString() << " error";
      close();
    }
  }
  input_buffer_.clear();
  return;
}

void RpcConnection::Impl::handleWrite()
{
  if (output_buffer_.isReadComplete())
  {
    LOG(INFO) << "write complete";
    event_->disableWriting();
    loop_->addEvent(event_.get());
    return;
  }
  //LOG(INFO) <<  "RpcConnection send message";
  uint32_t result = write(&output_buffer_, fd_);
  if (result == kSendMessageError)
  {
    LOG(ERROR) << "send message to " << address_.DebugString() << " error";
    close();
  }

  if (output_buffer_.isReadComplete())
  {
    LOG(INFO) << "write complete";
    event_->disableWriting();
    loop_->addEvent(event_.get());
  }
  return;
}

void readEventHandler::handlePacket()
{
  impl_->handleRead();
}

void writeEventHandler::handlePacket()
{
  impl_->handleWrite();
}

void RpcConnection::Impl::handleCloseTreadSafe()
{
  closeConnection *closeTask = new closeConnection(this);
  loop_->runTask(std::shared_ptr<Task>(closeTask));
  //loop_->wakeUp();
}

void closeConnection::handle() const
{
  impl_->close();
}

void RpcConnection::Impl::sendPacket( uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  //to do
  //may be we can write here directly if output_buffer_ is empty()?
  //no
  LOG(INFO) << " send packet ";
  encodeMessageToBuffer(opcode, message, &output_buffer_);
  if (!event_->isWriting())
  {
    //LOG(INFO) << " set writing ";
    event_->enableWriting();
    loop_->addEvent(event_.get());
  }
  //LOG(INFO) << " packet sended";
}

void RpcConnection::Impl::sendTreadSafe(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  writeConnection *sendTask = new writeConnection(this,opcode,message);
  loop_->runTask(std::shared_ptr<Task>(sendTask));
  // loop_->wakeUp();
}

void  writeConnection::handle() const
{
  impl_->sendPacket(opcode_, message_);
}

void RpcConnection::Impl::setFd(int fd)
{
  fd_ = fd;
}

int RpcConnection::Impl::getFd()
{
  return fd_;
}

void RpcConnection::Impl::setAddress(const NetAddress &address)
{
  address_ = address;
}

void RpcConnection::Impl::setReactorLoop(ReactorLoop* loop)
{
  loop_ = loop;
}

void RpcConnection::Impl::setHandler(MessageHandler *handler)
{
  message_handler_ = std::shared_ptr<MessageHandler>(handler);
}

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

RpcConnection::RpcConnection(RpcConnectionFactory *manager,
                      ReactorLoop* loop, int fd)
  : impl_( new Impl(this, manager, loop, fd) )
{
}

RpcConnection::~RpcConnection()
{
}

void RpcConnection::setFd(int fd)
{
  impl_->setFd(fd);
}

void RpcConnection::setAddress(const NetAddress &address)
{
  impl_->setAddress(address);
}

void RpcConnection::setReactorLoop(ReactorLoop* loop)
{
  impl_->setReactorLoop(loop);
}

void RpcConnection::setHandler(MessageHandler *handler)
{
  impl_->setHandler(handler);
}

void RpcConnection::sendPacket(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  impl_->sendPacket(opcode, message);
}

void RpcConnection::sendTreadSafe(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  impl_->sendTreadSafe(opcode, message);
}

void RpcConnection::start()
{
  impl_->start();
}

void RpcConnection::close()
{
  impl_->close();
}

void RpcConnection::handleCloseTreadSafe()
{
  impl_->handleCloseTreadSafe();
}

int RpcConnection::getFd()
{
  return impl_->getFd();
}

<commit_msg>Update RpcConnection.cpp<commit_after>// Copyright 2016,xiong feng.

#include "RpcConnection.h"

#include <map>
#include <list>
#include <string>
#include <memory>
#include "glog/logging.h"

#include "Event.h"
#include "ReactorLoop.h"
#include "Buffer.h"

using namespace minirpc;

class closeConnection :public Task
{
 public:
  explicit closeConnection(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  std::string taskName()
  {
    return "closeConnection";
  }

  void handle()const override;

 private:
  RpcConnection::Impl* impl_;
};

class writeConnection :public Task
{
 public:
  writeConnection(RpcConnection::Impl* impl, uint32_t opcode,
                  const ::google::protobuf::Message *message)
    :impl_(impl),
     opcode_(opcode),
     message_(message)
  {
  }

  std::string taskName()
  {
    return "writeConnection";
  }
  void handle() const override;

 private:
  RpcConnection::Impl* impl_;
  uint32_t opcode_;
  const ::google::protobuf::Message *message_;
};

class readEventHandler:public EventHandler
{
 public:
  explicit readEventHandler(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  void handlePacket()  override;

 private:
  RpcConnection::Impl* impl_;
};

class writeEventHandler:public EventHandler
{
 public:
  explicit writeEventHandler(RpcConnection::Impl* impl)
    :impl_(impl)
  {
  }

  virtual ~writeEventHandler()
  {
  }

  void handlePacket() override;

 private:
  RpcConnection::Impl* impl_;
};

class RpcConnection::Impl
{
 public:
  Impl(RpcConnection *connection, RpcConnectionFactory *manager,
         ReactorLoop* loop, int fd);

  ~Impl();

  void setFd(int fd);
  int  getFd();

  void setAddress(const NetAddress &address);
  void setReactorLoop(ReactorLoop* loop);
  void setHandler(MessageHandler *handler);

  void sendPacket(uint32_t opcode,
                  const ::google::protobuf::Message *message);
  void sendTreadSafe(uint32_t opcode,
                  const ::google::protobuf::Message *message);
  void start();
  void close();

  void handleCloseTreadSafe();
  void handleRead();
  void handleWrite();

 private:
  RpcConnection *connection_;
  RpcConnectionFactory *connection_manager_;
  ReactorLoop *loop_;
  ReadMessageState state_;
  int fd_;
  NetAddress address_;

  std::unique_ptr<Event> event_;
  MessageHeader messageHeader_;
  Buffer input_buffer_;
  Buffer output_buffer_;
  std::shared_ptr<MessageHandler> message_handler_;
};

RpcConnection::Impl::Impl(RpcConnection *connection,
                              RpcConnectionFactory *manager,
                              ReactorLoop* loop, int fd)
  : connection_(connection),
    connection_manager_(manager),
    loop_(loop),
    state_(READ_HEADER),
    fd_(fd)
{

}

RpcConnection::Impl::~Impl()
{
  //handleCloseTreadSafe();
  LOG(INFO)<< "delete rpc connection "<<connection_;
  //unique ptr event will delete another times
}

void RpcConnection::Impl::start()
{

  event_.reset(new Event(fd_));
  event_->setReadHandler(new readEventHandler(this));
  event_->setWriteHandler(new writeEventHandler(this));
  event_->disableWriting();
  loop_->addEvent(event_.get());

}

void RpcConnection::Impl::close()
{
  if (fd_ > 0)
  {
    input_buffer_.clear();
    output_buffer_.clear();
    state_ = READ_HEADER;
    event_->disableAll();
    LOG(INFO) << "delete event from rpc_connection "<<event_->eventsToString();
    loop_->deleteEvent(event_.get());
    connection_manager_->putConnection(connection_);//error will delete twice
    ::close(this->fd_);
    fd_ = -1;
  }
}

void RpcConnection::Impl::handleRead()
{
  int buffer_read = input_buffer_.Read(fd_);
  if (buffer_read == -1)
  {
    LOG(ERROR) << "recv message from "<<address_.DebugString() << " error";
    close();
    return;
  }
  else if (buffer_read == 0)
  {
    LOG(INFO) << "recv message from "<<address_.DebugString() << " close";
    close();
    return;
  }
  //LOG(INFO)<< " Handle Read "<< fd_;
  while (!input_buffer_.isReadComplete())
  {
    uint32_t result = decodeMessage(&input_buffer_, &messageHeader_, &state_);
    if (result == kRecvMessageNotCompleted)
    {
      return;
    }

    if (!message_handler_->handlePacket(messageHeader_, &input_buffer_))
    {
      LOG(ERROR) << "handle message from "<<address_.DebugString() << " error";
      close();
    }
  }
  input_buffer_.clear();
  return;
}

void RpcConnection::Impl::handleWrite()
{
  if (output_buffer_.isReadComplete())
  {
    LOG(INFO) << "write complete";
    event_->disableWriting();
    loop_->addEvent(event_.get());
    return;
  }
  //LOG(INFO) <<  "RpcConnection send message";
  uint32_t result = write(&output_buffer_, fd_);
  if (result == kSendMessageError)
  {
    LOG(ERROR) << "send message to " << address_.DebugString() << " error";
    close();
  }

  if (output_buffer_.isReadComplete())
  {
    LOG(INFO) << "write complete";
    event_->disableWriting();
    loop_->addEvent(event_.get());
  }
  return;
}

void readEventHandler::handlePacket()
{
  impl_->handleRead();
}

void writeEventHandler::handlePacket()
{
  impl_->handleWrite();
}

void RpcConnection::Impl::handleCloseTreadSafe()
{
  closeConnection *closeTask = new closeConnection(this);
  loop_->runTask(std::shared_ptr<Task>(closeTask));
  //loop_->wakeUp();
}

void closeConnection::handle() const
{
  impl_->close();
}

void RpcConnection::Impl::sendPacket( uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  //to do
  //may be we can write here directly if output_buffer_ is empty()?
  //no
  LOG(INFO) << " send packet ";
  encodeMessageToBuffer(opcode, message, &output_buffer_);
  if (!event_->isWriting())
  {
    //LOG(INFO) << " set writing ";
    event_->enableWriting();
    loop_->addEvent(event_.get());
  }
  //LOG(INFO) << " packet sended";
}

void RpcConnection::Impl::sendTreadSafe(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  writeConnection *sendTask = new writeConnection(this,opcode,message);
  loop_->runTask(std::shared_ptr<Task>(sendTask));
  // loop_->wakeUp();
}

void  writeConnection::handle() const
{
  impl_->sendPacket(opcode_, message_);
}

void RpcConnection::Impl::setFd(int fd)
{
  fd_ = fd;
}

int RpcConnection::Impl::getFd()
{
  return fd_;
}

void RpcConnection::Impl::setAddress(const NetAddress &address)
{
  address_ = address;
}

void RpcConnection::Impl::setReactorLoop(ReactorLoop* loop)
{
  loop_ = loop;
}

void RpcConnection::Impl::setHandler(MessageHandler *handler)
{
  message_handler_ = std::shared_ptr<MessageHandler>(handler);
}

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

RpcConnection::RpcConnection(RpcConnectionFactory *manager,
                      ReactorLoop* loop, int fd)
  : impl_( new Impl(this, manager, loop, fd) )
{
}

RpcConnection::~RpcConnection()
{
}

void RpcConnection::setFd(int fd)
{
  impl_->setFd(fd);
}

void RpcConnection::setAddress(const NetAddress &address)
{
  impl_->setAddress(address);
}

void RpcConnection::setReactorLoop(ReactorLoop* loop)
{
  impl_->setReactorLoop(loop);
}

void RpcConnection::setHandler(MessageHandler *handler)
{
  impl_->setHandler(handler);
}

void RpcConnection::sendPacket(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  impl_->sendPacket(opcode, message);
}

void RpcConnection::sendTreadSafe(uint32_t opcode,
                const ::google::protobuf::Message *message)
{
  impl_->sendTreadSafe(opcode, message);
}

void RpcConnection::start()
{
  impl_->start();
}

void RpcConnection::close()
{
  impl_->close();
}

void RpcConnection::handleCloseTreadSafe()
{
  impl_->handleCloseTreadSafe();
}

int RpcConnection::getFd()
{
  return impl_->getFd();
}

<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * 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.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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.
**
***********************************************************************************************************************/

#include "TypeAlias.h"
#include "../types/SymbolProviderType.h"

#include "ModelBase/src/nodes/TypedList.hpp"
template class Model::TypedList<OOModel::TypeAlias>;

namespace OOModel {

DEFINE_COMPOSITE_EMPTY_CONSTRUCTORS(TypeAlias)
DEFINE_COMPOSITE_TYPE_REGISTRATION_METHODS(TypeAlias)

DEFINE_ATTRIBUTE(TypeAlias, typeExpression, Expression, false, false, true)
DEFINE_ATTRIBUTE(TypeAlias, typeArguments, TypedListOfFormalTypeArgument, false, false, true)

TypeAlias::TypeAlias(const QString &name, Expression *typeExpression)
: Super{nullptr, TypeAlias::getMetaData()}
{
	setName(name);
	if (typeExpression) setTypeExpression(typeExpression);
}

Model::Node* TypeAlias::target() const
{
	Model::Node* ret{};

	auto type = this->typeExpression()->type();
	if (auto sp = dynamic_cast<SymbolProviderType*>(type.get()))
		ret = sp->symbolProvider();

	return ret;
}

TypeAlias::SymbolTypes TypeAlias::symbolType() const
{
	if (auto t = target()) return t->symbolType();
	else return UNSPECIFIED;
}

bool TypeAlias::findSymbols(QSet<Node*>& result, const Model::SymbolMatcher& matcher, const Model::Node* source,
		FindSymbolDirection direction, SymbolTypes symbolTypes, bool exhaustAllScopes) const
{
	bool found{};

	if (direction == SEARCH_HERE)
	{
		if (symbolMatches(matcher, symbolTypes))
		{
			result.insert(const_cast<TypeAlias*>(this));
			found = true;
		}
	}
	else if (direction == SEARCH_DOWN)
	{
		if (auto t = target())
			found = t->findSymbols(result, matcher, t, SEARCH_DOWN, symbolTypes, false);
	}
	else if (direction == SEARCH_UP)
	{
		auto ignore = childToSubnode(source);
		Q_ASSERT(ignore);
		if (typeArguments() != ignore)
			found = typeArguments()->findSymbols(result, matcher, source, SEARCH_HERE, symbolTypes, false) || found;

		if ((exhaustAllScopes || !found) && parent())
			found = parent()->findSymbols(result, matcher, source, SEARCH_UP, symbolTypes, exhaustAllScopes);
	}

	return found;
}

}
<commit_msg>prevent reference resolution from taking forever<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2014 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * 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.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT HOLDER OR 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.
**
***********************************************************************************************************************/

#include "TypeAlias.h"
#include "../types/SymbolProviderType.h"

#include "OOModel/src/expressions/ReferenceExpression.h"

#include "ModelBase/src/nodes/TypedList.hpp"
template class Model::TypedList<OOModel::TypeAlias>;

namespace OOModel {

DEFINE_COMPOSITE_EMPTY_CONSTRUCTORS(TypeAlias)
DEFINE_COMPOSITE_TYPE_REGISTRATION_METHODS(TypeAlias)

DEFINE_ATTRIBUTE(TypeAlias, typeExpression, Expression, false, false, true)
DEFINE_ATTRIBUTE(TypeAlias, typeArguments, TypedListOfFormalTypeArgument, false, false, true)

TypeAlias::TypeAlias(const QString &name, Expression *typeExpression)
: Super{nullptr, TypeAlias::getMetaData()}
{
	setName(name);
	if (typeExpression) setTypeExpression(typeExpression);
}

Model::Node* TypeAlias::target() const
{
	Model::Node* ret{};

	auto type = this->typeExpression()->type();
	if (auto sp = dynamic_cast<SymbolProviderType*>(type.get()))
		ret = sp->symbolProvider();

	return ret;
}

TypeAlias::SymbolTypes TypeAlias::symbolType() const
{
	if (auto t = target()) return t->symbolType();
	else return UNSPECIFIED;
}

bool TypeAlias::findSymbols(QSet<Node*>& result, const Model::SymbolMatcher& matcher, const Model::Node* source,
		FindSymbolDirection direction, SymbolTypes symbolTypes, bool exhaustAllScopes) const
{
	bool found{};

	// Without this check reference resolution takes forever
	if (auto reference = DCast<OOModel::ReferenceExpression>(this->typeExpression()))
		if (!reference->target())
			return found;

	if (direction == SEARCH_HERE)
	{
		if (symbolMatches(matcher, symbolTypes))
		{
			result.insert(const_cast<TypeAlias*>(this));
			found = true;
		}
	}
	else if (direction == SEARCH_DOWN)
	{
		if (auto t = target())
			found = t->findSymbols(result, matcher, t, SEARCH_DOWN, symbolTypes, false);
	}
	else if (direction == SEARCH_UP)
	{
		auto ignore = childToSubnode(source);
		Q_ASSERT(ignore);
		if (typeArguments() != ignore)
			found = typeArguments()->findSymbols(result, matcher, source, SEARCH_HERE, symbolTypes, false) || found;

		if ((exhaustAllScopes || !found) && parent())
			found = parent()->findSymbols(result, matcher, source, SEARCH_UP, symbolTypes, exhaustAllScopes);
	}

	return found;
}

}
<|endoftext|>


<commit_before><commit_msg>fix rtf image import ( causing wrong image sometimes displayed ) fdo#42640<commit_after><|endoftext|>


<commit_before>#ifndef __MEDIA_OBJECT_IMPL_HPP__
#define __MEDIA_OBJECT_IMPL_HPP__

#include <Factory.hpp>
#include "MediaObject.hpp"
#include <EventHandler.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <mutex>
#include <map>
#include "Tag.hpp"
#include <gst/gst.h>

namespace kurento
{

class MediaPipelineImpl;
class MediaObjectImpl;

void Serialize (std::shared_ptr<MediaObjectImpl> &object,
                JsonSerializer &serializer);

class MediaObjectImpl : public virtual MediaObject
{

public:

  MediaObjectImpl (const boost::property_tree::ptree &config);

  MediaObjectImpl (const boost::property_tree::ptree &config,
                   std::shared_ptr <MediaObject> parent);

  virtual ~MediaObjectImpl () {}

  void addTag (const std::string &key, const std::string &value);
  void removeTag (const std::string &key);
  std::string getTag (const std::string &key);
  std::vector<std::shared_ptr<Tag>> getTags ();

  virtual std::shared_ptr<MediaPipeline> getMediaPipeline ();

  virtual std::shared_ptr<MediaObject> getParent ()
  {
    return parent;
  }

  virtual std::vector<std::shared_ptr<MediaObject>> getChilds ();

  virtual std::string getId ();

  virtual std::string getName ();
  virtual void setName (const std::string &name);

  virtual bool getSendTagsInEvents ();
  virtual void setSendTagsInEvents (bool sendTagsInEvents);

  virtual int getCreationTime ();

  virtual void release ()
  {

  }

  /* Next methods are automatically implemented by code generator */
  virtual bool connect (const std::string &eventType,
                        std::shared_ptr<EventHandler> handler);

  sigc::signal<void, Error> signalError;

  virtual void invoke (std::shared_ptr<MediaObjectImpl> obj,
                       const std::string &methodName, const Json::Value &params,
                       Json::Value &response);

  virtual void Serialize (JsonSerializer &serializer);

protected:

  template <class T, class C>
  T getConfigValue (const std::string &key)
  {
    auto child = config.get_child ("modules." + dynamic_cast <C *>
                                   (this)->getModule() + "."
                                   + dynamic_cast <C *> (this)->getType() + "." + key);
    std::stringstream ss;
    Json::Value val;
    Json::Reader reader;
    kurento::JsonSerializer serializer (false);
    boost::property_tree::ptree array;

    array.push_back (std::make_pair ("val", child) );
    boost::property_tree::write_json (ss, array);

    reader.parse (ss.str(), val);

    T ret {};

    serializer.JsonValue = val;
    serializer.Serialize ("val", ret);

    return ret;
  }

  template <class T, class C>
  T getConfigValue (const std::string &key, T defaultValue)
  {
    try {
      return getConfigValue<T, C> (key);
    } catch (boost::property_tree::ptree_bad_path &e) {
      /* This case is expected, the config does not have the requested key */
    } catch (KurentoException &e) {
      GST_WARNING ("Posible error deserializing %s from config", key.c_str() );
    } catch (std::exception &e) {
      GST_WARNING ("Unknown error getting%s from config", key.c_str() );
    }

    return defaultValue;
  }

  /*
   * This method is intented to perform initialization actions that require
   * a call to shared_from_this ()
   */
  virtual void postConstructor ();

  const boost::property_tree::ptree &config;

private:

  std::string initialId;
  std::string id;
  std::string name;
  std::recursive_mutex mutex;
  std::shared_ptr<MediaObject> parent;
  int64_t creationTime;

  std::string createId();

  std::map<std::string, std::string> tagsMap;
  bool sendTagsInEvents;

  class StaticConstructor
  {
  public:
    StaticConstructor();
  };

  static StaticConstructor staticConstructor;

  friend Factory;
};

} /* kurento */

#endif /*  __MEDIA_OBJECT_IMPL_HPP__ */
<commit_msg>MediaObjectImpl: Add functions to get values from any node of the config file<commit_after>#ifndef __MEDIA_OBJECT_IMPL_HPP__
#define __MEDIA_OBJECT_IMPL_HPP__

#include <Factory.hpp>
#include "MediaObject.hpp"
#include <EventHandler.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <jsonrpc/JsonSerializer.hpp>
#include <KurentoException.hpp>
#include <mutex>
#include <map>
#include "Tag.hpp"
#include <gst/gst.h>

namespace kurento
{

class MediaPipelineImpl;
class MediaObjectImpl;

void Serialize (std::shared_ptr<MediaObjectImpl> &object,
                JsonSerializer &serializer);

class MediaObjectImpl : public virtual MediaObject
{

public:

  MediaObjectImpl (const boost::property_tree::ptree &config);

  MediaObjectImpl (const boost::property_tree::ptree &config,
                   std::shared_ptr <MediaObject> parent);

  virtual ~MediaObjectImpl () {}

  void addTag (const std::string &key, const std::string &value);
  void removeTag (const std::string &key);
  std::string getTag (const std::string &key);
  std::vector<std::shared_ptr<Tag>> getTags ();

  virtual std::shared_ptr<MediaPipeline> getMediaPipeline ();

  virtual std::shared_ptr<MediaObject> getParent () {
    return parent;
  }

  virtual std::vector<std::shared_ptr<MediaObject>> getChilds ();

  virtual std::string getId ();

  virtual std::string getName ();
  virtual void setName (const std::string &name);

  virtual bool getSendTagsInEvents ();
  virtual void setSendTagsInEvents (bool sendTagsInEvents);

  virtual int getCreationTime ();

  virtual void release () {

  }

  /* Next methods are automatically implemented by code generator */
  virtual bool connect (const std::string &eventType,
                        std::shared_ptr<EventHandler> handler);

  sigc::signal<void, Error> signalError;

  virtual void invoke (std::shared_ptr<MediaObjectImpl> obj,
                       const std::string &methodName, const Json::Value &params,
                       Json::Value &response);

  virtual void Serialize (JsonSerializer &serializer);

protected:

  template <class T>
  T getConfigValue (const std::string &key) {
    auto child = config.get_child (key);
    std::stringstream ss;
    Json::Value val;
    Json::Reader reader;
    kurento::JsonSerializer serializer (false);
    boost::property_tree::ptree array;

    array.push_back (std::make_pair ("val", child) );
    boost::property_tree::write_json (ss, array);

    reader.parse (ss.str(), val);

    T ret {};

    serializer.JsonValue = val;
    serializer.Serialize ("val", ret);

    return ret;
  }

  template <class T>
  T getConfigValue (const std::string &key, T defaultValue) {
    try {
      return getConfigValue<T> (key);
    } catch (boost::property_tree::ptree_bad_path &e) {
      /* This case is expected, the config does not have the requested key */
    } catch (KurentoException &e) {
      GST_WARNING ("Posible error deserializing %s from config", key.c_str() );
    } catch (std::exception &e) {
      GST_WARNING ("Unknown error getting%s from config", key.c_str() );
    }

    return defaultValue;
  }

  template <class T, class C>
  T getConfigValue (const std::string &key) {
    auto child = config.get_child ("modules." + dynamic_cast <C *>
                                   (this)->getModule() + "."
                                   + dynamic_cast <C *> (this)->getType() + "." + key);
    std::stringstream ss;
    Json::Value val;
    Json::Reader reader;
    kurento::JsonSerializer serializer (false);
    boost::property_tree::ptree array;

    array.push_back (std::make_pair ("val", child) );
    boost::property_tree::write_json (ss, array);

    reader.parse (ss.str(), val);

    T ret {};

    serializer.JsonValue = val;
    serializer.Serialize ("val", ret);

    return ret;
  }

  template <class T, class C>
  T getConfigValue (const std::string &key, T defaultValue) {
    try {
      return getConfigValue<T, C> (key);
    } catch (boost::property_tree::ptree_bad_path &e) {
      /* This case is expected, the config does not have the requested key */
    } catch (KurentoException &e) {
      GST_WARNING ("Posible error deserializing %s from config", key.c_str() );
    } catch (std::exception &e) {
      GST_WARNING ("Unknown error getting%s from config", key.c_str() );
    }

    return defaultValue;
  }

  /*
   * This method is intented to perform initialization actions that require
   * a call to shared_from_this ()
   */
  virtual void postConstructor ();

  const boost::property_tree::ptree &config;

private:

  std::string initialId;
  std::string id;
  std::string name;
  std::recursive_mutex mutex;
  std::shared_ptr<MediaObject> parent;
  int64_t creationTime;

  std::string createId();

  std::map<std::string, std::string> tagsMap;
  bool sendTagsInEvents;

  class StaticConstructor
  {
  public:
    StaticConstructor();
  };

  static StaticConstructor staticConstructor;

  friend Factory;
};

} /* kurento */

#endif /*  __MEDIA_OBJECT_IMPL_HPP__ */
<|endoftext|>


<commit_before>/**
 * @file mszreader.h Defines functions for reading a msz file
 *
 * @author Florian Letombe
 * @since November, 2007
 */

#ifndef MSZREADER__H__
#define MSZREADER__H__

#include <ctime>
#include <cstring>
#include <stdint.h>
#include <errno.h>

#include <signal.h>
#include <zlib.h>

#include <string>

using namespace std;

/**
 * Defines functions for input/output of DIMACS files.
 *
 * @author Florian Letombe
 * @since November, 2007
*/
namespace iomsz {

  /*************************************************************************************/
#if defined(__linux__)
  static inline int memReadStat(int field) {
    char    name[256];
    pid_t pid = getpid();
    sprintf(name, "/proc/%d/statm", pid);
    FILE*   in = fopen(name, "rb");
    if (in == NULL) return 0;
    int     value;
    for (; field >= 0; field--)
      fscanf(in, "%d", &value);
    fclose(in);
    return value;
  }
  static inline uint64_t memUsed() { return (uint64_t)memReadStat(0) * (uint64_t)getpagesize(); }

#elif defined(__FreeBSD__)
  static inline uint64_t memUsed(void) {
    struct rusage ru;
    getrusage(RUSAGE_SELF, &ru);
    return ru.ru_maxrss*1024;
  }

#else
  static inline uint64_t memUsed() { return 0; }
#endif

#if defined(__linux__)
#include <fpu_control.h>
#endif

  //=================================================================================================
  // DIMACS Parser:

#define CHUNK_LIMIT 1048576
#define reportf(format, args...) ( fflush(stdout), fprintf(stderr, format, ## args), fflush(stderr) )

  class StreamBuffer {
    gzFile  in;
    char    buf[CHUNK_LIMIT];
    int     pos;
    int     size;

    void assureLookahead() {
      if (pos >= size) {
	pos  = 0;
	size = gzread(in, buf, sizeof(buf));
      }
    }

  public:
  StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }

    int  operator *  () { return (pos >= size) ? EOF : buf[pos];}
    void operator ++ () { pos++; assureLookahead(); }
  };

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

  template<class B>
    static void skipWhitespace(B& in) {
    while ((*in >= 9 && *in <= 13) || *in == 32)
      ++in;
  }

  template<class B>
    static void skipLine(B& in) {
    for (;;){
      if (*in == EOF || *in == '\0') return;
      if (*in == '\n') { ++in; return; }
      ++in;
    }
  }

  template<class B>
    static int parseInt(B& in) {
    int     val = 0;
    bool    neg = false;
    skipWhitespace(in);
    if      (*in == '-') neg = true, ++in;
    else if (*in == '+') ++in;
    if (*in < '0' || *in > '9') reportf("PARSE ERROR! (parseInt) Unexpected char: %c\n", *in), exit(3);
    while (*in >= '0' && *in <= '9')
      val = val*10 + (*in - '0'),
	++in;
    return neg ? -val : val;
  }

  template<class B>
  static int parseDecimal(B& in, int& nbDec=0) {
    int     val = 0;
    if (*in < '0' || *in > '9') reportf("PARSE ERROR! (parseInt) Unexpected char: %c\n", *in), exit(3);
    while (*in >= '0' && *in <= '9')
      val = val*10 + (*in - '0'),
	++in, ++nbDec;
    return val;
  }

  template<class B>
    static double parseDouble(B& in) {
    int     valReal, nbDec=0;
    double valDecimal;
    valReal=parseInt(in);
    //reportf("valReal: %d\n", valReal);

    if (*in == '.') {
      ++in;
      valDecimal=(double)parseDecimal(in,nbDec);
    }
    else return (double)valReal;

    for (;nbDec!=0; nbDec--)
      valDecimal/=10;
    return valReal+valDecimal;
  }

  template<class B>
    static void readWord(B& in, string& word) {
    skipWhitespace(in);
    for (; (*in < 9 || *in > 13) && *in != 32;) {
      word+=*in;
      ++in;
    }
  }

  template<class B>
    static bool match(B& in, char* str) {
    for (; *str != 0; ++str, ++in)
      if (*str != *in)
	return false;
    return true;
  }

  template<class B>
    static void parse_MSZ_main(B& in,
			       unsigned int& nbSolvers,
			       unsigned int& nbFeatures,
			       unsigned int& nbInstances,
			       unsigned int& timeOut,
			       string*& solversNames,
			       string*& featuresNames,
			       string*& instancesNames,
			       double**& matrix) {
    for (unsigned int inst=0; inst<nbInstances;){
      skipWhitespace(in);
      //reportf("caractere lu : %c\n", *in);
      //(*in == 'q') ? reportf("OK\n") : reportf("KO\n");

      if (*in == EOF)
	break;
      else if (*in == 'p'){
	++in;++in;
	//reportf("Current character: %c\n", *in);

	if ((*in=='m') && (match(in, "msz"))){
	  nbSolvers = parseInt(in);
	  solversNames=new string [nbSolvers];
	  nbFeatures = parseInt(in);
	  featuresNames=new string [nbFeatures];
	  nbInstances = parseInt(in);
	  instancesNames=new string [nbInstances];

	  const int nbCases=nbSolvers+nbFeatures;
	  matrix=new double* [nbInstances];
	  for (unsigned int i=0; i<nbInstances; i++)
	    matrix[i]=new double [nbCases];
	  timeOut = parseInt(in);
	  reportf("c Number of solvers:    %2d\n", nbSolvers);
	  reportf("c Number of features:   %2d\n", nbFeatures);
	  reportf("c Number of instances:  %2d\n", nbInstances);
	  reportf("c Timeout:              %2d\n", timeOut);
	}
	else if ((*in=='s') && (match(in, "slv"))) {
	  reportf("c Solvers:");
	  for (unsigned int i=0; i<nbSolvers; i++) {
	    readWord(in,solversNames[i]);
	    reportf(" %s", solversNames[i].c_str());
	  }
	  reportf("\n");
	}
	else if ((*in=='f') && (match(in, "ftr"))) {
	  reportf("c Features:");
	  for (unsigned int i=0; i<nbFeatures; i++) {
	    readWord(in,featuresNames[i]);
	    reportf(" %s", featuresNames[i].c_str());
	  }
	  reportf("\n");
	}
	else reportf("PARSE ERROR! (parse_MSZ) Unexpected char: %c %c %c\n", *in, *in, *in), exit(3);
      }
      else if (*in == 'c' || *in == 'p')
	skipLine(in);
      else {
	readWord(in,instancesNames[inst]);
	reportf("Instance: %s\n", instancesNames[inst].c_str());

	reportf("matrix:\n");
	for (unsigned int i=0; i<nbSolvers; i++) {
	  matrix[inst][i]=parseDouble(in);
	  reportf(" %f", matrix[inst][i]);
	}
	for (unsigned int i=nbSolvers; i<nbSolvers+nbFeatures; i++) {
	  matrix[inst][i]=parseDouble(in);
	  reportf(" %f", matrix[inst][i]);
	}
	reportf("\n");
	inst++;
      }
    }
  }

  // Inserts problem into solver.
  //
  static void parse_DIMACS(gzFile input_stream,
			   unsigned int& nbSolvers,
			   unsigned int& nbFeatures,
			   unsigned int& nbInstances,
			   unsigned int& timeOut,
			   string*& solversNames,
			   string*& featuresNames,
			   string*& instancesNames,
			   double**& matrix) {
    StreamBuffer in(input_stream);
    parse_MSZ_main(in, nbSolvers, nbFeatures, nbInstances, timeOut, solversNames, featuresNames, instancesNames, matrix);
  }

} // end namespace iomsz

#endif // MSZREADER__H__
<commit_msg>No comment in msz files -> line removed<commit_after>/**
 * @file mszreader.h Defines functions for reading a msz file
 *
 * @author Florian Letombe
 * @since November, 2007
 */

#ifndef MSZREADER__H__
#define MSZREADER__H__

#include <ctime>
#include <cstring>
#include <stdint.h>
#include <errno.h>

#include <signal.h>
#include <zlib.h>

#include <string>

using namespace std;

/**
 * Defines functions for input/output of DIMACS files.
 *
 * @author Florian Letombe
 * @since November, 2007
*/
namespace iomsz {

  /*************************************************************************************/
#if defined(__linux__)
  static inline int memReadStat(int field) {
    char    name[256];
    pid_t pid = getpid();
    sprintf(name, "/proc/%d/statm", pid);
    FILE*   in = fopen(name, "rb");
    if (in == NULL) return 0;
    int     value;
    for (; field >= 0; field--)
      fscanf(in, "%d", &value);
    fclose(in);
    return value;
  }
  static inline uint64_t memUsed() { return (uint64_t)memReadStat(0) * (uint64_t)getpagesize(); }

#elif defined(__FreeBSD__)
  static inline uint64_t memUsed(void) {
    struct rusage ru;
    getrusage(RUSAGE_SELF, &ru);
    return ru.ru_maxrss*1024;
  }

#else
  static inline uint64_t memUsed() { return 0; }
#endif

#if defined(__linux__)
#include <fpu_control.h>
#endif

  //=================================================================================================
  // DIMACS Parser:

#define CHUNK_LIMIT 1048576
#define reportf(format, args...) ( fflush(stdout), fprintf(stderr, format, ## args), fflush(stderr) )

  class StreamBuffer {
    gzFile  in;
    char    buf[CHUNK_LIMIT];
    int     pos;
    int     size;

    void assureLookahead() {
      if (pos >= size) {
	pos  = 0;
	size = gzread(in, buf, sizeof(buf));
      }
    }

  public:
  StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }

    int  operator *  () { return (pos >= size) ? EOF : buf[pos];}
    void operator ++ () { pos++; assureLookahead(); }
  };

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

  template<class B>
    static void skipWhitespace(B& in) {
    while ((*in >= 9 && *in <= 13) || *in == 32)
      ++in;
  }

  template<class B>
    static void skipLine(B& in) {
    for (;;){
      if (*in == EOF || *in == '\0') return;
      if (*in == '\n') { ++in; return; }
      ++in;
    }
  }

  template<class B>
    static int parseInt(B& in) {
    int     val = 0;
    bool    neg = false;
    skipWhitespace(in);
    if      (*in == '-') neg = true, ++in;
    else if (*in == '+') ++in;
    if (*in < '0' || *in > '9') reportf("PARSE ERROR! (parseInt) Unexpected char: %c\n", *in), exit(3);
    while (*in >= '0' && *in <= '9')
      val = val*10 + (*in - '0'),
	++in;
    return neg ? -val : val;
  }

  template<class B>
  static int parseDecimal(B& in, int& nbDec=0) {
    int     val = 0;
    if (*in < '0' || *in > '9') reportf("PARSE ERROR! (parseInt) Unexpected char: %c\n", *in), exit(3);
    while (*in >= '0' && *in <= '9')
      val = val*10 + (*in - '0'),
	++in, ++nbDec;
    return val;
  }

  template<class B>
    static double parseDouble(B& in) {
    int     valReal, nbDec=0;
    double valDecimal;
    valReal=parseInt(in);
    //reportf("valReal: %d\n", valReal);

    if (*in == '.') {
      ++in;
      valDecimal=(double)parseDecimal(in,nbDec);
    }
    else return (double)valReal;

    for (;nbDec!=0; nbDec--)
      valDecimal/=10;
    return valReal+valDecimal;
  }

  template<class B>
    static void readWord(B& in, string& word) {
    skipWhitespace(in);
    for (; (*in < 9 || *in > 13) && *in != 32;) {
      word+=*in;
      ++in;
    }
  }

  template<class B>
    static bool match(B& in, char* str) {
    for (; *str != 0; ++str, ++in)
      if (*str != *in)
	return false;
    return true;
  }

  template<class B>
    static void parse_MSZ_main(B& in,
			       unsigned int& nbSolvers,
			       unsigned int& nbFeatures,
			       unsigned int& nbInstances,
			       unsigned int& timeOut,
			       string*& solversNames,
			       string*& featuresNames,
			       string*& instancesNames,
			       double**& matrix) {
    for (unsigned int inst=0; inst<nbInstances;){
      skipWhitespace(in);
      //reportf("caractere lu : %c\n", *in);
      //(*in == 'q') ? reportf("OK\n") : reportf("KO\n");

      if (*in == EOF)
	break;
      else if (*in == 'p'){
	++in;++in;
	//reportf("Current character: %c\n", *in);

	if ((*in=='m') && (match(in, "msz"))){
	  nbSolvers = parseInt(in);
	  solversNames=new string [nbSolvers];
	  nbFeatures = parseInt(in);
	  featuresNames=new string [nbFeatures];
	  nbInstances = parseInt(in);
	  instancesNames=new string [nbInstances];

	  const int nbCases=nbSolvers+nbFeatures;
	  matrix=new double* [nbInstances];
	  for (unsigned int i=0; i<nbInstances; i++)
	    matrix[i]=new double [nbCases];
	  timeOut = parseInt(in);
	  reportf("c Number of solvers:    %2d\n", nbSolvers);
	  reportf("c Number of features:   %2d\n", nbFeatures);
	  reportf("c Number of instances:  %2d\n", nbInstances);
	  reportf("c Timeout:              %2d\n", timeOut);
	}
	else if ((*in=='s') && (match(in, "slv"))) {
	  reportf("c Solvers:");
	  for (unsigned int i=0; i<nbSolvers; i++) {
	    readWord(in,solversNames[i]);
	    reportf(" %s", solversNames[i].c_str());
	  }
	  reportf("\n");
	}
	else if ((*in=='f') && (match(in, "ftr"))) {
	  reportf("c Features:");
	  for (unsigned int i=0; i<nbFeatures; i++) {
	    readWord(in,featuresNames[i]);
	    reportf(" %s", featuresNames[i].c_str());
	  }
	  reportf("\n");
	}
	else reportf("PARSE ERROR! (parse_MSZ) Unexpected char: %c %c %c\n", *in, *in, *in), exit(3);
      }
      //else if (*in == 'c' || *in == 'p')
      //skipLine(in);
      else {
	readWord(in,instancesNames[inst]);
	reportf("Instance: %s\n", instancesNames[inst].c_str());

	reportf("matrix:\n");
	for (unsigned int i=0; i<nbSolvers; i++) {
	  matrix[inst][i]=parseDouble(in);
	  reportf(" %f", matrix[inst][i]);
	}
	for (unsigned int i=nbSolvers; i<nbSolvers+nbFeatures; i++) {
	  matrix[inst][i]=parseDouble(in);
	  reportf(" %f", matrix[inst][i]);
	}
	reportf("\n");
	inst++;
      }
    }
  }

  // Inserts problem into solver.
  //
  static void parse_DIMACS(gzFile input_stream,
			   unsigned int& nbSolvers,
			   unsigned int& nbFeatures,
			   unsigned int& nbInstances,
			   unsigned int& timeOut,
			   string*& solversNames,
			   string*& featuresNames,
			   string*& instancesNames,
			   double**& matrix) {
    StreamBuffer in(input_stream);
    parse_MSZ_main(in, nbSolvers, nbFeatures, nbInstances, timeOut, solversNames, featuresNames, instancesNames, matrix);
  }

} // end namespace iomsz

#endif // MSZREADER__H__
<|endoftext|>


<commit_before><commit_msg>coverity#1209792 Dereference before null check<commit_after><|endoftext|>


<commit_before>#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#include <mtp/ptp/Device.h>

#include <map>
#include <string>

namespace
{
	class FuseWrapper
	{
		struct FileInfo
		{
			std::vector<mtp::u32> Files;
		};

		std::mutex		_mutex;
		mtp::DevicePtr	_device;
		mtp::SessionPtr	_session;

		typedef std::map<std::string, mtp::u32> Files;
		Files			_files;

		typedef mtp::Session::ObjectEditSessionPtr ObjectEditSessionPtr;
		typedef std::map<mtp::u32, ObjectEditSessionPtr> OpenedFiles;
		OpenedFiles		_openedFiles;

		typedef std::map<std::string, mtp::u32> Storages;
		Storages		_storages;

	public:
		FuseWrapper(mtp::DevicePtr device): _device(device), _session(device->OpenSession(1))
		{
			mtp::msg::StorageIDs ids = _session->GetStorageIDs();
			for(size_t i = 0; i < ids.StorageIDs.size(); ++i)
			{
				mtp::u32 id = ids.StorageIDs[i];
				mtp::msg::StorageInfo si = _session->GetStorageInfo(id);
				std::string path = "/" + (!si.VolumeLabel.empty()? si.VolumeLabel: si.StorageDescription);
				if (!path.empty())
					_storages[path] = id;
			}
		}

		int GetAttr(const char *path_, struct stat *stbuf)
		{
			std::string path(path_);
			if (path == "/")
			{
				stbuf->st_mode = S_IFDIR | 0755;
				stbuf->st_nlink = 2;
				return 0;
			}

			mtp::scoped_mutex_lock l(_mutex);
			Storages::const_iterator i = _storages.find(path);
			if (i != _storages.end())
			{
				stbuf->st_mode = S_IFDIR | 0755;
				stbuf->st_nlink = 2;
				return 0;
			}

			mtp::u32 id = Resolve(path);
			if (id)
			{
				stbuf->st_mode = 0644;

				mtp::msg::ObjectInfo oi = _session->GetObjectInfo(id);
				if (oi.ObjectFormat == mtp::ObjectFormat::Association)
					stbuf->st_mode |= S_IFDIR | 0111;
				else
					stbuf->st_mode |= S_IFREG;

				stbuf->st_ctim = timespec();
				stbuf->st_ctim.tv_sec = mtp::ConvertDateTime(oi.CaptureDate);
				stbuf->st_mtim = timespec();
				stbuf->st_mtim.tv_sec = mtp::ConvertDateTime(oi.ModificationDate);
				stbuf->st_nlink = 1;
				stbuf->st_size = oi.ObjectCompressedSize != mtp::MaxObjectSize? oi.ObjectCompressedSize: _session->GetObjectIntegerProperty(id, mtp::ObjectProperty::ObjectSize);
				return 0;
			}
			return -ENOENT;
		}

		void Append(const std::string &path, const mtp::msg::ObjectHandles &handles, void * buf, fuse_fill_dir_t filler)
		{
			for(auto & id : handles.ObjectHandles)
			{
				try
				{
					std::string name = _session->GetObjectStringProperty(id, mtp::ObjectProperty::ObjectFilename);
					_files[path + "/" + name] = id;
					if (filler)
						filler(buf, name.c_str(), NULL, 0);
				} catch(const std::exception &ex)
				{ }
			}
		}

		mtp::u32 Resolve(const std::string &path)
		{
			Files::const_iterator file = _files.find(path);
			if (file != _files.end())
				return file->second;

			// /STORAGE/dir1/dir2/file

			size_t idx = 0;
			while(idx < path.size())
			{
				size_t next = path.find('/', idx + 1);
				std::string subpath(path.substr(0, next));

				Storages::const_iterator storage = _storages.find(subpath);
				if (storage != _storages.end())
				{
					mtp::msg::ObjectHandles list = _session->GetObjectHandles(storage->second, mtp::Session::AllFormats, mtp::Session::Root);
					Append(subpath, list, 0, 0);
				}
				else
				{
					Files::const_iterator file = _files.find(subpath);
					if (file != _files.end())
					{
						mtp::msg::ObjectHandles list = _session->GetObjectHandles(mtp::Session::AllStorages, mtp::Session::AllFormats, file->second);
						Append(subpath, list, 0, 0);
					}
					else
						return 0;
				}
				if (next == path.npos)
					break;
				else
					idx = next;
			}

			file = _files.find(path);
			if (file != _files.end())
				return file->second;

			return 0;
		}

		int ReadDir(const char *path_, void *buf, fuse_fill_dir_t filler,
					 off_t offset, struct fuse_file_info *fi)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			if (path == "/")
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				for(auto & r : _storages)
				{
					filler(buf, r.first.c_str() + 1, NULL, 0);
				}
				return 0;
			}

			Storages::const_iterator storage = _storages.find(path);
			if (storage != _storages.end())
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				mtp::msg::ObjectHandles list = _session->GetObjectHandles(storage->second, mtp::Session::AllFormats, mtp::Session::Root);
				Append(path, list, buf, filler);
				return 0;
			}

			mtp::u32 id = Resolve(path);

			if (id)
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				mtp::msg::ObjectHandles list = _session->GetObjectHandles(mtp::Session::AllStorages, mtp::Session::AllFormats, id);
				Append(path, list, buf, filler);
				return 0;
			}

			return -ENOENT;
		}

		int Unlink (const char *path_)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;
			_session->DeleteObject(id);
			_files.erase(path);
			return 0;
		}

		int ResolveParent(const std::string &path, std::string &filename, mtp::u32 &storageId, mtp::u32 &parentId)
		{
			size_t parentPos = path.rfind('/');
			if (parentPos == path.npos)
				return -ENOENT;
			if (parentPos == 0)
				return -EACCES;

			size_t storagePos = path.find('/', 1);
			if (storagePos == path.npos)
				return -EACCES;

			std::string storage = path.substr(0, storagePos);
			Storages::const_iterator i = _storages.find(storage);
			if (i != _storages.end())
			{
				storageId = i->second;
			}
			else
				return -ENOENT;

			std::string parent = path.substr(0, parentPos);
			parentId = parent != storage? Resolve(parent): mtp::Session::Root;
			//printf("resolve parent %s -> %s %s %u %u\n", path.c_str(), storage.c_str(), parent.c_str(), storageId, parentId);

			if (storageId == 0 || parentId == 0)
				return -ENOENT;

			filename = path.substr(parentPos + 1);
			return 0;
		}

		int MakeDir (const char *path_, mode_t mode)
		{
			std::string path(path_);

			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 storageId, parentId;
			std::string filename;
			int r = ResolveParent(path, filename, storageId, parentId);
			if (r)
				return r;

			mtp::msg::ObjectInfo oi;
			oi.Filename = filename;
			oi.ObjectFormat = mtp::ObjectFormat::Association;
			oi.AssociationType = 1;
			_session->SendObjectInfo(oi, storageId, parentId);
			return 0;
		}

		int RemoveDir (const char *path)
		{ return Unlink(path); }

		int Create(const char *path_, mode_t mode, struct fuse_file_info *fi)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 storageId, parentId;
			std::string filename;
			int r = ResolveParent(path, filename, storageId, parentId);
			if (r)
				return r;

			mtp::msg::ObjectInfo oi;
			oi.Filename = filename;
			oi.ObjectFormat = mtp::ObjectFormatFromFilename(filename);
			_session->SendObjectInfo(oi, storageId, parentId);
			return 0;
		}

		int Open(const char *path, struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			return Resolve(path)? 0: -ENOENT;
		}

		int Read(const char *path, char *buf, size_t size, off_t offset,
					  struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;

			mtp::ByteArray data = _session->GetPartialObject(id, offset, size);
			if (data.size() > size)
				throw std::runtime_error("too much data");
			std::copy(data.begin(), data.end(), buf);
			return data.size();
		}

		ObjectEditSessionPtr GetSession(mtp::u32 id)
		{
			mtp::scoped_mutex_lock l(_mutex);
			OpenedFiles::const_iterator i = _openedFiles.find(id);
			if (i != _openedFiles.end())
				return i->second;
			else
				return _openedFiles[id] = mtp::Session::EditObject(_session, id);
		}

		int Flush(const char *path, struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;
			_openedFiles.erase(id);
			return 0;
		}

		int Write(const char *path, const char *buf, size_t size, off_t offset,
					  struct fuse_file_info *fi)
		{
			mtp::u32 id;
			{
				mtp::scoped_mutex_lock l(_mutex);
				id = Resolve(path);
				if (!id)
					return -ENOENT;
			}

			ObjectEditSessionPtr edit = GetSession(id);
			edit->Send(offset, mtp::ByteArray(buf, buf + size));
			return size;
		}

		int Truncate(const char *path, off_t offset)
		{
			mtp::u32 id;
			{
				mtp::scoped_mutex_lock l(_mutex);
				id = Resolve(path);
				if (!id)
					return -ENOENT;
			}

			ObjectEditSessionPtr edit = GetSession(id);
			edit->Truncate(offset);
			return 0;
		}

		int StatFS (const char *path, struct statvfs *stat)
		{
			stat->f_namemax = 254;
			return 0;
		}
	};

	mtp::DevicePtr					g_device;
	std::unique_ptr<FuseWrapper>	g_wrapper;

#define WRAP_EX(...) do { \
		try { return __VA_ARGS__ ; } \
		catch (const std::exception &ex) \
		{ fprintf(stderr, #__VA_ARGS__ " failed: %s", ex.what()); return -EIO; } \
	} while(false)

	int GetAttr(const char *path, struct stat *stbuf)
	{ WRAP_EX(g_wrapper->GetAttr(path, stbuf)); }

	int ReadDir(const char *path, void *buf, fuse_fill_dir_t filler,
				 off_t offset, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->ReadDir(path, buf, filler, offset, fi)); }

	int Open(const char *path, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Open(path, fi)); }

	int Create(const char *path, mode_t mode, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Create(path, mode, fi)); }

	int Read(const char *path, char *buf, size_t size, off_t offset,
				  struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Read(path, buf, size, offset, fi)); }

	int Write(const char *path, const char *buf, size_t size, off_t offset,
				  struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Write(path, buf, size, offset, fi)); }

	int Flush (const char *path, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Flush(path, fi)); }

	int Unlink (const char *path)
	{ WRAP_EX(g_wrapper->Unlink(path)); }

	int MakeDir (const char *path, mode_t mode)
	{ WRAP_EX(g_wrapper->MakeDir(path, mode)); }

	int RemoveDir (const char *path)
	{ WRAP_EX(g_wrapper->RemoveDir(path)); }

	int Truncate(const char *path, off_t offset)
	{ WRAP_EX(g_wrapper->Truncate(path, offset)); }

	int StatFS (const char *path, struct statvfs *stat)
	{ WRAP_EX(g_wrapper->StatFS(path, stat)); }
}

int main(int argc, char **argv)
{
	try
	{
		g_device = mtp::Device::Find();
		if (!g_device)
			throw std::runtime_error("no MTP device found");
		g_wrapper.reset(new FuseWrapper(g_device));
	} catch(const std::exception &ex)
	{ printf("%s\n", ex.what()); return 1; }

	struct fuse_operations ops = {};

	ops.getattr		= &GetAttr;
	ops.readdir		= &ReadDir;
	ops.open		= &Open;
	ops.create		= &Create;
	ops.read		= &Read;
	ops.write		= &Write;
	ops.flush		= &Flush;
	ops.mkdir		= &MakeDir;
	ops.rmdir		= &RemoveDir;
	ops.unlink		= &Unlink;
	ops.truncate	= &Truncate;
	ops.statfs		= &StatFS;

	return fuse_main(argc, argv, &ops, NULL);
}
<commit_msg>send empty object from create commands<commit_after>#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#include <mtp/ptp/Device.h>
#include <mtp/ptp/ByteArrayObjectStream.h>

#include <map>
#include <string>

namespace
{
	class FuseWrapper
	{
		struct FileInfo
		{
			std::vector<mtp::u32> Files;
		};

		std::mutex		_mutex;
		mtp::DevicePtr	_device;
		mtp::SessionPtr	_session;

		typedef std::map<std::string, mtp::u32> Files;
		Files			_files;

		typedef mtp::Session::ObjectEditSessionPtr ObjectEditSessionPtr;
		typedef std::map<mtp::u32, ObjectEditSessionPtr> OpenedFiles;
		OpenedFiles		_openedFiles;

		typedef std::map<std::string, mtp::u32> Storages;
		Storages		_storages;

	public:
		FuseWrapper(mtp::DevicePtr device): _device(device), _session(device->OpenSession(1))
		{
			mtp::msg::StorageIDs ids = _session->GetStorageIDs();
			for(size_t i = 0; i < ids.StorageIDs.size(); ++i)
			{
				mtp::u32 id = ids.StorageIDs[i];
				mtp::msg::StorageInfo si = _session->GetStorageInfo(id);
				std::string path = "/" + (!si.VolumeLabel.empty()? si.VolumeLabel: si.StorageDescription);
				if (!path.empty())
					_storages[path] = id;
			}
		}

		int GetAttr(const char *path_, struct stat *stbuf)
		{
			std::string path(path_);
			if (path == "/")
			{
				stbuf->st_mode = S_IFDIR | 0755;
				stbuf->st_nlink = 2;
				return 0;
			}

			mtp::scoped_mutex_lock l(_mutex);
			Storages::const_iterator i = _storages.find(path);
			if (i != _storages.end())
			{
				stbuf->st_mode = S_IFDIR | 0755;
				stbuf->st_nlink = 2;
				return 0;
			}

			mtp::u32 id = Resolve(path);
			if (id)
			{
				stbuf->st_mode = 0644;

				mtp::msg::ObjectInfo oi = _session->GetObjectInfo(id);
				if (oi.ObjectFormat == mtp::ObjectFormat::Association)
					stbuf->st_mode |= S_IFDIR | 0111;
				else
					stbuf->st_mode |= S_IFREG;

				stbuf->st_ctim = timespec();
				stbuf->st_ctim.tv_sec = mtp::ConvertDateTime(oi.CaptureDate);
				stbuf->st_mtim = timespec();
				stbuf->st_mtim.tv_sec = mtp::ConvertDateTime(oi.ModificationDate);
				stbuf->st_nlink = 1;
				stbuf->st_size = oi.ObjectCompressedSize != mtp::MaxObjectSize? oi.ObjectCompressedSize: _session->GetObjectIntegerProperty(id, mtp::ObjectProperty::ObjectSize);
				return 0;
			}
			return -ENOENT;
		}

		void Append(const std::string &path, const mtp::msg::ObjectHandles &handles, void * buf, fuse_fill_dir_t filler)
		{
			for(auto & id : handles.ObjectHandles)
			{
				try
				{
					std::string name = _session->GetObjectStringProperty(id, mtp::ObjectProperty::ObjectFilename);
					_files[path + "/" + name] = id;
					if (filler)
						filler(buf, name.c_str(), NULL, 0);
				} catch(const std::exception &ex)
				{ }
			}
		}

		mtp::u32 Resolve(const std::string &path)
		{
			Files::const_iterator file = _files.find(path);
			if (file != _files.end())
				return file->second;

			// /STORAGE/dir1/dir2/file

			size_t idx = 0;
			while(idx < path.size())
			{
				size_t next = path.find('/', idx + 1);
				std::string subpath(path.substr(0, next));

				Storages::const_iterator storage = _storages.find(subpath);
				if (storage != _storages.end())
				{
					mtp::msg::ObjectHandles list = _session->GetObjectHandles(storage->second, mtp::Session::AllFormats, mtp::Session::Root);
					Append(subpath, list, 0, 0);
				}
				else
				{
					Files::const_iterator file = _files.find(subpath);
					if (file != _files.end())
					{
						mtp::msg::ObjectHandles list = _session->GetObjectHandles(mtp::Session::AllStorages, mtp::Session::AllFormats, file->second);
						Append(subpath, list, 0, 0);
					}
					else
						return 0;
				}
				if (next == path.npos)
					break;
				else
					idx = next;
			}

			file = _files.find(path);
			if (file != _files.end())
				return file->second;

			return 0;
		}

		int ReadDir(const char *path_, void *buf, fuse_fill_dir_t filler,
					 off_t offset, struct fuse_file_info *fi)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			if (path == "/")
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				for(auto & r : _storages)
				{
					filler(buf, r.first.c_str() + 1, NULL, 0);
				}
				return 0;
			}

			Storages::const_iterator storage = _storages.find(path);
			if (storage != _storages.end())
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				mtp::msg::ObjectHandles list = _session->GetObjectHandles(storage->second, mtp::Session::AllFormats, mtp::Session::Root);
				Append(path, list, buf, filler);
				return 0;
			}

			mtp::u32 id = Resolve(path);

			if (id)
			{
				filler(buf, ".", NULL, 0);
				filler(buf, "..", NULL, 0);

				mtp::msg::ObjectHandles list = _session->GetObjectHandles(mtp::Session::AllStorages, mtp::Session::AllFormats, id);
				Append(path, list, buf, filler);
				return 0;
			}

			return -ENOENT;
		}

		int Unlink (const char *path_)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;
			_session->DeleteObject(id);
			_files.erase(path);
			return 0;
		}

		int ResolveParent(const std::string &path, std::string &filename, mtp::u32 &storageId, mtp::u32 &parentId)
		{
			size_t parentPos = path.rfind('/');
			if (parentPos == path.npos)
				return -ENOENT;
			if (parentPos == 0)
				return -EACCES;

			size_t storagePos = path.find('/', 1);
			if (storagePos == path.npos)
				return -EACCES;

			std::string storage = path.substr(0, storagePos);
			Storages::const_iterator i = _storages.find(storage);
			if (i != _storages.end())
			{
				storageId = i->second;
			}
			else
				return -ENOENT;

			std::string parent = path.substr(0, parentPos);
			parentId = parent != storage? Resolve(parent): mtp::Session::Root;
			//printf("resolve parent %s -> %s %s %u %u\n", path.c_str(), storage.c_str(), parent.c_str(), storageId, parentId);

			if (storageId == 0 || parentId == 0)
				return -ENOENT;

			filename = path.substr(parentPos + 1);
			return 0;
		}

		int MakeDir (const char *path_, mode_t mode)
		{
			std::string path(path_);

			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 storageId, parentId;
			std::string filename;
			int r = ResolveParent(path, filename, storageId, parentId);
			if (r)
				return r;

			mtp::msg::ObjectInfo oi;
			oi.Filename = filename;
			oi.ObjectFormat = mtp::ObjectFormat::Association;
			oi.AssociationType = 1;
			_session->SendObjectInfo(oi, storageId, parentId);
			return 0;
		}

		int RemoveDir (const char *path)
		{ return Unlink(path); }

		int Create(const char *path_, mode_t mode, struct fuse_file_info *fi)
		{
			std::string path(path_);
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 storageId, parentId;
			std::string filename;
			int r = ResolveParent(path, filename, storageId, parentId);
			if (r)
				return r;

			mtp::msg::ObjectInfo oi;
			oi.Filename = filename;
			oi.ObjectFormat = mtp::ObjectFormatFromFilename(filename);
			_session->SendObjectInfo(oi, storageId, parentId);
			_session->SendObject(std::make_shared<mtp::ByteArrayObjectInputStream>(mtp::ByteArray()));
			return 0;
		}

		int Open(const char *path, struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			return Resolve(path)? 0: -ENOENT;
		}

		int Read(const char *path, char *buf, size_t size, off_t offset,
					  struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;

			mtp::ByteArray data = _session->GetPartialObject(id, offset, size);
			if (data.size() > size)
				throw std::runtime_error("too much data");
			std::copy(data.begin(), data.end(), buf);
			return data.size();
		}

		ObjectEditSessionPtr GetSession(mtp::u32 id)
		{
			mtp::scoped_mutex_lock l(_mutex);
			OpenedFiles::const_iterator i = _openedFiles.find(id);
			if (i != _openedFiles.end())
				return i->second;
			else
				return _openedFiles[id] = mtp::Session::EditObject(_session, id);
		}

		int Flush(const char *path, struct fuse_file_info *fi)
		{
			mtp::scoped_mutex_lock l(_mutex);
			mtp::u32 id = Resolve(path);
			if (!id)
				return -ENOENT;
			_openedFiles.erase(id);
			return 0;
		}

		int Write(const char *path, const char *buf, size_t size, off_t offset,
					  struct fuse_file_info *fi)
		{
			mtp::u32 id;
			{
				mtp::scoped_mutex_lock l(_mutex);
				id = Resolve(path);
				if (!id)
					return -ENOENT;
			}

			ObjectEditSessionPtr edit = GetSession(id);
			edit->Send(offset, mtp::ByteArray(buf, buf + size));
			return size;
		}

		int Truncate(const char *path, off_t offset)
		{
			mtp::u32 id;
			{
				mtp::scoped_mutex_lock l(_mutex);
				id = Resolve(path);
				if (!id)
					return -ENOENT;
			}

			ObjectEditSessionPtr edit = GetSession(id);
			edit->Truncate(offset);
			return 0;
		}

		int StatFS (const char *path, struct statvfs *stat)
		{
			stat->f_namemax = 254;
			return 0;
		}
	};

	mtp::DevicePtr					g_device;
	std::unique_ptr<FuseWrapper>	g_wrapper;

#define WRAP_EX(...) do { \
		try { return __VA_ARGS__ ; } \
		catch (const std::exception &ex) \
		{ fprintf(stderr, #__VA_ARGS__ " failed: %s", ex.what()); return -EIO; } \
	} while(false)

	int GetAttr(const char *path, struct stat *stbuf)
	{ WRAP_EX(g_wrapper->GetAttr(path, stbuf)); }

	int ReadDir(const char *path, void *buf, fuse_fill_dir_t filler,
				 off_t offset, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->ReadDir(path, buf, filler, offset, fi)); }

	int Open(const char *path, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Open(path, fi)); }

	int Create(const char *path, mode_t mode, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Create(path, mode, fi)); }

	int Read(const char *path, char *buf, size_t size, off_t offset,
				  struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Read(path, buf, size, offset, fi)); }

	int Write(const char *path, const char *buf, size_t size, off_t offset,
				  struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Write(path, buf, size, offset, fi)); }

	int Flush (const char *path, struct fuse_file_info *fi)
	{ WRAP_EX(g_wrapper->Flush(path, fi)); }

	int Unlink (const char *path)
	{ WRAP_EX(g_wrapper->Unlink(path)); }

	int MakeDir (const char *path, mode_t mode)
	{ WRAP_EX(g_wrapper->MakeDir(path, mode)); }

	int RemoveDir (const char *path)
	{ WRAP_EX(g_wrapper->RemoveDir(path)); }

	int Truncate(const char *path, off_t offset)
	{ WRAP_EX(g_wrapper->Truncate(path, offset)); }

	int StatFS (const char *path, struct statvfs *stat)
	{ WRAP_EX(g_wrapper->StatFS(path, stat)); }
}

int main(int argc, char **argv)
{
	try
	{
		g_device = mtp::Device::Find();
		if (!g_device)
			throw std::runtime_error("no MTP device found");
		g_wrapper.reset(new FuseWrapper(g_device));
	} catch(const std::exception &ex)
	{ printf("%s\n", ex.what()); return 1; }

	struct fuse_operations ops = {};

	ops.getattr		= &GetAttr;
	ops.readdir		= &ReadDir;
	ops.open		= &Open;
	ops.create		= &Create;
	ops.read		= &Read;
	ops.write		= &Write;
	ops.flush		= &Flush;
	ops.mkdir		= &MakeDir;
	ops.rmdir		= &RemoveDir;
	ops.unlink		= &Unlink;
	ops.truncate	= &Truncate;
	ops.statfs		= &StatFS;

	return fuse_main(argc, argv, &ops, NULL);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cption.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2004-09-20 12:39:26 $
 *
 *  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 _CPTION_HXX
#define _CPTION_HXX

#ifndef _SVX_STDDLG_HXX //autogen
#include <svx/stddlg.hxx>
#endif

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _ACTCTRL_HXX //autogen
#include <actctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATIONACCESS_HPP_
#include <com/sun/star/container/XEnumerationAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_
#include <com/sun/star/container/XEnumeration.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XELEMENTACCESS_HPP_
#include <com/sun/star/container/XElementAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

class SwFldMgr;
class SwView;

#include "optload.hxx"
#include "swlbox.hxx"

class SwCaptionDialog : public SvxStandardDialog
{
    class CategoryBox : public ComboBox
    {
    public:
        CategoryBox( Window* pParent, const ResId& rResId )
            : ComboBox( pParent, rResId )
        {}

        virtual long    PreNotify( NotifyEvent& rNEvt );
    };

//  FixedText    aSampleText;
    FixedText    aTextText;
    Edit         aTextEdit;
    FixedLine    aSettingsFL;
    FixedText    aCategoryText;
    CategoryBox  aCategoryBox;
    FixedText    aFormatText;
    ListBox      aFormatBox;
    FixedText    aSepText;
    Edit         aSepEdit;
    FixedText    aPosText;
    ListBox      aPosBox;
    OKButton     aOKButton;
    CancelButton aCancelButton;
    HelpButton   aHelpButton;
    PushButton   aAutoCaptionButton;
    PushButton   aOptionButton;

    String       sNone;

    SwCaptionPreview aPrevWin;

    SwView       &rView;    //Suchen per aktive ::com::sun::star::sdbcx::View vermeiden.
    SwFldMgr     *pMgr;     //Ptr um das include zu sparen
    sal_uInt16   eType;

    String       sCharacterStyle;
    bool         bCopyAttributes;

    String          sObjectName;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    xNameAccess;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >         xNamed;

    DECL_LINK( SelectHdl, ListBox * );
    DECL_LINK( ModifyHdl, Edit * );
    DECL_LINK( OptionHdl, Button * );
    DECL_LINK( CaptionHdl, PushButton*);

    virtual void Apply();

    void DrawSample();

public:
     SwCaptionDialog( Window *pParent, SwView &rV );
    ~SwCaptionDialog();
};

#endif

<commit_msg>INTEGRATION: CWS pbbeta06 (1.6.222); FILE MERGED 2005/01/14 08:56:25 pb 1.6.222.1: fix: #i39983# CheckButtonWidth() added<commit_after>/*************************************************************************
 *
 *  $RCSfile: cption.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2005-01-25 14:44:44 $
 *
 *  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 _CPTION_HXX
#define _CPTION_HXX

#ifndef _SVX_STDDLG_HXX //autogen
#include <svx/stddlg.hxx>
#endif

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _GROUP_HXX //autogen
#include <vcl/group.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _ACTCTRL_HXX //autogen
#include <actctrl.hxx>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATIONACCESS_HPP_
#include <com/sun/star/container/XEnumerationAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALNAMEACCESS_HPP_
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCONTENTENUMERATIONACCESS_HPP_
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_
#include <com/sun/star/container/XEnumeration.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XELEMENTACCESS_HPP_
#include <com/sun/star/container/XElementAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

class SwFldMgr;
class SwView;

#include "optload.hxx"
#include "swlbox.hxx"

class SwCaptionDialog : public SvxStandardDialog
{
    class CategoryBox : public ComboBox
    {
    public:
        CategoryBox( Window* pParent, const ResId& rResId )
            : ComboBox( pParent, rResId )
        {}

        virtual long    PreNotify( NotifyEvent& rNEvt );
    };

    FixedText    aTextText;
    Edit         aTextEdit;
    FixedLine    aSettingsFL;
    FixedText    aCategoryText;
    CategoryBox  aCategoryBox;
    FixedText    aFormatText;
    ListBox      aFormatBox;
    FixedText    aSepText;
    Edit         aSepEdit;
    FixedText    aPosText;
    ListBox      aPosBox;
    OKButton     aOKButton;
    CancelButton aCancelButton;
    HelpButton   aHelpButton;
    PushButton   aAutoCaptionButton;
    PushButton   aOptionButton;

    String       sNone;

    SwCaptionPreview    aPrevWin;

    SwView       &rView; //Suchen per aktive ::com::sun::star::sdbcx::View vermeiden.
    SwFldMgr     *pMgr;      //Ptr um das include zu sparen
    sal_uInt16   eType;

    String       sCharacterStyle;
    String       sObjectName;
    bool         bCopyAttributes;

    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    xNameAccess;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNamed >         xNamed;

    DECL_LINK( SelectHdl, ListBox * );
    DECL_LINK( ModifyHdl, Edit * );
    DECL_LINK( OptionHdl, Button * );
    DECL_LINK( CaptionHdl, PushButton*);

    virtual void Apply();

    void    DrawSample();
    void    CheckButtonWidth();

public:
     SwCaptionDialog( Window *pParent, SwView &rV );
    ~SwCaptionDialog();
};

#endif

<|endoftext|>