You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bq...@apache.org on 2017/04/11 17:16:13 UTC

[05/20] nifi-minifi-cpp git commit: MINIFI-227: Provenance report

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/lib_json/json_writer.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/lib_json/json_writer.cpp b/thirdparty/jsoncpp/src/lib_json/json_writer.cpp
new file mode 100644
index 0000000..a03f0eb
--- /dev/null
+++ b/thirdparty/jsoncpp/src/lib_json/json_writer.cpp
@@ -0,0 +1,1224 @@
+// Copyright 2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/writer.h>
+#include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <iomanip>
+#include <memory>
+#include <sstream>
+#include <utility>
+#include <set>
+#include <cassert>
+#include <cstring>
+#include <cstdio>
+
+#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
+#include <float.h>
+#define isfinite _finite
+#elif defined(__sun) && defined(__SVR4) //Solaris
+#if !defined(isfinite)
+#include <ieeefp.h>
+#define isfinite finite
+#endif
+#elif defined(_AIX)
+#if !defined(isfinite)
+#include <math.h>
+#define isfinite finite
+#endif
+#elif defined(__hpux)
+#if !defined(isfinite)
+#if defined(__ia64) && !defined(finite)
+#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
+                     _Isfinitef(x) : _IsFinite(x)))
+#else
+#include <math.h>
+#define isfinite finite
+#endif
+#endif
+#else
+#include <cmath>
+#if !(defined(__QNXNTO__)) // QNX already defines isfinite
+#define isfinite std::isfinite
+#endif
+#endif
+
+#if defined(_MSC_VER)
+#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
+#define snprintf sprintf_s
+#elif _MSC_VER >= 1900 // VC++ 14.0 and above
+#define snprintf std::snprintf
+#else
+#define snprintf _snprintf
+#endif
+#elif defined(__ANDROID__) || defined(__QNXNTO__)
+#define snprintf snprintf
+#elif __cplusplus >= 201103L
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define snprintf std::snprintf
+#endif
+#endif
+
+#if defined(__BORLANDC__)  
+#include <float.h>
+#define isfinite _finite
+#define snprintf _snprintf
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
+// Disable warning about strdup being deprecated.
+#pragma warning(disable : 4996)
+#endif
+
+namespace Json {
+
+#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
+typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
+#else
+typedef std::auto_ptr<StreamWriter>   StreamWriterPtr;
+#endif
+
+static bool containsControlCharacter(const char* str) {
+  while (*str) {
+    if (isControlCharacter(*(str++)))
+      return true;
+  }
+  return false;
+}
+
+static bool containsControlCharacter0(const char* str, unsigned len) {
+  char const* end = str + len;
+  while (end != str) {
+    if (isControlCharacter(*str) || 0==*str)
+      return true;
+    ++str;
+  }
+  return false;
+}
+
+JSONCPP_STRING valueToString(LargestInt value) {
+  UIntToStringBuffer buffer;
+  char* current = buffer + sizeof(buffer);
+  if (value == Value::minLargestInt) {
+    uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
+    *--current = '-';
+  } else if (value < 0) {
+    uintToString(LargestUInt(-value), current);
+    *--current = '-';
+  } else {
+    uintToString(LargestUInt(value), current);
+  }
+  assert(current >= buffer);
+  return current;
+}
+
+JSONCPP_STRING valueToString(LargestUInt value) {
+  UIntToStringBuffer buffer;
+  char* current = buffer + sizeof(buffer);
+  uintToString(value, current);
+  assert(current >= buffer);
+  return current;
+}
+
+#if defined(JSON_HAS_INT64)
+
+JSONCPP_STRING valueToString(Int value) {
+  return valueToString(LargestInt(value));
+}
+
+JSONCPP_STRING valueToString(UInt value) {
+  return valueToString(LargestUInt(value));
+}
+
+#endif // # if defined(JSON_HAS_INT64)
+
+namespace {
+JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) {
+  // Allocate a buffer that is more than large enough to store the 16 digits of
+  // precision requested below.
+  char buffer[36];
+  int len = -1;
+
+  char formatString[6];
+  sprintf(formatString, "%%.%dg", precision);
+
+  // Print into the buffer. We need not request the alternative representation
+  // that always has a decimal point because JSON doesn't distingish the
+  // concepts of reals and integers.
+  if (isfinite(value)) {
+    len = snprintf(buffer, sizeof(buffer), formatString, value);
+    
+    // try to ensure we preserve the fact that this was given to us as a double on input
+    if (!strstr(buffer, ".") && !strstr(buffer, "e")) {
+      strcat(buffer, ".0");
+    }
+
+  } else {
+    // IEEE standard states that NaN values will not compare to themselves
+    if (value != value) {
+      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
+    } else if (value < 0) {
+      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
+    } else {
+      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
+    }
+    // For those, we do not need to call fixNumLoc, but it is fast.
+  }
+  assert(len >= 0);
+  fixNumericLocale(buffer, buffer + len);
+  return buffer;
+}
+}
+
+JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); }
+
+JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; }
+
+JSONCPP_STRING valueToQuotedString(const char* value) {
+  if (value == NULL)
+    return "";
+  // Not sure how to handle unicode...
+  if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
+      !containsControlCharacter(value))
+    return JSONCPP_STRING("\"") + value + "\"";
+  // We have to walk value and escape any special characters.
+  // Appending to JSONCPP_STRING is not efficient, but this should be rare.
+  // (Note: forward slashes are *not* rare, but I am not escaping them.)
+  JSONCPP_STRING::size_type maxsize =
+      strlen(value) * 2 + 3; // allescaped+quotes+NULL
+  JSONCPP_STRING result;
+  result.reserve(maxsize); // to avoid lots of mallocs
+  result += "\"";
+  for (const char* c = value; *c != 0; ++c) {
+    switch (*c) {
+    case '\"':
+      result += "\\\"";
+      break;
+    case '\\':
+      result += "\\\\";
+      break;
+    case '\b':
+      result += "\\b";
+      break;
+    case '\f':
+      result += "\\f";
+      break;
+    case '\n':
+      result += "\\n";
+      break;
+    case '\r':
+      result += "\\r";
+      break;
+    case '\t':
+      result += "\\t";
+      break;
+    // case '/':
+    // Even though \/ is considered a legal escape in JSON, a bare
+    // slash is also legal, so I see no reason to escape it.
+    // (I hope I am not misunderstanding something.
+    // blep notes: actually escaping \/ may be useful in javascript to avoid </
+    // sequence.
+    // Should add a flag to allow this compatibility mode and prevent this
+    // sequence from occurring.
+    default:
+      if (isControlCharacter(*c)) {
+        JSONCPP_OSTRINGSTREAM oss;
+        oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
+            << std::setw(4) << static_cast<int>(*c);
+        result += oss.str();
+      } else {
+        result += *c;
+      }
+      break;
+    }
+  }
+  result += "\"";
+  return result;
+}
+
+// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp
+static char const* strnpbrk(char const* s, char const* accept, size_t n) {
+  assert((s || !n) && accept);
+
+  char const* const end = s + n;
+  for (char const* cur = s; cur < end; ++cur) {
+    int const c = *cur;
+    for (char const* a = accept; *a; ++a) {
+      if (*a == c) {
+        return cur;
+      }
+    }
+  }
+  return NULL;
+}
+static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
+  if (value == NULL)
+    return "";
+  // Not sure how to handle unicode...
+  if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL &&
+      !containsControlCharacter0(value, length))
+    return JSONCPP_STRING("\"") + value + "\"";
+  // We have to walk value and escape any special characters.
+  // Appending to JSONCPP_STRING is not efficient, but this should be rare.
+  // (Note: forward slashes are *not* rare, but I am not escaping them.)
+  JSONCPP_STRING::size_type maxsize =
+      length * 2 + 3; // allescaped+quotes+NULL
+  JSONCPP_STRING result;
+  result.reserve(maxsize); // to avoid lots of mallocs
+  result += "\"";
+  char const* end = value + length;
+  for (const char* c = value; c != end; ++c) {
+    switch (*c) {
+    case '\"':
+      result += "\\\"";
+      break;
+    case '\\':
+      result += "\\\\";
+      break;
+    case '\b':
+      result += "\\b";
+      break;
+    case '\f':
+      result += "\\f";
+      break;
+    case '\n':
+      result += "\\n";
+      break;
+    case '\r':
+      result += "\\r";
+      break;
+    case '\t':
+      result += "\\t";
+      break;
+    // case '/':
+    // Even though \/ is considered a legal escape in JSON, a bare
+    // slash is also legal, so I see no reason to escape it.
+    // (I hope I am not misunderstanding something.)
+    // blep notes: actually escaping \/ may be useful in javascript to avoid </
+    // sequence.
+    // Should add a flag to allow this compatibility mode and prevent this
+    // sequence from occurring.
+    default:
+      if ((isControlCharacter(*c)) || (*c == 0)) {
+        JSONCPP_OSTRINGSTREAM oss;
+        oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
+            << std::setw(4) << static_cast<int>(*c);
+        result += oss.str();
+      } else {
+        result += *c;
+      }
+      break;
+    }
+  }
+  result += "\"";
+  return result;
+}
+
+// Class Writer
+// //////////////////////////////////////////////////////////////////
+Writer::~Writer() {}
+
+// Class FastWriter
+// //////////////////////////////////////////////////////////////////
+
+FastWriter::FastWriter()
+    : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
+      omitEndingLineFeed_(false) {}
+
+void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
+
+void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
+
+void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
+
+JSONCPP_STRING FastWriter::write(const Value& root) {
+  document_ = "";
+  writeValue(root);
+  if (!omitEndingLineFeed_)
+    document_ += "\n";
+  return document_;
+}
+
+void FastWriter::writeValue(const Value& value) {
+  switch (value.type()) {
+  case nullValue:
+    if (!dropNullPlaceholders_)
+      document_ += "null";
+    break;
+  case intValue:
+    document_ += valueToString(value.asLargestInt());
+    break;
+  case uintValue:
+    document_ += valueToString(value.asLargestUInt());
+    break;
+  case realValue:
+    document_ += valueToString(value.asDouble());
+    break;
+  case stringValue:
+  {
+    // Is NULL possible for value.string_? No.
+    char const* str;
+    char const* end;
+    bool ok = value.getString(&str, &end);
+    if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
+    break;
+  }
+  case booleanValue:
+    document_ += valueToString(value.asBool());
+    break;
+  case arrayValue: {
+    document_ += '[';
+    ArrayIndex size = value.size();
+    for (ArrayIndex index = 0; index < size; ++index) {
+      if (index > 0)
+        document_ += ',';
+      writeValue(value[index]);
+    }
+    document_ += ']';
+  } break;
+  case objectValue: {
+    Value::Members members(value.getMemberNames());
+    document_ += '{';
+    for (Value::Members::iterator it = members.begin(); it != members.end();
+         ++it) {
+      const JSONCPP_STRING& name = *it;
+      if (it != members.begin())
+        document_ += ',';
+      document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
+      document_ += yamlCompatiblityEnabled_ ? ": " : ":";
+      writeValue(value[name]);
+    }
+    document_ += '}';
+  } break;
+  }
+}
+
+// Class StyledWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledWriter::StyledWriter()
+    : rightMargin_(74), indentSize_(3), addChildValues_() {}
+
+JSONCPP_STRING StyledWriter::write(const Value& root) {
+  document_ = "";
+  addChildValues_ = false;
+  indentString_ = "";
+  writeCommentBeforeValue(root);
+  writeValue(root);
+  writeCommentAfterValueOnSameLine(root);
+  document_ += "\n";
+  return document_;
+}
+
+void StyledWriter::writeValue(const Value& value) {
+  switch (value.type()) {
+  case nullValue:
+    pushValue("null");
+    break;
+  case intValue:
+    pushValue(valueToString(value.asLargestInt()));
+    break;
+  case uintValue:
+    pushValue(valueToString(value.asLargestUInt()));
+    break;
+  case realValue:
+    pushValue(valueToString(value.asDouble()));
+    break;
+  case stringValue:
+  {
+    // Is NULL possible for value.string_? No.
+    char const* str;
+    char const* end;
+    bool ok = value.getString(&str, &end);
+    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+    else pushValue("");
+    break;
+  }
+  case booleanValue:
+    pushValue(valueToString(value.asBool()));
+    break;
+  case arrayValue:
+    writeArrayValue(value);
+    break;
+  case objectValue: {
+    Value::Members members(value.getMemberNames());
+    if (members.empty())
+      pushValue("{}");
+    else {
+      writeWithIndent("{");
+      indent();
+      Value::Members::iterator it = members.begin();
+      for (;;) {
+        const JSONCPP_STRING& name = *it;
+        const Value& childValue = value[name];
+        writeCommentBeforeValue(childValue);
+        writeWithIndent(valueToQuotedString(name.c_str()));
+        document_ += " : ";
+        writeValue(childValue);
+        if (++it == members.end()) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        document_ += ',';
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("}");
+    }
+  } break;
+  }
+}
+
+void StyledWriter::writeArrayValue(const Value& value) {
+  unsigned size = value.size();
+  if (size == 0)
+    pushValue("[]");
+  else {
+    bool isArrayMultiLine = isMultineArray(value);
+    if (isArrayMultiLine) {
+      writeWithIndent("[");
+      indent();
+      bool hasChildValue = !childValues_.empty();
+      unsigned index = 0;
+      for (;;) {
+        const Value& childValue = value[index];
+        writeCommentBeforeValue(childValue);
+        if (hasChildValue)
+          writeWithIndent(childValues_[index]);
+        else {
+          writeIndent();
+          writeValue(childValue);
+        }
+        if (++index == size) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        document_ += ',';
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("]");
+    } else // output on a single line
+    {
+      assert(childValues_.size() == size);
+      document_ += "[ ";
+      for (unsigned index = 0; index < size; ++index) {
+        if (index > 0)
+          document_ += ", ";
+        document_ += childValues_[index];
+      }
+      document_ += " ]";
+    }
+  }
+}
+
+bool StyledWriter::isMultineArray(const Value& value) {
+  ArrayIndex const size = value.size();
+  bool isMultiLine = size * 3 >= rightMargin_;
+  childValues_.clear();
+  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
+    const Value& childValue = value[index];
+    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+                        childValue.size() > 0);
+  }
+  if (!isMultiLine) // check if line length > max line length
+  {
+    childValues_.reserve(size);
+    addChildValues_ = true;
+    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+    for (ArrayIndex index = 0; index < size; ++index) {
+      if (hasCommentForValue(value[index])) {
+        isMultiLine = true;
+      }
+      writeValue(value[index]);
+      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
+    }
+    addChildValues_ = false;
+    isMultiLine = isMultiLine || lineLength >= rightMargin_;
+  }
+  return isMultiLine;
+}
+
+void StyledWriter::pushValue(const JSONCPP_STRING& value) {
+  if (addChildValues_)
+    childValues_.push_back(value);
+  else
+    document_ += value;
+}
+
+void StyledWriter::writeIndent() {
+  if (!document_.empty()) {
+    char last = document_[document_.length() - 1];
+    if (last == ' ') // already indented
+      return;
+    if (last != '\n') // Comments may add new-line
+      document_ += '\n';
+  }
+  document_ += indentString_;
+}
+
+void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
+  writeIndent();
+  document_ += value;
+}
+
+void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }
+
+void StyledWriter::unindent() {
+  assert(indentString_.size() >= indentSize_);
+  indentString_.resize(indentString_.size() - indentSize_);
+}
+
+void StyledWriter::writeCommentBeforeValue(const Value& root) {
+  if (!root.hasComment(commentBefore))
+    return;
+
+  document_ += "\n";
+  writeIndent();
+  const JSONCPP_STRING& comment = root.getComment(commentBefore);
+  JSONCPP_STRING::const_iterator iter = comment.begin();
+  while (iter != comment.end()) {
+    document_ += *iter;
+    if (*iter == '\n' &&
+       (iter != comment.end() && *(iter + 1) == '/'))
+      writeIndent();
+    ++iter;
+  }
+
+  // Comments are stripped of trailing newlines, so add one here
+  document_ += "\n";
+}
+
+void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+  if (root.hasComment(commentAfterOnSameLine))
+    document_ += " " + root.getComment(commentAfterOnSameLine);
+
+  if (root.hasComment(commentAfter)) {
+    document_ += "\n";
+    document_ += root.getComment(commentAfter);
+    document_ += "\n";
+  }
+}
+
+bool StyledWriter::hasCommentForValue(const Value& value) {
+  return value.hasComment(commentBefore) ||
+         value.hasComment(commentAfterOnSameLine) ||
+         value.hasComment(commentAfter);
+}
+
+// Class StyledStreamWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
+    : document_(NULL), rightMargin_(74), indentation_(indentation),
+      addChildValues_() {}
+
+void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
+  document_ = &out;
+  addChildValues_ = false;
+  indentString_ = "";
+  indented_ = true;
+  writeCommentBeforeValue(root);
+  if (!indented_) writeIndent();
+  indented_ = true;
+  writeValue(root);
+  writeCommentAfterValueOnSameLine(root);
+  *document_ << "\n";
+  document_ = NULL; // Forget the stream, for safety.
+}
+
+void StyledStreamWriter::writeValue(const Value& value) {
+  switch (value.type()) {
+  case nullValue:
+    pushValue("null");
+    break;
+  case intValue:
+    pushValue(valueToString(value.asLargestInt()));
+    break;
+  case uintValue:
+    pushValue(valueToString(value.asLargestUInt()));
+    break;
+  case realValue:
+    pushValue(valueToString(value.asDouble()));
+    break;
+  case stringValue:
+  {
+    // Is NULL possible for value.string_? No.
+    char const* str;
+    char const* end;
+    bool ok = value.getString(&str, &end);
+    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+    else pushValue("");
+    break;
+  }
+  case booleanValue:
+    pushValue(valueToString(value.asBool()));
+    break;
+  case arrayValue:
+    writeArrayValue(value);
+    break;
+  case objectValue: {
+    Value::Members members(value.getMemberNames());
+    if (members.empty())
+      pushValue("{}");
+    else {
+      writeWithIndent("{");
+      indent();
+      Value::Members::iterator it = members.begin();
+      for (;;) {
+        const JSONCPP_STRING& name = *it;
+        const Value& childValue = value[name];
+        writeCommentBeforeValue(childValue);
+        writeWithIndent(valueToQuotedString(name.c_str()));
+        *document_ << " : ";
+        writeValue(childValue);
+        if (++it == members.end()) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        *document_ << ",";
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("}");
+    }
+  } break;
+  }
+}
+
+void StyledStreamWriter::writeArrayValue(const Value& value) {
+  unsigned size = value.size();
+  if (size == 0)
+    pushValue("[]");
+  else {
+    bool isArrayMultiLine = isMultineArray(value);
+    if (isArrayMultiLine) {
+      writeWithIndent("[");
+      indent();
+      bool hasChildValue = !childValues_.empty();
+      unsigned index = 0;
+      for (;;) {
+        const Value& childValue = value[index];
+        writeCommentBeforeValue(childValue);
+        if (hasChildValue)
+          writeWithIndent(childValues_[index]);
+        else {
+          if (!indented_) writeIndent();
+          indented_ = true;
+          writeValue(childValue);
+          indented_ = false;
+        }
+        if (++index == size) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        *document_ << ",";
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("]");
+    } else // output on a single line
+    {
+      assert(childValues_.size() == size);
+      *document_ << "[ ";
+      for (unsigned index = 0; index < size; ++index) {
+        if (index > 0)
+          *document_ << ", ";
+        *document_ << childValues_[index];
+      }
+      *document_ << " ]";
+    }
+  }
+}
+
+bool StyledStreamWriter::isMultineArray(const Value& value) {
+  ArrayIndex const size = value.size();
+  bool isMultiLine = size * 3 >= rightMargin_;
+  childValues_.clear();
+  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
+    const Value& childValue = value[index];
+    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+                        childValue.size() > 0);
+  }
+  if (!isMultiLine) // check if line length > max line length
+  {
+    childValues_.reserve(size);
+    addChildValues_ = true;
+    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+    for (ArrayIndex index = 0; index < size; ++index) {
+      if (hasCommentForValue(value[index])) {
+        isMultiLine = true;
+      }
+      writeValue(value[index]);
+      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
+    }
+    addChildValues_ = false;
+    isMultiLine = isMultiLine || lineLength >= rightMargin_;
+  }
+  return isMultiLine;
+}
+
+void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) {
+  if (addChildValues_)
+    childValues_.push_back(value);
+  else
+    *document_ << value;
+}
+
+void StyledStreamWriter::writeIndent() {
+  // blep intended this to look at the so-far-written string
+  // to determine whether we are already indented, but
+  // with a stream we cannot do that. So we rely on some saved state.
+  // The caller checks indented_.
+  *document_ << '\n' << indentString_;
+}
+
+void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
+  if (!indented_) writeIndent();
+  *document_ << value;
+  indented_ = false;
+}
+
+void StyledStreamWriter::indent() { indentString_ += indentation_; }
+
+void StyledStreamWriter::unindent() {
+  assert(indentString_.size() >= indentation_.size());
+  indentString_.resize(indentString_.size() - indentation_.size());
+}
+
+void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
+  if (!root.hasComment(commentBefore))
+    return;
+
+  if (!indented_) writeIndent();
+  const JSONCPP_STRING& comment = root.getComment(commentBefore);
+  JSONCPP_STRING::const_iterator iter = comment.begin();
+  while (iter != comment.end()) {
+    *document_ << *iter;
+    if (*iter == '\n' &&
+       (iter != comment.end() && *(iter + 1) == '/'))
+      // writeIndent();  // would include newline
+      *document_ << indentString_;
+    ++iter;
+  }
+  indented_ = false;
+}
+
+void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+  if (root.hasComment(commentAfterOnSameLine))
+    *document_ << ' ' << root.getComment(commentAfterOnSameLine);
+
+  if (root.hasComment(commentAfter)) {
+    writeIndent();
+    *document_ << root.getComment(commentAfter);
+  }
+  indented_ = false;
+}
+
+bool StyledStreamWriter::hasCommentForValue(const Value& value) {
+  return value.hasComment(commentBefore) ||
+         value.hasComment(commentAfterOnSameLine) ||
+         value.hasComment(commentAfter);
+}
+
+//////////////////////////
+// BuiltStyledStreamWriter
+
+/// Scoped enums are not available until C++11.
+struct CommentStyle {
+  /// Decide whether to write comments.
+  enum Enum {
+    None,  ///< Drop all comments.
+    Most,  ///< Recover odd behavior of previous versions (not implemented yet).
+    All  ///< Keep all comments.
+  };
+};
+
+struct BuiltStyledStreamWriter : public StreamWriter
+{
+  BuiltStyledStreamWriter(
+      JSONCPP_STRING const& indentation,
+      CommentStyle::Enum cs,
+      JSONCPP_STRING const& colonSymbol,
+      JSONCPP_STRING const& nullSymbol,
+      JSONCPP_STRING const& endingLineFeedSymbol,
+      bool useSpecialFloats,
+      unsigned int precision);
+  int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
+private:
+  void writeValue(Value const& value);
+  void writeArrayValue(Value const& value);
+  bool isMultineArray(Value const& value);
+  void pushValue(JSONCPP_STRING const& value);
+  void writeIndent();
+  void writeWithIndent(JSONCPP_STRING const& value);
+  void indent();
+  void unindent();
+  void writeCommentBeforeValue(Value const& root);
+  void writeCommentAfterValueOnSameLine(Value const& root);
+  static bool hasCommentForValue(const Value& value);
+
+  typedef std::vector<JSONCPP_STRING> ChildValues;
+
+  ChildValues childValues_;
+  JSONCPP_STRING indentString_;
+  unsigned int rightMargin_;
+  JSONCPP_STRING indentation_;
+  CommentStyle::Enum cs_;
+  JSONCPP_STRING colonSymbol_;
+  JSONCPP_STRING nullSymbol_;
+  JSONCPP_STRING endingLineFeedSymbol_;
+  bool addChildValues_ : 1;
+  bool indented_ : 1;
+  bool useSpecialFloats_ : 1;
+  unsigned int precision_;
+};
+BuiltStyledStreamWriter::BuiltStyledStreamWriter(
+      JSONCPP_STRING const& indentation,
+      CommentStyle::Enum cs,
+      JSONCPP_STRING const& colonSymbol,
+      JSONCPP_STRING const& nullSymbol,
+      JSONCPP_STRING const& endingLineFeedSymbol,
+      bool useSpecialFloats,
+      unsigned int precision)
+  : rightMargin_(74)
+  , indentation_(indentation)
+  , cs_(cs)
+  , colonSymbol_(colonSymbol)
+  , nullSymbol_(nullSymbol)
+  , endingLineFeedSymbol_(endingLineFeedSymbol)
+  , addChildValues_(false)
+  , indented_(false)
+  , useSpecialFloats_(useSpecialFloats)
+  , precision_(precision)
+{
+}
+int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
+{
+  sout_ = sout;
+  addChildValues_ = false;
+  indented_ = true;
+  indentString_ = "";
+  writeCommentBeforeValue(root);
+  if (!indented_) writeIndent();
+  indented_ = true;
+  writeValue(root);
+  writeCommentAfterValueOnSameLine(root);
+  *sout_ << endingLineFeedSymbol_;
+  sout_ = NULL;
+  return 0;
+}
+void BuiltStyledStreamWriter::writeValue(Value const& value) {
+  switch (value.type()) {
+  case nullValue:
+    pushValue(nullSymbol_);
+    break;
+  case intValue:
+    pushValue(valueToString(value.asLargestInt()));
+    break;
+  case uintValue:
+    pushValue(valueToString(value.asLargestUInt()));
+    break;
+  case realValue:
+    pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
+    break;
+  case stringValue:
+  {
+    // Is NULL is possible for value.string_? No.
+    char const* str;
+    char const* end;
+    bool ok = value.getString(&str, &end);
+    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+    else pushValue("");
+    break;
+  }
+  case booleanValue:
+    pushValue(valueToString(value.asBool()));
+    break;
+  case arrayValue:
+    writeArrayValue(value);
+    break;
+  case objectValue: {
+    Value::Members members(value.getMemberNames());
+    if (members.empty())
+      pushValue("{}");
+    else {
+      writeWithIndent("{");
+      indent();
+      Value::Members::iterator it = members.begin();
+      for (;;) {
+        JSONCPP_STRING const& name = *it;
+        Value const& childValue = value[name];
+        writeCommentBeforeValue(childValue);
+        writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
+        *sout_ << colonSymbol_;
+        writeValue(childValue);
+        if (++it == members.end()) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        *sout_ << ",";
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("}");
+    }
+  } break;
+  }
+}
+
+void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
+  unsigned size = value.size();
+  if (size == 0)
+    pushValue("[]");
+  else {
+    bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
+    if (isMultiLine) {
+      writeWithIndent("[");
+      indent();
+      bool hasChildValue = !childValues_.empty();
+      unsigned index = 0;
+      for (;;) {
+        Value const& childValue = value[index];
+        writeCommentBeforeValue(childValue);
+        if (hasChildValue)
+          writeWithIndent(childValues_[index]);
+        else {
+          if (!indented_) writeIndent();
+          indented_ = true;
+          writeValue(childValue);
+          indented_ = false;
+        }
+        if (++index == size) {
+          writeCommentAfterValueOnSameLine(childValue);
+          break;
+        }
+        *sout_ << ",";
+        writeCommentAfterValueOnSameLine(childValue);
+      }
+      unindent();
+      writeWithIndent("]");
+    } else // output on a single line
+    {
+      assert(childValues_.size() == size);
+      *sout_ << "[";
+      if (!indentation_.empty()) *sout_ << " ";
+      for (unsigned index = 0; index < size; ++index) {
+        if (index > 0)
+          *sout_ << ((!indentation_.empty()) ? ", " : ",");
+        *sout_ << childValues_[index];
+      }
+      if (!indentation_.empty()) *sout_ << " ";
+      *sout_ << "]";
+    }
+  }
+}
+
+bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
+  ArrayIndex const size = value.size();
+  bool isMultiLine = size * 3 >= rightMargin_;
+  childValues_.clear();
+  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
+    Value const& childValue = value[index];
+    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+                        childValue.size() > 0);
+  }
+  if (!isMultiLine) // check if line length > max line length
+  {
+    childValues_.reserve(size);
+    addChildValues_ = true;
+    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+    for (ArrayIndex index = 0; index < size; ++index) {
+      if (hasCommentForValue(value[index])) {
+        isMultiLine = true;
+      }
+      writeValue(value[index]);
+      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
+    }
+    addChildValues_ = false;
+    isMultiLine = isMultiLine || lineLength >= rightMargin_;
+  }
+  return isMultiLine;
+}
+
+void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) {
+  if (addChildValues_)
+    childValues_.push_back(value);
+  else
+    *sout_ << value;
+}
+
+void BuiltStyledStreamWriter::writeIndent() {
+  // blep intended this to look at the so-far-written string
+  // to determine whether we are already indented, but
+  // with a stream we cannot do that. So we rely on some saved state.
+  // The caller checks indented_.
+
+  if (!indentation_.empty()) {
+    // In this case, drop newlines too.
+    *sout_ << '\n' << indentString_;
+  }
+}
+
+void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
+  if (!indented_) writeIndent();
+  *sout_ << value;
+  indented_ = false;
+}
+
+void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
+
+void BuiltStyledStreamWriter::unindent() {
+  assert(indentString_.size() >= indentation_.size());
+  indentString_.resize(indentString_.size() - indentation_.size());
+}
+
+void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
+  if (cs_ == CommentStyle::None) return;
+  if (!root.hasComment(commentBefore))
+    return;
+
+  if (!indented_) writeIndent();
+  const JSONCPP_STRING& comment = root.getComment(commentBefore);
+  JSONCPP_STRING::const_iterator iter = comment.begin();
+  while (iter != comment.end()) {
+    *sout_ << *iter;
+    if (*iter == '\n' &&
+       (iter != comment.end() && *(iter + 1) == '/'))
+      // writeIndent();  // would write extra newline
+      *sout_ << indentString_;
+    ++iter;
+  }
+  indented_ = false;
+}
+
+void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
+  if (cs_ == CommentStyle::None) return;
+  if (root.hasComment(commentAfterOnSameLine))
+    *sout_ << " " + root.getComment(commentAfterOnSameLine);
+
+  if (root.hasComment(commentAfter)) {
+    writeIndent();
+    *sout_ << root.getComment(commentAfter);
+  }
+}
+
+// static
+bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
+  return value.hasComment(commentBefore) ||
+         value.hasComment(commentAfterOnSameLine) ||
+         value.hasComment(commentAfter);
+}
+
+///////////////
+// StreamWriter
+
+StreamWriter::StreamWriter()
+    : sout_(NULL)
+{
+}
+StreamWriter::~StreamWriter()
+{
+}
+StreamWriter::Factory::~Factory()
+{}
+StreamWriterBuilder::StreamWriterBuilder()
+{
+  setDefaults(&settings_);
+}
+StreamWriterBuilder::~StreamWriterBuilder()
+{}
+StreamWriter* StreamWriterBuilder::newStreamWriter() const
+{
+  JSONCPP_STRING indentation = settings_["indentation"].asString();
+  JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
+  bool eyc = settings_["enableYAMLCompatibility"].asBool();
+  bool dnp = settings_["dropNullPlaceholders"].asBool();
+  bool usf = settings_["useSpecialFloats"].asBool(); 
+  unsigned int pre = settings_["precision"].asUInt();
+  CommentStyle::Enum cs = CommentStyle::All;
+  if (cs_str == "All") {
+    cs = CommentStyle::All;
+  } else if (cs_str == "None") {
+    cs = CommentStyle::None;
+  } else {
+    throwRuntimeError("commentStyle must be 'All' or 'None'");
+  }
+  JSONCPP_STRING colonSymbol = " : ";
+  if (eyc) {
+    colonSymbol = ": ";
+  } else if (indentation.empty()) {
+    colonSymbol = ":";
+  }
+  JSONCPP_STRING nullSymbol = "null";
+  if (dnp) {
+    nullSymbol = "";
+  }
+  if (pre > 17) pre = 17;
+  JSONCPP_STRING endingLineFeedSymbol = "";
+  return new BuiltStyledStreamWriter(
+      indentation, cs,
+      colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
+}
+static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
+{
+  valid_keys->clear();
+  valid_keys->insert("indentation");
+  valid_keys->insert("commentStyle");
+  valid_keys->insert("enableYAMLCompatibility");
+  valid_keys->insert("dropNullPlaceholders");
+  valid_keys->insert("useSpecialFloats");
+  valid_keys->insert("precision");
+}
+bool StreamWriterBuilder::validate(Json::Value* invalid) const
+{
+  Json::Value my_invalid;
+  if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
+  Json::Value& inv = *invalid;
+  std::set<JSONCPP_STRING> valid_keys;
+  getValidWriterKeys(&valid_keys);
+  Value::Members keys = settings_.getMemberNames();
+  size_t n = keys.size();
+  for (size_t i = 0; i < n; ++i) {
+    JSONCPP_STRING const& key = keys[i];
+    if (valid_keys.find(key) == valid_keys.end()) {
+      inv[key] = settings_[key];
+    }
+  }
+  return 0u == inv.size();
+}
+Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
+{
+  return settings_[key];
+}
+// static
+void StreamWriterBuilder::setDefaults(Json::Value* settings)
+{
+  //! [StreamWriterBuilderDefaults]
+  (*settings)["commentStyle"] = "All";
+  (*settings)["indentation"] = "\t";
+  (*settings)["enableYAMLCompatibility"] = false;
+  (*settings)["dropNullPlaceholders"] = false;
+  (*settings)["useSpecialFloats"] = false;
+  (*settings)["precision"] = 17;
+  //! [StreamWriterBuilderDefaults]
+}
+
+JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) {
+  JSONCPP_OSTRINGSTREAM sout;
+  StreamWriterPtr const writer(builder.newStreamWriter());
+  writer->write(root, &sout);
+  return sout.str();
+}
+
+JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
+  StreamWriterBuilder builder;
+  StreamWriterPtr const writer(builder.newStreamWriter());
+  writer->write(root, &sout);
+  return sout;
+}
+
+} // namespace Json

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/lib_json/sconscript
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/lib_json/sconscript b/thirdparty/jsoncpp/src/lib_json/sconscript
new file mode 100644
index 0000000..6e7c6c8
--- /dev/null
+++ b/thirdparty/jsoncpp/src/lib_json/sconscript
@@ -0,0 +1,8 @@
+Import( 'env buildLibrary' )
+
+buildLibrary( env, Split( """
+    json_reader.cpp 
+    json_value.cpp 
+    json_writer.cpp
+     """ ),
+    'json' )

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/lib_json/version.h.in
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/lib_json/version.h.in b/thirdparty/jsoncpp/src/lib_json/version.h.in
new file mode 100644
index 0000000..47aac69
--- /dev/null
+++ b/thirdparty/jsoncpp/src/lib_json/version.h.in
@@ -0,0 +1,20 @@
+// DO NOT EDIT. This file (and "version") is generated by CMake.
+// Run CMake configure step to update it.
+#ifndef JSON_VERSION_H_INCLUDED
+# define JSON_VERSION_H_INCLUDED
+
+# define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@"
+# define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@
+# define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@
+# define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@
+# define JSONCPP_VERSION_QUALIFIER
+# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+
+#ifdef JSONCPP_USING_SECURE_MEMORY
+#undef JSONCPP_USING_SECURE_MEMORY
+#endif
+#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@
+// If non-zero, the library zeroes any memory that it has allocated before
+// it frees its memory.
+
+#endif // JSON_VERSION_H_INCLUDED

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/test_lib_json/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/test_lib_json/CMakeLists.txt b/thirdparty/jsoncpp/src/test_lib_json/CMakeLists.txt
new file mode 100644
index 0000000..7000264
--- /dev/null
+++ b/thirdparty/jsoncpp/src/test_lib_json/CMakeLists.txt
@@ -0,0 +1,38 @@
+# vim: et ts=4 sts=4 sw=4 tw=0
+
+ADD_EXECUTABLE( jsoncpp_test 
+                jsontest.cpp
+                jsontest.h
+                main.cpp
+                )
+
+
+IF(BUILD_SHARED_LIBS)
+    ADD_DEFINITIONS( -DJSON_DLL )
+    TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib)
+ELSE(BUILD_SHARED_LIBS)
+    TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib_static)
+ENDIF()
+
+# another way to solve issue #90
+#set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store)
+
+# Run unit tests in post-build
+# (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?)
+IF(JSONCPP_WITH_POST_BUILD_UNITTEST)
+    IF(BUILD_SHARED_LIBS)
+        # First, copy the shared lib, for Microsoft.
+        # Then, run the test executable.
+        ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
+                            POST_BUILD
+                            COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:jsoncpp_lib> $<TARGET_FILE_DIR:jsoncpp_test>
+                            COMMAND $<TARGET_FILE:jsoncpp_test>)
+    ELSE(BUILD_SHARED_LIBS)
+        # Just run the test executable.
+        ADD_CUSTOM_COMMAND( TARGET jsoncpp_test
+                            POST_BUILD
+                            COMMAND $<TARGET_FILE:jsoncpp_test>)
+    ENDIF()
+ENDIF()
+
+SET_TARGET_PROPERTIES(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) 

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/test_lib_json/jsontest.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/test_lib_json/jsontest.cpp b/thirdparty/jsoncpp/src/test_lib_json/jsontest.cpp
new file mode 100644
index 0000000..4c10a37
--- /dev/null
+++ b/thirdparty/jsoncpp/src/test_lib_json/jsontest.cpp
@@ -0,0 +1,457 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC
+#include "jsontest.h"
+#include <stdio.h>
+#include <string>
+
+#if defined(_MSC_VER)
+// Used to install a report hook that prevent dialog on assertion and error.
+#include <crtdbg.h>
+#endif // if defined(_MSC_VER)
+
+#if defined(_WIN32)
+// Used to prevent dialog on memory fault.
+// Limits headers included by Windows.h
+#define WIN32_LEAN_AND_MEAN
+#define NOSERVICE
+#define NOMCX
+#define NOIME
+#define NOSOUND
+#define NOCOMM
+#define NORPC
+#define NOGDI
+#define NOUSER
+#define NODRIVERS
+#define NOLOGERROR
+#define NOPROFILER
+#define NOMEMMGR
+#define NOLFILEIO
+#define NOOPENFILE
+#define NORESOURCE
+#define NOATOM
+#define NOLANGUAGE
+#define NOLSTRING
+#define NODBCS
+#define NOKEYBOARDINFO
+#define NOGDICAPMASKS
+#define NOCOLOR
+#define NOGDIOBJ
+#define NODRAWTEXT
+#define NOTEXTMETRIC
+#define NOSCALABLEFONT
+#define NOBITMAP
+#define NORASTEROPS
+#define NOMETAFILE
+#define NOSYSMETRICS
+#define NOSYSTEMPARAMSINFO
+#define NOMSG
+#define NOWINSTYLES
+#define NOWINOFFSETS
+#define NOSHOWWINDOW
+#define NODEFERWINDOWPOS
+#define NOVIRTUALKEYCODES
+#define NOKEYSTATES
+#define NOWH
+#define NOMENUS
+#define NOSCROLL
+#define NOCLIPBOARD
+#define NOICONS
+#define NOMB
+#define NOSYSCOMMANDS
+#define NOMDI
+#define NOCTLMGR
+#define NOWINMESSAGES
+#include <windows.h>
+#endif // if defined(_WIN32)
+
+namespace JsonTest {
+
+// class TestResult
+// //////////////////////////////////////////////////////////////////
+
+TestResult::TestResult()
+    : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(0) {
+  // The root predicate has id 0
+  rootPredicateNode_.id_ = 0;
+  rootPredicateNode_.next_ = 0;
+  predicateStackTail_ = &rootPredicateNode_;
+}
+
+void TestResult::setTestName(const JSONCPP_STRING& name) { name_ = name; }
+
+TestResult&
+TestResult::addFailure(const char* file, unsigned int line, const char* expr) {
+  /// Walks the PredicateContext stack adding them to failures_ if not already
+  /// added.
+  unsigned int nestingLevel = 0;
+  PredicateContext* lastNode = rootPredicateNode_.next_;
+  for (; lastNode != 0; lastNode = lastNode->next_) {
+    if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext
+    {
+      lastUsedPredicateId_ = lastNode->id_;
+      addFailureInfo(
+          lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel);
+      // Link the PredicateContext to the failure for message target when
+      // popping the PredicateContext.
+      lastNode->failure_ = &(failures_.back());
+    }
+    ++nestingLevel;
+  }
+
+  // Adds the failed assertion
+  addFailureInfo(file, line, expr, nestingLevel);
+  messageTarget_ = &(failures_.back());
+  return *this;
+}
+
+void TestResult::addFailureInfo(const char* file,
+                                unsigned int line,
+                                const char* expr,
+                                unsigned int nestingLevel) {
+  Failure failure;
+  failure.file_ = file;
+  failure.line_ = line;
+  if (expr) {
+    failure.expr_ = expr;
+  }
+  failure.nestingLevel_ = nestingLevel;
+  failures_.push_back(failure);
+}
+
+TestResult& TestResult::popPredicateContext() {
+  PredicateContext* lastNode = &rootPredicateNode_;
+  while (lastNode->next_ != 0 && lastNode->next_->next_ != 0) {
+    lastNode = lastNode->next_;
+  }
+  // Set message target to popped failure
+  PredicateContext* tail = lastNode->next_;
+  if (tail != 0 && tail->failure_ != 0) {
+    messageTarget_ = tail->failure_;
+  }
+  // Remove tail from list
+  predicateStackTail_ = lastNode;
+  lastNode->next_ = 0;
+  return *this;
+}
+
+bool TestResult::failed() const { return !failures_.empty(); }
+
+unsigned int TestResult::getAssertionNestingLevel() const {
+  unsigned int level = 0;
+  const PredicateContext* lastNode = &rootPredicateNode_;
+  while (lastNode->next_ != 0) {
+    lastNode = lastNode->next_;
+    ++level;
+  }
+  return level;
+}
+
+void TestResult::printFailure(bool printTestName) const {
+  if (failures_.empty()) {
+    return;
+  }
+
+  if (printTestName) {
+    printf("* Detail of %s test failure:\n", name_.c_str());
+  }
+
+  // Print in reverse to display the callstack in the right order
+  Failures::const_iterator itEnd = failures_.end();
+  for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) {
+    const Failure& failure = *it;
+    JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' ');
+    if (failure.file_) {
+      printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_);
+    }
+    if (!failure.expr_.empty()) {
+      printf("%s\n", failure.expr_.c_str());
+    } else if (failure.file_) {
+      printf("\n");
+    }
+    if (!failure.message_.empty()) {
+      JSONCPP_STRING reindented = indentText(failure.message_, indent + "  ");
+      printf("%s\n", reindented.c_str());
+    }
+  }
+}
+
+JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text,
+                                   const JSONCPP_STRING& indent) {
+  JSONCPP_STRING reindented;
+  JSONCPP_STRING::size_type lastIndex = 0;
+  while (lastIndex < text.size()) {
+    JSONCPP_STRING::size_type nextIndex = text.find('\n', lastIndex);
+    if (nextIndex == JSONCPP_STRING::npos) {
+      nextIndex = text.size() - 1;
+    }
+    reindented += indent;
+    reindented += text.substr(lastIndex, nextIndex - lastIndex + 1);
+    lastIndex = nextIndex + 1;
+  }
+  return reindented;
+}
+
+TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) {
+  if (messageTarget_ != 0) {
+    messageTarget_->message_ += message;
+  }
+  return *this;
+}
+
+TestResult& TestResult::operator<<(Json::Int64 value) {
+  return addToLastFailure(Json::valueToString(value));
+}
+
+TestResult& TestResult::operator<<(Json::UInt64 value) {
+  return addToLastFailure(Json::valueToString(value));
+}
+
+TestResult& TestResult::operator<<(bool value) {
+  return addToLastFailure(value ? "true" : "false");
+}
+
+// class TestCase
+// //////////////////////////////////////////////////////////////////
+
+TestCase::TestCase() : result_(0) {}
+
+TestCase::~TestCase() {}
+
+void TestCase::run(TestResult& result) {
+  result_ = &result;
+  runTestCase();
+}
+
+// class Runner
+// //////////////////////////////////////////////////////////////////
+
+Runner::Runner() {}
+
+Runner& Runner::add(TestCaseFactory factory) {
+  tests_.push_back(factory);
+  return *this;
+}
+
+unsigned int Runner::testCount() const {
+  return static_cast<unsigned int>(tests_.size());
+}
+
+JSONCPP_STRING Runner::testNameAt(unsigned int index) const {
+  TestCase* test = tests_[index]();
+  JSONCPP_STRING name = test->testName();
+  delete test;
+  return name;
+}
+
+void Runner::runTestAt(unsigned int index, TestResult& result) const {
+  TestCase* test = tests_[index]();
+  result.setTestName(test->testName());
+  printf("Testing %s: ", test->testName());
+  fflush(stdout);
+#if JSON_USE_EXCEPTION
+  try {
+#endif // if JSON_USE_EXCEPTION
+    test->run(result);
+#if JSON_USE_EXCEPTION
+  }
+  catch (const std::exception& e) {
+    result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:")
+        << e.what();
+  }
+#endif // if JSON_USE_EXCEPTION
+  delete test;
+  const char* status = result.failed() ? "FAILED" : "OK";
+  printf("%s\n", status);
+  fflush(stdout);
+}
+
+bool Runner::runAllTest(bool printSummary) const {
+  unsigned int count = testCount();
+  std::deque<TestResult> failures;
+  for (unsigned int index = 0; index < count; ++index) {
+    TestResult result;
+    runTestAt(index, result);
+    if (result.failed()) {
+      failures.push_back(result);
+    }
+  }
+
+  if (failures.empty()) {
+    if (printSummary) {
+      printf("All %d tests passed\n", count);
+    }
+    return true;
+  } else {
+    for (unsigned int index = 0; index < failures.size(); ++index) {
+      TestResult& result = failures[index];
+      result.printFailure(count > 1);
+    }
+
+    if (printSummary) {
+      unsigned int failedCount = static_cast<unsigned int>(failures.size());
+      unsigned int passedCount = count - failedCount;
+      printf("%d/%d tests passed (%d failure(s))\n",
+             passedCount,
+             count,
+             failedCount);
+    }
+    return false;
+  }
+}
+
+bool Runner::testIndex(const JSONCPP_STRING& testName,
+                       unsigned int& indexOut) const {
+  unsigned int count = testCount();
+  for (unsigned int index = 0; index < count; ++index) {
+    if (testNameAt(index) == testName) {
+      indexOut = index;
+      return true;
+    }
+  }
+  return false;
+}
+
+void Runner::listTests() const {
+  unsigned int count = testCount();
+  for (unsigned int index = 0; index < count; ++index) {
+    printf("%s\n", testNameAt(index).c_str());
+  }
+}
+
+int Runner::runCommandLine(int argc, const char* argv[]) const {
+  // typedef std::deque<JSONCPP_STRING> TestNames;
+  Runner subrunner;
+  for (int index = 1; index < argc; ++index) {
+    JSONCPP_STRING opt = argv[index];
+    if (opt == "--list-tests") {
+      listTests();
+      return 0;
+    } else if (opt == "--test-auto") {
+      preventDialogOnCrash();
+    } else if (opt == "--test") {
+      ++index;
+      if (index < argc) {
+        unsigned int testNameIndex;
+        if (testIndex(argv[index], testNameIndex)) {
+          subrunner.add(tests_[testNameIndex]);
+        } else {
+          fprintf(stderr, "Test '%s' does not exist!\n", argv[index]);
+          return 2;
+        }
+      } else {
+        printUsage(argv[0]);
+        return 2;
+      }
+    } else {
+      printUsage(argv[0]);
+      return 2;
+    }
+  }
+  bool succeeded;
+  if (subrunner.testCount() > 0) {
+    succeeded = subrunner.runAllTest(subrunner.testCount() > 1);
+  } else {
+    succeeded = runAllTest(true);
+  }
+  return succeeded ? 0 : 1;
+}
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+// Hook MSVCRT assertions to prevent dialog from appearing
+static int
+msvcrtSilentReportHook(int reportType, char* message, int* /*returnValue*/) {
+  // The default CRT handling of error and assertion is to display
+  // an error dialog to the user.
+  // Instead, when an error or an assertion occurs, we force the
+  // application to terminate using abort() after display
+  // the message on stderr.
+  if (reportType == _CRT_ERROR || reportType == _CRT_ASSERT) {
+    // calling abort() cause the ReportHook to be called
+    // The following is used to detect this case and let's the
+    // error handler fallback on its default behaviour (
+    // display a warning message)
+    static volatile bool isAborting = false;
+    if (isAborting) {
+      return TRUE;
+    }
+    isAborting = true;
+
+    fprintf(stderr, "CRT Error/Assert:\n%s\n", message);
+    fflush(stderr);
+    abort();
+  }
+  // Let's other reportType (_CRT_WARNING) be handled as they would by default
+  return FALSE;
+}
+#endif // if defined(_MSC_VER)
+
+void Runner::preventDialogOnCrash() {
+#if defined(_MSC_VER) && defined(_DEBUG)
+  // Install a hook to prevent MSVCRT error and assertion from
+  // popping a dialog
+  // This function a NO-OP in release configuration
+  // (which cause warning since msvcrtSilentReportHook is not referenced)
+  _CrtSetReportHook(&msvcrtSilentReportHook);
+#endif // if defined(_MSC_VER)
+
+// @todo investiguate this handler (for buffer overflow)
+// _set_security_error_handler
+
+#if defined(_WIN32)
+  // Prevents the system from popping a dialog for debugging if the
+  // application fails due to invalid memory access.
+  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+               SEM_NOOPENFILEERRORBOX);
+#endif // if defined(_WIN32)
+}
+
+void Runner::printUsage(const char* appName) {
+  printf("Usage: %s [options]\n"
+         "\n"
+         "If --test is not specified, then all the test cases be run.\n"
+         "\n"
+         "Valid options:\n"
+         "--list-tests: print the name of all test cases on the standard\n"
+         "              output and exit.\n"
+         "--test TESTNAME: executes the test case with the specified name.\n"
+         "                 May be repeated.\n"
+         "--test-auto: prevent dialog prompting for debugging on crash.\n",
+         appName);
+}
+
+// Assertion functions
+// //////////////////////////////////////////////////////////////////
+
+JSONCPP_STRING ToJsonString(const char* toConvert) {
+  return JSONCPP_STRING(toConvert);
+}
+
+JSONCPP_STRING ToJsonString(JSONCPP_STRING in) {
+  return in;
+}
+
+#if JSONCPP_USING_SECURE_MEMORY
+JSONCPP_STRING ToJsonString(std::string in) {
+  return JSONCPP_STRING(in.data(), in.data() + in.length());
+}
+#endif
+
+TestResult& checkStringEqual(TestResult& result,
+                             const JSONCPP_STRING& expected,
+                             const JSONCPP_STRING& actual,
+                             const char* file,
+                             unsigned int line,
+                             const char* expr) {
+  if (expected != actual) {
+    result.addFailure(file, line, expr);
+    result << "Expected: '" << expected << "'\n";
+    result << "Actual  : '" << actual << "'";
+  }
+  return result;
+}
+
+} // namespace JsonTest

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/126c2ed5/thirdparty/jsoncpp/src/test_lib_json/jsontest.h
----------------------------------------------------------------------
diff --git a/thirdparty/jsoncpp/src/test_lib_json/jsontest.h b/thirdparty/jsoncpp/src/test_lib_json/jsontest.h
new file mode 100644
index 0000000..f0ba1fa
--- /dev/null
+++ b/thirdparty/jsoncpp/src/test_lib_json/jsontest.h
@@ -0,0 +1,286 @@
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSONTEST_H_INCLUDED
+#define JSONTEST_H_INCLUDED
+
+#include <json/config.h>
+#include <json/value.h>
+#include <json/writer.h>
+#include <stdio.h>
+#include <deque>
+#include <sstream>
+#include <string>
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// Mini Unit Testing framework
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/** \brief Unit testing framework.
+ * \warning: all assertions are non-aborting, test case execution will continue
+ *           even if an assertion namespace.
+ *           This constraint is for portability: the framework needs to compile
+ *           on Visual Studio 6 and must not require exception usage.
+ */
+namespace JsonTest {
+
+class Failure {
+public:
+  const char* file_;
+  unsigned int line_;
+  JSONCPP_STRING expr_;
+  JSONCPP_STRING message_;
+  unsigned int nestingLevel_;
+};
+
+/// Context used to create the assertion callstack on failure.
+/// Must be a POD to allow inline initialisation without stepping
+/// into the debugger.
+struct PredicateContext {
+  typedef unsigned int Id;
+  Id id_;
+  const char* file_;
+  unsigned int line_;
+  const char* expr_;
+  PredicateContext* next_;
+  /// Related Failure, set when the PredicateContext is converted
+  /// into a Failure.
+  Failure* failure_;
+};
+
+class TestResult {
+public:
+  TestResult();
+
+  /// \internal Implementation detail for assertion macros
+  /// Not encapsulated to prevent step into when debugging failed assertions
+  /// Incremented by one on assertion predicate entry, decreased by one
+  /// by addPredicateContext().
+  PredicateContext::Id predicateId_;
+
+  /// \internal Implementation detail for predicate macros
+  PredicateContext* predicateStackTail_;
+
+  void setTestName(const JSONCPP_STRING& name);
+
+  /// Adds an assertion failure.
+  TestResult&
+  addFailure(const char* file, unsigned int line, const char* expr = 0);
+
+  /// Removes the last PredicateContext added to the predicate stack
+  /// chained list.
+  /// Next messages will be targed at the PredicateContext that was removed.
+  TestResult& popPredicateContext();
+
+  bool failed() const;
+
+  void printFailure(bool printTestName) const;
+
+  // Generic operator that will work with anything ostream can deal with.
+  template <typename T> TestResult& operator<<(const T& value) {
+    JSONCPP_OSTRINGSTREAM oss;
+    oss.precision(16);
+    oss.setf(std::ios_base::floatfield);
+    oss << value;
+    return addToLastFailure(oss.str());
+  }
+
+  // Specialized versions.
+  TestResult& operator<<(bool value);
+  // std:ostream does not support 64bits integers on all STL implementation
+  TestResult& operator<<(Json::Int64 value);
+  TestResult& operator<<(Json::UInt64 value);
+
+private:
+  TestResult& addToLastFailure(const JSONCPP_STRING& message);
+  unsigned int getAssertionNestingLevel() const;
+  /// Adds a failure or a predicate context
+  void addFailureInfo(const char* file,
+                      unsigned int line,
+                      const char* expr,
+                      unsigned int nestingLevel);
+  static JSONCPP_STRING indentText(const JSONCPP_STRING& text,
+                                const JSONCPP_STRING& indent);
+
+  typedef std::deque<Failure> Failures;
+  Failures failures_;
+  JSONCPP_STRING name_;
+  PredicateContext rootPredicateNode_;
+  PredicateContext::Id lastUsedPredicateId_;
+  /// Failure which is the target of the messages added using operator <<
+  Failure* messageTarget_;
+};
+
+class TestCase {
+public:
+  TestCase();
+
+  virtual ~TestCase();
+
+  void run(TestResult& result);
+
+  virtual const char* testName() const = 0;
+
+protected:
+  TestResult* result_;
+
+private:
+  virtual void runTestCase() = 0;
+};
+
+/// Function pointer type for TestCase factory
+typedef TestCase* (*TestCaseFactory)();
+
+class Runner {
+public:
+  Runner();
+
+  /// Adds a test to the suite
+  Runner& add(TestCaseFactory factory);
+
+  /// Runs test as specified on the command-line
+  /// If no command-line arguments are provided, run all tests.
+  /// If --list-tests is provided, then print the list of all test cases
+  /// If --test <testname> is provided, then run test testname.
+  int runCommandLine(int argc, const char* argv[]) const;
+
+  /// Runs all the test cases
+  bool runAllTest(bool printSummary) const;
+
+  /// Returns the number of test case in the suite
+  unsigned int testCount() const;
+
+  /// Returns the name of the test case at the specified index
+  JSONCPP_STRING testNameAt(unsigned int index) const;
+
+  /// Runs the test case at the specified index using the specified TestResult
+  void runTestAt(unsigned int index, TestResult& result) const;
+
+  static void printUsage(const char* appName);
+
+private: // prevents copy construction and assignment
+  Runner(const Runner& other);
+  Runner& operator=(const Runner& other);
+
+private:
+  void listTests() const;
+  bool testIndex(const JSONCPP_STRING& testName, unsigned int& index) const;
+  static void preventDialogOnCrash();
+
+private:
+  typedef std::deque<TestCaseFactory> Factories;
+  Factories tests_;
+};
+
+template <typename T, typename U>
+TestResult& checkEqual(TestResult& result,
+                       T expected,
+                       U actual,
+                       const char* file,
+                       unsigned int line,
+                       const char* expr) {
+  if (static_cast<U>(expected) != actual) {
+    result.addFailure(file, line, expr);
+    result << "Expected: " << static_cast<U>(expected) << "\n";
+    result << "Actual  : " << actual;
+  }
+  return result;
+}
+
+JSONCPP_STRING ToJsonString(const char* toConvert);
+JSONCPP_STRING ToJsonString(JSONCPP_STRING in);
+#if JSONCPP_USING_SECURE_MEMORY
+JSONCPP_STRING ToJsonString(std::string in);
+#endif
+
+TestResult& checkStringEqual(TestResult& result,
+                             const JSONCPP_STRING& expected,
+                             const JSONCPP_STRING& actual,
+                             const char* file,
+                             unsigned int line,
+                             const char* expr);
+
+} // namespace JsonTest
+
+/// \brief Asserts that the given expression is true.
+/// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y;
+/// JSONTEST_ASSERT( x == y );
+#define JSONTEST_ASSERT(expr)                                                  \
+  if (expr) {                                                                  \
+  } else                                                                       \
+  result_->addFailure(__FILE__, __LINE__, #expr)
+
+/// \brief Asserts that the given predicate is true.
+/// The predicate may do other assertions and be a member function of the
+/// fixture.
+#define JSONTEST_ASSERT_PRED(expr)                                             \
+  {                                                                            \
+    JsonTest::PredicateContext _minitest_Context = {                           \
+      result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL             \
+    };                                                                         \
+    result_->predicateStackTail_->next_ = &_minitest_Context;                  \
+    result_->predicateId_ += 1;                                                \
+    result_->predicateStackTail_ = &_minitest_Context;                         \
+    (expr);                                                                    \
+    result_->popPredicateContext();                                            \
+  }
+
+/// \brief Asserts that two values are equals.
+#define JSONTEST_ASSERT_EQUAL(expected, actual)                                \
+  JsonTest::checkEqual(*result_,                                               \
+                       expected,                                               \
+                       actual,                                                 \
+                       __FILE__,                                               \
+                       __LINE__,                                               \
+                       #expected " == " #actual)
+
+/// \brief Asserts that two values are equals.
+#define JSONTEST_ASSERT_STRING_EQUAL(expected, actual)                         \
+  JsonTest::checkStringEqual(*result_,                                         \
+		                 JsonTest::ToJsonString(expected),                 \
+		                     JsonTest::ToJsonString(actual),                   \
+                             __FILE__,                                         \
+                             __LINE__,                                         \
+                             #expected " == " #actual)
+
+/// \brief Asserts that a given expression throws an exception
+#define JSONTEST_ASSERT_THROWS(expr)                                           \
+  {                                                                            \
+    bool _threw = false;                                                       \
+    try {                                                                      \
+      expr;                                                                    \
+    }                                                                          \
+    catch (...) {                                                              \
+      _threw = true;                                                           \
+    }                                                                          \
+    if (!_threw)                                                               \
+      result_->addFailure(                                                     \
+          __FILE__, __LINE__, "expected exception thrown: " #expr);            \
+  }
+
+/// \brief Begin a fixture test case.
+#define JSONTEST_FIXTURE(FixtureType, name)                                    \
+  class Test##FixtureType##name : public FixtureType {                         \
+  public:                                                                      \
+    static JsonTest::TestCase* factory() {                                     \
+      return new Test##FixtureType##name();                                    \
+    }                                                                          \
+                                                                               \
+  public: /* overidden from TestCase */                                        \
+    const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; }    \
+    void runTestCase() JSONCPP_OVERRIDE;                                                \
+  };                                                                           \
+                                                                               \
+  void Test##FixtureType##name::runTestCase()
+
+#define JSONTEST_FIXTURE_FACTORY(FixtureType, name)                            \
+  &Test##FixtureType##name::factory
+
+#define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name)                   \
+  (runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name))
+
+#endif // ifndef JSONTEST_H_INCLUDED