@@ -296,10 +296,13 @@ module json_value_module
296
296
procedure ,private :: json_update_string_val_ascii
297
297
#endif
298
298
299
+ procedure ,public :: add_with_path = > json_add_scalar_with_path
300
+
299
301
! >
300
302
! Create a [[json_value]] linked list using the
301
- ! path to the variables
302
- generic,public :: create = > MAYBEWRAP(json_create_by_path) ! this will create a null ...
303
+ ! path to the variables.
304
+ ! (This will create a `null` variable)
305
+ generic,public :: create = > MAYBEWRAP(json_create_by_path)
303
306
procedure :: MAYBEWRAP(json_create_by_path)
304
307
305
308
! >
@@ -2726,25 +2729,83 @@ subroutine json_value_insert_after_child_by_index(json,p,idx,element)
2726
2729
end subroutine json_value_insert_after_child_by_index
2727
2730
! *****************************************************************************************
2728
2731
2729
- ! ... to do .... add the full set of these ...
2732
+
2733
+ ! !*****************************************************************************************
2734
+ ! !>
2735
+ ! ! Add a double value to a [[json_value]], given the path.
2736
+ ! !
2737
+ ! !@warning Using this routine to change the type of an existing object or array to
2738
+ ! ! a scalar may result in a memory leak. It should only be used
2739
+ ! ! to add a new variable (or set an existing one).
2740
+ !
2741
+ ! subroutine json_add_double_with_path(json,me,path,value,found)
2742
+ !
2743
+ ! implicit none
2744
+ !
2745
+ ! class(json_core),intent(inout) :: json
2746
+ ! type(json_value),pointer :: me
2747
+ ! character(kind=CK,len=*),intent(in) :: path
2748
+ ! real(RK),intent(in) :: value
2749
+ ! logical(LK),intent(out),optional :: found
2750
+ !
2751
+ ! type(json_value),pointer :: p
2752
+ !
2753
+ ! if ( .not. json%exception_thrown ) then
2754
+ !
2755
+ ! nullify(p)
2756
+ !
2757
+ ! ! return a pointer to the path (possibly creating it)
2758
+ ! call json%create(me,path,p,found)
2759
+ !
2760
+ ! if (.not. associated(p)) then
2761
+ !
2762
+ ! call json%throw_exception('Error in json_add_double_with_path:'//&
2763
+ ! ' Unable to resolve path: '//trim(path))
2764
+ ! if (present(found)) then
2765
+ ! found = .false.
2766
+ ! call json%clear_exceptions()
2767
+ ! end if
2768
+ !
2769
+ ! else
2770
+ ! ! set the value (may need to change type,
2771
+ ! ! since if it had to be created, it is
2772
+ ! ! a null variable)
2773
+ ! if (p%var_type==json_double) then
2774
+ ! p%dbl_value = value
2775
+ ! else
2776
+ ! call to_double(p,value)
2777
+ ! end if
2778
+ !
2779
+ ! end if
2780
+ !
2781
+ ! else
2782
+ ! if ( present(found) ) found = .false.
2783
+ ! end if
2784
+ !
2785
+ ! end subroutine json_add_double_with_path
2786
+ ! !*****************************************************************************************
2730
2787
2731
2788
! *****************************************************************************************
2732
2789
! >
2733
- ! Add a double value to a [[json_value]], given the path.
2790
+ ! Add a scalar value to a [[json_value]], given the path.
2734
2791
!
2735
2792
! @warning Using this routine to change the type of an existing object or array to
2736
2793
! a scalar may result in a memory leak. It should only be used
2737
2794
! to add a new variable (or set an existing one).
2795
+ !
2796
+ ! @note This is different from the other routines, since we are using
2797
+ ! an unlimited polymorphic input instead of having separate routines.
2738
2798
2739
- subroutine json_add_double_with_path (json ,me ,path ,value ,found )
2799
+ subroutine json_add_scalar_with_path (json ,me ,path ,value ,found , was_created )
2740
2800
2741
2801
implicit none
2742
2802
2743
2803
class(json_core),intent (inout ) :: json
2744
2804
type (json_value),pointer :: me
2745
2805
character (kind= CK,len=* ),intent (in ) :: path
2746
- real (RK ),intent (in ) :: value
2806
+ class( * ),intent (in ) :: value
2747
2807
logical (LK),intent (out ),optional :: found
2808
+ logical (LK),intent (out ),optional :: was_created ! ! if the variable had to be created
2748
2809
2749
2810
type (json_value),pointer :: p
2750
2811
@@ -2753,39 +2814,77 @@ subroutine json_add_double_with_path(json,me,path,value,found)
2753
2814
nullify(p)
2754
2815
2755
2816
! return a pointer to the path (possibly creating it)
2756
- call json% create(me,path,p,found)
2817
+ call json% create(me,path,p,found,was_created )
2757
2818
2758
2819
if (.not. associated (p)) then
2759
2820
2760
- call json% throw_exception(' Error in json_add_double_with_path :' // &
2821
+ call json% throw_exception(' Error in json_add_scalar_with_path :' // &
2761
2822
' Unable to resolve path: ' // trim (path))
2762
2823
if (present (found)) then
2763
2824
found = .false.
2764
2825
call json% clear_exceptions()
2765
2826
end if
2766
2827
2767
2828
else
2829
+
2768
2830
! set the value (may need to change type,
2769
2831
! since if it had to be created, it is
2770
2832
! a null variable)
2771
- if (p% var_type== json_double) then
2772
- p% dbl_value = value
2773
- else
2774
- call to_double(p,value)
2775
- end if
2833
+ select type (value)
2834
+ type is (real (RK))
2835
+ if (p% var_type== json_double) then
2836
+ p% dbl_value = value
2837
+ else
2838
+ call to_double(p,value)
2839
+ end if
2840
+ type is (integer (IK))
2841
+ if (p% var_type== json_integer) then
2842
+ p% int_value = value
2843
+ else
2844
+ call to_integer(p,value)
2845
+ end if
2846
+ type is (character (kind= CK,len=* ))
2847
+ if (p% var_type== json_string) then
2848
+ p% str_value = value
2849
+ else
2850
+ call to_string(p,value)
2851
+ end if
2852
+ #if defined __GFORTRAN__ && defined USE_UCS4
2853
+ type is (character (kind= CDK,len=* ))
2854
+ ! only if using unicode
2855
+ if (p% var_type== json_string) then
2856
+ p% str_value = to_unicode(value)
2857
+ else
2858
+ call to_string(p,to_unicode(value))
2859
+ end if
2860
+ #endif
2861
+ type is (logical (kind= LK))
2862
+ if (p% var_type== json_logical) then
2863
+ p% log_value = value
2864
+ else
2865
+ call to_logical(p,value)
2866
+ end if
2867
+ class default
2868
+ call json% throw_exception(' Error in json_add_scalar_with_path:' // &
2869
+ ' Invalid input type' )
2870
+ if (present (found)) then
2871
+ found = .false.
2872
+ call json% clear_exceptions()
2873
+ end if
2874
+ end select
2776
2875
2777
2876
end if
2778
2877
2779
2878
else
2780
- if ( present (found) ) found = .false.
2879
+ if ( present (found) ) found = .false.
2880
+ if ( present (was_created) ) was_created = .false.
2781
2881
end if
2782
2882
2783
- end subroutine json_add_double_with_path
2883
+ end subroutine json_add_scalar_with_path
2784
2884
! *****************************************************************************************
2785
2885
2786
2886
2787
2887
2788
-
2789
2888
! *****************************************************************************************
2790
2889
! > author: Jacob Williams
2791
2890
! date: 1/19/2014
@@ -4064,27 +4163,37 @@ end subroutine json_get_by_path
4064
4163
! ### See also
4065
4164
! * [[json_get_by_path]]
4066
4165
4067
- subroutine json_create_by_path (json , me , path , p , found )
4166
+ subroutine json_create_by_path (json ,me ,path ,p , found , was_created )
4068
4167
4069
4168
implicit none
4070
4169
4071
4170
class(json_core),intent (inout ) :: json
4072
- type (json_value),pointer ,intent (in ) :: me ! ! a JSON linked list
4073
- character (kind= CK,len=* ),intent (in ) :: path ! ! path to the variable
4074
- type (json_value),pointer ,intent (out ) :: p ! ! pointer to the variable
4075
- ! ! specify by `path`
4076
- logical (LK),intent (out ),optional :: found ! ! true if it was found
4077
- ! ! ...TODO found should indicate if the variable was already there.
4078
- ! ! another logical output should indicate success.
4171
+ type (json_value),pointer ,intent (in ) :: me ! ! a JSON linked list
4172
+ character (kind= CK,len=* ),intent (in ) :: path ! ! path to the variable
4173
+ type (json_value),pointer ,intent (out ),optional :: p ! ! pointer to the variable
4174
+ ! ! specify by `path`
4175
+ logical (LK),intent (out ),optional :: found ! ! true if there were no errors
4176
+ ! ! (variable found or created)
4177
+ logical (LK),intent (out ),optional :: was_created ! ! true if it was actually created
4178
+ ! ! (as opposed to already being there)
4079
4179
4080
- ! note: it can only be 1 or 2 (which was checked in initialize)
4180
+ type (json_value),pointer :: tmp
4181
+
4182
+ if (present (p)) nullify(p)
4183
+
4184
+ ! note: path_mode can only be 1 or 2 (which was checked in initialize)
4081
4185
select case (json% path_mode)
4082
4186
case (1_IK )
4083
- call json% json_get_by_path_default(me, path, p, found, create_it= .true. )
4187
+ call json% json_get_by_path_default(me,path,tmp,found,&
4188
+ create_it= .true. ,&
4189
+ was_created= was_created)
4190
+ if (present (p)) p = > tmp
4084
4191
case (2_IK )
4085
4192
! the problem here is there isn't really a way to disambiguate
4086
4193
! the array elements, so '/a/0' could be 'a(1)' or 'a.0'.
4087
- call json% throw_exception(' Create by path not suppored in RFC 6901 path mode.' )
4194
+ call json% throw_exception(' Create by path not supported in RFC 6901 path mode.' )
4195
+ if (present (found)) found = .false.
4196
+ if (present (was_created)) was_created = .false.
4088
4197
end select
4089
4198
4090
4199
end subroutine json_create_by_path
@@ -4094,7 +4203,7 @@ end subroutine json_create_by_path
4094
4203
! >
4095
4204
! Alternate version of [[json_create_by_path]] where "path" is kind=CDK.
4096
4205
4097
- subroutine wrap_json_create_by_path (json , me , path , p , found )
4206
+ subroutine wrap_json_create_by_path (json ,me ,path ,p , found , was_created )
4098
4207
4099
4208
implicit none
4100
4209
@@ -4103,8 +4212,9 @@ subroutine wrap_json_create_by_path(json, me, path, p, found)
4103
4212
character (kind= CDK,len=* ),intent (in ) :: path
4104
4213
type (json_value),pointer ,intent (out ) :: p
4105
4214
logical (LK),intent (out ),optional :: found
4215
+ logical (LK),intent (out ),optional :: was_created
4106
4216
4107
- call json% get (me, to_unicode(path), p, found)
4217
+ call json% create (me,to_unicode(path),p, found,was_created )
4108
4218
4109
4219
end subroutine wrap_json_create_by_path
4110
4220
! *****************************************************************************************
@@ -4145,21 +4255,25 @@ end subroutine wrap_json_create_by_path
4145
4255
! converted to null once all the variables have been created (user would have
4146
4256
! had to do this).
4147
4257
4148
- subroutine json_get_by_path_default (json , me , path , p , found , create_it )
4258
+ subroutine json_get_by_path_default (json ,me ,path ,p , found ,create_it , was_created )
4149
4259
4150
4260
implicit none
4151
4261
4152
4262
class(json_core),intent (inout ) :: json
4153
- type (json_value),pointer ,intent (in ) :: me ! ! a JSON linked list
4154
- character (kind= CK,len=* ),intent (in ) :: path ! ! path to the variable
4155
- type (json_value),pointer ,intent (out ) :: p ! ! pointer to the variable
4156
- ! ! specify by `path`
4157
- logical (LK),intent (out ),optional :: found ! ! true if it was found
4158
- logical (LK),intent (in ),optional :: create_it ! ! if a variable is not present
4159
- ! ! in the path, then it is created.
4160
- ! ! the leaf node is returned as
4161
- ! ! a `null` json type and can be
4162
- ! ! changed by the caller.
4263
+ type (json_value),pointer ,intent (in ) :: me ! ! a JSON linked list
4264
+ character (kind= CK,len=* ),intent (in ) :: path ! ! path to the variable
4265
+ type (json_value),pointer ,intent (out ) :: p ! ! pointer to the variable
4266
+ ! ! specify by `path`
4267
+ logical (LK),intent (out ),optional :: found ! ! true if it was found
4268
+ logical (LK),intent (in ),optional :: create_it ! ! if a variable is not present
4269
+ ! ! in the path, then it is created.
4270
+ ! ! the leaf node is returned as
4271
+ ! ! a `null` json type and can be
4272
+ ! ! changed by the caller.
4273
+ logical (LK),intent (out ),optional :: was_created ! ! if `create_it` is true, this
4274
+ ! ! will be true if the variable
4275
+ ! ! was actually created. Otherwise
4276
+ ! ! it will be false.
4163
4277
4164
4278
integer (IK) :: i ! ! counter of characters in `path`
4165
4279
integer (IK) :: length ! ! significant length of `path`
@@ -4228,14 +4342,13 @@ subroutine json_get_by_path_default(json, me, path, p, found, create_it)
4228
4342
nullify(tmp)
4229
4343
if (create) then
4230
4344
4231
- !
4232
4345
! Example:
4233
4346
! 'aaa.bbb(1)'
4234
4347
! -> and aaa is a null, need to make it an object
4235
4348
!
4236
4349
! What about the case: aaa.bbb(1)(3) ?
4237
4350
! Is that already handled?
4238
- !
4351
+
4239
4352
if (p% var_type== json_null) then
4240
4353
! if p was also created, then we need to
4241
4354
! convert it into an object here:
@@ -4251,7 +4364,6 @@ subroutine json_get_by_path_default(json, me, path, p, found, create_it)
4251
4364
call to_array(tmp,path(child_i:i-1 ))
4252
4365
call json% add(p,tmp)
4253
4366
created = .true.
4254
- ! write(*,*) 'creating: '//path(child_i:i-1)
4255
4367
else
4256
4368
created = .false.
4257
4369
end if
@@ -4336,22 +4448,14 @@ subroutine json_get_by_path_default(json, me, path, p, found, create_it)
4336
4448
p% var_type = json_object
4337
4449
end if
4338
4450
! don't want to throw exceptions in this case
4339
- ! write(*,*) 'calling get_child...'
4340
4451
call json% get_child(p, path(child_i:i-1 ), tmp, child_found)
4341
- ! if (child_found) then
4342
- ! write(*,*) path(child_i:i-1)//' found'
4343
- ! else
4344
- ! write(*,*) path(child_i:i-1)//' not found'
4345
- ! end if
4346
-
4347
4452
if (.not. child_found) then
4348
4453
! have to create this child
4349
4454
! [make it an object]
4350
4455
call json_value_create(tmp)
4351
4456
call to_object(tmp,path(child_i:i-1 ))
4352
4457
call json% add(p,tmp)
4353
4458
created = .true.
4354
- ! write(*,*) 'creating: '//path(child_i:i-1)
4355
4459
else
4356
4460
created = .false.
4357
4461
end if
@@ -4398,26 +4502,21 @@ subroutine json_get_by_path_default(json, me, path, p, found, create_it)
4398
4502
! convert it into an object here:
4399
4503
p% var_type = json_object
4400
4504
end if
4401
- ! write(*,*) 'grab the last child: '//path(child_i:i-1)
4402
4505
call json% get_child(p, path(child_i:i-1 ), tmp, child_found)
4403
4506
if (.not. child_found) then
4404
- ! write(*,*) 'not found.'
4405
- ! write(*,*) 'creating: '//path(child_i:i-1)
4406
4507
! have to create this child
4407
4508
! (make it a null since it is the leaf)
4408
4509
call json_value_create(tmp)
4409
4510
call to_null(tmp,path(child_i:i-1 ))
4410
4511
call json% add(p,tmp)
4411
4512
created = .true.
4412
4513
else
4413
- ! write(*,*) 'found.'
4414
4514
created = .false.
4415
4515
end if
4416
4516
else
4417
4517
! call the normal way
4418
4518
call json% get_child(p, path(child_i:i-1 ), tmp)
4419
4519
end if
4420
- ! if (.not. associated(tmp)) write(*,*) '!!! tmp not associated !!!'
4421
4520
p = > tmp
4422
4521
else
4423
4522
! we already have p
@@ -4442,8 +4541,12 @@ subroutine json_get_by_path_default(json, me, path, p, found, create_it)
4442
4541
4443
4542
end if
4444
4543
4544
+ ! if it had to be created:
4545
+ if (present (was_created)) was_created = created
4546
+
4445
4547
else
4446
4548
if (present (found)) found = .false.
4549
+ if (present (was_created)) was_created = .false.
4447
4550
end if
4448
4551
4449
4552
end subroutine json_get_by_path_default
0 commit comments