Page 4 of 4
Re: JSON encoder and decoder
Posted: Sat Aug 03, 2013 12:56 pm
by PMV
update: 01.08.2013
+ bufix: string creation for unicode escaped characters (tab, linebreak, slash, ...) failed
@Fangbeast
Boolean values are the smalest variant of number-values.
You can use \i for that. Additional every element will save his
Datatype inside of \type. So you can use that field, too.
Code: Select all
If *out\o("items")\a(0)\o("accessInfo")\o("epub")\o("isAvailable")\type = #JSON_Type_True
Debug "epub is available: true"
Else
Debug "epub is available: false"
EndIf
I prefer the use of \type because if you are just using \i, you can't
know if it is really just a boolean value.
MFG PMV
Re: JSON encoder and decoder
Posted: Sun Aug 25, 2013 4:53 am
by nblackburn
Agreed, this would be a very useful thing to have in PB.
Re: JSON encoder and decoder
Posted: Sat Nov 02, 2013 2:50 pm
by rambodash
hey, I was using your library and discovered a small bug with 32bit integers overflowing (only effects 32bit OS)
possible fix:
Code: Select all
Procedure IsLargerThan32bitInteger(string$)
IF len(string$) > 10 : ProcedureReturn #True : ENDIF
IF len(string$) < 9 : ProcedureReturn #False : ENDIF
;2147483647
DIM highnum(9)
highnum(0) = 2
highnum(1) = 1
highnum(2) = 4
highnum(3) = 7
highnum(4) = 4
highnum(5) = 8
highnum(6) = 3
highnum(7) = 6
highnum(8) = 4
highnum(9) = 7
Define i
Define spos = 1
For i = 0 to ArraySize(highnum())
IF VAL(MID(string$, spos, 1)) > highnum(i) : ProcedureReturn #True : Endif
spos = spos + 1
Next
ProcedureReturn #False
EndProcedure
changes made to this section
Code: Select all
string = PeekS(*first, (*c - *first) / SizeOf(CHARACTER))
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
If FindString(string, ".", 1) OR IsLargerThan32bitInteger(string)
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
If FindString(string, ".", 1)
CompilerEndIf
*out\s = string ; used for JSON_encode()
*out\f = ValD(string)
*out\i = *out\f
*out\type = #JSON_Type_Float
;Debug "Float: " + StrD(*out\f)
ElseIf FindString(string, "e", 1)
*out\s = string ; used for JSON_encode()
e = StringField(string, 2, "e")
string = StringField(string, 1, "e")
*out\f = ValD(string) * Pow(10, Val(e))
*out\i = *out\f
*out\type = #JSON_Type_Float
;Debug "Float: " + StrD(*out\f)
Else
*out\i = Val(string)
*out\f = *out\i
*out\type = #JSON_Type_Integer
;Debug "Integer: " + Str(*out\i)
EndIf
Re: JSON encoder and decoder
Posted: Thu Dec 05, 2013 9:42 am
by Kukulkan
Hello,
quick question about the usage. I have loaded the following JSON (strFileList):
Code: Select all
{
"/path/to/invoice_678432.pdf" : {
"upload" : true,
"meta": [ "bzu54r2bzu", "€99.95" ]
},
"/path/to/some/marketing_flyer.pdf" : { },
"/path/to/invoice_126742.pdf" : {
"upload" : true,
"meta": [ "Invoice#=asd21r2f00", "Total=$23" ]
},
"/path/to/some/special_offer.pdf" : { "upload" : false }
}
Now parsing the content like this:
Code: Select all
*jFiles.jsonObj = JSON_decode(strFileList)
ForEach *jFiles\o()
Protected SourcePDF.s = MapKey(*jFiles\o())
; (Doing some conversion here resulting in a moved file path!)
; THEREFORE, I LIKE TO CHANGE THE KEY NAME HERE!!!!!
Next
strFileList.s = JSON_encode(*jFiles)
JSON_free(*jFiles)
As you can see, I need to
change the key name. Any idea how to do this preserving the individual content of all the elements below?
Kukulkan
Re: JSON encoder and decoder
Posted: Thu Dec 05, 2013 12:03 pm
by Kukulkan
Found no way to easily solve, but found a workaround by duplicating and swapping pointers:
Code: Select all
Protected *destFiles.jsonObj = JSON_Create() ; json object for destination
JSON_newObject(*destFiles)
*jFiles.jsonObj = JSON_decode(strFileList)
ForEach *jFiles\o()
Protected SourcePDF.s = MapKey(*jFiles\o())
Protected DestinationPDF.s = "some new filename"
; -----------------------------------
JSON_newPair(*destFiles, DestinationPDF.s) ; create fake entry
Copy.i = *destFiles\o(DestinationPDF.s)
*destFiles\o(DestinationPDF.s) = *jFiles\o() ; swap pointers (real/fake)
*jFiles\o() = Copy.i
; -----------------------------------
Next
strFileList.s = JSON_encode(*destFiles)
JSON_free(*jFiles)
JSON_free(*destFiles)
This did it for me. Maybe someone else can make use of it, too.
Kukulkan
Re: JSON encoder and decoder
Posted: Thu Dec 05, 2013 2:24 pm
by PMV
It is just 2 lines of code to change the key. With
PB even doesn't have to copy all elements, just writes the pointer
into the other key and delete the old key.
add this code at the end of the example inside of the JSON_Parser.pbi
file right before the line JSON_Debug(*myJSON, "")
Code: Select all
JSON_newPair(*myJSON, "Original")
*myJSON\o("Original")\s = "key to change"
*myJSON\o("Renamed") = *myJSON\o("Original") ; < create new key and copy original to new
DeleteMapElement(*myJSON\o(), "Original") ; < delete original
Hint:
If you doesn't use the pointer-way, you can remove the first line of
that example. As PB will copy all data inside of the map-element, it
will take some time if its a huge amount. Badly, there is no function to
rename a map-element to another key and preventing that.
feature request:
http://www.purebasic.fr/english/viewtop ... =3&t=57600
MFG PMV
Re: JSON encoder and decoder
Posted: Thu Dec 05, 2013 3:13 pm
by Kukulkan
Thanks!