Old 25th June 2012, 21:47   #1
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
nsJSON plug-in

A JSON (JavaScript Object Notation) parser, manipulator and generator plug-in for NSIS. See the readme file for usage and more information.

http://nsis.sf.net/File:NsJSON.zip

Stu
Afrow UK is offline   Reply With Quote
Old 26th June 2012, 08:37   #2
T.Slappy
Major Dude
 
T.Slappy's Avatar
 
Join Date: Jan 2006
Location: Slovakia
Posts: 506
Send a message via ICQ to T.Slappy
Nice work!
Please write a short article into wiki (or copy from readme): http://nsis.sourceforge.net/NsJSON_plug-in

Cool looking skinned Graphical Installers: www.graphical-installer.com
I offer NSIS scripting, C/C++/C#/Delphi programming: www.unsignedsw.com
Develop NSIS projects in Visual Studio 2005-2017: www.visual-installer.com
or RAD Studio 2009, 2010, XE-10.2 Tokyo: www.rad-installer.com
T.Slappy is offline   Reply With Quote
Old 26th June 2012, 13:11   #3
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,351
very nice, especially since none of the xml plugins worked to my satisfaction and i got the option to use json files for the same purpose. thanks stu!
Yathosho is offline   Reply With Quote
Old 26th June 2012, 17:50   #4
Brummelchen
Major Dude
 
Join Date: May 2003
Posts: 681
can i use it to parse json backup files from firefox (bookmark backup file/places)?
Brummelchen is offline   Reply With Quote
Old 26th June 2012, 18:42   #5
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
If it is valid JSON then yes.

Stu
Afrow UK is offline   Reply With Quote
Old 1st July 2012, 17:55   #6
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
New version:
Quote:
1.0.0.1 - 1st July 2012
* Fixed parsing of single digit numbers.
* Fixed Serialize not writing the output file when the stack isn't empty.
I've tested this version on Chrome's Preferences JSON file.

Stu
Afrow UK is offline   Reply With Quote
Old 15th August 2012, 10:59   #7
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
New version:
Quote:
1.0.0.2 - 15th August 2012
* Fixed Unicode build parsing and serializing.
Note the Unicode build still expects ASCII encoded JSON files at the moment. I will perhaps add support for UTF-8 encoded JSON in the future.

Stu
Afrow UK is offline   Reply With Quote
Old 16th August 2012, 04:48   #8
T.Slappy
Major Dude
 
T.Slappy's Avatar
 
Join Date: Jan 2006
Location: Slovakia
Posts: 506
Send a message via ICQ to T.Slappy
Hey Stu, is it possible to parse floating numbers with comma instead of point?
Some currencies use it: "1.23" is "1,23"

Cool looking skinned Graphical Installers: www.graphical-installer.com
I offer NSIS scripting, C/C++/C#/Delphi programming: www.unsignedsw.com
Develop NSIS projects in Visual Studio 2005-2017: www.visual-installer.com
or RAD Studio 2009, 2010, XE-10.2 Tokyo: www.rad-installer.com
T.Slappy is offline   Reply With Quote
Old 16th August 2012, 12:02   #9
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
You have to wrap the value in quotes so that it will be treated as a string rather than a float. It is not possible any other way as a comma is used as the delimiter between objects and values (whitespace is ignored).

Stu
Afrow UK is offline   Reply With Quote
Old 28th August 2012, 17:56   #10
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
New version (with a fair number of changes):
Quote:
1.0.1.0 - 28th August 2012
* Added /unicode switch to the Serialize function. Output files for both plug-in builds are now encoded in ANSI by default.
* Removed the Parse function in favour of Set /file [/unicode].
* Added /type, /key, /exists, /count, /isempty to the Get function.
* Added /index switch for referencing nodes by index.
http://nsis.sourceforge.net/File:NsJSON.zip

Stu
Afrow UK is offline   Reply With Quote
Old 26th April 2013, 16:41   #11
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
Awesome plugin Stu. Any chance of extending it to support multiple json instances open at once?
Marshallx7 is offline   Reply With Quote
Old 30th April 2013, 09:18   #12
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
That is already supported kind of. You just need to use Set /file with a node path to load a JSON file into. The only thing you cannot do is serialize a specific node to a file, which is where a change would be necessary. How much do you need multiple instance support (give an example of usage)?

Stu
Afrow UK is offline   Reply With Quote
Old 7th May 2013, 20:09   #13
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
I'm using in-memory json to store lots of my own user-specific data rather than tons of global variables.
Then I want to open up a program's settings file which is also in json, add a value and resave that settings.json.

