rocketmq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dongefore...@apache.org
Subject [06/17] incubator-rocketmq-externals git commit: [ROCKETMQ-129] Initialized the rocketmq c++ client closes apache/incubator-rocketmq-externals#11
Date Fri, 21 Apr 2017 10:09:46 GMT
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/jsoncpp/json_writer.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/jsoncpp/json_writer.cpp b/rocketmq-client4cpp/src/jsoncpp/json_writer.cpp
new file mode 100755
index 0000000..9d9e0cc
--- /dev/null
+++ b/rocketmq-client4cpp/src/jsoncpp/json_writer.cpp
@@ -0,0 +1,1220 @@
+// 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 rmq {
+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[32];
+  int len = -1;
+
+  char formatString[10];
+  snprintf(formatString, sizeof(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);
+  } 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(Value* invalid) const
+{
+  Value my_invalid;
+  if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
+  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(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
+} // namespace rmq

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/jsoncpp/version
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/jsoncpp/version b/rocketmq-client4cpp/src/jsoncpp/version
new file mode 100755
index 0000000..73c8b4f
--- /dev/null
+++ b/rocketmq-client4cpp/src/jsoncpp/version
@@ -0,0 +1 @@
+1.7.7
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/AtomicValue.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/AtomicValue.cpp b/rocketmq-client4cpp/src/kpr/AtomicValue.cpp
new file mode 100755
index 0000000..30777f9
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/AtomicValue.cpp
@@ -0,0 +1,146 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "AtomicValue.h"
+
+#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+
+#include "Mutex.h"
+
+namespace kpr
+{
+static const size_t kSwapLockCount = 64;
+static Mutex s_swapLocks[kSwapLockCount];
+
+static inline Mutex& getSwapLock(const volatile int64_t* addr)
+{
+    return s_swapLocks[(reinterpret_cast<intptr_t>(addr) >> 3U) % kSwapLockCount];
+}
+
+static int64_t atomicAddAndFetch(int64_t volatile* ptr, int64_t step)
+{
+    Mutex& mutex = getSwapLock(ptr);
+
+    mutex.Lock();
+    int64_t value = *ptr + step;
+    *ptr = value;
+    mutex.Unlock();
+
+    return value;
+}
+
+static int64_t atomicFetchAndAdd(int64_t volatile* ptr, int64_t step)
+{
+    Mutex& mutex = getSwapLock(ptr);
+
+    mutex.Lock();
+    int64_t value = *ptr;
+    *ptr += step;
+    mutex.Unlock();
+
+    return value;
+}
+
+static bool atomicBoolCompareAndSwap(int64_t volatile* ptr, int64_t oldval, int64_t newval)
+{
+    Mutex& mutex = getSwapLock(ptr);
+
+    mutex.Lock();
+    if (*ptr == oldval)
+    {
+    	*ptr = newval;
+    	mutex.Unlock();
+    	return true;
+    }
+
+    mutex.Unlock();
+    return false;
+}
+
+static int64_t atomicValCompareAndSwap(int64_t volatile* ptr, int64_t oldval, int64_t newval)
+{
+    Mutex& mutex = getSwapLock(ptr);
+
+    mutex.Lock();
+    int64_t value = *ptr;
+    if (value == oldval)
+    {
+    	*ptr = newval;
+    	mutex.Unlock();
+    	return value;
+    }
+
+    mutex.Unlock();
+    return value;
+}
+
+
+static int64_t atomicTestAndSet(int64_t volatile* ptr, int64_t val)
+{
+    Mutex& mutex = getSwapLock(ptr);
+
+    mutex.Lock();
+    int64_t value = *ptr;
+    *ptr = val;
+    mutex.Unlock();
+
+    return value;
+}
+
+
+
+extern "C" {
+int64_t __sync_add_and_fetch_8(int64_t volatile* ptr, int64_t value)
+{
+    return atomicAddAndFetch(ptr, value);
+}
+
+int64_t __sync_sub_and_fetch_8(int64_t volatile* ptr, int64_t value)
+{
+    return atomicAddAndFetch(ptr, -value);
+}
+
+int64_t __sync_fetch_and_add_8(int64_t volatile* ptr, int64_t value)
+{
+    return atomicFetchAndAdd(ptr, -value);
+}
+
+int64_t __sync_fetch_and_sub_8(int64_t volatile* ptr, int64_t value)
+{
+    return atomicFetchAndAdd(ptr, -value);
+}
+
+bool __sync_bool_compare_and_swap_8(volatile int64_t* ptr, int64_t oldval, int64_t newval)
+{
+    return atomicBoolCompareAndSwap(ptr, oldval, newval);
+}
+
+int64_t __sync_val_compare_and_swap_8(volatile int64_t* ptr, int64_t oldval, int64_t newval)
+{
+    return atomicValCompareAndSwap(ptr, oldval, newval);
+}
+
+bool __sync_lock_test_and_set_8(int64_t volatile* ptr, int64_t value)
+{
+    return atomicTestAndSet(ptr, value);
+}
+
+
+} // extern "C"
+
+} // namespace kpr
+#endif
+
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/AtomicValue.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/AtomicValue.h b/rocketmq-client4cpp/src/kpr/AtomicValue.h
new file mode 100755
index 0000000..50d198e
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/AtomicValue.h
@@ -0,0 +1,200 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_ATOMICVALUE_H__
+#define __KPR_ATOMICVALUE_H__
+
+#include "KPRTypes.h"
+
+namespace kpr
+{
+
+template <class T>
+class AtomicValue
+{
+public:
+	AtomicValue()
+		: value(0)
+	{
+	}
+
+    AtomicValue(T init)
+		: value(init)
+	{
+	}
+
+    AtomicValue<T>& operator=(T newValue)
+    {
+        set(newValue);
+        return *this;
+    }
+
+    AtomicValue<T>& operator=(const AtomicValue<T>& v)
+    {
+        set(v.get());
+
+        return *this;
+    }
+
+    inline T operator+=(T n)
+    {
+        return __sync_add_and_fetch(&value, n);
+    }
+
+    inline T operator-=(T n)
+    {
+        return __sync_sub_and_fetch(&value, n);
+    }
+
+    inline T operator++()
+    {
+        return *this += 1;
+    }
+
+    inline T operator--()
+    {
+        return *this -= 1;
+    }
+
+    inline T fetchAndAdd(T n)
+    {
+        return __sync_fetch_and_add(&value, n);
+    }
+
+    inline T fetchAndSub(T n)
+    {
+        return __sync_fetch_and_sub(&value, n);
+    }
+
+    inline T operator++(int)
+    {
+        return fetchAndAdd(1);
+    }
+
+    inline T operator--(int)
+    {
+        return fetchAndSub(1);
+    }
+
+    operator T() const
+    {
+        return get();
+    }
+
+    T get() const
+    {
+        return const_cast<AtomicValue<T>*>(this)->fetchAndAdd(static_cast<T>(0));
+    }
+
+    void set(T n)
+    {
+        __sync_lock_test_and_set((T*)&value, n);
+    }
+
+    inline T getAndSet(T comparand, T exchange)
+    {
+        return __sync_val_compare_and_swap((T*)&value, comparand, exchange);
+    }
+
+	inline bool compareAndSet(T comparand, T exchange)
+    {
+        return __sync_bool_compare_and_swap((T*)&value, comparand, exchange);
+    }
+
+private:
+    volatile T value;
+};
+
+
+template <class T>
+class AtomicReference
+{
+public:
+	AtomicReference() : value(NULL) {}
+    AtomicReference(T* init) : value(init) {}
+
+    AtomicReference<T>& operator=(T* newValue)
+    {
+        set(newValue);
+        return *this;
+    }
+
+    AtomicReference<T>& operator=(const AtomicReference<T>& v)
+    {
+        set(v.get());
+
+        return *this;
+    }
+
+	T* operator->() const
+    {
+        return get();
+    }
+
+    T& operator*()
+    {
+        return *get();
+    }
+
+    operator T*() const
+    {
+        return get();
+    }
+
+    T* get() const
+    {
+		if (value == NULL)
+		{
+			return NULL;
+		}
+		else
+		{
+        	return (T*)(__sync_fetch_and_add((uintptr_t*)&value, 0));
+		}
+    }
+
+    void set(T* n)
+    {
+		if (value == NULL)
+		{
+			value = n;
+		}
+		else
+		{
+			__sync_lock_test_and_set((uintptr_t*)&value, n);
+		}
+    }
+
+    inline T getAndSet(T* comparand, T* exchange)
+    {
+        return __sync_val_compare_and_swap((uintptr_t*)&value, comparand, exchange);
+    }
+
+	inline bool compareAndSet(T* comparand, T* exchange)
+    {
+        return __sync_bool_compare_and_swap((uintptr_t*)&value, comparand, exchange);
+    }
+
+private:
+    volatile T* value;
+};
+
+
+typedef AtomicValue<bool> AtomicBoolean;
+typedef AtomicValue<int> AtomicInteger;
+typedef AtomicValue<long long> AtomicLong;
+
+}
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Condition.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Condition.cpp b/rocketmq-client4cpp/src/kpr/Condition.cpp
new file mode 100755
index 0000000..c81765e
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Condition.cpp
@@ -0,0 +1,158 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "Condition.h"
+
+#include <errno.h>
+#include <assert.h>
+
+#include "Mutex.h"
+#include "ScopedLock.h"
+#include "Semaphore.h"
+#include "KPRUtil.h"
+#include "Exception.h"
+
+namespace kpr
+{
+class ConditionHelper
+{
+    RecursiveMutex& m_mutex;
+    int m_count;
+
+public:
+
+    ConditionHelper(RecursiveMutex& mutex, int count)
+        : m_mutex(mutex),
+          m_count(count)
+    {
+    }
+
+    ~ConditionHelper()
+    {
+        pthread_mutex_unlock(&m_mutex.m_mutex);
+        m_mutex.lock(m_count);
+    }
+};
+
+
+Condition::Condition()
+{
+    pthread_cond_init(&m_cond, 0);
+}
+
+Condition::~Condition()
+{
+    pthread_cond_destroy(&m_cond);
+}
+
+void Condition::Wait(Mutex& mutex)
+{
+    wait(mutex, -1);
+}
+
+bool Condition::Wait(Mutex& mutex, long timeout)
+{
+    assert(timeout >= 0 && "timeout value is negative");
+
+    return wait(mutex, timeout);
+}
+
+void Condition::Wait(RecursiveMutex& mutex)
+{
+    wait(mutex, -1);
+}
+
+bool Condition::Wait(RecursiveMutex& mutex, long timeout)
+{
+    assert(timeout >= 0 && "timeout value is negative");
+
+    return wait(mutex, timeout);
+}
+
+void Condition::Notify()
+{
+    pthread_cond_signal(&m_cond);
+}
+
+void Condition::NotifyAll()
+{
+    pthread_cond_broadcast(&m_cond);
+}
+
+bool Condition::wait(Mutex& mutex, long timeout)
+{
+    int ret = 0;
+    if (timeout < 0)
+    {
+        ret = pthread_cond_wait(&m_cond, &mutex.m_mutex);
+    }
+    else
+    {
+        struct timespec abstime = KPRUtil::CalcAbsTime(timeout);
+        ret = pthread_cond_timedwait(&m_cond, &mutex.m_mutex, &abstime);
+    }
+    if (ret == 0)
+    {
+        return true;
+    }
+    else
+    {
+        if (errno == EINTR)
+        {
+            THROW_EXCEPTION(InterruptedException, "pthread_cond_timedwait failed", errno);
+        }
+        else if (errno == ETIMEDOUT && timeout >= 0)
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool Condition::wait(RecursiveMutex& mutex, long timeout)
+{
+    unsigned int count = mutex.reset4Condvar();
+    ConditionHelper unlock(mutex, count);
+
+    int ret = 0;
+    if (timeout < 0)
+    {
+        ret = pthread_cond_wait(&m_cond, &mutex.m_mutex);
+    }
+    else
+    {
+        struct timespec abstime = KPRUtil::CalcAbsTime(timeout);
+        ret = pthread_cond_timedwait(&m_cond, &mutex.m_mutex, &abstime);
+    }
+
+    if (ret == 0)
+    {
+        return true;
+    }
+    else
+    {
+        if (errno == EINTR)
+        {
+            THROW_EXCEPTION(InterruptedException, "pthread_cond_timedwait failed", errno);
+        }
+        else if (errno == ETIMEDOUT && timeout >= 0)
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Condition.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Condition.h b/rocketmq-client4cpp/src/kpr/Condition.h
new file mode 100755
index 0000000..901e66c
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Condition.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_CONDITION_H__
+#define __KPR_CONDITION_H__
+
+#include "KPRTypes.h"
+
+namespace kpr
+{
+class Mutex;
+class RWMutex;
+class RecursiveMutex;
+
+class Condition
+{
+public:
+    Condition();
+    ~Condition();
+    void Wait(Mutex& mutex);
+
+    bool Wait(Mutex& mutex, long timeout);
+
+    void Wait(RecursiveMutex& mutex);
+
+    bool Wait(RecursiveMutex& mutex, long timeout);
+
+    void Notify();
+
+    void NotifyAll();
+
+private:
+    bool  wait(Mutex&, long timeout);
+    bool  wait(RecursiveMutex&, long timeout);
+
+    Condition(const Condition&);
+    void operator=(const Condition&);
+
+    pthread_cond_t m_cond;
+};
+}
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Epoller.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Epoller.cpp b/rocketmq-client4cpp/src/kpr/Epoller.cpp
new file mode 100755
index 0000000..3c4ddf3
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Epoller.cpp
@@ -0,0 +1,96 @@
+/**
+* Copyright (C) 2013 suwenkuang ,hooligan_520@qq.com
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "Epoller.h"
+#include <unistd.h>
+
+namespace kpr
+{
+Epoller::Epoller(bool bEt)
+{
+    _iEpollfd   = -1;
+    _pevs       = NULL;
+    _et         = bEt;
+    _max_connections = 1024;
+}
+
+Epoller::~Epoller()
+{
+    if (_pevs != NULL)
+    {
+        delete[] _pevs;
+        _pevs = NULL;
+    }
+
+    if (_iEpollfd > 0)
+    {
+        close(_iEpollfd);
+    }
+}
+
+void Epoller::ctrl(int fd, long long data, __uint32_t events, int op)
+{
+    struct epoll_event ev;
+    ev.data.u64 = data;
+    if (_et)
+    {
+        ev.events   = events | EPOLLET;
+    }
+    else
+    {
+        ev.events   = events;
+    }
+
+    epoll_ctl(_iEpollfd, op, fd, &ev);
+}
+
+void Epoller::create(int max_connections)
+{
+    _max_connections = max_connections;
+
+    _iEpollfd = epoll_create(_max_connections + 1);
+
+    if (_pevs != NULL)
+    {
+        delete[] _pevs;
+    }
+
+    _pevs = new epoll_event[_max_connections + 1];
+}
+
+void Epoller::add(int fd, long long data, __uint32_t event)
+{
+    ctrl(fd, data, event, EPOLL_CTL_ADD);
+}
+
+void Epoller::mod(int fd, long long data, __uint32_t event)
+{
+    ctrl(fd, data, event, EPOLL_CTL_MOD);
+}
+
+void Epoller::del(int fd, long long data, __uint32_t event)
+{
+    ctrl(fd, data, event, EPOLL_CTL_DEL);
+}
+
+int Epoller::wait(int millsecond)
+{
+    return epoll_wait(_iEpollfd, _pevs, _max_connections + 1, millsecond);
+}
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Epoller.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Epoller.h b/rocketmq-client4cpp/src/kpr/Epoller.h
new file mode 100755
index 0000000..d3d161b
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Epoller.h
@@ -0,0 +1,62 @@
+/**
+* Copyright (C) 2013 suwenkuang ,hooligan_520@qq.com
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __KPR_EPOLLER_H_
+#define __KPR_EPOLLER_H_
+
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <cassert>
+
+namespace kpr
+{
+
+
+class Epoller
+{
+public:
+    Epoller(bool bEt = true);
+    ~Epoller();
+
+
+    void create(int max_connections);
+
+    void add(int fd, long long data, __uint32_t event);
+    void mod(int fd, long long data, __uint32_t event);
+    void del(int fd, long long data, __uint32_t event);
+
+    int wait(int millsecond);
+
+    struct epoll_event& get(int i)
+    {
+        assert(_pevs != 0);
+        return _pevs[i];
+    }
+
+protected:
+    void ctrl(int fd, long long data, __uint32_t events, int op);
+
+protected:
+    int _iEpollfd;
+    int _max_connections;
+    struct epoll_event* _pevs;
+    bool _et;
+};
+
+}
+#endif
+
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Exception.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Exception.h b/rocketmq-client4cpp/src/kpr/Exception.h
new file mode 100755
index 0000000..524af84
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Exception.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_EXCEPTION_H
+#define __KPR_EXCEPTION_H
+
+#include "KPRTypes.h"
+#include <exception>
+#include <string>
+#include <sstream>
+
+namespace kpr
+{
+class Exception : public std::exception
+{
+public:
+    Exception(const char* msg, int error, const char* file, int line)throw()
+        : m_error(error), m_line(line), m_msg(msg), m_file(file)
+    {
+        try
+        {
+            std::stringstream ss;
+            ss << "[" << file << ":" << line << "]|error: " << error << "|msg:" << msg;
+            m_msg = ss.str();
+        }
+        catch (...)
+        {
+        }
+    }
+
+    virtual ~Exception()throw()
+    {
+    }
+
+    const char* what() const throw()
+    {
+        return m_msg.c_str();
+    }
+
+    int GetError() const throw()
+    {
+        return m_error;
+    }
+
+    virtual const char* GetType() const throw()
+    {
+        return "Exception";
+    }
+
+protected:
+    int m_error;
+    int m_line;
+    std::string m_msg;
+    std::string m_file;
+};
+}
+
+inline std::ostream& operator<<(std::ostream& os, const kpr::Exception& e)
+{
+    os << "Type:" << e.GetType() <<  e.what();
+    return os;
+}
+
+#define DEFINE_EXCEPTION(name) \
+    class name : public kpr::Exception \
+    {\
+    public:\
+        name(const char* msg, int error,const char* file,int line) throw ()\
+            : Exception(msg,error,file,line) {}\
+        virtual const char* GetType() const throw()\
+        {\
+            return #name;\
+        }\
+    };
+
+namespace kpr
+{
+DEFINE_EXCEPTION(SystemCallException);
+DEFINE_EXCEPTION(NotImplementException);
+DEFINE_EXCEPTION(InterruptedException);
+DEFINE_EXCEPTION(FileUtilException);
+DEFINE_EXCEPTION(RefHandleNullException);
+
+};
+
+#define THROW_EXCEPTION(e,msg,err) throw e(msg,err,__FILE__,__LINE__);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/FileUtil.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/FileUtil.cpp b/rocketmq-client4cpp/src/kpr/FileUtil.cpp
new file mode 100755
index 0000000..aa239e4
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/FileUtil.cpp
@@ -0,0 +1,523 @@
+/**
+* Copyright (C) 2013 suwenkuang ,hooligan_520@qq.com
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <cassert>
+#include <cstdio>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+#include <map>
+#include <stack>
+#include <vector>
+
+#include "FileUtil.h"
+#include "KPRUtil.h"
+#include "Exception.h"
+
+
+namespace kpr
+{
+
+std::ifstream::pos_type FileUtil::getFileSize(const std::string& sFullFileName)
+{
+    std::ifstream ifs(sFullFileName.c_str());
+    ifs.seekg(0, std::ios_base::end);
+    return ifs.tellg();
+}
+
+bool FileUtil::isAbsolute(const std::string& sFullFileName)
+{
+    if (sFullFileName.empty())
+    {
+        return false;
+    }
+
+    unsigned i = 0;
+    while (isspace(sFullFileName[i]))
+    {
+        ++i;
+    }
+
+    return sFullFileName[i] == '/';
+}
+
+bool FileUtil::isFileExist(const std::string& sFullFileName, mode_t iFileType)
+{
+    struct stat f_stat;
+
+    if (lstat(sFullFileName.c_str(), &f_stat) == -1)
+    {
+        return false;
+    }
+
+    if (!(f_stat.st_mode & iFileType))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool FileUtil::isFileExistEx(const std::string& sFullFileName, mode_t iFileType)
+{
+    struct stat f_stat;
+
+    if (stat(sFullFileName.c_str(), &f_stat) == -1)
+    {
+        return false;
+    }
+
+    if (!(f_stat.st_mode & iFileType))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool FileUtil::makeDir(const std::string& sDirectoryPath, mode_t iFlag)
+{
+    int iRetCode = mkdir(sDirectoryPath.c_str(), iFlag);
+    if (iRetCode < 0 && errno == EEXIST)
+    {
+        return isFileExistEx(sDirectoryPath, S_IFDIR);
+    }
+
+    return iRetCode == 0;
+}
+
+bool FileUtil::makeDirRecursive(const std::string& sDirectoryPath, mode_t iFlag)
+{
+    std::string simple = simplifyDirectory(sDirectoryPath);
+
+    std::string::size_type pos = 0;
+    for (; pos != std::string::npos;)
+    {
+        pos = simple.find("/", pos + 1);
+        std::string s;
+        if (pos == std::string::npos)
+        {
+            s = simple.substr(0, simple.size());
+            return makeDir(s.c_str(), iFlag);
+        }
+        else
+        {
+            s = simple.substr(0, pos);
+            if (!makeDir(s.c_str(), iFlag))
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+int FileUtil::setExecutable(const std::string& sFullFileName, bool canExecutable)
+{
+    struct stat f_stat;
+
+    if (stat(sFullFileName.c_str(), &f_stat) == -1)
+    {
+        return -1;
+    }
+
+    return chmod(sFullFileName.c_str(), canExecutable ? f_stat.st_mode | S_IXUSR : f_stat.st_mode & ~S_IXUSR);
+}
+
+bool FileUtil::canExecutable(const std::string& sFullFileName)
+{
+    struct stat f_stat;
+
+    if (stat(sFullFileName.c_str(), &f_stat) == -1)
+    {
+        return false;
+    }
+
+    return f_stat.st_mode & S_IXUSR;
+}
+
+int FileUtil::removeFile(const std::string& sFullFileName, bool bRecursive)
+{
+    std::string path = simplifyDirectory(sFullFileName);
+
+    if (isFileExist(path, S_IFDIR))
+    {
+        if (bRecursive)
+        {
+            std::vector<std::string> files;
+            listDirectory(path, files, false);
+            for (size_t i = 0; i < files.size(); i++)
+            {
+                removeFile(files[i], bRecursive);
+            }
+
+            if (path != "/")
+            {
+                if (::rmdir(path.c_str()) == -1)
+                {
+                    return -1;
+                }
+                return 0;
+            }
+        }
+        else
+        {
+            if (::rmdir(path.c_str()) == -1)
+            {
+                return -1;
+            }
+        }
+    }
+    else
+    {
+        if (::remove(path.c_str()) == -1)
+        {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+std::string FileUtil::simplifyDirectory(const std::string& path)
+{
+    std::string result = path;
+
+    std::string::size_type pos;
+
+    pos = 0;
+    while ((pos = result.find("//", pos)) != std::string::npos)
+    {
+        result.erase(pos, 1);
+    }
+
+    pos = 0;
+    while ((pos = result.find("/./", pos)) != std::string::npos)
+    {
+        result.erase(pos, 2);
+    }
+
+    while (result.substr(0, 4) == "/../")
+    {
+        result.erase(0, 3);
+    }
+
+    if (result == "/.")
+    {
+        return result.substr(0, result.size() - 1);
+    }
+
+    if (result.size() >= 2 && result.substr(result.size() - 2, 2) == "/.")
+    {
+        result.erase(result.size() - 2, 2);
+    }
+
+    if (result == "/")
+    {
+        return result;
+    }
+
+    if (result.size() >= 1 && result[result.size() - 1] == '/')
+    {
+        result.erase(result.size() - 1);
+    }
+
+    if (result == "/..")
+    {
+        result = "/";
+    }
+
+    return result;
+}
+
+std::string FileUtil::load2str(const std::string& sFullFileName)
+{
+    std::ifstream ifs(sFullFileName.c_str());
+    if (!ifs)
+    {
+        return "";
+    }
+    return std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
+}
+
+void FileUtil::save2file(const std::string& sFullFileName, const std::string& sFileData)
+{
+    std::ofstream ofs((sFullFileName).c_str());
+    ofs << sFileData;
+    ofs.close();
+}
+
+int FileUtil::save2file(const std::string& sFullFileName, const char* sFileData, size_t length)
+{
+    FILE* fp = fopen(sFullFileName.c_str(), "wb");
+    if (fp == NULL)
+    {
+        return -1;
+    }
+
+    size_t ret = fwrite((void*)sFileData, 1, length, fp);
+    fclose(fp);
+
+    if (ret == length)
+    {
+        return 0;
+    }
+    return -1;
+}
+
+std::string FileUtil::getExePath()
+{
+    std::string proc = "/proc/self/exe";
+    char buf[2048] = "\0";
+
+    int bufsize = sizeof(buf) / sizeof(char);
+
+    int count = readlink(proc.c_str(), buf, bufsize);
+
+    if (count < 0)
+    {
+        THROW_EXCEPTION(FileUtilException, "could not get exe path error", errno);
+    }
+
+    count = (count >= bufsize) ? (bufsize - 1) : count;
+
+    buf[count] = '\0';
+    return buf;
+}
+
+std::string FileUtil::extractFileName(const std::string& sFullFileName)
+{
+    if (sFullFileName.length() <= 0)
+    {
+        return "";
+    }
+
+    std::string::size_type pos = sFullFileName.rfind('/');
+    if (pos == std::string::npos)
+    {
+        return sFullFileName;
+    }
+
+    return sFullFileName.substr(pos + 1);
+}
+
+std::string FileUtil::extractFilePath(const std::string& sFullFileName)
+{
+    if (sFullFileName.length() <= 0)
+    {
+        return "./";
+    }
+
+    std::string::size_type pos = 0;
+
+    for (pos = sFullFileName.length(); pos != 0 ; --pos)
+    {
+        if (sFullFileName[pos - 1] == '/')
+        {
+            return sFullFileName.substr(0, pos);
+        }
+    }
+
+    return "./";
+}
+
+std::string FileUtil::extractFileExt(const std::string& sFullFileName)
+{
+    std::string::size_type pos;
+    if ((pos = sFullFileName.rfind('.')) == std::string::npos)
+    {
+        return std::string("");
+    }
+
+    return sFullFileName.substr(pos + 1);
+}
+
+std::string FileUtil::excludeFileExt(const std::string& sFullFileName)
+{
+    std::string::size_type pos;
+    if ((pos = sFullFileName.rfind('.')) == std::string::npos)
+    {
+        return sFullFileName;
+    }
+
+    return sFullFileName.substr(0, pos);
+}
+
+std::string FileUtil::replaceFileExt(const std::string& sFullFileName, const std::string& sExt)
+{
+    return excludeFileExt(sFullFileName) + "." + sExt;
+}
+
+std::string FileUtil::extractUrlFilePath(const std::string& sUrl)
+{
+    std::string sLowerUrl = KPRUtil::lower(sUrl);
+    std::string::size_type pos = sLowerUrl.find("http://");
+
+    if (pos == 0)
+    {
+        pos += strlen("http://");
+    }
+    else if (pos == std::string::npos)
+    {
+        pos = 0;
+    }
+
+    for (; pos < sUrl.length(); ++pos)
+    {
+        if (sUrl[pos] == '/')
+        {
+            if (pos < sUrl.length() - 1)
+            {
+                pos++;
+                break;
+            }
+            else
+            {
+                return "";
+            }
+        }
+    }
+
+    if (pos == std::string::npos || pos == sUrl.length())
+    {
+        pos = 0;
+    }
+
+    return sUrl.substr(pos);
+}
+
+size_t FileUtil::scanDir(const std::string& sFilePath, std::vector<std::string>& vtMatchFiles, FILE_SELECT f, int iMaxSize)
+{
+    vtMatchFiles.clear();
+
+    struct dirent** namelist;
+    int n = scandir(sFilePath.c_str(), &namelist, f, alphasort);
+
+    if (n < 0)
+    {
+        return 0;
+    }
+    else
+    {
+        while (n--)
+        {
+            if (iMaxSize > 0 && vtMatchFiles.size() >= (size_t)iMaxSize)
+            {
+                free(namelist[n]);
+                break;
+            }
+            else
+            {
+                vtMatchFiles.push_back(namelist[n]->d_name);
+                free(namelist[n]);
+            }
+        }
+        free(namelist);
+    }
+
+    return vtMatchFiles.size();
+}
+
+void FileUtil::listDirectory(const std::string& path, std::vector<std::string>& files, bool bRecursive)
+{
+    std::vector<std::string> tf;
+    scanDir(path, tf, 0, 0);
+
+    for (size_t i = 0; i < tf.size(); i++)
+    {
+        if (tf[i] == "." || tf[i] == "..")
+        {
+            continue;
+        }
+
+        std::string s = path + "/" + tf[i];
+
+        if (isFileExist(s, S_IFDIR))
+        {
+            files.push_back(simplifyDirectory(s));
+            if (bRecursive)
+            {
+                listDirectory(s, files, bRecursive);
+            }
+        }
+        else
+        {
+            files.push_back(simplifyDirectory(s));
+        }
+    }
+}
+
+void FileUtil::copyFile(const std::string& sExistFile, const std::string& sNewFile, bool bRemove)
+{
+    if (FileUtil::isFileExist(sExistFile, S_IFDIR))
+    {
+        FileUtil::makeDir(sNewFile);
+        std::vector<std::string> tf;
+        FileUtil::scanDir(sExistFile, tf, 0, 0);
+        for (size_t i = 0; i < tf.size(); i++)
+        {
+            if (tf[i] == "." || tf[i] == "..")
+            {
+                continue;
+            }
+            std::string s = sExistFile + "/" + tf[i];
+            std::string d = sNewFile + "/" + tf[i];
+            copyFile(s, d, bRemove);
+        }
+    }
+    else
+    {
+        if (bRemove)
+        {
+            std::remove(sNewFile.c_str());
+        }
+        std::ifstream fin(sExistFile.c_str());
+        if (!fin)
+        {
+            THROW_EXCEPTION(FileUtilException, "[FileUtil::copyFile] infile open fail", errno);
+        }
+        std::ofstream fout(sNewFile.c_str());
+        if (!fout)
+        {
+            THROW_EXCEPTION(FileUtilException, "[FileUtil::copyFile] newfile open fail", errno);
+        }
+        struct stat f_stat;
+        if (stat(sExistFile.c_str(), &f_stat) == -1)
+        {
+            THROW_EXCEPTION(FileUtilException, "[FileUtil::copyFile] infile stat fail", errno);
+        }
+        chmod(sNewFile.c_str(), f_stat.st_mode);
+        fout << fin.rdbuf();
+        fin.close();
+        fout.close();
+
+    }
+}
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/FileUtil.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/FileUtil.h b/rocketmq-client4cpp/src/kpr/FileUtil.h
new file mode 100755
index 0000000..c1e8518
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/FileUtil.h
@@ -0,0 +1,90 @@
+/**
+* Copyright (C) 2013 suwenkuang ,hooligan_520@qq.com
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __KPR_FILEUTIL_H_
+#define __KPR_FILEUTIL_H_
+
+#include <iostream>
+#include <fstream>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fnmatch.h>
+
+
+#include <string>
+#include <vector>
+
+
+namespace kpr
+{
+
+class FileUtil
+{
+public:
+
+    static std::ifstream::pos_type getFileSize(const std::string& sFullFileName);
+
+    static bool isAbsolute(const std::string& sFullFileName);
+
+    static bool isFileExist(const std::string& sFullFileName, mode_t iFileType = S_IFREG);
+
+    static bool isFileExistEx(const std::string& sFullFileName, mode_t iFileType = S_IFREG);
+
+    static std::string simplifyDirectory(const std::string& path);
+
+    static bool makeDir(const std::string& sDirectoryPath, mode_t iFlag = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |  S_IXOTH);
+
+    static bool makeDirRecursive(const std::string& sDirectoryPath, mode_t iFlag = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |  S_IXOTH);
+
+    static int setExecutable(const std::string& sFullFileName, bool canExecutable);
+
+    static bool canExecutable(const std::string& sFullFileName);
+
+    static int removeFile(const std::string& sFullFileName, bool bRecursive);
+
+    static std::string load2str(const std::string& sFullFileName);
+
+    static void save2file(const std::string& sFullFileName, const std::string& sFileData);
+
+    static int save2file(const std::string& sFullFileName, const char* sFileData, size_t length);
+
+    static std::string getExePath();
+
+    static std::string extractFileName(const std::string& sFullFileName);
+
+    static std::string extractFilePath(const std::string& sFullFileName);
+
+    static std::string extractFileExt(const std::string& sFullFileName);
+
+    static std::string excludeFileExt(const std::string& sFullFileName);
+
+    static std::string replaceFileExt(const std::string& sFullFileName, const std::string& sExt);
+
+    static std::string extractUrlFilePath(const std::string& sUrl);
+
+    typedef int (*FILE_SELECT)(const dirent*);
+
+    static size_t scanDir(const std::string& sFilePath, std::vector<std::string>& vtMatchFiles, FILE_SELECT f = NULL, int iMaxSize = 0);
+
+    static void listDirectory(const std::string& path, std::vector<std::string>& files, bool bRecursive);
+
+    static void copyFile(const std::string& sExistFile, const std::string& sNewFile, bool bRemove = false);
+};
+
+}
+#endif // __FILE_UTIL_H_

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/KPRTypes.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/KPRTypes.h b/rocketmq-client4cpp/src/kpr/KPRTypes.h
new file mode 100755
index 0000000..0a54123
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/KPRTypes.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_TYPES_H__
+#define __KPR_TYPES_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+
+typedef pthread_key_t ThreadKey;
+
+
+namespace kpr
+{
+class ThreadId
+{
+public:
+    ThreadId(pthread_t id = 0)
+        : m_threadId(id)
+    {
+    }
+
+    bool operator==(const ThreadId& id) const
+    {
+        return m_threadId == id.m_threadId;
+    }
+
+    bool operator!=(const ThreadId& id) const
+    {
+        return !(*this == id);
+    }
+
+    operator pthread_t() const
+    {
+        return m_threadId;
+    }
+
+    static ThreadId GetCurrentThreadId()
+    {
+        return ThreadId(pthread_self());
+    }
+
+    pthread_t m_threadId;
+};
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/KPRUtil.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/KPRUtil.cpp b/rocketmq-client4cpp/src/kpr/KPRUtil.cpp
new file mode 100755
index 0000000..fe2cdd2
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/KPRUtil.cpp
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "KPRUtil.h"
+#include <assert.h>
+
+
+
+unsigned long long KPRUtil::GetCurrentTimeMillis()
+{
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
+}
+
+struct timespec KPRUtil::CalcAbsTime(long timeout)
+{
+    assert(timeout >= 0);
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+
+    struct timespec abstime;
+    abstime.tv_sec = tv.tv_sec + (timeout / 1000);
+    abstime.tv_nsec = (tv.tv_usec * 1000) + ((timeout % 1000) * 1000000);
+    if (abstime.tv_nsec >= 1000000000)
+    {
+        ++abstime.tv_sec;
+        abstime.tv_nsec -= 1000000000;
+    }
+
+    return abstime;
+}
+
+long long KPRUtil::str2ll(const char* str)
+{
+    return atoll(str);
+}
+
+
+std::string KPRUtil::lower(const std::string& s)
+{
+    std::string sString = s;
+    for (std::string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
+    {
+        *iter = tolower(*iter);
+    }
+
+    return sString;
+}
+
+std::string KPRUtil::upper(const std::string& s)
+{
+    std::string sString = s;
+
+    for (std::string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
+    {
+        *iter = toupper(*iter);
+    }
+
+    return sString;
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/KPRUtil.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/KPRUtil.h b/rocketmq-client4cpp/src/kpr/KPRUtil.h
new file mode 100755
index 0000000..ae2c529
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/KPRUtil.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_UTIL_H__
+#define __KPR_UTIL_H__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string>
+
+
+class KPRUtil
+{
+public:
+	static struct timespec CalcAbsTime(long timeout);
+	static unsigned long long GetCurrentTimeMillis();
+	static long long str2ll(const char* str);
+    static std::string lower(const std::string& s);
+    static std::string upper(const std::string& s);
+};
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Monitor.cpp
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Monitor.cpp b/rocketmq-client4cpp/src/kpr/Monitor.cpp
new file mode 100644
index 0000000..d715f55
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Monitor.cpp
@@ -0,0 +1,125 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "Monitor.h"
+#include <assert.h>
+
+namespace kpr
+{
+Monitor::Monitor()
+    : m_notifyCount(0)
+{
+}
+
+Monitor::~Monitor()
+{
+}
+
+void Monitor::Wait()
+{
+    validateOwner(m_mutex.GetOwner(), "wait()");
+
+    notify(m_notifyCount);
+
+    try
+    {
+        m_condition.Wait(m_mutex);
+    }
+    catch (...)
+    {
+        m_notifyCount = 0;
+        throw;
+    }
+    m_notifyCount = 0;
+}
+
+void Monitor::Wait(long timeout)
+{
+    validateOwner(m_mutex.GetOwner(), "wait(long)");
+
+    notify(m_notifyCount);
+    try
+    {
+        m_condition.Wait(m_mutex, timeout);
+    }
+    catch (...)
+    {
+        m_notifyCount = 0;
+        throw;
+    }
+
+    m_notifyCount = 0;
+}
+
+void Monitor::Notify()
+{
+    validateOwner(m_mutex.GetOwner(), "notify");
+
+    if (m_notifyCount != -1)
+    {
+        ++m_notifyCount;
+    }
+}
+
+void Monitor::NotifyAll()
+{
+    validateOwner(m_mutex.GetOwner(), "notifyAll");
+
+    m_notifyCount = -1;
+}
+
+void Monitor::Lock() const
+{
+    if (m_mutex.Lock())
+    {
+        m_notifyCount = 0;
+    }
+}
+
+void Monitor::Unlock() const
+{
+    if (m_mutex.GetCount() == 1)
+    {
+        ((Monitor*)this)->notify(m_notifyCount);
+    }
+
+    m_mutex.Unlock();
+}
+
+void Monitor::notify(int nnotify)
+{
+    if (nnotify != 0)
+    {
+        if (nnotify == -1)
+        {
+            m_condition.NotifyAll();
+            return;
+        }
+        else
+        {
+            while (nnotify > 0)
+            {
+                m_condition.Notify();
+                --nnotify;
+            }
+        }
+    }
+}
+
+void Monitor::validateOwner(const ThreadId& id, const char* caller) const
+{
+    assert(id == ThreadId::GetCurrentThreadId());
+}
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq-externals/blob/6a45c767/rocketmq-client4cpp/src/kpr/Monitor.h
----------------------------------------------------------------------
diff --git a/rocketmq-client4cpp/src/kpr/Monitor.h b/rocketmq-client4cpp/src/kpr/Monitor.h
new file mode 100644
index 0000000..345f736
--- /dev/null
+++ b/rocketmq-client4cpp/src/kpr/Monitor.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2013 kangliqiang ,kangliq@163.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __KPR_MONITOR_H__
+#define __KPR_MONITOR_H__
+
+#include "KPRTypes.h"
+#include "Condition.h"
+#include "Mutex.h"
+namespace kpr
+{
+class Monitor
+{
+public:
+    Monitor();
+    virtual ~Monitor();
+
+    void Wait();
+    void Wait(long msec);
+
+    void Notify();
+    void NotifyAll();
+
+    void Lock() const;
+    void Unlock() const;
+
+private:
+    void notify(int times);
+    void validateOwner(const ThreadId& id, const char* caller) const;
+
+    RecursiveMutex m_mutex;
+    Condition m_condition;
+    mutable int m_notifyCount;
+};
+}
+#endif


Mime
View raw message