#include #include #include #include "rlinifile.h" #include "shm.hpp" int Shm::parseHeader(rlIniFile & ini, const char * item, int * off, int * qty) { const char * ptr, *sect = "Slave"; int ret = 0, tmp; ptr = ini.text(sect, item); if(ptr) { ret = sscanf(ptr, "%i,%i,%i", &tmp, off, qty); } return ret; } int Shm::parseItem(const char * name, map_t * list) { char s[256]; int tmp, size, type, off; int ret = sscanf(name, "%i,%i,%i,%i,%s", &tmp, &size, &type, &off, s); if(ret == 5) { ShmValue * val = new ShmValue(type, off); ::string * st = new ::string(s); list->insert(pair< ::string*, ShmValue*>(st, val)); // list->insert(pair(s, val)); } return 0; } int Shm::parseSect(rlIniFile & ini, const char * sect, map_t * list) { const char * ptr = ini.firstName(sect); while(ptr) { const char * name = ini.text(sect, ptr); parseItem(name, list); ptr = ini.nextName(sect); } return 0; } Shm::~Shm() { for(unsigned char i = 0; i < sizeof(maps) / sizeof(map_t *); i++) { for(map_t::iterator it = maps[i]->begin(); it != maps[i]->end(); it++) { delete it->first; delete it->second; } } delete shm; } Shm::Shm(const char * name) { maps[0] = &map_coil; maps[1] = &map_status; maps[2] = &map_inreg; maps[3] = &map_holdreg; const char *items[] = { "Coil", "Instat", "Inreg", "Holdreg" }; rlIniFile ini; ini.read(name); int size = 0; for(unsigned char i = 0; i < sizeof(items) / sizeof(const char *); i++) { int ret, off, qty; ret = parseHeader(ini, items[i], &off, &qty); if(ret == 3) { parseSect(ini, items[i], maps[i]); size += qty; } } shm = new rlSharedMemory("/dev/shm/wsi", atoi(ini.text("Slave", "ShmSize")) ? atoi(ini.text("Slave", "ShmSize")) : size); // last = map_coil.end(); } int Shm::isFound(const char *name, map_t::iterator & it, map_t * m) { ::string s; s = name; it = m->find(&s); if(it != m->end()) return 1; return 0; } int Shm::get(const char *name, int what) { map_t *maps[] = { &map_coil, &map_status, &map_inreg, &map_holdreg }; for(unsigned char i = 0; i < sizeof(maps) / sizeof(map_t*); i++) { map_t::iterator it; if(isFound(name, it, maps[i])) return what ? it->second->offset() : it->second->type(); } return -1; } int Shm::getType(const char * name) { return get(name, 0); } int Shm::getOffset(const char * name) { return get(name, 1); } void * Shm::get(int off, void * buf, int size) { if(shm->read(off, buf, size) == size) return buf; return NULL; } int Shm::set(int off, void * val, int size) { return shm->write(off, val, size); } void* Shm::get(const char *name, void * buf, int size, map_t * first, map_t * second) { map_t::iterator it; if(isFound(name, it, first) || isFound(name, it, second)) { return get(it->second->offset(), buf, size); } return NULL; } int Shm::set(const char *name, void * val, int size, map_t * first) { map_t::iterator it; if(isFound(name, it, first)) { return set(it->second->offset(), val, size); } return -1; } char Shm::getBool(const char *name) { char buf; return get(name, &buf, 1, &map_status, &map_coil) ? buf : -1; } char Shm::getBool(int off) { char buf; return get(off, &buf, 1) ? buf : -1; } int Shm::setBool(const char *name, char val) { // if(last->second->type() == BOOL || strcmp(last->first, name) != 0) val = !!val; return set(name, &val, 1, &map_coil); } int Shm::setBool(int off, char val) { // if(last->second->type() == BOOL || strcmp(last->first, name) != 0) val = !!val; return set(off, &val, 1); } short Shm::getShort(const char *name) { short buf; return get(name, &buf, 2, &map_inreg, &map_holdreg) ? buf : -1; } short Shm::getShort(int off) { short buf; return get(off, &buf, 2) ? buf : -1; } int Shm::setShort(const char *name, short val) { return set(name, &val, 2, &map_holdreg); } int Shm::setShort(int off, short val) { return set(off, &val, 2); } long Shm::getLong(const char *name) { long buf; return get(name, &buf, 4, &map_inreg, &map_holdreg) ? buf : -1; } long Shm::getLong(int off) { long buf; return get(off, &buf, 4) ? buf : -1; } int Shm::setLong(const char *name, long val) { return set(name, &val, 4, &map_holdreg); } int Shm::setLong(int off, long val) { return set(off, &val, 4); } float Shm::getFloat(const char *name) { float buf; return get(name, &buf, 4, &map_inreg, &map_holdreg) ? buf : -1; } float Shm::getFloat(int off) { float buf; return get(off, &buf, 4) ? buf : -1; } int Shm::setFloat(const char *name, float val) { return set(name, &val, 4, &map_holdreg); } int Shm::setFloat(int off, float val) { return set(off, &val, 4); }