3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: directorymap.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
40 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/base/directorymap.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
43 Q: こういうクラスはテンプレートにしたほうがいいと思うが?
44 A: ファイルに吐き出した後、読み出したときにどうやってクラス生成すべきかがわからない
46 今と違う型を代入されたときの対処法がわからない
50 #include "base/directorymap.h"
51 #include "base/message.h"
58 #pragma warning(disable:4786)
63 int Directory::defaultflag = Directory::NOTHING;
65 Directory::Directory(const Directory & src)
69 defaultflag &= ~DESTRUCT;
75 content.literal = new string(*src.content.literal);
78 content = src.content;
83 Directory::~Directory(void)
85 disconnect(); //親との連結を解除
86 map<string,Directory*>::clear(); //子ノードの削除
87 clearContent(); //自分の中身を削除する
90 void Directory::clearContent(void)
92 switch(this->getType())
95 delete content.literal;
98 delete content.instance;
108 Directory * Directory::findNode(bool automatic_creation, const string & path)
110 string::size_type top, tail, length;
112 Directory::iterator scope;
113 Directory * node = this;
121 length = path.length();
125 while(node->getParent() != 0)
126 node = node->getParent();
133 tail = path.find_first_of('/', top);
134 if(tail == string::npos)
135 work = path.substr(top);
137 work = path.substr(top, tail-top);
139 if(work.compare(".") == 0 || work.compare("..") == 0)
141 if(work.size() > 1 && node->getParent() != 0)
142 node = node->getParent();
145 scope = node->begin();
146 while(scope != node->end())
148 if(work.compare((*scope).first) == 0)
153 if(scope == node->end())
155 if(!automatic_creation)
157 node = node->addChild(work, new Directory);
159 node = (*scope).second;
162 } while( tail != string::npos && top < length );
167 Directory * Directory::findNode(bool automatic_creation, const char * key, va_list vl)
169 Directory::iterator scope;
170 Directory * node = this;
178 if(*key == '/' && *(key+1) == '\x0')
180 while(node->getParent() != 0)
181 node = node->getParent();
184 key = va_arg(vl, const char *);
188 if(strcmp(key,".") != 0)
190 if(strcmp(key,"..") == 0)
195 scope = node->begin();
196 while(scope != node->end())
198 if((*scope).first.compare(key) == 0)
203 if(scope == node->end())
205 if(!automatic_creation)
207 node = node->addChild(key, new Directory);
209 node = (*scope).second;
213 key = va_arg(vl, const char *);
216 } while( key != 0 && node != 0);
221 Directory & Directory::operator =(void * pointer)
223 if(this->getType() != UNKNOWN && this->getType() != POINTER)
227 content.pointer = pointer;
231 Directory & Directory::operator =(long value)
233 if(this->getType() != UNKNOWN && this->getType() != INTEGER)
237 content.value = value;
241 Directory & Directory::operator =(const string & literal)
243 if(this->getType() != UNKNOWN && this->getType() != LITERAL)
247 content.literal = new string(literal);
252 Directory & Directory::operator =(const char * constliteral)
254 if(this->getType() != UNKNOWN && this->getType() != CONSTLITERAL)
258 content.const_literal = constliteral;
262 Directory & Directory::operator =(Garbage * instance)
264 if(this->getType() != UNKNOWN)
268 content.instance = instance;
272 void * Directory::operator new(size_t sz)
274 defaultflag |= DESTRUCT;
275 return ::operator new(sz);
278 void * Directory::operator new(size_t sz, nothrow_t)
280 defaultflag |= DESTRUCT;
281 return ::operator new(sz, nothrow);
284 Directory::operator const long(void) const
286 if( type == UNKNOWN )
287 ExceptionMessage("Bad cast exception","不正キャスト例外") << throwException;
288 return content.value;
291 void * Directory::operator * (void) const
293 if( type == UNKNOWN )
294 ExceptionMessage("Bad cast exception","不正キャスト例外") << throwException;
295 return content.pointer;
298 Directory * Directory::addChild(const std::string & key, Directory * node)
301 std::pair<iterator, bool> work;
304 node = new Directory;
306 if(node->parent != 0)
310 if((scope = find(key)) != end())
312 Directory * old = (*scope).second;
317 work = insert(value_type(key, node));
318 node->myself = work.first;
323 Directory::iterator Directory::erase(iterator it)
326 Directory * scope = (*it).second;
329 if((result = it) == begin())
335 if((scope->flag & DESTRUCT) != 0)
343 void Directory::erase(void)
351 parent->erase(myself);
357 if((scope->second->flag & DESTRUCT) != 0)
358 delete scope->second;
360 scope->second->erase();
366 void Directory::disconnect(void)
370 parent->map<string,Directory*>::erase(myself);
375 Directory * Directory::getNext(void) const
383 if(scope == parent->end())
386 return (*scope).second;
389 Directory * Directory::getPrev(void) const
391 if(parent == 0 && myself == parent->begin())
394 reverse_iterator scope;
396 scope = parent->rbegin();
397 while(scope != parent->rend() && (*scope).second != (*myself).second)
401 return scope != parent->rend() ? (*scope).second : 0;
404 bool Directory::changeKey(const string & key)
414 scope->addChild(key, this);
419 void Directory::drawTree(ostream * out, int level, string * link)
427 *out << (*link).substr(0, (level-1)*3) << " +-";
429 *out << '[' << getKey() << ']';
434 *out << " : PTR [" << content.pointer << "]";
438 *out << " : INT [" << content.value << "]";
441 *out << " : STR [" << *content.literal << "]";
444 *out << " : CSTR[" << content.const_literal << "]";
459 while(scope != end())
465 (*link)[level*3+1] = ' ';
466 (*scope2).second->drawTree(out, level+1, link);
470 link->erase(level*3);
475 static string escapeXMLLiterals(const string & src)
478 string::size_type pos;
480 const char literal[4] ="&<>";
481 const char * escape[3] = {"&","<",">"};
484 for(index = 0; index < 3; index++)
487 while((pos = result.find_first_of(literal[index],pos)) != string::npos)
490 result.insert(pos, escape[index]);
498 static string encloseAttributes(const string & src)
500 if(src.find_first_of('"') != string::npos)
501 return string("'") + src + "'";
502 return string("\"") + src + "\"";
505 void Directory::drawTree_byXML(ostream * out, int level)
510 *out << "<?xml version='1.0' encoding='Shift_JIS' ?>\n<?xml-stylesheet type='text/xsl' href='basic.xsl' ?>\n";
512 *out << "<node key=" << encloseAttributes(escapeXMLLiterals(getKey())) << " type='";
518 *out << "PTR'><value>" << content.pointer << "</value>";
522 *out << "INT'><value>" << content.value << "</value>";
525 *out << "STR'><value>" << escapeXMLLiterals(*content.literal) << "</value>";
528 *out << "CSTR'><value>" << escapeXMLLiterals(content.const_literal) << "</value>";
546 scope->second->drawTree_byXML(out, level+1);
548 }while(scope != end());
549 *out << "</child>\n";
554 Directory * Directory::findChild(const char * key)
557 if(work.find_first_of('/') != string::npos)
558 return findChild(work);
559 return findNode(false, key, 0);
562 Directory * Directory::findChild(const char * key, const char * second, ... )
565 va_start(vl, second);
566 return findNode(false, key, 0)->findNode(false,second, vl);
569 Directory * Directory::openChild(const char * key)
572 if(work.find_first_of('/') != string::npos)
573 return openChild(work);
574 return findNode(true, key, 0);
578 Directory * Directory::openChild(const char * key, const char * second, ... )
581 va_start(vl, second);
582 return findNode(true, key, 0)->findNode(true, second, vl);
585 //指定したキーを持つ子孫を探す。サーチ順は中順
586 Directory * Directory::findDescandant(const string & key, unsigned int level) const
588 Directory::const_iterator scope;
589 const Directory * node = this;
596 while( scope != end() )
598 if((*scope).first.compare(key) == 0)
599 return const_cast<Directory *>((*scope).second);
606 while( scope != end() )
608 if((node = (*scope).second->findDescandant(key, level-1)) != 0)
609 return const_cast<Directory *>(node);
616 void Directory::copyTo(Directory * dest, int nest)
618 Directory::iterator scope;
624 assert(dest != NULL);
630 ExceptionMessage("CopyTo: dest must not be a descendant node.","CopyTo: 子孫ノードへのコピーはできません") << throwException;
631 node = node->getParent();
635 while(scope != end())
637 node = dest->findChild((*scope).first);
641 node = dest->addChild((*scope).first, new Directory(*(*scope).second));
643 (*scope).second->copyTo(node, nest-1);
649 void Directory::Store(ostream * out)
654 out->write((const char *)&type, sizeof(type));
658 out->write((const char *)&content.value, sizeof(content.value));
661 i = content.literal->size();
662 out->write((const char *)&i, sizeof(int));
663 out->write(content.literal->c_str(), i);
666 i = strlen(content.const_literal);
667 out->write((const char *)&i, sizeof(int));
668 out->write(content.const_literal, i);
671 out->write((const char *)&content.pointer, sizeof(content.pointer));
674 out->write((const char *)&i, sizeof(int));
675 for(node = getFirstChild(); node != 0; node = node->getNext())
677 const string & work = node->getKey();
679 out->write((const char *)&i, sizeof(int));
680 out->write(work.c_str(), i);
685 void Directory::Load(istream * in)
691 in->read((char *)&type, sizeof(type));
695 in->read((char *)&content.value, sizeof(content.value));
699 in->read((char *)&i, sizeof(int));
702 *this = string(buffer);
705 in->read((char *)&content.pointer, sizeof(content.pointer));
707 in->read((char *)&count, sizeof(int));
710 in->read((char *)&i, sizeof(int));
714 addChild(buffer)->Load(in);
718 string Directory::toString(const string & default_value) const
721 return default_value;
729 sprintf(buffer,"%08lx", (long)content.pointer);
730 return string(buffer);
735 sprintf(buffer,"%ld", content.value);
736 return string(buffer);
739 return string(content.const_literal);
741 return string(*content.literal);
743 return default_value;
746 return default_value;
749 void * Directory::toPointer(const void * default_value) const
752 return (void *)default_value;
757 return (void *)&content.value;
759 return (void *)content.const_literal;
761 return (void *)content.literal->c_str();
763 return (void *)content.pointer;
765 return (void *)content.instance;
767 return (void *)default_value;
770 return (void *)default_value;
773 long Directory::toInteger(const long default_value) const
780 return default_value;
785 return content.value;
788 return (long)content.pointer;
792 if(type == CONSTLITERAL)
793 str = content.const_literal;
795 str = content.literal->c_str();
806 if(*str == 'x' || *str == 'X')
808 if(sscanf(str+1, "%ux", (int *)&work) == 0)
809 return default_value;
813 if(sscanf(str, "%o", (int *)&work) == 0)
814 return default_value;
818 if(sscanf(str, "%d", (int *)&work) == 0)
819 return default_value;
825 return default_value;
828 return default_value;
831 static string::size_type find_corresponding_parenthesis(const string & target, string::size_type pos = 0, char left = '(', char right = ')')
837 if(target[pos] == left)
842 if(target[pos] == right)
846 return static_cast<int>(pos);
850 }while(pos < target.size());
856 string Directory::format(const string & fmt, int mode)
861 string default_value;
862 string::size_type top,tail;
863 string::size_type pos;
866 default_value.assign("(null)");
868 while((top = fmt.find_first_of('$', tail)) != string::npos)
871 work += fmt.substr(tail, top - tail);
881 work += (*myself).first;
887 i = find_corresponding_parenthesis(fmt, top);
888 key = fmt.substr(top, i - top);
890 if(key.find_first_of('$') != string::npos)
891 key = format(key,mode);
893 pos = key.find_first_of(',');
894 if(pos != string::npos)
896 default_value = key.substr(pos+1);
900 node = findNode(false,key);
901 if((mode & PTRPREFIX) != 0 && (node != NULL && node->type == POINTER))
903 work += node->toString(default_value);
910 work += fmt.substr(tail);
915 map<std::string, Directory *>::size_type Directory::size(map<string, Directory *>::size_type defval) const
918 const_iterator scope;
925 while(scope != end())