It's also useful to separate different blocks of data and only serialize the parts I need during debug.

I guess the only thing that's really needed is the ability to serialize a specific node.

Unless I can find a better solution for my in-memory storage... Actually, thinking about it I could probably use your arrays plugin and do arrays of pointers to arrays using a counter or concatenating names like
CarPark0 = array of license plates (e.g. 0=ABC123, 1=DEF456, 2=GHI789)
CarPark0_ABC123 = array of that particular car's properties (e.g. Make=ShinyThingsInc, Color=Green)

So yeah, it probably isn't necessary to have the json plugin handle more than 1 root json object at a time. I'll just write my own serializer for the arrays.

Cheers again for your awesome stuff.
Marshallx7 is offline   Reply With Quote
Old 6th June 2013, 11:59   #14
zeeh3
Senior Member
 
Join Date: Aug 2005
Posts: 121
I am getting truncated string values when they have spaces:

nsJSON::Set `more_stuff` `PSCHED_009_NAME` /value `QoS Packet Scheduler`

Results in:

"more_stuff": { "PSCHED_009_NAME": QoS }
zeeh3 is offline   Reply With Quote
Old 6th June 2013, 15:01   #15
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
Values are parsed as JSON. If you want quoted strings you must use double quotes around the value:

nsJSON::Set `more_stuff` `PSCHED_009_NAME` /value `"QoS Packet Scheduler"`

Stu
Afrow UK is offline   Reply With Quote
Old 17th March 2014, 11:50   #16
maliktous
Junior Member
 
Join Date: Dec 2012
Posts: 6
nsJSON::Serialize crashes nsis installer with recent stable chrome default Preferences, which contain a very long (~66 KBytes) `variations_seed` string parameter.

Test case:
Fresh install of google chrome (33.0.1750.154) which contain `variations_seed` parameter.
code:
nsJSON::Set /file "$Prefs"
nsJSON::Serialize /format /file "$Prefs"



I'm using ANSI NSIS v2.46 with nsJSON 1.0.1.0.

Preferences sample:
http://pastebin.com/raw.php?i=Xs4HLBMN

deleting `variations_seed` before serializing workarounds this, but is ugly
code:
nsJSON :: Delete `variations_seed` /end
maliktous is offline   Reply With Quote
Old 25th March 2014, 13:19   #17
maliktous
Junior Member
 
