diff --git a/Makefile b/Makefile index 34b1096131d88b..4d0eebfb7d1489 100644 --- a/Makefile +++ b/Makefile @@ -802,8 +802,8 @@ save-load-state: examples/save-load-state/save-load-state.cpp ggml.o llama.o $(C $(CXX) $(CXXFLAGS) -c $< -o $(call GET_OBJ_FILE, $<) $(CXX) $(CXXFLAGS) $(filter-out %.h $<,$^) $(call GET_OBJ_FILE, $<) -o $@ $(LDFLAGS) -server: examples/server/server.cpp examples/server/utils.hpp examples/server/python-parser.hpp examples/server/function-call-str.hpp examples/server/tree_sitter/libtree-sitter.a examples/server/httplib.h common/json.hpp examples/server/index.html.hpp examples/server/index.js.hpp examples/server/completion.js.hpp examples/server/json-schema-to-grammar.mjs.hpp common/stb_image.h ggml.o llama.o func_scanner.o func_parser.o $(COMMON_DEPS) grammar-parser.o $(OBJS) - $(CXX) $(CXXFLAGS) -c $< -I examples/server/tree_sitter -o $(call GET_OBJ_FILE, $<) +server: examples/server/server.cpp examples/server/utils.hpp examples/server/python-parser.hpp examples/server/yaml-parser.hpp examples/server/function-call.hpp examples/server/tree_sitter/libtree-sitter.a examples/server/yaml-cpp/libyaml-cpp.a examples/server/httplib.h common/json.hpp examples/server/index.html.hpp examples/server/index.js.hpp examples/server/completion.js.hpp examples/server/json-schema-to-grammar.mjs.hpp common/stb_image.h ggml.o llama.o func_scanner.o func_parser.o $(COMMON_DEPS) grammar-parser.o $(OBJS) + $(CXX) $(CXXFLAGS) -c $< -I examples/server/tree_sitter -I examples/server/yaml-cpp -o $(call GET_OBJ_FILE, $<) $(CXX) $(CXXFLAGS) $(filter-out %.h %.hpp $<,$^) $(call GET_OBJ_FILE, $<) -Iexamples/server -o $@ $(LDFLAGS) $(LWINSOCK2) # Portable equivalent of `cd examples/server/public && xxd -i $(notdir $<) ../$(notdir $<).hpp`: diff --git a/examples/server/function-call-str.hpp b/examples/server/function-call-str.hpp deleted file mode 100644 index 317c5adeb11900..00000000000000 --- a/examples/server/function-call-str.hpp +++ /dev/null @@ -1,348 +0,0 @@ -#include -#include "json.hpp" -#include -#include - -using json = nlohmann::ordered_json; -using namespace std; - -// Utility functions -static string join(const vector& vec, const string& delimiter) { - string result; - for (size_t i = 0; i < vec.size(); i++) { - result += vec[i]; - if (i < vec.size() - 1) { - result += delimiter; - } - } - return result; -} - -static string capitalize(const string& str) { - string capitalized = str; - if (!capitalized.empty()) { - capitalized[0] = toupper(capitalized[0]); - for (size_t i = 1; i < capitalized.length(); i++) { - capitalized[i] = tolower(capitalized[i]); - } - } - return capitalized; -} - -static string json_schema_to_typescript_type(const json& schema, const string& param_name, string& enum_comment, string& integer_comment, string& description_comment); - -static pair generate_typescript_interface(const json& schema, const string& interface_name); - -static string generate_typescript_function(const json& function_schema); - -// Main functions -static string json_schema_to_typescript_type(const json& schema, const string& param_name, string& enum_comment, string& integer_comment, string& description_comment) { - string ts_type = "any"; // Default type - enum_comment = ""; - integer_comment = ""; - description_comment = ""; - - if (schema.contains("type")) { - string json_type = schema["type"]; - if (json_type == "array") { - string item_type = "any"; - if (schema.contains("items")) { - item_type = json_schema_to_typescript_type(schema["items"], param_name, enum_comment, integer_comment, description_comment); - } - ts_type = item_type + "[]"; - } else if (json_type == "number") { - ts_type = "number"; - } else if (json_type == "integer") { - ts_type = "number"; - integer_comment = " * @param " + param_name + " - Integer"; - } else if (json_type == "object") { - auto [interface_type, _] = generate_typescript_interface(schema, param_name); - ts_type = interface_type; - } else if (json_type == "boolean") { - ts_type = "boolean"; - } else if (json_type == "null") { - ts_type = "null"; - } else if (json_type == "string") { - ts_type = "string"; - } - } - - if (schema.contains("enum")) { - vector enum_values; - for (const auto& val : schema["enum"]) { - enum_values.push_back("\"" + val.get() + "\""); - } - enum_comment = " * @enum " + param_name + " - Possible values: " + join(enum_values, ", "); - ts_type = "string"; - } - if (schema.contains("description")) { - description_comment = " * @param " + param_name + " - " + schema["description"].get(); - } - - return ts_type; -} - -static pair generate_typescript_interface(const json& schema, const string& interface_name) { - json properties = schema.contains("properties") && !schema["properties"].is_null() - ? schema["properties"] - : json::object(); - vector required = schema.value("required", vector()); - - vector interface_body; - vector descriptions; - for (auto& [prop_name, prop_schema] : properties.items()) { - string enum_comment, integer_comment, description_comment; - string prop_type = json_schema_to_typescript_type(prop_schema, prop_name, enum_comment, integer_comment, description_comment); - bool is_optional = find(required.begin(), required.end(), prop_name) == required.end(); - interface_body.push_back(" " + prop_name + (is_optional ? "?" : "") + ": " + prop_type + ";"); - if (!description_comment.empty()) { - descriptions.push_back(description_comment); - } - if (!enum_comment.empty()) { - descriptions.push_back(enum_comment); - } - if (!integer_comment.empty()) { - descriptions.push_back(integer_comment); - } - } - - string comments = join(descriptions, "\n"); - string interface_definition = "interface " + interface_name + " {\n" + join(interface_body, "\n") + "\n}"; - return {interface_definition, comments}; -} - - -bool starts_with(const std::string& fullString, const std::string& prefix) { - return fullString.find(prefix) == 0; -} - -static string generate_typescript_function(const json& function_schema) { - string func_name = function_schema["name"]; - string description = function_schema.value("description", ""); - json parameters_schema = function_schema.contains("parameters") && !function_schema["parameters"].is_null() - ? function_schema["parameters"] - : json::object(); - vector required_params = parameters_schema.value("required", vector()); - - vector args_list; - vector comments_list; - vector interfaces; - - if (parameters_schema.contains("properties") && parameters_schema["properties"].is_object()){ - for (auto& [param_name, param_schema] : parameters_schema["properties"].items()) { - string enum_comment, integer_comment, description_comment; - string ts_type = json_schema_to_typescript_type(param_schema, param_name, enum_comment, integer_comment, description_comment); - if (starts_with(ts_type, "interface")) { - auto [interface_definition, nested_comments] = generate_typescript_interface(param_schema, func_name + "_" + capitalize(param_name) + "Params"); - interfaces.push_back(interface_definition); - comments_list.push_back(nested_comments); - ts_type = func_name + "_" + capitalize(param_name) + "Params"; - } else { - if (!description_comment.empty()) { - comments_list.push_back(description_comment); - } - if (!enum_comment.empty()) { - comments_list.push_back(enum_comment); - } - if (!integer_comment.empty()) { - comments_list.push_back(integer_comment); - } - } - bool is_optional = find(required_params.begin(), required_params.end(), param_name) == required_params.end(); - args_list.push_back(param_name + (is_optional ? "?" : "") + ": " + ts_type); - } - } - - - string args_str = join(args_list, ", "); - string comments_str = join(comments_list, "\n"); - string interfaces_str = join(interfaces, "\n\n"); - - string description_comment = (!description.empty()) ? " * " + description + "\n" : ""; - string typescript_func_declaration = - "/**\n" + - description_comment + - (comments_str.empty() ? "" : (comments_str + "\n")) + - " */\n" + - (interfaces_str.empty() ? "" : (interfaces_str + "\n\n")) + - "function " + func_name + "(" + args_str + "): any {};"; - - return typescript_func_declaration; -} - - - -string rubra_format_typescript_function_call_str(const std::vector &functions, json &tool_name_map) { - std::string final_str = "You have access to the following tools:\n"; - std::vector function_definitions; - for (auto& function : functions) { - // If function is directly the object or nested under "function" - json spec = function.contains("function") ? function["function"] : function; - - // Making a modifiable copy of spec - json spec_copy = spec; - - std::string func_name = spec_copy.value("name", ""); - - if (func_name.find('-') != std::string::npos) { - const std::string origin_func_name = func_name; - std::replace(func_name.begin(), func_name.end(), '-', '_'); // replace "-" with "_" because - is invalid in typescript function name - tool_name_map[func_name] = origin_func_name; - spec_copy["name"] = func_name; // Modify the name in the copied json object - } - - string res_string = generate_typescript_function(spec_copy); // generate TypeScript function - function_definitions.push_back(res_string); - } - - - for (const auto& def : function_definitions) { - final_str += def + "\n\n"; - } - final_str += "Use the following format if using a tool:\n<>[toolname1(arg1=value1, arg2=value2, ...), toolname2(arg1=value1, arg2=value2, ...)]\nYou can choose to respond with 1 or more tool calls at once, or with a chat message back to the user. Only make tool calls once you have all the details to fill in the required params. Feel free to ask the user for more info when appropriate. Any tool call you make must match the name of a function(s) provided above."; - return final_str; - -} - - - -std::string default_tool_formatter(const std::vector& tools) { - std::string toolText = ""; - std::vector toolNames; - for (const auto& tool : tools) { - json function = tool["function"]; - std::string name = function["name"]; - std::string description = function["description"]; - json parameters = function["parameters"]["properties"]; - - toolText += "> Tool Name: " + name + "\nTool Description: " + description + "\nTool Args:\n"; - for (auto& [key, value] : parameters.items()) { - std::string paramType = value["type"]; - std::string paramDesc = value.value("description", ""); - bool required = function["parameters"]["required"].contains(key); - std::string enumValues = ""; - - if (value.contains("enum")) { - enumValues = ", should be one of ["; - for (const auto& enumValue : value["enum"]) { - enumValues += enumValue.get() + ", "; - } - enumValues.pop_back(); // Remove last comma - enumValues.pop_back(); // Remove last space - enumValues += "]"; - } - - toolText += " - " + key + " (" + paramType + (required ? ", required" : "") + "): " + paramDesc + enumValues + "\n"; - } - - toolNames.push_back(name); - } - - std::string toolNamesString = ""; - for (const auto& toolName : toolNames) { - if (!toolNamesString.empty()) { - toolNamesString += ", "; - } - toolNamesString += toolName; - } - - std::string formattedPrompt = "You have access to the following tools:\n" + toolText + - "Use the following format if using a tool:\n" + - "Action: tool name (one of [" + toolNamesString + "]).\n" + - "Action Input: {'arg1':'value1', 'arg2':'value2', ...}\n"; - return formattedPrompt; -} - - -std::string rubra_format_python_function_call_str(const std::vector & functions, json & tool_name_map) { - std::string final_str = "You have access to the following tools:\n"; - printf("rubra_format_function_call_str parsing...\n"); - json type_mapping = { - {"string", "str"}, - {"integer", "int"}, - {"number", "float"}, - {"float", "float"}, - {"object", "Dict[str, Any]"}, - {"array", "List"}, - {"boolean", "bool"}, - {"null", "None"} - }; - std::vector function_definitions; - for (const auto & function : functions) { - const auto &spec = function.contains("function") ? function["function"] : function; - std::string func_name = spec.value("name", ""); - if (func_name.find('-') != std::string::npos) { - const std::string origin_func_name = func_name; - std::replace(func_name.begin(), func_name.end(), '-', '_'); // replace "-" with "_" because - is invalid in python func name - tool_name_map[func_name] = origin_func_name; - } - const std::string description = spec.contains("description") ? spec["description"].get() : ""; - const auto& parameters = spec.contains("parameters") && spec["parameters"].contains("properties")? spec["parameters"].value("properties", json({})) : json({}); - const auto& required_params = spec.contains("parameters") && spec["parameters"].contains("properties")? spec["parameters"].value("required", std::vector()) : std::vector(); - - std::vector func_args; - for (auto it = parameters.begin(); it != parameters.end(); ++it) { - const std::string param = it.key(); - const json& details = it.value(); - std::string json_type = details["type"].get(); - std::string python_type = type_mapping.value(json_type, "Any"); - // TODO: handle the case array: should provide more details about type, such as List[str] - if (details.contains("enum")) { - python_type = "str"; - } - std::string arg_str = param + ": " + python_type; - if (find(required_params.begin(), required_params.end(), param) == required_params.end()) { - arg_str += " = None"; - } - func_args.push_back(arg_str); - } - std::string func_args_str; - for (const auto& arg : func_args) { - if (!func_args_str.empty()) func_args_str += ", "; - func_args_str += arg; - } - - // Generating Python-like docstring - std::string docstring = " \"\"\"\n " + description + "\n\n"; - for (auto it = parameters.begin(); it != parameters.end(); ++it) { - const std::string param = it.key(); - const json& details = it.value(); - const std::string& required_text = find(required_params.begin(), required_params.end(), param) != required_params.end() ? "" : "(Optional)"; - std::string param_description = ""; - if (details.count("description") > 0) { - param_description = details["description"]; // Assuming the description is the first element - } - if (details.count("enum") > 0) { - std::string enum_values; - for (const std::string val : details["enum"]) { - if (!enum_values.empty()) { - enum_values += " or "; - } - enum_values = enum_values+ "\"" + val + "\""; - } - if (details["enum"].size() == 1) { - param_description += " Only Acceptable value is: " + enum_values; - } else { - param_description += " Only Acceptable values are: " + enum_values; - } - } - if (param_description.empty()) { - param_description = "No description provided."; - } - docstring += " :param " + param + ": " + param_description + " " + required_text + "\n"; - std::string param_type = details["type"].get(); - docstring += " :type " + param + ": " + type_mapping.value(param_type, "Any") + "\n"; - } - docstring += " \"\"\"\n"; - - // Keeping the function definition in Python format - std::string function_definition = "def " + func_name + "(" + func_args_str + "):\n" + docstring; - function_definitions.push_back(function_definition); - } - - for (const auto& def : function_definitions) { - final_str += def + "\n"; - } - final_str += "Use the following format if using tools:\n<>[toolname1(arg1=value1, arg2=value2, ...), toolname2(arg1=value1, arg2=value2, ...)]"; - return final_str; -} diff --git a/examples/server/function-call.hpp b/examples/server/function-call.hpp new file mode 100644 index 00000000000000..f8925907e6c1f7 --- /dev/null +++ b/examples/server/function-call.hpp @@ -0,0 +1,695 @@ +#include +#include "json.hpp" +#include +#include +#include + +using json = nlohmann::ordered_json; +using namespace std; + + +namespace YAML { + template<> + struct convert { + static Node encode(const json& rhs) { + Node node; + switch (rhs.type()) { + case json::value_t::object: + for (const auto& item : rhs.items()) { + node[item.key()] = encode(item.value()); + } + break; + case json::value_t::array: + for (const auto& item : rhs) { + node.push_back(encode(item)); + } + break; + case json::value_t::string: + node = rhs.get(); + break; + case json::value_t::boolean: + node = rhs.get(); + break; + case json::value_t::number_integer: + node = rhs.get(); + break; + case json::value_t::number_unsigned: + node = rhs.get(); + break; + case json::value_t::number_float: + node = rhs.get(); + break; + case json::value_t::null: + break; + default: + throw std::runtime_error("Unsupported JSON type."); + } + return node; + } + }; +} + + +// Utility functions +static string join(const vector& vec, const string& delimiter) { + string result; + for (size_t i = 0; i < vec.size(); i++) { + result += vec[i]; + if (i < vec.size() - 1) { + result += delimiter; + } + } + return result; +} + +static string capitalize(const string& str) { + string capitalized = str; + if (!capitalized.empty()) { + capitalized[0] = toupper(capitalized[0]); + for (size_t i = 1; i < capitalized.length(); i++) { + capitalized[i] = tolower(capitalized[i]); + } + } + return capitalized; +} + +static string json_schema_to_typescript_type(const json& schema, const string& param_name, string& enum_comment, string& integer_comment, string& description_comment); + +static pair generate_typescript_interface(const json& schema, const string& interface_name); + +static string generate_typescript_function(const json& function_schema); + +// Main functions +static string json_schema_to_typescript_type(const json& schema, const string& param_name, string& enum_comment, string& integer_comment, string& description_comment) { + string ts_type = "any"; // Default type + enum_comment = ""; + integer_comment = ""; + description_comment = ""; + + if (schema.contains("type")) { + string json_type = schema["type"]; + if (json_type == "array") { + string item_type = "any"; + if (schema.contains("items")) { + item_type = json_schema_to_typescript_type(schema["items"], param_name, enum_comment, integer_comment, description_comment); + } + ts_type = item_type + "[]"; + } else if (json_type == "number") { + ts_type = "number"; + } else if (json_type == "integer") { + ts_type = "number"; + integer_comment = " * @param " + param_name + " - Integer"; + } else if (json_type == "object") { + auto [interface_type, _] = generate_typescript_interface(schema, param_name); + ts_type = interface_type; + } else if (json_type == "boolean") { + ts_type = "boolean"; + } else if (json_type == "null") { + ts_type = "null"; + } else if (json_type == "string") { + ts_type = "string"; + } + } + + if (schema.contains("enum")) { + vector enum_values; + for (const auto& val : schema["enum"]) { + enum_values.push_back("\"" + val.get() + "\""); + } + enum_comment = " * @enum " + param_name + " - Possible values: " + join(enum_values, ", "); + ts_type = "string"; + } + if (schema.contains("description")) { + description_comment = " * @param " + param_name + " - " + schema["description"].get(); + } + + return ts_type; +} + +static pair generate_typescript_interface(const json& schema, const string& interface_name) { + json properties = schema.contains("properties") && !schema["properties"].is_null() + ? schema["properties"] + : json::object(); + vector required = schema.value("required", vector()); + + vector interface_body; + vector descriptions; + for (auto& [prop_name, prop_schema] : properties.items()) { + string enum_comment, integer_comment, description_comment; + string prop_type = json_schema_to_typescript_type(prop_schema, prop_name, enum_comment, integer_comment, description_comment); + bool is_optional = find(required.begin(), required.end(), prop_name) == required.end(); + interface_body.push_back(" " + prop_name + (is_optional ? "?" : "") + ": " + prop_type + ";"); + if (!description_comment.empty()) { + descriptions.push_back(description_comment); + } + if (!enum_comment.empty()) { + descriptions.push_back(enum_comment); + } + if (!integer_comment.empty()) { + descriptions.push_back(integer_comment); + } + } + + string comments = join(descriptions, "\n"); + string interface_definition = "interface " + interface_name + " {\n" + join(interface_body, "\n") + "\n}"; + return {interface_definition, comments}; +} + + +bool starts_with(const std::string& fullString, const std::string& prefix) { + return fullString.find(prefix) == 0; +} + +static string generate_typescript_function(const json& function_schema) { + string func_name = function_schema["name"]; + string description = function_schema.value("description", ""); + json parameters_schema = function_schema.contains("parameters") && !function_schema["parameters"].is_null() + ? function_schema["parameters"] + : json::object(); + vector required_params = parameters_schema.value("required", vector()); + + vector args_list; + vector comments_list; + vector interfaces; + + if (parameters_schema.contains("properties") && parameters_schema["properties"].is_object()){ + for (auto& [param_name, param_schema] : parameters_schema["properties"].items()) { + string enum_comment, integer_comment, description_comment; + string ts_type = json_schema_to_typescript_type(param_schema, param_name, enum_comment, integer_comment, description_comment); + if (starts_with(ts_type, "interface")) { + auto [interface_definition, nested_comments] = generate_typescript_interface(param_schema, func_name + "_" + capitalize(param_name) + "Params"); + interfaces.push_back(interface_definition); + comments_list.push_back(nested_comments); + ts_type = func_name + "_" + capitalize(param_name) + "Params"; + } else { + if (!description_comment.empty()) { + comments_list.push_back(description_comment); + } + if (!enum_comment.empty()) { + comments_list.push_back(enum_comment); + } + if (!integer_comment.empty()) { + comments_list.push_back(integer_comment); + } + } + bool is_optional = find(required_params.begin(), required_params.end(), param_name) == required_params.end(); + args_list.push_back(param_name + (is_optional ? "?" : "") + ": " + ts_type); + } + } + + + string args_str = join(args_list, ", "); + string comments_str = join(comments_list, "\n"); + string interfaces_str = join(interfaces, "\n\n"); + + string description_comment = (!description.empty()) ? " * " + description + "\n" : ""; + string typescript_func_declaration = + "/**\n" + + description_comment + + (comments_str.empty() ? "" : (comments_str + "\n")) + + " */\n" + + (interfaces_str.empty() ? "" : (interfaces_str + "\n\n")) + + "function " + func_name + "(" + args_str + "): any {};"; + + return typescript_func_declaration; +} + + + +string rubra_format_typescript_function_call_str(const std::vector &functions, json &tool_name_map) { + std::string final_str = "You have access to the following tools:\n"; + std::vector function_definitions; + for (auto& function : functions) { + // If function is directly the object or nested under "function" + json spec = function.contains("function") ? function["function"] : function; + + // Making a modifiable copy of spec + json spec_copy = spec; + + std::string func_name = spec_copy.value("name", ""); + + if (func_name.find('-') != std::string::npos) { + const std::string origin_func_name = func_name; + std::replace(func_name.begin(), func_name.end(), '-', '_'); // replace "-" with "_" because - is invalid in typescript function name + tool_name_map[func_name] = origin_func_name; + spec_copy["name"] = func_name; // Modify the name in the copied json object + } + + string res_string = generate_typescript_function(spec_copy); // generate TypeScript function + function_definitions.push_back(res_string); + } + + + for (const auto& def : function_definitions) { + final_str += def + "\n\n"; + } + final_str += "Use the following format if using a tool:\n<>[toolname1(arg1=value1, arg2=value2, ...), toolname2(arg1=value1, arg2=value2, ...)]\nYou can choose to respond with 1 or more tool calls at once, or with a chat message back to the user. Only make tool calls once you have all the details to fill in the required params. Feel free to ask the user for more info when appropriate. Any tool call you make must match the name of a function(s) provided above."; + return final_str; + +} + + + +std::string default_tool_formatter(const std::vector& tools) { + std::string toolText = ""; + std::vector toolNames; + for (const auto& tool : tools) { + json function = tool["function"]; + std::string name = function["name"]; + std::string description = function["description"]; + json parameters = function["parameters"]["properties"]; + + toolText += "> Tool Name: " + name + "\nTool Description: " + description + "\nTool Args:\n"; + for (auto& [key, value] : parameters.items()) { + std::string paramType = value["type"]; + std::string paramDesc = value.value("description", ""); + bool required = function["parameters"]["required"].contains(key); + std::string enumValues = ""; + + if (value.contains("enum")) { + enumValues = ", should be one of ["; + for (const auto& enumValue : value["enum"]) { + enumValues += enumValue.get() + ", "; + } + enumValues.pop_back(); // Remove last comma + enumValues.pop_back(); // Remove last space + enumValues += "]"; + } + + toolText += " - " + key + " (" + paramType + (required ? ", required" : "") + "): " + paramDesc + enumValues + "\n"; + } + + toolNames.push_back(name); + } + + std::string toolNamesString = ""; + for (const auto& toolName : toolNames) { + if (!toolNamesString.empty()) { + toolNamesString += ", "; + } + toolNamesString += toolName; + } + + std::string formattedPrompt = "You have access to the following tools:\n" + toolText + + "Use the following format if using a tool:\n" + + "Action: tool name (one of [" + toolNamesString + "]).\n" + + "Action Input: {'arg1':'value1', 'arg2':'value2', ...}\n"; + return formattedPrompt; +} + + +std::string rubra_format_python_function_call_str(const std::vector & functions, json & tool_name_map) { + std::string final_str = "You have access to the following tools:\n"; + printf("rubra_format_function_call_str parsing...\n"); + json type_mapping = { + {"string", "str"}, + {"integer", "int"}, + {"number", "float"}, + {"float", "float"}, + {"object", "Dict[str, Any]"}, + {"array", "List"}, + {"boolean", "bool"}, + {"null", "None"} + }; + std::vector function_definitions; + for (const auto & function : functions) { + const auto &spec = function.contains("function") ? function["function"] : function; + std::string func_name = spec.value("name", ""); + if (func_name.find('-') != std::string::npos) { + const std::string origin_func_name = func_name; + std::replace(func_name.begin(), func_name.end(), '-', '_'); // replace "-" with "_" because - is invalid in python func name + tool_name_map[func_name] = origin_func_name; + } + const std::string description = spec.contains("description") ? spec["description"].get() : ""; + const auto& parameters = spec.contains("parameters") && spec["parameters"].contains("properties")? spec["parameters"].value("properties", json({})) : json({}); + const auto& required_params = spec.contains("parameters") && spec["parameters"].contains("properties")? spec["parameters"].value("required", std::vector()) : std::vector(); + + std::vector func_args; + for (auto it = parameters.begin(); it != parameters.end(); ++it) { + const std::string param = it.key(); + const json& details = it.value(); + std::string json_type = details["type"].get(); + std::string python_type = type_mapping.value(json_type, "Any"); + // TODO: handle the case array: should provide more details about type, such as List[str] + if (details.contains("enum")) { + python_type = "str"; + } + std::string arg_str = param + ": " + python_type; + if (find(required_params.begin(), required_params.end(), param) == required_params.end()) { + arg_str += " = None"; + } + func_args.push_back(arg_str); + } + std::string func_args_str; + for (const auto& arg : func_args) { + if (!func_args_str.empty()) func_args_str += ", "; + func_args_str += arg; + } + + // Generating Python-like docstring + std::string docstring = " \"\"\"\n " + description + "\n\n"; + for (auto it = parameters.begin(); it != parameters.end(); ++it) { + const std::string param = it.key(); + const json& details = it.value(); + const std::string& required_text = find(required_params.begin(), required_params.end(), param) != required_params.end() ? "" : "(Optional)"; + std::string param_description = ""; + if (details.count("description") > 0) { + param_description = details["description"]; // Assuming the description is the first element + } + if (details.count("enum") > 0) { + std::string enum_values; + for (const std::string val : details["enum"]) { + if (!enum_values.empty()) { + enum_values += " or "; + } + enum_values = enum_values+ "\"" + val + "\""; + } + if (details["enum"].size() == 1) { + param_description += " Only Acceptable value is: " + enum_values; + } else { + param_description += " Only Acceptable values are: " + enum_values; + } + } + if (param_description.empty()) { + param_description = "No description provided."; + } + docstring += " :param " + param + ": " + param_description + " " + required_text + "\n"; + std::string param_type = details["type"].get(); + docstring += " :type " + param + ": " + type_mapping.value(param_type, "Any") + "\n"; + } + docstring += " \"\"\"\n"; + + // Keeping the function definition in Python format + std::string function_definition = "def " + func_name + "(" + func_args_str + "):\n" + docstring; + function_definitions.push_back(function_definition); + } + + for (const auto& def : function_definitions) { + final_str += def + "\n"; + } + final_str += "Use the following format if using tools:\n<>[toolname1(arg1=value1, arg2=value2, ...), toolname2(arg1=value1, arg2=value2, ...)]"; + return final_str; +} + + + +/////json to yaml +static YAML::Node process_parameter(const string& name, const json& details, bool is_required); +static YAML::Node process_object(const json& obj_data); + +static YAML::Node process_parameter_from_list(const json& param) { + return process_parameter(param["name"], param, param.contains("required")); +} + +static YAML::Node function_json_to_yaml(const json& json_data) { + YAML::Node formatted_data; + formatted_data["functionName"] = json_data.value("name", ""); + + if (!json_data.value("description", "").empty()) { + formatted_data["description"] = json_data.value("description", ""); + } + + if (json_data.contains("parameters") && !json_data["parameters"].is_null()) { + auto& parameters = json_data["parameters"]; + if (parameters.is_object()) { + formatted_data["parameters"] = process_object(parameters); + } else if (parameters.is_array()) { + for (const auto& param : parameters) { + formatted_data["parameters"].push_back(process_parameter_from_list(param)); + } + } else { + cerr << "Unexpected type for parameters: " << parameters.type_name() << endl; + } + } + + return formatted_data; + +} + +static YAML::Node process_object(const json& obj_data) { + YAML::Node param_list; + json properties = obj_data.contains("properties") && !obj_data["properties"].is_null() + ? obj_data["properties"] + : json::object(); + json required = obj_data.value("required", json::array()); + + if (properties.contains("required") && required.empty()) { + required = properties["required"]; + properties.erase("required"); + } + + for (auto& [name, details] : properties.items()) { + bool is_required = find(required.begin(), required.end(), name) != required.end(); + auto param_info = process_parameter(name, details, is_required); + if (!param_info.IsNull()) { + param_list.push_back(param_info); + } + } + + if (obj_data.contains("additionalProperties")) { + YAML::Node additional_properties; + additional_properties["additionalProperties"] = obj_data.value("additionalProperties", ""); + param_list.push_back(additional_properties); + } + + return param_list; +} + +static YAML::Node process_parameter(const string& name, const json& details, bool is_required) { + YAML::Node param_info; + if (!details.is_object()) { + cerr << "Invalid parameter details for '" << name << "'. Expected a dictionary, got " << details.type_name() << ". Details: " << details << endl; + return param_info; + } + + param_info["name"] = name; + param_info["type"] = details.value("type", ""); + + if (!details.value("description", "").empty()) { + param_info["description"] = details.value("description", ""); + } + + if (is_required) { + param_info["required"] = true; + } + + if (details.contains("enum")) { + param_info["enum"] = details["enum"].get>(); + } + + + for (const auto& key : { "format", "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "minLength", "maxLength", "pattern", "default"}) { + if (details.contains(key)) { + param_info[key] = details[key].dump().c_str(); + } + } + + if (details.contains("properties")) { + param_info["properties"] = process_object(details); + } + + if (details.contains("additionalProperties")) { + param_info["additionalProperties"] = details.value("additionalProperties", ""); + } + + if (details.value("type", "") == "array" && details.contains("items")) { + if (details["items"].contains("properties")) { + param_info["items"] = process_object(details["items"]); + } else { + param_info["items"]["type"] = details["items"].value("type", "object"); + } + } + + return param_info; +} + + +static string rubra_format_yaml_function_call_str(const std::vector &functions) { + std::string final_str = "You have access to the following tools/functions:\n"; + std::vector function_definitions; + // int index = 0; + for (auto& function : functions) { + // If function is directly the object or nested under "function" + json spec = function.contains("function") ? function["function"] : function; + + // Making a modifiable copy of spec + json spec_copy = spec; + + YAML::Node node = function_json_to_yaml(spec_copy); + // node["id"] = index; + // index++; + YAML::Emitter out; + out << node; + string res_string = string(out.c_str()); + function_definitions.push_back(res_string); + } + + + for (const auto& def : function_definitions) { + final_str += def + "\n\n"; + } + final_str += "Respond directly to user queries with accurate and relevant information first. If the user's question directly implies the need for a specific tool or additional data that a tool can provide, then consider using the appropriate tool. You can only use the tools detailed above, do NOT make any tools up.To effectively utilize these tools, follow these YAML formatting guidelines for calling functions:\nSingle Function Call Example:\n- functionCall: \n arguments:\n : \n : \n ...\n\nMultiple Function Calls in Sequence Example:\n- functionCall: \n arguments:\n : \n ...\n- functionCall: \n arguments:\n : \n ...\n\nPlease ensure each function call is correctly formatted in YAML. Always ensure tool use is essential and directly applicable to what the user has asked for. Do not suggest tool use unless it clearly adds value to the response or if the user specifically requests it.If the user's intent is unclear or if the question could have multiple interpretations, clarify the user's needs before providing a response or using any tools. Focus on engaging meaningfully and precisely with the user’s requests."; + return final_str; + +} + + + +static string construct_python_tool_call_str(const json & tool_calls, nlohmann::ordered_map & func_observation_map){ + std::string tool_call_str = ""; + for (const auto & tool_call : tool_calls) { + std::string func_str = ""; + func_observation_map[tool_call["id"].get()] = ""; // initialize with empty value and later should be updated with the actual value from "tool_call" role message + json args = json::parse(tool_call["function"]["arguments"].get()); // TODO: catch the exceptions + for (auto& arg : args.items()) { + if (func_str != "") { + func_str += ", "; + } + func_str += arg.key() + "=" + arg.value().dump(); + } + func_str = tool_call["function"]["name"].get() + "(" + func_str + ")"; + if (tool_call_str != "") { + tool_call_str += ", "; + } + tool_call_str += func_str; + } + tool_call_str = std::string("<>") + "[" + tool_call_str + "]"; + return tool_call_str; +} + + +static string construct_yaml_tool_call_str(const json & tool_calls, nlohmann::ordered_map & func_observation_map){ + YAML::Node tool_node; + for (const auto & tool_call : tool_calls) { + + func_observation_map[tool_call["id"].get()] = ""; // initialize with empty value and later should be updated with the actual value from "tool_call" role message + YAML::Node func_node; + func_node["functionCall"] = tool_call["function"]["name"].get(); + json args = json::parse(tool_call["function"]["arguments"].get()); + func_node["arguments"] = YAML::convert::encode(args); + + tool_node.push_back(func_node); + // std::string func_str = "- functionCall: " + tool_call["function"]["name"].get() + "\n arguments:\n"; + + // json args = json::parse(tool_call["function"]["arguments"].get()); // TODO: catch the exceptions + // for (auto& arg : args.items()) { + + // func_str += " " + arg.key() + ": " + arg.value().dump() + "\n"; + // } + // tool_call_str += func_str; + + } + YAML::Emitter out; + out << tool_node; + string tool_string = string(out.c_str()); + string tool_call_str = std::string("<>") + tool_string; + return tool_call_str; +} + + + +const vector expand_messages(const json & body, json &tool_name_map) { + string function_str = ""; + if (body.contains("tools") && !body["tools"].empty()) { + // function_str = default_tool_formatter(body["tool"]); + // function_str = rubra_format_typescript_function_call_str(body["tools"], tool_name_map); + function_str = rubra_format_yaml_function_call_str(body["tools"]); + } + // If 'tool' is not set or empty, check 'functions' + else if (body.contains("functions") && !body["functions"].empty()) { + // function_str = default_tool_formatter(body["functions"]); + // function_str = rubra_format_typescript_function_call_str(body["functions"], tool_name_map); + function_str = rubra_format_yaml_function_call_str(body["functions"]); + } + + if (function_str != "") { + printf("\n=============Formatting function call Input from OPENAI format...============\n"); + const std::vector expanded_messages = [&]() { + std::vector temp_vec; + nlohmann::ordered_map func_observation_map; + for (size_t i = 0; i < body["messages"].size(); ++i) { + printf("-=-=-=-=-=--=-=------\nworking on message %s\n=----=--=--=-=--=-=\n", body["messages"].dump().c_str()); + if (body["messages"][i]["role"] != "tool" and func_observation_map.size() > 0) { + // insert the observation from the tool call before the next message + std::string observation_str = ""; + for (const auto& [key, value] : func_observation_map) { + if (observation_str != "") { + observation_str += ", "; + } + observation_str += value; + } + observation_str = std::string("<>") + "[" + observation_str + "]"; + json observation_call; + observation_call["role"] = "observation"; + observation_call["content"] = observation_str; + temp_vec.push_back(observation_call); + func_observation_map.clear(); + } + + if (i == 0){ + if (body["messages"][0]["role"] == "system") { + std::string old_content = body["messages"][0]["content"]; + json function_call; + function_call["role"] = "system"; + function_call["content"] = old_content + "\n" + function_str; + temp_vec.push_back(function_call); + } + else { // insert a system message of tool definition before the first message + json function_call; + function_call["role"] = "system"; + function_call["content"] = "You are a helpful assistant.\n" + function_str; + temp_vec.push_back(function_call); + temp_vec.push_back(body["messages"][0]); + } + } + // else if (body["messages"][i]["role"] == "assistant" and (body["messages"][i]["content"].is_null() or body["messages"][i]["content"]=="") and !body["messages"][i]["tool_calls"].is_null() and !body["messages"][i]["tool_calls"].empty()){ + else if (body["messages"][i]["role"] == "assistant" and body["messages"][i].contains("tool_calls")){ + // convert OpenAI function call format to Rubra format + // string tool_call_str = construct_python_tool_call_str(body["messages"][i]["tool_calls"], func_observation_map); + string tool_call_str = construct_yaml_tool_call_str(body["messages"][i]["tool_calls"], func_observation_map); + json function_call; + function_call["role"] = "function"; + function_call["content"] = tool_call_str; + temp_vec.push_back(function_call); + } + else if (body["messages"][i]["role"] == "tool") { + std::string tool_call_id = body["messages"][i]["tool_call_id"].get(); + if (func_observation_map.find(tool_call_id) != func_observation_map.end()) { + func_observation_map[tool_call_id] = body["messages"][i]["content"].get(); + } else { + printf("Tool call id not found in the map : %s", tool_call_id.c_str()); + // TODO: the input is not valid in this case, should return an error + } + + } + else { + temp_vec.push_back(body["messages"][i]); + } + + } + if (func_observation_map.size() > 0) { + // insert the observation from the tool call before the next message + std::string observation_str = ""; + for (const auto& [key, value] : func_observation_map) { + if (observation_str != "") { + observation_str += ", "; + } + observation_str += value; + } + observation_str = std::string("<>") + "[" + observation_str + "]"; + json observation_call; + observation_call["role"] = "observation"; + observation_call["content"] = observation_str; + temp_vec.push_back(observation_call); + func_observation_map.clear(); + } + return temp_vec; + }(); + printf("==================END of InPut================\n\n"); + return expanded_messages; + } + else { + return body["messages"]; + } + +} diff --git a/examples/server/python-parser.hpp b/examples/server/python-parser.hpp index e5edf6f4a0e478..ccba1be4970c46 100644 --- a/examples/server/python-parser.hpp +++ b/examples/server/python-parser.hpp @@ -104,7 +104,7 @@ static void parseFunctionCalls(const TSNode& node, std::vector& calls, con } } -static std::vector parsePythonFunctionCalls(std::string source_string, json tool_name_map) { +std::vector parsePythonFunctionCalls(std::string source_string, json tool_name_map) { // Parse Python function calls from the source code and return a JSON array std::vector calls; std::string delimiter = "<>"; diff --git a/examples/server/utils.hpp b/examples/server/utils.hpp index e28cd660885d52..171ec9d38e95ae 100644 --- a/examples/server/utils.hpp +++ b/examples/server/utils.hpp @@ -5,7 +5,8 @@ #include "json.hpp" #include "python-parser.hpp" -#include "function-call-str.hpp" +#include "function-call.hpp" +#include "yaml-parser.hpp" #include #include @@ -357,135 +358,11 @@ static json oaicompat_completion_params_parse( llama_params["__oaicompat"] = true; - std::string function_str = ""; + json tool_name_map; - if (body.contains("tools") && !body["tools"].empty()) { - // function_str = default_tool_formatter(body["tool"]); - function_str = rubra_format_typescript_function_call_str(body["tools"], tool_name_map); - } - // If 'tool' is not set or empty, check 'functions' - else if (body.contains("functions") && !body["functions"].empty()) { - // function_str = default_tool_formatter(body["functions"]); - function_str = rubra_format_typescript_function_call_str(body["functions"], tool_name_map); - } - printf("\n=============Formatting Input from OPENAI format...============\n"); - if (function_str != "") { - const std::vector expand_messages = [&]() { - // std::vector temp_vec = body["messages"]; - // if (body["messages"][0]["role"] == "system") { - // std::string old_content = temp_vec[0]["content"]; - // temp_vec[0]["content"] = old_content + "\n" + function_str; - // } - // else { - // json function_call; - // function_call["role"] = "system"; - // function_call["content"] = "You are a helpful assistant.\n" + function_str; - // temp_vec.push_back(function_call); - // } - std::vector temp_vec; - nlohmann::ordered_map func_observation_map; - for (size_t i = 0; i < body["messages"].size(); ++i) { - - if (body["messages"][i]["role"] != "tool" and func_observation_map.size() > 0) { - // insert the observation from the tool call before the next message - std::string observation_str = ""; - for (const auto& [key, value] : func_observation_map) { - if (observation_str != "") { - observation_str += ", "; - } - observation_str += value; - } - observation_str = std::string("<>") + "[" + observation_str + "]"; - json observation_call; - observation_call["role"] = "observation"; - observation_call["content"] = observation_str; - temp_vec.push_back(observation_call); - func_observation_map.clear(); - } - - if (i == 0){ - if (body["messages"][0]["role"] == "system") { - std::string old_content = body["messages"][0]["content"]; - json function_call; - function_call["role"] = "system"; - function_call["content"] = old_content + "\n" + function_str; - temp_vec.push_back(function_call); - } - else { // insert a system message of tool definition before the first message - json function_call; - function_call["role"] = "system"; - function_call["content"] = "You are a helpful assistant.\n" + function_str; - temp_vec.push_back(function_call); - temp_vec.push_back(body["messages"][0]); - } - } - // else if (body["messages"][i]["role"] == "assistant" and (body["messages"][i]["content"].is_null() or body["messages"][i]["content"]=="") and !body["messages"][i]["tool_calls"].is_null() and !body["messages"][i]["tool_calls"].empty()){ - else if (body["messages"][i]["role"] == "assistant" and body["messages"][i].contains("tool_calls")){ - // convert OpenAI function call format to Rubra format - std::string tool_call_str = ""; - for (const auto & tool_call : body["messages"][i]["tool_calls"]) { - std::string func_str = ""; - func_observation_map[tool_call["id"].get()] = ""; // initialize with empty value and later should be updated with the actual value from "tool_call" role message - json args = json::parse(tool_call["function"]["arguments"].get()); // TODO: catch the exceptions - for (auto& arg : args.items()) { - if (func_str != "") { - func_str += ", "; - } - func_str += arg.key() + "=" + arg.value().dump(); - } - func_str = tool_call["function"]["name"].get() + "(" + func_str + ")"; - if (tool_call_str != "") { - tool_call_str += ", "; - } - tool_call_str += func_str; - } - tool_call_str = std::string("<>") + "[" + tool_call_str + "]"; - - json function_call; - function_call["role"] = "function"; - function_call["content"] = tool_call_str; - temp_vec.push_back(function_call); - } - else if (body["messages"][i]["role"] == "tool") { - std::string tool_call_id = body["messages"][i]["tool_call_id"].get(); - if (func_observation_map.find(tool_call_id) != func_observation_map.end()) { - func_observation_map[tool_call_id] = body["messages"][i]["content"].get(); - } else { - LOG_ERROR("Tool call id not found in the map", {{"tool_call_id", tool_call_id}}); - // TODO: the input is not valid in this case, should return an error - } - - } - else { - temp_vec.push_back(body["messages"][i]); - } - - } - if (func_observation_map.size() > 0) { - // insert the observation from the tool call before the next message - std::string observation_str = ""; - for (const auto& [key, value] : func_observation_map) { - if (observation_str != "") { - observation_str += ", "; - } - observation_str += value; - } - observation_str = std::string("<>") + "[" + observation_str + "]"; - json observation_call; - observation_call["role"] = "observation"; - observation_call["content"] = observation_str; - temp_vec.push_back(observation_call); - func_observation_map.clear(); - } - return temp_vec; - }(); - llama_params["prompt"] = format_chat(model, chat_template, expand_messages); - } - else { - llama_params["prompt"] = format_chat(model, chat_template, body["messages"]); - } - printf("==================END of InPut================\n\n"); + const std::vector expanded_messages = expand_messages(body, tool_name_map); + llama_params["prompt"] = format_chat(model, chat_template, expanded_messages); llama_params["tool_name_map"] = tool_name_map; // Map OpenAI parameters to llama.cpp parameters @@ -569,7 +446,8 @@ static json format_final_response_oaicompat(const json & request, json result, c int num_prompt_tokens = json_value(result, "tokens_evaluated", 0); std::string content = json_value(result, "content", std::string("")); - std::vector parsed_content = parsePythonFunctionCalls(content, request["tool_name_map"]); + // std::vector parsed_content = parsePythonFunctionCalls(content, request["tool_name_map"]); + std::vector parsed_content = rubra_fc_yaml_tool_extractor(content); std::string finish_reason = "length"; if (stopped_word || stopped_eos) { @@ -651,7 +529,8 @@ static std::vector format_partial_response_oaicompat(json request ,json re bool stopped_limit = json_value(result, "stopped_limit", false); std::string content = json_value(result, "content", std::string("")); - std::vector parsed_content = parsePythonFunctionCalls(content, request["tool_name_map"]); + // std::vector parsed_content = parsePythonFunctionCalls(content, request["tool_name_map"]); + std::vector parsed_content = rubra_fc_yaml_tool_extractor(content); std::time_t t = std::time(0); if (!parsed_content.empty()) { std::vector res; diff --git a/examples/server/yaml-cpp/libyaml-cpp.a b/examples/server/yaml-cpp/libyaml-cpp.a new file mode 100644 index 00000000000000..cebf78357422b8 Binary files /dev/null and b/examples/server/yaml-cpp/libyaml-cpp.a differ diff --git a/examples/server/yaml-cpp/yaml-cpp/anchor.h b/examples/server/yaml-cpp/yaml-cpp/anchor.h new file mode 100644 index 00000000000000..f46d1d79dd8a14 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/anchor.h @@ -0,0 +1,17 @@ +#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +namespace YAML { +using anchor_t = std::size_t; +const anchor_t NullAnchor = 0; +} + +#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/binary.h b/examples/server/yaml-cpp/yaml-cpp/binary.h new file mode 100644 index 00000000000000..1050dae98c3cc9 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/binary.h @@ -0,0 +1,71 @@ +#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +YAML_CPP_API std::string EncodeBase64(const unsigned char *data, + std::size_t size); +YAML_CPP_API std::vector DecodeBase64(const std::string &input); + +class YAML_CPP_API Binary { + public: + Binary(const unsigned char *data_, std::size_t size_) + : m_data{}, m_unownedData(data_), m_unownedSize(size_) {} + Binary() : Binary(nullptr, 0) {} + Binary(const Binary &) = default; + Binary(Binary &&) = default; + Binary &operator=(const Binary &) = default; + Binary &operator=(Binary &&) = default; + + bool owned() const { return !m_unownedData; } + std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } + const unsigned char *data() const { + return owned() ? &m_data[0] : m_unownedData; + } + + void swap(std::vector &rhs) { + if (m_unownedData) { + m_data.swap(rhs); + rhs.clear(); + rhs.resize(m_unownedSize); + std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); + m_unownedData = nullptr; + m_unownedSize = 0; + } else { + m_data.swap(rhs); + } + } + + bool operator==(const Binary &rhs) const { + const std::size_t s = size(); + if (s != rhs.size()) + return false; + const unsigned char *d1 = data(); + const unsigned char *d2 = rhs.data(); + for (std::size_t i = 0; i < s; i++) { + if (*d1++ != *d2++) + return false; + } + return true; + } + + bool operator!=(const Binary &rhs) const { return !(*this == rhs); } + + private: + std::vector m_data; + const unsigned char *m_unownedData; + std::size_t m_unownedSize; +}; +} // namespace YAML + +#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/contrib/anchordict.h b/examples/server/yaml-cpp/yaml-cpp/contrib/anchordict.h new file mode 100644 index 00000000000000..1b7809b875f6ea --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/contrib/anchordict.h @@ -0,0 +1,40 @@ +#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "../anchor.h" + +namespace YAML { +/** + * An object that stores and retrieves values correlating to {@link anchor_t} + * values. + * + *

Efficient implementation that can make assumptions about how + * {@code anchor_t} values are assigned by the {@link Parser} class. + */ +template +class AnchorDict { + public: + AnchorDict() : m_data{} {} + void Register(anchor_t anchor, T value) { + if (anchor > m_data.size()) { + m_data.resize(anchor); + } + m_data[anchor - 1] = value; + } + + T Get(anchor_t anchor) const { return m_data[anchor - 1]; } + + private: + std::vector m_data; +}; +} // namespace YAML + +#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/contrib/graphbuilder.h b/examples/server/yaml-cpp/yaml-cpp/contrib/graphbuilder.h new file mode 100644 index 00000000000000..dbffd921e6691b --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/contrib/graphbuilder.h @@ -0,0 +1,149 @@ +#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/mark.h" +#include + +namespace YAML { +class Parser; + +// GraphBuilderInterface +// . Abstraction of node creation +// . pParentNode is always nullptr or the return value of one of the NewXXX() +// functions. +class GraphBuilderInterface { + public: + virtual ~GraphBuilderInterface() = 0; + + // Create and return a new node with a null value. + virtual void *NewNull(const Mark &mark, void *pParentNode) = 0; + + // Create and return a new node with the given tag and value. + virtual void *NewScalar(const Mark &mark, const std::string &tag, + void *pParentNode, const std::string &value) = 0; + + // Create and return a new sequence node + virtual void *NewSequence(const Mark &mark, const std::string &tag, + void *pParentNode) = 0; + + // Add pNode to pSequence. pNode was created with one of the NewXxx() + // functions and pSequence with NewSequence(). + virtual void AppendToSequence(void *pSequence, void *pNode) = 0; + + // Note that no moew entries will be added to pSequence + virtual void SequenceComplete(void *pSequence) { (void)pSequence; } + + // Create and return a new map node + virtual void *NewMap(const Mark &mark, const std::string &tag, + void *pParentNode) = 0; + + // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode + // were created with one of the NewXxx() methods and pMap with NewMap(). + virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; + + // Note that no more assignments will be made in pMap + virtual void MapComplete(void *pMap) { (void)pMap; } + + // Return the node that should be used in place of an alias referencing + // pNode (pNode by default) + virtual void *AnchorReference(const Mark &mark, void *pNode) { + (void)mark; + return pNode; + } +}; + +// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines +// Node, Sequence, and Map types. Sequence and Map must derive from Node +// (unless Node is defined as void). Impl must also implement function with +// all of the same names as the virtual functions in GraphBuilderInterface +// -- including the ones with default implementations -- but with the +// prototypes changed to accept an explicit Node*, Sequence*, or Map* where +// appropriate. +template +class GraphBuilder : public GraphBuilderInterface { + public: + typedef typename Impl::Node Node; + typedef typename Impl::Sequence Sequence; + typedef typename Impl::Map Map; + + GraphBuilder(Impl &impl) : m_impl(impl) { + Map *pMap = nullptr; + Sequence *pSeq = nullptr; + Node *pNode = nullptr; + + // Type consistency checks + pNode = pMap; + pNode = pSeq; + } + + GraphBuilderInterface &AsBuilderInterface() { return *this; } + + virtual void *NewNull(const Mark &mark, void *pParentNode) { + return CheckType(m_impl.NewNull(mark, AsNode(pParentNode))); + } + + virtual void *NewScalar(const Mark &mark, const std::string &tag, + void *pParentNode, const std::string &value) { + return CheckType( + m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); + } + + virtual void *NewSequence(const Mark &mark, const std::string &tag, + void *pParentNode) { + return CheckType( + m_impl.NewSequence(mark, tag, AsNode(pParentNode))); + } + virtual void AppendToSequence(void *pSequence, void *pNode) { + m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); + } + virtual void SequenceComplete(void *pSequence) { + m_impl.SequenceComplete(AsSequence(pSequence)); + } + + virtual void *NewMap(const Mark &mark, const std::string &tag, + void *pParentNode) { + return CheckType(m_impl.NewMap(mark, tag, AsNode(pParentNode))); + } + virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { + m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); + } + virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); } + + virtual void *AnchorReference(const Mark &mark, void *pNode) { + return CheckType(m_impl.AnchorReference(mark, AsNode(pNode))); + } + + private: + Impl &m_impl; + + // Static check for pointer to T + template + static T *CheckType(U *p) { + return p; + } + + static Node *AsNode(void *pNode) { return static_cast(pNode); } + static Sequence *AsSequence(void *pSeq) { + return static_cast(pSeq); + } + static Map *AsMap(void *pMap) { return static_cast(pMap); } +}; + +void *BuildGraphOfNextDocument(Parser &parser, + GraphBuilderInterface &graphBuilder); + +template +typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) { + GraphBuilder graphBuilder(impl); + return static_cast( + BuildGraphOfNextDocument(parser, graphBuilder)); +} +} + +#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/depthguard.h b/examples/server/yaml-cpp/yaml-cpp/depthguard.h new file mode 100644 index 00000000000000..8ca61ac6ccc175 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/depthguard.h @@ -0,0 +1,77 @@ +#ifndef DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 +#define DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "exceptions.h" + +namespace YAML { + +/** + * @brief The DeepRecursion class + * An exception class which is thrown by DepthGuard. Ideally it should be + * a member of DepthGuard. However, DepthGuard is a templated class which means + * that any catch points would then need to know the template parameters. It is + * simpler for clients to not have to know at the catch point what was the + * maximum depth. + */ +class DeepRecursion : public ParserException { +public: + virtual ~DeepRecursion() = default; + + DeepRecursion(int depth, const Mark& mark_, const std::string& msg_); + + // Returns the recursion depth when the exception was thrown + int depth() const { + return m_depth; + } + +private: + int m_depth = 0; +}; + +/** + * @brief The DepthGuard class + * DepthGuard takes a reference to an integer. It increments the integer upon + * construction of DepthGuard and decrements the integer upon destruction. + * + * If the integer would be incremented past max_depth, then an exception is + * thrown. This is ideally geared toward guarding against deep recursion. + * + * @param max_depth + * compile-time configurable maximum depth. + */ +template +class DepthGuard final { +public: + DepthGuard(int & depth_, const Mark& mark_, const std::string& msg_) : m_depth(depth_) { + ++m_depth; + if ( max_depth <= m_depth ) { + throw DeepRecursion{m_depth, mark_, msg_}; + } + } + + DepthGuard(const DepthGuard & copy_ctor) = delete; + DepthGuard(DepthGuard && move_ctor) = delete; + DepthGuard & operator=(const DepthGuard & copy_assign) = delete; + DepthGuard & operator=(DepthGuard && move_assign) = delete; + + ~DepthGuard() { + --m_depth; + } + + int current_depth() const { + return m_depth; + } + +private: + int & m_depth; +}; + +} // namespace YAML + +#endif // DEPTH_GUARD_H_00000000000000000000000000000000000000000000000000000000 diff --git a/examples/server/yaml-cpp/yaml-cpp/dll.h b/examples/server/yaml-cpp/yaml-cpp/dll.h new file mode 100644 index 00000000000000..eabdda1d95cb07 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/dll.h @@ -0,0 +1,61 @@ +#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +// Definition YAML_CPP_STATIC_DEFINE using to building YAML-CPP as static +// library (definition created by CMake or defined manually) + +// Definition yaml_cpp_EXPORTS using to building YAML-CPP as dll/so library +// (definition created by CMake or defined manually) + +#ifdef YAML_CPP_STATIC_DEFINE +# define YAML_CPP_API +# define YAML_CPP_NO_EXPORT +#else +# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) +# ifndef YAML_CPP_API +# ifdef yaml_cpp_EXPORTS + /* We are building this library */ +# pragma message( "Defining YAML_CPP_API for DLL export" ) +# define YAML_CPP_API __declspec(dllexport) +# else + /* We are using this library */ +# pragma message( "Defining YAML_CPP_API for DLL import" ) +# define YAML_CPP_API __declspec(dllimport) +# endif +# endif +# ifndef YAML_CPP_NO_EXPORT +# define YAML_CPP_NO_EXPORT +# endif +# else /* No _MSC_VER */ +# ifndef YAML_CPP_API +# ifdef yaml_cpp_EXPORTS + /* We are building this library */ +# define YAML_CPP_API __attribute__((visibility("default"))) +# else + /* We are using this library */ +# define YAML_CPP_API __attribute__((visibility("default"))) +# endif +# endif +# ifndef YAML_CPP_NO_EXPORT +# define YAML_CPP_NO_EXPORT __attribute__((visibility("hidden"))) +# endif +# endif /* _MSC_VER */ +#endif /* YAML_CPP_STATIC_DEFINE */ + +#ifndef YAML_CPP_DEPRECATED +# ifdef _MSC_VER +# define YAML_CPP_DEPRECATED __declspec(deprecated) +# else +# define YAML_CPP_DEPRECATED __attribute__ ((__deprecated__)) +# endif +#endif + +#ifndef YAML_CPP_DEPRECATED_EXPORT +# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED +#endif + +#ifndef YAML_CPP_DEPRECATED_NO_EXPORT +# define YAML_CPP_DEPRECATED_NO_EXPORT YAML_CPP_NO_EXPORT YAML_CPP_DEPRECATED +#endif + +#endif /* DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 */ diff --git a/examples/server/yaml-cpp/yaml-cpp/emitfromevents.h b/examples/server/yaml-cpp/yaml-cpp/emitfromevents.h new file mode 100644 index 00000000000000..c00d26e74d0bcc --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/emitfromevents.h @@ -0,0 +1,58 @@ +#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/anchor.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/eventhandler.h" + +namespace YAML { +struct Mark; +} // namespace YAML + +namespace YAML { +class Emitter; + +class EmitFromEvents : public EventHandler { + public: + EmitFromEvents(Emitter& emitter); + ~EmitFromEvents() override = default; + + void OnDocumentStart(const Mark& mark) override; + void OnDocumentEnd() override; + + void OnNull(const Mark& mark, anchor_t anchor) override; + void OnAlias(const Mark& mark, anchor_t anchor) override; + void OnScalar(const Mark& mark, const std::string& tag, + anchor_t anchor, const std::string& value) override; + + void OnSequenceStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) override; + void OnSequenceEnd() override; + + void OnMapStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) override; + void OnMapEnd() override; + + private: + void BeginNode(); + void EmitProps(const std::string& tag, anchor_t anchor); + + private: + Emitter& m_emitter; + + struct State { + enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; + }; + std::stack m_stateStack; +}; +} + +#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/emitter.h b/examples/server/yaml-cpp/yaml-cpp/emitter.h new file mode 100644 index 00000000000000..210b1ec974420e --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/emitter.h @@ -0,0 +1,281 @@ +#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "yaml-cpp/binary.h" +#include "yaml-cpp/dll.h" +#include "yaml-cpp/emitterdef.h" +#include "yaml-cpp/emittermanip.h" +#include "yaml-cpp/null.h" +#include "yaml-cpp/ostream_wrapper.h" + +namespace YAML { +class Binary; +struct _Null; +} // namespace YAML + +namespace YAML { +class EmitterState; + +class YAML_CPP_API Emitter { + public: + Emitter(); + explicit Emitter(std::ostream& stream); + Emitter(const Emitter&) = delete; + Emitter& operator=(const Emitter&) = delete; + ~Emitter(); + + // output + const char* c_str() const; + std::size_t size() const; + + // state checking + bool good() const; + const std::string GetLastError() const; + + // global setters + bool SetOutputCharset(EMITTER_MANIP value); + bool SetStringFormat(EMITTER_MANIP value); + bool SetBoolFormat(EMITTER_MANIP value); + bool SetNullFormat(EMITTER_MANIP value); + bool SetIntBase(EMITTER_MANIP value); + bool SetSeqFormat(EMITTER_MANIP value); + bool SetMapFormat(EMITTER_MANIP value); + bool SetIndent(std::size_t n); + bool SetPreCommentIndent(std::size_t n); + bool SetPostCommentIndent(std::size_t n); + bool SetFloatPrecision(std::size_t n); + bool SetDoublePrecision(std::size_t n); + void RestoreGlobalModifiedSettings(); + + // local setters + Emitter& SetLocalValue(EMITTER_MANIP value); + Emitter& SetLocalIndent(const _Indent& indent); + Emitter& SetLocalPrecision(const _Precision& precision); + + // overloads of write + Emitter& Write(const std::string& str); + Emitter& Write(bool b); + Emitter& Write(char ch); + Emitter& Write(const _Alias& alias); + Emitter& Write(const _Anchor& anchor); + Emitter& Write(const _Tag& tag); + Emitter& Write(const _Comment& comment); + Emitter& Write(const _Null& n); + Emitter& Write(const Binary& binary); + + template + Emitter& WriteIntegralType(T value); + + template + Emitter& WriteStreamable(T value); + + private: + template + void SetStreamablePrecision(std::stringstream&) {} + std::size_t GetFloatPrecision() const; + std::size_t GetDoublePrecision() const; + + void PrepareIntegralStream(std::stringstream& stream) const; + void StartedScalar(); + + private: + void EmitBeginDoc(); + void EmitEndDoc(); + void EmitBeginSeq(); + void EmitEndSeq(); + void EmitBeginMap(); + void EmitEndMap(); + void EmitNewline(); + void EmitKindTag(); + void EmitTag(bool verbatim, const _Tag& tag); + + void PrepareNode(EmitterNodeType::value child); + void PrepareTopNode(EmitterNodeType::value child); + void FlowSeqPrepareNode(EmitterNodeType::value child); + void BlockSeqPrepareNode(EmitterNodeType::value child); + + void FlowMapPrepareNode(EmitterNodeType::value child); + + void FlowMapPrepareLongKey(EmitterNodeType::value child); + void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); + void FlowMapPrepareSimpleKey(EmitterNodeType::value child); + void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); + + void BlockMapPrepareNode(EmitterNodeType::value child); + + void BlockMapPrepareLongKey(EmitterNodeType::value child); + void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); + void BlockMapPrepareSimpleKey(EmitterNodeType::value child); + void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); + + void SpaceOrIndentTo(bool requireSpace, std::size_t indent); + + const char* ComputeFullBoolName(bool b) const; + const char* ComputeNullName() const; + bool CanEmitNewline() const; + + private: + std::unique_ptr m_pState; + ostream_wrapper m_stream; +}; + +template +inline Emitter& Emitter::WriteIntegralType(T value) { + if (!good()) + return *this; + + PrepareNode(EmitterNodeType::Scalar); + + std::stringstream stream; + PrepareIntegralStream(stream); + stream << value; + m_stream << stream.str(); + + StartedScalar(); + + return *this; +} + +template +inline Emitter& Emitter::WriteStreamable(T value) { + if (!good()) + return *this; + + PrepareNode(EmitterNodeType::Scalar); + + std::stringstream stream; + SetStreamablePrecision(stream); + + bool special = false; + if (std::is_floating_point::value) { + if ((std::numeric_limits::has_quiet_NaN || + std::numeric_limits::has_signaling_NaN) && + std::isnan(value)) { + special = true; + stream << ".nan"; + } else if (std::numeric_limits::has_infinity && std::isinf(value)) { + special = true; + if (std::signbit(value)) { + stream << "-.inf"; + } else { + stream << ".inf"; + } + } + } + + if (!special) { + stream << value; + } + m_stream << stream.str(); + + StartedScalar(); + + return *this; +} + +template <> +inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { + stream.precision(static_cast(GetFloatPrecision())); +} + +template <> +inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { + stream.precision(static_cast(GetDoublePrecision())); +} + +// overloads of insertion +inline Emitter& operator<<(Emitter& emitter, const std::string& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, bool v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, char v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned char v) { + return emitter.Write(static_cast(v)); +} +inline Emitter& operator<<(Emitter& emitter, const _Alias& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Tag& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Comment& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Null& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const Binary& b) { + return emitter.Write(b); +} + +inline Emitter& operator<<(Emitter& emitter, const char* v) { + return emitter.Write(std::string(v)); +} + +inline Emitter& operator<<(Emitter& emitter, int v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned int v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, short v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned short v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, long long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned long long v) { + return emitter.WriteIntegralType(v); +} + +inline Emitter& operator<<(Emitter& emitter, float v) { + return emitter.WriteStreamable(v); +} +inline Emitter& operator<<(Emitter& emitter, double v) { + return emitter.WriteStreamable(v); +} + +inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { + return emitter.SetLocalValue(value); +} + +inline Emitter& operator<<(Emitter& emitter, _Indent indent) { + return emitter.SetLocalIndent(indent); +} + +inline Emitter& operator<<(Emitter& emitter, _Precision precision) { + return emitter.SetLocalPrecision(precision); +} +} // namespace YAML + +#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/emitterdef.h b/examples/server/yaml-cpp/yaml-cpp/emitterdef.h new file mode 100644 index 00000000000000..0b426957fae276 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/emitterdef.h @@ -0,0 +1,16 @@ +#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct EmitterNodeType { + enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; +}; +} + +#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/emittermanip.h b/examples/server/yaml-cpp/yaml-cpp/emittermanip.h new file mode 100644 index 00000000000000..976d14950fc7a7 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/emittermanip.h @@ -0,0 +1,144 @@ +#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +namespace YAML { +enum EMITTER_MANIP { + // general manipulators + Auto, + TagByKind, + Newline, + + // output character set + EmitNonAscii, + EscapeNonAscii, + EscapeAsJson, + + // string manipulators + // Auto, // duplicate + SingleQuoted, + DoubleQuoted, + Literal, + + // null manipulators + LowerNull, + UpperNull, + CamelNull, + TildeNull, + + // bool manipulators + YesNoBool, // yes, no + TrueFalseBool, // true, false + OnOffBool, // on, off + UpperCase, // TRUE, N + LowerCase, // f, yes + CamelCase, // No, Off + LongBool, // yes, On + ShortBool, // y, t + + // int manipulators + Dec, + Hex, + Oct, + + // document manipulators + BeginDoc, + EndDoc, + + // sequence manipulators + BeginSeq, + EndSeq, + Flow, + Block, + + // map manipulators + BeginMap, + EndMap, + Key, + Value, + // Flow, // duplicate + // Block, // duplicate + // Auto, // duplicate + LongKey +}; + +struct _Indent { + _Indent(int value_) : value(value_) {} + int value; +}; + +inline _Indent Indent(int value) { return _Indent(value); } + +struct _Alias { + _Alias(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Alias Alias(const std::string& content) { return _Alias(content); } + +struct _Anchor { + _Anchor(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Anchor Anchor(const std::string& content) { return _Anchor(content); } + +struct _Tag { + struct Type { + enum value { Verbatim, PrimaryHandle, NamedHandle }; + }; + + explicit _Tag(const std::string& prefix_, const std::string& content_, + Type::value type_) + : prefix(prefix_), content(content_), type(type_) {} + std::string prefix; + std::string content; + Type::value type; +}; + +inline _Tag VerbatimTag(const std::string& content) { + return _Tag("", content, _Tag::Type::Verbatim); +} + +inline _Tag LocalTag(const std::string& content) { + return _Tag("", content, _Tag::Type::PrimaryHandle); +} + +inline _Tag LocalTag(const std::string& prefix, const std::string content) { + return _Tag(prefix, content, _Tag::Type::NamedHandle); +} + +inline _Tag SecondaryTag(const std::string& content) { + return _Tag("", content, _Tag::Type::NamedHandle); +} + +struct _Comment { + _Comment(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Comment Comment(const std::string& content) { return _Comment(content); } + +struct _Precision { + _Precision(int floatPrecision_, int doublePrecision_) + : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} + + int floatPrecision; + int doublePrecision; +}; + +inline _Precision FloatPrecision(int n) { return _Precision(n, -1); } + +inline _Precision DoublePrecision(int n) { return _Precision(-1, n); } + +inline _Precision Precision(int n) { return _Precision(n, n); } +} + +#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/emitterstyle.h b/examples/server/yaml-cpp/yaml-cpp/emitterstyle.h new file mode 100644 index 00000000000000..67bb3981b12cb2 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/emitterstyle.h @@ -0,0 +1,16 @@ +#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct EmitterStyle { + enum value { Default, Block, Flow }; +}; +} + +#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/eventhandler.h b/examples/server/yaml-cpp/yaml-cpp/eventhandler.h new file mode 100644 index 00000000000000..7242fe1f5ba9db --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/eventhandler.h @@ -0,0 +1,45 @@ +#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/anchor.h" +#include "yaml-cpp/emitterstyle.h" + +namespace YAML { +struct Mark; + +class EventHandler { + public: + virtual ~EventHandler() = default; + + virtual void OnDocumentStart(const Mark& mark) = 0; + virtual void OnDocumentEnd() = 0; + + virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; + virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0; + virtual void OnScalar(const Mark& mark, const std::string& tag, + anchor_t anchor, const std::string& value) = 0; + + virtual void OnSequenceStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) = 0; + virtual void OnSequenceEnd() = 0; + + virtual void OnMapStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) = 0; + virtual void OnMapEnd() = 0; + + virtual void OnAnchor(const Mark& /*mark*/, + const std::string& /*anchor_name*/) { + // empty default implementation for compatibility + } +}; +} // namespace YAML + +#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/exceptions.h b/examples/server/yaml-cpp/yaml-cpp/exceptions.h new file mode 100644 index 00000000000000..f6b2602ae1c313 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/exceptions.h @@ -0,0 +1,303 @@ +#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/mark.h" +#include "yaml-cpp/noexcept.h" +#include "yaml-cpp/traits.h" +#include +#include +#include + +namespace YAML { +// error messages +namespace ErrorMsg { +const char* const YAML_DIRECTIVE_ARGS = + "YAML directives must have exactly one argument"; +const char* const YAML_VERSION = "bad YAML version: "; +const char* const YAML_MAJOR_VERSION = "YAML major version too large"; +const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; +const char* const TAG_DIRECTIVE_ARGS = + "TAG directives must have exactly two arguments"; +const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; +const char* const CHAR_IN_TAG_HANDLE = + "illegal character found while scanning tag handle"; +const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; +const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; +const char* const END_OF_MAP = "end of map not found"; +const char* const END_OF_MAP_FLOW = "end of map flow not found"; +const char* const END_OF_SEQ = "end of sequence not found"; +const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; +const char* const MULTIPLE_TAGS = + "cannot assign multiple tags to the same node"; +const char* const MULTIPLE_ANCHORS = + "cannot assign multiple anchors to the same node"; +const char* const MULTIPLE_ALIASES = + "cannot assign multiple aliases to the same node"; +const char* const ALIAS_CONTENT = + "aliases can't have any content, *including* tags"; +const char* const INVALID_HEX = "bad character found while scanning hex number"; +const char* const INVALID_UNICODE = "invalid unicode: "; +const char* const INVALID_ESCAPE = "unknown escape character: "; +const char* const UNKNOWN_TOKEN = "unknown token"; +const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; +const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; +const char* const CHAR_IN_SCALAR = "illegal character in scalar"; +const char* const TAB_IN_INDENTATION = + "illegal tab when looking for indentation"; +const char* const FLOW_END = "illegal flow end"; +const char* const BLOCK_ENTRY = "illegal block entry"; +const char* const MAP_KEY = "illegal map key"; +const char* const MAP_VALUE = "illegal map value"; +const char* const ALIAS_NOT_FOUND = "alias not found after *"; +const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; +const char* const CHAR_IN_ALIAS = + "illegal character found while scanning alias"; +const char* const CHAR_IN_ANCHOR = + "illegal character found while scanning anchor"; +const char* const ZERO_INDENT_IN_BLOCK = + "cannot set zero indentation for a block scalar"; +const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; +const char* const AMBIGUOUS_ANCHOR = + "cannot assign the same alias to multiple nodes"; +const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined: "; + +const char* const INVALID_NODE = + "invalid node; this may result from using a map iterator as a sequence " + "iterator, or vice-versa"; +const char* const INVALID_SCALAR = "invalid scalar"; +const char* const KEY_NOT_FOUND = "key not found"; +const char* const BAD_CONVERSION = "bad conversion"; +const char* const BAD_DEREFERENCE = "bad dereference"; +const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; +const char* const BAD_PUSHBACK = "appending to a non-sequence"; +const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; + +const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; +const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; +const char* const UNEXPECTED_END_MAP = "unexpected end map token"; +const char* const SINGLE_QUOTED_CHAR = + "invalid character in single-quoted string"; +const char* const INVALID_ANCHOR = "invalid anchor"; +const char* const INVALID_ALIAS = "invalid alias"; +const char* const INVALID_TAG = "invalid tag"; +const char* const BAD_FILE = "bad file"; + +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T&, typename disable_if>::type* = 0) { + return KEY_NOT_FOUND; +} + +inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} + +inline const std::string KEY_NOT_FOUND_WITH_KEY(const char* key) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} + +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T& key, typename enable_if>::type* = 0) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} + +template +inline const std::string BAD_SUBSCRIPT_WITH_KEY( + const T&, typename disable_if>::type* = nullptr) { + return BAD_SUBSCRIPT; +} + +inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) { + std::stringstream stream; + stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; + return stream.str(); +} + +inline const std::string BAD_SUBSCRIPT_WITH_KEY(const char* key) { + std::stringstream stream; + stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; + return stream.str(); +} + +template +inline const std::string BAD_SUBSCRIPT_WITH_KEY( + const T& key, typename enable_if>::type* = nullptr) { + std::stringstream stream; + stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; + return stream.str(); +} + +inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) { + std::stringstream stream; + if (key.empty()) { + return INVALID_NODE; + } + stream << "invalid node; first invalid key: \"" << key << "\""; + return stream.str(); +} +} // namespace ErrorMsg + +class YAML_CPP_API Exception : public std::runtime_error { + public: + Exception(const Mark& mark_, const std::string& msg_) + : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} + ~Exception() YAML_CPP_NOEXCEPT override; + + Exception(const Exception&) = default; + + Mark mark; + std::string msg; + + private: + static const std::string build_what(const Mark& mark, + const std::string& msg) { + if (mark.is_null()) { + return msg; + } + + std::stringstream output; + output << "yaml-cpp: error at line " << mark.line + 1 << ", column " + << mark.column + 1 << ": " << msg; + return output.str(); + } +}; + +class YAML_CPP_API ParserException : public Exception { + public: + ParserException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} + ParserException(const ParserException&) = default; + ~ParserException() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API RepresentationException : public Exception { + public: + RepresentationException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} + RepresentationException(const RepresentationException&) = default; + ~RepresentationException() YAML_CPP_NOEXCEPT override; +}; + +// representation exceptions +class YAML_CPP_API InvalidScalar : public RepresentationException { + public: + InvalidScalar(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} + InvalidScalar(const InvalidScalar&) = default; + ~InvalidScalar() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API KeyNotFound : public RepresentationException { + public: + template + KeyNotFound(const Mark& mark_, const T& key_) + : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { + } + KeyNotFound(const KeyNotFound&) = default; + ~KeyNotFound() YAML_CPP_NOEXCEPT override; +}; + +template +class YAML_CPP_API TypedKeyNotFound : public KeyNotFound { + public: + TypedKeyNotFound(const Mark& mark_, const T& key_) + : KeyNotFound(mark_, key_), key(key_) {} + ~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default; + + T key; +}; + +template +inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, + const T& key) { + return TypedKeyNotFound(mark, key); +} + +class YAML_CPP_API InvalidNode : public RepresentationException { + public: + InvalidNode(const std::string& key) + : RepresentationException(Mark::null_mark(), + ErrorMsg::INVALID_NODE_WITH_KEY(key)) {} + InvalidNode(const InvalidNode&) = default; + ~InvalidNode() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API BadConversion : public RepresentationException { + public: + explicit BadConversion(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} + BadConversion(const BadConversion&) = default; + ~BadConversion() YAML_CPP_NOEXCEPT override; +}; + +template +class TypedBadConversion : public BadConversion { + public: + explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {} +}; + +class YAML_CPP_API BadDereference : public RepresentationException { + public: + BadDereference() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} + BadDereference(const BadDereference&) = default; + ~BadDereference() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API BadSubscript : public RepresentationException { + public: + template + BadSubscript(const Mark& mark_, const Key& key) + : RepresentationException(mark_, ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {} + BadSubscript(const BadSubscript&) = default; + ~BadSubscript() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API BadPushback : public RepresentationException { + public: + BadPushback() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} + BadPushback(const BadPushback&) = default; + ~BadPushback() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API BadInsert : public RepresentationException { + public: + BadInsert() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} + BadInsert(const BadInsert&) = default; + ~BadInsert() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API EmitterException : public Exception { + public: + EmitterException(const std::string& msg_) + : Exception(Mark::null_mark(), msg_) {} + EmitterException(const EmitterException&) = default; + ~EmitterException() YAML_CPP_NOEXCEPT override; +}; + +class YAML_CPP_API BadFile : public Exception { + public: + explicit BadFile(const std::string& filename) + : Exception(Mark::null_mark(), + std::string(ErrorMsg::BAD_FILE) + ": " + filename) {} + BadFile(const BadFile&) = default; + ~BadFile() YAML_CPP_NOEXCEPT override; +}; +} // namespace YAML + +#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/mark.h b/examples/server/yaml-cpp/yaml-cpp/mark.h new file mode 100644 index 00000000000000..bf94b4f41fc6c9 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/mark.h @@ -0,0 +1,29 @@ +#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" + +namespace YAML { +struct YAML_CPP_API Mark { + Mark() : pos(0), line(0), column(0) {} + + static const Mark null_mark() { return Mark(-1, -1, -1); } + + bool is_null() const { return pos == -1 && line == -1 && column == -1; } + + int pos; + int line, column; + + private: + Mark(int pos_, int line_, int column_) + : pos(pos_), line(line_), column(column_) {} +}; +} + +#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/convert.h b/examples/server/yaml-cpp/yaml-cpp/node/convert.h new file mode 100644 index 00000000000000..d49702f82a8477 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/convert.h @@ -0,0 +1,469 @@ +#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) +#include +#endif + +#include "yaml-cpp/binary.h" +#include "yaml-cpp/node/impl.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/type.h" +#include "yaml-cpp/null.h" + + +namespace YAML { +class Binary; +struct _Null; +template +struct convert; +} // namespace YAML + +namespace YAML { +namespace conversion { +inline bool IsInfinity(const std::string& input) { + return input == ".inf" || input == ".Inf" || input == ".INF" || + input == "+.inf" || input == "+.Inf" || input == "+.INF"; +} + +inline bool IsNegativeInfinity(const std::string& input) { + return input == "-.inf" || input == "-.Inf" || input == "-.INF"; +} + +inline bool IsNaN(const std::string& input) { + return input == ".nan" || input == ".NaN" || input == ".NAN"; +} +} + +// Node +template <> +struct convert { + static Node encode(const Node& rhs) { return rhs; } + + static bool decode(const Node& node, Node& rhs) { + rhs.reset(node); + return true; + } +}; + +// std::string +template <> +struct convert { + static Node encode(const std::string& rhs) { return Node(rhs); } + + static bool decode(const Node& node, std::string& rhs) { + if (!node.IsScalar()) + return false; + rhs = node.Scalar(); + return true; + } +}; + +// C-strings can only be encoded +template <> +struct convert { + static Node encode(const char* rhs) { return Node(rhs); } +}; + +template <> +struct convert { + static Node encode(const char* rhs) { return Node(rhs); } +}; + +template +struct convert { + static Node encode(const char* rhs) { return Node(rhs); } +}; + +#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) +template <> +struct convert { + static Node encode(std::string_view rhs) { return Node(std::string(rhs)); } + + static bool decode(const Node& node, std::string_view& rhs) { + if (!node.IsScalar()) + return false; + rhs = node.Scalar(); + return true; + } +}; +#endif + +template <> +struct convert<_Null> { + static Node encode(const _Null& /* rhs */) { return Node(); } + + static bool decode(const Node& node, _Null& /* rhs */) { + return node.IsNull(); + } +}; + +namespace conversion { +template +typename std::enable_if< std::is_floating_point::value, void>::type +inner_encode(const T& rhs, std::stringstream& stream){ + if (std::isnan(rhs)) { + stream << ".nan"; + } else if (std::isinf(rhs)) { + if (std::signbit(rhs)) { + stream << "-.inf"; + } else { + stream << ".inf"; + } + } else { + stream << rhs; + } +} + +template +typename std::enable_if::value, void>::type +inner_encode(const T& rhs, std::stringstream& stream){ + stream << rhs; +} + +template +typename std::enable_if<(std::is_same::value || + std::is_same::value), bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + int num; + if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { + if (num >= (std::numeric_limits::min)() && + num <= (std::numeric_limits::max)()) { + rhs = static_cast(num); + return true; + } + } + return false; +} + +template +typename std::enable_if::value || + std::is_same::value), bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { + return true; + } + return false; +} +} + +#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ + template <> \ + struct convert { \ + \ + static Node encode(const type& rhs) { \ + std::stringstream stream; \ + stream.precision(std::numeric_limits::max_digits10); \ + conversion::inner_encode(rhs, stream); \ + return Node(stream.str()); \ + } \ + \ + static bool decode(const Node& node, type& rhs) { \ + if (node.Type() != NodeType::Scalar) { \ + return false; \ + } \ + const std::string& input = node.Scalar(); \ + std::stringstream stream(input); \ + stream.unsetf(std::ios::dec); \ + if ((stream.peek() == '-') && std::is_unsigned::value) { \ + return false; \ + } \ + if (conversion::ConvertStreamTo(stream, rhs)) { \ + return true; \ + } \ + if (std::numeric_limits::has_infinity) { \ + if (conversion::IsInfinity(input)) { \ + rhs = std::numeric_limits::infinity(); \ + return true; \ + } else if (conversion::IsNegativeInfinity(input)) { \ + rhs = negative_op std::numeric_limits::infinity(); \ + return true; \ + } \ + } \ + \ + if (std::numeric_limits::has_quiet_NaN) { \ + if (conversion::IsNaN(input)) { \ + rhs = std::numeric_limits::quiet_NaN(); \ + return true; \ + } \ + } \ + \ + return false; \ + } \ + } + +#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, -) + +#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, +) + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); + +#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED +#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED +#undef YAML_DEFINE_CONVERT_STREAMABLE + +// bool +template <> +struct convert { + static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } + + YAML_CPP_API static bool decode(const Node& node, bool& rhs); +}; + +// std::map +template +struct convert> { + static Node encode(const std::map& rhs) { + Node node(NodeType::Map); + for (const auto& element : rhs) + node.force_insert(element.first, element.second); + return node; + } + + static bool decode(const Node& node, std::map& rhs) { + if (!node.IsMap()) + return false; + + rhs.clear(); + for (const auto& element : node) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[element.first.template as()] = element.second.template as(); +#else + rhs[element.first.as()] = element.second.as(); +#endif + return true; + } +}; + +// std::unordered_map +template +struct convert> { + static Node encode(const std::unordered_map& rhs) { + Node node(NodeType::Map); + for (const auto& element : rhs) + node.force_insert(element.first, element.second); + return node; + } + + static bool decode(const Node& node, std::unordered_map& rhs) { + if (!node.IsMap()) + return false; + + rhs.clear(); + for (const auto& element : node) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[element.first.template as()] = element.second.template as(); +#else + rhs[element.first.as()] = element.second.as(); +#endif + return true; + } +}; + +// std::vector +template +struct convert> { + static Node encode(const std::vector& rhs) { + Node node(NodeType::Sequence); + for (const auto& element : rhs) + node.push_back(element); + return node; + } + + static bool decode(const Node& node, std::vector& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const auto& element : node) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.push_back(element.template as()); +#else + rhs.push_back(element.as()); +#endif + return true; + } +}; + +// std::list +template +struct convert> { + static Node encode(const std::list& rhs) { + Node node(NodeType::Sequence); + for (const auto& element : rhs) + node.push_back(element); + return node; + } + + static bool decode(const Node& node, std::list& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const auto& element : node) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.push_back(element.template as()); +#else + rhs.push_back(element.as()); +#endif + return true; + } +}; + +// std::array +template +struct convert> { + static Node encode(const std::array& rhs) { + Node node(NodeType::Sequence); + for (const auto& element : rhs) { + node.push_back(element); + } + return node; + } + + static bool decode(const Node& node, std::array& rhs) { + if (!isNodeValid(node)) { + return false; + } + + for (auto i = 0u; i < node.size(); ++i) { +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[i] = node[i].template as(); +#else + rhs[i] = node[i].as(); +#endif + } + return true; + } + + private: + static bool isNodeValid(const Node& node) { + return node.IsSequence() && node.size() == N; + } +}; + + +// std::valarray +template +struct convert> { + static Node encode(const std::valarray& rhs) { + Node node(NodeType::Sequence); + for (const auto& element : rhs) { + node.push_back(element); + } + return node; + } + + static bool decode(const Node& node, std::valarray& rhs) { + if (!node.IsSequence()) { + return false; + } + + rhs.resize(node.size()); + for (auto i = 0u; i < node.size(); ++i) { +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[i] = node[i].template as(); +#else + rhs[i] = node[i].as(); +#endif + } + return true; + } +}; + + +// std::pair +template +struct convert> { + static Node encode(const std::pair& rhs) { + Node node(NodeType::Sequence); + node.push_back(rhs.first); + node.push_back(rhs.second); + return node; + } + + static bool decode(const Node& node, std::pair& rhs) { + if (!node.IsSequence()) + return false; + if (node.size() != 2) + return false; + +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.first = node[0].template as(); +#else + rhs.first = node[0].as(); +#endif +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.second = node[1].template as(); +#else + rhs.second = node[1].as(); +#endif + return true; + } +}; + +// binary +template <> +struct convert { + static Node encode(const Binary& rhs) { + return Node(EncodeBase64(rhs.data(), rhs.size())); + } + + static bool decode(const Node& node, Binary& rhs) { + if (!node.IsScalar()) + return false; + + std::vector data = DecodeBase64(node.Scalar()); + if (data.empty() && !node.Scalar().empty()) + return false; + + rhs.swap(data); + return true; + } +}; +} + +#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/impl.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/impl.h new file mode 100644 index 00000000000000..b38038dfd22520 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/impl.h @@ -0,0 +1,235 @@ +#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/node/detail/node_data.h" + +#include +#include + +namespace YAML { +namespace detail { +template +struct get_idx { + static node* get(const std::vector& /* sequence */, + const Key& /* key */, shared_memory_holder /* pMemory */) { + return nullptr; + } +}; + +template +struct get_idx::value && + !std::is_same::value>::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder /* pMemory */) { + return key < sequence.size() ? sequence[key] : nullptr; + } + + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined())) + return nullptr; + if (key == sequence.size()) + sequence.push_back(&pMemory->create_node()); + return sequence[key]; + } +}; + +template +struct get_idx::value>::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : nullptr; + } + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : nullptr; + } +}; + +template +struct remove_idx { + static bool remove(std::vector&, const Key&, std::size_t&) { + return false; + } +}; + +template +struct remove_idx< + Key, typename std::enable_if::value && + !std::is_same::value>::type> { + + static bool remove(std::vector& sequence, const Key& key, + std::size_t& seqSize) { + if (key >= sequence.size()) { + return false; + } else { + sequence.erase(sequence.begin() + key); + if (seqSize > key) { + --seqSize; + } + return true; + } + } +}; + +template +struct remove_idx::value>::type> { + + static bool remove(std::vector& sequence, const Key& key, + std::size_t& seqSize) { + return key >= 0 ? remove_idx::remove( + sequence, static_cast(key), seqSize) + : false; + } +}; + +template +inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { + T lhs; + if (convert::decode(Node(*this, pMemory), lhs)) { + return lhs == rhs; + } + return false; +} + +inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { + std::string lhs; + if (convert::decode(Node(*this, std::move(pMemory)), lhs)) { + return lhs == rhs; + } + return false; +} + +// indexing +template +inline node* node_data::get(const Key& key, + shared_memory_holder pMemory) const { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + return nullptr; + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) + return pNode; + return nullptr; + case NodeType::Scalar: + throw BadSubscript(m_mark, key); + } + + auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); + + return it != m_map.end() ? it->second : nullptr; +} + +template +inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) { + m_type = NodeType::Sequence; + return *pNode; + } + + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadSubscript(m_mark, key); + } + + auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); + + if (it != m_map.end()) { + return *it->second; + } + + node& k = convert_to_node(key, pMemory); + node& v = pMemory->create_node(); + insert_map_pair(k, v); + return v; +} + +template +inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { + if (m_type == NodeType::Sequence) { + return remove_idx::remove(m_sequence, key, m_seqSize); + } + + if (m_type == NodeType::Map) { + kv_pairs::iterator it = m_undefinedPairs.begin(); + while (it != m_undefinedPairs.end()) { + kv_pairs::iterator jt = std::next(it); + if (it->first->equals(key, pMemory)) { + m_undefinedPairs.erase(it); + } + it = jt; + } + + auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); + + if (iter != m_map.end()) { + m_map.erase(iter); + return true; + } + } + + return false; +} + +// map +template +inline void node_data::force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadInsert(); + } + + node& k = convert_to_node(key, pMemory); + node& v = convert_to_node(value, pMemory); + insert_map_pair(k, v); +} + +template +inline node& node_data::convert_to_node(const T& rhs, + shared_memory_holder pMemory) { + Node value = convert::encode(rhs); + value.EnsureNodeExists(); + pMemory->merge(*value.m_pMemory); + return *value.m_pNode; +} +} +} + +#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator.h new file mode 100644 index 00000000000000..997c69a14c5708 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator.h @@ -0,0 +1,96 @@ +#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/detail/node_iterator.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/ptr.h" +#include +#include + + +namespace YAML { +namespace detail { +struct iterator_value; + +template +class iterator_base { + + private: + template + friend class iterator_base; + struct enabler {}; + using base_type = node_iterator; + + struct proxy { + explicit proxy(const V& x) : m_ref(x) {} + V* operator->() { return std::addressof(m_ref); } + operator V*() { return std::addressof(m_ref); } + + V m_ref; + }; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = V; + using difference_type = std::ptrdiff_t; + using pointer = V*; + using reference = V; + + public: + iterator_base() : m_iterator(), m_pMemory() {} + explicit iterator_base(base_type rhs, shared_memory_holder pMemory) + : m_iterator(rhs), m_pMemory(pMemory) {} + + template + iterator_base(const iterator_base& rhs, + typename std::enable_if::value, + enabler>::type = enabler()) + : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {} + + iterator_base& operator++() { + ++m_iterator; + return *this; + } + + iterator_base operator++(int) { + iterator_base iterator_pre(*this); + ++(*this); + return iterator_pre; + } + + template + bool operator==(const iterator_base& rhs) const { + return m_iterator == rhs.m_iterator; + } + + template + bool operator!=(const iterator_base& rhs) const { + return m_iterator != rhs.m_iterator; + } + + value_type operator*() const { + const typename base_type::value_type& v = *m_iterator; + if (v.pNode) + return value_type(Node(*v, m_pMemory)); + if (v.first && v.second) + return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); + return value_type(); + } + + proxy operator->() const { return proxy(**this); } + + private: + base_type m_iterator; + shared_memory_holder m_pMemory; +}; +} // namespace detail +} // namespace YAML + +#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator_fwd.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator_fwd.h new file mode 100644 index 00000000000000..75c9de086c0572 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/iterator_fwd.h @@ -0,0 +1,27 @@ +#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include +#include +#include + +namespace YAML { + +namespace detail { +struct iterator_value; +template +class iterator_base; +} + +using iterator = detail::iterator_base; +using const_iterator = detail::iterator_base; +} + +#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/memory.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/memory.h new file mode 100644 index 00000000000000..e881545bf2f240 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/memory.h @@ -0,0 +1,47 @@ +#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/ptr.h" + +namespace YAML { +namespace detail { +class node; +} // namespace detail +} // namespace YAML + +namespace YAML { +namespace detail { +class YAML_CPP_API memory { + public: + memory() : m_nodes{} {} + node& create_node(); + void merge(const memory& rhs); + + private: + using Nodes = std::set; + Nodes m_nodes; +}; + +class YAML_CPP_API memory_holder { + public: + memory_holder() : m_pMemory(new memory) {} + + node& create_node() { return m_pMemory->create_node(); } + void merge(memory_holder& rhs); + + private: + shared_memory m_pMemory; +}; +} // namespace detail +} // namespace YAML + +#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/node.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/node.h new file mode 100644 index 00000000000000..acf60ffb6dff58 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/node.h @@ -0,0 +1,177 @@ +#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/node/detail/node_ref.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/type.h" +#include +#include + +namespace YAML { +namespace detail { +class node { + private: + struct less { + bool operator ()(const node* l, const node* r) const {return l->m_index < r->m_index;} + }; + + public: + node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {} + node(const node&) = delete; + node& operator=(const node&) = delete; + + bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } + const node_ref* ref() const { return m_pRef.get(); } + + bool is_defined() const { return m_pRef->is_defined(); } + const Mark& mark() const { return m_pRef->mark(); } + NodeType::value type() const { return m_pRef->type(); } + + const std::string& scalar() const { return m_pRef->scalar(); } + const std::string& tag() const { return m_pRef->tag(); } + EmitterStyle::value style() const { return m_pRef->style(); } + + template + bool equals(const T& rhs, shared_memory_holder pMemory); + bool equals(const char* rhs, shared_memory_holder pMemory); + + void mark_defined() { + if (is_defined()) + return; + + m_pRef->mark_defined(); + for (node* dependency : m_dependencies) + dependency->mark_defined(); + m_dependencies.clear(); + } + + void add_dependency(node& rhs) { + if (is_defined()) + rhs.mark_defined(); + else + m_dependencies.insert(&rhs); + } + + void set_ref(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef = rhs.m_pRef; + } + void set_data(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef->set_data(*rhs.m_pRef); + } + + void set_mark(const Mark& mark) { m_pRef->set_mark(mark); } + + void set_type(NodeType::value type) { + if (type != NodeType::Undefined) + mark_defined(); + m_pRef->set_type(type); + } + void set_null() { + mark_defined(); + m_pRef->set_null(); + } + void set_scalar(const std::string& scalar) { + mark_defined(); + m_pRef->set_scalar(scalar); + } + void set_tag(const std::string& tag) { + mark_defined(); + m_pRef->set_tag(tag); + } + + // style + void set_style(EmitterStyle::value style) { + mark_defined(); + m_pRef->set_style(style); + } + + // size/iterator + std::size_t size() const { return m_pRef->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pRef).begin(); + } + node_iterator begin() { return m_pRef->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pRef).end(); + } + node_iterator end() { return m_pRef->end(); } + + // sequence + void push_back(node& input, shared_memory_holder pMemory) { + m_pRef->push_back(input, pMemory); + input.add_dependency(*this); + m_index = m_amount.fetch_add(1); + } + void insert(node& key, node& value, shared_memory_holder pMemory) { + m_pRef->insert(key, value, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + } + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be nullptr (if there is no such + // key). + return static_cast(*m_pRef).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + value.add_dependency(*this); + return value; + } + template + bool remove(const Key& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + node* get(node& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be nullptr (if there is no such + // key). + return static_cast(*m_pRef).get(key, pMemory); + } + node& get(node& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + return value; + } + bool remove(node& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + m_pRef->force_insert(key, value, pMemory); + } + + private: + shared_node_ref m_pRef; + using nodes = std::set; + nodes m_dependencies; + size_t m_index; + static YAML_CPP_API std::atomic m_amount; +}; +} // namespace detail +} // namespace YAML + +#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/node_data.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_data.h new file mode 100644 index 00000000000000..07cf81aa099217 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_data.h @@ -0,0 +1,127 @@ +#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/detail/node_iterator.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/type.h" + +namespace YAML { +namespace detail { +class node; +} // namespace detail +} // namespace YAML + +namespace YAML { +namespace detail { +class YAML_CPP_API node_data { + public: + node_data(); + node_data(const node_data&) = delete; + node_data& operator=(const node_data&) = delete; + + void mark_defined(); + void set_mark(const Mark& mark); + void set_type(NodeType::value type); + void set_tag(const std::string& tag); + void set_null(); + void set_scalar(const std::string& scalar); + void set_style(EmitterStyle::value style); + + bool is_defined() const { return m_isDefined; } + const Mark& mark() const { return m_mark; } + NodeType::value type() const { + return m_isDefined ? m_type : NodeType::Undefined; + } + const std::string& scalar() const { return m_scalar; } + const std::string& tag() const { return m_tag; } + EmitterStyle::value style() const { return m_style; } + + // size/iterator + std::size_t size() const; + + const_node_iterator begin() const; + node_iterator begin(); + + const_node_iterator end() const; + node_iterator end(); + + // sequence + void push_back(node& node, const shared_memory_holder& pMemory); + void insert(node& key, node& value, const shared_memory_holder& pMemory); + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const; + template + node& get(const Key& key, shared_memory_holder pMemory); + template + bool remove(const Key& key, shared_memory_holder pMemory); + + node* get(node& key, const shared_memory_holder& pMemory) const; + node& get(node& key, const shared_memory_holder& pMemory); + bool remove(node& key, const shared_memory_holder& pMemory); + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory); + + public: + static const std::string& empty_scalar(); + + private: + void compute_seq_size() const; + void compute_map_size() const; + + void reset_sequence(); + void reset_map(); + + void insert_map_pair(node& key, node& value); + void convert_to_map(const shared_memory_holder& pMemory); + void convert_sequence_to_map(const shared_memory_holder& pMemory); + + template + static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); + + private: + bool m_isDefined; + Mark m_mark; + NodeType::value m_type; + std::string m_tag; + EmitterStyle::value m_style; + + // scalar + std::string m_scalar; + + // sequence + using node_seq = std::vector; + node_seq m_sequence; + + mutable std::size_t m_seqSize; + + // map + using node_map = std::vector>; + node_map m_map; + + using kv_pair = std::pair; + using kv_pairs = std::list; + mutable kv_pairs m_undefinedPairs; +}; +} +} + +#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/node_iterator.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_iterator.h new file mode 100644 index 00000000000000..49dcf958dbbddf --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_iterator.h @@ -0,0 +1,181 @@ +#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/ptr.h" +#include +#include +#include +#include +#include +#include + +namespace YAML { +namespace detail { +struct iterator_type { + enum value { NoneType, Sequence, Map }; +}; + +template +struct node_iterator_value : public std::pair { + using kv = std::pair; + + node_iterator_value() : kv(), pNode(nullptr) {} + explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} + explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {} + + V& operator*() const { return *pNode; } + V& operator->() const { return *pNode; } + + V* pNode; +}; + +using node_seq = std::vector; +using node_map = std::vector>; + +template +struct node_iterator_type { + using seq = node_seq::iterator; + using map = node_map::iterator; +}; + +template +struct node_iterator_type { + using seq = node_seq::const_iterator; + using map = node_map::const_iterator; +}; + +template +class node_iterator_base { + private: + struct enabler {}; + + struct proxy { + explicit proxy(const node_iterator_value& x) : m_ref(x) {} + node_iterator_value* operator->() { return std::addressof(m_ref); } + operator node_iterator_value*() { return std::addressof(m_ref); } + + node_iterator_value m_ref; + }; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = node_iterator_value; + using difference_type = std::ptrdiff_t; + using pointer = node_iterator_value*; + using reference = node_iterator_value; + using SeqIter = typename node_iterator_type::seq; + using MapIter = typename node_iterator_type::map; + + node_iterator_base() + : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {} + explicit node_iterator_base(SeqIter seqIt) + : m_type(iterator_type::Sequence), + m_seqIt(seqIt), + m_mapIt(), + m_mapEnd() {} + explicit node_iterator_base(MapIter mapIt, MapIter mapEnd) + : m_type(iterator_type::Map), + m_seqIt(), + m_mapIt(mapIt), + m_mapEnd(mapEnd) { + m_mapIt = increment_until_defined(m_mapIt); + } + + template + node_iterator_base(const node_iterator_base& rhs, + typename std::enable_if::value, + enabler>::type = enabler()) + : m_type(rhs.m_type), + m_seqIt(rhs.m_seqIt), + m_mapIt(rhs.m_mapIt), + m_mapEnd(rhs.m_mapEnd) {} + + template + friend class node_iterator_base; + + template + bool operator==(const node_iterator_base& rhs) const { + if (m_type != rhs.m_type) + return false; + + switch (m_type) { + case iterator_type::NoneType: + return true; + case iterator_type::Sequence: + return m_seqIt == rhs.m_seqIt; + case iterator_type::Map: + return m_mapIt == rhs.m_mapIt; + } + return true; + } + + template + bool operator!=(const node_iterator_base& rhs) const { + return !(*this == rhs); + } + + node_iterator_base& operator++() { + switch (m_type) { + case iterator_type::NoneType: + break; + case iterator_type::Sequence: + ++m_seqIt; + break; + case iterator_type::Map: + ++m_mapIt; + m_mapIt = increment_until_defined(m_mapIt); + break; + } + return *this; + } + + node_iterator_base operator++(int) { + node_iterator_base iterator_pre(*this); + ++(*this); + return iterator_pre; + } + + value_type operator*() const { + switch (m_type) { + case iterator_type::NoneType: + return value_type(); + case iterator_type::Sequence: + return value_type(**m_seqIt); + case iterator_type::Map: + return value_type(*m_mapIt->first, *m_mapIt->second); + } + return value_type(); + } + + proxy operator->() const { return proxy(**this); } + + MapIter increment_until_defined(MapIter it) { + while (it != m_mapEnd && !is_defined(it)) + ++it; + return it; + } + + bool is_defined(MapIter it) const { + return it->first->is_defined() && it->second->is_defined(); + } + + private: + typename iterator_type::value m_type; + + SeqIter m_seqIt; + MapIter m_mapIt, m_mapEnd; +}; + +using node_iterator = node_iterator_base; +using const_node_iterator = node_iterator_base; +} +} + +#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/detail/node_ref.h b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_ref.h new file mode 100644 index 00000000000000..d8a94f8b8045cf --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/detail/node_ref.h @@ -0,0 +1,98 @@ +#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/type.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/detail/node_data.h" + +namespace YAML { +namespace detail { +class node_ref { + public: + node_ref() : m_pData(new node_data) {} + node_ref(const node_ref&) = delete; + node_ref& operator=(const node_ref&) = delete; + + bool is_defined() const { return m_pData->is_defined(); } + const Mark& mark() const { return m_pData->mark(); } + NodeType::value type() const { return m_pData->type(); } + const std::string& scalar() const { return m_pData->scalar(); } + const std::string& tag() const { return m_pData->tag(); } + EmitterStyle::value style() const { return m_pData->style(); } + + void mark_defined() { m_pData->mark_defined(); } + void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } + + void set_mark(const Mark& mark) { m_pData->set_mark(mark); } + void set_type(NodeType::value type) { m_pData->set_type(type); } + void set_tag(const std::string& tag) { m_pData->set_tag(tag); } + void set_null() { m_pData->set_null(); } + void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } + void set_style(EmitterStyle::value style) { m_pData->set_style(style); } + + // size/iterator + std::size_t size() const { return m_pData->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pData).begin(); + } + node_iterator begin() { return m_pData->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pData).end(); + } + node_iterator end() { return m_pData->end(); } + + // sequence + void push_back(node& node, shared_memory_holder pMemory) { + m_pData->push_back(node, pMemory); + } + void insert(node& key, node& value, shared_memory_holder pMemory) { + m_pData->insert(key, value, pMemory); + } + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const { + return static_cast(*m_pData).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + return m_pData->get(key, pMemory); + } + template + bool remove(const Key& key, shared_memory_holder pMemory) { + return m_pData->remove(key, pMemory); + } + + node* get(node& key, shared_memory_holder pMemory) const { + return static_cast(*m_pData).get(key, pMemory); + } + node& get(node& key, shared_memory_holder pMemory) { + return m_pData->get(key, pMemory); + } + bool remove(node& key, shared_memory_holder pMemory) { + return m_pData->remove(key, pMemory); + } + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + m_pData->force_insert(key, value, pMemory); + } + + private: + shared_node_data m_pData; +}; +} +} + +#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/emit.h b/examples/server/yaml-cpp/yaml-cpp/node/emit.h new file mode 100644 index 00000000000000..032268c5d04af8 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/emit.h @@ -0,0 +1,32 @@ +#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class Emitter; +class Node; + +/** + * Emits the node to the given {@link Emitter}. If there is an error in writing, + * {@link Emitter#good} will return false. + */ +YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node); + +/** Emits the node to the given output stream. */ +YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node); + +/** Converts the node to a YAML string. */ +YAML_CPP_API std::string Dump(const Node& node); +} // namespace YAML + +#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/impl.h b/examples/server/yaml-cpp/yaml-cpp/node/impl.h new file mode 100644 index 00000000000000..150a6cfc6e6df8 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/impl.h @@ -0,0 +1,385 @@ +#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/exceptions.h" +#include "yaml-cpp/node/detail/memory.h" +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/node.h" +#include +#include + +namespace YAML { +inline Node::Node() + : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {} + +inline Node::Node(NodeType::value type) + : m_isValid(true), + m_invalidKey{}, + m_pMemory(new detail::memory_holder), + m_pNode(&m_pMemory->create_node()) { + m_pNode->set_type(type); +} + +template +inline Node::Node(const T& rhs) + : m_isValid(true), + m_invalidKey{}, + m_pMemory(new detail::memory_holder), + m_pNode(&m_pMemory->create_node()) { + Assign(rhs); +} + +inline Node::Node(const detail::iterator_value& rhs) + : m_isValid(rhs.m_isValid), + m_invalidKey(rhs.m_invalidKey), + m_pMemory(rhs.m_pMemory), + m_pNode(rhs.m_pNode) {} + +inline Node::Node(const Node&) = default; + +inline Node::Node(Zombie) + : m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {} + +inline Node::Node(Zombie, const std::string& key) + : m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {} + +inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory) + : m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {} + +inline Node::~Node() = default; + +inline void Node::EnsureNodeExists() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + if (!m_pNode) { + m_pMemory.reset(new detail::memory_holder); + m_pNode = &m_pMemory->create_node(); + m_pNode->set_null(); + } +} + +inline bool Node::IsDefined() const { + if (!m_isValid) { + return false; + } + return m_pNode ? m_pNode->is_defined() : true; +} + +inline Mark Node::Mark() const { + if (!m_isValid) { + throw InvalidNode(m_invalidKey); + } + return m_pNode ? m_pNode->mark() : Mark::null_mark(); +} + +inline NodeType::value Node::Type() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return m_pNode ? m_pNode->type() : NodeType::Null; +} + +// access + +// template helpers +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + T operator()(const S& fallback) const { + if (!node.m_pNode) + return fallback; + + T t = fallback; + if (convert::decode(node, t)) + return t; + return fallback; + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + std::string operator()(const S& fallback) const { + if (node.Type() == NodeType::Null) + return "null"; + if (node.Type() != NodeType::Scalar) + return fallback; + return node.Scalar(); + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + T operator()() const { + if (!node.m_pNode) + throw TypedBadConversion(node.Mark()); + + T t; + if (convert::decode(node, t)) + return t; + throw TypedBadConversion(node.Mark()); + } +}; + +template <> +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + std::string operator()() const { + if (node.Type() == NodeType::Null) + return "null"; + if (node.Type() != NodeType::Scalar) + throw TypedBadConversion(node.Mark()); + return node.Scalar(); + } +}; + +// access functions +template +inline T Node::as() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return as_if(*this)(); +} + +template +inline T Node::as(const S& fallback) const { + if (!m_isValid) + return fallback; + return as_if(*this)(fallback); +} + +inline const std::string& Node::Scalar() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar(); +} + +inline const std::string& Node::Tag() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar(); +} + +inline void Node::SetTag(const std::string& tag) { + EnsureNodeExists(); + m_pNode->set_tag(tag); +} + +inline EmitterStyle::value Node::Style() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return m_pNode ? m_pNode->style() : EmitterStyle::Default; +} + +inline void Node::SetStyle(EmitterStyle::value style) { + EnsureNodeExists(); + m_pNode->set_style(style); +} + +// assignment +inline bool Node::is(const Node& rhs) const { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(m_invalidKey); + if (!m_pNode || !rhs.m_pNode) + return false; + return m_pNode->is(*rhs.m_pNode); +} + +template +inline Node& Node::operator=(const T& rhs) { + Assign(rhs); + return *this; +} + +inline Node& Node::operator=(const Node& rhs) { + if (is(rhs)) + return *this; + AssignNode(rhs); + return *this; +} + +inline void Node::reset(const YAML::Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(m_invalidKey); + m_pMemory = rhs.m_pMemory; + m_pNode = rhs.m_pNode; +} + +template +inline void Node::Assign(const T& rhs) { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + AssignData(convert::encode(rhs)); +} + +template <> +inline void Node::Assign(const std::string& rhs) { + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(const char* rhs) { + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(char* rhs) { + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::AssignData(const Node& rhs) { + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->set_data(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); +} + +inline void Node::AssignNode(const Node& rhs) { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + rhs.EnsureNodeExists(); + + if (!m_pNode) { + m_pNode = rhs.m_pNode; + m_pMemory = rhs.m_pMemory; + return; + } + + m_pNode->set_ref(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); + m_pNode = rhs.m_pNode; +} + +// size/iterator +inline std::size_t Node::size() const { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + return m_pNode ? m_pNode->size() : 0; +} + +inline const_iterator Node::begin() const { + if (!m_isValid) + return const_iterator(); + return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) + : const_iterator(); +} + +inline iterator Node::begin() { + if (!m_isValid) + return iterator(); + return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); +} + +inline const_iterator Node::end() const { + if (!m_isValid) + return const_iterator(); + return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); +} + +inline iterator Node::end() { + if (!m_isValid) + return iterator(); + return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); +} + +// sequence +template +inline void Node::push_back(const T& rhs) { + if (!m_isValid) + throw InvalidNode(m_invalidKey); + push_back(Node(rhs)); +} + +inline void Node::push_back(const Node& rhs) { + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->push_back(*rhs.m_pNode, m_pMemory); + m_pMemory->merge(*rhs.m_pMemory); +} + +template +std::string key_to_string(const Key& key) { + return streamable_to_string::value>().impl(key); +} + +// indexing +template +inline const Node Node::operator[](const Key& key) const { + EnsureNodeExists(); + detail::node* value = + static_cast(*m_pNode).get(key, m_pMemory); + if (!value) { + return Node(ZombieNode, key_to_string(key)); + } + return Node(*value, m_pMemory); +} + +template +inline Node Node::operator[](const Key& key) { + EnsureNodeExists(); + detail::node& value = m_pNode->get(key, m_pMemory); + return Node(value, m_pMemory); +} + +template +inline bool Node::remove(const Key& key) { + EnsureNodeExists(); + return m_pNode->remove(key, m_pMemory); +} + +inline const Node Node::operator[](const Node& key) const { + EnsureNodeExists(); + key.EnsureNodeExists(); + m_pMemory->merge(*key.m_pMemory); + detail::node* value = + static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); + if (!value) { + return Node(ZombieNode, key_to_string(key)); + } + return Node(*value, m_pMemory); +} + +inline Node Node::operator[](const Node& key) { + EnsureNodeExists(); + key.EnsureNodeExists(); + m_pMemory->merge(*key.m_pMemory); + detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory); + return Node(value, m_pMemory); +} + +inline bool Node::remove(const Node& key) { + EnsureNodeExists(); + key.EnsureNodeExists(); + return m_pNode->remove(*key.m_pNode, m_pMemory); +} + +// map +template +inline void Node::force_insert(const Key& key, const Value& value) { + EnsureNodeExists(); + m_pNode->force_insert(key, value, m_pMemory); +} + +// free functions +inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); } +} // namespace YAML + +#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/iterator.h b/examples/server/yaml-cpp/yaml-cpp/node/iterator.h new file mode 100644 index 00000000000000..1fcf6e400ff6b3 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/iterator.h @@ -0,0 +1,34 @@ +#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/detail/iterator_fwd.h" +#include "yaml-cpp/node/detail/iterator.h" +#include +#include +#include + +// Assert in place so gcc + libc++ combination properly builds +static_assert(std::is_constructible::value, "Node must be copy constructable"); + +namespace YAML { +namespace detail { +struct iterator_value : public Node, std::pair { + iterator_value() = default; + explicit iterator_value(const Node& rhs) + : Node(rhs), + std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} + explicit iterator_value(const Node& key, const Node& value) + : Node(Node::ZombieNode), std::pair(key, value) {} +}; +} +} + +#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/node.h b/examples/server/yaml-cpp/yaml-cpp/node/node.h new file mode 100644 index 00000000000000..c9e9a0a4bc190d --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/node.h @@ -0,0 +1,148 @@ +#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/mark.h" +#include "yaml-cpp/node/detail/iterator_fwd.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/type.h" + +namespace YAML { +namespace detail { +class node; +class node_data; +struct iterator_value; +} // namespace detail +} // namespace YAML + +namespace YAML { +class YAML_CPP_API Node { + public: + friend class NodeBuilder; + friend class NodeEvents; + friend struct detail::iterator_value; + friend class detail::node; + friend class detail::node_data; + template + friend class detail::iterator_base; + template + friend struct as_if; + + using iterator = YAML::iterator; + using const_iterator = YAML::const_iterator; + + Node(); + explicit Node(NodeType::value type); + template + explicit Node(const T& rhs); + explicit Node(const detail::iterator_value& rhs); + Node(const Node& rhs); + ~Node(); + + YAML::Mark Mark() const; + NodeType::value Type() const; + bool IsDefined() const; + bool IsNull() const { return Type() == NodeType::Null; } + bool IsScalar() const { return Type() == NodeType::Scalar; } + bool IsSequence() const { return Type() == NodeType::Sequence; } + bool IsMap() const { return Type() == NodeType::Map; } + + // bool conversions + explicit operator bool() const { return IsDefined(); } + bool operator!() const { return !IsDefined(); } + + // access + template + T as() const; + template + T as(const S& fallback) const; + const std::string& Scalar() const; + + const std::string& Tag() const; + void SetTag(const std::string& tag); + + // style + // WARNING: This API might change in future releases. + EmitterStyle::value Style() const; + void SetStyle(EmitterStyle::value style); + + // assignment + bool is(const Node& rhs) const; + template + Node& operator=(const T& rhs); + Node& operator=(const Node& rhs); + void reset(const Node& rhs = Node()); + + // size/iterator + std::size_t size() const; + + const_iterator begin() const; + iterator begin(); + + const_iterator end() const; + iterator end(); + + // sequence + template + void push_back(const T& rhs); + void push_back(const Node& rhs); + + // indexing + template + const Node operator[](const Key& key) const; + template + Node operator[](const Key& key); + template + bool remove(const Key& key); + + const Node operator[](const Node& key) const; + Node operator[](const Node& key); + bool remove(const Node& key); + + // map + template + void force_insert(const Key& key, const Value& value); + + private: + enum Zombie { ZombieNode }; + explicit Node(Zombie); + explicit Node(Zombie, const std::string&); + explicit Node(detail::node& node, detail::shared_memory_holder pMemory); + + void EnsureNodeExists() const; + + template + void Assign(const T& rhs); + void Assign(const char* rhs); + void Assign(char* rhs); + + void AssignData(const Node& rhs); + void AssignNode(const Node& rhs); + + private: + bool m_isValid; + // String representation of invalid key, if the node is invalid. + std::string m_invalidKey; + mutable detail::shared_memory_holder m_pMemory; + mutable detail::node* m_pNode; +}; + +YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); + +YAML_CPP_API Node Clone(const Node& node); + +template +struct convert; +} + +#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/parse.h b/examples/server/yaml-cpp/yaml-cpp/node/parse.h new file mode 100644 index 00000000000000..7745fd7245bec0 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/parse.h @@ -0,0 +1,78 @@ +#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class Node; + +/** + * Loads the input string as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(const std::string& input); + +/** + * Loads the input string as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(const char* input); + +/** + * Loads the input stream as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(std::istream& input); + +/** + * Loads the input file as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + * @throws {@link BadFile} if the file cannot be loaded. + */ +YAML_CPP_API Node LoadFile(const std::string& filename); + +/** + * Loads the input string as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(const std::string& input); + +/** + * Loads the input string as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(const char* input); + +/** + * Loads the input stream as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(std::istream& input); + +/** + * Loads the input file as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + * @throws {@link BadFile} if the file cannot be loaded. + */ +YAML_CPP_API std::vector LoadAllFromFile(const std::string& filename); +} // namespace YAML + +#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/ptr.h b/examples/server/yaml-cpp/yaml-cpp/node/ptr.h new file mode 100644 index 00000000000000..f55d95ed9cade1 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/ptr.h @@ -0,0 +1,28 @@ +#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +namespace YAML { +namespace detail { +class node; +class node_ref; +class node_data; +class memory; +class memory_holder; + +using shared_node = std::shared_ptr; +using shared_node_ref = std::shared_ptr; +using shared_node_data = std::shared_ptr; +using shared_memory_holder = std::shared_ptr; +using shared_memory = std::shared_ptr; +} +} + +#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/node/type.h b/examples/server/yaml-cpp/yaml-cpp/node/type.h new file mode 100644 index 00000000000000..9d55ca96621619 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/node/type.h @@ -0,0 +1,16 @@ +#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct NodeType { + enum value { Undefined, Null, Scalar, Sequence, Map }; +}; +} + +#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/noexcept.h b/examples/server/yaml-cpp/yaml-cpp/noexcept.h new file mode 100644 index 00000000000000..6aac63516f357a --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/noexcept.h @@ -0,0 +1,18 @@ +#ifndef NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8 +#define NOEXCEPT_H_768872DA_476C_11EA_88B8_90B11C0C0FF8 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +// This is here for compatibility with older versions of Visual Studio +// which don't support noexcept. +#if defined(_MSC_VER) && _MSC_VER < 1900 + #define YAML_CPP_NOEXCEPT _NOEXCEPT +#else + #define YAML_CPP_NOEXCEPT noexcept +#endif + +#endif diff --git a/examples/server/yaml-cpp/yaml-cpp/null.h b/examples/server/yaml-cpp/yaml-cpp/null.h new file mode 100644 index 00000000000000..b9521d488a6acb --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/null.h @@ -0,0 +1,26 @@ +#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include + +namespace YAML { +class Node; + +struct YAML_CPP_API _Null {}; +inline bool operator==(const _Null&, const _Null&) { return true; } +inline bool operator!=(const _Null&, const _Null&) { return false; } + +YAML_CPP_API bool IsNull(const Node& node); // old API only +YAML_CPP_API bool IsNullString(const std::string& str); + +extern YAML_CPP_API _Null Null; +} + +#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/ostream_wrapper.h b/examples/server/yaml-cpp/yaml-cpp/ostream_wrapper.h new file mode 100644 index 00000000000000..cf89741d0935aa --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/ostream_wrapper.h @@ -0,0 +1,76 @@ +#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class YAML_CPP_API ostream_wrapper { + public: + ostream_wrapper(); + explicit ostream_wrapper(std::ostream& stream); + ostream_wrapper(const ostream_wrapper&) = delete; + ostream_wrapper(ostream_wrapper&&) = delete; + ostream_wrapper& operator=(const ostream_wrapper&) = delete; + ostream_wrapper& operator=(ostream_wrapper&&) = delete; + ~ostream_wrapper(); + + void write(const std::string& str); + void write(const char* str, std::size_t size); + + void set_comment() { m_comment = true; } + + const char* str() const { + if (m_pStream) { + return nullptr; + } else { + m_buffer[m_pos] = '\0'; + return &m_buffer[0]; + } + } + + std::size_t row() const { return m_row; } + std::size_t col() const { return m_col; } + std::size_t pos() const { return m_pos; } + bool comment() const { return m_comment; } + + private: + void update_pos(char ch); + + private: + mutable std::vector m_buffer; + std::ostream* const m_pStream; + + std::size_t m_pos; + std::size_t m_row, m_col; + bool m_comment; +}; + +template +inline ostream_wrapper& operator<<(ostream_wrapper& stream, + const char (&str)[N]) { + stream.write(str, N - 1); + return stream; +} + +inline ostream_wrapper& operator<<(ostream_wrapper& stream, + const std::string& str) { + stream.write(str); + return stream; +} + +inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) { + stream.write(&ch, 1); + return stream; +} +} // namespace YAML + +#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/parser.h b/examples/server/yaml-cpp/yaml-cpp/parser.h new file mode 100644 index 00000000000000..2f403c35048056 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/parser.h @@ -0,0 +1,90 @@ +#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class EventHandler; +class Node; +class Scanner; +struct Directives; +struct Token; + +/** + * A parser turns a stream of bytes into one stream of "events" per YAML + * document in the input stream. + */ +class YAML_CPP_API Parser { + public: + /** Constructs an empty parser (with no input. */ + Parser(); + + Parser(const Parser&) = delete; + Parser(Parser&&) = delete; + Parser& operator=(const Parser&) = delete; + Parser& operator=(Parser&&) = delete; + + /** + * Constructs a parser from the given input stream. The input stream must + * live as long as the parser. + */ + explicit Parser(std::istream& in); + + ~Parser(); + + /** Evaluates to true if the parser has some valid input to be read. */ + explicit operator bool() const; + + /** + * Resets the parser with the given input stream. Any existing state is + * erased. + */ + void Load(std::istream& in); + + /** + * Handles the next document by calling events on the {@code eventHandler}. + * + * @throw a ParserException on error. + * @return false if there are no more documents + */ + bool HandleNextDocument(EventHandler& eventHandler); + + void PrintTokens(std::ostream& out); + + private: + /** + * Reads any directives that are next in the queue, setting the internal + * {@code m_pDirectives} state. + */ + void ParseDirectives(); + + void HandleDirective(const Token& token); + + /** + * Handles a "YAML" directive, which should be of the form 'major.minor' (like + * a version number). + */ + void HandleYamlDirective(const Token& token); + + /** + * Handles a "TAG" directive, which should be of the form 'handle prefix', + * where 'handle' is converted to 'prefix' in the file. + */ + void HandleTagDirective(const Token& token); + + private: + std::unique_ptr m_pScanner; + std::unique_ptr m_pDirectives; +}; +} // namespace YAML + +#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/stlemitter.h b/examples/server/yaml-cpp/yaml-cpp/stlemitter.h new file mode 100644 index 00000000000000..210a2f64e6a816 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/stlemitter.h @@ -0,0 +1,50 @@ +#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include + +namespace YAML { +template +inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { + emitter << BeginSeq; + for (const auto& v : seq) + emitter << v; + emitter << EndSeq; + return emitter; +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::vector& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::list& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::set& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::map& m) { + emitter << BeginMap; + for (const auto& v : m) + emitter << Key << v.first << Value << v.second; + emitter << EndMap; + return emitter; +} +} + +#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/traits.h b/examples/server/yaml-cpp/yaml-cpp/traits.h new file mode 100644 index 00000000000000..ffe9999f191fe8 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/traits.h @@ -0,0 +1,135 @@ +#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include + +namespace YAML { +template +struct is_numeric { + enum { value = false }; +}; + +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#if defined(_MSC_VER) && (_MSC_VER < 1310) +template <> +struct is_numeric<__int64> { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#else +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#endif +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; + +template +struct enable_if_c { + using type = T; +}; + +template +struct enable_if_c {}; + +template +struct enable_if : public enable_if_c {}; + +template +struct disable_if_c { + using type = T; +}; + +template +struct disable_if_c {}; + +template +struct disable_if : public disable_if_c {}; +} + +template +struct is_streamable { + template + static auto test(int) + -> decltype(std::declval() << std::declval(), std::true_type()); + + template + static auto test(...) -> std::false_type; + + static const bool value = decltype(test(0))::value; +}; + +template +struct streamable_to_string { + static std::string impl(const Key& key) { + std::stringstream ss; + ss << key; + return ss.str(); + } +}; + +template +struct streamable_to_string { + static std::string impl(const Key&) { + return ""; + } +}; +#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-cpp/yaml-cpp/yaml.h b/examples/server/yaml-cpp/yaml-cpp/yaml.h new file mode 100644 index 00000000000000..7f515efb961056 --- /dev/null +++ b/examples/server/yaml-cpp/yaml-cpp/yaml.h @@ -0,0 +1,24 @@ +#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/parser.h" +#include "yaml-cpp/emitter.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/stlemitter.h" +#include "yaml-cpp/exceptions.h" + +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/impl.h" +#include "yaml-cpp/node/convert.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/detail/impl.h" +#include "yaml-cpp/node/parse.h" +#include "yaml-cpp/node/emit.h" + +#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/examples/server/yaml-parser.hpp b/examples/server/yaml-parser.hpp new file mode 100644 index 00000000000000..acb911d9f1529f --- /dev/null +++ b/examples/server/yaml-parser.hpp @@ -0,0 +1,41 @@ +#include +#include "json.hpp" +#include + +using json = nlohmann::ordered_json; + +std::vector rubra_fc_yaml_tool_extractor(const std::string& source_string) { + std::vector calls; + std::string delimiter = "<>"; + std::string source_code; + printf("================Model Output================\n%s\n\n", source_string.c_str()); + size_t startPos = source_string.find(delimiter); + if (startPos != std::string::npos) { + source_code = source_string.substr(startPos + delimiter.length()); + } else { + return calls; + } + + // TODO: may need to preprocess before yaml load. + YAML::Node config = YAML::Load(source_code); + for (const auto& item : config) { + json call = { + {"id", std::to_string(calls.size())}, + {"name", ""}, + {"args", json::array()}, + {"kwargs", json::object()} + }; + call["name"] = item["functionCall"].as(); + + // Iterate through arguments if they exist + if (item["arguments"]) { + for (YAML::const_iterator it = item["arguments"].begin(); it != item["arguments"].end(); ++it) { + call["kwargs"][it->first.as()] = it->second.as(); + } + } + printf("\n======parsed call: %s=====\n", call.dump().c_str()); + calls.push_back(call); + } + return calls; +} + diff --git a/test_llamacpp.ipynb b/test_llamacpp.ipynb index 1a96b8e22f4651..ac2685eaf262ea 100644 --- a/test_llamacpp.ipynb +++ b/test_llamacpp.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -413,7 +413,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -424,7 +424,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -434,19 +434,31 @@ "Pointing to URL: http://localhost:8019/v1/\n", "\n", "[AI calling functions]:\n", - "Tool Call: Function(arguments='{\"origin\":\"San Francisco\",\"destination\":\"Cupertino\",\"mode\":\"driving\"}', name='calculate_distance')\n", - "Tool Call: Function(arguments='{\"origin\":\"Cupertino\",\"destination\":\"San Francisco\",\"mode\":\"driving\"}', name='calculate_distance')\n", + "Tool Call: Function(arguments='{\"origin\":\"San Francisco\",\"destination\":\"Cupertino\",\"mode\":\"drive\"}', name='calculate_distance')\n", + "Observation: Distance is 50 miles.\n", + "Pointing to URL: http://localhost:8019/v1/\n", + "Loop 0\n", + "\n", + "[AI calling functions]:\n", + "Tool Call: Function(arguments='{\"origin\":\"Cupertino\",\"destination\":\"San Francisco\",\"mode\":\"drive\"}', name='calculate_distance')\n", + "Observation: Distance is 50 miles.\n", + "Pointing to URL: http://localhost:8019/v1/\n", + "Loop 1\n", + "\n", + "[AI calling functions]:\n", "Tool Call: Function(arguments='{\"origin\":\"San Francisco\",\"destination\":\"Cupertino\",\"mode\":\"air\"}', name='calculate_distance')\n", + "Observation: Distance is 50 miles.\n", + "Pointing to URL: http://localhost:8019/v1/\n", + "Loop 2\n", + "\n", + "[AI calling functions]:\n", "Tool Call: Function(arguments='{\"origin\":\"Cupertino\",\"destination\":\"San Francisco\",\"mode\":\"air\"}', name='calculate_distance')\n", "Observation: Distance is 50 miles.\n", - "Observation: Distance is 100 miles.\n", - "Observation: Distance is 150 miles.\n", - "Observation: Distance is 200 miles.\n", "Pointing to URL: http://localhost:8019/v1/\n", - "Loop 0\n", + "Loop 3\n", "\n", "[AI response]:\n", - " The distance between San Francisco and Cupertino is 50 miles by driving from San Francisco and 100 miles from Cupertino. If you consider the distance by air, it is 150 miles from San Francisco to Cupertino and 200 miles from Cupertino to San Francisco.\n" + " The distance between San Francisco and Cupertino is 50 miles whether you drive or fly from either direction.\n" ] } ],