Permalink
Browse files

Wrote the streambuf filter used to escape json string characters.

Changed a static function from private to public in the Value class.
  • Loading branch information...
1 parent d893122 commit 7c1c9c9028d28265c5b9b86a710a6bdf4c6e8e44 @madbranch madbranch committed Jan 23, 2012
Showing with 99 additions and 22 deletions.
  1. +19 −0 include/JsonBox/Escaper.h
  2. +1 −0 include/JsonBox/Indenter.h
  3. +11 −11 include/JsonBox/Value.h
  4. +56 −0 src/Escaper.cpp
  5. +12 −11 src/Value.cpp
View
@@ -0,0 +1,19 @@
+#ifndef JB_ESCAPER_H
+#define JB_ESCAPER_H
+
+#include <streambuf>
+
+namespace JsonBox {
+ class Escaper {
+ public:
+ Escaper();
+
+ std::streambuf::int_type operator()(std::streambuf &destination,
+ std::streambuf::int_type character);
+ private:
+ bool afterBackSlash;
+ bool inString;
+ };
+}
+
+#endif
@@ -6,6 +6,7 @@
namespace JsonBox {
/**
* Adds a level of indentation to a streambuf.
+ * @see JsonBox::OutputFilter
*/
class Indenter {
public:
View
@@ -57,7 +57,17 @@ namespace JsonBox {
* @see JsonBox::Value::escapeMinimumCharacters(const std::string& str)
*/
static std::string escapeAllCharacters(const std::string& str);
-
+
+ /**
+ * Escapes a character to its unicode equivalent. This function only
+ * takes characters from '/0' to '/x1f'.
+ * @param charToEscape Character to escape, must be between '\0' and
+ * '\x1f'.
+ * @return String with the character escaped in the format "\u00xx".
+ * "xx" being the hexadecimal ASCII code of the character escaped.
+ */
+ static const std::string escapeToUnicode(char charToEscape);
+
/**
* Default constructor. Makes the value null.
*/
@@ -492,16 +502,6 @@ namespace JsonBox {
* @param nbTabs Number of tabs to write in the stream.
*/
static void outputNbTabs(std::ostream& output, unsigned int nbTabs);
-
- /**
- * Escapes a character to its unicode equivalent. This function only
- * takes characters from '/0' to '/x1f'.
- * @param charToEscape Character to escape, must be between '\0' and
- * '\x1f'.
- * @return String with the character escaped in the format "\u00xx".
- * "xx" being the hexadecimal ASCII code of the character escaped.
- */
- static std::string escapeToUnicode(char charToEscape);
/**
* Sets the value's pointer and type.
View
@@ -0,0 +1,56 @@
+#include <JsonBox/Escaper.h>
+
+#include <JsonBox/Grammar.h>
+#include <JsonBox/Value.h>
+
+namespace JsonBox {
+ Escaper::Escaper() : afterBackSlash(false), inString(false) {
+ }
+
+ std::streambuf::int_type Escaper::operator()(std::streambuf &destination,
+ std::streambuf::int_type character) {
+ bool notEscaped = true;
+ std::streambuf::char_type tmpChar = std::streambuf::traits_type::to_char_type(character);
+
+ // If we encounter a quotation mark.
+ if (tmpChar == Strings::Json::Escape::QUOTATION_MARK) {
+ // If we're not in a string, we change that. If we're in a string,
+ // we change that only if we're not after an escape back slash.
+ inString = !inString || (afterBackSlash);
+
+ } else if (inString && !afterBackSlash) {
+ // If we are in a string definition and we're not after a backslash
+ // escape.
+ if (tmpChar == Strings::Std::REVERSE_SOLIDUS) {
+ destination.sputn(Strings::Json::REVERSE_SOLIDUS.c_str(), Strings::Json::REVERSE_SOLIDUS.size());
+ notEscaped = false;
+
+ } else if (tmpChar == Strings::Std::BACKSPACE) {
+ destination.sputn(Strings::Json::BACKSPACE.c_str(), Strings::Json::BACKSPACE.size());
+ notEscaped = false;
+
+ } else if (tmpChar == Strings::Std::FORM_FEED) {
+ destination.sputn(Strings::Json::FORM_FEED.c_str(), Strings::Json::FORM_FEED.size());
+ notEscaped = false;
+
+ } else if (tmpChar == Strings::Std::LINE_FEED) {
+ destination.sputn(Strings::Json::LINE_FEED.c_str(), Strings::Json::LINE_FEED.size());
+ notEscaped = false;
+
+ } else if (tmpChar == Strings::Std::TAB) {
+ destination.sputn(Strings::Json::TAB.c_str(), Strings::Json::TAB.size());
+ notEscaped = false;
+
+ } else if (tmpChar >= '\0' && tmpChar <= '\x1f') {
+ std::string tmp(Value::escapeToUnicode(tmpChar));
+ destination.sputn(tmp.c_str(), tmp.size());
+ notEscaped = false;
+ }
+
+ }
+
+ // We determine if we start a backslash escape or not.
+ afterBackSlash = inString && !afterBackSlash && (tmpChar == '\\');
+ return (notEscaped) ? (destination.sputc(tmpChar)) : (0);
+ }
+}
View
@@ -78,6 +78,18 @@ namespace JsonBox {
return result.str();
}
+
+ const std::string Value::escapeToUnicode(char charToEscape) {
+ std::stringstream result;
+
+ if(charToEscape >= '\0' && charToEscape <= '\x1f') {
+ result << "\\u00";
+ result << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(charToEscape);
+ }
+
+ return result.str();
+ }
+
Value::Value() : type(Type::NULL_VALUE) {
valuePointer.stringValue = NULL;
}
@@ -745,17 +757,6 @@ namespace JsonBox {
}
}
- std::string Value::escapeToUnicode(char charToEscape) {
- std::stringstream result;
-
- if(charToEscape >= '\0' && charToEscape <= '\x1f') {
- result << "\\u00";
- result << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(charToEscape);
- }
-
- return result.str();
- }
-
void Value::setValue(ValueDataPointer newValuePointer,
Type::Enum newType) {
if(newType != Type::UNKNOWN) {

0 comments on commit 7c1c9c9

Please sign in to comment.