Join Date: Dec 2012
Posts: 6
PHP Code:
nsJSON::Set /file "$Prefs"
nsJSON::Serialize /format /file "$Prefs
with following json:
PHP Code:
{
   
"selectfile": {
      
"last_directory""E:\\"
   
},
   
"session": {
      
"restore_on_startup_migrated"true,
      
"startup_urls_migration_time""13037468179710507"
   
}

saves broken json:
PHP Code:
{
    
"selectfile": {
        
"last_directory""E:\\"
   
},
   
"
    }

maliktous is offline   Reply With Quote
Old 25th March 2014, 13:30   #18
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,351
Quote:
Originally Posted by maliktous View Post
PHP Code:
{
   
"selectfile": {
      
"last_directory""E:\\"
   
},

It take it the plugin escapes the last quote, but wouldn't you have to escape the backslash as well?
Yathosho is offline   Reply With Quote
Old 25th March 2014, 13:34   #19
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
Quote:
Originally Posted by Yathosho View Post
It take it the plugin escapes the last quote, but wouldn't you have to escape the backslash as well?
"E:\\" should end up as "E:\", there is no escaped quote because that double backslash was already used to create a backslash

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 25th March 2014, 13:35   #20
maliktous
Junior Member
 
Join Date: Dec 2012
Posts: 6
Quote:
Originally Posted by Yathosho View Post
It take it the plugin escapes the last quote, but wouldn't you have to escape the backslash as well?
1. It is a standart Google Chrome Preferences, so it is a valid json. I did not create it manually. I just read it, add my values, then save it.
2. Python parses it correctly:
PHP Code:
cat test.json
{
   
"selectfile": {
      
"last_directory""E:\\"
   
},
   
"session": {
      
"restore_on_startup_migrated"true,
      
"startup_urls_migration_time""13037468179710507"
   
}
}
>>> 
f=open("test.json")
>>> 
import json
>>> json.load(f)
{
u'selectfile': {u'last_directory'u'E:\\'}, u'session': {u'restore_on_startup_migrated'Trueu'startup_urls_migration_time'u'13037468179710507'}} 
maliktous is offline   Reply With Quote
Old 25th March 2014, 13:36   #21
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,351
Quote:
Originally Posted by Anders View Post
"E:\\" should end up as "E:\", there is no escaped quote because that double backslash was already used to create a backslash
ah, of course. you're right
Yathosho is offline   Reply With Quote
Old 26th March 2014, 06:51   #22
maliktous
Junior Member
 
Join Date: Dec 2012
Posts: 6
Quote:
Originally Posted by maliktous View Post
nsJSON::Set /file "$Prefs"
nsJSON::Serialize /format /file "$Prefs"
with following json:
saves broken json:
workaround (should be used before Set /file ):
PHP Code:
Push `\\"`          # text to be replaced
Push `"`            # replace with
Push all            # replace all occurrences
Push all            # replace all occurrences
Push ${PrefsFile}   # file to replace in
Call AdvReplaceInFile 
maliktous is offline   Reply With Quote
Old 26th March 2014, 19:17   #23
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
I will try to look at the issues this weekend.

Stu
Afrow UK is offline   Reply With Quote
Old 29th March 2014, 09:24   #24
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
Quote:
1.0.1.1 - 29th March 2014
* Fixed incorrect handling of escape character (\).
Quote:
Originally Posted by maliktous View Post
nsJSON::Serialize crashes nsis installer with recent stable chrome default Preferences, which contain a very long (~66 KBytes) `variations_seed` string parameter.
I could not reproduce this with the new build so it may be fixed. The full output string (66224 bytes) is correctly written to the output file for both the ANSI and Unicode versions. No memory access violations were caught in the debugger either.

Stu
Afrow UK is offline   Reply With Quote
Old 10th July 2014, 14:02   #25
CherryDT
Junior Member
 
Join Date: Jul 2014
Posts: 1
I can confirm that there is still a problem. The problem happens when the data is >64KB. It doesn't always crash, though, because it's corrupting the heap which might or might not result in a crash.

The source of the problem is that in the Serialize function, you allocate 65536 bytes for pszArg:
code:
PTCHAR pszArg = (PTCHAR)LocalAlloc(LPTR, sizeof(TCHAR) * 65536);

...and later you are using this buffer to store the serialized string:
code:
bOK = JSON_Serialize(g_root, pszArg, bIsFile, bAsUnicode, bFormat);


There is no length check taking place anywhere.
CherryDT is offline   Reply With Quote
Old 10th July 2014, 15:17   #26
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
I will work on a fix to automatically increase the buffer size this weekend.

Stu
Afrow UK is offline   Reply With Quote
Old 12th July 2014, 21:06   #27
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
New version:
Quote:
1.0.1.2 - 12th July 2014
* Fixed crash on serialization to file for node values larger than 64KB.
* Fixed crash on serialization to stack for JSON larger than NSIS_MAX_STRLEN. The JSON will now be truncated.
The file serialization doesn't use any temporary buffer any more (it just writes directly to the file) so no reallocation was necessary.

Stu
Afrow UK is offline   Reply With Quote
Old 5th September 2014, 13:09   #28
maliktous
Junior Member
 
Join Date: Dec 2012
Posts: 6
1.0.1.2 crashes if JSON file starts with Byte order mark

It seems that `nsJSON::Set /file $JSON` works but the next `nsJSON::Set` crashes installer.

I don't know if json can contain BOM, so it is just for your attention, but I guess, at least, it should not crash.

Quote:
--- "Bad" 2014-09-05 15:53:16.000000000 +0300
+++ "Good" 2014-09-05 15:53:16.000000000 +0300
@@ -1,4 +1,4 @@
-<U+FEFF>{
+{
"test": {
Attached Files
File Type: txt Preferences_Bad.txt (63.0 KB, 667 views)
maliktous is offline   Reply With Quote
Old 18th October 2014, 21:27   #29
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
New version:
Quote:
1.0.1.3 - 18th October 2014
* Added UTF-16LE BOM, UTF-16BE BOM and UTF-8 signature detection for input files (with UTF-16BE conversion to UTF-16LE).
* Fixed formatting errors for the Serialize function.
* Fixed closing bracket or curly brace not being included on Serialize to stack when not using /format.
This should resolve the crash for files with UTF-8 signatures.

My next task is to add HTTP GET/PUT/POST support for use with REST.

Stu
Afrow UK is offline   Reply With Quote
Old 9th April 2015, 09:24   #30
MeTaNoV
Junior Member
 
Join Date: Apr 2015
Posts: 1
nsJSON does not support comment

Hi,
I am trying to use nsJSON plug-in and just find out that comment '//' does disturb somehow the parser, and break the reading of any node inside the file...
I'll temporally avoid using comment until I find a proper solution!
Cheers,
Pascal
MeTaNoV is offline   Reply With Quote
Old 9th April 2015, 14:52   #31
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
JSON does not really have comments AFAIK.

The safest option is to use _mycomment:"comment text" style entries.

If you still want a real comment then /**/ block comments probably have a higher chance of working across parsers...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 16th November 2015, 16:34   #32
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
This plugin is awesome.

However, is there any chance of adding an escape function to convert an NSIS string into a JSON string?

For example, right now if I call
nsjson::Set some node path /value ":"
Then the colon is not stored because it is invalid JSON, not a string. I have to call
nsjson::Set some node path /value `":"`

But if I don't know where the text has come from e.g.
nsjson::Set some node path /value $R0
Then that's a problem.

One of the following would be ideal:
nsjson::escape $R0
Pop $R0
nsjson::Set some node path /value $R0

alternatively,
nsjson::Set some node path /value /escape $R0

Such a function shouldn't try to determine the type of data - just treat the input as an unescaped, unquoted string.
Marshallx7 is offline   Reply With Quote
Old 17th November 2015, 04:27   #33
JasonFriday13
Major Dude
 
JasonFriday13's Avatar
 
Join Date: May 2005
Location: New Zealand
Posts: 853
Try quotes or double quotes around the variable? Like: "$R0". If strings have spaces, they can resolve to multiple arguments when used with a plugin, which is why quotes are needed.

"Only a MouseHelmet will save you from a MouseTrap" -Jason Ross (Me)
NSIS 3 POSIX Ninja
Wiki Profile
JasonFriday13 is offline   Reply With Quote
Old 23rd November 2015, 07:21   #34
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
Quote:
1.1.0.1 - 23rd November 2015
* Added Quote function.
* Added amd64-unicode build.

1.1.0.0 - 19th April 2015
* Support for multiple JSON trees.
* JSON via HTTP web requests.
Somehow I hadn't uploaded the last version I'd been working on so I apologise for that. It includes built-in support for multiple JSON trees and HTTP web requests (e.g. for REST APIs).

http://nsis.sourceforge.net/File:NsJSON.zip

Stu
Afrow UK is offline   Reply With Quote
Old 23rd November 2015, 10:25   #35
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
This is great, thanks Stu
Marshallx7 is offline   Reply With Quote
Old 24th November 2015, 13:54   #36
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
NB: When you use nsJSON::Get /type, if the nodepath doesn't exist then nothing gets pushed onto the stack - so always make sure you check that the nodepath /exists before you try to get the type.

Stu, you could change /type to return empty string if the node path doesn't exist, and do away with /exists altogether.
Marshallx7 is offline   Reply With Quote
Old 25th November 2015, 08:58   #37
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
Hey, Stu
The new Quote function doesn't escape strings whose first and last characters are already quotemarks. For example, nsjson::Quote `"some"text"`
Marshallx7 is offline   Reply With Quote
Old 9th December 2015, 10:20   #38
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Surrey, England
Posts: 8,433
Quote:
Originally Posted by Marshallx7 View Post
Hey, Stu
The new Quote function doesn't escape strings whose first and last characters are already quotemarks. For example, nsjson::Quote `"some"text"`
The output is:
Quote:
"some\"text"
This is correct assuming the original feature request was to only surround the string in quotes if it isn't so already. Nevertheless:
Quote:
1.1.0.2 - 9th December 2015
* Get function /type switch returns an empty string if the node does not exist.
* Added /always switch to Quote function which surrounds the input string in quotes even if it is already quoted.
Therefore, use the /always switch and the output will instead be:
Quote:
"\"some\"text\""
http://nsis.sourceforge.net/File:NsJSON.zip

Stu
Afrow UK is offline   Reply With Quote
Old 9th February 2016, 13:48   #39
Marshallx7
Junior Member
 
Join Date: Oct 2012
Posts: 35
This is really great Stu, thanks.

Readme needs updating with latest switches behavior btw.

I have another feature request if you feel inclined:

{ a: 'a', b: 1, c: {}}
nsJSON::Get /keys ...
Returns on the stack:
3
a
b
c
Marshallx7 is offline   Reply With Quote
Old 10th February 2016, 06:35   #40
Yathosho
Forum King
 
Yathosho's Avatar
 
Join Date: Jan 2002
Location: AT-DE
Posts: 3,351
Quote:
Originally Posted by Marshallx7 View Post
{ a: 'a', b: 1, c: {}}
Erm, I would expect the plugin to deny this input, since it's invalid JSON
Yathosho is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > NSIS Discussion

Tags
json, plug-in

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump