unused; also not what official StepMania uses.

This commit is contained in:
AJ Kelly
2010-12-15 18:34:47 -06:00
parent 4aa3110e25
commit a31bc6c27d
6 changed files with 0 additions and 691 deletions
-5
View File
@@ -1,5 +0,0 @@
Since a few people have asked me, I figured I'd put a LICENSE file here. I wrote
this small library as an excercise. You are welcome to include jsonxx in your
project and redistributed it with your code in any license, provided that you
don't sue me for anything. Please let me know if you improved it, so that I can
merge your changes.
-44
View File
@@ -1,44 +0,0 @@
h1. Introduction
JSON++ is a light-weight JSON parser written in C++.
h2. Why another JSON parser?
Perhaps because web service clients are usually written in dynamic
languages these days, none of the existing C++ JSON parsers suite my
needs very well, so I wrote one to used in another project. My goals
for JSON++ were:
* Efficient in both memory and speed.
* No third party dependencies. JSON++ only depends on the standard C++ library.
* Cross platform.
* Robust.
* Small and convenient API. Most of the time, you only need to call one function and two function templates.
* Easy to integrate. JSON++ only has one source file and one header file. Just compile the source file and link with your program.
h3. Usage
The following snippet is from one of the unit tests. It's quite self-descriptive.
<pre>
<code>
string teststr(
"{"
" \"foo\" : 1,"
" \"bar\" : false,"
" \"person\" : {\"name\" : \"GWB\", \"age\" : 60},"
" \"data\": [\"abcd\", 42]"
"}"
);
istringstream input(teststr);
Object o;
assert(o.parse(input));
assert(1 == o.get<long>("foo"));
assert(o.has<bool>("bar"));
assert(o.has<Object>("person"));
assert(o.get<Object>("person").has<long>("age"));
assert(o.has<Array>("data"));
assert(o.get<Array>("data").get<long>(1) == 42);
assert(o.get<Array>("data").get<string>(0) == "abcd");
assert(!o.has<long>("data"));
</code>
</pre>
-264
View File
@@ -1,264 +0,0 @@
// Author: Hong Jiang <[email protected]>
#include "jsonxx.h"
#include <cctype>
#include <iostream>
#include <sstream>
namespace jsonxx {
void eat_whitespaces(std::istream& input) {
char ch;
do {
input.get(ch);
} while(isspace(ch));
input.putback(ch);
}
// Try to consume characters from the input stream and match the
// pattern string. Leading whitespaces from the input are ignored if
// ignore_ws is true.
bool match(const std::string& pattern, std::istream& input,
bool ignore_ws = true) {
if (ignore_ws) {
eat_whitespaces(input);
}
std::string::const_iterator cur(pattern.begin());
char ch(0);
while(input && !input.eof() && cur != pattern.end()) {
input.get(ch);
if (ch != *cur) {
input.putback(ch);
return false;
} else {
cur++;
}
}
return cur == pattern.end();
}
bool parse_string(std::istream& input, std::string* value) {
if (!match("\"", input)) {
return false;
}
char ch;
while(!input.eof() && input.good()) {
input.get(ch);
if (ch == '"') {
break;
}
value->push_back(ch);
}
if (input && ch == '"') {
return true;
} else {
return false;
}
}
bool parse_bool(std::istream& input, bool* value) {
if (match("true", input)) {
*value = true;
return true;
}
if (match("false", input)) {
*value = false;
return true;
}
return false;
}
bool parse_null(std::istream& input) {
if (match("null", input)) {
return true;
}
return false;
}
bool parse_number(std::istream& input, long* value) {
eat_whitespaces(input);
char ch;
std::string value_str;
int sign = 1;
if (match("-", input)) {
sign = -1;
} else {
match("+", input);
}
while(input && !input.eof()) {
input.get(ch);
if (!isdigit(ch)) {
input.putback(ch);
break;
}
value_str.push_back(ch);
}
if (value_str.size() > 0) {
std::istringstream(value_str) >> *value;
return true;
} else {
return false;
}
}
Object::Object() : value_map_() {}
Object::~Object() {
std::map<std::string, Value*>::iterator i;
for (i = value_map_.begin(); i != value_map_.end(); ++i) {
delete i->second;
}
}
bool Object::parse(std::istream& input) {
if (!match("{", input)) {
return false;
}
do {
std::string key;
if (!parse_string(input, &key)) {
return false;
}
if (!match(":", input)) {
return false;
}
Value* v = new Value();
if (!v->parse(input)) {
delete v;
break;
}
value_map_[key] = v;
} while (match(",", input));
if (!match("}", input)) {
return false;
}
return true;
}
Value::Value() : type_(INVALID_) {}
Value::~Value() {
if (type_ == STRING_) {
delete string_value_;
}
if (type_ == OBJECT_) {
delete object_value_;
}
if (type_ == ARRAY_) {
delete array_value_;
}
}
bool Value::parse(std::istream& input) {
std::string string_value;
if (parse_string(input, &string_value)) {
string_value_ = new std::string();
string_value_->swap(string_value);
type_ = STRING_;
return true;
}
if (parse_number(input, &integer_value_)) {
type_ = INTEGER_;
return true;
}
if (parse_bool(input, &bool_value_)) {
type_ = BOOL_;
return true;
}
if (parse_null(input)) {
type_ = NULL_;
return true;
}
array_value_ = new Array();
if (array_value_->parse(input)) {
type_ = ARRAY_;
return true;
}
delete array_value_;
object_value_ = new Object();
if (object_value_->parse(input)) {
type_ = OBJECT_;
return true;
}
delete object_value_;
return false;
}
Array::Array() : values_() {}
Array::~Array() {
for (unsigned int i = 0; i < values_.size(); ++i) {
delete values_[i];
}
}
bool Array::parse(std::istream& input) {
if (!match("[", input)) {
return false;
}
do {
Value* v = new Value();
if (!v->parse(input)) {
delete v;
break;
}
values_.push_back(v);
} while (match(",", input));
if (!match("]", input)) {
return false;
}
return true;
}
} // namespace jsonxx
std::ostream& operator<<(std::ostream& stream, const jsonxx::Value& v) {
if (v.is<long>()) {
return stream << v.get<long>();
} else if (v.is<std::string>()) {
return stream << '"' << v.get<std::string>() << '"';
} else if (v.is<bool>()) {
if (v.get<bool>()) {
return stream << "true";
} else {
return stream << "false";
}
} else if (v.is<jsonxx::Value::Null>()) {
return stream << "null";
} else if (v.is<jsonxx::Object>()) {
return stream << v.get<jsonxx::Object>();
} else if (v.is<jsonxx::Array>()){
return stream << v.get<jsonxx::Array>();
}
// Shouldn't reach here.
return stream;
}
std::ostream& operator<<(std::ostream& stream, const jsonxx::Array& v) {
stream << "[";
const std::vector<jsonxx::Value*>& values(v.values());
for (unsigned int i = 0; i < values.size()-1; ++i) {
stream << *(values[i]) << ", ";
}
return stream << *(values[values.size()-1]) << "]";
}
std::ostream& operator<<(std::ostream& stream, const jsonxx::Object& v) {
stream << "{";
const std::map<std::string, jsonxx::Value*>& kv(v.kv_map());
for (std::map<std::string, jsonxx::Value*>::const_iterator i = kv.begin();
i != kv.end(); /**/) {
stream << i->first << ": " << *(i->second);
++i;
if ( i != kv.end()) {
stream << ", ";
}
}
return stream << "}";
}
-226
View File
@@ -1,226 +0,0 @@
#ifndef JSONXX_H
#define JSONXX_H
// Author: Hong Jiang <[email protected]>
#include <cassert>
#include <iostream>
#include <map>
#include <vector>
namespace jsonxx {
// TODO: *::parse() should be static functions.
class Value;
// A JSON Object
class Object {
public:
Object();
~Object();
bool parse(std::istream& input);
template <typename T>
bool has(const std::string& key) const;
// Always call has<>() first. If the key doesn't exist, consider
// the behavior undefined.
template <typename T>
T& get(const std::string& key) const;
const std::map<std::string, Value*>& kv_map() const { return value_map_; }
private:
Object(const Object&);
Object& operator=(const Object&);
std::map<std::string, Value*> value_map_;
};
class Value;
class Array {
public:
Array();
~Array();
bool parse(std::istream& input);
unsigned int size() const { return values_.size(); }
template <typename T>
bool has(unsigned int i) const;
template <typename T>
T& get(unsigned int i) const;
const std::vector<Value*>& values() const {
return values_;
}
private:
Array(const Array&);
Array& operator=(const Array&);
std::vector<Value*> values_;
};
// A value could be a number, an array, a string, an object, a
// boolean, or null
class Value {
public:
class Null {};
Value();
~Value();
bool parse(std::istream& input);
template<typename T>
bool is() const;
template<typename T>
T& get();
template<typename T>
const T& get() const;
private:
Value(const Value&);
Value& operator=(const Value&);
enum {
INTEGER_,
STRING_,
BOOL_,
NULL_,
ARRAY_,
OBJECT_,
INVALID_
} type_;
union {
long integer_value_;
std::string* string_value_;
bool bool_value_;
Array* array_value_;
Object* object_value_;
};
};
template <typename T>
bool Array::has(unsigned int i) const {
if (i >= size()) {
return false;
} else {
Value* v = values_.at(i);
return v->is<T>();
}
}
template <typename T>
T& Array::get(unsigned int i) const {
assert(i < size());
Value* v = values_.at(i);
return v->get<T>();
}
template <typename T>
bool Object::has(const std::string& key) const {
std::map<std::string, Value*>::const_iterator it(value_map_.find(key));
return it != value_map_.end() && it->second->is<T>();
}
template <typename T>
T& Object::get(const std::string& key) const {
assert(has<T>(key));
return value_map_.find(key)->second->get<T>();
}
template<>
inline bool Value::is<Value::Null>() const {
return type_ == NULL_;
}
template<>
inline bool Value::is<bool>() const {
return type_ == BOOL_;
}
template<>
inline bool Value::is<std::string>() const {
return type_ == STRING_;
}
template<>
inline bool Value::is<long>() const {
return type_ == INTEGER_;
}
template<>
inline bool Value::is<Array>() const {
return type_ == ARRAY_;
}
template<>
inline bool Value::is<Object>() const {
return type_ == OBJECT_;
}
template<>
inline bool& Value::get<bool>() {
assert(is<bool>());
return bool_value_;
}
template<>
inline std::string& Value::get<std::string>() {
assert(is<std::string>());
return *string_value_;
}
template<>
inline long& Value::get<long>() {
assert(is<long>());
return integer_value_;
}
template<>
inline Array& Value::get<Array>() {
assert(is<Array>());
return *array_value_;
}
template<>
inline Object& Value::get<Object>() {
assert(is<Object>());
return *object_value_;
}
template<>
inline const bool& Value::get<bool>() const {
assert(is<bool>());
return bool_value_;
}
template<>
inline const std::string& Value::get<std::string>() const {
assert(is<std::string>());
return *string_value_;
}
template<>
inline const long& Value::get<long>() const {
assert(is<long>());
return integer_value_;
}
template<>
inline const Array& Value::get<Array>() const {
assert(is<Array>());
return *array_value_;
}
template<>
inline const Object& Value::get<Object>() const {
assert(is<Object>());
return *object_value_;
}
} // namespace jsonxx
std::ostream& operator<<(std::ostream& stream, const jsonxx::Value& v);
std::ostream& operator<<(std::ostream& stream, const jsonxx::Object& v);
std::ostream& operator<<(std::ostream& stream, const jsonxx::Array& v);
#endif
-149
View File
@@ -1,149 +0,0 @@
// Author: Hong Jiang <[email protected]>
#include <cassert>
#include <sstream>
#include <string>
#include "jsonxx.h"
namespace jsonxx {
bool parse_string(std::istream& input, std::string* value);
bool parse_number(std::istream& input, long* value);
bool match(const std::string& pattern, std::istream& input, bool ignore_ws = true);
}
int main() {
using namespace jsonxx;
using namespace std;
{
string teststr("\"field1\"");
string value;
istringstream input(teststr);
assert(parse_string(input, &value));
}
{
string teststr("\" field1\"");
string value;
istringstream input(teststr);
assert(parse_string(input, &value));
}
{
string teststr(" \"field1\"");
string value;
istringstream input(teststr);
assert(parse_string(input, &value));
}
{
string teststr("6");
istringstream input(teststr);
long value;
assert(parse_number(input, &value));
}
{
string teststr(" }");
istringstream input(teststr);
assert(match("}", input));
}
{
string teststr("{ \"field1\" : 6 }");
istringstream input(teststr);
Object o;
assert(o.parse(input));
}
{
string teststr("{ \"field1 : 6 }");
istringstream input(teststr);
Object o;
assert(!o.parse(input));
}
{
string teststr("6");
istringstream input(teststr);
Value v;
assert(v.parse(input));
}
{
string teststr("+6");
istringstream input(teststr);
Value v;
assert(v.parse(input));
}
{
string teststr("-6");
istringstream input(teststr);
Value v;
assert(v.parse(input));
}
{
string teststr("asdf");
istringstream input(teststr);
Value v;
assert(!v.parse(input));
}
{
string teststr("true");
istringstream input(teststr);
Value v;
assert(v.parse(input));
assert(v.is<bool>());
}
{
string teststr("false");
istringstream input(teststr);
Value v;
assert(v.parse(input));
assert(v.is<bool>());
assert(v.get<bool>() == false);
}
{
string teststr("null");
istringstream input(teststr);
Value v;
assert(v.parse(input));
assert(v.is<Value::Null>());
assert(!v.is<bool>());
}
{
string teststr("\"field1\"");
istringstream input(teststr);
Value v;
assert(v.parse(input));
assert(v.is<std::string>());
assert("field1" == v.get<std::string>());
ostringstream stream;
stream << v;
assert(stream.str() == "\"field1\"");
}
{
string teststr("[\"field1\", 6]");
istringstream input(teststr);
Array v;
assert(v.parse(input));
assert(v.has<std::string>(0));
assert("field1" == v.get<std::string>(0));
assert(v.has<long>(1));
assert(6 == v.get<long>(1));
assert(!v.has<bool>(2));
}
{
string teststr(
"{"
" \"foo\" : 1,"
" \"bar\" : false,"
" \"person\" : {\"name\" : \"GWB\", \"age\" : 60},"
" \"data\": [\"abcd\", 42]"
"}"
);
istringstream input(teststr);
Object o;
assert(o.parse(input));
assert(1 == o.get<long>("foo"));
assert(o.has<bool>("bar"));
assert(o.has<Object>("person"));
assert(o.get<Object>("person").has<long>("age"));
assert(o.has<Array>("data"));
assert(o.get<Array>("data").get<long>(1) == 42);
assert(o.get<Array>("data").get<string>(0) == "abcd");
assert(!o.has<long>("data"));
}
}
-3
View File
@@ -1,3 +0,0 @@
http://hjiang.net/archives/245
and
http://github.com/hjiang/jsonxx