UnQLite Users Forum

Decoding of negative Numbers in Json by JX9

append delete Pauline

Hi,

I have a question that should probably be a bug report, but the link you provide for bug reporting gives me a page not found.

Problem description:
Trying out some unqlite and jx9 basics in a Visual Studio 2015 C++ Project, I came across a Json decoding Error. When a value in the Json Structure is a negative number, the json_decode function returns null.

Below is the Jx9 Script and my C++ Code (both nearly directly from the Examples Page you provide). I can run the script from my code just fine, when I change -5 to 5 in line 13. When it's -5 I get the reported error.

Any elaboration on the matter would be much appreciated.
Best Regards. Pauline

JX9 --------------------------------------------------
// ---------------------- config_writer.jx9 ----------------------------

// Create a dummy JSON object configuration
$my_config = {
bind_ip : "127.0.0.1",
config : "/etc/symisc/jx9.conf",
dbpath : "/usr/local/unqlite",
fork : true,
logappend : true,
logpath : "/var/log/jx9.log",
quiet : true,
port : 8080,
number : -5
};

// Dump the JSON object
print $my_config;

// Write to disk
$file = "config.json.txt";
print "\n\n------------------\nWriting JSON object to disk file: '$file'\n";

// Create the file
$fp = fopen($file,'w+');
if( !$fp )
exit("Cannot create $file");

// Write the JSON object
fwrite($fp,$my_config);

// Close the file
fclose($fp);

// All done
print "$file successfully created on: "..__DATE__..' '..__TIME__;
print "\n";

// ---------------------- config_reader.jx9 ----------------------------

// Read the configuration file defined above
$zFile = "config.json.txt";
$iSz = filesize($zFile); // Size of the whole file
$fp = fopen($zFile,'r'); // Read-only mode
if( !$fp ){
exit("Cannot open '$zFile'");
}

// Read the raw content
$zBuf = fread($fp,$iSz);

// decode the JSON object now
$my_config = json_decode($zBuf);
if( !$my_config ){
print "JSON decoding error\n";
}else{
// Dump the JSON object
foreach( $my_config as $key,$value ){
print "$key ===> $value\n";
}
}

// Close the file
fclose($fp);

-------------------------------------------------------------------------------------------

C++ Main

----------------------------------------------------------------------------------------------

#ifdef __cplusplus
extern "C" {
#endif
#include "unqlite.h"
#ifdef __cplusplus
}
#endif

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
/* Extract database error log and exit */
static void Fatal(unqlite *pDb, const char *zMsg)
{
if (pDb) {
const char *zErr;
int iLen = 0; /* Stupid cc warning */

/* Extract the database error log */
unqlite_config(pDb, UNQLITE_CONFIG_ERR_LOG, &zErr, &iLen);
if (iLen > 0) {
/* Output the DB error log */
puts(zErr); /* Always null termniated */
}
}
else {
if (zMsg) {
puts(zMsg);
}
}
/* Manually shutdown the library */
unqlite_lib_shutdown();
std::cin.get();
/* Exit immediately */
exit(0);
}

/* Forward declaration: VM output consumer callback */
static int VmOutputConsumer(const void *pOutput, unsigned int nOutLen, void *pUserData /* Unused */);

char * ReadJx9Script(string fileName, int& sizeOffRead) {

ifstream file(fileName, ios::in | ios::ate);
streampos begin, end;

streampos size;
char * file_content;

if (file.is_open())
{
size = file.tellg();
file_content = new char[size];;
file.seekg(0, ios::beg);
file.read(file_content, size);
file.close();
}
else {
cout << "Unable to open file ";
cout << fileName << endl;
return NULL;
}
sizeOffRead = size;

return file_content;
}

void CompileScript(unqlite *pDb, const char *JX9_PROG, int sizeOffJx9Script, unqlite_vm **pVm) {

int rc;
rc = unqlite_compile(pDb, JX9_PROG, sizeOffJx9Script, pVm);

if (rc != UNQLITE_OK) {
/* Compile error, extract the compiler error log */
const char *zBuf;
int iLen;
/* Extract error log */
unqlite_config(pDb, UNQLITE_CONFIG_JX9_ERR_LOG, &zBuf, &iLen);
if (iLen > 0) {
puts(zBuf);
}
Fatal(0, "Jx9 compile error");
}

/* Install a VM output consumer callback */
rc = unqlite_vm_config(*pVm, UNQLITE_VM_CONFIG_OUTPUT, VmOutputConsumer, 0);
if (rc != UNQLITE_OK) {
Fatal(pDb, 0);
}
}

int main(int argc, char *argv[])
{
unqlite *pDb; /* Database handle */
unqlite_kv_cursor *pCur; /* Cursor handle */
unqlite_vm *pVmCreateSamples; /* UnQLite VM resulting from successful compilation of the target Jx9 script */
unqlite_value *pScalar;

//Open DB
int rc;
rc = unqlite_open(&pDb, argc > 1 ? argv[1] /* On-disk DB */ : ":mem:" /* In-mem DB */, UNQLITE_OPEN_CREATE);
if (rc != UNQLITE_OK) { Fatal(pDb, 0); }


int sizeOffReadJx9Script;
/*The Jx9 Script*/
char * JX9_PROG = ReadJx9Script("configwrite.jx9", sizeOffReadJx9Script);
CompileScript(pDb, JX9_PROG, sizeOffReadJx9Script, &pVmCreateSamples);

/* Execute script */
rc = unqlite_vm_exec(pVmCreateSamples);
if (rc != UNQLITE_OK) {
Fatal(pDb, 0);
}
/* Release VM */
unqlite_vm_release(pVmCreateSamples);

unqlite_close(pDb);

std::cin.get();
delete[] JX9_PROG;
return 0;
}

#ifdef __WINNT__
#include <Windows.h>
#else
/* Assume UNIX */
#include <unistd.h>
#endif
/*
* The following define is used by the UNIX build process and have
* no particular meaning on windows.
*/
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/*
* VM output consumer callback.
* Each time the UnQLite VM generates some outputs, the following
* function gets called by the underlying virtual machine to consume
* the generated output.
*
* All this function does is redirecting the VM output to STDOUT.
* This function is registered via a call to [unqlite_vm_config()]
* with a configuration verb set to: UNQLITE_VM_CONFIG_OUTPUT.
*/
static int VmOutputConsumer(const void *pOutput, unsigned int nOutLen, void *pUserData /* Unused */)
{
#ifdef __WINNT__
BOOL rc;
rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pOutput, (DWORD)nOutLen, 0, 0);
if (!rc) {
/* Abort processing */
return UNQLITE_ABORT;
}
#else
ssize_t nWr;
nWr = write(STDOUT_FILENO, pOutput, nOutLen);
if (nWr < 0) {
/* Abort processing */
return UNQLITE_ABORT;
}
#endif /* __WINT__ */

/* All done, data was redirected to STDOUT */
return UNQLITE_OK;
}

Reply RSS

Replies

append delete #1. chm

Hi

A quick fix consist of extracting the negative number as a null terminated string and converting this later via unqlite_value_to_int64() which will give you the negative number correctly.

append delete #2. Pauline

Hi,

thank you for your answer.

This would mean not to work with the Scripts json_decode() function but to read and manually decode the document in my C or C++ Code, right?

Best Regards. Pauline

append delete #3. chm

Yes,only if you are willing to play with negative numbers . Otherwise, you should rely on json_decode()

append delete #4. Pauline

Ok. Thank you.

Reply

(Leave this as-is, it’s a trap!)

There is no need to “register”, just enter the same name + password of your choice every time.

Pro tip: Use markup to add links, quotes and more.

Your friendly neighbourhood moderators: chm_at_symisc, devel_at_symisc