1 #include "yaml-cpp03/conversion.h"
2 #include <algorithm>
3 
4 ////////////////////////////////////////////////////////////////
5 // Specializations for converting a string to specific types
6 
7 namespace
8 {
9 	// we're not gonna mess with the mess that is all the isupper/etc. functions
IsLower(char ch)10 	bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
IsUpper(char ch)11 	bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
ToLower(char ch)12 	char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
13 
tolower(const std::string & str)14 	std::string tolower(const std::string& str)
15 	{
16 		std::string s(str);
17 		std::transform(s.begin(), s.end(), s.begin(), ToLower);
18 		return s;
19 	}
20 
21 	template <typename T>
IsEntirely(const std::string & str,T func)22 	bool IsEntirely(const std::string& str, T func)
23 	{
24 		for(std::size_t i=0;i<str.size();i++)
25 			if(!func(str[i]))
26 				return false;
27 
28 		return true;
29 	}
30 
31 	// IsFlexibleCase
32 	// . Returns true if 'str' is:
33 	//   . UPPERCASE
34 	//   . lowercase
35 	//   . Capitalized
IsFlexibleCase(const std::string & str)36 	bool IsFlexibleCase(const std::string& str)
37 	{
38 		if(str.empty())
39 			return true;
40 
41 		if(IsEntirely(str, IsLower))
42 			return true;
43 
44 		bool firstcaps = IsUpper(str[0]);
45 		std::string rest = str.substr(1);
46 		return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
47 	}
48 }
49 
50 namespace YAML
51 {
Convert(const std::string & input,bool & b)52 	bool Convert(const std::string& input, bool& b)
53 	{
54 		// we can't use iostream bool extraction operators as they don't
55 		// recognize all possible values in the table below (taken from
56 		// http://yaml.org/type/bool.html)
57 		static const struct {
58 			std::string truename, falsename;
59 		} names[] = {
60 			{ "y", "n" },
61 			{ "yes", "no" },
62 			{ "true", "false" },
63 			{ "on", "off" },
64 		};
65 
66 		if(!IsFlexibleCase(input))
67 			return false;
68 
69 		for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
70 			if(names[i].truename == tolower(input)) {
71 				b = true;
72 				return true;
73 			}
74 
75 			if(names[i].falsename == tolower(input)) {
76 				b = false;
77 				return true;
78 			}
79 		}
80 
81 		return false;
82 	}
83 
Convert(const std::string & input,_Null &)84 	bool Convert(const std::string& input, _Null& /*output*/)
85 	{
86 		return input.empty() || input == "~" || input == "null" || input == "Null" || input == "NULL";
87 	}
88 }
89 
90