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)

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

Arguments

Type IntentOptional AttributesName
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=1), intent(in), optional :: comment_char

If present, this character is 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: * 1 – Default mode (see json_get_by_path_default) * 2 – as RFC 6901 “JSON Pointer” paths (see json_get_by_path_rfc6901) * 3 – JSONPath “bracket-notation” see json_get_by_path_jsonpath_bracket)

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).


Contents

Source Code


Source Code

    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)

    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

    !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 = 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

    !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