Vladimir Golovnev (Glassez)
11 years ago
18 changed files with 7824 additions and 1 deletions
@ -0,0 +1,206 @@ |
|||||||
|
// -*-C++-*-
|
||||||
|
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
||||||
|
// by flex
|
||||||
|
|
||||||
|
// Copyright (c) 1993 The Regents of the University of California.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This code is derived from software contributed to Berkeley by
|
||||||
|
// Kent Williams and Tom Epperly.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
|
||||||
|
// 1. Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
// Neither the name of the University nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
|
||||||
|
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||||
|
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE.
|
||||||
|
|
||||||
|
// This file defines FlexLexer, an abstract class which specifies the
|
||||||
|
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
||||||
|
// which defines a particular lexer class.
|
||||||
|
//
|
||||||
|
// If you want to create multiple lexer classes, you use the -P flag
|
||||||
|
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
||||||
|
// include <FlexLexer.h> in your other sources once per lexer class:
|
||||||
|
//
|
||||||
|
// #undef yyFlexLexer
|
||||||
|
// #define yyFlexLexer xxFlexLexer
|
||||||
|
// #include <FlexLexer.h>
|
||||||
|
//
|
||||||
|
// #undef yyFlexLexer
|
||||||
|
// #define yyFlexLexer zzFlexLexer
|
||||||
|
// #include <FlexLexer.h>
|
||||||
|
// ...
|
||||||
|
|
||||||
|
#ifndef __FLEX_LEXER_H |
||||||
|
// Never included before - need to define base class.
|
||||||
|
#define __FLEX_LEXER_H |
||||||
|
|
||||||
|
#include <iostream> |
||||||
|
# ifndef FLEX_STD |
||||||
|
# define FLEX_STD std:: |
||||||
|
# endif |
||||||
|
|
||||||
|
extern "C++" { |
||||||
|
|
||||||
|
struct yy_buffer_state; |
||||||
|
typedef int yy_state_type; |
||||||
|
|
||||||
|
class FlexLexer { |
||||||
|
public: |
||||||
|
virtual ~FlexLexer() { } |
||||||
|
|
||||||
|
const char* YYText() const { return yytext; } |
||||||
|
int YYLeng() const { return yyleng; } |
||||||
|
|
||||||
|
virtual void |
||||||
|
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; |
||||||
|
virtual struct yy_buffer_state* |
||||||
|
yy_create_buffer( FLEX_STD istream* s, int size ) = 0; |
||||||
|
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; |
||||||
|
virtual void yyrestart( FLEX_STD istream* s ) = 0; |
||||||
|
|
||||||
|
virtual int yylex() = 0; |
||||||
|
|
||||||
|
// Call yylex with new input/output sources.
|
||||||
|
int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) |
||||||
|
{ |
||||||
|
switch_streams( new_in, new_out ); |
||||||
|
return yylex(); |
||||||
|
} |
||||||
|
|
||||||
|
// Switch to new input/output streams. A nil stream pointer
|
||||||
|
// indicates "keep the current one".
|
||||||
|
virtual void switch_streams( FLEX_STD istream* new_in = 0, |
||||||
|
FLEX_STD ostream* new_out = 0 ) = 0; |
||||||
|
|
||||||
|
int lineno() const { return yylineno; } |
||||||
|
|
||||||
|
int debug() const { return yy_flex_debug; } |
||||||
|
void set_debug( int flag ) { yy_flex_debug = flag; } |
||||||
|
|
||||||
|
protected: |
||||||
|
char* yytext; |
||||||
|
int yyleng; |
||||||
|
int yylineno; // only maintained if you use %option yylineno
|
||||||
|
int yy_flex_debug; // only has effect with -d or "%option debug"
|
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
#endif // FLEXLEXER_H
|
||||||
|
|
||||||
|
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) |
||||||
|
// Either this is the first time through (yyFlexLexerOnce not defined),
|
||||||
|
// or this is a repeated include to define a different flavor of
|
||||||
|
// yyFlexLexer, as discussed in the flex manual.
|
||||||
|
#define yyFlexLexerOnce |
||||||
|
|
||||||
|
extern "C++" { |
||||||
|
|
||||||
|
class yyFlexLexer : public FlexLexer { |
||||||
|
public: |
||||||
|
// arg_yyin and arg_yyout default to the cin and cout, but we
|
||||||
|
// only make that assignment when initializing in yylex().
|
||||||
|
yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); |
||||||
|
|
||||||
|
virtual ~yyFlexLexer(); |
||||||
|
|
||||||
|
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); |
||||||
|
struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); |
||||||
|
void yy_delete_buffer( struct yy_buffer_state* b ); |
||||||
|
void yyrestart( FLEX_STD istream* s ); |
||||||
|
|
||||||
|
void yypush_buffer_state( struct yy_buffer_state* new_buffer ); |
||||||
|
void yypop_buffer_state(); |
||||||
|
|
||||||
|
virtual int yylex(); |
||||||
|
virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ); |
||||||
|
virtual int yywrap(); |
||||||
|
|
||||||
|
protected: |
||||||
|
virtual int LexerInput( char* buf, int max_size ); |
||||||
|
virtual void LexerOutput( const char* buf, int size ); |
||||||
|
virtual void LexerError( const char* msg ); |
||||||
|
|
||||||
|
void yyunput( int c, char* buf_ptr ); |
||||||
|
int yyinput(); |
||||||
|
|
||||||
|
void yy_load_buffer_state(); |
||||||
|
void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); |
||||||
|
void yy_flush_buffer( struct yy_buffer_state* b ); |
||||||
|
|
||||||
|
int yy_start_stack_ptr; |
||||||
|
int yy_start_stack_depth; |
||||||
|
int* yy_start_stack; |
||||||
|
|
||||||
|
void yy_push_state( int new_state ); |
||||||
|
void yy_pop_state(); |
||||||
|
int yy_top_state(); |
||||||
|
|
||||||
|
yy_state_type yy_get_previous_state(); |
||||||
|
yy_state_type yy_try_NUL_trans( yy_state_type current_state ); |
||||||
|
int yy_get_next_buffer(); |
||||||
|
|
||||||
|
FLEX_STD istream* yyin; // input source for default LexerInput
|
||||||
|
FLEX_STD ostream* yyout; // output sink for default LexerOutput
|
||||||
|
|
||||||
|
// yy_hold_char holds the character lost when yytext is formed.
|
||||||
|
char yy_hold_char; |
||||||
|
|
||||||
|
// Number of characters read into yy_ch_buf.
|
||||||
|
int yy_n_chars; |
||||||
|
|
||||||
|
// Points to current character in buffer.
|
||||||
|
char* yy_c_buf_p; |
||||||
|
|
||||||
|
int yy_init; // whether we need to initialize
|
||||||
|
int yy_start; // start state number
|
||||||
|
|
||||||
|
// Flag which is used to allow yywrap()'s to do buffer switches
|
||||||
|
// instead of setting up a fresh yyin. A bit of a hack ...
|
||||||
|
int yy_did_buffer_switch_on_eof; |
||||||
|
|
||||||
|
|
||||||
|
size_t yy_buffer_stack_top; /**< index of top of stack. */ |
||||||
|
size_t yy_buffer_stack_max; /**< capacity of stack. */ |
||||||
|
struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ |
||||||
|
void yyensure_buffer_stack(void); |
||||||
|
|
||||||
|
// The following are not always needed, but may be depending
|
||||||
|
// on use of certain flex features (like REJECT or yymore()).
|
||||||
|
|
||||||
|
yy_state_type yy_last_accepting_state; |
||||||
|
char* yy_last_accepting_cpos; |
||||||
|
|
||||||
|
yy_state_type* yy_state_buf; |
||||||
|
yy_state_type* yy_state_ptr; |
||||||
|
|
||||||
|
char* yy_full_match; |
||||||
|
int* yy_full_state; |
||||||
|
int yy_full_lp; |
||||||
|
|
||||||
|
int yy_lp; |
||||||
|
int yy_looking_for_trail_begin; |
||||||
|
|
||||||
|
int yy_more_flag; |
||||||
|
int yy_more_len; |
||||||
|
int yy_more_offset; |
||||||
|
int yy_prev_more_offset; |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif // yyFlexLexer || ! yyFlexLexerOnce
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,300 @@ |
|||||||
|
/* A Bison parser, made by GNU Bison 2.7. */ |
||||||
|
|
||||||
|
/* Skeleton interface for Bison LALR(1) parsers in C++
|
||||||
|
|
||||||
|
Copyright (C) 2002-2012 Free Software Foundation, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work |
||||||
|
under terms of your choice, so long as that work isn't itself a |
||||||
|
parser generator using the skeleton or a modified version thereof |
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute |
||||||
|
the parser skeleton itself, you may (at your option) remove this |
||||||
|
special exception, which will cause the skeleton and the resulting |
||||||
|
Bison output files to be licensed under the GNU General Public |
||||||
|
License without this special exception. |
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in |
||||||
|
version 2.2 of Bison. */ |
||||||
|
|
||||||
|
/**
|
||||||
|
** \file json_parser.hh |
||||||
|
** Define the yy::parser class. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* C++ LALR(1) parser skeleton written by Akim Demaille. */ |
||||||
|
|
||||||
|
#ifndef YY_YY_JSON_PARSER_HH_INCLUDED |
||||||
|
# define YY_YY_JSON_PARSER_HH_INCLUDED |
||||||
|
|
||||||
|
/* "%code requires" blocks. */ |
||||||
|
/* Line 33 of lalr1.cc */ |
||||||
|
#line 26 "json_parser.yy" |
||||||
|
|
||||||
|
#include "parser_p.h" |
||||||
|
#include "json_scanner.h" |
||||||
|
#include "qjson_debug.h" |
||||||
|
|
||||||
|
#include <QtCore/QByteArray> |
||||||
|
#include <QtCore/QMap> |
||||||
|
#include <QtCore/QString> |
||||||
|
#include <QtCore/QVariant> |
||||||
|
|
||||||
|
#include <limits> |
||||||
|
|
||||||
|
class JSonScanner; |
||||||
|
|
||||||
|
namespace QJson { |
||||||
|
class Parser; |
||||||
|
} |
||||||
|
|
||||||
|
#define YYERROR_VERBOSE 1 |
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QVector<QVariant>*) |
||||||
|
Q_DECLARE_METATYPE(QVariantMap*) |
||||||
|
|
||||||
|
|
||||||
|
/* Line 33 of lalr1.cc */ |
||||||
|
#line 72 "json_parser.hh" |
||||||
|
|
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include <iostream> |
||||||
|
#include "stack.hh" |
||||||
|
#include "location.hh" |
||||||
|
|
||||||
|
/* Enabling traces. */ |
||||||
|
#ifndef YYDEBUG |
||||||
|
# define YYDEBUG 1 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
namespace yy { |
||||||
|
/* Line 33 of lalr1.cc */ |
||||||
|
#line 88 "json_parser.hh" |
||||||
|
|
||||||
|
/// A Bison parser.
|
||||||
|
class json_parser |
||||||
|
{ |
||||||
|
public: |
||||||
|
/// Symbol semantic values.
|
||||||
|
#ifndef YYSTYPE |
||||||
|
typedef int semantic_type; |
||||||
|
#else |
||||||
|
typedef YYSTYPE semantic_type; |
||||||
|
#endif |
||||||
|
/// Symbol locations.
|
||||||
|
typedef location location_type; |
||||||
|
/// Tokens.
|
||||||
|
struct token |
||||||
|
{ |
||||||
|
/* Tokens. */ |
||||||
|
enum yytokentype { |
||||||
|
END = 0, |
||||||
|
CURLY_BRACKET_OPEN = 1, |
||||||
|
CURLY_BRACKET_CLOSE = 2, |
||||||
|
SQUARE_BRACKET_OPEN = 3, |
||||||
|
SQUARE_BRACKET_CLOSE = 4, |
||||||
|
COLON = 5, |
||||||
|
COMMA = 6, |
||||||
|
NUMBER = 7, |
||||||
|
TRUE_VAL = 8, |
||||||
|
FALSE_VAL = 9, |
||||||
|
NULL_VAL = 10, |
||||||
|
STRING = 11, |
||||||
|
INVALID = 12 |
||||||
|
}; |
||||||
|
|
||||||
|
}; |
||||||
|
/// Token type.
|
||||||
|
typedef token::yytokentype token_type; |
||||||
|
|
||||||
|
/// Build a parser object.
|
||||||
|
json_parser (QJson::ParserPrivate* driver_yyarg); |
||||||
|
virtual ~json_parser (); |
||||||
|
|
||||||
|
/// Parse.
|
||||||
|
/// \returns 0 iff parsing succeeded.
|
||||||
|
virtual int parse (); |
||||||
|
|
||||||
|
#if YYDEBUG |
||||||
|
/// The current debugging stream.
|
||||||
|
std::ostream& debug_stream () const; |
||||||
|
/// Set the current debugging stream.
|
||||||
|
void set_debug_stream (std::ostream &); |
||||||
|
|
||||||
|
/// Type for debugging levels.
|
||||||
|
typedef int debug_level_type; |
||||||
|
/// The current debugging level.
|
||||||
|
debug_level_type debug_level () const; |
||||||
|
/// Set the current debugging level.
|
||||||
|
void set_debug_level (debug_level_type l); |
||||||
|
#endif |
||||||
|
|
||||||
|
private: |
||||||
|
/// Report a syntax error.
|
||||||
|
/// \param loc where the syntax error is found.
|
||||||
|
/// \param msg a description of the syntax error.
|
||||||
|
virtual void error (const location_type& loc, const std::string& msg); |
||||||
|
|
||||||
|
/// Generate an error message.
|
||||||
|
/// \param state the state where the error occurred.
|
||||||
|
/// \param tok the lookahead token.
|
||||||
|
virtual std::string yysyntax_error_ (int yystate, int tok); |
||||||
|
|
||||||
|
#if YYDEBUG |
||||||
|
/// \brief Report a symbol value on the debug stream.
|
||||||
|
/// \param yytype The token type.
|
||||||
|
/// \param yyvaluep Its semantic value.
|
||||||
|
/// \param yylocationp Its location.
|
||||||
|
virtual void yy_symbol_value_print_ (int yytype, |
||||||
|
const semantic_type* yyvaluep, |
||||||
|
const location_type* yylocationp); |
||||||
|
/// \brief Report a symbol on the debug stream.
|
||||||
|
/// \param yytype The token type.
|
||||||
|
/// \param yyvaluep Its semantic value.
|
||||||
|
/// \param yylocationp Its location.
|
||||||
|
virtual void yy_symbol_print_ (int yytype, |
||||||
|
const semantic_type* yyvaluep, |
||||||
|
const location_type* yylocationp); |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
/// State numbers.
|
||||||
|
typedef int state_type; |
||||||
|
/// State stack type.
|
||||||
|
typedef stack<state_type> state_stack_type; |
||||||
|
/// Semantic value stack type.
|
||||||
|
typedef stack<semantic_type> semantic_stack_type; |
||||||
|
/// location stack type.
|
||||||
|
typedef stack<location_type> location_stack_type; |
||||||
|
|
||||||
|
/// The state stack.
|
||||||
|
state_stack_type yystate_stack_; |
||||||
|
/// The semantic value stack.
|
||||||
|
semantic_stack_type yysemantic_stack_; |
||||||
|
/// The location stack.
|
||||||
|
location_stack_type yylocation_stack_; |
||||||
|
|
||||||
|
/// Whether the given \c yypact_ value indicates a defaulted state.
|
||||||
|
/// \param yyvalue the value to check
|
||||||
|
static bool yy_pact_value_is_default_ (int yyvalue); |
||||||
|
|
||||||
|
/// Whether the given \c yytable_ value indicates a syntax error.
|
||||||
|
/// \param yyvalue the value to check
|
||||||
|
static bool yy_table_value_is_error_ (int yyvalue); |
||||||
|
|
||||||
|
/// Internal symbol numbers.
|
||||||
|
typedef unsigned char token_number_type; |
||||||
|
/* Tables. */ |
||||||
|
/// For a state, the index in \a yytable_ of its portion.
|
||||||
|
static const signed char yypact_[]; |
||||||
|
static const signed char yypact_ninf_; |
||||||
|
|
||||||
|
/// For a state, default reduction number.
|
||||||
|
/// Unless\a yytable_ specifies something else to do.
|
||||||
|
/// Zero means the default is an error.
|
||||||
|
static const unsigned char yydefact_[]; |
||||||
|
|
||||||
|
static const signed char yypgoto_[]; |
||||||
|
static const signed char yydefgoto_[]; |
||||||
|
|
||||||
|
/// What to do in a state.
|
||||||
|
/// \a yytable_[yypact_[s]]: what to do in state \a s.
|
||||||
|
/// - if positive, shift that token.
|
||||||
|
/// - if negative, reduce the rule which number is the opposite.
|
||||||
|
/// - if zero, do what YYDEFACT says.
|
||||||
|
static const unsigned char yytable_[]; |
||||||
|
static const signed char yytable_ninf_; |
||||||
|
|
||||||
|
static const signed char yycheck_[]; |
||||||
|
|
||||||
|
/// For a state, its accessing symbol.
|
||||||
|
static const unsigned char yystos_[]; |
||||||
|
|
||||||
|
/// For a rule, its LHS.
|
||||||
|
static const unsigned char yyr1_[]; |
||||||
|
/// For a rule, its RHS length.
|
||||||
|
static const unsigned char yyr2_[]; |
||||||
|
|
||||||
|
/// Convert the symbol name \a n to a form suitable for a diagnostic.
|
||||||
|
static std::string yytnamerr_ (const char *n); |
||||||
|
|
||||||
|
|
||||||
|
/// For a symbol, its name in clear.
|
||||||
|
static const char* const yytname_[]; |
||||||
|
#if YYDEBUG |
||||||
|
/// A type to store symbol numbers and -1.
|
||||||
|
typedef signed char rhs_number_type; |
||||||
|
/// A `-1'-separated list of the rules' RHS.
|
||||||
|
static const rhs_number_type yyrhs_[]; |
||||||
|
/// For each rule, the index of the first RHS symbol in \a yyrhs_.
|
||||||
|
static const unsigned char yyprhs_[]; |
||||||
|
/// For each rule, its source line number.
|
||||||
|
static const unsigned char yyrline_[]; |
||||||
|
/// For each scanner token number, its symbol number.
|
||||||
|
static const unsigned short int yytoken_number_[]; |
||||||
|
/// Report on the debug stream that the rule \a r is going to be reduced.
|
||||||
|
virtual void yy_reduce_print_ (int r); |
||||||
|
/// Print the state stack on the debug stream.
|
||||||
|
virtual void yystack_print_ (); |
||||||
|
|
||||||
|
/* Debugging. */ |
||||||
|
int yydebug_; |
||||||
|
std::ostream* yycdebug_; |
||||||
|
#endif |
||||||
|
|
||||||
|
/// Convert a scanner token number \a t to a symbol number.
|
||||||
|
token_number_type yytranslate_ (int t); |
||||||
|
|
||||||
|
/// \brief Reclaim the memory associated to a symbol.
|
||||||
|
/// \param yymsg Why this token is reclaimed.
|
||||||
|
/// If null, do not display the symbol, just free it.
|
||||||
|
/// \param yytype The symbol type.
|
||||||
|
/// \param yyvaluep Its semantic value.
|
||||||
|
/// \param yylocationp Its location.
|
||||||
|
inline void yydestruct_ (const char* yymsg, |
||||||
|
int yytype, |
||||||
|
semantic_type* yyvaluep, |
||||||
|
location_type* yylocationp); |
||||||
|
|
||||||
|
/// Pop \a n symbols the three stacks.
|
||||||
|
inline void yypop_ (unsigned int n = 1); |
||||||
|
|
||||||
|
/* Constants. */ |
||||||
|
static const int yyeof_; |
||||||
|
/* LAST_ -- Last index in TABLE_. */ |
||||||
|
static const int yylast_; |
||||||
|
static const int yynnts_; |
||||||
|
static const int yyempty_; |
||||||
|
static const int yyfinal_; |
||||||
|
static const int yyterror_; |
||||||
|
static const int yyerrcode_; |
||||||
|
static const int yyntokens_; |
||||||
|
static const unsigned int yyuser_token_number_max_; |
||||||
|
static const token_number_type yyundef_token_; |
||||||
|
|
||||||
|
/* User arguments. */ |
||||||
|
QJson::ParserPrivate* driver; |
||||||
|
}; |
||||||
|
|
||||||
|
} // yy
|
||||||
|
/* Line 33 of lalr1.cc */ |
||||||
|
#line 297 "json_parser.hh" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !YY_YY_JSON_PARSER_HH_INCLUDED */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,82 @@ |
|||||||
|
/* This file is part of QJson
|
||||||
|
* |
||||||
|
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com> |
||||||
|
* Copyright (C) 2013 Silvio Moioli <silvio@moioli.net> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
#include "json_scanner.cc" |
||||||
|
|
||||||
|
#include "qjson_debug.h" |
||||||
|
#include "json_scanner.h" |
||||||
|
#include "json_parser.hh" |
||||||
|
|
||||||
|
#include <ctype.h> |
||||||
|
|
||||||
|
#include <QtCore/QDebug> |
||||||
|
#include <QtCore/QRegExp> |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
|
||||||
|
|
||||||
|
JSonScanner::JSonScanner(QIODevice* io) |
||||||
|
: m_allowSpecialNumbers(false), |
||||||
|
m_io (io), |
||||||
|
m_criticalError(false), |
||||||
|
m_C_locale(QLocale::C) |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
JSonScanner::~JSonScanner() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void JSonScanner::allowSpecialNumbers(bool allow) { |
||||||
|
m_allowSpecialNumbers = allow; |
||||||
|
} |
||||||
|
|
||||||
|
int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc) { |
||||||
|
m_yylval = yylval; |
||||||
|
m_yylloc = yylloc; |
||||||
|
m_yylloc->step(); |
||||||
|
int result = yylex(); |
||||||
|
|
||||||
|
if (m_criticalError) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
int JSonScanner::LexerInput(char* buf, int max_size) { |
||||||
|
if (!m_io->isOpen()) { |
||||||
|
qCritical() << "JSonScanner::yylex - io device is not open"; |
||||||
|
m_criticalError = true; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int readBytes = m_io->read(buf, max_size); |
||||||
|
if(readBytes < 0) { |
||||||
|
qCritical() << "JSonScanner::yylex - error while reading from io device"; |
||||||
|
m_criticalError = true; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return readBytes; |
||||||
|
} |
||||||
|
|
||||||
|
|
@ -0,0 +1,66 @@ |
|||||||
|
/* This file is part of QJson
|
||||||
|
* |
||||||
|
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _JSON_SCANNER |
||||||
|
#define _JSON_SCANNER |
||||||
|
|
||||||
|
#include <QtCore/QIODevice> |
||||||
|
#include <QtCore/QVariant> |
||||||
|
#include <QtCore/QLocale> |
||||||
|
|
||||||
|
#define YYSTYPE QVariant |
||||||
|
|
||||||
|
// Only include FlexLexer.h if it hasn't been already included
|
||||||
|
#if ! defined(yyFlexLexerOnce) |
||||||
|
#include <FlexLexer.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "parser_p.h" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace yy { |
||||||
|
class location; |
||||||
|
int yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver); |
||||||
|
} |
||||||
|
|
||||||
|
class JSonScanner : public yyFlexLexer |
||||||
|
{ |
||||||
|
public: |
||||||
|
explicit JSonScanner(QIODevice* io); |
||||||
|
~JSonScanner(); |
||||||
|
|
||||||
|
void allowSpecialNumbers(bool allow); |
||||||
|
|
||||||
|
int yylex(YYSTYPE* yylval, yy::location *yylloc); |
||||||
|
int yylex(); |
||||||
|
int LexerInput(char* buf, int max_size); |
||||||
|
protected: |
||||||
|
bool m_allowSpecialNumbers; |
||||||
|
QIODevice* m_io; |
||||||
|
|
||||||
|
YYSTYPE* m_yylval; |
||||||
|
yy::location* m_yylloc; |
||||||
|
bool m_criticalError; |
||||||
|
QString m_currentString; |
||||||
|
QLocale m_C_locale; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,181 @@ |
|||||||
|
/* A Bison parser, made by GNU Bison 2.7. */ |
||||||
|
|
||||||
|
/* Locations for Bison parsers in C++
|
||||||
|
|
||||||
|
Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work |
||||||
|
under terms of your choice, so long as that work isn't itself a |
||||||
|
parser generator using the skeleton or a modified version thereof |
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute |
||||||
|
the parser skeleton itself, you may (at your option) remove this |
||||||
|
special exception, which will cause the skeleton and the resulting |
||||||
|
Bison output files to be licensed under the GNU General Public |
||||||
|
License without this special exception. |
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in |
||||||
|
version 2.2 of Bison. */ |
||||||
|
|
||||||
|
/**
|
||||||
|
** \file location.hh |
||||||
|
** Define the yy::location class. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef YY_YY_LOCATION_HH_INCLUDED |
||||||
|
# define YY_YY_LOCATION_HH_INCLUDED |
||||||
|
|
||||||
|
# include "position.hh" |
||||||
|
|
||||||
|
|
||||||
|
namespace yy { |
||||||
|
/* Line 166 of location.cc */ |
||||||
|
#line 47 "location.hh" |
||||||
|
|
||||||
|
/// Abstract a location.
|
||||||
|
class location |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
/// Construct a location from \a b to \a e.
|
||||||
|
location (const position& b, const position& e) |
||||||
|
: begin (b) |
||||||
|
, end (e) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/// Construct a 0-width location in \a p.
|
||||||
|
explicit location (const position& p = position ()) |
||||||
|
: begin (p) |
||||||
|
, end (p) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||||
|
explicit location (std::string* f, |
||||||
|
unsigned int l = 1u, |
||||||
|
unsigned int c = 1u) |
||||||
|
: begin (f, l, c) |
||||||
|
, end (f, l, c) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// Initialization.
|
||||||
|
void initialize (std::string* f = YY_NULL, |
||||||
|
unsigned int l = 1u, |
||||||
|
unsigned int c = 1u) |
||||||
|
{ |
||||||
|
begin.initialize (f, l, c); |
||||||
|
end = begin; |
||||||
|
} |
||||||
|
|
||||||
|
/** \name Line and Column related manipulators
|
||||||
|
** \{ */ |
||||||
|
public: |
||||||
|
/// Reset initial location to final location.
|
||||||
|
void step () |
||||||
|
{ |
||||||
|
begin = end; |
||||||
|
} |
||||||
|
|
||||||
|
/// Extend the current location to the COUNT next columns.
|
||||||
|
void columns (unsigned int count = 1) |
||||||
|
{ |
||||||
|
end += count; |
||||||
|
} |
||||||
|
|
||||||
|
/// Extend the current location to the COUNT next lines.
|
||||||
|
void lines (unsigned int count = 1) |
||||||
|
{ |
||||||
|
end.lines (count); |
||||||
|
} |
||||||
|
/** \} */ |
||||||
|
|
||||||
|
|
||||||
|
public: |
||||||
|
/// Beginning of the located region.
|
||||||
|
position begin; |
||||||
|
/// End of the located region.
|
||||||
|
position end; |
||||||
|
}; |
||||||
|
|
||||||
|
/// Join two location objects to create a location.
|
||||||
|
inline const location operator+ (const location& begin, const location& end) |
||||||
|
{ |
||||||
|
location res = begin; |
||||||
|
res.end = end.end; |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/// Add two location objects.
|
||||||
|
inline const location operator+ (const location& begin, unsigned int width) |
||||||
|
{ |
||||||
|
location res = begin; |
||||||
|
res.columns (width); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/// Add and assign a location.
|
||||||
|
inline location& operator+= (location& res, unsigned int width) |
||||||
|
{ |
||||||
|
res.columns (width); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool |
||||||
|
operator== (const location& loc1, const location& loc2) |
||||||
|
{ |
||||||
|
return loc1.begin == loc2.begin && loc1.end == loc2.end; |
||||||
|
} |
||||||
|
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool |
||||||
|
operator!= (const location& loc1, const location& loc2) |
||||||
|
{ |
||||||
|
return !(loc1 == loc2); |
||||||
|
} |
||||||
|
|
||||||
|
/** \brief Intercept output stream redirection.
|
||||||
|
** \param ostr the destination output stream |
||||||
|
** \param loc a reference to the location to redirect |
||||||
|
** |
||||||
|
** Avoid duplicate information. |
||||||
|
*/ |
||||||
|
template <typename YYChar> |
||||||
|
inline std::basic_ostream<YYChar>& |
||||||
|
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc) |
||||||
|
{ |
||||||
|
position last = loc.end - 1; |
||||||
|
ostr << loc.begin; |
||||||
|
if (last.filename |
||||||
|
&& (!loc.begin.filename |
||||||
|
|| *loc.begin.filename != *last.filename)) |
||||||
|
ostr << '-' << last; |
||||||
|
else if (loc.begin.line != last.line) |
||||||
|
ostr << '-' << last.line << '.' << last.column; |
||||||
|
else if (loc.begin.column != last.column) |
||||||
|
ostr << '-' << last.column; |
||||||
|
return ostr; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} // yy
|
||||||
|
/* Line 296 of location.cc */ |
||||||
|
#line 180 "location.hh" |
||||||
|
|
||||||
|
#endif /* !YY_YY_LOCATION_HH_INCLUDED */ |
@ -0,0 +1,141 @@ |
|||||||
|
/* This file is part of QJson
|
||||||
|
* |
||||||
|
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "parser.h" |
||||||
|
#include "parser_p.h" |
||||||
|
#include "json_parser.hh" |
||||||
|
#include "json_scanner.h" |
||||||
|
|
||||||
|
#include <QtCore/QBuffer> |
||||||
|
#include <QtCore/QStringList> |
||||||
|
#include <QtCore/QTextStream> |
||||||
|
#include <QtCore/QDebug> |
||||||
|
|
||||||
|
using namespace QJson; |
||||||
|
|
||||||
|
ParserPrivate::ParserPrivate() : |
||||||
|
m_scanner(0) |
||||||
|
{ |
||||||
|
m_specialNumbersAllowed = false; |
||||||
|
reset(); |
||||||
|
} |
||||||
|
|
||||||
|
ParserPrivate::~ParserPrivate() |
||||||
|
{ |
||||||
|
if (m_scanner) |
||||||
|
delete m_scanner; |
||||||
|
} |
||||||
|
|
||||||
|
void ParserPrivate::setError(QString errorMsg, int errorLine) { |
||||||
|
m_error = true; |
||||||
|
m_errorMsg = errorMsg; |
||||||
|
m_errorLine = errorLine; |
||||||
|
} |
||||||
|
|
||||||
|
void ParserPrivate::reset() |
||||||
|
{ |
||||||
|
m_error = false; |
||||||
|
m_errorLine = 0; |
||||||
|
m_errorMsg.clear(); |
||||||
|
if (m_scanner) { |
||||||
|
delete m_scanner; |
||||||
|
m_scanner = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Parser::Parser() : |
||||||
|
d(new ParserPrivate) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
Parser::~Parser() |
||||||
|
{ |
||||||
|
delete d; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant Parser::parse (QIODevice* io, bool* ok) |
||||||
|
{ |
||||||
|
d->reset(); |
||||||
|
|
||||||
|
if (!io->isOpen()) { |
||||||
|
if (!io->open(QIODevice::ReadOnly)) { |
||||||
|
if (ok != 0) |
||||||
|
*ok = false; |
||||||
|
qCritical ("Error opening device"); |
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!io->isReadable()) { |
||||||
|
if (ok != 0) |
||||||
|
*ok = false; |
||||||
|
qCritical ("Device is not readable"); |
||||||
|
io->close(); |
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
|
||||||
|
if (io->atEnd()) { |
||||||
|
if (ok != 0) |
||||||
|
*ok = false; |
||||||
|
d->setError(QLatin1String("No data"), 0); |
||||||
|
io->close(); |
||||||
|
return QVariant(); |
||||||
|
} |
||||||
|
|
||||||
|
d->m_scanner = new JSonScanner (io); |
||||||
|
d->m_scanner->allowSpecialNumbers(d->m_specialNumbersAllowed); |
||||||
|
yy::json_parser parser(d); |
||||||
|
parser.parse(); |
||||||
|
|
||||||
|
delete d->m_scanner; |
||||||
|
d->m_scanner = 0; |
||||||
|
|
||||||
|
if (ok != 0) |
||||||
|
*ok = !d->m_error; |
||||||
|
|
||||||
|
io->close(); |
||||||
|
return d->m_result; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant Parser::parse(const QByteArray& jsonString, bool* ok) { |
||||||
|
QBuffer buffer; |
||||||
|
buffer.open(QBuffer::ReadWrite); |
||||||
|
buffer.write(jsonString); |
||||||
|
buffer.seek(0); |
||||||
|
return parse (&buffer, ok); |
||||||
|
} |
||||||
|
|
||||||
|
QString Parser::errorString() const |
||||||
|
{ |
||||||
|
return d->m_errorMsg; |
||||||
|
} |
||||||
|
|
||||||
|
int Parser::errorLine() const |
||||||
|
{ |
||||||
|
return d->m_errorLine; |
||||||
|
} |
||||||
|
|
||||||
|
void QJson::Parser::allowSpecialNumbers(bool allowSpecialNumbers) { |
||||||
|
d->m_specialNumbersAllowed = allowSpecialNumbers; |
||||||
|
} |
||||||
|
|
||||||
|
bool Parser::specialNumbersAllowed() const { |
||||||
|
return d->m_specialNumbersAllowed; |
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
/* This file is part of QJson
|
||||||
|
* |
||||||
|
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef QJSON_PARSER_H |
||||||
|
#define QJSON_PARSER_H |
||||||
|
|
||||||
|
#include "qjson_export.h" |
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE |
||||||
|
class QIODevice; |
||||||
|
class QVariant; |
||||||
|
QT_END_NAMESPACE |
||||||
|
|
||||||
|
/**
|
||||||
|
* Namespace used by QJson |
||||||
|
*/ |
||||||
|
namespace QJson { |
||||||
|
|
||||||
|
class ParserPrivate; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main class used to convert JSON data to QVariant objects |
||||||
|
*/ |
||||||
|
class QJSON_EXPORT Parser |
||||||
|
{ |
||||||
|
public: |
||||||
|
Parser(); |
||||||
|
~Parser(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Read JSON string from the I/O Device and converts it to a QVariant object |
||||||
|
* @param io Input output device |
||||||
|
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true. |
||||||
|
* @returns a QVariant object generated from the JSON string |
||||||
|
*/ |
||||||
|
QVariant parse(QIODevice* io, bool* ok = 0); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a method provided for convenience. |
||||||
|
* @param jsonData data containing the JSON object representation |
||||||
|
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true. |
||||||
|
* @returns a QVariant object generated from the JSON string |
||||||
|
* @sa errorString |
||||||
|
* @sa errorLine |
||||||
|
*/ |
||||||
|
QVariant parse(const QByteArray& jsonData, bool* ok = 0); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the error message |
||||||
|
* @returns a QString object containing the error message of the last parse operation |
||||||
|
* @sa errorLine |
||||||
|
*/ |
||||||
|
QString errorString() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns line number where the error occurred |
||||||
|
* @returns the line number where the error occurred |
||||||
|
* @sa errorString |
||||||
|
*/ |
||||||
|
int errorLine() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether special numbers (Infinity, -Infinity, NaN) are allowed as an extension to |
||||||
|
* the standard |
||||||
|
* @param allowSpecialNumbers new value of whether special numbers are allowed |
||||||
|
* @sa specialNumbersAllowed |
||||||
|
*/ |
||||||
|
void allowSpecialNumbers(bool allowSpecialNumbers); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns whether special numbers (Infinity, -Infinity, NaN) are allowed |
||||||
|
* @sa allowSpecialNumbers |
||||||
|
*/ |
||||||
|
bool specialNumbersAllowed() const; |
||||||
|
|
||||||
|
private: |
||||||
|
Q_DISABLE_COPY(Parser) |
||||||
|
ParserPrivate* const d; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
#endif // QJSON_PARSER_H
|
@ -0,0 +1,57 @@ |
|||||||
|
/* This file is part of QJson
|
||||||
|
* |
||||||
|
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com> |
||||||
|
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef QJSON_PARSER_P_H |
||||||
|
#define QJSON_PARSER_P_H |
||||||
|
|
||||||
|
#include "parser.h" |
||||||
|
|
||||||
|
#include <QtCore/QString> |
||||||
|
#include <QtCore/QVariant> |
||||||
|
|
||||||
|
class JSonScanner; |
||||||
|
|
||||||
|
namespace yy { |
||||||
|
class json_parser; |
||||||
|
} |
||||||
|
|
||||||
|
namespace QJson { |
||||||
|
|
||||||
|
class ParserPrivate |
||||||
|
{ |
||||||
|
public: |
||||||
|
ParserPrivate(); |
||||||
|
~ParserPrivate(); |
||||||
|
|
||||||
|
void reset(); |
||||||
|
|
||||||
|
void setError(QString errorMsg, int line); |
||||||
|
|
||||||
|
JSonScanner* m_scanner; |
||||||
|
bool m_error; |
||||||
|
int m_errorLine; |
||||||
|
QString m_errorMsg; |
||||||
|
QVariant m_result; |
||||||
|
bool m_specialNumbersAllowed; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
#endif // QJSON_PARSER_H
|
@ -0,0 +1,172 @@ |
|||||||
|
/* A Bison parser, made by GNU Bison 2.7. */ |
||||||
|
|
||||||
|
/* Positions for Bison parsers in C++
|
||||||
|
|
||||||
|
Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work |
||||||
|
under terms of your choice, so long as that work isn't itself a |
||||||
|
parser generator using the skeleton or a modified version thereof |
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute |
||||||
|
the parser skeleton itself, you may (at your option) remove this |
||||||
|
special exception, which will cause the skeleton and the resulting |
||||||
|
Bison output files to be licensed under the GNU General Public |
||||||
|
License without this special exception. |
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in |
||||||
|
version 2.2 of Bison. */ |
||||||
|
|
||||||
|
/**
|
||||||
|
** \file position.hh |
||||||
|
** Define the yy::position class. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef YY_YY_POSITION_HH_INCLUDED |
||||||
|
# define YY_YY_POSITION_HH_INCLUDED |
||||||
|
|
||||||
|
# include <algorithm> // std::max
|
||||||
|
# include <iostream> |
||||||
|
# include <string> |
||||||
|
|
||||||
|
# ifndef YY_NULL |
||||||
|
# if defined __cplusplus && 201103L <= __cplusplus |
||||||
|
# define YY_NULL nullptr |
||||||
|
# else |
||||||
|
# define YY_NULL 0 |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
|
||||||
|
|
||||||
|
namespace yy { |
||||||
|
/* Line 36 of location.cc */ |
||||||
|
#line 57 "position.hh" |
||||||
|
/// Abstract a position.
|
||||||
|
class position |
||||||
|
{ |
||||||
|
public: |
||||||
|
|
||||||
|
/// Construct a position.
|
||||||
|
explicit position (std::string* f = YY_NULL, |
||||||
|
unsigned int l = 1u, |
||||||
|
unsigned int c = 1u) |
||||||
|
: filename (f) |
||||||
|
, line (l) |
||||||
|
, column (c) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// Initialization.
|
||||||
|
void initialize (std::string* fn = YY_NULL, |
||||||
|
unsigned int l = 1u, |
||||||
|
unsigned int c = 1u) |
||||||
|
{ |
||||||
|
filename = fn; |
||||||
|
line = l; |
||||||
|
column = c; |
||||||
|
} |
||||||
|
|
||||||
|
/** \name Line and Column related manipulators
|
||||||
|
** \{ */ |
||||||
|
/// (line related) Advance to the COUNT next lines.
|
||||||
|
void lines (int count = 1) |
||||||
|
{ |
||||||
|
column = 1u; |
||||||
|
line += count; |
||||||
|
} |
||||||
|
|
||||||
|
/// (column related) Advance to the COUNT next columns.
|
||||||
|
void columns (int count = 1) |
||||||
|
{ |
||||||
|
column = std::max (1u, column + count); |
||||||
|
} |
||||||
|
/** \} */ |
||||||
|
|
||||||
|
/// File name to which this position refers.
|
||||||
|
std::string* filename; |
||||||
|
/// Current line number.
|
||||||
|
unsigned int line; |
||||||
|
/// Current column number.
|
||||||
|
unsigned int column; |
||||||
|
}; |
||||||
|
|
||||||
|
/// Add and assign a position.
|
||||||
|
inline position& |
||||||
|
operator+= (position& res, const int width) |
||||||
|
{ |
||||||
|
res.columns (width); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/// Add two position objects.
|
||||||
|
inline const position |
||||||
|
operator+ (const position& begin, const int width) |
||||||
|
{ |
||||||
|
position res = begin; |
||||||
|
return res += width; |
||||||
|
} |
||||||
|
|
||||||
|
/// Add and assign a position.
|
||||||
|
inline position& |
||||||
|
operator-= (position& res, const int width) |
||||||
|
{ |
||||||
|
return res += -width; |
||||||
|
} |
||||||
|
|
||||||
|
/// Add two position objects.
|
||||||
|
inline const position |
||||||
|
operator- (const position& begin, const int width) |
||||||
|
{ |
||||||
|
return begin + -width; |
||||||
|
} |
||||||
|
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool |
||||||
|
operator== (const position& pos1, const position& pos2) |
||||||
|
{ |
||||||
|
return (pos1.line == pos2.line |
||||||
|
&& pos1.column == pos2.column |
||||||
|
&& (pos1.filename == pos2.filename |
||||||
|
|| (pos1.filename && pos2.filename |
||||||
|
&& *pos1.filename == *pos2.filename))); |
||||||
|
} |
||||||
|
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool |
||||||
|
operator!= (const position& pos1, const position& pos2) |
||||||
|
{ |
||||||
|
return !(pos1 == pos2); |
||||||
|
} |
||||||
|
|
||||||
|
/** \brief Intercept output stream redirection.
|
||||||
|
** \param ostr the destination output stream |
||||||
|
** \param pos a reference to the position to redirect |
||||||
|
*/ |
||||||
|
template <typename YYChar> |
||||||
|
inline std::basic_ostream<YYChar>& |
||||||
|
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos) |
||||||
|
{ |
||||||
|
if (pos.filename) |
||||||
|
ostr << *pos.filename << ':'; |
||||||
|
return ostr << pos.line << '.' << pos.column; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} // yy
|
||||||
|
/* Line 148 of location.cc */ |
||||||
|
#line 172 "position.hh" |
||||||
|
#endif /* !YY_YY_POSITION_HH_INCLUDED */ |
@ -0,0 +1,19 @@ |
|||||||
|
INCLUDEPATH += $$PWD |
||||||
|
|
||||||
|
HEADERS += $$PWD/FlexLexer.h \ |
||||||
|
$$PWD/stack.hh \ |
||||||
|
$$PWD/position.hh \ |
||||||
|
$$PWD/location.hh \ |
||||||
|
$$PWD/json_parser.hh \ |
||||||
|
$$PWD/json_scanner.h \ |
||||||
|
$$PWD/parser.h \ |
||||||
|
$$PWD/parser_p.h \ |
||||||
|
$$PWD_debug.h \ |
||||||
|
$$PWD_export.h \ |
||||||
|
$$PWD/serializer.h |
||||||
|
|
||||||
|
SOURCES += $$PWD/json_parser.cc \ |
||||||
|
$$PWD/json_scanner.cc \ |
||||||
|
$$PWD/json_scanner.cpp \ |
||||||
|
$$PWD/parser.cpp \ |
||||||
|
$$PWD/serializer.cpp |
@ -0,0 +1,34 @@ |
|||||||
|
/* This file is part of qjson
|
||||||
|
* |
||||||
|
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org> |
||||||
|
* Copyright (C) 2013 Silvio Moioli <silvio@moioli.net> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef QJSON_DEBUG_H |
||||||
|
#define QJSON_DEBUG_H |
||||||
|
|
||||||
|
#include <QtCore/QDebug> |
||||||
|
|
||||||
|
// define qjsonDebug()
|
||||||
|
#ifdef QJSON_VERBOSE_DEBUG_OUTPUT |
||||||
|
inline QDebug qjsonDebug() { return QDebug(QtDebugMsg); } |
||||||
|
#else |
||||||
|
#define qjsonDebug() if(false) QDebug(QtDebugMsg) |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,37 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2014 Vladimir Golovnev |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU General Public License |
||||||
|
* as published by the Free Software Foundation; either version 2 |
||||||
|
* of the License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; if not, write to the Free Software |
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
* |
||||||
|
* Contact : glassez@yandex.ru |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef QJSON_EXPORT_H |
||||||
|
#define QJSON_EXPORT_H |
||||||
|
|
||||||
|
#include <qglobal.h> |
||||||
|
#define QJSON_EXPORT |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,444 @@ |
|||||||
|
/* This file is part of qjson
|
||||||
|
* |
||||||
|
* Copyright (C) 2009 Till Adam <adam@kde.org> |
||||||
|
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "serializer.h" |
||||||
|
|
||||||
|
#include <QtCore/QDataStream> |
||||||
|
#include <QtCore/QStringList> |
||||||
|
#include <QtCore/QVariant> |
||||||
|
|
||||||
|
#include <cmath> |
||||||
|
|
||||||
|
#ifdef Q_OS_SOLARIS |
||||||
|
# ifndef isinf |
||||||
|
# include <ieeefp.h> |
||||||
|
# define isinf(x) (!finite((x)) && (x)==(x)) |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef _MSC_VER // using MSVC compiler
|
||||||
|
#include <float.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
using namespace QJson; |
||||||
|
|
||||||
|
class Serializer::SerializerPrivate { |
||||||
|
public: |
||||||
|
SerializerPrivate() : |
||||||
|
specialNumbersAllowed(false), |
||||||
|
indentMode(QJson::IndentNone), |
||||||
|
doublePrecision(6) { |
||||||
|
errorMessage.clear(); |
||||||
|
} |
||||||
|
QString errorMessage; |
||||||
|
bool specialNumbersAllowed; |
||||||
|
IndentMode indentMode; |
||||||
|
int doublePrecision; |
||||||
|
QByteArray buildIndent(int spaces); |
||||||
|
QByteArray serialize( const QVariant &v, bool *ok, int indentLevel = 0); |
||||||
|
QString sanitizeString( QString str ); |
||||||
|
QByteArray join( const QList<QByteArray>& list, const QByteArray& sep ); |
||||||
|
}; |
||||||
|
|
||||||
|
QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, const QByteArray& sep ) { |
||||||
|
QByteArray res; |
||||||
|
Q_FOREACH( const QByteArray& i, list ) { |
||||||
|
if ( !res.isEmpty() ) |
||||||
|
res += sep; |
||||||
|
res += i; |
||||||
|
} |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, bool *ok, int indentLevel) |
||||||
|
{ |
||||||
|
QByteArray str; |
||||||
|
|
||||||
|
if ( ! v.isValid() ) { // invalid or null?
|
||||||
|
str = "null"; |
||||||
|
} else if (( v.type() == QVariant::List ) || ( v.type() == QVariant::StringList )){ // an array or a stringlist?
|
||||||
|
const QVariantList list = v.toList(); |
||||||
|
QList<QByteArray> values; |
||||||
|
Q_FOREACH( const QVariant& var, list ) |
||||||
|
{ |
||||||
|
QByteArray serializedValue; |
||||||
|
|
||||||
|
serializedValue = serialize( var, ok, indentLevel+1); |
||||||
|
|
||||||
|
if ( !*ok ) { |
||||||
|
break; |
||||||
|
} |
||||||
|
switch(indentMode) { |
||||||
|
case QJson::IndentFull : |
||||||
|
case QJson::IndentMedium : |
||||||
|
case QJson::IndentMinimum : |
||||||
|
values << serializedValue; |
||||||
|
break; |
||||||
|
case QJson::IndentCompact : |
||||||
|
case QJson::IndentNone : |
||||||
|
default: |
||||||
|
values << serializedValue.trimmed(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull ) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]"; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentMinimum) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str = indent + "[\n" + join( values, ",\n" ) + "\n" + indent + "]"; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str = "[" + join( values, "," ) + "]"; |
||||||
|
} |
||||||
|
else { |
||||||
|
str = "[ " + join( values, ", " ) + " ]"; |
||||||
|
} |
||||||
|
|
||||||
|
} else if ( v.type() == QVariant::Map ) { // variant is a map?
|
||||||
|
const QVariantMap vmap = v.toMap(); |
||||||
|
QMapIterator<QString, QVariant> it( vmap ); |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentMinimum) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str = indent + "{ "; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
QByteArray nextindent = buildIndent(indentLevel + 1); |
||||||
|
str = indent + "{\n" + nextindent; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str = "{"; |
||||||
|
} |
||||||
|
else { |
||||||
|
str = "{ "; |
||||||
|
} |
||||||
|
|
||||||
|
QList<QByteArray> pairs; |
||||||
|
while ( it.hasNext() ) { |
||||||
|
it.next(); |
||||||
|
indentLevel++; |
||||||
|
QByteArray serializedValue = serialize( it.value(), ok, indentLevel); |
||||||
|
indentLevel--; |
||||||
|
if ( !*ok ) { |
||||||
|
break; |
||||||
|
} |
||||||
|
QByteArray key = sanitizeString( it.key() ).toUtf8(); |
||||||
|
QByteArray value = serializedValue.trimmed(); |
||||||
|
if (indentMode == QJson::IndentCompact) { |
||||||
|
pairs << key + ":" + value; |
||||||
|
} else { |
||||||
|
pairs << key + " : " + value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel + 1); |
||||||
|
str += join( pairs, ",\n" + indent); |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str += join( pairs, "," ); |
||||||
|
} |
||||||
|
else { |
||||||
|
str += join( pairs, ", " ); |
||||||
|
} |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str += "\n" + indent + "}"; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str += "}"; |
||||||
|
} |
||||||
|
else { |
||||||
|
str += " }"; |
||||||
|
} |
||||||
|
|
||||||
|
} else if ( v.type() == QVariant::Hash ) { // variant is a hash?
|
||||||
|
const QVariantHash vhash = v.toHash(); |
||||||
|
QHashIterator<QString, QVariant> it( vhash ); |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentMinimum) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str = indent + "{ "; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
QByteArray nextindent = buildIndent(indentLevel + 1); |
||||||
|
str = indent + "{\n" + nextindent; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str = "{"; |
||||||
|
} |
||||||
|
else { |
||||||
|
str = "{ "; |
||||||
|
} |
||||||
|
|
||||||
|
QList<QByteArray> pairs; |
||||||
|
while ( it.hasNext() ) { |
||||||
|
it.next(); |
||||||
|
|
||||||
|
QByteArray serializedValue = serialize( it.value(), ok, indentLevel + 1); |
||||||
|
|
||||||
|
if ( !*ok ) { |
||||||
|
break; |
||||||
|
} |
||||||
|
QByteArray key = sanitizeString( it.key() ).toUtf8(); |
||||||
|
QByteArray value = serializedValue.trimmed(); |
||||||
|
if (indentMode == QJson::IndentCompact) { |
||||||
|
pairs << key + ":" + value; |
||||||
|
} else { |
||||||
|
pairs << key + " : " + value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel + 1); |
||||||
|
str += join( pairs, ",\n" + indent); |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str += join( pairs, "," ); |
||||||
|
} |
||||||
|
else { |
||||||
|
str += join( pairs, ", " ); |
||||||
|
} |
||||||
|
|
||||||
|
if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) { |
||||||
|
QByteArray indent = buildIndent(indentLevel); |
||||||
|
str += "\n" + indent + "}"; |
||||||
|
} |
||||||
|
else if (indentMode == QJson::IndentCompact) { |
||||||
|
str += "}"; |
||||||
|
} |
||||||
|
else { |
||||||
|
str += " }"; |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
// Add indent, we may need to remove it later for some layouts
|
||||||
|
switch(indentMode) { |
||||||
|
case QJson::IndentFull : |
||||||
|
case QJson::IndentMedium : |
||||||
|
case QJson::IndentMinimum : |
||||||
|
str += buildIndent(indentLevel); |
||||||
|
break; |
||||||
|
case QJson::IndentCompact : |
||||||
|
case QJson::IndentNone : |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) { // a string or a byte array?
|
||||||
|
str = sanitizeString( v.toString() ).toUtf8(); |
||||||
|
} else if (( v.type() == QVariant::Double) || ((QMetaType::Type)v.type() == QMetaType::Float)) { // a double or a float?
|
||||||
|
const double value = v.toDouble(); |
||||||
|
#if defined _WIN32 && !defined(Q_OS_SYMBIAN) |
||||||
|
const bool special = _isnan(value) || !_finite(value); |
||||||
|
#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_SOLARIS) |
||||||
|
const bool special = isnan(value) || isinf(value); |
||||||
|
#else |
||||||
|
const bool special = std::isnan(value) || std::isinf(value); |
||||||
|
#endif |
||||||
|
if (special) { |
||||||
|
if (specialNumbersAllowed) { |
||||||
|
#if defined _WIN32 && !defined(Q_OS_SYMBIAN) |
||||||
|
if (_isnan(value)) { |
||||||
|
#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_SOLARIS) |
||||||
|
if (isnan(value)) { |
||||||
|
#else |
||||||
|
if (std::isnan(value)) { |
||||||
|
#endif |
||||||
|
str += "NaN"; |
||||||
|
} else { |
||||||
|
if (value<0) { |
||||||
|
str += '-'; |
||||||
|
} |
||||||
|
str += "Infinity"; |
||||||
|
} |
||||||
|
} else { |
||||||
|
errorMessage += QLatin1String("Attempt to write NaN or infinity, which is not supported by json\n"); |
||||||
|
*ok = false; |
||||||
|
} |
||||||
|
} else { |
||||||
|
str = QByteArray::number( value , 'g', doublePrecision); |
||||||
|
if( ! str.contains( "." ) && ! str.contains( "e" ) ) { |
||||||
|
str += ".0"; |
||||||
|
} |
||||||
|
} |
||||||
|
} else if ( v.type() == QVariant::Bool ) { // boolean value?
|
||||||
|
str += ( v.toBool() ? "true" : "false" ); |
||||||
|
} else if ( v.type() == QVariant::ULongLong ) { // large unsigned number?
|
||||||
|
str += QByteArray::number( v.value<qulonglong>() ); |
||||||
|
} else if ( v.type() == QVariant::UInt ) { // unsigned int number?
|
||||||
|
str += QByteArray::number( v.value<quint32>() ); |
||||||
|
} else if ( v.canConvert<qlonglong>() ) { // any signed number?
|
||||||
|
str += QByteArray::number( v.value<qlonglong>() ); |
||||||
|
} else if ( v.canConvert<int>() ) { // unsigned short number?
|
||||||
|
str += QByteArray::number( v.value<int>() ); |
||||||
|
} else if ( v.canConvert<QString>() ){ // can value be converted to string?
|
||||||
|
// this will catch QDate, QDateTime, QUrl, ...
|
||||||
|
str += sanitizeString( v.toString() ).toUtf8(); |
||||||
|
//TODO: catch other values like QImage, QRect, ...
|
||||||
|
} else { |
||||||
|
*ok = false; |
||||||
|
errorMessage += QLatin1String("Cannot serialize "); |
||||||
|
errorMessage += v.toString(); |
||||||
|
errorMessage += QLatin1String(" because type "); |
||||||
|
errorMessage += QLatin1String(v.typeName()); |
||||||
|
errorMessage += QLatin1String(" is not supported by QJson\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
if ( *ok ) |
||||||
|
{ |
||||||
|
return str; |
||||||
|
} |
||||||
|
else |
||||||
|
return QByteArray(); |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray Serializer::SerializerPrivate::buildIndent(int spaces) |
||||||
|
{ |
||||||
|
QByteArray indent; |
||||||
|
if (spaces < 0) { |
||||||
|
spaces = 0; |
||||||
|
} |
||||||
|
for (int i = 0; i < spaces; i++ ) { |
||||||
|
indent += " "; |
||||||
|
} |
||||||
|
return indent; |
||||||
|
} |
||||||
|
|
||||||
|
QString Serializer::SerializerPrivate::sanitizeString( QString str ) |
||||||
|
{ |
||||||
|
str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) ); |
||||||
|
|
||||||
|
// escape unicode chars
|
||||||
|
QString result; |
||||||
|
const ushort* unicode = str.utf16(); |
||||||
|
unsigned int i = 0; |
||||||
|
|
||||||
|
while ( unicode[ i ] ) { |
||||||
|
if ( unicode[ i ] < 128 ) { |
||||||
|
result.append( QChar( unicode[ i ] ) ); |
||||||
|
} |
||||||
|
else { |
||||||
|
QString hexCode = QString::number( unicode[ i ], 16 ).rightJustified( 4, |
||||||
|
QLatin1Char('0') ); |
||||||
|
|
||||||
|
result.append( QLatin1String ("\\u") ).append( hexCode ); |
||||||
|
} |
||||||
|
++i; |
||||||
|
} |
||||||
|
str = result; |
||||||
|
|
||||||
|
str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) ); |
||||||
|
str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) ); |
||||||
|
str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) ); |
||||||
|
str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) ); |
||||||
|
str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) ); |
||||||
|
str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) ); |
||||||
|
|
||||||
|
return QString( QLatin1String( "\"%1\"" ) ).arg( str ); |
||||||
|
} |
||||||
|
|
||||||
|
Serializer::Serializer() |
||||||
|
: d( new SerializerPrivate ) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
Serializer::~Serializer() { |
||||||
|
delete d; |
||||||
|
} |
||||||
|
|
||||||
|
void Serializer::serialize( const QVariant& v, QIODevice* io, bool* ok) |
||||||
|
{ |
||||||
|
Q_ASSERT( io ); |
||||||
|
*ok = true; |
||||||
|
|
||||||
|
if (!io->isOpen()) { |
||||||
|
if (!io->open(QIODevice::WriteOnly)) { |
||||||
|
d->errorMessage = QLatin1String("Error opening device"); |
||||||
|
*ok = false; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!io->isWritable()) { |
||||||
|
d->errorMessage = QLatin1String("Device is not readable"); |
||||||
|
io->close(); |
||||||
|
*ok = false; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
const QByteArray str = serialize( v, ok); |
||||||
|
if (*ok && (io->write(str) != str.count())) { |
||||||
|
*ok = false; |
||||||
|
d->errorMessage = QLatin1String("Something went wrong while writing to IO device"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray Serializer::serialize( const QVariant &v) |
||||||
|
{ |
||||||
|
bool ok; |
||||||
|
|
||||||
|
return serialize(v, &ok); |
||||||
|
} |
||||||
|
|
||||||
|
QByteArray Serializer::serialize( const QVariant &v, bool *ok) |
||||||
|
{ |
||||||
|
bool _ok = true; |
||||||
|
d->errorMessage.clear(); |
||||||
|
|
||||||
|
if (ok) { |
||||||
|
*ok = true; |
||||||
|
} else { |
||||||
|
ok = &_ok; |
||||||
|
} |
||||||
|
|
||||||
|
return d->serialize(v, ok); |
||||||
|
} |
||||||
|
|
||||||
|
void QJson::Serializer::allowSpecialNumbers(bool allow) { |
||||||
|
d->specialNumbersAllowed = allow; |
||||||
|
} |
||||||
|
|
||||||
|
bool QJson::Serializer::specialNumbersAllowed() const { |
||||||
|
return d->specialNumbersAllowed; |
||||||
|
} |
||||||
|
|
||||||
|
void QJson::Serializer::setIndentMode(IndentMode mode) { |
||||||
|
d->indentMode = mode; |
||||||
|
} |
||||||
|
|
||||||
|
void QJson::Serializer::setDoublePrecision(int precision) { |
||||||
|
d->doublePrecision = precision; |
||||||
|
} |
||||||
|
|
||||||
|
IndentMode QJson::Serializer::indentMode() const { |
||||||
|
return d->indentMode; |
||||||
|
} |
||||||
|
|
||||||
|
QString QJson::Serializer::errorMessage() const { |
||||||
|
return d->errorMessage; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,230 @@ |
|||||||
|
/* This file is part of qjson
|
||||||
|
* |
||||||
|
* Copyright (C) 2009 Till Adam <adam@kde.org> |
||||||
|
* |
||||||
|
* This library is free software; you can redistribute it and/or |
||||||
|
* modify it under the terms of the GNU Lesser General Public |
||||||
|
* License version 2.1, as published by the Free Software Foundation. |
||||||
|
* |
||||||
|
* |
||||||
|
* This library is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
* Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
||||||
|
* Boston, MA 02110-1301, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef QJSON_SERIALIZER_H |
||||||
|
#define QJSON_SERIALIZER_H |
||||||
|
|
||||||
|
#include "qjson_export.h" |
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE |
||||||
|
class QIODevice; |
||||||
|
class QString; |
||||||
|
class QVariant; |
||||||
|
QT_END_NAMESPACE |
||||||
|
|
||||||
|
namespace QJson { |
||||||
|
/**
|
||||||
|
@brief How the indentation should work. |
||||||
|
\verbatim |
||||||
|
none (default) : |
||||||
|
{ "foo" : 0, "foo1" : 1, "foo2" : [ { "bar" : 1, "foo" : 0, "foobar" : 0 }, { "bar" : 1, "foo" : 1, "foobar" : 1 } ], "foo3" : [ 1, 2, 3, 4, 5, 6 ] } |
||||||
|
|
||||||
|
compact : |
||||||
|
{"foo":0,"foo1":1,"foo2":[{"bar":1,"foo":0,"foobar":0},{"bar":1,"foo":1,"foobar":1}],"foo3":[1,2,3,4,5,6]} |
||||||
|
|
||||||
|
minimum : |
||||||
|
{ "foo" : 0, "foo1" : 1, "foo2" : [ |
||||||
|
{ "bar" : 1, "foo" : 0, "foobar" : 0 }, |
||||||
|
{ "bar" : 1, "foo" : 1, "foobar" : 1 } |
||||||
|
], "foo3" : [ |
||||||
|
1, |
||||||
|
2, |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6 |
||||||
|
] } |
||||||
|
|
||||||
|
medium : |
||||||
|
{ |
||||||
|
"foo" : 0, "foo1" : 1, "foo2" : [ |
||||||
|
{ |
||||||
|
"bar" : 1, "foo" : 0, "foobar" : 0 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"bar" : 1, "foo" : 1, "foobar" : 1 |
||||||
|
} |
||||||
|
], "foo3" : [ |
||||||
|
1, |
||||||
|
2, |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6 |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
full : |
||||||
|
{ |
||||||
|
"foo" : 0, |
||||||
|
"foo1" : 1, |
||||||
|
"foo2" : [ |
||||||
|
{ |
||||||
|
"bar" : 1, |
||||||
|
"foo" : 0, |
||||||
|
"foobar" : 0 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"bar" : 1, |
||||||
|
"foo" : 1, |
||||||
|
"foobar" : 1 |
||||||
|
} |
||||||
|
], |
||||||
|
"foo3" : [ |
||||||
|
1, |
||||||
|
2, |
||||||
|
3, |
||||||
|
4, |
||||||
|
5, |
||||||
|
6 |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
\endverbatim |
||||||
|
*/ |
||||||
|
enum IndentMode { |
||||||
|
IndentNone, |
||||||
|
IndentCompact, |
||||||
|
IndentMinimum, |
||||||
|
IndentMedium, |
||||||
|
IndentFull |
||||||
|
}; |
||||||
|
/**
|
||||||
|
* @brief Main class used to convert QVariant objects to JSON data. |
||||||
|
* |
||||||
|
* QVariant objects are converted to a string containing the JSON data. |
||||||
|
* |
||||||
|
* |
||||||
|
* Usage: |
||||||
|
* |
||||||
|
* \code |
||||||
|
* QVariantList people; |
||||||
|
* |
||||||
|
* QVariantMap bob; |
||||||
|
* bob.insert("Name", "Bob"); |
||||||
|
* bob.insert("Phonenumber", 123); |
||||||
|
* |
||||||
|
* QVariantMap alice; |
||||||
|
* alice.insert("Name", "Alice"); |
||||||
|
* alice.insert("Phonenumber", 321); |
||||||
|
* |
||||||
|
* people << bob << alice; |
||||||
|
* |
||||||
|
* QJson::Serializer serializer; |
||||||
|
* bool ok; |
||||||
|
* QByteArray json = serializer.serialize(people, &ok); |
||||||
|
* |
||||||
|
* if (ok) { |
||||||
|
* qDebug() << json; |
||||||
|
* } else { |
||||||
|
* qCritical() << "Something went wrong:" << serializer.errorMessage(); |
||||||
|
* } |
||||||
|
* \endcode |
||||||
|
* |
||||||
|
* The output will be: |
||||||
|
* |
||||||
|
* \code |
||||||
|
* "[ { "Name" : "Bob", "Phonenumber" : 123 }, |
||||||
|
* { "Name" : "Alice", "Phonenumber" : 321 } ]" |
||||||
|
* \endcode |
||||||
|
* |
||||||
|
* It's possible to tune the indentation level of the resulting string. \sa setIndentMode |
||||||
|
*/ |
||||||
|
class QJSON_EXPORT Serializer { |
||||||
|
public: |
||||||
|
Serializer(); |
||||||
|
~Serializer(); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a textual JSON representation and outputs it to the |
||||||
|
* passed in I/O Device. |
||||||
|
* @param variant The JSON document in its in-memory representation as generated by the |
||||||
|
* parser. |
||||||
|
* @param out Input output device |
||||||
|
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true |
||||||
|
*/ |
||||||
|
void serialize( const QVariant& variant, QIODevice* out, bool* ok); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a method provided for convenience. It turns the passed in in-memory |
||||||
|
* representation of the JSON document into a textual one, which is returned. |
||||||
|
* If the returned string is empty, the document was empty. If it was null, there |
||||||
|
* was a parsing error. |
||||||
|
* |
||||||
|
* @param variant The JSON document in its in-memory representation as generated by the |
||||||
|
* parser. |
||||||
|
* |
||||||
|
* \deprecated This method is going to be removed with the next major release of QJson. |
||||||
|
*/ |
||||||
|
QByteArray serialize( const QVariant& variant); |
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a method provided for convenience. It turns the passed in in-memory |
||||||
|
* representation of the JSON document into a textual one, which is returned. |
||||||
|
* If the returned string is empty, the document was empty. If it was null, there |
||||||
|
* was a parsing error. |
||||||
|
* |
||||||
|
* @param variant The JSON document in its in-memory representation as generated by the |
||||||
|
* parser. |
||||||
|
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true |
||||||
|
*/ |
||||||
|
QByteArray serialize( const QVariant& variant, bool *ok); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow or disallow writing of NaN and/or Infinity (as an extension to QJson) |
||||||
|
*/ |
||||||
|
void allowSpecialNumbers(bool allow); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Is Nan and/or Infinity allowed? |
||||||
|
*/ |
||||||
|
bool specialNumbersAllowed() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* set output indentation mode as defined in QJson::IndentMode |
||||||
|
*/ |
||||||
|
void setIndentMode(IndentMode mode = QJson::IndentNone); |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set double precision used while converting Double |
||||||
|
* \sa QByteArray::number |
||||||
|
*/ |
||||||
|
void setDoublePrecision(int precision); |
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns one of the indentation modes defined in QJson::IndentMode |
||||||
|
*/ |
||||||
|
IndentMode indentMode() const; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the error message |
||||||
|
*/ |
||||||
|
QString errorMessage() const; |
||||||
|
|
||||||
|
private: |
||||||
|
Q_DISABLE_COPY(Serializer) |
||||||
|
class SerializerPrivate; |
||||||
|
SerializerPrivate* const d; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
#endif // QJSON_SERIALIZER_H
|
@ -0,0 +1,133 @@ |
|||||||
|
/* A Bison parser, made by GNU Bison 2.7. */ |
||||||
|
|
||||||
|
/* Stack handling for Bison parsers in C++
|
||||||
|
|
||||||
|
Copyright (C) 2002-2012 Free Software Foundation, Inc. |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License |
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work |
||||||
|
under terms of your choice, so long as that work isn't itself a |
||||||
|
parser generator using the skeleton or a modified version thereof |
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute |
||||||
|
the parser skeleton itself, you may (at your option) remove this |
||||||
|
special exception, which will cause the skeleton and the resulting |
||||||
|
Bison output files to be licensed under the GNU General Public |
||||||
|
License without this special exception. |
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in |
||||||
|
version 2.2 of Bison. */ |
||||||
|
|
||||||
|
/**
|
||||||
|
** \file stack.hh |
||||||
|
** Define the yy::stack class. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef YY_YY_STACK_HH_INCLUDED |
||||||
|
# define YY_YY_STACK_HH_INCLUDED |
||||||
|
|
||||||
|
# include <deque> |
||||||
|
|
||||||
|
|
||||||
|
namespace yy { |
||||||
|
/* Line 34 of stack.hh */ |
||||||
|
#line 47 "stack.hh" |
||||||
|
template <class T, class S = std::deque<T> > |
||||||
|
class stack |
||||||
|
{ |
||||||
|
public: |
||||||
|
// Hide our reversed order.
|
||||||
|
typedef typename S::reverse_iterator iterator; |
||||||
|
typedef typename S::const_reverse_iterator const_iterator; |
||||||
|
|
||||||
|
stack () : seq_ () |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
stack (unsigned int n) : seq_ (n) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
T& |
||||||
|
operator [] (unsigned int i) |
||||||
|
{ |
||||||
|
return seq_[i]; |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
const T& |
||||||
|
operator [] (unsigned int i) const |
||||||
|
{ |
||||||
|
return seq_[i]; |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
void |
||||||
|
push (const T& t) |
||||||
|
{ |
||||||
|
seq_.push_front (t); |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
void |
||||||
|
pop (unsigned int n = 1) |
||||||
|
{ |
||||||
|
for (; n; --n) |
||||||
|
seq_.pop_front (); |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
unsigned int |
||||||
|
height () const |
||||||
|
{ |
||||||
|
return seq_.size (); |
||||||
|
} |
||||||
|
|
||||||
|
inline const_iterator begin () const { return seq_.rbegin (); } |
||||||
|
inline const_iterator end () const { return seq_.rend (); } |
||||||
|
|
||||||
|
private: |
||||||
|
S seq_; |
||||||
|
}; |
||||||
|
|
||||||
|
/// Present a slice of the top of a stack.
|
||||||
|
template <class T, class S = stack<T> > |
||||||
|
class slice |
||||||
|
{ |
||||||
|
public: |
||||||
|
slice (const S& stack, unsigned int range) |
||||||
|
: stack_ (stack) |
||||||
|
, range_ (range) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
inline |
||||||
|
const T& |
||||||
|
operator [] (unsigned int i) const |
||||||
|
{ |
||||||
|
return stack_[range_ - i]; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
const S& stack_; |
||||||
|
unsigned int range_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // yy
|
||||||
|
/* Line 116 of stack.hh */ |
||||||
|
#line 132 "stack.hh" |
||||||
|
|
||||||
|
#endif /* !YY_YY_STACK_HH_INCLUDED */ |
Loading…
Reference in new issue