json_initialize Subroutine

private subroutine json_initialize(me, verbose, compact_reals, print_signs, real_format, spaces_per_tab, strict_type_checking, trailing_spaces_significant, case_sensitive_keys, no_whitespace, unescape_strings, comment_char, path_mode, path_separator, compress_vectors, allow_duplicate_keys, escape_solidus, stop_on_error, null_to_real_mode, non_normal_mode, use_quiet_nan, strict_integer_type_checking)

Initialize the json_core instance.

The routine may be called before any of the json_core methods are used in order to specify certain parameters. If it is not called, then the defaults are used. This routine is also called internally by various routines. It can also be called to clear exceptions, or to reset some of the variables (note that only the arguments present are changed).

Modified

  • Izaak Beekman : 02/24/2015

Type Bound

json_core

Arguments

Type IntentOptional Attributes Name
class(json_core), intent(inout) :: me
logical(kind=LK), intent(in), optional :: verbose

mainly useful for debugging (default is false)

logical(kind=LK), intent(in), optional :: compact_reals

to compact the real number strings for output (default is true)

logical(kind=LK), intent(in), optional :: print_signs

always print numeric sign (default is false)

character(kind=CDK, len=*), intent(in), optional :: real_format

Real number format: ‘E’ [default], ‘*’, ‘G’, ‘EN’, or ‘ES’

integer(kind=IK), intent(in), optional :: spaces_per_tab

number of spaces per tab for indenting (default is 2)

logical(kind=LK), intent(in), optional :: strict_type_checking

if true, no integer, double, or logical type conversions are done for the get routines (default is false).

logical(kind=LK), intent(in), optional :: trailing_spaces_significant

for name and path comparisons, is trailing space to be considered significant. (default is false)

logical(kind=LK), intent(in), optional :: case_sensitive_keys

for name and path comparisons, are they case sensitive. (default is true)

logical(kind=LK), intent(in), optional :: no_whitespace

if true, printing the JSON structure is done without adding any non-significant spaces or linebreaks (default is false)

logical(kind=LK), intent(in), optional :: unescape_strings

If false, then the raw escaped string is returned from json_get_string and similar routines. If true [default], then the string is returned unescaped.

character(kind=CK, len=*), intent(in), optional :: comment_char

If present, these characters are used to denote comments in the JSON file, which will be ignored if present. Example: !, #, or /!#. Setting this to a blank string disables the ignoring of comments. (Default is /!#).

integer(kind=IK), intent(in), optional :: path_mode

How the path strings are interpreted in the get_by_path routines:

character(kind=CK, len=1), intent(in), optional :: path_separator

The path separator to use in the “default” mode for the paths in the various get_by_path routines. Example: . [default] or %. Note: if path_mode/=1 then this is ignored.

logical(kind=LK), intent(in), optional :: compress_vectors

If true, then arrays of integers, nulls, doubles, and logicals are printed all on one line. [Note: no_whitespace will override this option if necessary]. (Default is False).

logical(kind=LK), intent(in), optional :: allow_duplicate_keys
  • If True [default] then no special checks are done to check for duplicate keys.
  • If False, then after parsing, if any duplicate keys are found, an error is thrown. A call to json_value_validate will also check for duplicates.
logical(kind=LK), intent(in), optional :: escape_solidus
  • If True then the solidus “/” is always escaped “\/” when serializing JSON
  • If False [default], then it is not escaped.

Note that this option does not affect parsing (both escaped and unescaped are still valid in all cases).

logical(kind=LK), intent(in), optional :: stop_on_error

If an exception is raised, then immediately quit. (Default is False).

integer(kind=IK), intent(in), optional :: null_to_real_mode

if strict_type_checking=false:

  • 1 : an exception will be raised if try to retrieve a null as a real.
  • 2 : a null retrieved as a real will return a NaN. [default]
  • 3 : a null retrieved as a real will return 0.0.
integer(kind=IK), intent(in), optional :: non_normal_mode

How to serialize NaN, Infinity, and -Infinity real values:

  • 1 : as strings (e.g., “NaN”, “Infinity”, “-Infinity”) [default]
  • 2 : as JSON null values
logical(kind=LK), intent(in), optional :: use_quiet_nan
  • If true [default], null_to_real_mode=2 and string_to_real will use ieee_quiet_nan for NaN values.
  • If false, ieee_signaling_nan will be used.
logical(kind=LK), intent(in), optional :: strict_integer_type_checking
  • If false, when parsing JSON, if an integer numeric value cannot be converted to an integer (integer(IK)), then an attempt is then make to convert it to a real (real(RK)).
  • If true, an exception will be raised if the integer value cannot be read.

(default is true)


Calls

