📄 cpp_regex_traits.cpp
字号:
if((id <= boost::REG_E_UNKNOWN) && (pmd->error_strings[id].size()))
return pmd->error_strings[id];
return boost::re_detail::re_default_error_messages[id];
}
cpp_regex_traits<char>::locale_type BOOST_REGEX_CALL cpp_regex_traits<char>::imbue(locale_type l)
{
locale_type old_l(locale_inst);
locale_inst = l;
re_detail::message_data<char>* npmd = new re_detail::message_data<char>(locale_inst, regex_message_cat);
delete pmd;
pmd = npmd;
psyntax = pmd->syntax_map;
for(unsigned int i = 0; i < char_set_size; ++i)
lower_map[i] = static_cast<char>(i);
pctype = &BOOST_USE_FACET(std::ctype<char>, locale_inst);
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
pcollate = &BOOST_USE_FACET(std::collate<char>, locale_inst);
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
return old_l;
}
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_STD_WSTREAMBUF)
namespace re_detail{
std::string BOOST_REGEX_CALL to_narrow(const std::basic_string<wchar_t>& is, const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
{
BOOST_RE_GUARD_STACK
std::basic_string<wchar_t>::size_type bufsize = is.size() * 2;
//
// declare buffer first as VC6 workaround for internal compiler error!
char* pc = new char[bufsize];
scoped_array<char> t(pc);
#if defined(BOOST_MSVC) && !defined(DINKUMWARE_CE)
std::mbstate_t state = 0;
#else
std::mbstate_t state = std::mbstate_t();
#endif
const wchar_t* next_in;
char* next_out;
while(true)
{
switch(cvt.out(state, is.c_str(), is.c_str() + is.size(), next_in, t.get(), t.get() + bufsize, next_out))
{
case std::codecvt_base::ok:
return std::string(t.get(), next_out);
case std::codecvt_base::partial:
bufsize *= 2;
t.reset(new char[bufsize]);
continue;
case std::codecvt_base::error:
// not much we can do here but guess:
case std::codecvt_base::noconv:
std::string out;
for(unsigned i = 0; i < is.size(); ++i)
{
out.append(1, (char)is[i]);
}
return out;
}
}
}
std::wstring BOOST_REGEX_CALL to_wide(const std::string& is, const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
{
BOOST_RE_GUARD_STACK
std::string::size_type bufsize = is.size() + 2;
std::string::size_type maxsize = is.size() * 100;
//
// declare buffer first as VC6 workaround for internal compiler error!
wchar_t* pc = new wchar_t[bufsize];
scoped_array<wchar_t> t(pc);
#if defined(BOOST_MSVC) && !defined(DINKUMWARE_CE)
std::mbstate_t state = 0;
#else
std::mbstate_t state = std::mbstate_t();
#endif
wchar_t* next_out;
const char* next_in;
while(true)
{
switch(cvt.in(state, is.c_str(), is.c_str() + is.size(), next_in, t.get(), t.get() + bufsize, next_out))
{
case std::codecvt_base::ok:
return std::wstring(t.get(), next_out);
case std::codecvt_base::partial:
bufsize *= 2;
if(bufsize < maxsize)
{
t.reset(new wchar_t[bufsize]);
continue;
}
//
// error fall through:
case std::codecvt_base::error:
// not much we can do here but guess:
case std::codecvt_base::noconv:
std::wstring out;
for(unsigned i = 0; i < is.size(); ++i)
{
out.append(1, is[i]);
}
return out;
}
}
}
template <>
struct message_data<wchar_t>
{
#ifndef BOOST_NO_STD_MESSAGES
typedef std::messages<wchar_t>::string_type string_type;
#else
typedef std::wstring string_type;
#endif
string_type name;
struct syntax_map
{
wchar_t c;
unsigned int type;
};
std::list<syntax_map> syntax;
std::map<string_type, std::size_t> classes;
std::map<string_type, string_type> collating_elements;
unsigned char syntax_[CHAR_MAX-CHAR_MIN+1];
parser_buf<wchar_t> sbuf;
std::wistream is;
std::string error_strings[boost::REG_E_UNKNOWN+1];
message_data(const std::locale& l, const std::string& regex_message_catalogue);
private:
message_data(const message_data&);
message_data& operator=(const message_data&);
};
message_data<wchar_t>::message_data(const std::locale& l, const std::string& regex_message_catalogue)
: is(&sbuf)
{
is.imbue(l);
syntax_map m;
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_type;
const cvt_type& cvt = BOOST_USE_FACET(cvt_type, l);
#ifndef BOOST_NO_STD_MESSAGES
const std::messages<wchar_t>& msgs = BOOST_USE_FACET(std::messages<wchar_t>, l);
#ifndef __IBMCPP__
std::messages<wchar_t>::catalog cat = static_cast<std::messages<wchar_t>::catalog>(-1);
#else
std::messages<wchar_t>::catalog cat = reinterpret_cast<std::messages<wchar_t>::catalog>(-1);
#endif
if(regex_message_catalogue.size())
{
cat = msgs.open(regex_message_catalogue, l);
if(cat < 0)
{
std::string mess("Unable to open message catalog: ");
std::runtime_error err(mess + regex_message_catalogue);
boost::throw_exception(err);
}
}
#endif
scoped_array<char> a;
std::size_t array_size = 0;
std::size_t new_size;
std::size_t i;
std::memset(syntax_, cpp_regex_traits<wchar_t>::syntax_char, sizeof(syntax_));
for(i = 1; i < cpp_regex_traits<wchar_t>::syntax_max; ++i)
{
new_size = re_get_default_message(0, 0, i+100);
if(new_size > array_size)
{
a.reset(new char[new_size]);
array_size = new_size;
}
re_get_default_message(a.get(), array_size, i+100);
std::string ns = a.get();
string_type s = to_wide(ns, cvt);
#ifndef BOOST_NO_STD_MESSAGES
if((int)cat >= 0)
s = BOOST_USE_FACET(std::messages<wchar_t>, l).get(cat, 0, (int)i+100, s);
#endif
for(unsigned int j = 0; j < s.size(); ++j)
{
#if defined(WCHAR_MIN) && (WCHAR_MIN == 0)
if(s[j] <= UCHAR_MAX)
#else
if((s[j] <= UCHAR_MAX) && (s[j] >= 0))
#endif
syntax_[s[j]] = static_cast<unsigned char>(i);
else
{
m.c = s[j];
m.type = static_cast<unsigned int>(i);
syntax.push_back(m);
}
}
}
#ifndef BOOST_NO_STD_MESSAGES
// load any custom collate names:
string_type c1, c2;
i = 400;
if((int)cat >= 0)
{
c2 = msgs.get(cat, 0, (int)i, c1);
while(c2.size())
{
const wchar_t* p1, *p2, *p3, *p4;;
p1 = c2.c_str();
while(*p1 && BOOST_REGEX_STD isspace((wchar_t)*p1, l))++p1;
p2 = p1;
while(*p2 && !BOOST_REGEX_STD isspace((wchar_t)*p2, l))++p2;
p3 = p2;
while(*p3 && BOOST_REGEX_STD isspace((wchar_t)*p3, l))++p3;
p4 = p3;
while(*p4 && !BOOST_REGEX_STD isspace((wchar_t)*p4, l))++p4;
collating_elements[std::basic_string<wchar_t>(p1, p2)] = std::basic_string<wchar_t>(p3, p4);
++i;
c2 = msgs.get(cat, 0, (int)i, c1);
}
}
if((int)cat >= 0)
{
c2.erase();
for(i = 0; i < re_classes_max; ++i)
{
c1 = msgs.get(cat, 0, static_cast<int>(i+300), c2);
if(c1.size())
classes[c1] = i;
}
for(i = 0; i <= boost::REG_E_UNKNOWN ; ++i)
{
c1 = msgs.get(cat, 0, static_cast<int>(i+200), c2);
error_strings[i] = to_narrow(c1, cvt);
}
}
if((int)cat >= 0)
msgs.close(cat);
#endif
}
} // namespace re_detail
unsigned int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::do_syntax_type(size_type c)const
{
std::list<re_detail::message_data<wchar_t>::syntax_map>::const_iterator i, j;
i = pmd->syntax.begin();
j = pmd->syntax.end();
while(i != j)
{
if(((uchar_type)(*i).c) == c)
return (*i).type;
++i;
}
return 0;
}
void BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::transform_primary(std::basic_string<wchar_t>& out, const std::basic_string<wchar_t>& in)const
{
transform(out, in);
switch(sort_type)
{
case re_detail::sort_C:
case re_detail::sort_unknown:
break;
case re_detail::sort_fixed:
if((unsigned)sort_delim < out.size())
out.erase((int)sort_delim);
break;
case re_detail::sort_delim:
for(unsigned int i = 0; i < out.size(); ++i)
{
if((out[i] == sort_delim) && (i+1 < out.size()))
{
out.erase(i+1);
break;
}
}
}
}
int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::toi(wchar_t c)const
{
pmd->sbuf.pubsetbuf(&c, 1);
pmd->is.clear();
pmd->is >> std::dec;
int val;
if(pmd->is >> val)
{
return val;
}
else
return 0;
}
int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::toi(const wchar_t*& first, const wchar_t* last, int radix)const
{
pmd->sbuf.pubsetbuf(const_cast<wchar_t*>(first), static_cast<std::streamsize>(last-first));
pmd->is.clear();
if(std::abs(radix) == 16) pmd->is >> std::hex;
else if(std::abs(radix) == 8) pmd->is >> std::oct;
else pmd->is >> std::dec;
int val;
if(pmd->is >> val)
{
first = first + ((last - first) - pmd->sbuf.in_avail());
return val;
}
else
return 0;
}
boost::uint_fast32_t BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::lookup_classname(const wchar_t* first, const wchar_t* last)const
{
BOOST_RE_GUARD_STACK
unsigned int i;
std::wstring s(first, last);
std::map<std::wstring, std::size_t>::const_iterator pos = pmd->classes.find(s);
if(pos != pmd->classes.end())
return re_char_class_id[(*pos).second];
std::string ns = re_detail::to_narrow(s, *pcdv);
for(i = 0; i < re_classes_max; ++i)
{
if(ns == re_char_class_names[i])
return re_char_class_id[i];
}
return 0;
}
bool BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::lookup_collatename(std::basic_string<wchar_t>& s, const wchar_t* first, const wchar_t* last)const
{
BOOST_RE_GUARD_STACK
std::wstring name(first, last);
std::map<std::wstring, std::wstring>::const_iterator pos = pmd->collating_elements.find(name);
if(pos != pmd->collating_elements.end())
{
s = (*pos).second;
return true;
}
std::string ns = re_detail::to_narrow(name, *pcdv);
std::string ns2;
bool result = re_detail::re_lookup_def_collate_name(ns2, ns.c_str());
s = re_detail::to_wide(ns2, *pcdv);
return result;
}
std::string BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::error_string(unsigned id)const
{
if((id <= boost::REG_E_UNKNOWN) && (pmd->error_strings[id].size()))
return pmd->error_strings[id];
return boost::re_detail::re_default_error_messages[id];
}
cpp_regex_traits<wchar_t>::cpp_regex_traits()
{
pmd = new re_detail::message_data<wchar_t>(locale_inst, std::string(regex_message_cat));
psyntax = pmd->syntax_;
#ifndef BOOST_NO_EXCEPTIONS
try{
#endif
lower_map = new wchar_t[char_set_size];
BOOST_REGEX_NOEH_ASSERT(lower_map)
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
delete pmd;
throw;
}
#endif
for(unsigned int i = 0; i < char_set_size; ++i)
lower_map[i] = static_cast<wchar_t>(i);
pctype = &BOOST_USE_FACET(std::ctype<wchar_t>, locale_inst);
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
pcollate = &BOOST_USE_FACET(std::collate<wchar_t>, locale_inst);
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_t;
pcdv = &BOOST_USE_FACET(cvt_t, locale_inst);
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
}
cpp_regex_traits<wchar_t>::~cpp_regex_traits()
{
delete pmd;
delete[] lower_map;
}
cpp_regex_traits<wchar_t>::locale_type BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::imbue(locale_type l)
{
locale_type old_l(locale_inst);
locale_inst = l;
re_detail::message_data<wchar_t>* npmd = new re_detail::message_data<wchar_t>(locale_inst, std::string(regex_message_cat));
delete pmd;
pmd = npmd;
psyntax = pmd->syntax_;
for(unsigned int i = 0; i < char_set_size; ++i)
lower_map[i] = static_cast<wchar_t>(i);
pctype = &BOOST_USE_FACET(std::ctype<wchar_t>, locale_inst);
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
pcollate = &BOOST_USE_FACET(std::collate<wchar_t>, locale_inst);
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_t;
pcdv = &BOOST_USE_FACET(cvt_t, locale_inst);
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
return old_l;
}
std::size_t BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::strwiden(wchar_t *s1, std::size_t len, const char *s2)const
{
std::string s(s2);
std::wstring ws = re_detail::to_wide(s2, *pcdv);
if(len > ws.size())
std::wcscpy(s1, ws.c_str());
return ws.size()+1;
}
void cpp_regex_traits<wchar_t>::swap(cpp_regex_traits<wchar_t>& that)
{
std::swap(locale_inst, that.locale_inst); // this one must go first
std::swap(pmd, that.pmd);
std::swap(psyntax, that.psyntax);
std::swap(lower_map, that.lower_map);
std::swap(pctype, that.pctype);
std::swap(pcollate, that.pcollate);
std::swap(pcdv, that.pcdv);
std::swap(sort_type, that.sort_type);
std::swap(sort_delim, that.sort_delim);
}
#endif // BOOST_NO_WREGEX
} // namespace boost
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -