📄 directorymap.cpp
字号:
static string escapeXMLLiterals(const string & src)
{
int index;
string::size_type pos;
string result;
const char literal[4] ="&<>";
const char * escape[3] = {"&","<",">"};
result = src;
for(index = 0; index < 3; index++)
{
pos = 0;
while((pos = result.find_first_of(literal[index],pos)) != string::npos)
{
result.erase(pos,1);
result.insert(pos, escape[index]);
++ pos;
}
}
return result;
}
static string encloseAttributes(const string & src)
{
if(src.find_first_of('"') != string::npos)
return string("'") + src + "'";
return string("\"") + src + "\"";
}
void Directory::drawTree_byXML(ostream * out, int level)
{
iterator scope;
if(level == 0)
*out << "<?xml version='1.0' encoding='Shift_JIS' ?>\n<?xml-stylesheet type='text/xsl' href='basic.xsl' ?>\n";
*out << "<node key=" << encloseAttributes(escapeXMLLiterals(getKey())) << " type='";
switch(type)
{
case POINTER:
out->setf(ios::hex);
*out << "PTR'><value>" << content.pointer << "</value>";
break;
case INTEGER:
out->setf(ios::dec);
*out << "INT'><value>" << content.value << "</value>";
break;
case LITERAL:
*out << "STR'><value>" << escapeXMLLiterals(*content.literal) << "</value>";
break;
case CONSTLITERAL:
*out << "CSTR'><value>" << escapeXMLLiterals(content.const_literal) << "</value>";
break;
case OBJECT:
*out << "OBJ'>";
break;
case UNKNOWN:
*out << "'>";
break;
default:
*out << "UNKNOWN'>";
}
*out << '\n';
scope = begin();
if(scope != end())
{
*out << "<child>\n";
do{
scope->second->drawTree_byXML(out, level+1);
++ scope;
}while(scope != end());
*out << "</child>\n";
}
*out << "</node>\n";
}
Directory * Directory::findChild(const char * key)
{
string work(key);
if(work.find_first_of('/') != string::npos)
return findChild(work);
return findNode(false, key, 0);
}
Directory * Directory::findChild(const char * key, const char * second, ... )
{
va_list vl;
va_start(vl, second);
vl = (char *)vl - sizeof(const char *);
return findNode(false, key, vl);
}
Directory * Directory::openChild(const char * key)
{
string work(key);
if(work.find_first_of('/') != string::npos)
return openChild(work);
return findNode(true, key, 0);
}
Directory * Directory::openChild(const char * key, const char * second, ... )
{
va_list vl;
va_start(vl, second);
vl = (char *)vl - sizeof(const char *);
return findNode(true, key, vl);
}
//巜掕偟偨僉乕傪帩偮巕懛傪扵偡丅僒乕僠弴偼拞弴
Directory * Directory::findDescandant(const string & key, unsigned int level) const
{
Directory::const_iterator scope;
const Directory * node = this;
if(empty())
return 0;
//巕偱扵偡
scope = begin();
while( scope != end() )
{
if((*scope).first.compare(key) == 0)
return const_cast<Directory *>((*scope).second);
++ scope;
}
if(level > 0)
{
scope = begin();
while( scope != end() )
{
if((node = (*scope).second->findDescandant(key, level-1)) != 0)
return const_cast<Directory *>(node);
++ scope;
}
}
return 0;
}
void Directory::copyTo(Directory * dest, int nest)
{
Directory::iterator scope;
Directory * node;
if(this == NULL)
return;
assert(dest != NULL);
node = dest;
while(node != 0)
{
if(node == this)
ExceptionMessage("CopyTo: dest must not be a descendant node.","CopyTo: 巕懛僲乕僪傊偺僐僺乕偼偱偒傑偣傫") << throwException;
node = node->getParent();
}
scope = begin();
while(scope != end())
{
node = dest->findChild((*scope).first);
if(node != 0)
node->erase();
node = dest->addChild((*scope).first, new Directory(*(*scope).second));
if(nest > 0)
(*scope).second->copyTo(node, nest-1);
++ scope;
}
}
void Directory::Store(ostream * out)
{
int i;
Directory * node;
out->write((const char *)&type, sizeof(type));
switch(type)
{
case INTEGER:
out->write((const char *)&content.value, sizeof(content.value));
break;
case LITERAL:
i = content.literal->size();
out->write((const char *)&i, sizeof(int));
out->write(content.literal->c_str(), i);
break;
case CONSTLITERAL:
i = strlen(content.const_literal);
out->write((const char *)&i, sizeof(int));
out->write(content.const_literal, i);
break;
default:
out->write((const char *)&content.pointer, sizeof(content.pointer));
}
i = size();
out->write((const char *)&i, sizeof(int));
for(node = getFirstChild(); node != 0; node = node->getNext())
{
const string & work = node->getKey();
i = work.size();
out->write((const char *)&i, sizeof(int));
out->write(work.c_str(), i);
node->Store(out);
}
}
void Directory::Load(istream * in)
{
int i;
int count;
char buffer[1024];
in->read((char *)&type, sizeof(type));
switch(type)
{
case INTEGER:
in->read((char *)&content.value, sizeof(content.value));
break;
case CONSTLITERAL:
case LITERAL:
in->read((char *)&i, sizeof(int));
in->read(buffer, i);
buffer[i] = '\x0';
*this = string(buffer);
break;
default:
in->read((char *)&content.pointer, sizeof(content.pointer));
}
in->read((char *)&count, sizeof(int));
while(count-- > 0)
{
in->read((char *)&i, sizeof(int));
in->read(buffer, i);
buffer[i] = '\x0';
addChild(buffer)->Load(in);
}
}
string Directory::toString(const string & default_value) const
{
if(this == 0)
return default_value;
switch(type)
{
case POINTER:
case OBJECT:
{
char buffer[256];
sprintf(buffer,"%08lx", (long)content.pointer);
return string(buffer);
}
case INTEGER:
{
char buffer[256];
sprintf(buffer,"%ld", content.value);
return string(buffer);
}
case CONSTLITERAL:
return string(content.const_literal);
case LITERAL:
return string(*content.literal);
default:
return default_value;
}
return default_value;
}
void * Directory::toPointer(const void * default_value) const
{
if(this == 0)
return (void *)default_value;
switch(type)
{
case INTEGER:
return (void *)&content.value;
case CONSTLITERAL:
return (void *)content.const_literal;
case LITERAL:
return (void *)content.literal->c_str();
case POINTER:
return (void *)content.pointer;
case OBJECT:
return (void *)content.instance;
default:
return (void *)default_value;
}
return (void *)default_value;
}
long Directory::toInteger(const long default_value) const
{
bool minus = false;
long work;
const char * str;
if(this == 0)
return default_value;
switch(type)
{
case INTEGER:
return content.value;
case POINTER:
return (long)content.pointer;
case LITERAL:
case CONSTLITERAL:
if(type == CONSTLITERAL)
str = content.const_literal;
else
str = content.literal->c_str();
if(*str == '-')
{
minus = true;
str ++;
}
if(*str == '0')
{
str ++;
if(*str == 'x' || *str == 'X')
{
if(sscanf(str+1, "%ux", (int *)&work) == 0)
return default_value;
}else
if(*str != '\x0')
{
if(sscanf(str, "%o", (int *)&work) == 0)
return default_value;
}else
return 0;
}else
if(sscanf(str, "%d", (int *)&work) == 0)
return default_value;
if(minus)
work = -work;
return work;
default:
return default_value;
}
return default_value;
}
static string::size_type find_corresponding_parenthesis(const string & target, string::size_type pos = 0, char left = '(', char right = ')')
{
int nest;
nest = 1;
do {
if(target[pos] == left)
{
++ nest;
}else
{
if(target[pos] == right)
{
-- nest;
if(nest == 0)
return static_cast<int>(pos);
}
}
++ pos;
}while(pos < target.size());
return string::npos;
}
string Directory::format(const string & fmt, int mode)
{
Directory * node;
string work;
string key;
string default_value;
string::size_type top,tail;
string::size_type pos;
int i;
default_value.assign("(null)");
tail = 0;
while((top = fmt.find_first_of('$', tail)) != string::npos)
{
if(top != tail)
work += fmt.substr(tail, top - tail);
switch(fmt[top+1])
{
case '$':
tail = top+2;
work += '$';
break;
case '@':
work += (*myself).first;
tail = top + 2;
break;
case '(':
top += 2;
i = find_corresponding_parenthesis(fmt, top);
key = fmt.substr(top, i - top);
if(key.find_first_of('$') != string::npos)
key = format(key,mode);
pos = key.find_first_of(',');
if(pos != string::npos)
{
default_value = key.substr(pos+1);
key.erase(pos);
}
node = findNode(false,key);
if((mode & PTRPREFIX) != 0 && (node != NULL && node->type == POINTER))
work += "0x";
work += node->toString(default_value);
tail = i+1;
break;
}
}
work += fmt.substr(tail);
return work;
}
map<std::string, Directory *>::size_type Directory::size(map<string, Directory *>::size_type defval) const
{
size_type i;
const_iterator scope;
if(this == NULL)
return defval;
i = 0;
scope = begin();
while(scope != end())
++ i, ++ scope;
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -