[DEV/DOC/DEBUG] add basic sample and basic documentation and corect some parsing bug...
This commit is contained in:
parent
cad8aaaa6d
commit
f756cfd131
@ -1,67 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# Declare the project
|
||||
project(ejson)
|
||||
|
||||
##
|
||||
## Include C++ X11 dependency ... (check correct flags)
|
||||
##
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
|
||||
if(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
else()
|
||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# set output path:
|
||||
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
|
||||
|
||||
include_directories(.)
|
||||
|
||||
#Create src file list
|
||||
set(src_files
|
||||
ejson/debug.cpp
|
||||
ejson/debug.h
|
||||
ejson/ejson.cpp
|
||||
ejson/ejson.h
|
||||
ejson/Array.cpp
|
||||
ejson/Array.h
|
||||
ejson/Boolean.cpp
|
||||
ejson/Boolean.h
|
||||
ejson/Null.cpp
|
||||
ejson/Null.h
|
||||
ejson/Number.cpp
|
||||
ejson/Number.h
|
||||
ejson/String.cpp
|
||||
ejson/String.h
|
||||
ejson/Object.cpp
|
||||
ejson/Object.h
|
||||
ejson/Value.cpp
|
||||
ejson/Value.h
|
||||
)
|
||||
|
||||
add_definitions( -DDEBUG_LEVEL=3 )
|
||||
add_definitions( -DDEBUG=1 )
|
||||
if (APPLE)
|
||||
add_definitions( -D__TARGET_OS__MacOs )
|
||||
elseif (UNIX)
|
||||
add_definitions( -D__TARGET_OS__Linux )
|
||||
elseif (WIN32)
|
||||
add_definitions( -D__TARGET_OS__Windows )
|
||||
endif ()
|
||||
|
||||
|
||||
include_directories(${etk_SOURCE_DIR})
|
||||
include_directories(${linearmath_SOURCE_DIR}/bullet/src/)
|
||||
|
||||
#Create a static Lib:
|
||||
add_library(ejson STATIC ${src_files} )
|
||||
target_link_libraries(ejson etk)
|
||||
|
@ -1,79 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(ejson)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
## is used, also find other catkin packages
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
etk
|
||||
)
|
||||
|
||||
|
||||
###################################
|
||||
## catkin specific configuration ##
|
||||
###################################
|
||||
## The catkin_package macro generates cmake config files for your package
|
||||
## Declare things to be passed to dependent projects
|
||||
## INCLUDE_DIRS: uncomment this if you package contains header files
|
||||
## LIBRARIES: libraries you create in this project that dependent projects also need
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
INCLUDE_DIRS ../
|
||||
LIBRARIES ${PROJECT_NAME}
|
||||
CATKIN_DEPENDS etk
|
||||
DEPENDS system_lib
|
||||
)
|
||||
|
||||
###########
|
||||
## Build ##
|
||||
###########
|
||||
|
||||
## Specify additional locations of header files
|
||||
## Your package locations should be listed before other locations
|
||||
include_directories(
|
||||
..
|
||||
${catkin_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
## Declare a cpp library
|
||||
add_library(${PROJECT_NAME}
|
||||
../${PROJECT_NAME}/debug.cpp
|
||||
../${PROJECT_NAME}/ejson.cpp
|
||||
../${PROJECT_NAME}/Array.cpp
|
||||
../${PROJECT_NAME}/Boolean.cpp
|
||||
../${PROJECT_NAME}/Null.cpp
|
||||
../${PROJECT_NAME}/Number.cpp
|
||||
../${PROJECT_NAME}/String.cpp
|
||||
../${PROJECT_NAME}/Object.cpp
|
||||
../${PROJECT_NAME}/Value.cpp
|
||||
)
|
||||
|
||||
|
||||
## Add cmake target dependencies of the executable/library
|
||||
## as an example, message headers may need to be generated before nodes
|
||||
#add_dependencies(${PROJECT_NAME} test_perfo_core_generate_messages_cpp)
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
${catkin_LIBRARIES}
|
||||
)
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
#############
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
)
|
||||
|
||||
## Mark cpp header files for installation
|
||||
install(DIRECTORY ../${PROJECT_NAME}/
|
||||
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>ejson</name>
|
||||
<version>0.3.0</version>
|
||||
<description>Ewol Json file reader</description>
|
||||
<maintainer email="yui.heero@gmail.com">Edouard DUPIN</maintainer>
|
||||
<license>Apache-2.0</license>
|
||||
<build_depend>etk</build_depend>
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
<run_depend>etk</run_depend>
|
||||
</package>
|
66
doc/build.md
Normal file
66
doc/build.md
Normal file
@ -0,0 +1,66 @@
|
||||
Build lib & build sample {#ejson_build}
|
||||
========================
|
||||
|
||||
@tableofcontents
|
||||
|
||||
Download: {#ejson_build_download}
|
||||
=========
|
||||
|
||||
ejson use some tools to manage source and build it:
|
||||
|
||||
lutin (build-system): {#ejson_build_download_lutin}
|
||||
---------------------
|
||||
|
||||
```{.sh}
|
||||
pip install lutin --user
|
||||
# optionnal dependency of lutin (manage image changing size for application release)
|
||||
pip install pillow --user
|
||||
```
|
||||
|
||||
|
||||
dependency: {#ejson_build_download_dependency}
|
||||
-----------
|
||||
|
||||
```{.sh}
|
||||
mkdir framework
|
||||
cd framework
|
||||
git clone https://github.com/atria-soft/elog.git
|
||||
git clone https://github.com/atria-soft/etk.git
|
||||
git clone https://github.com/atria-soft/ememory.git
|
||||
cd ..
|
||||
```
|
||||
|
||||
sources: {#ejson_build_download_sources}
|
||||
--------
|
||||
|
||||
```{.sh}
|
||||
cd framework
|
||||
git clone https://github.com/atria-soft/ejson.git
|
||||
cd ..
|
||||
```
|
||||
|
||||
Build: {#ejson_build_build}
|
||||
======
|
||||
|
||||
|
||||
library: {#ejson_build_build_library}
|
||||
--------
|
||||
|
||||
```{.sh}
|
||||
lutin -mdebug ejson
|
||||
```
|
||||
|
||||
Sample: {#ejson_build_build_sample}
|
||||
-------
|
||||
|
||||
```{.sh}
|
||||
lutin -mdebug ejson-sample
|
||||
```
|
||||
|
||||
|
||||
Run sample: {#ejson_build_run_sample}
|
||||
===========
|
||||
|
||||
```{.sh}
|
||||
lutin -mdebug ejson-sample?run
|
||||
```
|
32
doc/index.bb
32
doc/index.bb
@ -1,32 +0,0 @@
|
||||
== [center]E-json library[/center] ==
|
||||
__________________________________________________
|
||||
|
||||
===What is EJSON, and how can I use it?===
|
||||
EJSON, or Ewol json file interface, is a multi-platform library for creating and reading json file.
|
||||
|
||||
===What languages are supported?===
|
||||
EJSON is written in C++.
|
||||
|
||||
===Are there any licensing restrictions?===
|
||||
EJSON is [b]FREE software[/b].
|
||||
|
||||
That allow you to use it for every program you want, including those developing proprietary software, without any license fees or royalties.
|
||||
|
||||
|
||||
==== License (DSB) ====
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
:** Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
:** 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.
|
||||
:** The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==== Tutorials : ====
|
||||
|
||||
:** [tutorial[000_Build | Build example]]
|
||||
:** [tutorial[001_Read | Read a json file]]
|
||||
:** [tutorial[002_Write | Write a json file]]
|
||||
|
81
doc/mainpage.md
Normal file
81
doc/mainpage.md
Normal file
@ -0,0 +1,81 @@
|
||||
EJSON library {#mainpage}
|
||||
=============
|
||||
|
||||
@tableofcontents
|
||||
|
||||
What is EJSON: {#ejson_mainpage_what}
|
||||
==============
|
||||
|
||||
EJSON, or Ewol JSON interface is a simple, small, efficient, C++ JSON parser/generator that can be easily integrating into other programs.
|
||||
|
||||
What it does: {#ejson_mainpage_what_it_does}
|
||||
-------------
|
||||
|
||||
EJSON parses an JSON document, and builds from that a Document Object Model (DOM) that can be read, modified, and saved.
|
||||
|
||||
JSON stands for "JavaScript Object Notation". It is a general purpose human and machine readable machine language to describe arbitrary data (base internal system of the JavaScript object).
|
||||
All those random file formats created to store application data can all be replaced with JSON. One parser for everything.
|
||||
|
||||
http://wikipedia.org/wiki/JSON
|
||||
|
||||
There are different ways to access and interact with JSON data.
|
||||
EJSON uses a Document Object Model (DOM), meaning the JSON data is parsed into a C++ objects that can be browsed and manipulated, and then written to disk.
|
||||
You can also construct an JSON document from scratch with C++ objects and write this to disk.
|
||||
|
||||
EJSON is designed to be easy and fast to learn.
|
||||
|
||||
EJSON is dependent of the STL (compatible with MacOs stl (CXX))
|
||||
|
||||
What it doesn't do: {#ejson_mainpage_what_it_not_does}
|
||||
-------------------
|
||||
|
||||
I do not know...
|
||||
|
||||
Internal extention: {#ejson_mainpage_extention}
|
||||
-------------------
|
||||
|
||||
I Add some costum feature of JSON:
|
||||
- Support inline comment starting with **#**
|
||||
- Support Unquotet name if the name is not separate with space and not start with number
|
||||
- Support simple quote **'** instead of double quote **"**
|
||||
- Support removing of the **{}** arround the file (by default present)
|
||||
|
||||
|
||||
What languages are supported? {#ejson_mainpage_language}
|
||||
=============================
|
||||
|
||||
EJSON is written in C++.
|
||||
|
||||
|
||||
Are there any licensing restrictions? {#ejson_mainpage_license_restriction}
|
||||
=====================================
|
||||
|
||||
EJSON is **FREE software** and _all sub-library are FREE and staticly linkable !!!_
|
||||
|
||||
|
||||
License (APACHE-2.0) {#ejson_mainpage_license}
|
||||
====================
|
||||
|
||||
Copyright EJSON Edouard DUPIN
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
<http://www.apache.org/licenses/LICENSE-2.0>
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Other pages {#ejson_mainpage_sub_page}
|
||||
===========
|
||||
|
||||
- @ref ejson_build
|
||||
- @ref ejson_tutorial_read
|
||||
- @ref ejson_tutorial_write
|
||||
- [**ewol coding style**](http://atria-soft.github.io/ewol/ewol_coding_style.html)
|
||||
|
121
doc/read.md
Normal file
121
doc/read.md
Normal file
@ -0,0 +1,121 @@
|
||||
Read an JSON content {#ejson_tutorial_read}
|
||||
===================
|
||||
|
||||
@tableofcontents
|
||||
|
||||
The first thing to do when reading or writing a JSON file/stream, is to declare the Document interface
|
||||
|
||||
Include ejson
|
||||
@snippet read.cpp ejson_sample_include
|
||||
|
||||
Declare document interface
|
||||
@snippet read.cpp ejson_sample_declare_doc
|
||||
|
||||
|
||||
Read an JSON file {#ejson_tutorial_read_file}
|
||||
================
|
||||
|
||||
File to read: "read.json"
|
||||
@include read.json
|
||||
|
||||
Reading a file is done like this:
|
||||
@snippet read.cpp ejson_sample_read_file
|
||||
|
||||
The file naming is manage by @ref etk::FSNode that provide "DATA:" start string for internal application asset. You can use external path like "./plop/file.json" too.
|
||||
|
||||
|
||||
Read an JSON Stream {#ejson_tutorial_read_stream}
|
||||
==================
|
||||
|
||||
Reading a stream is done like this:
|
||||
@snippet read.cpp ejson_sample_read_stream1
|
||||
|
||||
In C and C++ it is very hard to read string with the \\" then to simplify parsing of json the parser engine support the use of simple **'** interface:
|
||||
@snippet read.cpp ejson_sample_read_stream2
|
||||
|
||||
|
||||
Access at all Element datas {#ejson_tutorial_read_folow}
|
||||
===========================
|
||||
|
||||
In an ejson::Object (or ejson::Document) the sub-nodes are accessible threw an abstraction class stores in an element name **Value**
|
||||
|
||||
Get a value with its name:
|
||||
@snippet read.cpp ejson_sample_read_get_element
|
||||
|
||||
Access to a string in an Object:
|
||||
-------------------------------
|
||||
|
||||
The generic Way to access to an element is to convert it in the corect type:
|
||||
@snippet read.cpp ejson_sample_read_convert_string
|
||||
|
||||
And after Get the Value:
|
||||
@snippet read.cpp ejson_sample_read_get_string_value
|
||||
|
||||
Commonly you might use like this:
|
||||
@snippet read.cpp ejson_sample_read_get_string_1
|
||||
|
||||
Helper function:
|
||||
@snippet read.cpp ejson_sample_read_get_string_2
|
||||
|
||||
|
||||
|
||||
Access to a boolean in an Object:
|
||||
---------------------------------
|
||||
|
||||
@snippet read.cpp ejson_sample_read_get_boolean_1
|
||||
|
||||
Helper function:
|
||||
@snippet read.cpp ejson_sample_read_get_boolean_2
|
||||
|
||||
|
||||
Access to a Number in an Object:
|
||||
---------------------------------
|
||||
|
||||
@snippet read.cpp ejson_sample_read_get_number_1
|
||||
|
||||
Helper function:
|
||||
@snippet read.cpp ejson_sample_read_get_number_2
|
||||
|
||||
|
||||
Access to a Array in an Object:
|
||||
---------------------------------
|
||||
|
||||
Get the Array
|
||||
@snippet read.cpp ejson_sample_read_get_array
|
||||
|
||||
Move threw all element:
|
||||
@snippet read.cpp ejson_sample_read_move_threw_array
|
||||
|
||||
Move threw all element in C mode:
|
||||
@snippet read.cpp ejson_sample_read_move_threw_array_c
|
||||
|
||||
|
||||
Access to a Object in an Object:
|
||||
---------------------------------
|
||||
|
||||
Get the Object
|
||||
@snippet read.cpp ejson_sample_read_get_object
|
||||
|
||||
Move threw all element:
|
||||
@snippet read.cpp ejson_sample_read_move_threw_object
|
||||
|
||||
Move threw all element in C mode:
|
||||
@snippet read.cpp ejson_sample_read_move_threw_object_c
|
||||
|
||||
|
||||
Now we can copy the Object we want
|
||||
==================================
|
||||
|
||||
ejson manage reference object, then it is possible that 2 part of the software access at the same object/element ...
|
||||
|
||||
You can copy object to separate or duplicate section.
|
||||
|
||||
This is named cloning:
|
||||
@snippet read.cpp ejson_sample_read_clone
|
||||
|
||||
|
||||
All example file {#ejson_tutorial_read_all}
|
||||
================
|
||||
|
||||
@snippet read.cpp ejson_sample_read_all
|
||||
|
@ -1,41 +0,0 @@
|
||||
=?=E-json extract and build examples=?=
|
||||
__________________________________________________
|
||||
[right][tutorial[001_Read | Next: Read a file]][/right]
|
||||
|
||||
All developpement software will start by getting the dependency and the sources.
|
||||
|
||||
=== Linux dependency packages ===
|
||||
[code style=shell]
|
||||
sudo apt-get install g++ zlib1g-dev
|
||||
# if you want to compile with clang :
|
||||
sudo apt-get install clang
|
||||
[/code]
|
||||
|
||||
=== Download instructions ===
|
||||
|
||||
Download the software :
|
||||
[code style=shell]
|
||||
# create a working directory path
|
||||
mkdir your_workspace_path
|
||||
cd your_workspace_path
|
||||
# clone ewol and all sub-library
|
||||
git clone http://github.com/HeeroYui/ewol.git
|
||||
cd ewol
|
||||
git submodule init
|
||||
git submodule update
|
||||
cd ..
|
||||
# download examples
|
||||
git clone http://github.com/HeeroYui/example.git
|
||||
[/code]
|
||||
|
||||
[note]
|
||||
The full build tool documentation is availlable here : [[http://heeroyui.github.io/lutin/ | lutin]]
|
||||
[/note]
|
||||
|
||||
=== Common build instructions ===
|
||||
|
||||
Compile software in debug for the curent platform :
|
||||
[code style=shell]
|
||||
./ewol/build/lutin.py -mdebug ejson*
|
||||
[/code]
|
||||
|
@ -1,282 +0,0 @@
|
||||
=?=Read a json file=?=
|
||||
__________________________________________________
|
||||
[left][tutorial[000_Build | Previous: Build example]][/left] [right][tutorial[002_Write | Next: Write a file]][/right]
|
||||
|
||||
|
||||
A json file is like a xml, but in a simplest way.
|
||||
It is in the minimum constituated of:
|
||||
[code style=json]
|
||||
{}
|
||||
[/code]
|
||||
This is the simplest json code.
|
||||
|
||||
for example we will use the next json file :
|
||||
[code style=json]
|
||||
{
|
||||
"element1":25622.53,
|
||||
"element2":"a string...",
|
||||
"is active":false,
|
||||
"NULL element":null,
|
||||
"exampleObject":{
|
||||
"a string":"my super example of string",
|
||||
"a null element":null,
|
||||
"an array element":[
|
||||
12, 25, 65, 654
|
||||
],
|
||||
"a boolean Element":true,
|
||||
"a simple sumber"=156156.343,
|
||||
"an other object":{
|
||||
"plop": 1,
|
||||
"plop2": 2
|
||||
}
|
||||
},
|
||||
"exampleArray":[
|
||||
12,
|
||||
25,
|
||||
65,
|
||||
654,
|
||||
{
|
||||
"plup": true,
|
||||
"plup2": false
|
||||
},
|
||||
true,
|
||||
null,
|
||||
[ 22, 23, 24, 25]
|
||||
}
|
||||
}
|
||||
[/code]
|
||||
|
||||
|
||||
|
||||
== Open the file ==
|
||||
|
||||
The first step to open a file is to create the json document:
|
||||
|
||||
[code style=c++]
|
||||
#include <ejson/ejson.h>
|
||||
|
||||
int main() {
|
||||
// declare document
|
||||
ejson::Document doc;
|
||||
...
|
||||
}
|
||||
[/code]
|
||||
|
||||
=== Load a stored file ===
|
||||
|
||||
It is important to remember that the input file is manage by etk,
|
||||
then the naming form is describe by the class: [class[etk::FSNode]]
|
||||
|
||||
[code style=c++]
|
||||
// read file
|
||||
if (doc.load("DATA:example.json") == false) {
|
||||
APPL_ERROR("An error occured when reading the file...");
|
||||
// TODO : STANDARDIZE ERROR....
|
||||
return -1;
|
||||
}
|
||||
[/code]
|
||||
|
||||
=== Load a file stored in memory ===
|
||||
|
||||
This step is easyest has a reading in a file.
|
||||
|
||||
In the first step, declare a string containing the json description:
|
||||
[code style=c++]
|
||||
std:string myJson = "{ \"element1\":25622.53, \"element2\":\"a string...\" }";
|
||||
[/code]
|
||||
|
||||
Now we just need to load the string:
|
||||
[code style=c++]
|
||||
if (doc.parse(myJson) == false) {
|
||||
APPL_ERROR("An error occured when parsing the string");
|
||||
return -1;
|
||||
}
|
||||
[/code]
|
||||
|
||||
it could be interesting to add some \n in the string to find some error in the json string
|
||||
|
||||
== Access on the data ==
|
||||
|
||||
now we have the data stored in the doc instance, it could be interesting to access on it.
|
||||
|
||||
Despite of XML interface that is not designed to be keep in memory but just parsed and drop,
|
||||
the json element is many time use as a simple interface to acces on the data.
|
||||
|
||||
This is the reason for this json interfce is designed for simple acces and use.
|
||||
|
||||
=== The simple way ===
|
||||
|
||||
Read a number value in the doc:
|
||||
[code style=c++]
|
||||
double myValue = doc.getNumberValue("element1", 49);
|
||||
APPL_INFO("Get the element value:" << myValue);
|
||||
[/code]
|
||||
Note that we had a return value, in case of the element is not present or in the wrong form.
|
||||
|
||||
We have the same interface for boolean, string and number:
|
||||
:** [methode[ejson::Object::getNumberValue]]
|
||||
:** [methode[ejson::Object::getStringValue]]
|
||||
:** [methode[ejson::Object::getBooleanValue]]
|
||||
|
||||
These interface methode are availlable for [class[ejson::Document]], [class[ejson::Object]].
|
||||
The similar interface are availlable on [class[ejson:Array]]:
|
||||
:** [methode[ejson::Array::getNumberValue]]
|
||||
:** [methode[ejson::Array::getStringValue]]
|
||||
:** [methode[ejson::Array::getBooleanValue]]
|
||||
|
||||
It could be interesting to remember that the maain node of a json file in an object,
|
||||
this is the reason that [class[ejson::Document]] herited of [class[ejson::Object]].
|
||||
|
||||
=== The generic way ===
|
||||
|
||||
The classical way to read a json file is to parse it like a xml:
|
||||
|
||||
==== Object ====
|
||||
We are now reading all node in an object:
|
||||
[code style=c++]
|
||||
std::shared_ptr<ejson::Object> obj = doc.getObject("exampleObject");
|
||||
// note that the obj is NULL if it not an "Object"
|
||||
if (obj == nullptr) {
|
||||
APPL_ERROR("Can not get the object 'exampleObject' in the json file");
|
||||
return -1;
|
||||
}
|
||||
[/code]
|
||||
Note at this point we can parse an object in 2 way:
|
||||
|
||||
1: The fastest but not the best:
|
||||
[code style=c++]
|
||||
for (size_t iii=0; iii < obj->size(); ++iii) {
|
||||
std::string key = obj->getKey(iii);
|
||||
std::shared_ptr<ejson::Value> val = obj[iii];
|
||||
// note that error can appear, then check result...
|
||||
if (val == nullptr) {
|
||||
APPL_ERROR("Can not read the object id=" << iii);
|
||||
continue;
|
||||
}
|
||||
switch(val->getType()) {
|
||||
case typeArray: {
|
||||
std::shared_ptr<ejson::Array> myArray = val->toArray();
|
||||
APPL_INFO("Find an Array @" << key);
|
||||
} break;
|
||||
case typeString: {
|
||||
std::shared_ptr<ejson::String> myString = val->toString();
|
||||
APPL_INFO("Find a String @" << key << " value='" << myString->get() << "'");
|
||||
} break;
|
||||
case typeNumber: {
|
||||
std::shared_ptr<ejson::Number> myNumber = val->toNumber();
|
||||
APPL_INFO("Find a Number @" << key << " value='" << myNumber->get() << "'");
|
||||
} break;
|
||||
case typeBoolean: {
|
||||
std::shared_ptr<ejson::Boolean> myBoolean = val->toBoolean();
|
||||
APPL_INFO("Find a Boolean @" << key << " value='" << myBoolean->get() << "'");
|
||||
} break;
|
||||
case typeNull:
|
||||
APPL_INFO("Find a null @" << key);
|
||||
break;
|
||||
case typeObject: {
|
||||
std::shared_ptr<ejson::Object> myObject = val->toObject();
|
||||
APPL_INFO("Find an Object @" << key);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
[/code]
|
||||
|
||||
2: A more generic way to acces on the elemnts:
|
||||
[code style=c++]
|
||||
stk::vector<std::string> keys = obj->getKeys();
|
||||
for (auto key in keys) {
|
||||
std::shared_ptr<ejson::Value> val = obj[key];
|
||||
// note that error can appear, then check result...
|
||||
if (val == nullptr) {
|
||||
APPL_ERROR("Can not read the object key=" << key);
|
||||
continue;
|
||||
}
|
||||
switch(val->getType()) {
|
||||
case typeArray: {
|
||||
std::shared_ptr<ejson::Array> myArray = val->toArray();
|
||||
APPL_INFO("Find an Array @" << key);
|
||||
} break;
|
||||
case typeString: {
|
||||
std::shared_ptr<ejson::String> myString = val->toString();
|
||||
APPL_INFO("Find a String @" << key << " value='" << myString->get() << "'");
|
||||
} break;
|
||||
case typeNumber: {
|
||||
std::shared_ptr<ejson::Number> myNumber = val->toNumber();
|
||||
APPL_INFO("Find a Number @" << key << " value='" << myNumber->get() << "'");
|
||||
} break;
|
||||
case typeBoolean: {
|
||||
std::shared_ptr<ejson::Boolean> myBoolean = val->toBoolean();
|
||||
APPL_INFO("Find a Boolean @" << key << " value='" << myBoolean->get() << "'");
|
||||
} break;
|
||||
case typeNull:
|
||||
APPL_INFO("Find a null @" << key);
|
||||
break;
|
||||
case typeObject: {
|
||||
std::shared_ptr<ejson::Object> myObject = val->toObject();
|
||||
APPL_INFO("Find an Object @" << key);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
[/code]
|
||||
|
||||
==== Array ====
|
||||
|
||||
We are now reading all node in an Array:
|
||||
[code style=c++]
|
||||
std::shared_ptr<ejson::Array> obj = doc.getArray("exampleArray");
|
||||
// note that the obj is nullptr if it not an "Array"
|
||||
if (obj == nullptr) {
|
||||
APPL_ERROR("Can not get the array 'exampleArray' in the json file");
|
||||
return -1;
|
||||
}
|
||||
[/code]
|
||||
|
||||
Note for an array we have only one methode to parse the data :
|
||||
|
||||
[code style=c++]
|
||||
for (size_t iii=0; iii < obj->size(); ++iii) {
|
||||
std::shared_ptr<ejson::Value> val = obj[iii];
|
||||
// or std::shared_ptr<ejson::Value> val = obj->get(iii);
|
||||
// note that error can appear, then check result...
|
||||
if (val == nullptr) {
|
||||
APPL_ERROR("Can not read the object id=" << iii);
|
||||
continue;
|
||||
}
|
||||
switch(val->getType()) {
|
||||
case typeArray: {
|
||||
std::shared_ptr<ejson::Array> myArray = val->toArray();
|
||||
APPL_INFO("Find an Array @" << key);
|
||||
} break;
|
||||
case typeString: {
|
||||
std::shared_ptr<ejson::String> myString = val->toString();
|
||||
APPL_INFO("Find a String @" << key << " value='" << myString->get() << "'");
|
||||
} break;
|
||||
case typeNumber: {
|
||||
std::shared_ptr<ejson::Number> myNumber = val->toNumber();
|
||||
APPL_INFO("Find a Number @" << key << " value='" << myNumber->get() << "'");
|
||||
} break;
|
||||
case typeBoolean: {
|
||||
std::shared_ptr<ejson::Boolean> myBoolean = val->toBoolean();
|
||||
APPL_INFO("Find a Boolean @" << key << " value='" << myBoolean->get() << "'");
|
||||
} break;
|
||||
case typeNull:
|
||||
APPL_INFO("Find a null @" << key);
|
||||
break;
|
||||
case typeObject: {
|
||||
std::shared_ptr<ejson::Object> myObject = val->toObject();
|
||||
APPL_INFO("Find an Object @" << key);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
[/code]
|
||||
|
||||
|
||||
It is important to note that many time the user know what type will appear in a list or in an object , then you can directly use:
|
||||
:** [methode[ejson::Array::getNumber]]
|
||||
:** [methode[ejson::Array::getNull]]
|
||||
:** [methode[ejson::Array::getArray]]
|
||||
:** [methode[ejson::Array::getObject]]
|
||||
:** [methode[ejson::Array::getBoolean]]
|
||||
:** [methode[ejson::Array::getstring]]
|
||||
These fuction automatly cast the result in the good form (if it is the real one)
|
||||
|
@ -1,3 +0,0 @@
|
||||
=?=Write a json file=?=
|
||||
__________________________________________________
|
||||
[left][tutorial[001_Read | Previous: Read a file]][/left]
|
61
doc/write.md
Normal file
61
doc/write.md
Normal file
@ -0,0 +1,61 @@
|
||||
Write an JSON content {#ejson_tutorial_write}
|
||||
====================
|
||||
|
||||
@tableofcontents
|
||||
|
||||
The first thing to do when reading or writing a JSON file/stream, is to declare the Document interface
|
||||
|
||||
Include ejson
|
||||
@snippet read.cpp ejson_sample_include
|
||||
|
||||
Declare document interface
|
||||
@snippet read.cpp ejson_sample_declare_doc
|
||||
|
||||
|
||||
Write an JSON file {#ejson_tutorial_write_file}
|
||||
=================
|
||||
|
||||
Write an json tree is done like:
|
||||
@snippet write.cpp ejson_sample_write_file
|
||||
|
||||
|
||||
Write an JSON Stream {#ejson_tutorial_write_stream}
|
||||
===================
|
||||
|
||||
Writing a stream is done like this:
|
||||
@snippet write.cpp ejson_sample_write_stream
|
||||
|
||||
Operation on Tree {#ejson_tutorial_write_operation}
|
||||
=================
|
||||
|
||||
Add Node/Declaration:
|
||||
@snippet write.cpp ejson_sample_write_add_declaration
|
||||
|
||||
Add an Node/Element:
|
||||
@snippet write.cpp ejson_sample_write_add_element
|
||||
|
||||
Remove a Node/Element:
|
||||
@snippet write.cpp ejson_sample_write_rm_node
|
||||
|
||||
|
||||
Add an attribute (simple version):
|
||||
@snippet write.cpp ejson_sample_write_add_attribute_simple
|
||||
|
||||
Add an attribute (complex version):
|
||||
@snippet write.cpp ejson_sample_write_add_attribute_complex
|
||||
|
||||
Remove an attribute:
|
||||
@snippet write.cpp ejson_sample_write_rm_attribute
|
||||
|
||||
Object concept {#ejson_tutorial_concept}
|
||||
==============
|
||||
|
||||
the ejson concept is to abstract the implementation of the internal system. All the element are maped on shared memory.
|
||||
Then if you asign an element to an other, it is the same. You need to clone it if you want to have new standalone element.
|
||||
|
||||
|
||||
All example file {#ejson_tutorial_write_all}
|
||||
================
|
||||
|
||||
@snippet write.cpp ejson_sample_write_all
|
||||
|
@ -14,6 +14,9 @@ def create(target, module_name):
|
||||
module_name,
|
||||
"doc"
|
||||
])
|
||||
my_module.add_sample_path([
|
||||
"sample"
|
||||
])
|
||||
my_module.add_module_depend([
|
||||
'elog',
|
||||
'etk',
|
||||
|
@ -160,4 +160,10 @@ const ejson::Array::iterator ejson::Array::end() const {
|
||||
#include <ejson/details/iterator.hxx>
|
||||
|
||||
template class ejson::iterator<ejson::Array>;
|
||||
|
||||
// Not implemented ==> force link error ...
|
||||
/*
|
||||
template<>
|
||||
std::string ejson::iterator<ejson::Array>::getKey() {
|
||||
return m_data.getKey(m_id);
|
||||
}
|
||||
*/
|
@ -105,10 +105,26 @@ namespace ejson {
|
||||
*/
|
||||
bool addNumber(double _value);
|
||||
public:
|
||||
using iterator = ejson::iterator<ejson::Array>;
|
||||
using iterator = ejson::iterator<ejson::Array>; //!< Specify iterator of the Array methode
|
||||
/**
|
||||
* @brief Get iterator of the first Value
|
||||
* @return iterator on the begin position of the Value
|
||||
*/
|
||||
iterator begin();
|
||||
/**
|
||||
* @brief Get iterator of the next of the last Value
|
||||
* @return iterator on the next of the last position of the Value
|
||||
*/
|
||||
iterator end();
|
||||
/**
|
||||
* @brief Get const iterator of the first Value
|
||||
* @return const iterator on the begin position of the Value
|
||||
*/
|
||||
const iterator begin() const;
|
||||
/**
|
||||
* @brief Get const iterator of the next of the last Value
|
||||
* @return const iterator on the next of the last position of the Value
|
||||
*/
|
||||
const iterator end() const;
|
||||
};
|
||||
}
|
||||
|
@ -200,3 +200,8 @@ const ejson::Object::iterator ejson::Object::end() const {
|
||||
|
||||
template class ejson::iterator<ejson::Object>;
|
||||
|
||||
template<>
|
||||
std::string ejson::iterator<ejson::Object>::getKey() {
|
||||
return m_data.getKey(m_id);
|
||||
}
|
||||
|
||||
|
@ -142,10 +142,26 @@ namespace ejson {
|
||||
*/
|
||||
bool addNumber(const std::string& _name, double _value);
|
||||
public:
|
||||
using iterator = ejson::iterator<ejson::Object>;
|
||||
using iterator = ejson::iterator<ejson::Object>; //!< Specify iterator of the Object methode
|
||||
/**
|
||||
* @brief Get iterator of the first Value
|
||||
* @return iterator on the begin position of the Value
|
||||
*/
|
||||
iterator begin();
|
||||
/**
|
||||
* @brief Get iterator of the next of the last Value
|
||||
* @return iterator on the next of the last position of the Value
|
||||
*/
|
||||
iterator end();
|
||||
/**
|
||||
* @brief Get const iterator of the first Value
|
||||
* @return const iterator on the begin position of the Value
|
||||
*/
|
||||
const iterator begin() const;
|
||||
/**
|
||||
* @brief Get const iterator of the next of the last Value
|
||||
* @return const iterator on the next of the last position of the Value
|
||||
*/
|
||||
const iterator end() const;
|
||||
};
|
||||
}
|
||||
|
@ -32,12 +32,12 @@ bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejso
|
||||
drawElementParsed(_data[iii], _filePos);
|
||||
#endif
|
||||
ejson::FilePos tmpPos;
|
||||
if( _data[iii] == ' '
|
||||
|| _data[iii] == '\t'
|
||||
|| _data[iii] == '\n'
|
||||
|| _data[iii] == '\r') {
|
||||
if ( _data[iii] == ' '
|
||||
|| _data[iii] == '\t'
|
||||
|| _data[iii] == '\n'
|
||||
|| _data[iii] == '\r') {
|
||||
// white space == > nothing to do ...
|
||||
} else if(_data[iii] == '#') {
|
||||
} else if (_data[iii] == '#') {
|
||||
// comment Line ...
|
||||
for (iii++; iii<_data.size(); iii++) {
|
||||
if( _data[iii] == '\n'
|
||||
@ -45,7 +45,7 @@ bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejso
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(_data[iii] == ']') {
|
||||
} else if (_data[iii] == ']') {
|
||||
// find end of value:
|
||||
_pos=iii; // == > return the end element type ==> usefull to check end and check if adding element is needed
|
||||
return true;
|
||||
@ -83,8 +83,17 @@ bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejso
|
||||
}
|
||||
tmpElement->iParse(_data, iii, _filePos, _doc);
|
||||
m_value.push_back(tmpElement);
|
||||
} else if( _data[iii] == 'f'
|
||||
|| _data[iii] == 't' ) {
|
||||
} else if ( ( _data[iii] == 'f'
|
||||
&& iii+4 < _data.size()
|
||||
&& _data[iii+1] == 'a'
|
||||
&& _data[iii+2] == 'l'
|
||||
&& _data[iii+3] == 's'
|
||||
&& _data[iii+4] == 'e')
|
||||
|| ( _data[iii] == 't'
|
||||
&& iii+3 < _data.size()
|
||||
&& _data[iii+1] == 'r'
|
||||
&& _data[iii+2] == 'u'
|
||||
&& _data[iii+3] == 'e') ) {
|
||||
// find boolean:
|
||||
EJSON_PARSE_ELEMENT("find Boolean");
|
||||
ememory::SharedPtr<ejson::internal::Boolean> tmpElement = ejson::internal::Boolean::create();
|
||||
@ -95,18 +104,22 @@ bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejso
|
||||
}
|
||||
tmpElement->iParse(_data, iii, _filePos, _doc);
|
||||
m_value.push_back(tmpElement);
|
||||
} else if( _data[iii] == 'n') {
|
||||
} else if ( _data[iii] == 'n'
|
||||
&& iii+3 < _data.size()
|
||||
&& _data[iii+1] == 'u'
|
||||
&& _data[iii+2] == 'l'
|
||||
&& _data[iii+3] == 'l') {
|
||||
// find null:
|
||||
EJSON_PARSE_ELEMENT("find Null");
|
||||
ememory::SharedPtr<ejson::internal::Null> tmpElement = ejson::internal::Null::create();
|
||||
if (tmpElement == nullptr) {
|
||||
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean");
|
||||
_pos=iii;
|
||||
_pos = iii;
|
||||
return false;
|
||||
}
|
||||
tmpElement->iParse(_data, iii, _filePos, _doc);
|
||||
m_value.push_back(tmpElement);
|
||||
} else if(true == checkNumber(_data[iii])) {
|
||||
} else if (checkNumber(_data[iii]) == true) {
|
||||
// find number:
|
||||
EJSON_PARSE_ELEMENT("find Number");
|
||||
ememory::SharedPtr<ejson::internal::Number> tmpElement = ejson::internal::Number::create();
|
||||
@ -117,12 +130,18 @@ bool ejson::internal::Array::iParse(const std::string& _data, size_t& _pos, ejso
|
||||
}
|
||||
tmpElement->iParse(_data, iii, _filePos, _doc);
|
||||
m_value.push_back(tmpElement);
|
||||
} else if(_data[iii] == ',') {
|
||||
} else if (_data[iii] == ',') {
|
||||
// find Separator : Restart cycle ...
|
||||
// TODO : check if element are separated with ','
|
||||
} else if (_data[iii] == '}') {
|
||||
// find an error ....
|
||||
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Find '}' with no element in the element... Check if is not a ']' element (to stop array)");
|
||||
// move the curent index
|
||||
_pos = iii+1;
|
||||
return false;
|
||||
} else {
|
||||
// find an error ....
|
||||
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Find '?' with no element in the element...");
|
||||
EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, std::string("Find '") + _data[iii] + "' with no element in the element...");
|
||||
// move the curent index
|
||||
_pos = iii+1;
|
||||
return false;
|
||||
|
@ -28,8 +28,8 @@ bool ejson::internal::Null::iParse(const std::string& _data, size_t& _pos, ejson
|
||||
EJSON_CREATE_ERROR(_doc, _data, _pos, _filePos, "Not a corect 'null' element");
|
||||
return false;
|
||||
}
|
||||
_pos+=4;
|
||||
_filePos+=4;
|
||||
_pos+=3;
|
||||
_filePos+=3;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ namespace ejson {
|
||||
virtual ememory::SharedPtr<ejson::internal::Value> clone() const;
|
||||
protected:
|
||||
/**
|
||||
* @brief check if the current element is white or not : '\t' '\n' '\r' ' '
|
||||
* @brief check if the current element is white or not : '\\t' '\\n' '\\r' ' '
|
||||
* @return tue if it is white char
|
||||
*/
|
||||
static bool isWhiteChar(char32_t _val);
|
||||
|
@ -97,5 +97,10 @@ namespace ejson {
|
||||
* @return Const reference on the value.
|
||||
*/
|
||||
ejson::Value operator *() noexcept;
|
||||
/**
|
||||
* @brief Get Key of an element
|
||||
* @return Key of the Element
|
||||
*/
|
||||
std::string getKey();
|
||||
};
|
||||
}
|
||||
|
37
lutin_ejson-sample.py
Normal file
37
lutin_ejson-sample.py
Normal file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python
|
||||
import lutin.module as module
|
||||
import lutin.tools as tools
|
||||
import datetime
|
||||
|
||||
def get_type():
|
||||
return "BINARY"
|
||||
|
||||
def get_sub_type():
|
||||
return "SAMPLE"
|
||||
|
||||
def get_desc():
|
||||
return "e-json sample"
|
||||
|
||||
def get_licence():
|
||||
return "APACHE-2"
|
||||
|
||||
def get_compagny_type():
|
||||
return "com"
|
||||
|
||||
def get_compagny_name():
|
||||
return "atria-soft"
|
||||
|
||||
def get_maintainer():
|
||||
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||
|
||||
def create(target, module_name):
|
||||
my_module = module.Module(__file__, module_name, get_type())
|
||||
my_module.add_src_file([
|
||||
'sample/main.cpp',
|
||||
'sample/read.cpp',
|
||||
'sample/write.cpp'
|
||||
])
|
||||
my_module.add_module_depend(['ejson', 'test-debug'])
|
||||
my_module.copy_path('sample/read.json')
|
||||
return my_module
|
||||
|
@ -1,18 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
import monkModule as module
|
||||
import monkTools as tools
|
||||
|
||||
def get_desc():
|
||||
return "e-json Json parser and genrator"
|
||||
|
||||
def create():
|
||||
# module name is 'edn' and type binary.
|
||||
myModule = module.Module(__file__, 'ejson', 'LIBRARY')
|
||||
# enable doculentation :
|
||||
myModule.set_website("http://heeroyui.github.io/ejson/")
|
||||
myModule.set_website_sources("http://github.com/heeroyui/ejson/")
|
||||
myModule.set_path(tools.get_current_path(__file__) + "/ejson/")
|
||||
myModule.set_path_general_doc(tools.get_current_path(__file__) + "/doc/")
|
||||
# add the currrent module at the
|
||||
return myModule
|
||||
|
32
sample/main.cpp
Normal file
32
sample/main.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <test-debug/debug.h>
|
||||
#include <etk/etk.h>
|
||||
#include "read.h"
|
||||
#include "write.h"
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
// the only one init for etk:
|
||||
etk::init(argc, argv);
|
||||
for (int32_t iii=0; iii<argc ; ++iii) {
|
||||
std::string data = argv[iii];
|
||||
if ( data == "-h"
|
||||
|| data == "--help") {
|
||||
TEST_PRINT("Help : ");
|
||||
TEST_PRINT(" ./xxx [options]");
|
||||
TEST_PRINT(" -h/--help: this help");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
TEST_INFO("read [START] ***************************");
|
||||
appl::read();
|
||||
TEST_INFO("read [STOP ] ***************************");
|
||||
TEST_INFO("write [START] ***************************");
|
||||
appl::write();
|
||||
TEST_INFO("write [STOP ] ***************************");
|
||||
return 0;
|
||||
}
|
301
sample/read.cpp
Normal file
301
sample/read.cpp
Normal file
@ -0,0 +1,301 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
//! [ejson_sample_read_all]
|
||||
#include <test-debug/debug.h>
|
||||
//! [ejson_sample_include]
|
||||
#include <ejson/ejson.h>
|
||||
//! [ejson_sample_include]
|
||||
#include "read.h"
|
||||
|
||||
|
||||
static void readFromFile() {
|
||||
//! [ejson_sample_declare_doc]
|
||||
ejson::Document doc;
|
||||
//! [ejson_sample_declare_doc]
|
||||
//! [ejson_sample_read_file]
|
||||
bool retParse = doc.load("DATA:read.json");
|
||||
//! [ejson_sample_read_file]
|
||||
TEST_INFO("parse ret = " << retParse);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
}
|
||||
|
||||
static void readFromString1() {
|
||||
ejson::Document doc;
|
||||
TEST_INFO("parse");
|
||||
//! [ejson_sample_read_stream1]
|
||||
std::string stream = "{"
|
||||
" \"object A\":\"bonjour\","
|
||||
" \"object B\":null,"
|
||||
" \"object C\":true,"
|
||||
" \"object D\":123854.215,"
|
||||
" \"object E\":["
|
||||
" 1,2,3,54,false"
|
||||
" ],"
|
||||
" \"object F\":{"
|
||||
" \"a\":1,"
|
||||
" \"b\":2"
|
||||
" }"
|
||||
"}";
|
||||
bool retParse = doc.parse(stream);
|
||||
//! [ejson_sample_read_stream1]
|
||||
TEST_INFO("parse ret = " << retParse);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
}
|
||||
|
||||
static void readFromString2() {
|
||||
ejson::Document doc;
|
||||
TEST_INFO("parse");
|
||||
//! [ejson_sample_read_stream2]
|
||||
std::string stream = "{"
|
||||
" objectA:'bonjour',"
|
||||
" objectB:null,"
|
||||
" objectC:true,"
|
||||
" objectD:123854.215,"
|
||||
" objectE:["
|
||||
" #simple comment one Line"
|
||||
" 1,2,3,54,false"
|
||||
" ],"
|
||||
" objectF:{"
|
||||
" a:1,"
|
||||
" b:2"
|
||||
" }"
|
||||
"}";
|
||||
bool retParse = doc.parse(stream);
|
||||
//! [ejson_sample_read_stream2]
|
||||
TEST_INFO("parse ret = " << retParse);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
}
|
||||
|
||||
|
||||
static void readFull() {
|
||||
ejson::Document doc;
|
||||
TEST_INFO("parse");
|
||||
bool retParse = doc.load("DATA:read.json");
|
||||
TEST_INFO("parse ret = " << retParse);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
TEST_INFO("list of Object:");
|
||||
for (const auto it: doc) {
|
||||
TEST_INFO(" " << it);
|
||||
if (it.isObject() == true) {
|
||||
ejson::Object obj = it.toObject();
|
||||
// check if the convertion in ejson::Object has been done corectly
|
||||
if (obj.exist() == false) {
|
||||
continue;
|
||||
}
|
||||
TEST_INFO(" list of object:");
|
||||
for (const auto itObj: obj) {
|
||||
TEST_INFO(" " << itObj);
|
||||
}
|
||||
} else if (it.isArray() == true) {
|
||||
ejson::Array array = it.toArray();
|
||||
// check if the convertion in ejson::Array has been done corectly
|
||||
if (array.exist() == false) {
|
||||
continue;
|
||||
}
|
||||
TEST_INFO(" list of object:");
|
||||
for (const auto itArray: array) {
|
||||
TEST_INFO(" " << itArray);
|
||||
}
|
||||
} else if (it.isBoolean() == true) {
|
||||
ejson::Boolean boolean = it.toBoolean();
|
||||
// check if the convertion in ejson::Boolean has been done corectly
|
||||
if (boolean.exist() == false) {
|
||||
continue;
|
||||
}
|
||||
TEST_INFO(" boolean Value:" << boolean.get());
|
||||
} else if (it.isString() == true) {
|
||||
ejson::String str = it.toString();
|
||||
// check if the convertion in ejson::String has been done corectly
|
||||
if (str.exist() == false) {
|
||||
continue;
|
||||
}
|
||||
TEST_INFO(" String Value:" << str.get());
|
||||
} else if (it.isNumber() == true) {
|
||||
ejson::Number num = it.toNumber();
|
||||
// check if the convertion in ejson::Number has been done corectly
|
||||
if (num.exist() == false) {
|
||||
continue;
|
||||
}
|
||||
TEST_INFO(" Number Value:" << num.get());
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t iii=0; iii<doc.size(); ++iii) {
|
||||
switch (doc[iii].getType()) {
|
||||
case ejson::valueType::object:
|
||||
TEST_INFO(" Get an Object:" << doc.getKey(iii) );
|
||||
break;
|
||||
case ejson::valueType::array:
|
||||
TEST_INFO(" Get an Array:" << doc.getKey(iii) );
|
||||
break;
|
||||
case ejson::valueType::boolean:
|
||||
TEST_INFO(" Get an Boolean:" << doc.getKey(iii) );
|
||||
break;
|
||||
case ejson::valueType::null:
|
||||
TEST_INFO(" Get an Null:" << doc.getKey(iii) );
|
||||
break;
|
||||
case ejson::valueType::number:
|
||||
TEST_INFO(" Get an Number:" << doc.getKey(iii) );
|
||||
break;
|
||||
case ejson::valueType::string:
|
||||
TEST_INFO(" Get an String:" << doc.getKey(iii) );
|
||||
break;
|
||||
default:
|
||||
TEST_INFO(" Inknow element:" << doc.getKey(iii) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_INFO(" Direct get node exml:");
|
||||
//! [ejson_sample_read_get_element]
|
||||
ejson::Value element = doc["object C"];
|
||||
//! [ejson_sample_read_get_element]
|
||||
//! [ejson_sample_read_check_element]
|
||||
|
||||
//! [ejson_sample_read_check_element]
|
||||
|
||||
TEST_INFO("Read String:");
|
||||
{
|
||||
// you can simply change the type of the exml value if you know what it is:
|
||||
//! [ejson_sample_read_convert_string]
|
||||
ejson::String elem = doc["object A"].toString();
|
||||
//! [ejson_sample_read_convert_string]
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_string_value]
|
||||
std::string value = elem.get();
|
||||
//! [ejson_sample_read_get_string_value]
|
||||
TEST_INFO(" String Value:" << value);
|
||||
}
|
||||
// or simply:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_string_1]
|
||||
std::string value = doc["object A"].toString().get();
|
||||
//! [ejson_sample_read_get_string_1]
|
||||
TEST_INFO(" String Value:" << value);
|
||||
}
|
||||
// helper function:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_string_2]
|
||||
std::string value = doc.getStringValue("object A");
|
||||
//! [ejson_sample_read_get_string_2]
|
||||
TEST_INFO(" String Value:" << value);
|
||||
}
|
||||
|
||||
TEST_INFO("Read Boolean:");
|
||||
|
||||
// Get a Boolean value:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_boolean_1]
|
||||
bool value = doc["object C"].toBoolean().get();
|
||||
//! [ejson_sample_read_get_boolean_1]
|
||||
TEST_INFO(" Boolean Value:" << value);
|
||||
}
|
||||
// helper function:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_boolean_2]
|
||||
bool value = doc.getBooleanValue("object C");
|
||||
//! [ejson_sample_read_get_boolean_2]
|
||||
TEST_INFO(" Boolean Value:" << value);
|
||||
}
|
||||
|
||||
TEST_INFO("Read Number:");
|
||||
|
||||
// Get a number value:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_number_1]
|
||||
double value = doc["object D"].toNumber().get();
|
||||
//! [ejson_sample_read_get_number_1]
|
||||
TEST_INFO(" Number Value:" << value);
|
||||
}
|
||||
// helper function:
|
||||
{
|
||||
// Get the value:
|
||||
//! [ejson_sample_read_get_number_2]
|
||||
double value = doc.getNumberValue("object D");
|
||||
//! [ejson_sample_read_get_number_2]
|
||||
TEST_INFO(" Number Value:" << value);
|
||||
}
|
||||
|
||||
TEST_INFO("Read Array:");
|
||||
{
|
||||
//! [ejson_sample_read_get_array]
|
||||
ejson::Array array = doc["object E"].toArray();
|
||||
//! [ejson_sample_read_get_array]
|
||||
// check if the convertion in ejson::Array has been done corectly
|
||||
if (array.exist() == true) {
|
||||
TEST_INFO(" list of Element in Array:");
|
||||
//! [ejson_sample_read_move_threw_array]
|
||||
for (const auto itArray: array) {
|
||||
TEST_INFO(" " << itArray);
|
||||
}
|
||||
//! [ejson_sample_read_move_threw_array]
|
||||
TEST_INFO(" list of Element in Array (C mode):");
|
||||
//! [ejson_sample_read_move_threw_array_c]
|
||||
for (size_t iii=0; iii<array.size(); ++iii) {
|
||||
TEST_INFO(" " << array[iii]);
|
||||
}
|
||||
//! [ejson_sample_read_move_threw_array_c]
|
||||
}
|
||||
}
|
||||
|
||||
TEST_INFO("Read Object:");
|
||||
{
|
||||
//! [ejson_sample_read_get_object]
|
||||
ejson::Object obj = doc["object F"].toObject();
|
||||
//! [ejson_sample_read_get_object]
|
||||
// check if the convertion in ejson::Object has been done corectly
|
||||
if (obj.exist() == true) {
|
||||
TEST_INFO(" list of Element in Object:");
|
||||
//! [ejson_sample_read_move_threw_object]
|
||||
for (const auto itObj: obj) {
|
||||
TEST_INFO(" " << itObj);
|
||||
}
|
||||
//! [ejson_sample_read_move_threw_object]
|
||||
TEST_INFO(" list of Element in Object (C mode):");
|
||||
//! [ejson_sample_read_move_threw_object_c]
|
||||
for (size_t iii=0; iii<obj.size(); ++iii) {
|
||||
TEST_INFO(" " << obj[iii]);
|
||||
}
|
||||
//! [ejson_sample_read_move_threw_object_c]
|
||||
}
|
||||
}
|
||||
|
||||
TEST_INFO("Clone Object:");
|
||||
// in the local system, All element get are not copied but referenced. the to have a copy of an object, you need to clone it :
|
||||
{
|
||||
// Clone object:
|
||||
//! [ejson_sample_read_clone]
|
||||
ejson::Value tmpClone = doc["object F"].clone();
|
||||
//! [ejson_sample_read_clone]
|
||||
ejson::Object obj = tmpClone.toObject();
|
||||
// check if the clone and convertion in ejson::Object has been done corectly
|
||||
if (obj.exist() == true) {
|
||||
TEST_INFO(" list of Element in Object:");
|
||||
for (const auto itObj: obj) {
|
||||
TEST_INFO(" " << itObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void appl::read() {
|
||||
readFromFile();
|
||||
readFromString1();
|
||||
readFromString1();
|
||||
readFull();
|
||||
}
|
||||
//! [ejson_sample_read_all]
|
11
sample/read.h
Normal file
11
sample/read.h
Normal file
@ -0,0 +1,11 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace appl {
|
||||
void read();
|
||||
}
|
13
sample/read.json
Normal file
13
sample/read.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"object A": "bonjour",
|
||||
"object B": null,
|
||||
"object C": true,
|
||||
"object D": 123854,
|
||||
"object E": [
|
||||
1,2,3,54,false
|
||||
],
|
||||
"object F": {
|
||||
"a": 1,
|
||||
"b": 2
|
||||
}
|
||||
}
|
109
sample/write.cpp
Normal file
109
sample/write.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
//! [ejson_sample_write_all]
|
||||
#include <test-debug/debug.h>
|
||||
#include <ejson/ejson.h>
|
||||
#include "write.h"
|
||||
|
||||
static void writeToFile() {
|
||||
ejson::Document doc;
|
||||
doc.add("A", ejson::String("2.5"));
|
||||
doc.add("B", ejson::Number(2010));
|
||||
doc.add("C", ejson::Boolean(false));
|
||||
doc.add("D", ejson::Array());
|
||||
TEST_INFO("store");
|
||||
//! [ejson_sample_write_file]
|
||||
bool retGenerate = doc.store("generate.json");
|
||||
//! [ejson_sample_write_file]
|
||||
TEST_INFO("parse ret = " << retGenerate);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
}
|
||||
|
||||
static void writeToString() {
|
||||
ejson::Document doc;
|
||||
doc.add("A", ejson::String("2.5"));
|
||||
doc.add("B", ejson::Number(2010));
|
||||
doc.add("C", ejson::Boolean(false));
|
||||
doc.add("D", ejson::Array());
|
||||
TEST_INFO("generate");
|
||||
//! [ejson_sample_write_stream]
|
||||
std::string streamOut;
|
||||
bool retGenerate = doc.generate(streamOut);
|
||||
//! [ejson_sample_write_stream]
|
||||
TEST_INFO("parse ret = " << retGenerate);
|
||||
TEST_INFO("Debug display of the tree:");
|
||||
doc.display();
|
||||
}
|
||||
|
||||
static void writeAll() {
|
||||
ejson::Document doc;
|
||||
|
||||
//! [ejson_sample_write_add_string_1]
|
||||
doc.add("A", ejson::String("2.5"));
|
||||
//! [ejson_sample_write_add_string_1]
|
||||
//! [ejson_sample_write_add_string_2]
|
||||
doc.addString("Aa", "lkjlkjlkj");
|
||||
//! [ejson_sample_write_add_string_2]
|
||||
|
||||
//! [ejson_sample_write_add_null_1]
|
||||
doc.add("B", ejson::Null());
|
||||
//! [ejson_sample_write_add_null_1]
|
||||
//! [ejson_sample_write_add_null_2]
|
||||
doc.addNull("Bb");
|
||||
//! [ejson_sample_write_add_null_2]
|
||||
|
||||
//! [ejson_sample_write_add_number_1]
|
||||
doc.add("C", ejson::Number(2010));
|
||||
//! [ejson_sample_write_add_number_1]
|
||||
//! [ejson_sample_write_add_number_2]
|
||||
doc.addNumber("Cc", 5161.2);
|
||||
//! [ejson_sample_write_add_number_2]
|
||||
|
||||
//! [ejson_sample_write_add_boolean_1]
|
||||
doc.add("D", ejson::Boolean(false));
|
||||
//! [ejson_sample_write_add_boolean_1]
|
||||
//! [ejson_sample_write_add_boolean_2]
|
||||
doc.addBoolean("Dd", true);
|
||||
//! [ejson_sample_write_add_boolean_2]
|
||||
|
||||
//! [ejson_sample_write_add_array]
|
||||
ejson::Array array;
|
||||
array.add(ejson::String("elem1"));
|
||||
array.add(ejson::Number(22));
|
||||
array.add(ejson::Null());
|
||||
doc.add("E", array);
|
||||
//! [ejson_sample_write_add_array]
|
||||
|
||||
//! [ejson_sample_write_add_object]
|
||||
ejson::Object object;
|
||||
object.add("ee", ejson::String("elem1"));
|
||||
object.add("55", ejson::Number(22));
|
||||
object.add("lk", ejson::Null());
|
||||
doc.add("F", object);
|
||||
//! [ejson_sample_write_add_object]
|
||||
|
||||
// remove the object named "F"
|
||||
//! [ejson_sample_write_rm_object]
|
||||
//doc.remove("F");
|
||||
//! [ejson_sample_write_rm_object]
|
||||
|
||||
// Remove element 2 in the array
|
||||
//! [ejson_sample_write_rm_array]
|
||||
//array.remove(2);
|
||||
//! [ejson_sample_write_rm_array]
|
||||
doc.display();
|
||||
}
|
||||
|
||||
|
||||
void appl::write() {
|
||||
writeToFile();
|
||||
writeToString();
|
||||
writeAll();
|
||||
}
|
||||
//! [ejson_sample_write_all]
|
||||
|
12
sample/write.h
Normal file
12
sample/write.h
Normal file
@ -0,0 +1,12 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace appl {
|
||||
void write();
|
||||
}
|
||||
|
@ -46,3 +46,6 @@ TEST(TestBoolean, testBaseFalse2) {
|
||||
localTest(refOutputBoolean2, "{ tmpElement:False }\n", 1);
|
||||
}
|
||||
|
||||
TEST(TestBoolean, multipleValue) {
|
||||
localTest("{\n\t\"tmpElement\": false,\n\t\"tmpElement2\": true\n}\n", "{ tmpElement:false, tmpElement2:true }\n", -1);
|
||||
}
|
@ -24,3 +24,8 @@ TEST(TestNull, testTabbedNullElementNoPThese) {
|
||||
localTest(refOutputNull, "tmpElement:null\n", -1);
|
||||
}
|
||||
|
||||
|
||||
TEST(TestNull, multipleElement) {
|
||||
localTest("{\n\t\"tmpElement\": null,\n\t\"tmpElement2\": null\n}\n", "{tmpElement:null, tmpElement2:null\n}", -1);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user