Repository: nifi-minifi-cpp Updated Branches: refs/heads/master b26b06479 -> eb9128c37
MINIFICPP-471 Implemented string manipulation EL functions This closes #312. Signed-off-by: Aldrin Piri <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/commit/eb9128c3 Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/eb9128c3 Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/eb9128c3 Branch: refs/heads/master Commit: eb9128c37b2819da56785c3c5b453f33d5b2d085 Parents: b26b064 Author: Andrew I. Christianson <[email protected]> Authored: Wed Apr 25 11:47:26 2018 -0400 Committer: Aldrin Piri <[email protected]> Committed: Fri May 4 09:06:01 2018 -0400 ---------------------------------------------------------------------- EXPRESSIONS.md | 76 ++++++++++++++++++-- extensions/expression-language/Expression.cpp | 29 ++++++++ .../ExpressionLanguageTests.cpp | 32 +++++++++ 3 files changed, 133 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/eb9128c3/EXPRESSIONS.md ---------------------------------------------------------------------- diff --git a/EXPRESSIONS.md b/EXPRESSIONS.md index f2a4876..95864d7 100644 --- a/EXPRESSIONS.md +++ b/EXPRESSIONS.md @@ -177,6 +177,10 @@ token, filename. - [`replaceAll`](#replaceall) - [`replaceNull`](#replacenull) - [`replaceEmpty`](#replaceempty) +- [`trim`](#trim) +- [`append`](#append) +- [`prepend`](#prepend) +- [`length`](#length) ### Mathematical Operations and Numeric Manipulation @@ -222,11 +226,7 @@ token, filename. ### String Manipulation -- `trim` - `getDelimitedField` -- `append` -- `prepend` -- `length` ### Searching @@ -859,6 +859,74 @@ filename.txt` and the attribute `hello` has the value ` `, then the Expression `${filename:replaceEmpty('abc')}` will return `a brand new filename.txt`, while `${hello:replaceEmpty('abc')}` will return `abc`. +### trim + +**Description**: The `trim` function will remove any leading or trailing white +space from its subject. + +**Subject Type**: String + +**Arguments**: No Arguments + +**Return Type**: String + +**Examples**: If the attribute `attr` has the value " 1 2 3 ", then the +Expression `${attr:trim()}` will return the value "1 2 3". + +### append + +**Description**: The `append` function returns the result of appending the +argument to the value of the Subject. If the Subject is null, returns the +argument itself. + +**Subject Type**: String + +**Arguments**: + +| Argument | Description | +| - | - | +| value | The String to append to the end of the Subject | + +**Return Type**: String + +**Examples**: If the "filename" attribute has the value "a brand new +filename.txt", then the Expression `${filename:append('.gz')}` will return "a +brand new filename.txt.gz". + +### prepend + +**Description**: The `prepend` function returns the result of prepending the +argument to the value of the Subject. If the subject is null, returns the +argument itself. + +**Subject Type**: String + +**Arguments**: + +| Argument | Description | +| - | - | +| value | The String to prepend to the beginning of the Subject | + +**Return Type**: String + +**Examples**: If the "filename" attribute has the value "filename.txt", then +the Expression `${filename:prepend('a brand new ')}` will return "a brand new +filename.txt". + +### length + +**Description**: Returns the length of the Subject + +**Subject Type**: String + +**Arguments**: No arguments + +**Return Type**: String + +**Examples**: If the attribute "filename" has a value of "a brand new +filename.txt" and the attribute "hello" does not exist, then the Expression +`${filename:length()}` will return 24. `${hello:length()}` will return 0. + ## Mathematical Operations and Numeric Manipulation For those functions that support Decimal and Number (whole number) types, the http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/eb9128c3/extensions/expression-language/Expression.cpp ---------------------------------------------------------------------- diff --git a/extensions/expression-language/Expression.cpp b/extensions/expression-language/Expression.cpp index 9722028..6c2acc8 100644 --- a/extensions/expression-language/Expression.cpp +++ b/extensions/expression-language/Expression.cpp @@ -1288,6 +1288,27 @@ Value expr_find(const std::vector<Value> &args) { #endif // EXPRESSION_LANGUAGE_USE_REGEX +Value expr_trim(const std::vector<Value> &args) { + std::string result = args[0].asString(); + auto ws_front = std::find_if_not(result.begin(), result.end(), [](int c) { return std::isspace(c); }); + auto ws_back = std::find_if_not(result.rbegin(), result.rend(), [](int c) { return std::isspace(c); }).base(); + return (ws_back <= ws_front ? Value(std::string()) : Value(std::string(ws_front, ws_back))); +} + +Value expr_append(const std::vector<Value> &args) { + std::string result = args[0].asString(); + return Value(result.append(args[1].asString())); +} + +Value expr_prepend(const std::vector<Value> &args) { + std::string result = args[1].asString(); + return Value(result.append(args[0].asString())); +} + +Value expr_length(const std::vector<Value> &args) { + return Value(args[0].asString().length()); +} + Value expr_binary_op(const std::vector<Value> &args, long double (*ldop)(long double, long double), int64_t (*iop)(int64_t, int64_t), @@ -1594,6 +1615,14 @@ Expression make_dynamic_function(const std::string &function_name, } else if (function_name == "find") { return make_dynamic_function_incomplete<expr_find>(function_name, args, 1); #endif // EXPRESSION_LANGUAGE_USE_REGEX + } else if (function_name == "trim") { + return make_dynamic_function_incomplete<expr_trim>(function_name, args, 0); + } else if (function_name == "append") { + return make_dynamic_function_incomplete<expr_append>(function_name, args, 1); + } else if (function_name == "prepend") { + return make_dynamic_function_incomplete<expr_prepend>(function_name, args, 1); + } else if (function_name == "length") { + return make_dynamic_function_incomplete<expr_length>(function_name, args, 0); } else if (function_name == "plus") { return make_dynamic_function_incomplete<expr_plus>(function_name, args, 1); } else if (function_name == "minus") { http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/eb9128c3/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp ---------------------------------------------------------------------- diff --git a/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp b/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp index 5b687d7..17fb903 100644 --- a/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp +++ b/libminifi/test/expression-language-tests/ExpressionLanguageTests.cpp @@ -1189,3 +1189,35 @@ TEST_CASE("UUID", "[expressionUuid]") { // NOLINT auto flow_file_a = std::make_shared<MockFlowFile>(); REQUIRE(36 == expr({flow_file_a}).asString().length()); } + +TEST_CASE("Trim", "[expressionTrim]") { // NOLINT + auto expr = expression::compile("${message:trim()}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", " 1 2 3 "); + REQUIRE("1 2 3" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Append", "[expressionAppend]") { // NOLINT + auto expr = expression::compile("${message:append('.gz')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "a brand new filename.txt"); + REQUIRE("a brand new filename.txt.gz" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Prepend", "[expressionPrepend]") { // NOLINT + auto expr = expression::compile("${message:prepend('a brand new ')}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "filename.txt"); + REQUIRE("a brand new filename.txt" == expr({flow_file_a}).asString()); +} + +TEST_CASE("Length", "[expressionLength]") { // NOLINT + auto expr = expression::compile("${message:length()}"); + + auto flow_file_a = std::make_shared<MockFlowFile>(); + flow_file_a->addAttribute("message", "a brand new filename.txt"); + REQUIRE(24 == expr({flow_file_a}).asUnsignedLong()); +}