proc~~json_initialize~~CallsGraph proc~json_initialize json_core%json_initialize none~throw_exception json_core%throw_exception proc~json_initialize->none~throw_exception proc~integer_to_string integer_to_string proc~json_initialize->proc~integer_to_string proc~json_clear_exceptions json_core%json_clear_exceptions proc~json_initialize->proc~json_clear_exceptions proc~json_throw_exception json_core%json_throw_exception none~throw_exception->proc~json_throw_exception

Called by

proc~~json_initialize~~CalledByGraph proc~json_initialize json_core%json_initialize proc~initialize_json_core initialize_json_core proc~initialize_json_core->proc~json_initialize proc~initialize_json_core_in_file json_file%initialize_json_core_in_file proc~initialize_json_core_in_file->proc~json_initialize proc~json_parse_file json_core%json_parse_file proc~json_parse_file->proc~json_initialize proc~json_parse_string json_core%json_parse_string proc~json_parse_string->proc~json_initialize interface~json_core json_core interface~json_core->proc~initialize_json_core none~deserialize json_core%deserialize none~deserialize->proc~json_parse_string none~initialize~2 json_file%initialize none~initialize~2->proc~initialize_json_core_in_file none~load json_core%load none~load->proc~json_parse_file proc~initialize_json_file initialize_json_file proc~initialize_json_file->none~initialize~2 proc~initialize_json_file_from_string initialize_json_file_from_string proc~initialize_json_file_from_string->none~initialize~2 none~deserialize~2 json_file%deserialize proc~initialize_json_file_from_string->none~deserialize~2 proc~json_file_load json_file%json_file_load proc~json_file_load->none~load proc~json_file_load_from_string json_file%json_file_load_from_string proc~json_file_load_from_string->none~deserialize proc~json_file_move_pointer json_file%json_file_move_pointer proc~json_file_move_pointer->none~initialize~2 proc~wrap_json_parse_string wrap_json_parse_string proc~wrap_json_parse_string->none~deserialize interface~json_file json_file interface~json_file->proc~initialize_json_file interface~json_file->proc~initialize_json_file_from_string proc~initialize_json_file_from_string_v2 initialize_json_file_from_string_v2 interface~json_file->proc~initialize_json_file_from_string_v2 none~deserialize~2->proc~json_file_load_from_string proc~wrap_initialize_json_file_from_string wrap_initialize_json_file_from_string proc~wrap_initialize_json_file_from_string->proc~initialize_json_file_from_string proc~assign_string_to_json_file json_file%assign_string_to_json_file proc~assign_string_to_json_file->none~deserialize~2 proc~initialize_json_file_from_string_v2->none~deserialize~2 proc~wrap_json_file_load_from_string wrap_json_file_load_from_string proc~wrap_json_file_load_from_string->none~deserialize~2 proc~wrap_assign_string_to_json_file wrap_assign_string_to_json_file proc~wrap_assign_string_to_json_file->proc~assign_string_to_json_file proc~wrap_initialize_json_file_from_string_v2 wrap_initialize_json_file_from_string_v2 proc~wrap_initialize_json_file_from_string_v2->proc~initialize_json_file_from_string_v2

Source Code

    subroutine json_initialize(me,&
#include "json_initialize_dummy_arguments.inc"
                              )

    implicit none

    class(json_core),intent(inout)  :: me
#include "json_initialize_arguments.inc"

    character(kind=CDK,len=10) :: w            !! max string length
    character(kind=CDK,len=10) :: d            !! real precision digits
    character(kind=CDK,len=10) :: e            !! real exponent digits
    character(kind=CDK,len=2)  :: sgn          !! sign flag: `ss` or `sp`
    character(kind=CDK,len=2)  :: rl_edit_desc !! `G`, `E`, `EN`, or `ES`
    integer(IK)                :: istat        !! `iostat` flag for
                                               !! write statements
    logical(LK)                :: sgn_prnt     !! print sign flag
    character(kind=CK,len=max_integer_str_len) :: istr !! for integer to
                                                       !! string conversion

    !reset exception to false:
    call me%clear_exceptions()

    !Just in case, clear these global variables also:
    me%pushed_index = 0
    me%pushed_char  = CK_''
    me%char_count   = 0
    me%line_count   = 1
    me%ipos         = 1
    if (use_unformatted_stream) then
        me%filesize = 0
        me%ichunk   = 0
        me%chunk    = repeat(space, stream_chunk_size) ! default chunk size
    end if

#ifdef USE_UCS4
    ! reopen stdout and stderr with utf-8 encoding
    open(output_unit,encoding='utf-8')
    open(error_unit, encoding='utf-8')
