Skip to content
Jacob Williams edited this page May 9, 2016 · 3 revisions

JSON-Fortran 5.0 Changes

JSON-Fortran 5.0 includes some significant changes that break backward compatibility with previous releases. This note provides some information on these changes, and shows how to convert your code over to the new release.

Overview of changes

  • The library is now completely thread-safe. Previous versions were not thread-safe due to the use of various global variables.
  • The library is now split into multiple files. However, the entire library capability can still be accessed by a single use statement:
use json_module
  • All the public routines in the module have been eliminated. Now, methods may only be accessed through two public classes: json_core and json_file. This was necessary in order to provide thread-safe usage. Use of these classes is described below.

Public entities in the library

Kinds

  • The kind variables RK, IK, LK, CK, and CDK have been renamed to json_RK, json_IK, json_LK, json_CK, and json_CDK in order to avoid namespace collisions. So, if you are using these variables in your code, you can continue using the old names by renaming them when you use the module:
use json_fortran, RK => json_RK, &
                  LK => json_LK
logical(LK) :: found
real(RK) :: rval

or, by renaming the variables in the variable declarations like so:

use json_fortran
logical(json_LK) :: found
real(json_RK) :: rval

json_file

  • The json_file class is much the same as before with the addition of new methods such as: json_file%initialize() (which replaces the old json_initialize()) and json_file%failed() (which replaces the old json_failed()). So, for applications that only use json_file to access JSON data, the code changes are minimal. For example the program:

    program example
    
    use json_module
    
    implicit none
    
    type(json_file) :: json
    logical(LK) :: found
    integer(IK) :: i
    
    call json_initialize()
    call json%load_file(filename = '../files/inputs/test1.json')
    call json%print_file()
    call json%get('version.major', i, found)
    if ( .not. found ) error stop 'error'
    
    call json%destroy()
    if (json_failed()) error stop 'error'
    
    end program example

    Can be converted to the 5.0 syntax by renaming the kind variables, and replacing two _ characters with % characters like so:

    program example
    
    use json_module, LK=>json_LK,IK=>json_IK
    
    implicit none
    
    type(json_file) :: json
    logical(LK) :: found
    integer(IK) :: i
    
    call json%initialize()
    call json%load_file(filename = '../files/inputs/test1.json')
    call json%print_file()
    call json%get('version.major', i, found)
    if ( .not. found ) error stop 'error'
    
    call json%destroy()
    if (json%failed()) error stop 'error'
    
    end program example

    As always, in order to prevent a memory leak, json_file%destroy() must be called before the variable goes out of scope in order to free the memory.

json_core

  • The json_core class is a new class that must be used if you need to manipulate the json_value pointers that are used to build a JSON linked-list. Formerly, manipulation of these variables was done using a series of overloaded subroutines such as json_get, json_update, etc. Now, these subroutines have been moved into the json_core class. Consider the following example program using the pre-5.0 library:

    program example
    
    use json_module
    
    implicit none
    
    type(json_value),pointer :: p, inp
    
    call json_initialize()
    call json_create_object(p,'')
    call json_create_object(inp,'inputs')
    call json_add(p, inp)
    call json_add(inp, 't0', 0.1_RK)
    call json_print(p,'../files/example2.json')
    call json_destroy(p)
    if (json_failed()) error stop 'error'
    
    end program example

    Using the 5.0 library, this code can be converted by declaring an instance of json_core (for convenience, we can name it json), and again changing some _ characters to % like so:

    program example
    
    use json_module, RK => json_RK
    
    implicit none
    
    type(json_core) :: json
    type(json_value),pointer :: p, inp
    
    call json%initialize()
    call json%create_object(p,'')
    call json%create_object(inp,'inputs')
    call json%add(p, inp)
    call json%add(inp, 't0', 0.1_RK)
    call json%print(p,'../files/example2.json')
    call json%destroy(p)
    if (json%failed()) error stop 'error'
    
    end program example

json_value

  • The json_value type has not changed from previous versions. It should always be a pointer variable, and it is used to create the linked list tree structures containing the JSON data. Care must be taken to properly free memory using json_core%destroy() where appropriate, or a memory leak will ensue.

Operators

  • The Unicode version of the module also exports three operators (==, /=, and //) for dealing with CK and CDK character strings.