/* PIP - Platform Independent Primitives Resources subsystem Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 program. If not, see . */ #include "piresourcesstorage.h" #include "pichunkstream.h" #include "piset.h" PIResourcesStorage::Section::Section() { } PIResourcesStorage::Section::~Section() { //piCout << "~Section"; } void PIResourcesStorage::Section::add(const PIResourcesStorage::Section & s) { PIMap::const_iterator i; for (i = s.entries.begin(); i != s.entries.end(); ++i) { if (!i.value()) continue; if (entries.value(i.key(), 0)) continue; entries[i.key()] = i.value(); } } void PIResourcesStorage::Section::purge() { PIVector bav = entries.values(); PISet bas; piForeach (PIByteArray * i, bav) { if (i) bas << i; } bav = bas.toVector(); piForeach (PIByteArray * i, bav) delete i; entries.clear(); } PIResourcesStorage::PIResourcesStorage() { } PIResourcesStorage::~PIResourcesStorage() { clear(); } void PIResourcesStorage::registerSection(const PIString & section_name, const PIResourcesStorage::Section & data) { Section * s = sections.value(section_name, 0); if (!s) { s = new Section(); sections[section_name] = s; } s->add(data); } void PIResourcesStorage::registerSection(const uchar * rc_data, const uchar * rc_desc, int rc_desc_size) { //piCout << "registerSection" << this; PIByteArray dba(rc_desc, rc_desc_size); PIVector el; dba >> el; PIMap > ebs; piForeachC (PIResourcesStorage::__RCEntry & e, el) { ebs[e.section] << e; } PIMap >::iterator it; for (it = ebs.begin(); it != ebs.end(); ++it) { PIResourcesStorage::Section s; PIVector & itv(it.value()); piForeachC (PIResourcesStorage::__RCEntry & e, itv) { //piCout << "add" << e.name << e.alias << PIString::readableSize(e.size); PIByteArray * eba = new PIByteArray(&(rc_data[e.offset]), e.size); s.entries[e.name] = eba; if (!e.alias.isEmpty() && e.alias != e.name) s.entries[e.alias] = eba; } registerSection(it.key(), s); } } PIResourcesStorage::Section * PIResourcesStorage::section(const PIString & section_name) const { return sections.value(section_name, 0); } PIByteArray PIResourcesStorage::get(const PIString & section_name, const PIString & entry_name) const { Section * s = sections.value(section_name, 0); if (!s) return PIByteArray(); PIByteArray * ba = s->entries.value(entry_name, 0); if (!ba) return PIByteArray(); return *ba; } PIByteArray PIResourcesStorage::get(const PIString & entry_name) const { PIMap::const_iterator i; for (i = sections.begin(); i != sections.end(); ++i) { if (!i.value()) continue; PIByteArray * ba = i.value()->entries.value(entry_name, 0); if (!ba) continue; return *ba; } return PIByteArray(); } void PIResourcesStorage::clear() { //piCout << "PIResourcesStorage clear"; PIVector
sv = sections.values(); piForeach (Section * i, sv) { if (i) i->purge(); } sections.clear(); } PIResourcesStorage * PIResourcesStorage::instance() { static PIResourcesStorage * ret = new PIResourcesStorage(); return ret; } PIByteArray & operator <<(PIByteArray & b, const PIResourcesStorage::__RCEntry & v) { PIChunkStream cs; cs << cs.chunk(1, v.section) << cs.chunk(2, v.name) << cs.chunk(3, v.file) << cs.chunk(4, v.size) << cs.chunk(5, v.offset) << cs.chunk(6, v.flags) << cs.chunk(7, v.alias); b << cs.data(); return b; } PIByteArray & operator >>(PIByteArray & b, PIResourcesStorage::__RCEntry & v) { PIByteArray ba; b >> ba; PIChunkStream cs(ba); while (!cs.atEnd()) { switch (cs.read()) { case 1: cs.get(v.section); break; case 2: cs.get(v.name); break; case 3: cs.get(v.file); break; case 4: cs.get(v.size); break; case 5: cs.get(v.offset); break; case 6: cs.get(v.flags); break; case 7: cs.get(v.alias); break; } } return b; }