property.cpp
来自「一个语言识别引擎」· C++ 代码 · 共 459 行
CPP
459 行
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
/*
* Copyright (C) 2006 Paul Fitzpatrick
* CopyPolicy: Released under the terms of the GNU GPL v2.0.
*
*/
#include <yarp/os/Property.h>
#include <yarp/os/Bottle.h>
#include <yarp/Logger.h>
#include <yarp/StringInputStream.h>
#include <yarp/NetType.h>
#include <ace/Hash_Map_Manager.h>
#include <ace/Null_Mutex.h>
#include <fstream>
using namespace std;
using namespace yarp;
using namespace yarp::os;
class PropertyItem {
public:
Bottle bot;
bool singleton;
PropertyItem() {
singleton = false;
}
ConstString toString() {
return bot.toString();
}
};
class PropertyHelper {
public:
ACE_Hash_Map_Manager<String,PropertyItem,ACE_Null_Mutex> data;
Property& owner;
PropertyHelper(Property& owner) : owner(owner) {}
PropertyItem *getPropNoCreate(const char *key) const {
String n(key);
ACE_Hash_Map_Entry<String,PropertyItem> *entry = NULL;
int result = data.find(n,entry);
if (result==-1) {
return NULL;
}
YARP_ASSERT(result!=-1);
YARP_ASSERT(entry!=NULL);
return &(entry->int_id_);
}
PropertyItem *getProp(const char *key, bool create = true) {
String n(key);
ACE_Hash_Map_Entry<String,PropertyItem> *entry = NULL;
int result = data.find(n,entry);
if (result==-1) {
if (!create) {
return NULL;
}
data.bind(n,PropertyItem());
result = data.find(n,entry);
}
YARP_ASSERT(result!=-1);
YARP_ASSERT(entry!=NULL);
return &(entry->int_id_);
}
void put(const char *key, const char *val) {
PropertyItem *p = getProp(key,true);
p->singleton = true;
p->bot.clear();
p->bot.addString(key);
p->bot.addString(val);
}
void put(const char *key, const Value& bit) {
PropertyItem *p = getProp(key,true);
p->singleton = true;
p->bot.clear();
p->bot.addString(key);
p->bot.add(bit);
}
void put(const char *key, Value *bit) {
PropertyItem *p = getProp(key,true);
p->singleton = true;
p->bot.clear();
p->bot.addString(key);
p->bot.add(bit);
}
bool check(const char *key, Value *&output) const {
PropertyItem *p = getPropNoCreate(key);
return p!=NULL;
}
void unput(const char *key) {
data.unbind(String(key));
}
bool check(const char *key) const {
PropertyItem *p = getPropNoCreate(key);
if (owner.getMonitor()!=NULL) {
SearchReport report;
report.key = key;
report.isFound = (p!=NULL);
owner.reportToMonitor(report);
}
return p!=NULL;
}
Value& get(const char *key) const {
String out;
PropertyItem *p = getPropNoCreate(key);
if (p!=NULL) {
if (owner.getMonitor()!=NULL) {
SearchReport report;
report.key = key;
report.isFound = true;
report.value = p->bot.get(1).toString();
owner.reportToMonitor(report);
}
return p->bot.get(1);
}
if (owner.getMonitor()!=NULL) {
SearchReport report;
report.key = key;
owner.reportToMonitor(report);
}
return Value::getNullValue();
}
Bottle& putBottle(const char *key, const Bottle& val) {
PropertyItem *p = getProp(key,true);
p->singleton = false;
// inefficient! copy not implemented yet...
p->bot.fromString(val.toString().c_str());
return p->bot;
}
Bottle& putBottle(const char *key) {
PropertyItem *p = getProp(key,true);
p->singleton = false;
p->bot.clear();
return p->bot;
}
Bottle *getBottle(const char *key) const {
PropertyItem *p = getPropNoCreate(key);
if (p!=NULL) {
return &(p->bot);
}
return NULL;
}
void clear() {
data.unbind_all();
}
void fromString(const char *txt) {
Bottle bot;
bot.fromString(txt);
fromBottle(bot);
}
void fromCommand(int argc, char *argv[]) {
String tag = "";
Bottle accum;
Bottle total;
for (int i=0; i<argc; i++) {
String work = argv[i];
bool isTag = false;
if (work.length()>=2) {
if (work[0]=='-'&&work[1]=='-') {
work = work.substr(2,work.length()-2);
isTag = true;
}
}
if (isTag) {
if (tag!="") {
total.addList().copy(accum);
}
tag = work;
accum.clear();
}
accum.add(Value::makeValue(work.c_str()));
}
if (tag!="") {
total.addList().copy(accum);
}
fromBottle(total);
}
void fromConfigFile(const char *fname) {
ifstream fin(fname);
String txt;
if (fin.fail()) {
YARP_ERROR(Logger::get(),String("cannot read from ") +
fname);
}
while (!(fin.eof()||fin.fail())) {
char buf[1000];
fin.getline(buf,sizeof(buf));
if (!fin.eof()) {
txt += buf;
txt += "\n";
}
}
fromConfig(txt.c_str());
}
void fromConfig(const char *txt) {
StringInputStream sis;
sis.add(txt);
clear();
String tag = "";
Bottle accum;
bool done = false;
do {
bool isTag = false;
String buf;
try {
buf = NetType::readLine(sis);
} catch (IOException e) {
done = true;
}
if (!done) {
// this comment filter is not safe for quoting
int comment = buf.strstr("//");
if (comment>=0) {
buf = buf.substr(0,comment);
}
if (buf[0]=='[') {
int stop = buf.strstr("]");
if (stop>=0) {
buf = buf.substr(1,stop-1);
isTag = true;
}
}
}
if (!isTag) {
Bottle bot;
bot.fromString(buf.c_str());
if (bot.size()>=1) {
if (tag=="") {
putBottle(bot.get(0).toString().c_str(),bot);
} else {
accum.addList().copy(bot);
}
}
}
if (isTag||done) {
if (tag!="") {
if (accum.size()>=1) {
putBottle(tag.c_str(),accum);
}
tag = "";
}
tag = buf;
accum.clear();
accum.addString(tag.c_str());
}
} while (!done);
}
void fromBottle(Bottle& bot) {
for (int i=0; i<bot.size(); i++) {
Value& bb = bot.get(i);
if (bb.isList()) {
Bottle *sub = bb.asList();
putBottle(bb.asList()->get(0).toString().c_str(),*sub);
}
}
}
ConstString toString() {
Bottle bot;
for (ACE_Hash_Map_Manager<String,PropertyItem,ACE_Null_Mutex>::iterator
it = data.begin(); it!=data.end(); it++) {
PropertyItem& rec = (*it).int_id_;
Bottle& sub = bot.addList();
sub.copy(rec.bot);
}
return bot.toString();
}
};
// implementation is a PropertyHelper
#define HELPER(x) (*((PropertyHelper*)(x)))
Property::Property() {
implementation = new PropertyHelper(*this);
YARP_ASSERT(implementation!=NULL);
}
Property::Property(const char *str) {
implementation = new PropertyHelper(*this);
YARP_ASSERT(implementation!=NULL);
fromString(str);
}
Property::Property(const Property& prop) {
implementation = new PropertyHelper(*this);
YARP_ASSERT(implementation!=NULL);
fromString(prop.toString());
}
Property::~Property() {
if (implementation!=NULL) {
delete &HELPER(implementation);
implementation = NULL;
}
}
const Property& Property::operator = (const Property& prop) {
fromString(prop.toString());
return *this;
}
void Property::put(const char *key, const char *val) {
HELPER(implementation).put(key,val);
}
void Property::put(const char *key, const Value& value) {
HELPER(implementation).put(key,value);
}
void Property::put(const char *key, Value *value) {
HELPER(implementation).put(key,value);
}
/*
bool Property::check(const char *key, Value *&output) {
bool ok = false;
if (HELPER(implementation).check(key)) {
output = &find(key);
ok = true;
}
return ok;
}
*/
bool Property::check(const char *key) {
return HELPER(implementation).check(key);
}
void Property::unput(const char *key) {
HELPER(implementation).unput(key);
}
Value& Property::find(const char *key) {
return HELPER(implementation).get(key);
}
/*
Bottle& Property::putBottle(const char *key, const Bottle& val) {
return HELPER(implementation).putBottle(key,val);
}
Bottle& Property::putBottle(const char *key) {
return HELPER(implementation).putBottle(key);
}
Bottle *Property::getBottle(const char *key) const {
return HELPER(implementation).getBottle(key);
}
*/
void Property::clear() {
HELPER(implementation).clear();
}
void Property::fromString(const char *txt) {
HELPER(implementation).fromString(txt);
}
ConstString Property::toString() const {
return HELPER(implementation).toString();
}
void Property::fromCommand(int argc, char *argv[], bool skipFirst) {
if (skipFirst) {
argc--;
argv++;
}
HELPER(implementation).fromCommand(argc,argv);
}
void Property::fromConfigFile(const char *fname) {
HELPER(implementation).fromConfigFile(fname);
}
void Property::fromConfig(const char *txt) {
HELPER(implementation).fromConfig(txt);
}
bool Property::read(ConnectionReader& reader) {
// for now just delegate to Bottle
Bottle b;
bool ok = b.read(reader);
if (ok) {
fromString(b.toString());
}
return ok;
}
bool Property::write(ConnectionWriter& writer) {
// for now just delegate to Bottle
Bottle b(toString());
return b.write(writer);
}
Bottle& Property::findGroup(const char *key) {
Bottle *result = HELPER(implementation).getBottle(key);
if (getMonitor()!=NULL) {
SearchReport report;
report.key = key;
report.isGroup = true;
if (result!=0/*NULL*/) {
report.isFound = true;
report.value = result->toString();
}
reportToMonitor(report);
}
if (result!=((Bottle*)0)) { return *result; }
return Bottle::getNullBottle();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?