#endif

    !various optional inputs:
    if (present(spaces_per_tab)) &
        me%spaces_per_tab = spaces_per_tab
    if (present(stop_on_error)) &
        me%stop_on_error = stop_on_error
    if (present(verbose)) &
        me%is_verbose = verbose
    if (present(strict_type_checking)) &
        me%strict_type_checking = strict_type_checking
    if (present(trailing_spaces_significant)) &
        me%trailing_spaces_significant = trailing_spaces_significant
    if (present(case_sensitive_keys)) &
        me%case_sensitive_keys = case_sensitive_keys
    if (present(no_whitespace)) &
        me%no_whitespace = no_whitespace
    if (present(unescape_strings)) &
        me%unescaped_strings = unescape_strings
    if (present(path_mode)) then
        if (path_mode==1_IK .or. path_mode==2_IK .or. path_mode==3_IK) then
            me%path_mode = path_mode
        else
            me%path_mode = 1_IK  ! just to have a valid value
            call me%throw_exception('Invalid path_mode.')
        end if
    end if

    ! if we are allowing comments in the file:
    ! [an empty string disables comments]
    if (present(comment_char)) then
        me%allow_comments = comment_char/=CK_''
        me%comment_char = trim(adjustl(comment_char))
    end if

    ! path separator:
    if (present(path_separator)) then
        me%path_separator = path_separator
    end if

    ! printing vectors in compressed form:
    if (present(compress_vectors)) then
        me%compress_vectors = compress_vectors
    end if

    ! checking for duplicate keys:
    if (present(allow_duplicate_keys)) then
        me%allow_duplicate_keys = allow_duplicate_keys
    end if

    ! if escaping the forward slash:
    if (present(escape_solidus)) then
        me%escape_solidus = escape_solidus
    end if

    ! how to handle null to real conversions:
    if (present(null_to_real_mode)) then
        select case (null_to_real_mode)
        case(1_IK:3_IK)
            me%null_to_real_mode = null_to_real_mode
        case default
            me%null_to_real_mode = 2_IK  ! just to have a valid value
            call integer_to_string(null_to_real_mode,int_fmt,istr)
            call me%throw_exception('Invalid null_to_real_mode: '//istr)
        end select
    end if

    ! how to handle NaN and Infinities:
    if (present(non_normal_mode)) then
        select case (non_normal_mode)
        case(1_IK) ! use strings
            me%non_normals_to_null = .false.
        case(2_IK) ! use null
            me%non_normals_to_null = .true.
        case default
            call integer_to_string(non_normal_mode,int_fmt,istr)
            call me%throw_exception('Invalid non_normal_mode: '//istr)
        end select
    end if

    if (present(use_quiet_nan)) then
        me%use_quiet_nan = use_quiet_nan
    end if

    if (present(strict_integer_type_checking)) then
        me%strict_integer_type_checking = strict_integer_type_checking
    end if

    !Set the format for real numbers:
    ! [if not changing it, then it remains the same]

    if ( (.not. allocated(me%real_fmt)) .or. &  ! if this hasn't been done yet
          present(compact_reals) .or. &
          present(print_signs)   .or. &
          present(real_format) ) then

        !allow the special case where real format is '*':
        ! [this overrides the other options]
        if (present(real_format)) then
            if (real_format==star) then
                if (present(compact_reals)) then
                    ! we will also allow for compact reals with
                    ! '*' format, if both arguments are present.
                    me%compact_real = compact_reals
                else
                    me%compact_real = .false.
                end if
                me%real_fmt = star
                return
            end if
        end if

        if (present(compact_reals)) me%compact_real = compact_reals

        !set defaults
        sgn_prnt = .false.
        if ( present( print_signs) ) sgn_prnt = print_signs
        if ( sgn_prnt ) then
           sgn = 'sp'
        else
           sgn = 'ss'
        end if

        rl_edit_desc = 'E'
        if ( present( real_format ) ) then
           select case ( real_format )
           case ('g','G','e','E','en','EN','es','ES')
              rl_edit_desc = real_format
           case default
              call me%throw_exception('Invalid real format, "' // &
                        trim(real_format) // '", passed to json_initialize.'// &
                        new_line('a') // 'Acceptable formats are: "G", "E", "EN", and "ES".' )
           end select
        end if

        ! set the default output/input format for reals:
                      write(w,'(ss,I0)',iostat=istat) max_numeric_str_len
        if (istat==0) write(d,'(ss,I0)',iostat=istat) real_precision
        if (istat==0) write(e,'(ss,I0)',iostat=istat) real_exponent_digits
        if (istat==0) then
            me%real_fmt = '(' // sgn // ',' // trim(rl_edit_desc) //&
                            trim(w) // '.' // trim(d) // 'E' // trim(e) // ')'
        else
            me%real_fmt = '(' // sgn // ',' // trim(rl_edit_desc) // &
                            '27.17E4)'  !just use this one (should never happen)
        end if

    end if

    end subroutine json_initialize