summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
blob: f0ea7c90dcac82f1fb78be38b440cc54c08fd0d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562

/* Execute compiled code */

/* XXX TO DO:
   XXX speed up searching for keywords by using a dictionary
   XXX document it!
   */

/* enable more aggressive intra-module optimizations, where available */
#define PY_LOCAL_AGGRESSIVE

#include "Python.h"

#include "code.h"
#include "frameobject.h"
#include "opcode.h"
#include "structmember.h"

#include <ctype.h>

#ifndef WITH_TSC

#define READ_TIMESTAMP(var)

#else

typedef unsigned long long uint64;

/* PowerPC support.
   "__ppc__" appears to be the preprocessor definition to detect on OS X, whereas
   "__powerpc__" appears to be the correct one for Linux with GCC
*/
#if defined(__ppc__) || defined (__powerpc__)

#define READ_TIMESTAMP(var) ppc_getcounter(&var)

static void
ppc_getcounter(uint64 *v)
{
    register unsigned long tbu, tb, tbu2;

  loop:
    asm volatile ("mftbu %0" : "=r" (tbu) );
    asm volatile ("mftb  %0" : "=r" (tb)  );
    asm volatile ("mftbu %0" : "=r" (tbu2));
    if (__builtin_expect(tbu != tbu2, 0)) goto loop;

    /* The slightly peculiar way of writing the next lines is
       compiled better by GCC than any other way I tried. */
    ((long*)(v))[0] = tbu;
    ((long*)(v))[1] = tb;
}

#elif defined(__i386__)

/* this is for linux/x86 (and probably any other GCC/x86 combo) */

#define READ_TIMESTAMP(val) \
     __asm__ __volatile__("rdtsc" : "=A" (val))

#elif defined(__x86_64__)

/* for gcc/x86_64, the "A" constraint in DI mode means *either* rax *or* rdx;
   not edx:eax as it does for i386.  Since rdtsc puts its result in edx:eax
   even in 64-bit mode, we need to use "a" and "d" for the lower and upper
   32-bit pieces of the result. */

#define READ_TIMESTAMP(val) \
    __asm__ __volatile__("rdtsc" : \
                         "=a" (((int*)&(val))[0]), "=d" (((int*)&(val))[1]));


#else

#error "Don't know how to implement timestamp counter for this architecture"

#endif

void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
              uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
{
    uint64 intr, inst, loop;
    PyThreadState *tstate = PyThreadState_Get();
    if (!tstate->interp->tscdump)
        return;
    intr = intr1 - intr0;
    inst = inst1 - inst0 - intr;
    loop = loop1 - loop0 - intr;
    fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
            opcode, ticked, inst, loop);
}

#endif

/* Turn this on if your compiler chokes on the big switch: */
/* #define CASE_TOO_BIG 1 */

#ifdef Py_DEBUG
/* For debugging the interpreter: */
#define LLTRACE  1      /* Low-level trace feature */
#define CHECKEXC 1      /* Double-check exception checking */
#endif

typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);

/* Forward declarations */
#ifdef WITH_TSC
static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
#else
static PyObject * call_function(PyObject ***, int);
#endif
static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
static PyObject * do_call(PyObject *, PyObject ***, int, int);
static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
static PyObject * update_keyword_args(PyObject *, int, PyObject ***,
                                      PyObject *);
static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
static PyObject * load_args(PyObject ***, int);
#define CALL_FLAG_VAR 1
#define CALL_FLAG_KW 2

#ifdef LLTRACE
static int lltrace;
static int prtrace(PyObject *, char *);
#endif
static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
                      int, PyObject *);
static int call_trace_protected(Py_tracefunc, PyObject *,
                                PyFrameObject *, int, PyObject *);
static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
                                 PyFrameObject *, int *, int *, int *);

static PyObject * cmp_outcome(int, PyObject *, PyObject *);
static PyObject * import_from(PyObject *, PyObject *);
static int import_all_from(PyObject *, PyObject *);
static void format_exc_check_arg(PyObject *, const char *, PyObject *);
static void format_exc_unbound(PyCodeObject *co, int oparg);
static PyObject * unicode_concatenate(PyObject *, PyObject *,
                                      PyFrameObject *, unsigned char *);
static PyObject * special_lookup(PyObject *, char *, PyObject **);

#define NAME_ERROR_MSG \
    "name '%.200s' is not defined"
#define GLOBAL_NAME_ERROR_MSG \
    "global name '%.200s' is not defined"
#define UNBOUNDLOCAL_ERROR_MSG \
    "local variable '%.200s' referenced before assignment"
#define UNBOUNDFREE_ERROR_MSG \
    "free variable '%.200s' referenced before assignment" \
    " in enclosing scope"

/* Dynamic execution profile */
#ifdef DYNAMIC_EXECUTION_PROFILE
#ifdef DXPAIRS
static long dxpairs[257][256];
#define dxp dxpairs[256]
#else
static long dxp[256];
#endif
#endif

/* Function call profile */
#ifdef CALL_PROFILE
#define PCALL_NUM 11
static int pcall[PCALL_NUM];

#define PCALL_ALL 0
#define PCALL_FUNCTION 1
#define PCALL_FAST_FUNCTION 2
#define PCALL_FASTER_FUNCTION 3
#define PCALL_METHOD 4
#define PCALL_BOUND_METHOD 5
#define PCALL_CFUNCTION 6
#define PCALL_TYPE 7
#define PCALL_GENERATOR 8
#define PCALL_OTHER 9
#define PCALL_POP 10

/* Notes about the statistics

   PCALL_FAST stats

   FAST_FUNCTION means no argument tuple needs to be created.
   FASTER_FUNCTION means that the fast-path frame setup code is used.

   If there is a method call where the call can be optimized by changing
   the argument tuple and calling the function directly, it gets recorded
   twice.

   As a result, the relationship among the statistics appears to be
   PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
                PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
   PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
   PCALL_METHOD > PCALL_BOUND_METHOD
*/

#define PCALL(POS) pcall[POS]++

PyObject *
PyEval_GetCallStats(PyObject *self)
{
    return Py_BuildValue("iiiiiiiiiii",
                         pcall[0], pcall[1], pcall[2], pcall[3],
                         pcall[4], pcall[5], pcall[6], pcall[7],
                         pcall[8], pcall[9], pcall[10]);
}
#else
#define PCALL(O)

PyObject *
PyEval_GetCallStats(PyObject *self)
{
    Py_INCREF(Py_None);
    return Py_None;
}
#endif


#ifdef WITH_THREAD
#define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
#else
#define GIL_REQUEST 0
#endif

/* This can set eval_breaker to 0 even though gil_drop_request became
   1.  We believe this is all right because the eval loop will release
   the GIL eventually anyway. */
#define COMPUTE_EVAL_BREAKER() \
    _Py_atomic_store_relaxed( \
        &eval_breaker, \
        GIL_REQUEST | \
        _Py_atomic_load_relaxed(&pendingcalls_to_do) | \
        pending_async_exc)

#ifdef WITH_THREAD

#define SET_GIL_DROP_REQUEST() \
    do { \
        _Py_atomic_store_relaxed(&gil_drop_request, 1); \
        _Py_atomic_store_relaxed(&eval_breaker, 1); \
    } while (0)

#define RESET_GIL_DROP_REQUEST() \
    do { \
        _Py_atomic_store_relaxed(&gil_drop_request, 0); \
        COMPUTE_EVAL_BREAKER(); \
    } while (0)

#endif

/* Pending calls are only modified under pending_lock */
#define SIGNAL_PENDING_CALLS() \
    do { \
        _Py_atomic_store_relaxed(&pendingcalls_to_do, 1); \
        _Py_atomic_store_relaxed(&eval_breaker, 1); \
    } while (0)

#define UNSIGNAL_PENDING_CALLS() \
    do { \
        _Py_atomic_store_relaxed(&pendingcalls_to_do, 0); \
        COMPUTE_EVAL_BREAKER(); \
    } while (0)

#define SIGNAL_ASYNC_EXC() \
    do { \
        pending_async_exc = 1; \
        _Py_atomic_store_relaxed(&eval_breaker, 1); \
    } while (0)

#define UNSIGNAL_ASYNC_EXC() \
    do { pending_async_exc = 0; COMPUTE_EVAL_BREAKER(); } while (0)


#ifdef WITH_THREAD

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "pythread.h"

static PyThread_type_lock pending_lock = 0; /* for pending calls */
static long main_thread = 0;
/* This single variable consolidates all requests to break out of the fast path
   in the eval loop. */
static _Py_atomic_int eval_breaker = {0};
/* Request for dropping the GIL */
static _Py_atomic_int gil_drop_request = {0};
/* Request for running pending calls. */
static _Py_atomic_int pendingcalls_to_do = {0};
/* Request for looking at the `async_exc` field of the current thread state.
   Guarded by the GIL. */
static int pending_async_exc = 0;

#include "ceval_gil.h"

int
PyEval_ThreadsInitialized(void)
{
    return gil_created();
}

void
PyEval_InitThreads(void)
{
    if (gil_created())
        return;
    create_gil();
    take_gil(PyThreadState_GET());
    main_thread = PyThread_get_thread_ident();
    if (!pending_lock)
        pending_lock = PyThread_allocate_lock();
}

void
_PyEval_FiniThreads(void)
{
    if (!gil_created())
        return;
    destroy_gil();
    assert(!gil_created());
}

void
PyEval_AcquireLock(void)
{
    PyThreadState *tstate = PyThreadState_GET();
    if (tstate == NULL)
        Py_FatalError("PyEval_AcquireLock: current thread state is NULL");
    take_gil(tstate);
}

void
PyEval_ReleaseLock(void)
{
    /* This function must succeed when the current thread state is NULL.
       We therefore avoid PyThreadState_GET() which dumps a fatal error
       in debug mode.
    */
    drop_gil((PyThreadState*)_Py_atomic_load_relaxed(
        &_PyThreadState_Current));
}

void
PyEval_AcquireThread(PyThreadState *tstate)
{
    if (tstate == NULL)
        Py_FatalError("PyEval_AcquireThread: NULL new thread state");
    /* Check someone has called PyEval_InitThreads() to create the lock */
    assert(gil_created());
    take_gil(tstate);
    if (PyThreadState_Swap(tstate) != NULL)
        Py_FatalError(
            "PyEval_AcquireThread: non-NULL old thread state");
}

void
PyEval_ReleaseThread(PyThreadState *tstate)
{
    if (tstate == NULL)
        Py_FatalError("PyEval_ReleaseThread: NULL thread state");
    if (PyThreadState_Swap(NULL) != tstate)
        Py_FatalError("PyEval_ReleaseThread: wrong thread state");
    drop_gil(tstate);
}

/* This function is called from PyOS_AfterFork to ensure that newly
   created child processes don't hold locks referring to threads which
   are not running in the child process.  (This could also be done using
   pthread_atfork mechanism, at least for the pthreads implementation.) */

void
PyEval_ReInitThreads(void)
{
    PyObject *threading, *result;
    PyThreadState *tstate = PyThreadState_GET();

    if (!gil_created())
        return;
    recreate_gil();
    pending_lock = PyThread_allocate_lock();
    take_gil(tstate);
    main_thread = PyThread_get_thread_ident();

    /* Update the threading module with the new state.
     */
    tstate = PyThreadState_GET();
    threading = PyMapping_GetItemString(tstate->interp->modules,
                                        "threading");
    if (threading == NULL) {
        /* threading not imported */
        PyErr_Clear();
        return;
    }
    result = PyObject_CallMethod(threading, "_after_fork", NULL);
    if (result == NULL)
        PyErr_WriteUnraisable(threading);
    else
        Py_DECREF(result);
    Py_DECREF(threading);
}

#else
static _Py_atomic_int eval_breaker = {0};
static int pending_async_exc = 0;
#endif /* WITH_THREAD */

/* This function is used to signal that async exceptions are waiting to be
   raised, therefore it is also useful in non-threaded builds. */

void
_PyEval_SignalAsyncExc(void)
{
    SIGNAL_ASYNC_EXC();
}

/* Functions save_thread and restore_thread are always defined so
   dynamically loaded modules needn't be compiled separately for use
   with and without threads: */

PyThreadState *
PyEval_SaveThread(void)
{
    PyThreadState *tstate = PyThreadState_Swap(NULL);
    if (tstate == NULL)
        Py_FatalError("PyEval_SaveThread: NULL tstate");
#ifdef WITH_THREAD
    if (gil_created())
        drop_gil(tstate);
#endif
    return tstate;
}

void
PyEval_RestoreThread(PyThreadState *tstate)
{
    if (tstate == NULL)
        Py_FatalError("PyEval_RestoreThread: NULL tstate");
#ifdef WITH_THREAD
    if (gil_created()) {
        int err = errno;
        take_gil(tstate);
        /* _Py_Finalizing is protected by the GIL */
        if (_Py_Finalizing && tstate != _Py_Finalizing) {
            drop_gil(tstate);
            PyThread_exit_thread();
            assert(0);  /* unreachable */
        }
        errno = err;
    }
#endif
    PyThreadState_Swap(tstate);
}


/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
   signal handlers or Mac I/O completion routines) can schedule calls
   to a function to be called synchronously.
   The synchronous function is called with one void* argument.
   It should return 0 for success or -1 for failure -- failure should
   be accompanied by an exception.

   If registry succeeds, the registry function returns 0; if it fails
   (e.g. due to too many pending calls) it returns -1 (without setting
   an exception condition).

   Note that because registry may occur from within signal handlers,
   or other asynchronous events, calling malloc() is unsafe!

#ifdef WITH_THREAD
   Any thread can schedule pending calls, but only the main thread
   will execute them.
   There is no facility to schedule calls to a particular thread, but
   that should be easy to change, should that ever be required.  In
   that case, the static variables here should go into the python
   threadstate.
#endif
*/

#ifdef WITH_THREAD

/* The WITH_THREAD implementation is thread-safe.  It allows
   scheduling to be made from any thread, and even from an executing
   callback.
 */

#define NPENDINGCALLS 32
static struct {
    int (*func)(void *);
    void *arg;
} pendingcalls[NPENDINGCALLS];
static int pendingfirst = 0;
static int pendinglast = 0;
static char pendingbusy = 0;

int
Py_AddPendingCall(int (*func)(void *), void *arg)
{
    int i, j, result=0;
    PyThread_type_lock lock = pending_lock;

    /* try a few times for the lock.  Since this mechanism is used
     * for signal handling (on the main thread), there is a (slim)
     * chance that a signal is delivered on the same thread while we
     * hold the lock during the Py_MakePendingCalls() function.
     * This avoids a deadlock in that case.
     * Note that signals can be delivered on any thread.  In particular,
     * on Windows, a SIGINT is delivered on a system-created worker
     * thread.
     * We also check for lock being NULL, in the unlikely case that
     * this function is called before any bytecode evaluation takes place.
     */
    if (lock != NULL) {
        for (i = 0; i<100; i++) {
            if (PyThread_acquire_lock(lock, NOWAIT_LOCK))
                break;
        }
        if (i == 100)
            return -1;
    }

    i = pendinglast;
    j = (i + 1) % NPENDINGCALLS;
    if (j == pendingfirst) {
        result = -1; /* Queue full */
    } else {
        pendingcalls[i].func = func;
        pendingcalls[i].arg = arg;
        pendinglast = j;
    }
    /* signal main loop */
    SIGNAL_PENDING_CALLS();
    if (lock != NULL)
        PyThread_release_lock(lock);
    return result;
}

int
Py_MakePendingCalls(void)
{
    int i;
    int r = 0;

    if (!pending_lock) {
        /* initial allocation of the lock */
        pending_lock = PyThread_allocate_lock();
        if (pending_lock == NULL)
            return -1;
    }

    /* only service pending calls on main thread */
    if (main_thread && PyThread_get_thread_ident() != main_thread)
        return 0;
    /* don't perform recursive pending calls */
    if (pendingbusy)
        return 0;
    pendingbusy = 1;
    /* perform a bounded number of calls, in case of recursion */
    for (i=0; i<NPENDINGCALLS; i++) {
        int j;
        int (*func)(void *);
        void *arg = NULL;

        /* pop one item off the queue while holding the lock */
        PyThread_acquire_lock(pending_lock, WAIT_LOCK);
        j = pendingfirst;
        if (j == pendinglast) {
            func = NULL; /* Queue empty */
        } else {
            func = pendingcalls[j].func;
            arg = pendingcalls[j].arg;
            pendingfirst = (j + 1) % NPENDINGCALLS;
        }
        if (pendingfirst != pendinglast)
            SIGNAL_PENDING_CALLS();
        else
            UNSIGNAL_PENDING_CALLS();
        PyThread_release_lock(pending_lock);
        /* having released the lock, perform the callback */
        if (func == NULL)
            break;
        r = func(arg);
        if (r)
            break;
    }
    pendingbusy = 0;
    return r;
}

#else /* if ! defined WITH_THREAD */

/*
   WARNING!  ASYNCHRONOUSLY EXECUTING CODE!
   This code is used for signal handling in python that isn't built
   with WITH_THREAD.
   Don't use this implementation when Py_AddPendingCalls() can happen
   on a different thread!

   There are two possible race conditions:
   (1) nested asynchronous calls to Py_AddPendingCall()
   (2) AddPendingCall() calls made while pending calls are being processed.

   (1) is very unlikely because typically signal delivery
   is blocked during signal handling.  So it should be impossible.
   (2) is a real possibility.
   The current code is safe against (2), but not against (1).
   The safety against (2) is derived from the fact that only one
   thread is present, interrupted by signals, and that the critical
   section is protected with the "busy" variable.  On Windows, which
   delivers SIGINT on a system thread, this does not hold and therefore
   Windows really shouldn't use this version.
   The two threads could theoretically wiggle around the "busy" variable.
*/

#define NPENDINGCALLS 32
static struct {
    int (*func)(void *);
    void *arg;
} pendingcalls[NPENDINGCALLS];
static volatile int pendingfirst = 0;
static volatile int pendinglast = 0;
static _Py_atomic_int pendingcalls_to_do = {0};

int
Py_AddPendingCall(int (*func)(void *), void *arg)
{
    static volatile int busy = 0;
    int i, j;
    /* XXX Begin critical section */
    if (busy)
        return -1;
    busy = 1;
    i = pendinglast;
    j = (i + 1) % NPENDINGCALLS;
    if (j == pendingfirst) {
        busy = 0;
        return -1; /* Queue full */
    }
    pendingcalls[i].func = func;
    pendingcalls[i].arg = arg;
    pendinglast = j;

    SIGNAL_PENDING_CALLS();
    busy = 0;
    /* XXX End critical section */
    return 0;
}

int
Py_MakePendingCalls(void)
{
    static int busy = 0;
    if (busy)
        return 0;
    busy = 1;
    UNSIGNAL_PENDING_CALLS();
    for (;;) {
        int i;
        int (*func)(void *);
        void *arg;
        i = pendingfirst;
        if (i == pendinglast)
            break; /* Queue empty */
        func = pendingcalls[i].func;
        arg = pendingcalls[i].arg;
        pendingfirst = (i + 1) % NPENDINGCALLS;
        if (func(arg) < 0) {
            busy = 0;
            SIGNAL_PENDING_CALLS(); /* We're not done yet */
            return -1;
        }
    }
    busy = 0;
    return 0;
}

#endif /* WITH_THREAD */


/* The interpreter's recursion limit */

#ifndef Py_DEFAULT_RECURSION_LIMIT
#define Py_DEFAULT_RECURSION_LIMIT 1000
#endif
static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;

int
Py_GetRecursionLimit(void)
{
    return recursion_limit;
}

void
Py_SetRecursionLimit(int new_limit)
{
    recursion_limit = new_limit;
    _Py_CheckRecursionLimit = recursion_limit;
}

/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
   if the recursion_depth reaches _Py_CheckRecursionLimit.
   If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
   to guarantee that _Py_CheckRecursiveCall() is regularly called.
   Without USE_STACKCHECK, there is no need for this. */
int
_Py_CheckRecursiveCall(char *where)
{
    PyThreadState *tstate = PyThreadState_GET();

#ifdef USE_STACKCHECK
    if (PyOS_CheckStack()) {
        --tstate->recursion_depth;
        PyErr_SetString(PyExc_MemoryError, "Stack overflow");
        return -1;
    }
#endif
    _Py_CheckRecursionLimit = recursion_limit;
    if (tstate->recursion_critical)
        /* Somebody asked that we don't check for recursion. */
        return 0;
    if (tstate->overflowed) {
        if (tstate->recursion_depth > recursion_limit + 50) {
            /* Overflowing while handling an overflow. Give up. */
            Py_FatalError("Cannot recover from stack overflow.");
        }
        return 0;
    }
    if (tstate->recursion_depth > recursion_limit) {
        --tstate->recursion_depth;
        tstate->overflowed = 1;
        PyErr_Format(PyExc_RuntimeError,
                     "maximum recursion depth exceeded%s",
                     where);
        return -1;
    }
    return 0;
}

/* Status code for main loop (reason for stack unwind) */
enum why_code {
        WHY_NOT =       0x0001, /* No error */
        WHY_EXCEPTION = 0x0002, /* Exception occurred */
        WHY_RERAISE =   0x0004, /* Exception re-raised by 'finally' */
        WHY_RETURN =    0x0008, /* 'return' statement */
        WHY_BREAK =     0x0010, /* 'break' statement */
        WHY_CONTINUE =  0x0020, /* 'continue' statement */
        WHY_YIELD =     0x0040, /* 'yield' operator */
        WHY_SILENCED =  0x0080  /* Exception silenced by 'with' */
};

static enum why_code do_raise(PyObject *, PyObject *);
static int unpack_iterable(PyObject *, int, int, PyObject **);

/* Records whether tracing is on for any thread.  Counts the number of
   threads for which tstate->c_tracefunc is non-NULL, so if the value
   is 0, we know we don't have to check this thread's c_tracefunc.
   This speeds up the if statement in PyEval_EvalFrameEx() after
   fast_next_opcode*/
static int _Py_TracingPossible = 0;



PyObject *
PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
{
    return PyEval_EvalCodeEx(co,
                      globals, locals,
                      (PyObject **)NULL, 0,
                      (PyObject **)NULL, 0,
                      (PyObject **)NULL, 0,
                      NULL, NULL);
}


/* Interpreter main loop */

PyObject *
PyEval_EvalFrame(PyFrameObject *f) {
    /* This is for backward compatibility with extension modules that
       used this API; core interpreter code should call
       PyEval_EvalFrameEx() */
    return PyEval_EvalFrameEx(f, 0);
}

PyObject *
PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
{
#ifdef DXPAIRS
    int lastopcode = 0;
#endif
    register PyObject **stack_pointer;  /* Next free slot in value stack */
    register unsigned char *next_instr;
    register int opcode;        /* Current opcode */
    register int oparg;         /* Current opcode argument, if any */
    register enum why_code why; /* Reason for block stack unwind */
    register int err;           /* Error status -- nonzero if error */
    register PyObject *x;       /* Result object -- NULL if error */
    register PyObject *v;       /* Temporary objects popped off stack */
    register PyObject *w;
    register PyObject *u;
    register PyObject *t;
    register PyObject **fastlocals, **freevars;
    PyObject *retval = NULL;            /* Return value */
    PyThreadState *tstate = PyThreadState_GET();
    PyCodeObject *co;

    /* when tracing we set things up so that

           not (instr_lb <= current_bytecode_offset < instr_ub)

       is true when the line being executed has changed.  The
       initial values are such as to make this false the first
       time it is tested. */
    int instr_ub = -1, instr_lb = 0, instr_prev = -1;

    unsigned char *first_instr;
    PyObject *names;
    PyObject *consts;
#if defined(Py_DEBUG) || defined(LLTRACE)
    /* Make it easier to find out where we are with a debugger */
    char *filename;
#endif

/* Computed GOTOs, or
       the-optimization-commonly-but-improperly-known-as-"threaded code"
   using gcc's labels-as-values extension
   (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html).

   The traditional bytecode evaluation loop uses a "switch" statement, which
   decent compilers will optimize as a single indirect branch instruction
   combined with a lookup table of jump addresses. However, since the
   indirect jump instruction is shared by all opcodes, the CPU will have a
   hard time making the right prediction for where to jump next (actually,
   it will be always wrong except in the uncommon case of a sequence of
   several identical opcodes).

   "Threaded code" in contrast, uses an explicit jump table and an explicit
   indirect jump instruction at the end of each opcode. Since the jump
   instruction is at a different address for each opcode, the CPU will make a
   separate prediction for each of these instructions, which is equivalent to
   predicting the second opcode of each opcode pair. These predictions have
   a much better chance to turn out valid, especially in small bytecode loops.

   A mispredicted branch on a modern CPU flushes the whole pipeline and
   can cost several CPU cycles (depending on the pipeline depth),
   and potentially many more instructions (depending on the pipeline width).
   A correctly predicted branch, however, is nearly free.

   At the time of this writing, the "threaded code" version is up to 15-20%
   faster than the normal "switch" version, depending on the compiler and the
   CPU architecture.

   We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined,
   because it would render the measurements invalid.


   NOTE: care must be taken that the compiler doesn't try to "optimize" the
   indirect jumps by sharing them between all opcodes. Such optimizations
   can be disabled on gcc by using the -fno-gcse flag (or possibly
   -fno-crossjumping).
*/

#ifdef DYNAMIC_EXECUTION_PROFILE
#undef USE_COMPUTED_GOTOS
#define USE_COMPUTED_GOTOS 0
#endif

#ifdef HAVE_COMPUTED_GOTOS
    #ifndef USE_COMPUTED_GOTOS
    #define USE_COMPUTED_GOTOS 1
    #endif
#else
    #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS
    #error "Computed gotos are not supported on this compiler."
    #endif
    #undef USE_COMPUTED_GOTOS
    #define USE_COMPUTED_GOTOS 0
#endif

#if USE_COMPUTED_GOTOS
/* Import the static jump table */
#include "opcode_targets.h"

/* This macro is used when several opcodes defer to the same implementation
   (e.g. SETUP_LOOP, SETUP_FINALLY) */
#define TARGET_WITH_IMPL(op, impl) \
    TARGET_##op: \
        opcode = op; \
        if (HAS_ARG(op)) \
            oparg = NEXTARG(); \
    case op: \
        goto impl; \

#define TARGET(op) \
    TARGET_##op: \
        opcode = op; \
        if (HAS_ARG(op)) \
            oparg = NEXTARG(); \
    case op:


#define DISPATCH() \
    { \
        if (!_Py_atomic_load_relaxed(&eval_breaker)) {      \
                    FAST_DISPATCH(); \
        } \
        continue; \
    }

#ifdef LLTRACE
#define FAST_DISPATCH() \
    { \
        if (!lltrace && !_Py_TracingPossible) { \
            f->f_lasti = INSTR_OFFSET(); \
            goto *opcode_targets[*next_instr++]; \
        } \
        goto fast_next_opcode; \
    }
#else
#define FAST_DISPATCH() \
    { \
        if (!_Py_TracingPossible) { \
            f->f_lasti = INSTR_OFFSET(); \
            goto *opcode_targets[*next_instr++]; \
        } \
        goto fast_next_opcode; \
    }
#endif

#else
#define TARGET(op) \
    case op:
#define TARGET_WITH_IMPL(op, impl) \
    /* silence compiler warnings about `impl` unused */ \
    if (0) goto impl; \
    case op:
#define DISPATCH() continue
#define FAST_DISPATCH() goto fast_next_opcode
#endif


/* Tuple access macros */

#ifndef Py_DEBUG
#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
#else
#define GETITEM(v, i) PyTuple_GetItem((v), (i))
#endif

#ifdef WITH_TSC
/* Use Pentium timestamp counter to mark certain events:
   inst0 -- beginning of switch statement for opcode dispatch
   inst1 -- end of switch statement (may be skipped)
   loop0 -- the top of the mainloop
   loop1 -- place where control returns again to top of mainloop
            (may be skipped)
   intr1 -- beginning of long interruption
   intr2 -- end of long interruption

   Many opcodes call out to helper C functions.  In some cases, the
   time in those functions should be counted towards the time for the
   opcode, but not in all cases.  For example, a CALL_FUNCTION opcode
   calls another Python function; there's no point in charge all the
   bytecode executed by the called function to the caller.

   It's hard to make a useful judgement statically.  In the presence
   of operator overloading, it's impossible to tell if a call will
   execute new Python code or not.

   It's a case-by-case judgement.  I'll use intr1 for the following
   cases:

   IMPORT_STAR
   IMPORT_FROM
   CALL_FUNCTION (and friends)

 */
    uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
    int ticked = 0;

    READ_TIMESTAMP(inst0);
    READ_TIMESTAMP(inst1);
    READ_TIMESTAMP(loop0);
    READ_TIMESTAMP(loop1);

    /* shut up the compiler */
    opcode = 0;
#endif

/* Code access macros */

#define INSTR_OFFSET()  ((int)(next_instr - first_instr))
#define NEXTOP()        (*next_instr++)
#define NEXTARG()       (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define PEEKARG()       ((next_instr[2]<<8) + next_instr[1])
#define JUMPTO(x)       (next_instr = first_instr + (x))
#define JUMPBY(x)       (next_instr += (x))

/* OpCode prediction macros
    Some opcodes tend to come in pairs thus making it possible to
    predict the second code when the first is run.  For example,
    COMPARE_OP is often followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And,
    those opcodes are often followed by a POP_TOP.

    Verifying the prediction costs a single high-speed test of a register
    variable against a constant.  If the pairing was good, then the
    processor's own internal branch predication has a high likelihood of
    success, resulting in a nearly zero-overhead transition to the
    next opcode.  A successful prediction saves a trip through the eval-loop
    including its two unpredictable branches, the HAS_ARG test and the
    switch-case.  Combined with the processor's internal branch prediction,
    a successful PREDICT has the effect of making the two opcodes run as if
    they were a single new opcode with the bodies combined.

    If collecting opcode statistics, your choices are to either keep the
    predictions turned-on and interpret the results as if some opcodes
    had been combined or turn-off predictions so that the opcode frequency
    counter updates for both opcodes.

    Opcode prediction is disabled with threaded code, since the latter allows
    the CPU to record separate branch prediction information for each
    opcode.

*/

#if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS
#define PREDICT(op)             if (0) goto PRED_##op
#define PREDICTED(op)           PRED_##op:
#define PREDICTED_WITH_ARG(op)  PRED_##op:
#else
#define PREDICT(op)             if (*next_instr == op) goto PRED_##op
#define PREDICTED(op)           PRED_##op: next_instr++
#define PREDICTED_WITH_ARG(op)  PRED_##op: oparg = PEEKARG(); next_instr += 3
#endif


/* Stack manipulation macros */

/* The stack can grow at most MAXINT deep, as co_nlocals and
   co_stacksize are ints. */
#define STACK_LEVEL()     ((int)(stack_pointer - f->f_valuestack))
#define EMPTY()           (STACK_LEVEL() == 0)
#define TOP()             (stack_pointer[-1])
#define SECOND()          (stack_pointer[-2])
#define THIRD()           (stack_pointer[-3])
#define FOURTH()          (stack_pointer[-4])
#define PEEK(n)           (stack_pointer[-(n)])
#define SET_TOP(v)        (stack_pointer[-1] = (v))
#define SET_SECOND(v)     (stack_pointer[-2] = (v))
#define SET_THIRD(v)      (stack_pointer[-3] = (v))
#define SET_FOURTH(v)     (stack_pointer[-4] = (v))
#define SET_VALUE(n, v)   (stack_pointer[-(n)] = (v))
#define BASIC_STACKADJ(n) (stack_pointer += n)
#define BASIC_PUSH(v)     (*stack_pointer++ = (v))
#define BASIC_POP()       (*--stack_pointer)

#ifdef LLTRACE
#define PUSH(v)         { (void)(BASIC_PUSH(v), \
                          lltrace && prtrace(TOP(), "push")); \
                          assert(STACK_LEVEL() <= co->co_stacksize); }
#define POP()           ((void)(lltrace && prtrace(TOP(), "pop")), \
                         BASIC_POP())
#define STACKADJ(n)     { (void)(BASIC_STACKADJ(n), \
                          lltrace && prtrace(TOP(), "stackadj")); \
                          assert(STACK_LEVEL() <= co->co_stacksize); }
#define EXT_POP(STACK_POINTER) ((void)(lltrace && \
                                prtrace((STACK_POINTER)[-1], "ext_pop")), \
                                *--(STACK_POINTER))
#else
#define PUSH(v)                BASIC_PUSH(v)
#define POP()                  BASIC_POP()
#define STACKADJ(n)            BASIC_STACKADJ(n)
#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
#endif

/* Local variable macros */

#define GETLOCAL(i)     (fastlocals[i])

/* The SETLOCAL() macro must not DECREF the local variable in-place and
   then store the new value; it must copy the old value to a temporary
   value, then store the new value, and then DECREF the temporary value.
   This is because it is possible that during the DECREF the frame is
   accessed by other code (e.g. a __del__ method or gc.collect()) and the
   variable would be pointing to already-freed memory. */
#define SETLOCAL(i, value)      do { PyObject *tmp = GETLOCAL(i); \
                                     GETLOCAL(i) = value; \
                                     Py_XDECREF(tmp); } while (0)


#define UNWIND_BLOCK(b) \
    while (STACK_LEVEL() > (b)->b_level) { \
        PyObject *v = POP(); \
        Py_XDECREF(v); \
    }

#define UNWIND_EXCEPT_HANDLER(b) \
    { \
        PyObject *type, *value, *traceback; \
        assert(STACK_LEVEL() >= (b)->b_level + 3); \
        while (STACK_LEVEL() > (b)->b_level + 3) { \
            value = POP(); \
            Py_XDECREF(value); \
        } \
        type = tstate->exc_type; \
        value = tstate->exc_value; \
        traceback = tstate->exc_traceback; \
        tstate->exc_type = POP(); \
        tstate->exc_value = POP(); \
        tstate->exc_traceback = POP(); \
        Py_XDECREF(type); \
        Py_XDECREF(value); \
        Py_XDECREF(traceback); \
    }

#define SAVE_EXC_STATE() \
    { \
        PyObject *type, *value, *traceback; \
        Py_XINCREF(tstate->exc_type); \
        Py_XINCREF(tstate->exc_value); \
        Py_XINCREF(tstate->exc_traceback); \
        type = f->f_exc_type; \
        value = f->f_exc_value; \
        traceback = f->f_exc_traceback; \
        f->f_exc_type = tstate->exc_type; \
        f->f_exc_value = tstate->exc_value; \
        f->f_exc_traceback = tstate->exc_traceback; \
        Py_XDECREF(type); \
        Py_XDECREF(value); \
        Py_XDECREF(traceback); \
    }

#define SWAP_EXC_STATE() \
    { \
        PyObject *tmp; \
        tmp = tstate->exc_type; \
        tstate->exc_type = f->f_exc_type; \
        f->f_exc_type = tmp; \
        tmp = tstate->exc_value; \
        tstate->exc_value = f->f_exc_value; \
        f->f_exc_value = tmp; \
        tmp = tstate->exc_traceback; \
        tstate->exc_traceback = f->f_exc_traceback; \
        f->f_exc_traceback = tmp; \
    }

#define RESTORE_AND_CLEAR_EXC_STATE() \
    { \
        PyObject *type, *value, *tb; \
        type = tstate->exc_type; \
        value = tstate->exc_value; \
        tb = tstate->exc_traceback; \
        tstate->exc_type = f->f_exc_type; \
        tstate->exc_value = f->f_exc_value; \
        tstate->exc_traceback = f->f_exc_traceback; \
        f->f_exc_type = NULL; \
        f->f_exc_value = NULL; \
        f->f_exc_traceback = NULL; \
        Py_XDECREF(type); \
        Py_XDECREF(value); \
        Py_XDECREF(tb); \
    }

/* Start of code */

    if (f == NULL)
        return NULL;

    /* push frame */
    if (Py_EnterRecursiveCall(""))
        return NULL;

    tstate->frame = f;

    if (tstate->use_tracing) {
        if (tstate->c_tracefunc != NULL) {
            /* tstate->c_tracefunc, if defined, is a
               function that will be called on *every* entry
               to a code block.  Its return value, if not
               None, is a function that will be called at
               the start of each executed line of code.
               (Actually, the function must return itself
               in order to continue tracing.)  The trace
               functions are called with three arguments:
               a pointer to the current frame, a string
               indicating why the function is called, and
               an argument which depends on the situation.
               The global trace function is also called
               whenever an exception is detected. */
            if (call_trace_protected(tstate->c_tracefunc,
                                     tstate->c_traceobj,
                                     f, PyTrace_CALL, Py_None)) {
                /* Trace function raised an error */
                goto exit_eval_frame;
            }
        }
        if (tstate->c_profilefunc != NULL) {
            /* Similar for c_profilefunc, except it needn't
               return itself and isn't called for "line" events */
            if (call_trace_protected(tstate->c_profilefunc,
                                     tstate->c_profileobj,
                                     f, PyTrace_CALL, Py_None)) {
                /* Profile function raised an error */
                goto exit_eval_frame;
            }
        }
    }

    co = f->f_code;
    names = co->co_names;
    consts = co->co_consts;
    fastlocals = f->f_localsplus;
    freevars = f->f_localsplus + co->co_nlocals;
    first_instr = (unsigned char*) PyBytes_AS_STRING(co->co_code);
    /* An explanation is in order for the next line.

       f->f_lasti now refers to the index of the last instruction
       executed.  You might think this was obvious from the name, but
       this wasn't always true before 2.3!  PyFrame_New now sets
       f->f_lasti to -1 (i.e. the index *before* the first instruction)
       and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
       does work.  Promise.

       When the PREDICT() macros are enabled, some opcode pairs follow in
       direct succession without updating f->f_lasti.  A successful
       prediction effectively links the two codes together as if they
       were a single new opcode; accordingly,f->f_lasti will point to
       the first code in the pair (for instance, GET_ITER followed by
       FOR_ITER is effectively a single opcode and f->f_lasti will point
       at to the beginning of the combined pair.)
    */
    next_instr = first_instr + f->f_lasti + 1;
    stack_pointer = f->f_stacktop;
    assert(stack_pointer != NULL);
    f->f_stacktop = NULL;       /* remains NULL unless yield suspends frame */

    if (co->co_flags & CO_GENERATOR && !throwflag) {
        if (f->f_exc_type != NULL && f->f_exc_type != Py_None) {
            /* We were in an except handler when we left,
               restore the exception state which was put aside
               (see YIELD_VALUE). */
            SWAP_EXC_STATE();
        }
        else {
            SAVE_EXC_STATE();
        }
    }

#ifdef LLTRACE
    lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
#endif
#if defined(Py_DEBUG) || defined(LLTRACE)
    {
        PyObject *error_type, *error_value, *error_traceback;
        PyErr_Fetch(&error_type, &error_value, &error_traceback);
        filename = _PyUnicode_AsString(co->co_filename);
        if (filename == NULL && tstate->overflowed) {
            /* maximum recursion depth exceeded */
            goto exit_eval_frame;
        }
        PyErr_Restore(error_type, error_value, error_traceback);
    }
#endif

    why = WHY_NOT;
    err = 0;
    x = Py_None;        /* Not a reference, just anything non-NULL */
    w = NULL;

    if (throwflag) { /* support for generator.throw() */
        why = WHY_EXCEPTION;
        goto on_error;
    }

    for (;;) {
#ifdef WITH_TSC
        if (inst1 == 0) {
            /* Almost surely, the opcode executed a break
               or a continue, preventing inst1 from being set
               on the way out of the loop.
            */
            READ_TIMESTAMP(inst1);
            loop1 = inst1;
        }
        dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
                 intr0, intr1);
        ticked = 0;
        inst1 = 0;
        intr0 = 0;
        intr1 = 0;
        READ_TIMESTAMP(loop0);
#endif
        assert(stack_pointer >= f->f_valuestack); /* else underflow */
        assert(STACK_LEVEL() <= co->co_stacksize);  /* else overflow */

        /* Do periodic things.  Doing this every time through
           the loop would add too much overhead, so we do it
           only every Nth instruction.  We also do it if
           ``pendingcalls_to_do'' is set, i.e. when an asynchronous
           event needs attention (e.g. a signal handler or
           async I/O handler); see Py_AddPendingCall() and
           Py_MakePendingCalls() above. */

        if (_Py_atomic_load_relaxed(&eval_breaker)) {
            if (*next_instr == SETUP_FINALLY) {
                /* Make the last opcode before
                   a try: finally: block uninterruptible. */
                goto fast_next_opcode;
            }
            tstate->tick_counter++;
#ifdef WITH_TSC
            ticked = 1;
#endif
            if (_Py_atomic_load_relaxed(&pendingcalls_to_do)) {
                if (Py_MakePendingCalls() < 0) {
                    why = WHY_EXCEPTION;
                    goto on_error;
                }
            }
#ifdef WITH_THREAD
            if (_Py_atomic_load_relaxed(&gil_drop_request)) {
                /* Give another thread a chance */
                if (PyThreadState_Swap(NULL) != tstate)
                    Py_FatalError("ceval: tstate mix-up");
                drop_gil(tstate);

                /* Other threads may run now */

                take_gil(tstate);
                if (PyThreadState_Swap(tstate) != NULL)
                    Py_FatalError("ceval: orphan tstate");
            }
#endif
            /* Check for asynchronous exceptions. */
            if (tstate->async_exc != NULL) {
                x = tstate->async_exc;
                tstate->async_exc = NULL;
                UNSIGNAL_ASYNC_EXC();
                PyErr_SetNone(x);
                Py_DECREF(x);
                why = WHY_EXCEPTION;
                goto on_error;
            }
        }

    fast_next_opcode:
        f->f_lasti = INSTR_OFFSET();

        /* line-by-line tracing support */

        if (_Py_TracingPossible &&
            tstate->c_tracefunc != NULL && !tstate->tracing) {
            /* see maybe_call_line_trace
               for expository comments */
            f->f_stacktop = stack_pointer;

            err = maybe_call_line_trace(tstate->c_tracefunc,
                                        tstate->c_traceobj,
                                        f, &instr_lb, &instr_ub,
                                        &instr_prev);
            /* Reload possibly changed frame fields */
            JUMPTO(f->f_lasti);
            if (f->f_stacktop != NULL) {
                stack_pointer = f->f_stacktop;
                f->f_stacktop = NULL;
            }
            if (err) {
                /* trace function raised an exception */
                goto on_error;
            }
        }

        /* Extract opcode and argument */

        opcode = NEXTOP();
        oparg = 0;   /* allows oparg to be stored in a register because
            it doesn't have to be remembered across a full loop */
        if (HAS_ARG(opcode))
            oparg = NEXTARG();
    dispatch_opcode:
#ifdef DYNAMIC_EXECUTION_PROFILE
#ifdef DXPAIRS
        dxpairs[lastopcode][opcode]++;
        lastopcode = opcode;
#endif
        dxp[opcode]++;
#endif

#ifdef LLTRACE
        /* Instruction tracing */

        if (lltrace) {
            if (HAS_ARG(opcode)) {
                printf("%d: %d, %d\n",
                       f->f_lasti, opcode, oparg);
            }
            else {
                printf("%d: %d\n",
                       f->f_lasti, opcode);
            }
        }
#endif

        /* Main switch on opcode */
        READ_TIMESTAMP(inst0);

        switch (opcode) {

        /* BEWARE!
           It is essential that any operation that fails sets either
           x to NULL, err to nonzero, or why to anything but WHY_NOT,
           and that no operation that succeeds does this! */

        /* case STOP_CODE: this is an error! */

        TARGET(NOP)
            FAST_DISPATCH();

        TARGET(LOAD_FAST)
            x = GETLOCAL(oparg);
            if (x != NULL) {
                Py_INCREF(x);
                PUSH(x);
                FAST_DISPATCH();
            }
            format_exc_check_arg(PyExc_UnboundLocalError,
                UNBOUNDLOCAL_ERROR_MSG,
                PyTuple_GetItem(co->co_varnames, oparg));
            break;

        TARGET(LOAD_CONST)
            x = GETITEM(consts, oparg);
            Py_INCREF(x);
            PUSH(x);
            FAST_DISPATCH();

        PREDICTED_WITH_ARG(STORE_FAST);
        TARGET(STORE_FAST)
            v = POP();
            SETLOCAL(oparg, v);
            FAST_DISPATCH();

        TARGET(POP_TOP)
            v = POP();
            Py_DECREF(v);
            FAST_DISPATCH();

        TARGET(ROT_TWO)
            v = TOP();
            w = SECOND();
            SET_TOP(w);
            SET_SECOND(v);
            FAST_DISPATCH();

        TARGET(ROT_THREE)
            v = TOP();
            w = SECOND();
            x = THIRD();
            SET_TOP(w);
            SET_SECOND(x);
            SET_THIRD(v);
            FAST_DISPATCH();

        TARGET(DUP_TOP)
            v = TOP();
            Py_INCREF(v);
            PUSH(v);
            FAST_DISPATCH();

        TARGET(DUP_TOP_TWO)
            x = TOP();
            Py_INCREF(x);
            w = SECOND();
            Py_INCREF(w);
            STACKADJ(2);
            SET_TOP(x);
            SET_SECOND(w);
            FAST_DISPATCH();

        TARGET(UNARY_POSITIVE)
            v = TOP();
            x = PyNumber_Positive(v);
            Py_DECREF(v);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(UNARY_NEGATIVE)
            v = TOP();
            x = PyNumber_Negative(v);
            Py_DECREF(v);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(UNARY_NOT)
            v = TOP();
            err = PyObject_IsTrue(v);
            Py_DECREF(v);
            if (err == 0) {
                Py_INCREF(Py_True);
                SET_TOP(Py_True);
                DISPATCH();
            }
            else if (err > 0) {
                Py_INCREF(Py_False);
                SET_TOP(Py_False);
                err = 0;
                DISPATCH();
            }
            STACKADJ(-1);
            break;

        TARGET(UNARY_INVERT)
            v = TOP();
            x = PyNumber_Invert(v);
            Py_DECREF(v);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_POWER)
            w = POP();
            v = TOP();
            x = PyNumber_Power(v, w, Py_None);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_MULTIPLY)
            w = POP();
            v = TOP();
            x = PyNumber_Multiply(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_TRUE_DIVIDE)
            w = POP();
            v = TOP();
            x = PyNumber_TrueDivide(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_FLOOR_DIVIDE)
            w = POP();
            v = TOP();
            x = PyNumber_FloorDivide(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_MODULO)
            w = POP();
            v = TOP();
            if (PyUnicode_CheckExact(v))
                x = PyUnicode_Format(v, w);
            else
                x = PyNumber_Remainder(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_ADD)
            w = POP();
            v = TOP();
            if (PyUnicode_CheckExact(v) &&
                     PyUnicode_CheckExact(w)) {
                x = unicode_concatenate(v, w, f, next_instr);
                /* unicode_concatenate consumed the ref to v */
                goto skip_decref_vx;
            }
            else {
                x = PyNumber_Add(v, w);
            }
            Py_DECREF(v);
          skip_decref_vx:
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_SUBTRACT)
            w = POP();
            v = TOP();
            x = PyNumber_Subtract(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_SUBSCR)
            w = POP();
            v = TOP();
            x = PyObject_GetItem(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_LSHIFT)
            w = POP();
            v = TOP();
            x = PyNumber_Lshift(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_RSHIFT)
            w = POP();
            v = TOP();
            x = PyNumber_Rshift(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_AND)
            w = POP();
            v = TOP();
            x = PyNumber_And(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_XOR)
            w = POP();
            v = TOP();
            x = PyNumber_Xor(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(BINARY_OR)
            w = POP();
            v = TOP();
            x = PyNumber_Or(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(LIST_APPEND)
            w = POP();
            v = PEEK(oparg);
            err = PyList_Append(v, w);
            Py_DECREF(w);
            if (err == 0) {
                PREDICT(JUMP_ABSOLUTE);
                DISPATCH();
            }
            break;

        TARGET(SET_ADD)
            w = POP();
            v = stack_pointer[-oparg];
            err = PySet_Add(v, w);
            Py_DECREF(w);
            if (err == 0) {
                PREDICT(JUMP_ABSOLUTE);
                DISPATCH();
            }
            break;

        TARGET(INPLACE_POWER)
            w = POP();
            v = TOP();
            x = PyNumber_InPlacePower(v, w, Py_None);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_MULTIPLY)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceMultiply(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_TRUE_DIVIDE)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceTrueDivide(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_FLOOR_DIVIDE)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceFloorDivide(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_MODULO)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceRemainder(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_ADD)
            w = POP();
            v = TOP();
            if (PyUnicode_CheckExact(v) &&
                     PyUnicode_CheckExact(w)) {
                x = unicode_concatenate(v, w, f, next_instr);
                /* unicode_concatenate consumed the ref to v */
                goto skip_decref_v;
            }
            else {
                x = PyNumber_InPlaceAdd(v, w);
            }
            Py_DECREF(v);
          skip_decref_v:
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_SUBTRACT)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceSubtract(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_LSHIFT)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceLshift(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_RSHIFT)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceRshift(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_AND)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceAnd(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_XOR)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceXor(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(INPLACE_OR)
            w = POP();
            v = TOP();
            x = PyNumber_InPlaceOr(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(STORE_SUBSCR)
            w = TOP();
            v = SECOND();
            u = THIRD();
            STACKADJ(-3);
            /* v[w] = u */
            err = PyObject_SetItem(v, w, u);
            Py_DECREF(u);
            Py_DECREF(v);
            Py_DECREF(w);
            if (err == 0) DISPATCH();
            break;

        TARGET(DELETE_SUBSCR)
            w = TOP();
            v = SECOND();
            STACKADJ(-2);
            /* del v[w] */
            err = PyObject_DelItem(v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            if (err == 0) DISPATCH();
            break;

        TARGET(PRINT_EXPR)
            v = POP();
            w = PySys_GetObject("displayhook");
            if (w == NULL) {
                PyErr_SetString(PyExc_RuntimeError,
                                "lost sys.displayhook");
                err = -1;
                x = NULL;
            }
            if (err == 0) {
                x = PyTuple_Pack(1, v);
                if (x == NULL)
                    err = -1;
            }
            if (err == 0) {
                w = PyEval_CallObject(w, x);
                Py_XDECREF(w);
                if (w == NULL)
                    err = -1;
            }
            Py_DECREF(v);
            Py_XDECREF(x);
            break;

#ifdef CASE_TOO_BIG
        default: switch (opcode) {
#endif
        TARGET(RAISE_VARARGS)
            v = w = NULL;
            switch (oparg) {
            case 2:
                v = POP(); /* cause */
            case 1:
                w = POP(); /* exc */
            case 0: /* Fallthrough */
                why = do_raise(w, v);
                break;
            default:
                PyErr_SetString(PyExc_SystemError,
                           "bad RAISE_VARARGS oparg");
                why = WHY_EXCEPTION;
                break;
            }
            break;

        TARGET(STORE_LOCALS)
            x = POP();
            v = f->f_locals;
            Py_XDECREF(v);
            f->f_locals = x;
            DISPATCH();

        TARGET(RETURN_VALUE)
            retval = POP();
            why = WHY_RETURN;
            goto fast_block_end;

        TARGET(YIELD_VALUE)
            retval = POP();
            f->f_stacktop = stack_pointer;
            why = WHY_YIELD;
            goto fast_yield;

        TARGET(POP_EXCEPT)
            {
                PyTryBlock *b = PyFrame_BlockPop(f);
                if (b->b_type != EXCEPT_HANDLER) {
                    PyErr_SetString(PyExc_SystemError,
                        "popped block is not an except handler");
                    why = WHY_EXCEPTION;
                    break;
                }
                UNWIND_EXCEPT_HANDLER(b);
            }
            DISPATCH();

        TARGET(POP_BLOCK)
            {
                PyTryBlock *b = PyFrame_BlockPop(f);
                UNWIND_BLOCK(b);
            }
            DISPATCH();

        PREDICTED(END_FINALLY);
        TARGET(END_FINALLY)
            v = POP();
            if (PyLong_Check(v)) {
                why = (enum why_code) PyLong_AS_LONG(v);
                assert(why != WHY_YIELD);
                if (why == WHY_RETURN ||
                    why == WHY_CONTINUE)
                    retval = POP();
                if (why == WHY_SILENCED) {
                    /* An exception was silenced by 'with', we must
                    manually unwind the EXCEPT_HANDLER block which was
                    created when the exception was caught, otherwise
                    the stack will be in an inconsistent state. */
                    PyTryBlock *b = PyFrame_BlockPop(f);
                    assert(b->b_type == EXCEPT_HANDLER);
                    UNWIND_EXCEPT_HANDLER(b);
                    why = WHY_NOT;
                }
            }
            else if (PyExceptionClass_Check(v)) {
                w = POP();
                u = POP();
                PyErr_Restore(v, w, u);
                why = WHY_RERAISE;
                break;
            }
            else if (v != Py_None) {
                PyErr_SetString(PyExc_SystemError,
                    "'finally' pops bad exception");
                why = WHY_EXCEPTION;
            }
            Py_DECREF(v);
            break;

        TARGET(LOAD_BUILD_CLASS)
            x = PyDict_GetItemString(f->f_builtins,
                                     "__build_class__");
            if (x == NULL) {
                PyErr_SetString(PyExc_ImportError,
                                "__build_class__ not found");
                break;
            }
            Py_INCREF(x);
            PUSH(x);
            break;

        TARGET(STORE_NAME)
            w = GETITEM(names, oparg);
            v = POP();
            if ((x = f->f_locals) != NULL) {
                if (PyDict_CheckExact(x))
                    err = PyDict_SetItem(x, w, v);
                else
                    err = PyObject_SetItem(x, w, v);
                Py_DECREF(v);
                if (err == 0) DISPATCH();
                break;
            }
            PyErr_Format(PyExc_SystemError,
                         "no locals found when storing %R", w);
            break;

        TARGET(DELETE_NAME)
            w = GETITEM(names, oparg);
            if ((x = f->f_locals) != NULL) {
                if ((err = PyObject_DelItem(x, w)) != 0)
                    format_exc_check_arg(PyExc_NameError,
                                         NAME_ERROR_MSG,
                                         w);
                break;
            }
            PyErr_Format(PyExc_SystemError,
                         "no locals when deleting %R", w);
            break;

        PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
        TARGET(UNPACK_SEQUENCE)
            v = POP();
            if (PyTuple_CheckExact(v) &&
                PyTuple_GET_SIZE(v) == oparg) {
                PyObject **items = \
                    ((PyTupleObject *)v)->ob_item;
                while (oparg--) {
                    w = items[oparg];
                    Py_INCREF(w);
                    PUSH(w);
                }
                Py_DECREF(v);
                DISPATCH();
            } else if (PyList_CheckExact(v) &&
                       PyList_GET_SIZE(v) == oparg) {
                PyObject **items = \
                    ((PyListObject *)v)->ob_item;
                while (oparg--) {
                    w = items[oparg];
                    Py_INCREF(w);
                    PUSH(w);
                }
            } else if (unpack_iterable(v, oparg, -1,
                                       stack_pointer + oparg)) {
                STACKADJ(oparg);
            } else {
                /* unpack_iterable() raised an exception */
                why = WHY_EXCEPTION;
            }
            Py_DECREF(v);
            break;

        TARGET(UNPACK_EX)
        {
            int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
            v = POP();

            if (unpack_iterable(v, oparg & 0xFF, oparg >> 8,
                                stack_pointer + totalargs)) {
                stack_pointer += totalargs;
            } else {
                why = WHY_EXCEPTION;
            }
            Py_DECREF(v);
            break;
        }

        TARGET(STORE_ATTR)
            w = GETITEM(names, oparg);
            v = TOP();
            u = SECOND();
            STACKADJ(-2);
            err = PyObject_SetAttr(v, w, u); /* v.w = u */
            Py_DECREF(v);
            Py_DECREF(u);
            if (err == 0) DISPATCH();
            break;

        TARGET(DELETE_ATTR)
            w = GETITEM(names, oparg);
            v = POP();
            err = PyObject_SetAttr(v, w, (PyObject *)NULL);
                                            /* del v.w */
            Py_DECREF(v);
            break;

        TARGET(STORE_GLOBAL)
            w = GETITEM(names, oparg);
            v = POP();
            err = PyDict_SetItem(f->f_globals, w, v);
            Py_DECREF(v);
            if (err == 0) DISPATCH();
            break;

        TARGET(DELETE_GLOBAL)
            w = GETITEM(names, oparg);
            if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
                format_exc_check_arg(
                    PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
            break;

        TARGET(LOAD_NAME)
            w = GETITEM(names, oparg);
            if ((v = f->f_locals) == NULL) {
                PyErr_Format(PyExc_SystemError,
                             "no locals when loading %R", w);
                why = WHY_EXCEPTION;
                break;
            }
            if (PyDict_CheckExact(v)) {
                x = PyDict_GetItem(v, w);
                Py_XINCREF(x);
            }
            else {
                x = PyObject_GetItem(v, w);
                if (x == NULL && PyErr_Occurred()) {
                    if (!PyErr_ExceptionMatches(
                                    PyExc_KeyError))
                        break;
                    PyErr_Clear();
                }
            }
            if (x == NULL) {
                x = PyDict_GetItem(f->f_globals, w);
                if (x == NULL) {
                    x = PyDict_GetItem(f->f_builtins, w);
                    if (x == NULL) {
                        format_exc_check_arg(
                                    PyExc_NameError,
                                    NAME_ERROR_MSG, w);
                        break;
                    }
                }
                Py_INCREF(x);
            }
            PUSH(x);
            DISPATCH();

        TARGET(LOAD_GLOBAL)
            w = GETITEM(names, oparg);
            if (PyUnicode_CheckExact(w)) {
                /* Inline the PyDict_GetItem() calls.
                   WARNING: this is an extreme speed hack.
                   Do not try this at home. */
                Py_hash_t hash = ((PyUnicodeObject *)w)->hash;
                if (hash != -1) {
                    PyDictObject *d;
                    PyDictEntry *e;
                    d = (PyDictObject *)(f->f_globals);
                    e = d->ma_lookup(d, w, hash);
                    if (e == NULL) {
                        x = NULL;
                        break;
                    }
                    x = e->me_value;
                    if (x != NULL) {
                        Py_INCREF(x);
                        PUSH(x);
                        DISPATCH();
                    }
                    d = (PyDictObject *)(f->f_builtins);
                    e = d->ma_lookup(d, w, hash);
                    if (e == NULL) {
                        x = NULL;
                        break;
                    }
                    x = e->me_value;
                    if (x != NULL) {
                        Py_INCREF(x);
                        PUSH(x);
                        DISPATCH();
                    }
                    goto load_global_error;
                }
            }
            /* This is the un-inlined version of the code above */
            x = PyDict_GetItem(f->f_globals, w);
            if (x == NULL) {
                x = PyDict_GetItem(f->f_builtins, w);
                if (x == NULL) {
                  load_global_error:
                    format_exc_check_arg(
                                PyExc_NameError,
                                GLOBAL_NAME_ERROR_MSG, w);
                    break;
                }
            }
            Py_INCREF(x);
            PUSH(x);
            DISPATCH();

        TARGET(DELETE_FAST)
            x = GETLOCAL(oparg);
            if (x != NULL) {
                SETLOCAL(oparg, NULL);
                DISPATCH();
            }
            format_exc_check_arg(
                PyExc_UnboundLocalError,
                UNBOUNDLOCAL_ERROR_MSG,
                PyTuple_GetItem(co->co_varnames, oparg)
                );
            break;

        TARGET(DELETE_DEREF)
            x = freevars[oparg];
            if (PyCell_GET(x) != NULL) {
                PyCell_Set(x, NULL);
                DISPATCH();
            }
            err = -1;
            format_exc_unbound(co, oparg);
            break;

        TARGET(LOAD_CLOSURE)
            x = freevars[oparg];
            Py_INCREF(x);
            PUSH(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(LOAD_DEREF)
            x = freevars[oparg];
            w = PyCell_Get(x);
            if (w != NULL) {
                PUSH(w);
                DISPATCH();
            }
            err = -1;
            format_exc_unbound(co, oparg);
            break;

        TARGET(STORE_DEREF)
            w = POP();
            x = freevars[oparg];
            PyCell_Set(x, w);
            Py_DECREF(w);
            DISPATCH();

        TARGET(BUILD_TUPLE)
            x = PyTuple_New(oparg);
            if (x != NULL) {
                for (; --oparg >= 0;) {
                    w = POP();
                    PyTuple_SET_ITEM(x, oparg, w);
                }
                PUSH(x);
                DISPATCH();
            }
            break;

        TARGET(BUILD_LIST)
            x =  PyList_New(oparg);
            if (x != NULL) {
                for (; --oparg >= 0;) {
                    w = POP();
                    PyList_SET_ITEM(x, oparg, w);
                }
                PUSH(x);
                DISPATCH();
            }
            break;

        TARGET(BUILD_SET)
            x = PySet_New(NULL);
            if (x != NULL) {
                for (; --oparg >= 0;) {
                    w = POP();
                    if (err == 0)
                        err = PySet_Add(x, w);
                    Py_DECREF(w);
                }
                if (err != 0) {
                    Py_DECREF(x);
                    break;
                }
                PUSH(x);
                DISPATCH();
            }
            break;

        TARGET(BUILD_MAP)
            x = _PyDict_NewPresized((Py_ssize_t)oparg);
            PUSH(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(STORE_MAP)
            w = TOP();     /* key */
            u = SECOND();  /* value */
            v = THIRD();   /* dict */
            STACKADJ(-2);
            assert (PyDict_CheckExact(v));
            err = PyDict_SetItem(v, w, u);  /* v[w] = u */
            Py_DECREF(u);
            Py_DECREF(w);
            if (err == 0) DISPATCH();
            break;

        TARGET(MAP_ADD)
            w = TOP();     /* key */
            u = SECOND();  /* value */
            STACKADJ(-2);
            v = stack_pointer[-oparg];  /* dict */
            assert (PyDict_CheckExact(v));
            err = PyDict_SetItem(v, w, u);  /* v[w] = u */
            Py_DECREF(u);
            Py_DECREF(w);
            if (err == 0) {
                PREDICT(JUMP_ABSOLUTE);
                DISPATCH();
            }
            break;

        TARGET(LOAD_ATTR)
            w = GETITEM(names, oparg);
            v = TOP();
            x = PyObject_GetAttr(v, w);
            Py_DECREF(v);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(COMPARE_OP)
            w = POP();
            v = TOP();
            x = cmp_outcome(oparg, v, w);
            Py_DECREF(v);
            Py_DECREF(w);
            SET_TOP(x);
            if (x == NULL) break;
            PREDICT(POP_JUMP_IF_FALSE);
            PREDICT(POP_JUMP_IF_TRUE);
            DISPATCH();

        TARGET(IMPORT_NAME)
            w = GETITEM(names, oparg);
            x = PyDict_GetItemString(f->f_builtins, "__import__");
            if (x == NULL) {
                PyErr_SetString(PyExc_ImportError,
                                "__import__ not found");
                break;
            }
            Py_INCREF(x);
            v = POP();
            u = TOP();
            if (PyLong_AsLong(u) != -1 || PyErr_Occurred())
                w = PyTuple_Pack(5,
                            w,
                            f->f_globals,
                            f->f_locals == NULL ?
                                  Py_None : f->f_locals,
                            v,
                            u);
            else
                w = PyTuple_Pack(4,
                            w,
                            f->f_globals,
                            f->f_locals == NULL ?
                                  Py_None : f->f_locals,
                            v);
            Py_DECREF(v);
            Py_DECREF(u);
            if (w == NULL) {
                u = POP();
                Py_DECREF(x);
                x = NULL;
                break;
            }
            READ_TIMESTAMP(intr0);
            v = x;
            x = PyEval_CallObject(v, w);
            Py_DECREF(v);
            READ_TIMESTAMP(intr1);
            Py_DECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(IMPORT_STAR)
            v = POP();
            PyFrame_FastToLocals(f);
            if ((x = f->f_locals) == NULL) {
                PyErr_SetString(PyExc_SystemError,
                    "no locals found during 'import *'");
                break;
            }
            READ_TIMESTAMP(intr0);
            err = import_all_from(x, v);
            READ_TIMESTAMP(intr1);
            PyFrame_LocalsToFast(f, 0);
            Py_DECREF(v);
            if (err == 0) DISPATCH();
            break;

        TARGET(IMPORT_FROM)
            w = GETITEM(names, oparg);
            v = TOP();
            READ_TIMESTAMP(intr0);
            x = import_from(v, w);
            READ_TIMESTAMP(intr1);
            PUSH(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(JUMP_FORWARD)
            JUMPBY(oparg);
            FAST_DISPATCH();

        PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE);
        TARGET(POP_JUMP_IF_FALSE)
            w = POP();
            if (w == Py_True) {
                Py_DECREF(w);
                FAST_DISPATCH();
            }
            if (w == Py_False) {
                Py_DECREF(w);
                JUMPTO(oparg);
                FAST_DISPATCH();
            }
            err = PyObject_IsTrue(w);
            Py_DECREF(w);
            if (err > 0)
                err = 0;
            else if (err == 0)
                JUMPTO(oparg);
            else
                break;
            DISPATCH();

        PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE);
        TARGET(POP_JUMP_IF_TRUE)
            w = POP();
            if (w == Py_False) {
                Py_DECREF(w);
                FAST_DISPATCH();
            }
            if (w == Py_True) {
                Py_DECREF(w);
                JUMPTO(oparg);
                FAST_DISPATCH();
            }
            err = PyObject_IsTrue(w);
            Py_DECREF(w);
            if (err > 0) {
                err = 0;
                JUMPTO(oparg);
            }
            else if (err == 0)
                ;
            else
                break;
            DISPATCH();

        TARGET(JUMP_IF_FALSE_OR_POP)
            w = TOP();
            if (w == Py_True) {
                STACKADJ(-1);
                Py_DECREF(w);
                FAST_DISPATCH();
            }
            if (w == Py_False) {
                JUMPTO(oparg);
                FAST_DISPATCH();
            }
            err = PyObject_IsTrue(w);
            if (err > 0) {
                STACKADJ(-1);
                Py_DECREF(w);
                err = 0;
            }
            else if (err == 0)
                JUMPTO(oparg);
            else
                break;
            DISPATCH();

        TARGET(JUMP_IF_TRUE_OR_POP)
            w = TOP();
            if (w == Py_False) {
                STACKADJ(-1);
                Py_DECREF(w);
                FAST_DISPATCH();
            }
            if (w == Py_True) {
                JUMPTO(oparg);
                FAST_DISPATCH();
            }
            err = PyObject_IsTrue(w);
            if (err > 0) {
                err = 0;
                JUMPTO(oparg);
            }
            else if (err == 0) {
                STACKADJ(-1);
                Py_DECREF(w);
            }
            else
                break;
            DISPATCH();

        PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
        TARGET(JUMP_ABSOLUTE)
            JUMPTO(oparg);
#if FAST_LOOPS
            /* Enabling this path speeds-up all while and for-loops by bypassing
               the per-loop checks for signals.  By default, this should be turned-off
               because it prevents detection of a control-break in tight loops like
               "while 1: pass".  Compile with this option turned-on when you need
               the speed-up and do not need break checking inside tight loops (ones
               that contain only instructions ending with FAST_DISPATCH).
            */
            FAST_DISPATCH();
#else
            DISPATCH();
#endif

        TARGET(GET_ITER)
            /* before: [obj]; after [getiter(obj)] */
            v = TOP();
            x = PyObject_GetIter(v);
            Py_DECREF(v);
            if (x != NULL) {
                SET_TOP(x);
                PREDICT(FOR_ITER);
                DISPATCH();
            }
            STACKADJ(-1);
            break;

        PREDICTED_WITH_ARG(FOR_ITER);
        TARGET(FOR_ITER)
            /* before: [iter]; after: [iter, iter()] *or* [] */
            v = TOP();
            x = (*v->ob_type->tp_iternext)(v);
            if (x != NULL) {
                PUSH(x);
                PREDICT(STORE_FAST);
                PREDICT(UNPACK_SEQUENCE);
                DISPATCH();
            }
            if (PyErr_Occurred()) {
                if (!PyErr_ExceptionMatches(
                                PyExc_StopIteration))
                    break;
                PyErr_Clear();
            }
            /* iterator ended normally */
            x = v = POP();
            Py_DECREF(v);
            JUMPBY(oparg);
            DISPATCH();

        TARGET(BREAK_LOOP)
            why = WHY_BREAK;
            goto fast_block_end;

        TARGET(CONTINUE_LOOP)
            retval = PyLong_FromLong(oparg);
            if (!retval) {
                x = NULL;
                break;
            }
            why = WHY_CONTINUE;
            goto fast_block_end;

        TARGET_WITH_IMPL(SETUP_LOOP, _setup_finally)
        TARGET_WITH_IMPL(SETUP_EXCEPT, _setup_finally)
        TARGET(SETUP_FINALLY)
        _setup_finally:
            /* NOTE: If you add any new block-setup opcodes that
               are not try/except/finally handlers, you may need
               to update the PyGen_NeedsFinalizing() function.
               */

            PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
                               STACK_LEVEL());
            DISPATCH();

        TARGET(SETUP_WITH)
        {
            static PyObject *exit, *enter;
            w = TOP();
            x = special_lookup(w, "__exit__", &exit);
            if (!x)
                break;
            SET_TOP(x);
            u = special_lookup(w, "__enter__", &enter);
            Py_DECREF(w);
            if (!u) {
                x = NULL;
                break;
            }
            x = PyObject_CallFunctionObjArgs(u, NULL);
            Py_DECREF(u);
            if (!x)
                break;
            /* Setup the finally block before pushing the result
               of __enter__ on the stack. */
            PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
                               STACK_LEVEL());

            PUSH(x);
            DISPATCH();
        }

        TARGET(WITH_CLEANUP)
        {
            /* At the top of the stack are 1-3 values indicating
               how/why we entered the finally clause:
               - TOP = None
               - (TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval
               - TOP = WHY_*; no retval below it
               - (TOP, SECOND, THIRD) = exc_info()
                 (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER
               Below them is EXIT, the context.__exit__ bound method.
               In the last case, we must call
                 EXIT(TOP, SECOND, THIRD)
               otherwise we must call
                 EXIT(None, None, None)

               In the first two cases, we remove EXIT from the
               stack, leaving the rest in the same order.  In the
               third case, we shift the bottom 3 values of the
               stack down, and replace the empty spot with NULL.

               In addition, if the stack represents an exception,
               *and* the function call returns a 'true' value, we
               push WHY_SILENCED onto the stack.  END_FINALLY will
               then not re-raise the exception.  (But non-local
               gotos should still be resumed.)
            */

            PyObject *exit_func;
            u = TOP();
            if (u == Py_None) {
                (void)POP();
                exit_func = TOP();
                SET_TOP(u);
                v = w = Py_None;
            }
            else if (PyLong_Check(u)) {
                (void)POP();
                switch(PyLong_AsLong(u)) {
                case WHY_RETURN:
                case WHY_CONTINUE:
                    /* Retval in TOP. */
                    exit_func = SECOND();
                    SET_SECOND(TOP());
                    SET_TOP(u);
                    break;
                default:
                    exit_func = TOP();
                    SET_TOP(u);
                    break;
                }
                u = v = w = Py_None;
            }
            else {
                PyObject *tp, *exc, *tb;
                PyTryBlock *block;
                v = SECOND();
                w = THIRD();
                tp = FOURTH();
                exc = PEEK(5);
                tb = PEEK(6);
                exit_func = PEEK(7);
                SET_VALUE(7, tb);
                SET_VALUE(6, exc);
                SET_VALUE(5, tp);
                /* UNWIND_EXCEPT_HANDLER will pop this off. */
                SET_FOURTH(NULL);
                /* We just shifted the stack down, so we have
                   to tell the except handler block that the
                   values are lower than it expects. */
                block = &f->f_blockstack[f->f_iblock - 1];
                assert(block->b_type == EXCEPT_HANDLER);
                block->b_level--;
            }
            /* XXX Not the fastest way to call it... */
            x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
                                             NULL);
            Py_DECREF(exit_func);
            if (x == NULL)
                break; /* Go to error exit */

            if (u != Py_None)
                err = PyObject_IsTrue(x);
            else
                err = 0;
            Py_DECREF(x);

            if (err < 0)
                break; /* Go to error exit */
            else if (err > 0) {
                err = 0;
                /* There was an exception and a True return */
                PUSH(PyLong_FromLong((long) WHY_SILENCED));
            }
            PREDICT(END_FINALLY);
            break;
        }

        TARGET(CALL_FUNCTION)
        {
            PyObject **sp;
            PCALL(PCALL_ALL);
            sp = stack_pointer;
#ifdef WITH_TSC
            x = call_function(&sp, oparg, &intr0, &intr1);
#else
            x = call_function(&sp, oparg);
#endif
            stack_pointer = sp;
            PUSH(x);
            if (x != NULL)
                DISPATCH();
            break;
        }

        TARGET_WITH_IMPL(CALL_FUNCTION_VAR, _call_function_var_kw)
        TARGET_WITH_IMPL(CALL_FUNCTION_KW, _call_function_var_kw)
        TARGET(CALL_FUNCTION_VAR_KW)
        _call_function_var_kw:
        {
            int na = oparg & 0xff;
            int nk = (oparg>>8) & 0xff;
            int flags = (opcode - CALL_FUNCTION) & 3;
            int n = na + 2 * nk;
            PyObject **pfunc, *func, **sp;
            PCALL(PCALL_ALL);
            if (flags & CALL_FLAG_VAR)
                n++;
            if (flags & CALL_FLAG_KW)
                n++;
            pfunc = stack_pointer - n - 1;
            func = *pfunc;

            if (PyMethod_Check(func)
                && PyMethod_GET_SELF(func) != NULL) {
                PyObject *self = PyMethod_GET_SELF(func);
                Py_INCREF(self);
                func = PyMethod_GET_FUNCTION(func);
                Py_INCREF(func);
                Py_DECREF(*pfunc);
                *pfunc = self;
                na++;
                n++;
            } else
                Py_INCREF(func);
            sp = stack_pointer;
            READ_TIMESTAMP(intr0);
            x = ext_do_call(func, &sp, flags, na, nk);
            READ_TIMESTAMP(intr1);
            stack_pointer = sp;
            Py_DECREF(func);

            while (stack_pointer > pfunc) {
                w = POP();
                Py_DECREF(w);
            }
            PUSH(x);
            if (x != NULL)
                DISPATCH();
            break;
        }

        TARGET_WITH_IMPL(MAKE_CLOSURE, _make_function)
        TARGET(MAKE_FUNCTION)
        _make_function:
        {
            int posdefaults = oparg & 0xff;
            int kwdefaults = (oparg>>8) & 0xff;
            int num_annotations = (oparg >> 16) & 0x7fff;

            v = POP(); /* code object */
            x = PyFunction_New(v, f->f_globals);
            Py_DECREF(v);

            if (x != NULL && opcode == MAKE_CLOSURE) {
                v = POP();
                if (PyFunction_SetClosure(x, v) != 0) {
                    /* Can't happen unless bytecode is corrupt. */
                    why = WHY_EXCEPTION;
                }
                Py_DECREF(v);
            }

            if (x != NULL && num_annotations > 0) {
                Py_ssize_t name_ix;
                u = POP(); /* names of args with annotations */
                v = PyDict_New();
                if (v == NULL) {
                    Py_DECREF(x);
                    x = NULL;
                    break;
                }
                name_ix = PyTuple_Size(u);
                assert(num_annotations == name_ix+1);
                while (name_ix > 0) {
                    --name_ix;
                    t = PyTuple_GET_ITEM(u, name_ix);
                    w = POP();
                    /* XXX(nnorwitz): check for errors */
                    PyDict_SetItem(v, t, w);
                    Py_DECREF(w);
                }

                if (PyFunction_SetAnnotations(x, v) != 0) {
                    /* Can't happen unless
                       PyFunction_SetAnnotations changes. */
                    why = WHY_EXCEPTION;
                }
                Py_DECREF(v);
                Py_DECREF(u);
            }

            /* XXX Maybe this should be a separate opcode? */
            if (x != NULL && posdefaults > 0) {
                v = PyTuple_New(posdefaults);
                if (v == NULL) {
                    Py_DECREF(x);
                    x = NULL;
                    break;
                }
                while (--posdefaults >= 0) {
                    w = POP();
                    PyTuple_SET_ITEM(v, posdefaults, w);
                }
                if (PyFunction_SetDefaults(x, v) != 0) {
                    /* Can't happen unless
                       PyFunction_SetDefaults changes. */
                    why = WHY_EXCEPTION;
                }
                Py_DECREF(v);
            }
            if (x != NULL && kwdefaults > 0) {
                v = PyDict_New();
                if (v == NULL) {
                    Py_DECREF(x);
                    x = NULL;
                    break;
                }
                while (--kwdefaults >= 0) {
                    w = POP(); /* default value */
                    u = POP(); /* kw only arg name */
                    /* XXX(nnorwitz): check for errors */
                    PyDict_SetItem(v, u, w);
                    Py_DECREF(w);
                    Py_DECREF(u);
                }
                if (PyFunction_SetKwDefaults(x, v) != 0) {
                    /* Can't happen unless
                       PyFunction_SetKwDefaults changes. */
                    why = WHY_EXCEPTION;
                }
                Py_DECREF(v);
            }
            PUSH(x);
            break;
        }

        TARGET(BUILD_SLICE)
            if (oparg == 3)
                w = POP();
            else
                w = NULL;
            v = POP();
            u = TOP();
            x = PySlice_New(u, v, w);
            Py_DECREF(u);
            Py_DECREF(v);
            Py_XDECREF(w);
            SET_TOP(x);
            if (x != NULL) DISPATCH();
            break;

        TARGET(EXTENDED_ARG)
            opcode = NEXTOP();
            oparg = oparg<<16 | NEXTARG();
            goto dispatch_opcode;

#if USE_COMPUTED_GOTOS
        _unknown_opcode:
#endif
        default:
            fprintf(stderr,
                "XXX lineno: %d, opcode: %d\n",
                PyFrame_GetLineNumber(f),
                opcode);
            PyErr_SetString(PyExc_SystemError, "unknown opcode");
            why = WHY_EXCEPTION;
            break;

#ifdef CASE_TOO_BIG
        }
#endif

        } /* switch */

        on_error:

        READ_TIMESTAMP(inst1);

        /* Quickly continue if no error occurred */

        if (why == WHY_NOT) {
            if (err == 0 && x != NULL) {
#ifdef CHECKEXC
                /* This check is expensive! */
                if (PyErr_Occurred())
                    fprintf(stderr,
                        "XXX undetected error\n");
                else {
#endif
                    READ_TIMESTAMP(loop1);
                    continue; /* Normal, fast path */
#ifdef CHECKEXC
                }
#endif
            }
            why = WHY_EXCEPTION;
            x = Py_None;
            err = 0;
        }

        /* Double-check exception status */

        if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
            if (!PyErr_Occurred()) {
                PyErr_SetString(PyExc_SystemError,
                    "error return without exception set");
                why = WHY_EXCEPTION;
            }
        }
#ifdef CHECKEXC
        else {
            /* This check is expensive! */
            if (PyErr_Occurred()) {
                char buf[128];
                sprintf(buf, "Stack unwind with exception "
                    "set and why=%d", why);
                Py_FatalError(buf);
            }
        }
#endif

        /* Log traceback info if this is a real exception */

        if (why == WHY_EXCEPTION) {
            PyTraceBack_Here(f);

            if (tstate->c_tracefunc != NULL)
                call_exc_trace(tstate->c_tracefunc,
                               tstate->c_traceobj, f);
        }

        /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */

        if (why == WHY_RERAISE)
            why = WHY_EXCEPTION;

        /* Unwind stacks if a (pseudo) exception occurred */

fast_block_end:
        while (why != WHY_NOT && f->f_iblock > 0) {
            /* Peek at the current block. */
            PyTryBlock *b = &f->f_blockstack[f->f_iblock - 1];

            assert(why != WHY_YIELD);
            if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
                why = WHY_NOT;
                JUMPTO(PyLong_AS_LONG(retval));
                Py_DECREF(retval);
                break;
            }
            /* Now we have to pop the block. */
            f->f_iblock--;

            if (b->b_type == EXCEPT_HANDLER) {
                UNWIND_EXCEPT_HANDLER(b);
                continue;
            }
            UNWIND_BLOCK(b);
            if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
                why = WHY_NOT;
                JUMPTO(b->b_handler);
                break;
            }
            if (why == WHY_EXCEPTION && (b->b_type == SETUP_EXCEPT
                || b->b_type == SETUP_FINALLY)) {
                PyObject *exc, *val, *tb;
                int handler = b->b_handler;
                /* Beware, this invalidates all b->b_* fields */
                PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL());
                PUSH(tstate->exc_traceback);
                PUSH(tstate->exc_value);
                if (tstate->exc_type != NULL) {
                    PUSH(tstate->exc_type);
                }
                else {
                    Py_INCREF(Py_None);
                    PUSH(Py_None);
                }
                PyErr_Fetch(&exc, &val, &tb);
                /* Make the raw exception data
                   available to the handler,
                   so a program can emulate the
                   Python main loop. */
                PyErr_NormalizeException(
                    &exc, &val, &tb);
                PyException_SetTraceback(val, tb);
                Py_INCREF(exc);
                tstate->exc_type = exc;
                Py_INCREF(val);
                tstate->exc_value = val;
                tstate->exc_traceback = tb;
                if (tb == NULL)
                    tb = Py_None;
                Py_INCREF(tb);
                PUSH(tb);
                PUSH(val);
                PUSH(exc);
                why = WHY_NOT;
                JUMPTO(handler);
                break;
            }
            if (b->b_type == SETUP_FINALLY) {
                if (why & (WHY_RETURN | WHY_CONTINUE))
                    PUSH(retval);
                PUSH(PyLong_FromLong((long)why));
                why = WHY_NOT;
                JUMPTO(b->b_handler);
                break;
            }
        } /* unwind stack */

        /* End the loop if we still have an error (or return) */

        if (why != WHY_NOT)
            break;
        READ_TIMESTAMP(loop1);

    } /* main loop */

    assert(why != WHY_YIELD);
    /* Pop remaining stack entries. */
    while (!EMPTY()) {
        v = POP();
        Py_XDECREF(v);
    }

    if (why != WHY_RETURN)
        retval = NULL;

fast_yield:
    if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) {
        /* The purpose of this block is to put aside the generator's exception
           state and restore that of the calling frame. If the current
           exception state is from the caller, we clear the exception values
           on the generator frame, so they are not swapped back in latter. The
           origin of the current exception state is determined by checking for
           except handler blocks, which we must be in iff a new exception
           state came into existence in this frame. (An uncaught exception
           would have why == WHY_EXCEPTION, and we wouldn't be here). */
        int i;
        for (i = 0; i < f->f_iblock; i++)
            if (f->f_blockstack[i].b_type == EXCEPT_HANDLER)
                break;
        if (i == f->f_iblock)
            /* We did not create this exception. */
            RESTORE_AND_CLEAR_EXC_STATE()
        else
            SWAP_EXC_STATE()
    }

    if (tstate->use_tracing) {
        if (tstate->c_tracefunc) {
            if (why == WHY_RETURN || why == WHY_YIELD) {
                if (call_trace(tstate->c_tracefunc,
                               tstate->c_traceobj, f,
                               PyTrace_RETURN, retval)) {
                    Py_XDECREF(retval);
                    retval = NULL;
                    why = WHY_EXCEPTION;
                }
            }
            else if (why == WHY_EXCEPTION) {
                call_trace_protected(tstate->c_tracefunc,
                                     tstate->c_traceobj, f,
                                     PyTrace_RETURN, NULL);
            }
        }
        if (tstate->c_profilefunc) {
            if (why == WHY_EXCEPTION)
                call_trace_protected(tstate->c_profilefunc,
                                     tstate->c_profileobj, f,
                                     PyTrace_RETURN, NULL);
            else if (call_trace(tstate->c_profilefunc,
                                tstate->c_profileobj, f,
                                PyTrace_RETURN, retval)) {
                Py_XDECREF(retval);
                retval = NULL;
                why = WHY_EXCEPTION;
            }
        }
    }

    /* pop frame */
exit_eval_frame:
    Py_LeaveRecursiveCall();
    tstate->frame = f->f_back;

    return retval;
}

/* This is gonna seem *real weird*, but if you put some other code between
   PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
   the test in the if statements in Misc/gdbinit (pystack and pystackv). */

PyObject *
PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
           PyObject **args, int argcount, PyObject **kws, int kwcount,
           PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
{
    PyCodeObject* co = (PyCodeObject*)_co;
    register PyFrameObject *f;
    register PyObject *retval = NULL;
    register PyObject **fastlocals, **freevars;
    PyThreadState *tstate = PyThreadState_GET();
    PyObject *x, *u;
    int total_args = co->co_argcount + co->co_kwonlyargcount;

    if (globals == NULL) {
        PyErr_SetString(PyExc_SystemError,
                        "PyEval_EvalCodeEx: NULL globals");
        return NULL;
    }

    assert(tstate != NULL);
    assert(globals != NULL);
    f = PyFrame_New(tstate, co, globals, locals);
    if (f == NULL)
        return NULL;

    fastlocals = f->f_localsplus;
    freevars = f->f_localsplus + co->co_nlocals;

    if (total_args || co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
        int i;
        int n = argcount;
        PyObject *kwdict = NULL;
        if (co->co_flags & CO_VARKEYWORDS) {
            kwdict = PyDict_New();
            if (kwdict == NULL)
                goto fail;
            i = total_args;
            if (co->co_flags & CO_VARARGS)
                i++;
            SETLOCAL(i, kwdict);
        }
        if (argcount > co->co_argcount) {
            if (!(co->co_flags & CO_VARARGS)) {
                PyErr_Format(PyExc_TypeError,
                    "%U() takes %s %d "
                    "positional argument%s (%d given)",
                    co->co_name,
                    defcount ? "at most" : "exactly",
                    co->co_argcount,
                    co->co_argcount == 1 ? "" : "s",
                    argcount + kwcount);
                goto fail;
            }
            n = co->co_argcount;
        }
        for (i = 0; i < n; i++) {
            x = args[i];
            Py_INCREF(x);
            SETLOCAL(i, x);
        }
        if (co->co_flags & CO_VARARGS) {
            u = PyTuple_New(argcount - n);
            if (u == NULL)
                goto fail;
            SETLOCAL(total_args, u);
            for (i = n; i < argcount; i++) {
                x = args[i];
                Py_INCREF(x);
                PyTuple_SET_ITEM(u, i-n, x);
            }
        }
        for (i = 0; i < kwcount; i++) {
            PyObject **co_varnames;
            PyObject *keyword = kws[2*i];
            PyObject *value = kws[2*i + 1];
            int j;
            if (keyword == NULL || !PyUnicode_Check(keyword)) {
                PyErr_Format(PyExc_TypeError,
                    "%U() keywords must be strings",
                    co->co_name);
                goto fail;
            }
            /* Speed hack: do raw pointer compares. As names are
               normally interned this should almost always hit. */
            co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
            for (j = 0; j < total_args; j++) {
                PyObject *nm = co_varnames[j];
                if (nm == keyword)
                    goto kw_found;
            }
            /* Slow fallback, just in case */
            for (j = 0; j < total_args; j++) {
                PyObject *nm = co_varnames[j];
                int cmp = PyObject_RichCompareBool(
                    keyword, nm, Py_EQ);
                if (cmp > 0)
                    goto kw_found;
                else if (cmp < 0)
                    goto fail;
            }
            if (j >= total_args && kwdict == NULL) {
                PyErr_Format(PyExc_TypeError,
                             "%U() got an unexpected "
                             "keyword argument '%S'",
                             co->co_name,
                             keyword);
                goto fail;
            }
            PyDict_SetItem(kwdict, keyword, value);
            continue;
          kw_found:
            if (GETLOCAL(j) != NULL) {
                PyErr_Format(PyExc_TypeError,
                         "%U() got multiple "
                         "values for keyword "
                         "argument '%S'",
                         co->co_name,
                         keyword);
                goto fail;
            }
            Py_INCREF(value);
            SETLOCAL(j, value);
        }
        if (co->co_kwonlyargcount > 0) {
            for (i = co->co_argcount; i < total_args; i++) {
                PyObject *name;
                if (GETLOCAL(i) != NULL)
                    continue;
                name = PyTuple_GET_ITEM(co->co_varnames, i);
                if (kwdefs != NULL) {
                    PyObject *def = PyDict_GetItem(kwdefs, name);
                    if (def) {
                        Py_INCREF(def);
                        SETLOCAL(i, def);
                        continue;
                    }
                }
                PyErr_Format(PyExc_TypeError,
                    "%U() needs keyword-only argument %S",
                    co->co_name, name);
                goto fail;
            }
        }
        if (argcount < co->co_argcount) {
            int m = co->co_argcount - defcount;
            for (i = argcount; i < m; i++) {
                if (GETLOCAL(i) == NULL) {
                    int j, given = 0;
                    for (j = 0; j < co->co_argcount; j++)
                        if (GETLOCAL(j))
                            given++;
                    PyErr_Format(PyExc_TypeError,
                        "%U() takes %s %d "
                        "argument%s "
                        "(%d given)",
                        co->co_name,
                        ((co->co_flags & CO_VARARGS) ||
                         defcount) ? "at least"
                                   : "exactly",
                             m, m == 1 ? "" : "s", given);
                    goto fail;
                }
            }
            if (n > m)
                i = n - m;
            else
                i = 0;
            for (; i < defcount; i++) {
                if (GETLOCAL(m+i) == NULL) {
                    PyObject *def = defs[i];
                    Py_INCREF(def);
                    SETLOCAL(m+i, def);
                }
            }
        }
    }
    else if (argcount > 0 || kwcount > 0) {
        PyErr_Format(PyExc_TypeError,
                     "%U() takes no arguments (%d given)",
                     co->co_name,
                     argcount + kwcount);
        goto fail;
    }
    /* Allocate and initialize storage for cell vars, and copy free
       vars into frame.  This isn't too efficient right now. */
    if (PyTuple_GET_SIZE(co->co_cellvars)) {
        int i, j, nargs, found;
        Py_UNICODE *cellname, *argname;
        PyObject *c;

        nargs = total_args;
        if (co->co_flags & CO_VARARGS)
            nargs++;
        if (co->co_flags & CO_VARKEYWORDS)
            nargs++;

        /* Initialize each cell var, taking into account
           cell vars that are initialized from arguments.

           Should arrange for the compiler to put cellvars
           that are arguments at the beginning of the cellvars
           list so that we can march over it more efficiently?
        */
        for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
            cellname = PyUnicode_AS_UNICODE(
                PyTuple_GET_ITEM(co->co_cellvars, i));
            found = 0;
            for (j = 0; j < nargs; j++) {
                argname = PyUnicode_AS_UNICODE(
                    PyTuple_GET_ITEM(co->co_varnames, j));
                if (Py_UNICODE_strcmp(cellname, argname) == 0) {
                    c = PyCell_New(GETLOCAL(j));
                    if (c == NULL)
                        goto fail;
                    GETLOCAL(co->co_nlocals + i) = c;
                    found = 1;
                    break;
                }
            }
            if (found == 0) {
                c = PyCell_New(NULL);
                if (c == NULL)
                    goto fail;
                SETLOCAL(co->co_nlocals + i, c);
            }
        }
    }
    if (PyTuple_GET_SIZE(co->co_freevars)) {
        int i;
        for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
            PyObject *o = PyTuple_GET_ITEM(closure, i);
            Py_INCREF(o);
            freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
        }
    }

    if (co->co_flags & CO_GENERATOR) {
        /* Don't need to keep the reference to f_back, it will be set
         * when the generator is resumed. */
        Py_XDECREF(f->f_back);
        f->f_back = NULL;

        PCALL(PCALL_GENERATOR);

        /* Create a new generator that owns the ready to run frame
         * and return that as the value. */
        return PyGen_New(f);
    }

    retval = PyEval_EvalFrameEx(f,0);

fail: /* Jump here from prelude on failure */

    /* decref'ing the frame can cause __del__ methods to get invoked,
       which can call back into Python.  While we're done with the
       current Python frame (f), the associated C stack is still in use,
       so recursion_depth must be boosted for the duration.
    */
    assert(tstate != NULL);
    ++tstate->recursion_depth;
    Py_DECREF(f);
    --tstate->recursion_depth;
    return retval;
}


static PyObject *
special_lookup(PyObject *o, char *meth, PyObject **cache)
{
    PyObject *res;
    res = _PyObject_LookupSpecial(o, meth, cache);
    if (res == NULL && !PyErr_Occurred()) {
        PyErr_SetObject(PyExc_AttributeError, *cache);
        return NULL;
    }
    return res;
}


/* Logic for the raise statement (too complicated for inlining).
   This *consumes* a reference count to each of its arguments. */
static enum why_code
do_raise(PyObject *exc, PyObject *cause)
{
    PyObject *type = NULL, *value = NULL;

    if (exc == NULL) {
        /* Reraise */
        PyThreadState *tstate = PyThreadState_GET();
        PyObject *tb;
        type = tstate->exc_type;
        value = tstate->exc_value;
        tb = tstate->exc_traceback;
        if (type == Py_None) {
            PyErr_SetString(PyExc_RuntimeError,
                            "No active exception to reraise");
            return WHY_EXCEPTION;
            }
        Py_XINCREF(type);
        Py_XINCREF(value);
        Py_XINCREF(tb);
        PyErr_Restore(type, value, tb);
        return WHY_RERAISE;
    }

    /* We support the following forms of raise:
       raise
       raise <instance>
       raise <type> */

    if (PyExceptionClass_Check(exc)) {
        type = exc;
        value = PyObject_CallObject(exc, NULL);
        if (value == NULL)
            goto raise_error;
        if (!PyExceptionInstance_Check(value)) {
            PyErr_Format(PyExc_TypeError,
                         "calling %R should have returned an instance of "
                         "BaseException, not %R",
                         type, Py_TYPE(value));
            goto raise_error;
        }
    }
    else if (PyExceptionInstance_Check(exc)) {
        value = exc;
        type = PyExceptionInstance_Class(exc);
        Py_INCREF(type);
    }
    else {
        /* Not something you can raise.  You get an exception
           anyway, just not what you specified :-) */
        Py_DECREF(exc);
        PyErr_SetString(PyExc_TypeError,
                        "exceptions must derive from BaseException");
        goto raise_error;
    }

    if (cause) {
        PyObject *fixed_cause;
        if (PyExceptionClass_Check(cause)) {
            fixed_cause = PyObject_CallObject(cause, NULL);
            if (fixed_cause == NULL)
                goto raise_error;
            Py_DECREF(cause);
        }
        else if (PyExceptionInstance_Check(cause)) {
            fixed_cause = cause;
        }
        else {
            PyErr_SetString(PyExc_TypeError,
                            "exception causes must derive from "
                            "BaseException");
            goto raise_error;
        }
        PyException_SetCause(value, fixed_cause);
    }

    PyErr_SetObject(type, value);
    /* PyErr_SetObject incref's its arguments */
    Py_XDECREF(value);
    Py_XDECREF(type);
    return WHY_EXCEPTION;

raise_error:
    Py_XDECREF(value);
    Py_XDECREF(type);
    Py_XDECREF(cause);
    return WHY_EXCEPTION;
}

/* Iterate v argcnt times and store the results on the stack (via decreasing
   sp).  Return 1 for success, 0 if error.

   If argcntafter == -1, do a simple unpack. If it is >= 0, do an unpack
   with a variable target.
*/

static int
unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
{
    int i = 0, j = 0;
    Py_ssize_t ll = 0;
    PyObject *it;  /* iter(v) */
    PyObject *w;
    PyObject *l = NULL; /* variable list */

    assert(v != NULL);

    it = PyObject_GetIter(v);
    if (it == NULL)
        goto Error;

    for (; i < argcnt; i++) {
        w = PyIter_Next(it);
        if (w == NULL) {
            /* Iterator done, via error or exhaustion. */
            if (!PyErr_Occurred()) {
                PyErr_Format(PyExc_ValueError,
                    "need more than %d value%s to unpack",
                    i, i == 1 ? "" : "s");
            }
            goto Error;
        }
        *--sp = w;
    }

    if (argcntafter == -1) {
        /* We better have exhausted the iterator now. */
        w = PyIter_Next(it);
        if (w == NULL) {
            if (PyErr_Occurred())
                goto Error;
            Py_DECREF(it);
            return 1;
        }
        Py_DECREF(w);
        PyErr_Format(PyExc_ValueError, "too many values to unpack "
                     "(expected %d)", argcnt);
        goto Error;
    }

    l = PySequence_List(it);
    if (l == NULL)
        goto Error;
    *--sp = l;
    i++;

    ll = PyList_GET_SIZE(l);
    if (ll < argcntafter) {
        PyErr_Format(PyExc_ValueError, "need more than %zd values to unpack",
                     argcnt + ll);
        goto Error;
    }

    /* Pop the "after-variable" args off the list. */
    for (j = argcntafter; j > 0; j--, i++) {
        *--sp = PyList_GET_ITEM(l, ll - j);
    }
    /* Resize the list. */
    Py_SIZE(l) = ll - argcntafter;
    Py_DECREF(it);
    return 1;

Error:
    for (; i > 0; i--, sp++)
        Py_DECREF(*sp);
    Py_XDECREF(it);
    return 0;
}


#ifdef LLTRACE
static int
prtrace(PyObject *v, char *str)
{
    printf("%s ", str);
    if (PyObject_Print(v, stdout, 0) != 0)
        PyErr_Clear(); /* Don't know what else to do */
    printf("\n");
    return 1;
}
#endif

static void
call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
{
    PyObject *type, *value, *traceback, *arg;
    int err;
    PyErr_Fetch(&type, &value, &traceback);
    if (value == NULL) {
        value = Py_None;
        Py_INCREF(value);
    }
    arg = PyTuple_Pack(3, type, value, traceback);
    if (arg == NULL) {
        PyErr_Restore(type, value, traceback);
        return;
    }
    err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
    Py_DECREF(arg);
    if (err == 0)
        PyErr_Restore(type, value, traceback);
    else {
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(traceback);
    }
}

static int
call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
                     int what, PyObject *arg)
{
    PyObject *type, *value, *traceback;
    int err;
    PyErr_Fetch(&type, &value, &traceback);
    err = call_trace(func, obj, frame, what, arg);
    if (err == 0)
    {
        PyErr_Restore(type, value, traceback);
        return 0;
    }
    else {
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(traceback);
        return -1;
    }
}

static int
call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
           int what, PyObject *arg)
{
    register PyThreadState *tstate = frame->f_tstate;
    int result;
    if (tstate->tracing)
        return 0;
    tstate->tracing++;
    tstate->use_tracing = 0;
    result = func(obj, frame, what, arg);
    tstate->use_tracing = ((tstate->c_tracefunc != NULL)
                           || (tstate->c_profilefunc != NULL));
    tstate->tracing--;
    return result;
}

PyObject *
_PyEval_CallTracing(PyObject *func, PyObject *args)
{
    PyFrameObject *frame = PyEval_GetFrame();
    PyThreadState *tstate = frame->f_tstate;
    int save_tracing = tstate->tracing;
    int save_use_tracing = tstate->use_tracing;
    PyObject *result;

    tstate->tracing = 0;
    tstate->use_tracing = ((tstate->c_tracefunc != NULL)
                           || (tstate->c_profilefunc != NULL));
    result = PyObject_Call(func, args, NULL);
    tstate->tracing = save_tracing;
    tstate->use_tracing = save_use_tracing;
    return result;
}

/* See Objects/lnotab_notes.txt for a description of how tracing works. */
static int
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
                      PyFrameObject *frame, int *instr_lb, int *instr_ub,
                      int *instr_prev)
{
    int result = 0;
    int line = frame->f_lineno;

    /* If the last instruction executed isn't in the current
       instruction window, reset the window.
    */
    if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
        PyAddrPair bounds;
        line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
                                       &bounds);
        *instr_lb = bounds.ap_lower;
        *instr_ub = bounds.ap_upper;
    }
    /* If the last instruction falls at the start of a line or if
       it represents a jump backwards, update the frame's line
       number and call the trace function. */
    if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
        frame->f_lineno = line;
        result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);
    }
    *instr_prev = frame->f_lasti;
    return result;
}

void
PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
{
    PyThreadState *tstate = PyThreadState_GET();
    PyObject *temp = tstate->c_profileobj;
    Py_XINCREF(arg);
    tstate->c_profilefunc = NULL;
    tstate->c_profileobj = NULL;
    /* Must make sure that tracing is not ignored if 'temp' is freed */
    tstate->use_tracing = tstate->c_tracefunc != NULL;
    Py_XDECREF(temp);
    tstate->c_profilefunc = func;
    tstate->c_profileobj = arg;
    /* Flag that tracing or profiling is turned on */
    tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
}

void
PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
{
    PyThreadState *tstate = PyThreadState_GET();
    PyObject *temp = tstate->c_traceobj;
    _Py_TracingPossible += (func != NULL) - (tstate->c_tracefunc != NULL);
    Py_XINCREF(arg);
    tstate->c_tracefunc = NULL;
    tstate->c_traceobj = NULL;
    /* Must make sure that profiling is not ignored if 'temp' is freed */
    tstate->use_tracing = tstate->c_profilefunc != NULL;
    Py_XDECREF(temp);
    tstate->c_tracefunc = func;
    tstate->c_traceobj = arg;
    /* Flag that tracing or profiling is turned on */
    tstate->use_tracing = ((func != NULL)
                           || (tstate->c_profilefunc != NULL));
}

PyObject *
PyEval_GetBuiltins(void)
{
    PyFrameObject *current_frame = PyEval_GetFrame();
    if (current_frame == NULL)
        return PyThreadState_GET()->interp->builtins;
    else
        return current_frame->f_builtins;
}

PyObject *
PyEval_GetLocals(void)
{
    PyFrameObject *current_frame = PyEval_GetFrame();
    if (current_frame == NULL)
        return NULL;
    PyFrame_FastToLocals(current_frame);
    return current_frame->f_locals;
}

PyObject *
PyEval_GetGlobals(void)
{
    PyFrameObject *current_frame = PyEval_GetFrame();
    if (current_frame == NULL)
        return NULL;
    else
        return current_frame->f_globals;
}

PyFrameObject *
PyEval_GetFrame(void)
{
    PyThreadState *tstate = PyThreadState_GET();
    return _PyThreadState_GetFrame(tstate);
}

int
PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
{
    PyFrameObject *current_frame = PyEval_GetFrame();
    int result = cf->cf_flags != 0;

    if (current_frame != NULL) {
        const int codeflags = current_frame->f_code->co_flags;
        const int compilerflags = codeflags & PyCF_MASK;
        if (compilerflags) {
            result = 1;
            cf->cf_flags |= compilerflags;
        }
#if 0 /* future keyword */
        if (codeflags & CO_GENERATOR_ALLOWED) {
            result = 1;
            cf->cf_flags |= CO_GENERATOR_ALLOWED;
        }
#endif
    }
    return result;
}


/* External interface to call any callable object.
   The arg must be a tuple or NULL.  The kw must be a dict or NULL. */

PyObject *
PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
{
    PyObject *result;

    if (arg == NULL) {
        arg = PyTuple_New(0);
        if (arg == NULL)
            return NULL;
    }
    else if (!PyTuple_Check(arg)) {
        PyErr_SetString(PyExc_TypeError,
                        "argument list must be a tuple");
        return NULL;
    }
    else
        Py_INCREF(arg);

    if (kw != NULL && !PyDict_Check(kw)) {
        PyErr_SetString(PyExc_TypeError,
                        "keyword list must be a dictionary");
        Py_DECREF(arg);
        return NULL;
    }

    result = PyObject_Call(func, arg, kw);
    Py_DECREF(arg);
    return result;
}

const char *
PyEval_GetFuncName(PyObject *func)
{
    if (PyMethod_Check(func))
        return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
    else if (PyFunction_Check(func))
        return _PyUnicode_AsString(((PyFunctionObject*)func)->func_name);
    else if (PyCFunction_Check(func))
        return ((PyCFunctionObject*)func)->m_ml->ml_name;
    else
        return func->ob_type->tp_name;
}

const char *
PyEval_GetFuncDesc(PyObject *func)
{
    if (PyMethod_Check(func))
        return "()";
    else if (PyFunction_Check(func))
        return "()";
    else if (PyCFunction_Check(func))
        return "()";
    else
        return " object";
}

static void
err_args(PyObject *func, int flags, int nargs)
{
    if (flags & METH_NOARGS)
        PyErr_Format(PyExc_TypeError,
                     "%.200s() takes no arguments (%d given)",
                     ((PyCFunctionObject *)func)->m_ml->ml_name,
                     nargs);
    else
        PyErr_Format(PyExc_TypeError,
                     "%.200s() takes exactly one argument (%d given)",
                     ((PyCFunctionObject *)func)->m_ml->ml_name,
                     nargs);
}

#define C_TRACE(x, call) \
if (tstate->use_tracing && tstate->c_profilefunc) { \
    if (call_trace(tstate->c_profilefunc, \
        tstate->c_profileobj, \
        tstate->frame, PyTrace_C_CALL, \
        func)) { \
        x = NULL; \
    } \
    else { \
        x = call; \
        if (tstate->c_profilefunc != NULL) { \
            if (x == NULL) { \
                call_trace_protected(tstate->c_profilefunc, \
                    tstate->c_profileobj, \
                    tstate->frame, PyTrace_C_EXCEPTION, \
                    func); \
                /* XXX should pass (type, value, tb) */ \
            } else { \
                if (call_trace(tstate->c_profilefunc, \
                    tstate->c_profileobj, \
                    tstate->frame, PyTrace_C_RETURN, \
                    func)) { \
                    Py_DECREF(x); \
                    x = NULL; \
                } \
            } \
        } \
    } \
} else { \
    x = call; \
    }

static PyObject *
call_function(PyObject ***pp_stack, int oparg
#ifdef WITH_TSC
                , uint64* pintr0, uint64* pintr1
#endif
                )
{
    int na = oparg & 0xff;
    int nk = (oparg>>8) & 0xff;
    int n = na + 2 * nk;
    PyObject **pfunc = (*pp_stack) - n - 1;
    PyObject *func = *pfunc;
    PyObject *x, *w;

    /* Always dispatch PyCFunction first, because these are
       presumed to be the most frequent callable object.
    */
    if (PyCFunction_Check(func) && nk == 0) {
        int flags = PyCFunction_GET_FLAGS(func);
        PyThreadState *tstate = PyThreadState_GET();

        PCALL(PCALL_CFUNCTION);
        if (flags & (METH_NOARGS | METH_O)) {
            PyCFunction meth = PyCFunction_GET_FUNCTION(func);
            PyObject *self = PyCFunction_GET_SELF(func);
            if (flags & METH_NOARGS && na == 0) {
                C_TRACE(x, (*meth)(self,NULL));
            }
            else if (flags & METH_O && na == 1) {
                PyObject *arg = EXT_POP(*pp_stack);
                C_TRACE(x, (*meth)(self,arg));
                Py_DECREF(arg);
            }
            else {
                err_args(func, flags, na);
                x = NULL;
            }
        }
        else {
            PyObject *callargs;
            callargs = load_args(pp_stack, na);
            READ_TIMESTAMP(*pintr0);
            C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
            READ_TIMESTAMP(*pintr1);
            Py_XDECREF(callargs);
        }
    } else {
        if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
            /* optimize access to bound methods */
            PyObject *self = PyMethod_GET_SELF(func);
            PCALL(PCALL_METHOD);
            PCALL(PCALL_BOUND_METHOD);
            Py_INCREF(self);
            func = PyMethod_GET_FUNCTION(func);
            Py_INCREF(func);
            Py_DECREF(*pfunc);
            *pfunc = self;
            na++;
            n++;
        } else
            Py_INCREF(func);
        READ_TIMESTAMP(*pintr0);
        if (PyFunction_Check(func))
            x = fast_function(func, pp_stack, n, na, nk);
        else
            x = do_call(func, pp_stack, na, nk);
        READ_TIMESTAMP(*pintr1);
        Py_DECREF(func);
    }

    /* Clear the stack of the function object.  Also removes
       the arguments in case they weren't consumed already
       (fast_function() and err_args() leave them on the stack).
     */
    while ((*pp_stack) > pfunc) {
        w = EXT_POP(*pp_stack);
        Py_DECREF(w);
        PCALL(PCALL_POP);
    }
    return x;
}

/* The fast_function() function optimize calls for which no argument
   tuple is necessary; the objects are passed directly from the stack.
   For the simplest case -- a function that takes only positional
   arguments and is called with only positional arguments -- it
   inlines the most primitive frame setup code from
   PyEval_EvalCodeEx(), which vastly reduces the checks that must be
   done before evaluating the frame.
*/

static PyObject *
fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
{
    PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
    PyObject *globals = PyFunction_GET_GLOBALS(func);
    PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
    PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func);
    PyObject **d = NULL;
    int nd = 0;

    PCALL(PCALL_FUNCTION);
    PCALL(PCALL_FAST_FUNCTION);
    if (argdefs == NULL && co->co_argcount == n &&
        co->co_kwonlyargcount == 0 && nk==0 &&
        co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
        PyFrameObject *f;
        PyObject *retval = NULL;
        PyThreadState *tstate = PyThreadState_GET();
        PyObject **fastlocals, **stack;
        int i;

        PCALL(PCALL_FASTER_FUNCTION);
        assert(globals != NULL);
        /* XXX Perhaps we should create a specialized
           PyFrame_New() that doesn't take locals, but does
           take builtins without sanity checking them.
        */
        assert(tstate != NULL);
        f = PyFrame_New(tstate, co, globals, NULL);
        if (f == NULL)
            return NULL;

        fastlocals = f->f_localsplus;
        stack = (*pp_stack) - n;

        for (i = 0; i < n; i++) {
            Py_INCREF(*stack);
            fastlocals[i] = *stack++;
        }
        retval = PyEval_EvalFrameEx(f,0);
        ++tstate->recursion_depth;
        Py_DECREF(f);
        --tstate->recursion_depth;
        return retval;
    }
    if (argdefs != NULL) {
        d = &PyTuple_GET_ITEM(argdefs, 0);
        nd = Py_SIZE(argdefs);
    }
    return PyEval_EvalCodeEx((PyObject*)co, globals,
                             (PyObject *)NULL, (*pp_stack)-n, na,
                             (*pp_stack)-2*nk, nk, d, nd, kwdefs,
                             PyFunction_GET_CLOSURE(func));
}

static PyObject *
update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
                    PyObject *func)
{
    PyObject *kwdict = NULL;
    if (orig_kwdict == NULL)
        kwdict = PyDict_New();
    else {
        kwdict = PyDict_Copy(orig_kwdict);
        Py_DECREF(orig_kwdict);
    }
    if (kwdict == NULL)
        return NULL;
    while (--nk >= 0) {
        int err;
        PyObject *value = EXT_POP(*pp_stack);
        PyObject *key = EXT_POP(*pp_stack);
        if (PyDict_GetItem(kwdict, key) != NULL) {
            PyErr_Format(PyExc_TypeError,
                         "%.200s%s got multiple values "
                         "for keyword argument '%U'",
                         PyEval_GetFuncName(func),
                         PyEval_GetFuncDesc(func),
                         key);
            Py_DECREF(key);
            Py_DECREF(value);
            Py_DECREF(kwdict);
            return NULL;
        }
        err = PyDict_SetItem(kwdict, key, value);
        Py_DECREF(key);
        Py_DECREF(value);
        if (err) {
            Py_DECREF(kwdict);
            return NULL;
        }
    }
    return kwdict;
}

static PyObject *
update_star_args(int nstack, int nstar, PyObject *stararg,
                 PyObject ***pp_stack)
{
    PyObject *callargs, *w;

    callargs = PyTuple_New(nstack + nstar);
    if (callargs == NULL) {
        return NULL;
    }
    if (nstar) {
        int i;
        for (i = 0; i < nstar; i++) {
            PyObject *a = PyTuple_GET_ITEM(stararg, i);
            Py_INCREF(a);
            PyTuple_SET_ITEM(callargs, nstack + i, a);
        }
    }
    while (--nstack >= 0) {
        w = EXT_POP(*pp_stack);
        PyTuple_SET_ITEM(callargs, nstack, w);
    }
    return callargs;
}

static PyObject *
load_args(PyObject ***pp_stack, int na)
{
    PyObject *args = PyTuple_New(na);
    PyObject *w;

    if (args == NULL)
        return NULL;
    while (--na >= 0) {
        w = EXT_POP(*pp_stack);
        PyTuple_SET_ITEM(args, na, w);
    }
    return args;
}

static PyObject *
do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
{
    PyObject *callargs = NULL;
    PyObject *kwdict = NULL;
    PyObject *result = NULL;

    if (nk > 0) {
        kwdict = update_keyword_args(NULL, nk, pp_stack, func);
        if (kwdict == NULL)
            goto call_fail;
    }
    callargs = load_args(pp_stack, na);
    if (callargs == NULL)
        goto call_fail;
#ifdef CALL_PROFILE
    /* At this point, we have to look at the type of func to
       update the call stats properly.  Do it here so as to avoid
       exposing the call stats machinery outside ceval.c
    */
    if (PyFunction_Check(func))
        PCALL(PCALL_FUNCTION);
    else if (PyMethod_Check(func))
        PCALL(PCALL_METHOD);
    else if (PyType_Check(func))
        PCALL(PCALL_TYPE);
    else if (PyCFunction_Check(func))
        PCALL(PCALL_CFUNCTION);
    else
        PCALL(PCALL_OTHER);
#endif
    if (PyCFunction_Check(func)) {
        PyThreadState *tstate = PyThreadState_GET();
        C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
    }
    else
        result = PyObject_Call(func, callargs, kwdict);
call_fail:
    Py_XDECREF(callargs);
    Py_XDECREF(kwdict);
    return result;
}

static PyObject *
ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
{
    int nstar = 0;
    PyObject *callargs = NULL;
    PyObject *stararg = NULL;
    PyObject *kwdict = NULL;
    PyObject *result = NULL;

    if (flags & CALL_FLAG_KW) {
        kwdict = EXT_POP(*pp_stack);
        if (!PyDict_Check(kwdict)) {
            PyObject *d;
            d = PyDict_New();
            if (d == NULL)
                goto ext_call_fail;
            if (PyDict_Update(d, kwdict) != 0) {
                Py_DECREF(d);
                /* PyDict_Update raises attribute
                 * error (percolated from an attempt
                 * to get 'keys' attribute) instead of
                 * a type error if its second argument
                 * is not a mapping.
                 */
                if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
                    PyErr_Format(PyExc_TypeError,
                                 "%.200s%.200s argument after ** "
                                 "must be a mapping, not %.200s",
                                 PyEval_GetFuncName(func),
                                 PyEval_GetFuncDesc(func),
                                 kwdict->ob_type->tp_name);
                }
                goto ext_call_fail;
            }
            Py_DECREF(kwdict);
            kwdict = d;
        }
    }
    if (flags & CALL_FLAG_VAR) {
        stararg = EXT_POP(*pp_stack);
        if (!PyTuple_Check(stararg)) {
            PyObject *t = NULL;
            t = PySequence_Tuple(stararg);
            if (t == NULL) {
                if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                    PyErr_Format(PyExc_TypeError,
                                 "%.200s%.200s argument after * "
                                 "must be a sequence, not %200s",
                                 PyEval_GetFuncName(func),
                                 PyEval_GetFuncDesc(func),
                                 stararg->ob_type->tp_name);
                }
                goto ext_call_fail;
            }
            Py_DECREF(stararg);
            stararg = t;
        }
        nstar = PyTuple_GET_SIZE(stararg);
    }
    if (nk > 0) {
        kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
        if (kwdict == NULL)
            goto ext_call_fail;
    }
    callargs = update_star_args(na, nstar, stararg, pp_stack);
    if (callargs == NULL)
        goto ext_call_fail;
#ifdef CALL_PROFILE
    /* At this point, we have to look at the type of func to
       update the call stats properly.  Do it here so as to avoid
       exposing the call stats machinery outside ceval.c
    */
    if (PyFunction_Check(func))
        PCALL(PCALL_FUNCTION);
    else if (PyMethod_Check(func))
        PCALL(PCALL_METHOD);
    else if (PyType_Check(func))
        PCALL(PCALL_TYPE);
    else if (PyCFunction_Check(func))
        PCALL(PCALL_CFUNCTION);
    else
        PCALL(PCALL_OTHER);
#endif
    if (PyCFunction_Check(func)) {
        PyThreadState *tstate = PyThreadState_GET();
        C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
    }
    else
        result = PyObject_Call(func, callargs, kwdict);
ext_call_fail:
    Py_XDECREF(callargs);
    Py_XDECREF(kwdict);
    Py_XDECREF(stararg);
    return result;
}

/* Extract a slice index from a PyInt or PyLong or an object with the
   nb_index slot defined, and store in *pi.
   Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
   and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
   Return 0 on error, 1 on success.
*/
/* Note:  If v is NULL, return success without storing into *pi.  This
   is because_PyEval_SliceIndex() is called by apply_slice(), which can be
   called by the SLICE opcode with v and/or w equal to NULL.
*/
int
_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
{
    if (v != NULL) {
        Py_ssize_t x;
        if (PyIndex_Check(v)) {
            x = PyNumber_AsSsize_t(v, NULL);
            if (x == -1 && PyErr_Occurred())
                return 0;
        }
        else {
            PyErr_SetString(PyExc_TypeError,
                            "slice indices must be integers or "
                            "None or have an __index__ method");
            return 0;
        }
        *pi = x;
    }
    return 1;
}

#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
                         "BaseException is not allowed"

static PyObject *
cmp_outcome(int op, register PyObject *v, register PyObject *w)
{
    int res = 0;
    switch (op) {
    case PyCmp_IS:
        res = (v == w);
        break;
    case PyCmp_IS_NOT:
        res = (v != w);
        break;
    case PyCmp_IN:
        res = PySequence_Contains(w, v);
        if (res < 0)
            return NULL;
        break;
    case PyCmp_NOT_IN:
        res = PySequence_Contains(w, v);
        if (res < 0)
            return NULL;
        res = !res;
        break;
    case PyCmp_EXC_MATCH:
        if (PyTuple_Check(w)) {
            Py_ssize_t i, length;
            length = PyTuple_Size(w);
            for (i = 0; i < length; i += 1) {
                PyObject *exc = PyTuple_GET_ITEM(w, i);
                if (!PyExceptionClass_Check(exc)) {
                    PyErr_SetString(PyExc_TypeError,
                                    CANNOT_CATCH_MSG);
                    return NULL;
                }
            }
        }
        else {
            if (!PyExceptionClass_Check(w)) {
                PyErr_SetString(PyExc_TypeError,
                                CANNOT_CATCH_MSG);
                return NULL;
            }
        }
        res = PyErr_GivenExceptionMatches(v, w);
        break;
    default:
        return PyObject_RichCompare(v, w, op);
    }
    v = res ? Py_True : Py_False;
    Py_INCREF(v);
    return v;
}

static PyObject *
import_from(PyObject *v, PyObject *name)
{
    PyObject *x;

    x = PyObject_GetAttr(v, name);
    if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
        PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
    }
    return x;
}

static int
import_all_from(PyObject *locals, PyObject *v)
{
    PyObject *all = PyObject_GetAttrString(v, "__all__");
    PyObject *dict, *name, *value;
    int skip_leading_underscores = 0;
    int pos, err;

    if (all == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return -1; /* Unexpected error */
        PyErr_Clear();
        dict = PyObject_GetAttrString(v, "__dict__");
        if (dict == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
                return -1;
            PyErr_SetString(PyExc_ImportError,
            "from-import-* object has no __dict__ and no __all__");
            return -1;
        }
        all = PyMapping_Keys(dict);
        Py_DECREF(dict);
        if (all == NULL)
            return -1;
        skip_leading_underscores = 1;
    }

    for (pos = 0, err = 0; ; pos++) {
        name = PySequence_GetItem(all, pos);
        if (name == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_IndexError))
                err = -1;
            else
                PyErr_Clear();
            break;
        }
        if (skip_leading_underscores &&
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
        {
            Py_DECREF(name);
            continue;
        }
        value = PyObject_GetAttr(v, name);
        if (value == NULL)
            err = -1;
        else if (PyDict_CheckExact(locals))
            err = PyDict_SetItem(locals, name, value);
        else
            err = PyObject_SetItem(locals, name, value);
        Py_DECREF(name);
        Py_XDECREF(value);
        if (err != 0)
            break;
    }
    Py_DECREF(all);
    return err;
}

static void
format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj)
{
    const char *obj_str;

    if (!obj)
        return;

    obj_str = _PyUnicode_AsString(obj);
    if (!obj_str)
        return;

    PyErr_Format(exc, format_str, obj_str);
}

static void
format_exc_unbound(PyCodeObject *co, int oparg)
{
    PyObject *name;
    /* Don't stomp existing exception */
    if (PyErr_Occurred())
        return;
    if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
        name = PyTuple_GET_ITEM(co->co_cellvars,
                                oparg);
        format_exc_check_arg(
            PyExc_UnboundLocalError,
            UNBOUNDLOCAL_ERROR_MSG,
            name);
    } else {
        name = PyTuple_GET_ITEM(co->co_freevars, oparg -
                                PyTuple_GET_SIZE(co->co_cellvars));
        format_exc_check_arg(PyExc_NameError,
                             UNBOUNDFREE_ERROR_MSG, name);
    }
}

static PyObject *
unicode_concatenate(PyObject *v, PyObject *w,
                   PyFrameObject *f, unsigned char *next_instr)
{
    /* This function implements 'variable += expr' when both arguments
       are (Unicode) strings. */
    Py_ssize_t v_len = PyUnicode_GET_SIZE(v);
    Py_ssize_t w_len = PyUnicode_GET_SIZE(w);
    Py_ssize_t new_len = v_len + w_len;
    if (new_len < 0) {
        PyErr_SetString(PyExc_OverflowError,
                        "strings are too large to concat");
        return NULL;
    }

    if (Py_REFCNT(v) == 2) {
        /* In the common case, there are 2 references to the value
         * stored in 'variable' when the += is performed: one on the
         * value stack (in 'v') and one still stored in the
         * 'variable'.  We try to delete the variable now to reduce
         * the refcnt to 1.
         */
        switch (*next_instr) {
        case STORE_FAST:
        {
            int oparg = PEEKARG();
            PyObject **fastlocals = f->f_localsplus;
            if (GETLOCAL(oparg) == v)
                SETLOCAL(oparg, NULL);
            break;
        }
        case STORE_DEREF:
        {
            PyObject **freevars = (f->f_localsplus +
                                   f->f_code->co_nlocals);
            PyObject *c = freevars[PEEKARG()];
            if (PyCell_GET(c) == v)
                PyCell_Set(c, NULL);
            break;
        }
        case STORE_NAME:
        {
            PyObject *names = f->f_code->co_names;
            PyObject *name = GETITEM(names, PEEKARG());
            PyObject *locals = f->f_locals;
            if (PyDict_CheckExact(locals) &&
                PyDict_GetItem(locals, name) == v) {
                if (PyDict_DelItem(locals, name) != 0) {
                    PyErr_Clear();
                }
            }
            break;
        }
        }
    }

    if (Py_REFCNT(v) == 1 && !PyUnicode_CHECK_INTERNED(v)) {
        /* Now we own the last reference to 'v', so we can resize it
         * in-place.
         */
        if (PyUnicode_Resize(&v, new_len) != 0) {
            /* XXX if PyUnicode_Resize() fails, 'v' has been
             * deallocated so it cannot be put back into
             * 'variable'.  The MemoryError is raised when there
             * is no value in 'variable', which might (very
             * remotely) be a cause of incompatibilities.
             */
            return NULL;
        }
        /* copy 'w' into the newly allocated area of 'v' */
        memcpy(PyUnicode_AS_UNICODE(v) + v_len,
               PyUnicode_AS_UNICODE(w), w_len*sizeof(Py_UNICODE));
        return v;
    }
    else {
        /* When in-place resizing is not an option. */
        w = PyUnicode_Concat(v, w);
        Py_DECREF(v);
        return w;
    }
}

#ifdef DYNAMIC_EXECUTION_PROFILE

static PyObject *
getarray(long a[256])
{
    int i;
    PyObject *l = PyList_New(256);
    if (l == NULL) return NULL;
    for (i = 0; i < 256; i++) {
        PyObject *x = PyLong_FromLong(a[i]);
        if (x == NULL) {
            Py_DECREF(l);
            return NULL;
        }
        PyList_SetItem(l, i, x);
    }
    for (i = 0; i < 256; i++)
        a[i] = 0;
    return l;
}

PyObject *
_Py_GetDXProfile(PyObject *self, PyObject *args)
{
#ifndef DXPAIRS
    return getarray(dxp);
#else
    int i;
    PyObject *l = PyList_New(257);
    if (l == NULL) return NULL;
    for (i = 0; i < 257; i++) {
        PyObject *x = getarray(dxpairs[i]);
        if (x == NULL) {
            Py_DECREF(l);
            return NULL;
        }
        PyList_SetItem(l, i, x);
    }
    return l;
#endif
}

#endif
jlp++; + } /* end if */ + + if ((status = H5Pset_chunk((hid_t)plist, (int)ndims, da)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (da) + HDfree(da); + if (theArray) + UNPIN_BYTE_ARRAY(ENVONLY, dim, theArray, JNI_ABORT); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1chunk */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_chunk + * Signature: (JI[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1chunk + (JNIEnv *env, jclass clss, jlong plist, jint max_ndims, jlongArray dims) +{ + jboolean isCopy; + hsize_t *da = NULL; + jlong *theArray = NULL; + jsize arrLen; + int i; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_chunk: dims is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_chunk: dims array length < 0"); + } + if (arrLen < max_ndims) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_chunk: dims array < max_ndims"); + + PIN_LONG_ARRAY(ENVONLY, dims, theArray, &isCopy, "H5Pget_chunk: input dims not pinned"); + + if (NULL == (da = (hsize_t *) HDmalloc((size_t)max_ndims * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_chunk: memory allocation failed"); + + if ((status = H5Pget_chunk((hid_t)plist, (int)max_ndims, da)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < max_ndims; i++) + theArray[i] = (jlong)da[i]; + +done: + if (da) + HDfree(da); + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, dims, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1chunk */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_chunk_opts + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts + (JNIEnv *env, jclass clss, jlong dcpl_id, jint opts) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_chunk_opts((hid_t)dcpl_id, (unsigned)opts)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_chunk_opts + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts + (JNIEnv *env, jclass clss, jlong dcpl_id) +{ + unsigned opts = 0; + + UNUSED(clss); + + if (H5Pget_chunk_opts((hid_t)dcpl_id, &opts) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)opts; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_dset_no_attrs_hint + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1dset_1no_1attrs_1hint +(JNIEnv *env, jclass clss, jlong dcpl_id, jboolean minimize) +{ + hbool_t minimize_val; + herr_t retVal = FAIL; + + UNUSED(clss); + + minimize_val = (JNI_TRUE == minimize) ? TRUE : FALSE; + + if ((retVal = H5Pset_dset_no_attrs_hint((hid_t)dcpl_id, (hbool_t)minimize_val)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1dset_1no_1attrs_1hint */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_dset_no_attrs_hint + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1dset_1no_1attrs_1hint +(JNIEnv *env, jclass clss, jlong dcpl_id) +{ + hbool_t minimize = FALSE; + jboolean bval = JNI_FALSE; + + UNUSED(clss); + + if (H5Pget_dset_no_attrs_hint((hid_t)dcpl_id, (hbool_t *)&minimize) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (minimize == TRUE) + bval = JNI_TRUE; + +done: + return bval; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1dset_1no_1attrs_1hint */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_deflate + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1deflate + (JNIEnv *env, jclass clss, jlong plist, jint level) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_deflate((hid_t)plist, (unsigned)level)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1deflate */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fill_value + * Signature: (JJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fill_1value + (JNIEnv *env, jclass clss, jlong plist_id, jlong type_id, jbyteArray value) +{ + jboolean isCopy; + jbyte *byteP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) { + if ((status = H5Pset_fill_value((hid_t)plist_id, (hid_t)type_id, byteP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + else { + PIN_BYTE_ARRAY(ENVONLY, value, byteP, &isCopy, "H5Pget_fill_value: value array not pinned"); + + if ((status = H5Pset_fill_value((hid_t)plist_id, (hid_t)type_id, byteP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (byteP) + UNPIN_BYTE_ARRAY(ENVONLY, value, byteP, JNI_ABORT); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fill_1value */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fill_value + * Signature: (JJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fill_1value + (JNIEnv *env, jclass clss, jlong plist_id, jlong type_id, jbyteArray value) +{ + jboolean isCopy; + herr_t status = FAIL; + jbyte *byteP = NULL; + + UNUSED(clss); + + if (NULL == value) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_fill_value: value is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, value, byteP, &isCopy, "H5Pget_fill_value: value array not pinned"); + + if ((status = H5Pget_fill_value((hid_t)plist_id, (hid_t)type_id, byteP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (byteP) + UNPIN_BYTE_ARRAY(ENVONLY, value, byteP, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fill_1value */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pfill_value_defined + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined + (JNIEnv *env, jclass clss, jlong plist, jintArray status) +{ + H5D_fill_value_t value = H5D_FILL_VALUE_ERROR; + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == status) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pfill_value_defined: status is NULL"); + + PIN_INT_ARRAY(ENVONLY, status, theArray, &isCopy, "H5Pfill_value_defined: status not pinned"); + + if ((retVal = H5Pfill_value_defined((hid_t)plist, &value)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jint)value; + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, status, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fill_time + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fill_1time + (JNIEnv *env, jclass clss, jlong plist, jint fill_time) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fill_time((hid_t)plist, (H5D_fill_time_t)fill_time)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fill_1time */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fill_time + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fill_1time + (JNIEnv *env, jclass clss, jlong plist, jintArray fill_time) +{ + H5D_fill_time_t time = H5D_FILL_TIME_ERROR; + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == fill_time) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_fill_time: fill_time is NULL"); + + PIN_INT_ARRAY(ENVONLY, fill_time, theArray, &isCopy, "H5Pget_fill_time: fill_time not pinned"); + + if ((retVal = H5Pget_fill_time((hid_t)plist, &time)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jint)time; + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, fill_time, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fill_1time */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_alloc_time + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time + (JNIEnv *env, jclass clss, jlong plist, jint alloc_time) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_alloc_time((hid_t)plist, (H5D_alloc_time_t)alloc_time)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_alloc_time + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time + (JNIEnv *env, jclass clss, jlong plist, jintArray alloc_time) +{ + H5D_alloc_time_t time = H5D_ALLOC_TIME_ERROR; + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == alloc_time) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_alloc_time: alloc_time is NULL"); + + PIN_INT_ARRAY(ENVONLY, alloc_time, theArray, &isCopy, "H5Pget_alloc_time: alloc_time not pinned"); + + if ((retVal = H5Pget_alloc_time((hid_t)plist, &time)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = time; + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, alloc_time, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_filter + * Signature: (JIIJ[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1filter + (JNIEnv *env, jclass clss, jlong plist, jint filter, jint flags, + jlong cd_nelmts, jintArray cd_values) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == cd_values) { + if ((status = H5Pset_filter((hid_t)plist, (H5Z_filter_t)filter, + (unsigned int)flags, (size_t)cd_nelmts, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + else { + PIN_INT_ARRAY(ENVONLY, cd_values, theArray, &isCopy, "H5Pset_filter: input array not pinned"); + + if ((status = H5Pset_filter((hid_t)plist, (H5Z_filter_t)filter, + (unsigned int)flags, (size_t)cd_nelmts, (const unsigned int *)theArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, cd_values, theArray, JNI_ABORT); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1filter */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pall_filters_avail + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail + (JNIEnv *env, jclass clss, jlong dcpl_id) +{ + htri_t bval = JNI_FALSE; + + UNUSED(clss); + + if ((bval = H5Pall_filters_avail((hid_t)dcpl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: + return (jboolean)bval; +} /* end Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_nfilters + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1nfilters + (JNIEnv *env, jclass clss, jlong plist) +{ + int retVal = -1; + + UNUSED(clss); + + if ((retVal = H5Pget_nfilters((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1nfilters */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter + * Signature: (JI[I[J[IJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter + (JNIEnv *env, jclass clss, jlong plist, jint filter_number, jintArray flags, + jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name) +{ + jboolean isCopy; + jstring str; + jint *flagsArray = NULL; + jlong *cd_nelmtsArray = NULL; + jint *cd_valuesArray = NULL; + char *filter = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (namelen <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter: namelen <= 0"); + if (NULL == flags) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter: flags is NULL"); + if (NULL == cd_nelmts) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter: cd_nelmts is NULL"); + if (NULL == cd_values) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter: cd_values is NULL"); + + if (NULL == (filter = (char *) HDmalloc(sizeof(char) * (size_t)namelen))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter: memory allocation failed"); + + PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter: flags array not pinned"); + PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter: nelmts array not pinned"); + PIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, &isCopy, "H5Pget_filter: elmts array not pinned"); + + + /* direct cast (size_t *)variable fails on 32-bit environment */ + { + unsigned int filter_config; + long long cd_nelmts_temp = *cd_nelmtsArray; + size_t cd_nelmts_t = (size_t) cd_nelmts_temp; + + if ((status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, + (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, + (size_t)namelen, filter, &filter_config)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + filter[namelen - 1] = '\0'; + + *cd_nelmtsArray = (jlong)cd_nelmts_t; + } + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, filter))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (cd_valuesArray) + UNPIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, (status < 0) ? JNI_ABORT : 0); + if (cd_nelmtsArray) + UNPIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, (status < 0) ? JNI_ABORT : 0); + if (flagsArray) + UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0) + if (filter) + HDfree(filter); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter2 + * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter2 + (JNIEnv *env, jclass clss, jlong plist, jint filter_number, + jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, + jobjectArray name, jintArray filter_config) +{ + jboolean isCopy; + jstring str; + jint *flagsArray = NULL; + jlong *cd_nelmtsArray = NULL; + jint *cd_valuesArray = NULL; + jint *filter_configArray = NULL; + char *filter = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (namelen <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: namelen <= 0"); + if (NULL == flags) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: flags is NULL"); + if (NULL == cd_nelmts) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: cd_nelmts is NULL"); + if (NULL == filter_config) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: filter_config is NULL"); + + if (NULL == (filter = (char *) HDmalloc(sizeof(char) * (size_t)namelen))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter2: memory allocation failed"); + + PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter2: flags array not pinned"); + PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter2: nelmts array not pinned"); + PIN_INT_ARRAY(ENVONLY, filter_config, filter_configArray, &isCopy, "H5Pget_filter2: filter_config array not pinned"); + + if (NULL == cd_values && *cd_nelmtsArray == 0) { + /* direct cast (size_t *)variable fails on 32-bit environment */ + long long cd_nelmts_temp = 0; + size_t cd_nelmts_t = (size_t) cd_nelmts_temp; + + if ((status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, + (unsigned int *)flagsArray, &cd_nelmts_t, NULL, + (size_t)namelen, filter, (unsigned int *)filter_configArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + filter[namelen - 1] = '\0'; + + *cd_nelmtsArray = (jlong)cd_nelmts_t; + } + else { + if (NULL == cd_values) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter2: cd_values is NULL"); + + PIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, &isCopy, "H5Pget_filter2: elmts array not pinned"); + + { + /* direct cast (size_t *)variable fails on 32-bit environment */ + long long cd_nelmts_temp = *cd_nelmtsArray; + size_t cd_nelmts_t = (size_t) cd_nelmts_temp; + + if ((status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, + (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, + (size_t)namelen, filter, (unsigned int *)filter_configArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + filter[namelen - 1] = '\0'; + + *cd_nelmtsArray = (jlong)cd_nelmts_t; + } /* end direct cast special */ + } + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, filter))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter2: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (cd_valuesArray) + UNPIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, (status < 0) ? JNI_ABORT : 0); + if (filter_configArray) + UNPIN_INT_ARRAY(ENVONLY, filter_config, filter_configArray, (status < 0) ? JNI_ABORT : 0); + if (cd_nelmtsArray) + UNPIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, (status < 0) ? JNI_ABORT : 0); + if (flagsArray) + UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0); + if (filter) + HDfree(filter); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter2 */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter_by_id + * Signature: (JI[I[J[IJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id + (JNIEnv *env, jclass clss, jlong plist, jint filter, + jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name) +{ + jboolean isCopy; + jstring str; + jlong *cd_nelmtsArray = NULL; + jint *cd_valuesArray = NULL; + jint *flagsArray = NULL; + char *aName = NULL; + long bs; + int rank; + herr_t status = FAIL; + + UNUSED(clss); + + bs = (long)namelen; + + if (bs <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: namelen <= 0"); + if (NULL == flags) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: flags is NULL"); + if (NULL == cd_nelmts) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: cd_nelmts is NULL"); + if (NULL == cd_values) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: cd_values is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: name is NULL"); + + if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)bs))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id: memory allocation failed"); + + PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter_by_id: flags not pinned"); + PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter_by_id: cd_nelms not pinned"); + PIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, &isCopy, "H5Pget_filter_by_id: cd_values array not pinned"); + + if ((rank = ENVPTR->GetArrayLength(ENVONLY, cd_values)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id: cd_values array length < 0"); + } + + { + /* direct cast (size_t *)variable fails on 32-bit environment */ + unsigned int filter_config; + long long cd_nelmts_temp = *cd_nelmtsArray; + size_t cd_nelmts_t = (size_t) cd_nelmts_temp; + + if ((status = H5Pget_filter_by_id2((hid_t)plist, (H5Z_filter_t)filter, + (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, + (size_t)namelen, (char *)aName, &filter_config)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + aName[bs - 1] = '\0'; + + *cd_nelmtsArray = (jlong)cd_nelmts_t; + } /* end direct cast special */ + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (cd_valuesArray) + UNPIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, (status < 0) ? JNI_ABORT : 0); + if (cd_nelmtsArray) + UNPIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, (status < 0) ? JNI_ABORT : 0); + if (flagsArray) + UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0); + if (aName) + HDfree(aName); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter_by_id2 + * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 + (JNIEnv *env, jclass clss, jlong plist, jint filter, + jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name, jintArray filter_config) +{ + jboolean isCopy; + jstring str; + jlong *cd_nelmtsArray = NULL; + jint *cd_valuesArray = NULL; + jint *flagsArray = NULL; + jint *filter_configArray = NULL; + long bs; + char *aName = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + bs = (long)namelen; + + if (bs <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: namelen <= 0"); + if (NULL == flags) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: flags is NULL"); + if (NULL == cd_nelmts) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: cd_nelmts is NULL"); + if (NULL == cd_values) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: cd_values is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: name is NULL"); + if (NULL == filter_config) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_filter_by_id2: filter_config is NULL"); + + if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)bs))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id2: memory allocation failed"); + + PIN_INT_ARRAY(ENVONLY, flags, flagsArray, &isCopy, "H5Pget_filter_by_id2: flags not pinned"); + PIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, &isCopy, "H5Pget_filter_by_id2: cd_nelms not pinned"); + PIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, &isCopy, "H5Pget_filter_by_id2: cd_values array not pinned"); + PIN_INT_ARRAY(ENVONLY, filter_config, filter_configArray, &isCopy, "H5Pget_filter_by_id2: filter_config not pinned"); + + { + /* direct cast (size_t *)variable fails on 32-bit environment */ + long long cd_nelmts_temp = *cd_nelmtsArray; + size_t cd_nelmts_t = (size_t) cd_nelmts_temp; + + if ((status = H5Pget_filter_by_id2((hid_t)plist, (H5Z_filter_t)filter, + (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, + (size_t)namelen, (char *)aName, (unsigned int *)filter_configArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + aName[bs - 1] = '\0'; + + *cd_nelmtsArray = (jlong)cd_nelmts_t; + } /* end direct cast special handling */ + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_filter_by_id2: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (filter_configArray) + UNPIN_INT_ARRAY(ENVONLY, filter_config, filter_configArray, (status < 0) ? JNI_ABORT : 0); + if (cd_valuesArray) + UNPIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesArray, (status < 0) ? JNI_ABORT : 0); + if (cd_nelmtsArray) + UNPIN_LONG_ARRAY(ENVONLY, cd_nelmts, cd_nelmtsArray, (status < 0) ? JNI_ABORT : 0); + if (flagsArray) + UNPIN_INT_ARRAY(ENVONLY, flags, flagsArray, (status < 0) ? JNI_ABORT : 0); + if (aName) + HDfree(aName); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pmodify_filter + * Signature: (JIIJ[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pmodify_1filter + (JNIEnv *env, jclass clss, jlong plist, jint filter, + jint flags, jlong cd_nelmts, jintArray cd_values) +{ + jboolean isCopy; + jint *cd_valuesP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == cd_values) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pmodify_filter: cd_values is NULL"); + + PIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesP, &isCopy, "H5Pmodify_filter: cd_values not pinned"); + + if ((status = H5Pmodify_filter((hid_t)plist, (H5Z_filter_t)filter, (const unsigned int)flags, + (size_t)cd_nelmts, (unsigned int *)cd_valuesP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (cd_valuesP) + UNPIN_INT_ARRAY(ENVONLY, cd_values, cd_valuesP, JNI_ABORT); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pmodify_1filter */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Premove_filter + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5P1remove_1filter + (JNIEnv *env, jclass clss, jlong obj_id, jint filter) +{ + herr_t status = FAIL; + + UNUSED(clss); + + if ((status = H5Premove_filter((hid_t)obj_id, (H5Z_filter_t)filter)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5P1remove_1filter */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fletcher32 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 + (JNIEnv *env, jclass clss, jlong plist) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fletcher32((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_nbit + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1nbit + (JNIEnv *env, jclass clss, jlong plist_id) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_nbit((hid_t)plist_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1nbit */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_scaleoffset + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset + (JNIEnv *env, jclass clss, jlong plist_id, jint scale_type, jint scale_factor) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if (scale_factor <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_scaleoffset: scale factor must be > 0"); + if (scale_type != H5Z_SO_FLOAT_DSCALE && scale_type != H5Z_SO_FLOAT_ESCALE && scale_type != H5Z_SO_INT) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_scaleoffset: invalid scale type"); + + if ((retVal = H5Pset_scaleoffset((hid_t)plist_id, (H5Z_SO_scale_type_t)scale_type, scale_factor)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shuffle + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shuffle + (JNIEnv *env, jclass clss, jlong plist) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_shuffle((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1shuffle */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_szip + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1szip + (JNIEnv *env, jclass clss, jlong plist, jint options_mask, jint pixels_per_block) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_szip((hid_t)plist, (unsigned int)options_mask, (unsigned int)pixels_per_block)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1szip */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_external + * Signature: (JLjava/lang/String;JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1external + (JNIEnv *env, jclass clss, jlong plist, jstring name, jlong offset, jlong size) +{ + const char *fileName = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Pset_external: file name not pinned"); + + if ((status = H5Pset_external((hid_t)plist, fileName, (off_t)offset, (hsize_t)size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (fileName) + UNPIN_JAVA_STRING(ENVONLY, name, fileName); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1external */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_external + * Signature: (JIJ[Ljava/lang/String;[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1external + (JNIEnv *env, jclass clss, jlong plist, jint idx, jlong name_size, + jobjectArray name, jlongArray size) +{ + jboolean isCopy; + jstring str; + hsize_t s; + off_t o; + jsize arrLen; + jlong *theArray = NULL; + char *file = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (name_size < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_external: name_size < 0"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, size)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_external: size array length < 0"); + } + if ((size != NULL) && (arrLen < 2)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_external: size input array < 2"); + + if (name_size > 0) + if (NULL == (file = (char *) HDmalloc(sizeof(char) * (size_t)name_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_external: memory allocation failed"); + + if ((status = H5Pget_external((hid_t) plist, (unsigned)idx, (size_t)name_size, + file, (off_t *)&o, (hsize_t *)&s)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL != size) { + PIN_LONG_ARRAY(ENVONLY, size, theArray, &isCopy, "H5Pget_external: size array not pinned"); + + theArray[0] = o; + theArray[1] = (jlong)s; + } + + if (NULL != file) { + file[name_size - 1] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, file))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_external: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, size, theArray, (status < 0) ? JNI_ABORT : 0); + if (file) + HDfree(file); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1external */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_external_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1external_1count + (JNIEnv *env, jclass clss, jlong plist) +{ + int retVal = -1; + + UNUSED(clss); + + if ((retVal = H5Pget_external_count((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1external_1count */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_virtual + * Signature: (JJLjava/lang/String;Ljava/lang/String;J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1virtual + (JNIEnv *env, jclass clss, jlong dcpl_id, jlong vspace_id, + jstring src_file_name, jstring src_dset_name, jlong src_space_id) +{ + const char *fstr = NULL; + const char *dstr = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, src_file_name, fstr, NULL, "H5Pset_virtual: src_file_name not pinned"); + PIN_JAVA_STRING(ENVONLY, src_dset_name, dstr, NULL, "H5Pset_virtual: src_dset_name not pinned"); + + if ((retVal = H5Pset_virtual((hid_t)dcpl_id, (hid_t)vspace_id, fstr, dstr, (hid_t)src_space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (dstr) + UNPIN_JAVA_STRING(ENVONLY, src_dset_name, dstr); + if (fstr) + UNPIN_JAVA_STRING(ENVONLY, src_file_name, fstr); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_count + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count + (JNIEnv *env, jclass clss, jlong dcpl_id) +{ + size_t s = 0; + + UNUSED(clss); + + if (H5Pget_virtual_count((hid_t)dcpl_id, &s) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)s; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_dsetname + * Signature: (JJ)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname + (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) +{ + ssize_t buf_size; + char *dname = NULL; + jstring str = NULL; + + UNUSED(clss); + + /* get the length of the filename */ + if ((buf_size = H5Pget_virtual_dsetname((hid_t)dcpl_id, (size_t)index, NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (dname = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_dsetname: memory allocation failed"); + + if (H5Pget_virtual_dsetname((hid_t)dcpl_id, (size_t)index, dname, (size_t)buf_size + 1) < 0) + H5_LIBRARY_ERROR(ENVONLY); + dname[buf_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, dname))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_dsetname: out of memory - unable to construct string from UTF characters"); + } + +done: + if (dname) + HDfree(dname); + + return (jstring)str; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_filename + * Signature: (JJ)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename + (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) +{ + ssize_t buf_size; + char *fname = NULL; + jstring str = NULL; + + UNUSED(clss); + + /* get the length of the filename */ + if ((buf_size = H5Pget_virtual_filename((hid_t)dcpl_id, (size_t)index, NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (fname = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_filename: memory allocation failed"); + + if (H5Pget_virtual_filename((hid_t)dcpl_id, (size_t)index, fname, (size_t)buf_size + 1) < 0) + H5_LIBRARY_ERROR(ENVONLY); + fname[buf_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, fname))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_filename: out of memory - unable to construct string from UTF characters"); + } + +done: + if (fname) + HDfree(fname); + + return (jstring)str; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_srcspace + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace + (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) +{ + hid_t space_id = H5I_INVALID_HID; + + UNUSED(clss); + + if ((space_id = H5Pget_virtual_srcspace((hid_t)dcpl_id, (size_t)index)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)space_id; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_vspace + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace + (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) +{ + hid_t space_id = H5I_INVALID_HID; + + UNUSED(clss); + + if ((space_id = H5Pget_virtual_vspace((hid_t)dcpl_id, (size_t)index)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)space_id; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_virtual_prefix + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix + (JNIEnv *env, jclass clss, jlong dapl_id, jstring prefix) +{ + const char *virtPrefix = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, prefix, virtPrefix, NULL, "H5Pset_virtual_prefix: virtual prefix not pinned"); + + if ((retVal = H5Pset_virtual_prefix((hid_t)dapl_id, virtPrefix)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (virtPrefix) + UNPIN_JAVA_STRING(ENVONLY, prefix, virtPrefix); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_prefix + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix + (JNIEnv *env, jclass clss, jlong dapl_id) +{ + ssize_t prefix_size = -1; + char *pre = NULL; + jstring str = NULL; + + UNUSED(clss); + + if ((prefix_size = H5Pget_virtual_prefix((hid_t)dapl_id, (char *)NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t) prefix_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_prefix: memory allocation failed"); + + if (H5Pget_virtual_prefix((hid_t)dapl_id, (char *)pre, (size_t) prefix_size + 1) < 0) + H5_LIBRARY_ERROR(ENVONLY); + pre[prefix_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_virtual_prefix: out of memory - unable to construct string from UTF characters"); + } + +done: + if (pre) + HDfree(pre); + + return (jstring)str; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pDCPLImp.h b/java/src/jni/h5pDCPLImp.h new file mode 100644 index 0000000..6e5c225 --- /dev/null +++ b/java/src/jni/h5pDCPLImp.h @@ -0,0 +1,396 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PDCPL +#define _Included_hdf_hdf5lib_H5_H5PDCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_layout + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1layout +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_layout + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1layout +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_chunk + * Signature: (JI[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1chunk +(JNIEnv *, jclass, jlong, jint, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_chunk + * Signature: (JI[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1chunk +(JNIEnv *, jclass, jlong, jint, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_chunk_opts + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_chunk_opts + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_dset_no_attrs_hint + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1dset_1no_1attrs_1hint + (JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_dset_no_attrs_hint + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1dset_1no_1attrs_1hint + (JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_deflate + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1deflate +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fill_value + * Signature: (JJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fill_1value +(JNIEnv *, jclass, jlong, jlong, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fill_value + * Signature: (JJ[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fill_1value +(JNIEnv *, jclass, jlong, jlong, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pfill_value_defined + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fill_time + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fill_1time +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fill_time + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fill_1time +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_alloc_time + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_alloc_time + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_filter + * Signature: (JIIJ[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1filter +(JNIEnv *, jclass, jlong, jint, jint, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pall_filters_avail + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_nfilters + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1nfilters +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter + * Signature: (JI[I[J[IJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter +(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter2 + * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter2 +(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter_by_id + * Signature: (JI[I[J[IJ[Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id +(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_filter_by_id2 + * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 +(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pmodify_filter + * Signature: (JIIJ[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pmodify_1filter +(JNIEnv *, jclass, jlong, jint, jint, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Premove_filter + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5P1remove_1filter +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fletcher32 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_nbit + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1nbit +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_scaleoffset + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shuffle + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shuffle +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_szip + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1szip +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_external + * Signature: (JLjava/lang/String;JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1external +(JNIEnv *, jclass, jlong, jstring, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_external + * Signature: (JIJ[Ljava/lang/String;[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1external +(JNIEnv *, jclass, jlong, jint, jlong, jobjectArray, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_external_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1external_1count +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_virtual + * Signature: (JJLjava/lang/String;Ljava/lang/String;J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1virtual +(JNIEnv *, jclass, jlong, jlong, jstring, jstring, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_count + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_dsetname + * Signature: (JJ)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_filename + * Signature: (JJ)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_srcspace + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_vspace + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_virtual_prefix + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix +(JNIEnv *, jclass, jlong, jstring); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_virtual_prefix + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix +(JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PDCPL */ diff --git a/java/src/jni/h5pDXPLImp.c b/java/src/jni/h5pDXPLImp.c new file mode 100644 index 0000000..2bdc36b --- /dev/null +++ b/java/src/jni/h5pDXPLImp.c @@ -0,0 +1,502 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pDXPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_buffer + * Signature: (JJ[B[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1buffer + (JNIEnv *env, jclass clss, jlong plist, jlong size, jbyteArray tconv, jbyteArray bkg) +{ +#ifdef notdef + jboolean isCopy; + jbyte *tconvP = NULL; + jbyte *bkgP = NULL; +#endif + herr_t status = FAIL; + + UNUSED(clss); +#ifndef notdef + UNUSED(plist); + UNUSED(size); + UNUSED(tconv); + UNUSED(bkg); +#endif + + H5_UNIMPLEMENTED(ENVONLY, "H5Pset_buffer: not implemented"); + + /* NOTE: DON'T IMPLEMENT THIS!!! */ +#ifdef notdef + if (NULL != tconv) + PIN_BYTE_ARRAY(ENVONLY, tconv, tconvP, &isCopy, "H5Pset_buffer: tconv not pinned"); + if (NULL != bkg) + PIN_BYTE_ARRAY(ENVONLY, bkg, bkgP, &isCopy, "H5Pset_buffer: bkg not pinned"); + + if ((status = H5Pset_buffer((hid_t)plist, (size_t)size, tconvP, bkgP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +#endif + +done: +#ifdef notdef + if (bkgP) + UNPIN_BYTE_ARRAY(ENVONLY, bkg, bkgP, (status < 0) ? JNI_ABORT : 0); + if (tconvP) + UNPIN_BYTE_ARRAY(ENVONLY, tconv, tconvP, (status < 0) ? JNI_ABORT : 0); +#endif + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1buffer */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_buffer + * Signature: (J[B[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1buffer + (JNIEnv *env, jclass clss, jlong plist, jbyteArray tconv, jbyteArray bkg) +{ +#ifdef notdef + jboolean isCopy; + jbyte *tconvP = NULL; + jbyte *bkgP = NULL; +#endif + herr_t status = FAIL; + + UNUSED(clss); +#ifndef notdef + UNUSED(plist); + UNUSED(tconv); + UNUSED(bkg); +#endif + + H5_UNIMPLEMENTED(ENVONLY, "H5Pget_buffer: not implemented"); + + /* NOTE: DON'T IMPLEMENT THIS!!! */ +#ifdef notdef + if (NULL == tconv) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_buffer: tconv input array is NULL"); + if (NULL == bkg) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_buffer: bkg array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, tconv, tconvP, &isCopy, "H5Pget_buffer: tconv not pinned"); + PIN_BYTE_ARRAY(ENVONLY, bkg, bkgP, &isCopy, "H5Pget_buffer: bkg not pinned"); + + if ((status = H5Pget_buffer((hid_t)plist, tconvP, bkgP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +#endif + +done: +#ifdef notdef + if (bkgP) + UNPIN_BYTE_ARRAY(ENVONLY, bkg, bkgP, (status < 0) ? JNI_ABORT : 0); + if (tconvP) + UNPIN_BYTE_ARRAY(ENVONLY, tconv, tconvP, (status < 0) ? JNI_ABORT : 0); +#endif + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1buffer */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_buffer_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size + (JNIEnv *env, jclass clss, jlong plist, jlong size) +{ + UNUSED(clss); + + if (H5Pset_buffer((hid_t)plist, (size_t)size, NULL, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_buffer_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size + (JNIEnv *env, jclass clss, jlong plist) +{ + size_t size = 0; + + UNUSED(clss); + + if (!(size = H5Pget_buffer((hid_t)plist, NULL, NULL))) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)size; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_preserve + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1preserve + (JNIEnv *env, jclass clss, jlong plist, jboolean status) +{ + hbool_t st = JNI_FALSE; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (JNI_TRUE == status) + st = TRUE; + else if (JNI_FALSE == status) + st = false; + else + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_preserve: status not TRUE or FALSE"); + + if ((retVal = H5Pset_preserve((hid_t)plist, st)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1preserve */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_preserve + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1preserve + (JNIEnv *env, jclass clss, jlong plist) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pget_preserve((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1preserve */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_edc_check + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1edc_1check + (JNIEnv *env, jclass clss, jlong plist, jint check) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_edc_check((hid_t)plist, (H5Z_EDC_t)check)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1edc_1check */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_edc_check + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1edc_1check + (JNIEnv *env, jclass clss, jlong plist) +{ + H5Z_EDC_t retVal = -1; + + UNUSED(clss); + + if ((retVal = H5Pget_edc_check((hid_t)plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1edc_1check */ + +/* + * TODO: H5Pset_filter_callback + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_data_transform + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1data_1transform + (JNIEnv *env, jclass clss, jlong plist_id, jstring expression) +{ + const char *express = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, expression, express, NULL, "H5Pset_data_transform: data transform expression not pinned"); + + if ((retVal = H5Pset_data_transform((hid_t)plist_id, express)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (express) + UNPIN_JAVA_STRING(ENVONLY, expression, express); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1data_1transform */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_data_transform + * Signature: (J[Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1data_1transform + (JNIEnv *env, jclass clss, jlong plist_id, jobjectArray expression, jlong size) +{ + jstring str = NULL; + char *express = NULL; + ssize_t express_size = -1; + + UNUSED(clss); + + if (size <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_data_transform: size <= 0"); + + if ((express_size = H5Pget_data_transform((hid_t)plist_id, (char *)NULL, (size_t)size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (express = (char *) HDmalloc(sizeof(char) * (size_t)express_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_data_transform: memory allocation failed"); + + if (H5Pget_data_transform((hid_t)plist_id, express, (size_t)express_size + 1) < 0) + H5_LIBRARY_ERROR(ENVONLY); + express[express_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, express))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_data_transform: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, expression, 0, str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (express) + HDfree(express); + + return (jlong)express_size; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1data_1transform */ + +/* + * TODO: H5Pset_type_conv_cb + */ + +/* + * TODO: H5Pget_type_conv_cb + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_hyper_vector_size + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size + (JNIEnv *env, jclass clss, jlong plist, jlong vector_size) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_hyper_vector_size((hid_t)plist, (size_t)vector_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_hyper_vector_size + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size + (JNIEnv *env, jclass clss, jlong plist, jlongArray vector_size) +{ + jboolean isCopy; + size_t size; + jlong *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == vector_size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_hyper_vector_size: vector_size is NULL"); + + PIN_LONG_ARRAY(ENVONLY, vector_size, theArray, &isCopy, "H5Pget_hyper_vector_size: vector_size not pinned"); + + if ((retVal = H5Pget_hyper_vector_size((hid_t)plist, &size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jlong)size; + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, vector_size, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_btree_ratios + * Signature: (JDDD)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios + (JNIEnv *env, jclass clss, jlong plist_id, jdouble left, jdouble middle, jdouble right) +{ + herr_t status = FAIL; + + UNUSED(clss); + + if ((status = H5Pset_btree_ratios((hid_t)plist_id, (double)left,(double)middle, (double)right)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_btree_ratios + * Signature: (J[D[D[D)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios + (JNIEnv *env, jclass clss, jlong plist_id, jdoubleArray left, + jdoubleArray middle, jdoubleArray right) +{ + jboolean isCopy; + jdouble *leftP = NULL; + jdouble *middleP = NULL; + jdouble *rightP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == left) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_btree_ratios: left input array is NULL"); + if (NULL == middle) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_btree_ratios: middle input array is NULL"); + if (NULL == right) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_btree_ratios: right input array is NULL"); + + PIN_DOUBLE_ARRAY(ENVONLY, left, leftP, &isCopy, "H5Pget_btree_ratios: left array not pinned"); + PIN_DOUBLE_ARRAY(ENVONLY, middle, middleP, &isCopy, "H5Pget_btree_ratios: middle array not pinned"); + PIN_DOUBLE_ARRAY(ENVONLY, right, rightP, &isCopy, "H5Pget_btree_ratios: right array not pinned"); + + if ((status = H5Pget_btree_ratios((hid_t)plist_id, (double *)leftP, + (double *)middleP, (double *)rightP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (rightP) + UNPIN_DOUBLE_ARRAY(ENVONLY, right, rightP, (status < 0) ? JNI_ABORT : 0); + if (middleP) + UNPIN_DOUBLE_ARRAY(ENVONLY, middle, middleP, (status < 0) ? JNI_ABORT : 0); + if (leftP) + UNPIN_DOUBLE_ARRAY(ENVONLY, left, leftP, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios */ + +/* + * TODO: H5Pset_vlen_mem_manager + */ + +/* + * TODO: H5Pget_vlen_mem_manager + */ + +/* + * TODO: H5Pset_dxpl_mpio + */ + +/* + * TODO: H5Pget_dxpl_mpio + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt_num + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt_ratio + */ + +/* + * TODO: H5Pset_dxpl_mpio_collective_opt + */ + +/* + * TODO: H5Pget_mpio_actual_chunk_opt_mode + */ + +/* + * TODO: H5Pget_mpio_actual_io_mode + */ + +/* + * TODO: H5Pget_mpio_no_collective_cause + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pDXPLImp.h b/java/src/jni/h5pDXPLImp.h new file mode 100644 index 0000000..d62f9c5 --- /dev/null +++ b/java/src/jni/h5pDXPLImp.h @@ -0,0 +1,209 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PDXPL +#define _Included_hdf_hdf5lib_H5_H5PDXPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_buffer + * Signature: (JJ[B[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1buffer +(JNIEnv *, jclass, jlong, jlong, jbyteArray, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_buffer + * Signature: (J[B[B)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1buffer +(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_buffer_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_buffer_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_preserve + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1preserve +(JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_preserve + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1preserve +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_edc_check + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1edc_1check +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_edc_check + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1edc_1check +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pset_filter_callback + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_data_transform + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1data_1transform +(JNIEnv *, jclass, jlong, jstring); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_data_transform + * Signature: (J[Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1data_1transform +(JNIEnv *, jclass, jlong, jobjectArray, jlong); + +/* + * TODO: H5Pset_type_conv_cb + */ + +/* + * TODO: H5Pget_type_conv_cb + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_hyper_vector_size + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_hyper_vector_size + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size +(JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_btree_ratios + * Signature: (JDDD)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios +(JNIEnv *, jclass, jlong, jdouble, jdouble, jdouble); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_btree_ratios + * Signature: (J[D[D[D)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios +(JNIEnv *, jclass, jlong, jdoubleArray, jdoubleArray, jdoubleArray); + +/* + * TODO: H5Pset_vlen_mem_manager + */ + +/* + * TODO: H5Pget_vlen_mem_manager + */ + +/* + * TODO: H5Pset_dxpl_mpio + */ + +/* + * TODO: H5Pget_dxpl_mpio + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt_num + */ + +/* + * TODO: H5Pset_dxpl_mpio_chunk_opt_ratio + */ + +/* + * TODO: H5Pset_dxpl_mpio_collective_opt + */ + +/* + * TODO: H5Pget_mpio_actual_chunk_opt_mode + */ + +/* + * TODO: H5Pget_mpio_actual_io_mode + */ + +/* + * TODO: H5Pget_mpio_no_collective_cause + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PDXPL */ diff --git a/java/src/jni/h5pFAPLImp.c b/java/src/jni/h5pFAPLImp.c new file mode 100644 index 0000000..aec6581 --- /dev/null +++ b/java/src/jni/h5pFAPLImp.c @@ -0,0 +1,1624 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5util.h" +#include "h5pFAPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * TODO: H5Pset_driver + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_driver + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1driver + (JNIEnv *env, jclass clss, jlong plist) +{ + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if ((retVal = H5Pget_driver((hid_t) plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1driver */ + +/* + * TODO: H5Pget_driver_info + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fclose_degree + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree + (JNIEnv *env, jclass clss, jlong plist, jint fc_degree) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fclose_degree((hid_t)plist, (H5F_close_degree_t)fc_degree)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fclose_degree + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree + (JNIEnv *env, jclass clss, jlong plist) +{ + H5F_close_degree_t degree = H5F_CLOSE_DEFAULT; + + UNUSED(clss); + + if (H5Pget_fclose_degree((hid_t)plist, °ree) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)degree; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_core + * Signature: (JJZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core + (JNIEnv *env, jclass clss, jlong fapl_id, jlong increment, jboolean backing_store) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fapl_core((hid_t)fapl_id, (size_t)increment, (hbool_t)backing_store)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_core + * Signature: (J[J[Z)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core + (JNIEnv *env, jclass clss, jlong fapl_id, jlongArray increment, jbooleanArray backing_store) +{ + jboolean isCopy; + jboolean *backArray = NULL; + jlong *incArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == increment) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_fapl_core: increment is NULL"); + if (NULL == backing_store) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_fapl_core: backing_store is NULL"); + + PIN_LONG_ARRAY(ENVONLY, increment, incArray, &isCopy, "H5Pget_fapl_core: incArray not pinned"); + PIN_BOOL_ARRAY(ENVONLY, backing_store, backArray, &isCopy, "H5Pget_fapl_core: backArray not pinned"); + + { + /* Direct cast (size_t *)variable fails on 32-bit environment */ + long long inc_temp = *incArray; + size_t inc_t = (size_t) inc_temp; + + if ((status = H5Pget_fapl_core((hid_t)fapl_id, &inc_t, (hbool_t *)backArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + *incArray = (jlong)inc_t; + } + +done: + if (backArray) + UNPIN_BOOL_ARRAY(ENVONLY, backing_store, backArray, (status < 0) ? JNI_ABORT : 0); + if (incArray) + UNPIN_LONG_ARRAY(ENVONLY, increment, incArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core */ + +/* + * TODO: H5Pset_core_write_tracking + */ + +/* + * TODO: H5Pget_core_write_tracking + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_direct + * Signature: (JJJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct + (JNIEnv *env, jclass clss, jlong fapl_id, jlong alignment, + jlong block_size, jlong cbuf_size) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + +#ifdef H5_HAVE_DIRECT + if ((retVal = H5Pset_fapl_direct((hid_t)fapl_id, (size_t)alignment, (size_t)block_size, (size_t)cbuf_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: +#else + UNUSED(env); + UNUSED(fapl_id); + UNUSED(alignment); + UNUSED(block_size); + UNUSED(cbuf_size); +#endif + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_direct + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct + (JNIEnv *env, jclass clss, jlong fapl_id, jlongArray info) +{ +#ifdef H5_HAVE_DIRECT + jboolean isCopy; + jlong *theArray = NULL; + size_t alignment = 0; + size_t block_size = 0; + size_t cbuf_size = 0; + jsize arrLen; +#endif + herr_t retVal = FAIL; + + UNUSED(clss); + +#ifdef H5_HAVE_DIRECT + if (NULL == info) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_fapl_direct: info input array is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, info)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_fapl_direct: info array length < 0"); + } + if (arrLen < 3) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_fapl_direct: info input array < 3"); + + PIN_LONG_ARRAY(ENVONLY, info, theArray, &isCopy, "H5Pget_fapl_direct: info not pinned"); + + if ((retVal = H5Pget_fapl_direct((hid_t)fapl_id, &alignment, &block_size, &cbuf_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jlong)alignment; + theArray[1] = (jlong)block_size; + theArray[2] = (jlong)cbuf_size; + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, info, theArray, (retVal < 0) ? JNI_ABORT : 0); +#else + UNUSED(env); + UNUSED(fapl_id); + UNUSED(info); +#endif + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_family + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family + (JNIEnv *env, jclass clss, jlong plist, jlong memb_size, jlong memb_plist) +{ + long ms = (long)memb_size; + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fapl_family((hid_t)plist, (hsize_t)ms, (hid_t)memb_plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_family + * Signature: (J[J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family + (JNIEnv *env, jclass clss, jlong tid, jlongArray memb_size, jlongArray memb_plist) +{ + jboolean isCopy; + hsize_t *sa = NULL; + size_t i; + jlong *sizeArray = NULL; + jlong *plistArray = NULL; + jsize rank; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == memb_size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_family: memb_size is NULL"); + if (NULL == memb_plist) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_family: memb_plist is NULL"); + + PIN_LONG_ARRAY(ENVONLY, memb_size, sizeArray, &isCopy, "H5Pget_family: sizeArray not pinned"); + + if ((rank = ENVPTR->GetArrayLength(ENVONLY, memb_size)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_family: memb_size array length < 0"); + } + + if (NULL == (sa = (hsize_t *) HDmalloc((size_t) rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_family: memory allocation failed"); + + PIN_LONG_ARRAY(ENVONLY, memb_plist, plistArray, &isCopy, "H5Pget_family: plistArray not pinned"); + + if ((status = H5Pget_fapl_family((hid_t)tid, sa, (hid_t *)plistArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (size_t) rank; i++) + sizeArray[i] = (jlong)sa[i]; + +done: + if (plistArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_plist, plistArray, (status < 0) ? JNI_ABORT : 0); + if (sa) + HDfree(sa); + if (sizeArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_size, sizeArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_family_offset + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1family_1offset + (JNIEnv *env, jclass clss, jlong fapl_id, jlong offset) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_family_offset((hid_t)fapl_id, (hsize_t)offset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1family_1offset */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_family_offset + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1family_1offset + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + hsize_t offset = 0; + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pget_family_offset((hid_t)fapl_id, &offset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)offset; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1family_1offset */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_log + * Signature: (JLjava/lang/String;JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log + (JNIEnv *env, jclass clss, jlong fapl_id, jstring logfile, jlong flags, jlong buf_size) +{ + const char *pLogfile = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, logfile, pLogfile, NULL, "H5Pset_fapl_log: log file name not pinned"); + + if ((retVal = H5Pset_fapl_log((hid_t)fapl_id, pLogfile, (unsigned long long)flags, (size_t)buf_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (pLogfile) + UNPIN_JAVA_STRING(ENVONLY, logfile, pLogfile); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log */ + +/* + * TODO: H5Pset_fapl_mpio + */ + +/* + * TODO: H5Pget_fapl_mpio + */ + +/* + * TODO: H5Pset_fapl_mpiposix + */ + +/* + * TODO: H5Pget_fapl_mpiposix + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_multi + * Signature: (J[I[J[Ljava/lang/String;[JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi + (JNIEnv *env, jclass clss, jlong tid, jintArray memb_map, + jlongArray memb_fapl, jobjectArray memb_name, jlongArray memb_addr, jboolean relax) +{ + const char * const *mName = NULL; + jboolean isCopy; + jboolean bb; + jobject o; + jstring rstring; + jclass Sjc; + size_t i; + jlong *thefaplArray = NULL; + jlong *theaddrArray = NULL; + jint *themapArray = NULL; + char *member_name[H5FD_MEM_NTYPES]; + herr_t status = FAIL; + + UNUSED(clss); + + HDmemset(member_name, 0, H5FD_MEM_NTYPES * sizeof(char *)); + + if (memb_map) + PIN_INT_ARRAY(ENVONLY, memb_map, themapArray, &isCopy, "H5Pset_fapl_multi: memb_map not pinned"); + if (memb_fapl) + PIN_LONG_ARRAY(ENVONLY, memb_fapl, thefaplArray, &isCopy, "H5Pset_fapl_multi: memb_fapl not pinned"); + if (memb_addr) + PIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, &isCopy, "H5Pset_fapl_multi: memb_addr not pinned"); + + if (memb_name) { + jstring obj; + + for (i = 0; i < H5FD_MEM_NTYPES; i++) { + const char *utf8 = NULL; + size_t str_len; + + if (NULL == (obj = (jstring) ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray) memb_name, (jsize) i))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + /* + * If the string object was NULL, skip it. + */ + member_name[i] = NULL; + continue; + } + + /* + * length = ENVPTR->GetStringUTFLength(ENVONLY, obj); + * CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + */ + + PIN_JAVA_STRING(ENVONLY, obj, utf8, NULL, "H5Pset_fapl_multi: string not pinned"); + + str_len = HDstrlen(utf8); + + if (NULL == (member_name[i] = (char *) HDmalloc(str_len + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: memory allocation failed"); + + HDstrncpy(member_name[i], utf8, str_len + 1); + + UNPIN_JAVA_STRING(ENVONLY, obj, utf8); + utf8 = NULL; + + ENVPTR->DeleteLocalRef(ENVONLY, obj); + } + + mName = (const char * const *)member_name; + } + + if ((status = H5Pset_fapl_multi((hid_t)tid, (const H5FD_mem_t *)themapArray, (const hid_t *)thefaplArray, + mName, (const haddr_t *)theaddrArray, (hbool_t)relax)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (memb_name && mName) { + if (NULL == (Sjc = ENVPTR->FindClass(ENVONLY, "java/lang/String"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + for (i = 0; i < H5FD_MEM_NTYPES; i++) { + if (NULL == (rstring = ENVPTR->NewStringUTF(ENVONLY, member_name[i]))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: out of memory - unable to construct string from UTF characters"); + } + + if (NULL == (o = ENVPTR->GetObjectArrayElement(ENVONLY, memb_name, (jsize) i))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + /* + * If the string object was NULL, skip it. + */ + ENVPTR->DeleteLocalRef(ENVONLY, rstring); + continue; + } + + if (JNI_TRUE == (bb = ENVPTR->IsInstanceOf(ENVONLY, o, Sjc))) { + ENVPTR->SetObjectArrayElement(ENVONLY, memb_name, (jsize) i, (jobject)rstring); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + + ENVPTR->DeleteLocalRef(ENVONLY, o); + ENVPTR->DeleteLocalRef(ENVONLY, rstring); + + HDfree(member_name[i]); + member_name[i] = NULL; + } + } + +done: + h5str_array_free(member_name, H5FD_MEM_NTYPES); + if (theaddrArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, (status < 0) ? JNI_ABORT : 0); + if (thefaplArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_fapl, thefaplArray, (status < 0) ? JNI_ABORT : 0); + if (themapArray) + UNPIN_INT_ARRAY(ENVONLY, memb_map, themapArray, (status < 0) ? JNI_ABORT : 0); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_multi + * Signature: (J[I[J[Ljava/lang/String;[J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi + (JNIEnv *env, jclass clss, jlong tid, jintArray memb_map, + jlongArray memb_fapl, jobjectArray memb_name, jlongArray memb_addr) +{ + jboolean isCopy; + jstring str; + herr_t status = FAIL; + size_t i; + jlong *thefaplArray = NULL; + jlong *theaddrArray = NULL; + jint *themapArray = NULL; + char **mName = NULL; + int relax = 0; + int retVal = 0; + + UNUSED(clss); + + if (memb_map) + PIN_INT_ARRAY(ENVONLY, memb_map, themapArray, &isCopy, "H5Pget_fapl_multi: memb_map not pinned"); + if (memb_fapl) + PIN_LONG_ARRAY(ENVONLY, memb_fapl, thefaplArray, &isCopy, "H5Pget_fapl_multi: memb_fapl not pinned"); + if (memb_addr) + PIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, &isCopy, "H5Pget_fapl_multi: memb_addr not pinned"); + if (memb_name) + if (NULL == (mName = (char **) HDcalloc(H5FD_MEM_NTYPES, sizeof(*mName)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_multi: memory allocation failed"); + + if ((status = H5Pget_fapl_multi((hid_t)tid, (H5FD_mem_t *)themapArray, (hid_t *)thefaplArray, + mName, (haddr_t *)theaddrArray, (hbool_t *)&relax)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (memb_name && mName) { + for (i = 0; i < H5FD_MEM_NTYPES; i++) { + if (mName[i]) { + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, mName[i]))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_fapl_multi: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, memb_name, (jsize) i, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->DeleteLocalRef(ENVONLY, str); + } + } + } + + retVal = (relax != 0); + +done: + h5str_array_free(mName, H5FD_MEM_NTYPES); + if (theaddrArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, (status < 0) ? JNI_ABORT : 0); + if (thefaplArray) + UNPIN_LONG_ARRAY(ENVONLY, memb_fapl, thefaplArray, (status < 0) ? JNI_ABORT : 0); + if (themapArray) + UNPIN_INT_ARRAY(ENVONLY, memb_map, themapArray, (status < 0) ? JNI_ABORT : 0); + + return (jboolean)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi */ + +/* + * TODO: H5Pset_multi_type + */ + +/* + * TODO: H5Pget_multi_type + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_split + * Signature: (JLjava/lang/String;JLjava/lang/String;J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split + (JNIEnv *env, jclass clss, jlong fapl_id, jstring metaext, jlong meta_pl_id, jstring rawext, jlong raw_pl_id) +{ + const char *mstr = NULL; + const char *rstr = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, metaext, mstr, NULL, "H5Pset_fapl_split: metaext not pinned"); + PIN_JAVA_STRING(ENVONLY, rawext, rstr, NULL, "H5Pset_fapl_split: rawext not pinned"); + + if ((retVal = H5Pset_fapl_split((hid_t)fapl_id, mstr, (hid_t)meta_pl_id, rstr, (hid_t)raw_pl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (rstr) + UNPIN_JAVA_STRING(ENVONLY, rawext, rstr); + if (mstr) + UNPIN_JAVA_STRING(ENVONLY, metaext, mstr); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_sec2 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fapl_sec2((hid_t) fapl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_stdio + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_fapl_stdio((hid_t) fapl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_windows + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + +#ifdef H5_HAVE_WINDOWS + if ((retVal = H5Pset_fapl_windows((hid_t) fapl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: +#else + UNUSED(env); + UNUSED(fapl_id); +#endif + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows */ + +/* + * TODO: H5Pset_file_image + */ + +/* + * TODO: H5Pget_file_image + */ + +/* + * TODO: H5Pset_file_image_callbacks + */ + +/* + * TODO: H5Pget_file_image_callbacks + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_meta_block_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size + (JNIEnv *env, jclass clss, jlong plist, jlong size) +{ + long sz = (long)size; + + UNUSED(clss); + + if (H5Pset_meta_block_size((hid_t)plist, (hsize_t)sz) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_meta_block_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size + (JNIEnv *env, jclass clss, jlong plist) +{ + hsize_t s = 0; + + UNUSED(clss); + + if (H5Pget_meta_block_size((hid_t)plist, &s) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)s; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size */ + +/* + * TODO: H5Pset_page_buffer_size + */ + +/* + * TODO: H5Pget_page_buffer_size + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sieve_buf_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size + (JNIEnv *env, jclass clss, jlong plist, jlong size) +{ + size_t sz = (size_t)size; + + UNUSED(clss); + + if (H5Pset_sieve_buf_size((hid_t)plist, (size_t)sz) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sieve_buf_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size + (JNIEnv *env, jclass clss, jlong plist) +{ + size_t s = 0; + + UNUSED(clss); + + if (H5Pget_sieve_buf_size((hid_t)plist, &s) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)s; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_alignment + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1alignment + (JNIEnv *env, jclass clss, jlong plist, jlong threshold, jlong alignment) +{ + long thr = (long)threshold; + long align = (long)alignment; + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_alignment((hid_t)plist, (hsize_t)thr, (hsize_t)align)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1alignment */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_alignment + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1alignment + (JNIEnv *env, jclass clss, jlong plist, jlongArray alignment) +{ + jboolean isCopy; + hsize_t t = 0; + hsize_t a = 0; + jsize arrLen; + jlong *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == alignment) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_alignment: input alignment is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, alignment)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_alignment: alignment array length < 0"); + } + if (arrLen < 2) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_alignment: alignment input array < 2"); + + PIN_LONG_ARRAY(ENVONLY, alignment, theArray, &isCopy, "H5Pget_alignment: input array not pinned"); + + if ((status = H5Pget_alignment((hid_t)plist, &t, &a)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jlong)t; + theArray[1] = (jlong)a; + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, alignment, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1alignment */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_cache + * Signature: (JIJJD)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1cache + (JNIEnv *env, jclass clss, jlong plist, jint mdc_nelmts, jlong rdcc_nelmts, + jlong rdcc_nbytes, jdouble rdcc_w0) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_cache((hid_t)plist, (int)mdc_nelmts, (size_t)rdcc_nelmts, + (size_t)rdcc_nbytes, (double) rdcc_w0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1cache */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_cache + * Signature: (J[I[J[J[D)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1cache + (JNIEnv *env, jclass clss, jlong plist, jintArray mdc_nelmts, + jlongArray rdcc_nelmts, jlongArray rdcc_nbytes, jdoubleArray rdcc_w0) +{ + jboolean isCopy; + jdouble *w0Array = NULL; + jlong *rdcc_nelmtsArray = NULL; + jlong *nbytesArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + UNUSED(mdc_nelmts); + + if (NULL != rdcc_w0) + PIN_DOUBLE_ARRAY(ENVONLY, rdcc_w0, w0Array, &isCopy, "H5Pget_cache: rdcc_w0 array not pinned"); + if (NULL != rdcc_nelmts) + PIN_LONG_ARRAY(ENVONLY, rdcc_nelmts, rdcc_nelmtsArray, &isCopy, "H5Pget_cache: rdcc_nelmts array not pinned"); + if (NULL != rdcc_nbytes) + PIN_LONG_ARRAY(ENVONLY, rdcc_nbytes, nbytesArray, &isCopy, "H5Pget_cache: nbytesArray array not pinned"); + + { + /* direct cast (size_t *)variable fails on 32-bit environment */ + long long rdcc_nelmts_temp = *rdcc_nelmtsArray; + long long nbytes_temp = *nbytesArray; + size_t rdcc_nelmts_t = (size_t) rdcc_nelmts_temp; + size_t nbytes_t = (size_t) nbytes_temp; + + if ((status = H5Pget_cache((hid_t)plist, (int *)NULL, &rdcc_nelmts_t, + &nbytes_t, (double *)w0Array)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + *rdcc_nelmtsArray = (jlong)rdcc_nelmts_t; + *nbytesArray = (jlong)nbytes_t; + } /* end direct cast special */ + +done: + if (nbytesArray) + UNPIN_LONG_ARRAY(ENVONLY, rdcc_nbytes, nbytesArray, (status < 0) ? JNI_ABORT : 0); + if (rdcc_nelmtsArray) + UNPIN_LONG_ARRAY(ENVONLY, rdcc_nelmts, rdcc_nelmtsArray, (status < 0) ? JNI_ABORT : 0); + if (w0Array) + UNPIN_DOUBLE_ARRAY(ENVONLY, rdcc_w0, w0Array, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1cache */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_file_cache_size + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size + (JNIEnv *env, jclass clss, jlong plist, jint size) +{ + unsigned sz = (unsigned)size; + + UNUSED(clss); + + if (H5Pset_elink_file_cache_size((hid_t)plist, (unsigned)sz) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_file_cache_size + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size + (JNIEnv *env, jclass clss, jlong plist) +{ + unsigned s = 0; + + UNUSED(clss); + + if (H5Pget_elink_file_cache_size((hid_t)plist, &s) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)s; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_evict_on_close + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close + (JNIEnv *env, jclass clss, jlong fapl_id, jboolean evict_on_close) +{ + hbool_t evict_on_close_val = FALSE; + herr_t retVal = FAIL; + + UNUSED(clss); + + evict_on_close_val = (evict_on_close == JNI_TRUE) ? TRUE : FALSE; + + if ((retVal = H5Pset_evict_on_close((hid_t)fapl_id, (hbool_t)evict_on_close_val)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_evict_on_close + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + hbool_t evict_on_close_val = FALSE; + jboolean bval = JNI_FALSE; + + UNUSED(clss); + + if (H5Pget_evict_on_close((hid_t)fapl_id, (hbool_t *)&evict_on_close_val) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (evict_on_close_val == TRUE) ? JNI_TRUE : JNI_FALSE; + +done: + return bval; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_metadata_read_attempts + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts + (JNIEnv *env, jclass clss, jlong plist_id, jlong attempts) +{ + UNUSED(clss); + + if (attempts <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_metadata_read_attempts: attempts <= 0"); + + if (H5Pset_metadata_read_attempts((hid_t)plist_id, (unsigned)attempts) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_metadata_read_attempts + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts + (JNIEnv *env, jclass clss, jlong plist_id) +{ + unsigned attempts = 0; + + UNUSED(clss); + + if (H5Pget_metadata_read_attempts((hid_t)plist_id, &attempts) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong) attempts; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_mdc_config + * Signature: (JLhdf/hdf5lib/structs/H5AC_cache_config_t;)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config + (JNIEnv *env, jclass clss, jlong plist, jobject cache_config) +{ + H5AC_cache_config_t cacheinfo; + const char *str = NULL; + jfieldID fid; + jstring j_str; + jclass cls; + jint flash_incr_mode; + jint incr_mode; + jint decr_mode; + herr_t status = FAIL; + + UNUSED(clss); + + HDmemset(&cacheinfo, 0, sizeof(H5AC_cache_config_t)); + + if (NULL == (cls = ENVPTR->GetObjectClass(ENVONLY, cache_config))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "version", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.version = ENVPTR->GetIntField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "rpt_fcn_enabled", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.rpt_fcn_enabled = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "open_trace_file", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.open_trace_file = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "close_trace_file", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.close_trace_file = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "trace_file_name", "Ljava/lang/String;"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (j_str = (jstring)ENVPTR->GetObjectField(ENVONLY, cache_config, fid))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_JAVA_STRING(ENVONLY, j_str, str, NULL, "H5Pset_mdc_config: cache_config not pinned"); + + HDstrncpy(cacheinfo.trace_file_name, str, H5AC__MAX_TRACE_FILE_NAME_LEN + 1); + + UNPIN_JAVA_STRING(ENVONLY, j_str, str); + str = NULL; + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "evictions_enabled", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.evictions_enabled = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "set_initial_size", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.set_initial_size = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "initial_size", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.initial_size = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "min_clean_fraction", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.min_clean_fraction = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "max_size", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.max_size = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "min_size", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.min_size = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "epoch_length", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.epoch_length = (long int)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "incr_mode", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + incr_mode = ENVPTR->GetIntField(ENVONLY, cache_config, fid); /*(enum H5C_cache_incr_mode) */ + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + cacheinfo.incr_mode = (enum H5C_cache_incr_mode) incr_mode; + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "lower_hr_threshold", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.lower_hr_threshold = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "increment", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.increment = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "apply_max_increment", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.apply_max_increment = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "max_increment", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.max_increment = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "flash_incr_mode", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + flash_incr_mode = ENVPTR->GetIntField(ENVONLY, cache_config, fid); /*(enum H5C_cache_flash_incr_mode) */ + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + cacheinfo.flash_incr_mode = (enum H5C_cache_flash_incr_mode) flash_incr_mode; + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "flash_multiple", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.flash_multiple = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "flash_threshold", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.flash_threshold = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "decr_mode", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + decr_mode = ENVPTR->GetIntField(ENVONLY, cache_config, fid); /*(enum H5C_cache_decr_mode) */ + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + cacheinfo.decr_mode = (enum H5C_cache_decr_mode) decr_mode; + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "upper_hr_threshold", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.upper_hr_threshold = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "decrement", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.decrement = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "apply_max_decrement", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.apply_max_decrement = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "max_decrement", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.max_decrement = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "epochs_before_eviction", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.epochs_before_eviction = ENVPTR->GetIntField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "apply_empty_reserve", "Z"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.apply_empty_reserve = ENVPTR->GetBooleanField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "empty_reserve", "D"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.empty_reserve = ENVPTR->GetDoubleField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "dirty_bytes_threshold", "J"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.dirty_bytes_threshold = (size_t)ENVPTR->GetLongField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "metadata_write_strategy", "I"))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + cacheinfo.metadata_write_strategy = ENVPTR->GetIntField(ENVONLY, cache_config, fid); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((status = H5Pset_mdc_config((hid_t)plist, &cacheinfo)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (str) + UNPIN_JAVA_STRING(ENVONLY, j_str, str); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_mdc_config + * Signature: (J)Lhdf/hdf5lib/structs/H5AC_cache_config_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config + (JNIEnv *env, jclass clss, jlong plist) +{ + H5AC_cache_config_t cacheinfo; + jstring j_str = NULL; + jvalue args[30]; + herr_t status = FAIL; + jobject ret_obj = NULL; + + UNUSED(clss); + + HDmemset(&cacheinfo, 0, sizeof(H5AC_cache_config_t)); + cacheinfo.version = H5AC__CURR_CACHE_CONFIG_VERSION; + + if ((status = H5Pget_mdc_config((hid_t)plist, &cacheinfo)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + args[0].i = cacheinfo.version; + args[1].z = cacheinfo.rpt_fcn_enabled; + args[2].z = cacheinfo.open_trace_file; + args[3].z = cacheinfo.close_trace_file; + + if (NULL != cacheinfo.trace_file_name) { + if (NULL == (j_str = ENVPTR->NewStringUTF(ENVONLY, cacheinfo.trace_file_name))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_config: out of memory - unable to construct string from UTF characters"); + } + } + + args[4].l = j_str; + args[5].z = cacheinfo.evictions_enabled; + args[6].z = cacheinfo.set_initial_size; + args[7].j = (jlong)cacheinfo.initial_size; + args[8].d = cacheinfo.min_clean_fraction; + args[9].j = (jlong)cacheinfo.max_size; + args[10].j = (jlong)cacheinfo.min_size; + args[11].j = cacheinfo.epoch_length; + args[12].i = cacheinfo.incr_mode; + args[13].d = cacheinfo.lower_hr_threshold; + args[14].d = cacheinfo.increment; + args[15].z = cacheinfo.apply_max_increment; + args[16].j = (jlong)cacheinfo.max_increment; + args[17].i = cacheinfo.flash_incr_mode; + args[18].d = cacheinfo.flash_multiple; + args[19].d = cacheinfo.flash_threshold; + args[20].i = cacheinfo.decr_mode; + args[21].d = cacheinfo.upper_hr_threshold; + args[22].d = cacheinfo.decrement; + args[23].z = cacheinfo.apply_max_decrement; + args[24].j = (jlong)cacheinfo.max_decrement; + args[25].i = cacheinfo.epochs_before_eviction; + args[26].z = cacheinfo.apply_empty_reserve; + args[27].d = cacheinfo.empty_reserve; + args[28].j = (jlong)cacheinfo.dirty_bytes_threshold; + args[29].i = cacheinfo.metadata_write_strategy; + + CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5AC_cache_config_t", "(IZZZLjava/lang/String;ZZJDJJJIDDZJIDDIDDZJIZDJI)V", args, ret_obj); + +done: + return ret_obj; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config */ + +/* + * TODO: H5Pset_mdc_image_config + */ + +/* + * TODO: H5Pget_mdc_image_config + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_mdc_log_options + * Signature: (JZLjava/lang/String;Z)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options + (JNIEnv *env, jclass clss, jlong fapl_id, jboolean is_enabled, jstring location, jboolean start_on_access) +{ + const char *locStr = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, location, locStr, NULL, "H5Pset_mdc_log_options: location string not pinned"); + + if ((retVal = H5Pset_mdc_log_options((hid_t)fapl_id, (hbool_t)is_enabled, locStr, (hbool_t)start_on_access)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (locStr) + UNPIN_JAVA_STRING(ENVONLY, location, locStr); +} /* end Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_mdc_log_options + * Signature: (J[Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options + (JNIEnv *env, jclass clss, jlong fapl_id, jbooleanArray mdc_log_options) +{ + jboolean isCopy; + jboolean *mdc_log_options_ptr = NULL; + hbool_t is_enabled; + hbool_t start_on_access; + ssize_t status = -1; + size_t location_size; + jsize arrLen; + char *lname = NULL; + jstring str = NULL; + + UNUSED(clss); + + if (NULL == mdc_log_options) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_mdc_log_options: mdc_log_options is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, mdc_log_options)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_mdc_log_options: mdc_log_options array length < 0"); + } + if (arrLen < 2) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_mdc_log_options: length of mdc_log_options < 2"); + + PIN_BOOL_ARRAY(ENVONLY, mdc_log_options, mdc_log_options_ptr, &isCopy, "H5Pget_mdc_log_options: mdc_log_options array not pinned"); + + /* get the length of the filename */ + if (H5Pget_mdc_log_options((hid_t)fapl_id, &is_enabled, NULL, &location_size, &start_on_access) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!location_size) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_mdc_log_options: location_size is 0"); + + location_size++; /* add extra space for the null terminator */ + if (NULL == (lname = (char *) HDmalloc(sizeof(char) * location_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_log_options: memory allocation failed"); + + if ((status = H5Pget_mdc_log_options((hid_t)fapl_id, &is_enabled, lname, &location_size, &start_on_access)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + lname[location_size - 1] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, lname))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_mdc_log_options: out of memory - unable to construct string from UTF characters"); + } + + mdc_log_options_ptr[0] = (jboolean)is_enabled; + mdc_log_options_ptr[1] = (jboolean)start_on_access; + +done: + if (lname) + HDfree(lname); + if (mdc_log_options_ptr) + UNPIN_BOOL_ARRAY(ENVONLY, mdc_log_options, mdc_log_options_ptr, (status < 0) ? JNI_ABORT : 0); + + return (jstring)str; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options */ + +/* + * TODO: H5Pset_all_coll_metadata_ops + */ + +/* + * TODO: H5Pget_all_coll_metadata_ops + */ + +/* + * TODO: H5Pset_coll_metadata_write + */ + +/* + * TODO: H5Pget_coll_metadata_write + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_gc_references + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1gc_1references + (JNIEnv *env, jclass clss, jlong fapl_id, jboolean gc_ref) +{ + unsigned gc_ref_val = 0; + herr_t retVal = FAIL; + + UNUSED(clss); + + gc_ref_val = (gc_ref == JNI_TRUE) ? 1 : 0; + + if ((retVal = H5Pset_gc_references((hid_t)fapl_id, gc_ref_val)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1gc_1references */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_gc_references + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1gc_1references + (JNIEnv *env, jclass clss, jlong fapl_id) +{ + unsigned gc_ref_val = 0; + jboolean bval = JNI_FALSE; + + UNUSED(clss); + + if (H5Pget_gc_references((hid_t)fapl_id, (unsigned *)&gc_ref_val) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (gc_ref_val == 1) ? JNI_TRUE : JNI_FALSE; + +done: + return bval; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1gc_1references */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_small_data_block_size + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size + (JNIEnv *env, jclass clss, jlong plist, jlong size) +{ + long sz = (long)size; + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_small_data_block_size((hid_t)plist, (hsize_t)sz)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_small_data_block_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size + (JNIEnv *env, jclass clss, jlong plist) +{ + hsize_t s = 0; + + UNUSED(clss); + + if (H5Pget_small_data_block_size((hid_t)plist, &s) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)s; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_libver_bounds + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds + (JNIEnv *env, jclass clss, jlong fapl_id, jint low, jint high) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_libver_bounds((hid_t)fapl_id, (H5F_libver_t)low, (H5F_libver_t)high)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_libver_bounds + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds + (JNIEnv *env, jclass clss, jlong fapl_id, jintArray libver) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == libver) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_libver_bounds: libversion bounds is NULL"); + + PIN_INT_ARRAY(ENVONLY, libver, theArray, &isCopy, "H5Pget_libver_bounds: input not pinned"); + + if ((retVal = H5Pget_libver_bounds((hid_t)fapl_id, (H5F_libver_t *)&(theArray[0]), (H5F_libver_t *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, libver, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds */ + +/* + * TODO: H5Pset_object_flush_cb + */ + +/* + * TODO: H5Pget_object_flush_cb + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pFAPLImp.h b/java/src/jni/h5pFAPLImp.h new file mode 100644 index 0000000..28b1d95 --- /dev/null +++ b/java/src/jni/h5pFAPLImp.h @@ -0,0 +1,501 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PFAPL +#define _Included_hdf_hdf5lib_H5_H5PFAPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * TODO: H5Pset_driver + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_driver + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1driver +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pget_driver_info + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fclose_degree + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fclose_degree + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_core + * Signature: (JJZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core +(JNIEnv *, jclass, jlong, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_core + * Signature: (J[J[Z)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core +(JNIEnv *, jclass, jlong, jlongArray, jbooleanArray); + +/* + * TODO: H5Pset_core_write_tracking + */ + +/* + * TODO: H5Pget_core_write_tracking + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_direct + * Signature: (JJJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct +(JNIEnv *, jclass, jlong, jlong, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_direct + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct +(JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_family + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family +(JNIEnv *, jclass, jlong, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_family + * Signature: (J[J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family +(JNIEnv *, jclass, jlong, jlongArray, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_family_offset + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1family_1offset +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_family_offset + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1family_1offset +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_log + * Signature: (JLjava/lang/String;JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log +(JNIEnv *, jclass, jlong, jstring, jlong, jlong); + +/* + * TODO: H5Pset_fapl_mpio + */ + +/* + * TODO: H5Pget_fapl_mpio + */ + +/* + * TODO: H5Pset_fapl_mpiposix + */ + +/* + * TODO: H5Pget_fapl_mpiposix + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_multi + * Signature: (J[I[J[Ljava/lang/String;[JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi +(JNIEnv *, jclass, jlong, jintArray, jlongArray, jobjectArray, jlongArray, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_fapl_multi + * Signature: (J[I[J[Ljava/lang/String;[J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi +(JNIEnv *, jclass, jlong, jintArray, jlongArray, jobjectArray, jlongArray); + +/* + * TODO: H5Pset_multi_type + */ + +/* + * TODO: H5Pget_multi_type + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_split + * Signature: (JLjava/lang/String;JLjava/lang/String;J)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split +(JNIEnv *, jclass, jlong, jstring, jlong, jstring, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_sec2 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_stdio + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_fapl_windows + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pset_file_image + */ + +/* + * TODO: H5Pget_file_image + */ + +/* + * TODO: H5Pset_file_image_callbacks + */ + +/* + * TODO: H5Pget_file_image_callbacks + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_meta_block_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_meta_block_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pset_page_buffer_size + */ + +/* + * TODO: H5Pget_page_buffer_size + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sieve_buf_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sieve_buf_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_alignment + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1alignment +(JNIEnv *, jclass, jlong, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_alignment + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1alignment +(JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_cache + * Signature: (JIJJD)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1cache +(JNIEnv *, jclass, jlong, jint, jlong, jlong, jdouble); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_cache + * Signature: (J[I[J[J[D)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1cache +(JNIEnv *, jclass, jlong, jintArray, jlongArray, jlongArray, jdoubleArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_file_cache_size + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_file_cache_size + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_evict_on_close + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close +(JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_evict_on_close + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_metadata_read_attempts + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_metadata_read_attempts + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_mdc_config + * Signature: (JLhdf/hdf5lib/structs/H5AC_cache_config_t;)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config +(JNIEnv *, jclass, jlong, jobject); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_mdc_config + * Signature: (J)Lhdf/hdf5lib/structs/H5AC_cache_config_t; + */ +JNIEXPORT jobject JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pset_mdc_image_config + */ + +/* + * TODO: H5Pget_mdc_image_config + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_mdc_log_options + * Signature: (JZLjava/lang/String;Z)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options +(JNIEnv *, jclass, jlong, jboolean, jstring, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_mdc_log_options + * Signature: (J[Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options +(JNIEnv *, jclass, jlong, jbooleanArray); + +/* + * TODO: H5Pset_all_coll_metadata_ops + */ + +/* + * TODO: H5Pget_all_coll_metadata_ops + */ + +/* + * TODO: H5Pset_coll_metadata_write + */ + +/* + * TODO: H5Pget_coll_metadata_write + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_gc_references + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1gc_1references +(JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_gc_references + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1gc_1references +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_small_data_block_size + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_small_data_block_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_libver_bounds + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_libver_bounds + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds +(JNIEnv *, jclass, jlong, jintArray); + +/* + * TODO: H5Pset_object_flush_cb + */ + +/* + * TODO: H5Pget_object_flush_cb + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PFAPL */ diff --git a/java/src/jni/h5pFCPLImp.c b/java/src/jni/h5pFCPLImp.c new file mode 100644 index 0000000..9c82ba6 --- /dev/null +++ b/java/src/jni/h5pFCPLImp.c @@ -0,0 +1,572 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pFCPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_userblock + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1userblock + (JNIEnv *env, jclass clss, jlong plist, jlong size) +{ + long sz = (long) size; + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_userblock((hid_t)plist, (hsize_t)sz)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1userblock */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_userblock + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1userblock + (JNIEnv *env, jclass clss, jlong plist, jlongArray size) +{ + jboolean isCopy; + hsize_t s; + jlong *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_userblock: size is NULL"); + + PIN_LONG_ARRAY(ENVONLY, size, theArray, &isCopy, "H5Pget_userblock: size not pinned"); + + if ((status = H5Pget_userblock((hid_t)plist, &s)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jlong)s; + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, size, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1userblock */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sizes + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sizes + (JNIEnv *env, jclass clss, jlong plist, jint sizeof_addr, jint sizeof_size) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_sizes((hid_t)plist, (size_t)sizeof_addr, (size_t)sizeof_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1sizes */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sizes + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sizes + (JNIEnv *env, jclass clss, jlong plist, jlongArray size) +{ + jboolean isCopy; + jlong *theArray = NULL; + jsize arrLen; + size_t ss; + size_t sa; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_sizes: size is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, size)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_sizes: size array length < 0"); + } + if (arrLen < 2) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_sizes: size input array < 2 elements"); + + PIN_LONG_ARRAY(ENVONLY, size, theArray, &isCopy, "H5Pget_sizes: size not pinned"); + + if ((status = H5Pget_sizes((hid_t)plist, &sa, &ss)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + theArray[0] = (jlong)sa; + theArray[1] = (jlong)ss; + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, size, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1sizes */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sym_k + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sym_1k + (JNIEnv *env, jclass clss, jlong plist, jint ik, jint lk) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_sym_k((hid_t)plist, (unsigned)ik, (unsigned)lk)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1sym_1k */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sym_k + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sym_1k + (JNIEnv *env, jclass clss, jlong plist, jintArray size) +{ + jboolean isCopy; + jsize arrLen; + jint *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_sym_k: size is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, size)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_sym_k: size array length < 0"); + } + if (arrLen < 2) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_sym_k: size < 2 elements"); + + PIN_INT_ARRAY(ENVONLY, size, theArray, &isCopy, "H5Pget_sym_k: size not pinned"); + + if ((status = H5Pget_sym_k((hid_t)plist, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_LONG_ARRAY(ENVONLY, size, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1sym_1k */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_istore_k + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1istore_1k + (JNIEnv *env, jclass clss, jlong plist, jint ik) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_istore_k((hid_t)plist, (unsigned)ik)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1istore_1k */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_istore_k + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1istore_1k + (JNIEnv *env, jclass clss, jlong plist, jintArray ik) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == ik) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_store_k: ik is NULL"); + + PIN_INT_ARRAY(ENVONLY, ik, theArray, &isCopy, "H5Pget_store_k: size not pinned"); + + if ((status = H5Pget_istore_k((hid_t)plist, (unsigned *)&(theArray[0]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, ik, theArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1istore_1k */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_file_space_page_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1page_1size + (JNIEnv *env, jclass clss, jlong fcpl_id, jlong fsp_size) +{ + UNUSED(clss); + + if (H5Pset_file_space_page_size((hid_t)fcpl_id, (hsize_t)fsp_size) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1page_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_page_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1page_1size + (JNIEnv *env, jclass clss, jlong fcpl_id) +{ + hsize_t fsp_size = 0; + + UNUSED(clss); + + if (H5Pget_file_space_page_size((hid_t)fcpl_id, &fsp_size) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)fsp_size; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1page_1size */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_file_space_strategy + * Signature: (JIZJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1strategy + (JNIEnv *env, jclass clss, jlong fcpl_id, jint strategy, jboolean persist, jlong threshold) +{ + UNUSED(clss); + + if (H5Pset_file_space_strategy((hid_t)fcpl_id, (H5F_fspace_strategy_t)strategy, (hbool_t)persist, (hsize_t)threshold) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_file_space_strategy */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy + * Signature: (J[Z[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy + (JNIEnv *env, jclass clss, jlong fcpl_id, jbooleanArray persist, jlongArray threshold) +{ + H5F_fspace_strategy_t thestrategy = H5F_FSPACE_STRATEGY_FSM_AGGR; /* Library default */ + jboolean isCopy; + jboolean *persistArray = NULL; + jlong *thresholdArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (persist) + PIN_BOOL_ARRAY(ENVONLY, persist, persistArray, &isCopy, "H5Pget_file_space: persist not pinned"); + if (threshold) + PIN_LONG_ARRAY(ENVONLY, threshold, thresholdArray, &isCopy, "H5Pget_file_space: threshold not pinned"); + + if ((status = H5Pget_file_space_strategy((hid_t)fcpl_id, &thestrategy, (hbool_t *)persistArray, (hsize_t *)thresholdArray)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (thresholdArray) + UNPIN_LONG_ARRAY(ENVONLY, threshold, thresholdArray, (status < 0) ? JNI_ABORT : 0); + if (persistArray) + UNPIN_BOOL_ARRAY(ENVONLY, persist, persistArray, (status < 0) ? JNI_ABORT : 0); + + return (jint)thestrategy; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy_persist + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist + (JNIEnv *env, jclass clss, jlong fcpl_id) +{ + hbool_t persist = FALSE; + herr_t status = FAIL; + + UNUSED(clss); + + if ((status = H5Pget_file_space_strategy((hid_t)fcpl_id, NULL, &persist, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jboolean)persist; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy_threshold + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1threshold + (JNIEnv *env, jclass clss, jlong fcpl_id) +{ + hsize_t threshold = 0; + herr_t status = FAIL; + + UNUSED(clss); + + if ((status = H5Pget_file_space_strategy((hid_t)fcpl_id, NULL, NULL, &threshold)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)threshold; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1threshold */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_nindexes + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes + (JNIEnv *env, jclass clss, jlong plist_id, jint nindexes) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if (nindexes > H5O_SHMESG_MAX_NINDEXES) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_nindexes: number of indexes is greater than H5O_SHMESG_MAX_NINDEXES"); + + if ((retVal = H5Pset_shared_mesg_nindexes((hid_t)plist_id, (unsigned)nindexes)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_nindexes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes + (JNIEnv *env, jclass clss, jlong fcpl_id) +{ + unsigned nindexes; + + UNUSED(clss); + + if (H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)nindexes; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_index + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index + (JNIEnv *env, jclass clss, jlong fcpl_id, jint index_num, + jint mesg_type_flags, jint min_mesg_size) +{ + unsigned nindexes; /* Number of SOHM indexes */ + herr_t retVal = FAIL; + + UNUSED(clss); + + /* Check arguments */ + if ((unsigned) mesg_type_flags > H5O_SHMESG_ALL_FLAG) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_index: unrecognized flags in mesg_type_flags"); + + /* Read the current number of indexes */ + if (H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Range check */ + if ((unsigned) index_num >= nindexes) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_index: index_num is too large; no such index"); + + if ((retVal = H5Pset_shared_mesg_index((hid_t)fcpl_id, (unsigned)index_num, (unsigned) mesg_type_flags, (unsigned) min_mesg_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_index + * Signature: (JI[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index + (JNIEnv *env, jclass clss, jlong fcpl_id, jint index_num, jintArray mesg_info) +{ + jboolean isCopy; + unsigned nindexes; /* Number of SOHM indexes */ + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == mesg_info) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_shared_mesg_index: mesg_info is NULL"); + + /* Read the current number of indexes */ + if (H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Range check */ + if ((unsigned) index_num >= nindexes) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pget_shared_mesg_index: index_num is too large; no such index"); + + PIN_INT_ARRAY(ENVONLY, mesg_info, theArray, &isCopy, "H5Pget_shared_mesg_index: input not pinned"); + + if ((retVal = H5Pget_shared_mesg_index((hid_t)fcpl_id, (unsigned)index_num, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, mesg_info, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_phase_change + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change + (JNIEnv *env, jclass clss, jlong fcpl_id, jint max_list, jint min_btree) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + /* Check that values are sensible. The min_btree value must be no greater + * than the max list plus one. + * + * Range check to make certain they will fit into encoded form. + */ + + if (max_list + 1 < min_btree) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_phase_change: minimum B-tree value is greater than maximum list value"); + if (max_list > H5O_SHMESG_MAX_LIST_SIZE) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_phase_change: max list value is larger than H5O_SHMESG_MAX_LIST_SIZE"); + if (min_btree > H5O_SHMESG_MAX_LIST_SIZE) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_shared_mesg_phase_change: min btree value is larger than H5O_SHMESG_MAX_LIST_SIZE"); + + if ((retVal = H5Pset_shared_mesg_phase_change((hid_t)fcpl_id, (unsigned)max_list, (unsigned)min_btree)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change + (JNIEnv *env, jclass clss, jlong fcpl_id, jintArray size) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == size) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_shared_mesg_phase_change: size is NULL"); + + PIN_INT_ARRAY(ENVONLY, size, theArray, &isCopy, "H5Pget_shared_mesg_phase_change: input not pinned"); + + if ((retVal = H5Pget_shared_mesg_phase_change((hid_t)fcpl_id, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, size, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pFCPLImp.h b/java/src/jni/h5pFCPLImp.h new file mode 100644 index 0000000..57fcae8 --- /dev/null +++ b/java/src/jni/h5pFCPLImp.h @@ -0,0 +1,207 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PFCPL +#define _Included_hdf_hdf5lib_H5_H5PFCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_userblock + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1userblock +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_userblock + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1userblock +(JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sizes + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sizes +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sizes + * Signature: (J[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sizes +(JNIEnv *, jclass, jlong, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_sym_k + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1sym_1k +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_sym_k + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1sym_1k +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_istore_k + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1istore_1k +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_istore_k + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1istore_1k +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_file_space_page_size + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1page_1size +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_page_size + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1page_1size +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_file_space_strategy + * Signature: (JIZJ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1strategy +(JNIEnv *, jclass, jlong, jint, jboolean, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy + * Signature: (J[Z[J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy +(JNIEnv *, jclass, jlong, jbooleanArray, jlongArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy_persist + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_file_space_strategy_threshold + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1threshold +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_nindexes + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_nindexes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_index + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index +(JNIEnv *, jclass, jlong, jint, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_index + * Signature: (JI[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index +(JNIEnv *, jclass, jlong, jint, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_shared_mesg_phase_change + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_shared_mesg_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change +(JNIEnv *, jclass, jlong, jintArray); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PFCPL */ diff --git a/java/src/jni/h5pGAPLImp.c b/java/src/jni/h5pGAPLImp.c new file mode 100644 index 0000000..9540387 --- /dev/null +++ b/java/src/jni/h5pGAPLImp.c @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pGAPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pGAPLImp.h b/java/src/jni/h5pGAPLImp.h new file mode 100644 index 0000000..73ad4a8 --- /dev/null +++ b/java/src/jni/h5pGAPLImp.h @@ -0,0 +1,27 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PGAPL +#define _Included_hdf_hdf5lib_H5_H5PGAPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PGAPL */ diff --git a/java/src/jni/h5pGCPLImp.c b/java/src/jni/h5pGCPLImp.c new file mode 100644 index 0000000..2ba1c7d --- /dev/null +++ b/java/src/jni/h5pGCPLImp.c @@ -0,0 +1,227 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pGCPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_local_heap_size_hint + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint + (JNIEnv *env, jclass clss, jlong gcpl_id, jlong size_hint) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_local_heap_size_hint((hid_t)gcpl_id, (size_t)size_hint)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_local_heap_size_hint + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint + (JNIEnv *env, jclass clss, jlong gcpl_id) +{ + size_t size_hint = 0; + + UNUSED(clss); + + if (H5Pget_local_heap_size_hint((hid_t)gcpl_id, &size_hint) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)size_hint; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_link_creation_order + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order + (JNIEnv *env, jclass clss, jlong gcpl_id, jint crt_order_flags) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_link_creation_order((hid_t)gcpl_id, (unsigned)crt_order_flags)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_link_creation_order + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order + (JNIEnv *env, jclass clss, jlong gcpl_id) +{ + unsigned crt_order_flags; + + UNUSED(clss); + + if (H5Pget_link_creation_order((hid_t)gcpl_id, &crt_order_flags) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)crt_order_flags; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_est_link_info + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info + (JNIEnv *env, jclass clss, jlong gcpl_id, jint est_num_entries, jint est_name_len) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + /* Range check values */ + if ((est_num_entries > 65535) || (est_name_len > 65535)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_est_link_info: est. name length or number of entries must be < 65536"); + + if ((retVal = H5Pset_est_link_info((hid_t)gcpl_id, (unsigned)est_num_entries, (unsigned)est_name_len)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_est_link_info + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info + (JNIEnv *env, jclass clss, jlong gcpl_id, jintArray link_info) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == link_info) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_est_link_info: link_info is NULL"); + + PIN_INT_ARRAY(ENVONLY, link_info, theArray, &isCopy, "H5Pget_est_link_info: input not pinned"); + + if ((retVal = H5Pget_est_link_info((hid_t)gcpl_id, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, link_info, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_link_phase_change + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change + (JNIEnv *env, jclass clss, jlong gcpl_id, jint max_compact, jint min_dense) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if (max_compact < min_dense) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_link_phase_change: max compact value must be >= min dense value"); + if (max_compact > 65535) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_link_phase_change: max compact value must be < 65536"); + if (min_dense > 65535) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_link_phase_change: min dense value must be < 65536"); + + if ((retVal = H5Pset_link_phase_change((hid_t)gcpl_id, (unsigned)max_compact, (unsigned)min_dense)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_link_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change + (JNIEnv *env, jclass clss, jlong gcpl_id, jintArray links) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == links) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_link_phase_change: links is NULL"); + + PIN_INT_ARRAY(ENVONLY, links, theArray, &isCopy, "H5Pget_link_phase_change: input not pinned"); + + if ((retVal = H5Pget_link_phase_change((hid_t)gcpl_id, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, links, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pGCPLImp.h b/java/src/jni/h5pGCPLImp.h new file mode 100644 index 0000000..9c32063 --- /dev/null +++ b/java/src/jni/h5pGCPLImp.h @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PGCPL +#define _Included_hdf_hdf5lib_H5_H5PGCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_local_heap_size_hint + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_local_heap_size_hint + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_link_creation_order + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_link_creation_order + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_est_link_info + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_est_link_info + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_link_phase_change + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_link_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change +(JNIEnv *, jclass, jlong, jintArray); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PGCPL */ diff --git a/java/src/jni/h5pImp.c b/java/src/jni/h5pImp.c index ac21d1d..bed23c9 100644 --- a/java/src/jni/h5pImp.c +++ b/java/src/jni/h5pImp.c @@ -26,7 +26,11 @@ extern "C" { #include "h5util.h" #include "h5pImp.h" +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ extern JavaVM *jvm; + extern jobject copy_callback; extern jobject close_callback; extern jobject create_callback; @@ -44,17 +48,16 @@ typedef struct _cb_wrapper { /* Local Prototypes */ /********************/ -static herr_t H5P_cls_create_func_cb(hid_t prop_id, void *create_data); -static herr_t H5P_cls_copy_func_cb(hid_t new_prop_id, hid_t old_prop_id, void *copy_data); -static herr_t H5P_cls_close_func_cb(hid_t prop_id, void *close_data); - -static herr_t H5P_prp_create_func_cb(const char *name, size_t size, void *value); -static herr_t H5P_prp_copy_func_cb(const char *name, size_t size, void *value); -static herr_t H5P_prp_close_func_cb(const char *name, size_t size, void *value); -static int H5P_prp_compare_func_cb(void *value1, void *value2, size_t size); -static herr_t H5P_prp_get_func_cb(hid_t prop_id, const char *name, size_t size, void *value); -static herr_t H5P_prp_set_func_cb(hid_t prop_id, const char *name, size_t size, void *value); -static herr_t H5P_prp_delete_func_cb(hid_t prop_id, const char *name, size_t size, void *value); +static herr_t H5P_cls_create_cb(hid_t prop_id, void *create_data); +static herr_t H5P_cls_copy_cb(hid_t new_prop_id, hid_t old_prop_id, void *copy_data); +static herr_t H5P_cls_close_cb(hid_t prop_id, void *close_data); +static herr_t H5P_prp_create_cb(const char *name, size_t size, void *value); +static herr_t H5P_prp_copy_cb(const char *name, size_t size, void *value); +static herr_t H5P_prp_close_cb(const char *name, size_t size, void *value); +static int H5P_prp_compare_cb(void *value1, void *value2, size_t size); +static herr_t H5P_prp_get_cb(hid_t prop_id, const char *name, size_t size, void *value); +static herr_t H5P_prp_set_cb(hid_t prop_id, const char *name, size_t size, void *value); +static herr_t H5P_prp_delete_cb(hid_t prop_id, const char *name, size_t size, void *value); static herr_t H5P_iterate_cb(hid_t prop_id, const char *name, void *cb_data); @@ -67,37 +70,19 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Pcreate (JNIEnv *env, jclass clss, jlong type) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; - retVal = H5Pcreate((hid_t)type); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Pcreate((hid_t) type)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Pcreate */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pclose - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5__1H5Pclose - (JNIEnv *env, jclass clss, jlong plist) -{ - herr_t retVal = 0; - - if (plist > 0) - retVal = H5Pclose((hid_t)plist); - - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5__1H5Pclose */ - -/* - * Class: hdf_hdf5lib_H5 * Method: H5Pget_class * Signature: (J)J */ @@ -105,12 +90,19 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Pget_1class (JNIEnv *env, jclass clss, jlong plist) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; - retVal = H5Pget_class((hid_t) plist); - if (retVal == H5P_ROOT) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Pget_class((hid_t) plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* + * if (retVal == H5P_ROOT) + * H5_LIBRARY_ERROR(ENVONLY); + */ + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Pget_1class */ @@ -123,5834 +115,964 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Pcopy (JNIEnv *env, jclass clss, jlong plist) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Pcopy((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Pcopy((hid_t) plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Pcopy */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_userblock - * Signature: (JJ)I + * Method: H5Pclose + * Signature: (J)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1userblock - (JNIEnv *env, jclass clss, jlong plist, jlong size) +Java_hdf_hdf5lib_H5__1H5Pclose + (JNIEnv *env, jclass clss, jlong plist) { - herr_t retVal = -1; - long sz = (long)size; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Pset_userblock((hid_t)plist, (hsize_t)sz); - if (retVal < 0) - h5libraryError(env); + if (plist >= 0) + if ((retVal = H5Pclose((hid_t) plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1userblock */ +} /* end Java_hdf_hdf5lib_H5__1H5Pclose */ /* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_userblock - * Signature: (J[J)I + * TODO: H5Pencode */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1userblock - (JNIEnv *env, jclass clss, jlong plist, jlongArray size) -{ - herr_t status = -1; - jlong *theArray; - jboolean isCopy; - hsize_t s; - - if (size == NULL) { - h5nullArgument(env, "H5Pget_userblock: size is NULL"); - } /* end if */ - else { - theArray = (jlong*)ENVPTR->GetLongArrayElements(ENVPAR size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_userblock: size not pinned"); - } /* end if */ - else { - status = H5Pget_userblock((hid_t)plist, &s); - - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR size, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jlong)s; - ENVPTR->ReleaseLongArrayElements(ENVPAR size, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1userblock */ +/* + * TODO: H5Pdecode + */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sizes - * Signature: (JII)I + * Method: _H5Pcreate_class + * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sizes - (JNIEnv *env, jclass clss, jlong plist, jint sizeof_addr, jint sizeof_size) +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pcreate_1class + (JNIEnv *env, jclass clss, jlong parent_class, jstring name, jobject create_op, + jobject create_data, jobject copy_op, jobject copy_data, jobject close_op, jobject close_data) { - herr_t retVal = -1; + const char *cstr = NULL; + hid_t class_id = H5I_INVALID_HID; - retVal = H5Pset_sizes((hid_t)plist, (size_t)sizeof_addr, (size_t)sizeof_size); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1sizes */ + create_callback = create_op; + close_callback = close_op; + copy_callback = copy_op; -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sizes - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sizes - (JNIEnv *env, jclass clss, jlong plist, jlongArray size) -{ - herr_t status = -1; - jlong *theArray; - jboolean isCopy; - size_t ss; - size_t sa; - - if (size == NULL) { - h5nullArgument(env, "H5Pget_sizes: size is NULL"); - } /* end if */ - else if (ENVPTR->GetArrayLength(ENVPAR size) < 2) { - h5badArgument(env, "H5Pget_sizes: size input array < 2 elements"); - } - else { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_sizes: size not pinned"); - } /* end if */ - else { - status = H5Pget_sizes((hid_t)plist, &sa, &ss); - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR size, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jlong)sa; - theArray[1] = (jlong)ss; - ENVPTR->ReleaseLongArrayElements(ENVPAR size, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "_H5Pcreate_class: class name not pinned"); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1sizes */ + if ((class_id = H5Pcreate_class((hid_t)parent_class, cstr, (H5P_cls_create_func_t)H5P_cls_create_cb, (void *) create_data, + (H5P_cls_copy_func_t)H5P_cls_copy_cb, (void *) copy_data, (H5P_cls_close_func_t)H5P_cls_close_cb, (void *) close_data)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); + + return (jlong)class_id; +} /* end Java_hdf_hdf5lib_H5__1H5Pcreate_1class */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sym_k - * Signature: (JII)I + * Method: _H5Pcreate_class_nocb + * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sym_1k - (JNIEnv *env, jclass clss, jlong plist, jint ik, jint lk) +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb + (JNIEnv *env, jclass clss, jlong parent_class, jstring name) { - herr_t retVal = -1; + const char *cstr = NULL; + hid_t class_id = H5I_INVALID_HID; - retVal = H5Pset_sym_k((hid_t)plist, (unsigned)ik, (unsigned)lk); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1sym_1k */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "_H5Pcreate_class_nocb: class name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sym_k - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sym_1k - (JNIEnv *env, jclass clss, jlong plist, jintArray size) -{ - herr_t status = -1; - jint *theArray; - jboolean isCopy; - - if (size == NULL) { - h5nullArgument(env, "H5Pget_sym_k: size is NULL"); - } /* end if */ - else if (ENVPTR->GetArrayLength(ENVPAR size) < 2) { - h5badArgument(env, "H5Pget_sym_k: size < 2 elements"); - } /* end else if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_sym_k: size not pinned"); - } /* end if */ - else { - status = H5Pget_sym_k((hid_t)plist, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1])); - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR size, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR size, theArray, 0); - } /* end else */ - } /* end else */ + if ((class_id = H5Pcreate_class((hid_t)parent_class, cstr, NULL, NULL, NULL, NULL, NULL, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1sym_1k */ +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); + + return (jlong)class_id; +} /* end Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_istore_k - * Signature: (JI)I + * Method: H5Pregister2 + * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1istore_1k - (JNIEnv *env, jclass clss, jlong plist, jint ik) +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pregister2 + (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, + jbyteArray def_value, jobject prp_create, jobject prp_set, jobject prp_get, jobject prp_delete, + jobject prp_copy, jobject prp_cmp, jobject prp_close) { - herr_t retVal = -1; + const char *cstr = NULL; + jboolean isCopy; + herr_t status = FAIL; + jbyte *propValBuf = NULL; - retVal = H5Pset_istore_k((hid_t)plist, (unsigned)ik); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1istore_1k */ + copy_callback = prp_copy; + close_callback = prp_close; + create_callback = prp_create; + compare_callback = prp_cmp; + set_callback = prp_set; + get_callback = prp_get; + delete_callback = prp_delete; -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_istore_k - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1istore_1k - (JNIEnv *env, jclass clss, jlong plist, jintArray ik) -{ - herr_t status = -1; - jint *theArray; - jboolean isCopy; + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pregister2: property name not pinned"); - if (ik == NULL) { - h5nullArgument(env, "H5Pget_store_k: ik is NULL"); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR ik, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_store_k: size not pinned"); - } /* end if */ - else { - status = H5Pget_istore_k((hid_t)plist, (unsigned *)&(theArray[0])); - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR ik, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR ik, theArray, 0); - } /* end else */ - } /* end else */ + PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pregister2: default property value buffer not pinned"); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1istore_1k */ + if ((status = H5Pregister2((hid_t)cls_id, cstr, (size_t)prp_size, (void *)propValBuf, (H5P_prp_create_func_t)H5P_prp_create_cb, + (H5P_prp_set_func_t)H5P_prp_set_cb, (H5P_prp_get_func_t)H5P_prp_get_cb, (H5P_prp_delete_func_t)H5P_prp_delete_cb, + (H5P_prp_copy_func_t)H5P_prp_copy_cb, (H5P_prp_compare_func_t)H5P_prp_compare_cb, (H5P_prp_close_func_t)H5P_prp_close_cb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (propValBuf) + UNPIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, (status < 0) ? JNI_ABORT : 0); + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); +} /* end Java_hdf_hdf5lib_H5_H5Pregister2 */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_layout - * Signature: (JI)I + * Method: H5Pregister2_nocb + * Signature: (JLjava/lang/String;J[B)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1layout - (JNIEnv *env, jclass clss, jlong plist, jint layout) +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pregister2_1nocb + (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, jbyteArray def_value) { - herr_t retVal = -1; + const char *cstr = NULL; + jboolean isCopy; + herr_t status = FAIL; + jbyte *propValBuf = NULL; - retVal = H5Pset_layout((hid_t)plist, (H5D_layout_t)layout); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1layout */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pregister2_nocb: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_layout - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1layout - (JNIEnv *env, jclass clss, jlong plist) -{ - H5D_layout_t retVal = H5D_LAYOUT_ERROR; + PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pregister2_nocb: default property value buffer not pinned"); - retVal = H5Pget_layout((hid_t)plist); - if (retVal == H5D_LAYOUT_ERROR) - h5libraryError(env); + if ((status = H5Pregister2((hid_t)cls_id, cstr, (size_t)prp_size, (void *)propValBuf, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1layout */ +done: + if (propValBuf) + UNPIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, (status < 0) ? JNI_ABORT : 0); + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); +} /* end Java_hdf_hdf5lib_H5_H5Pregister2_1nocb */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk - * Signature: (JI[B)I + * Method: H5Pinsert2 + * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk - (JNIEnv *env, jclass clss, jlong plist, jint ndims, jbyteArray dim) +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pinsert2 + (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, + jbyteArray def_value, jobject prp_set, jobject prp_get, jobject prp_delete, + jobject prp_copy, jobject prp_cmp, jobject prp_close) { - herr_t status = -1; - jbyte *theArray; - jboolean isCopy; - hsize_t *da; - hsize_t *lp; - jlong *jlp; - size_t i; - size_t rank; - - if (dim == NULL) { - h5nullArgument(env, "H5Pset_chunk: dim array is NULL"); - } /* end if */ - else { - i = (size_t)ENVPTR->GetArrayLength(ENVPAR dim); - rank = i / sizeof(jlong); - if (rank < ndims) { - h5badArgument(env, "H5Pset_chunk: dims array < ndims"); - } /* end if */ - else { - theArray = (jbyte *)ENVPTR->GetByteArrayElements(ENVPAR dim, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pset_chunk: dim array not pinned"); - } /* end if */ - else { - da = lp = (hsize_t *)HDmalloc(rank * sizeof(hsize_t)); - if (da == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR dim, theArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pset_chunk: dims not converted to hsize_t"); - } /* end if */ - else { - jlp = (jlong *)theArray; - for (i = 0; i < rank; i++) { - *lp = (hsize_t)*jlp; - lp++; - jlp++; - } /* end if */ - - status = H5Pset_chunk((hid_t)plist, (int)ndims, da); - - ENVPTR->ReleaseByteArrayElements(ENVPAR dim, theArray, JNI_ABORT); - HDfree(da); - - if (status < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + const char *cstr = NULL; + jboolean isCopy; + herr_t status = FAIL; + jbyte *propValBuf = NULL; - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1chunk */ + UNUSED(clss); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk - * Signature: (JI[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk - (JNIEnv *env, jclass clss, jlong plist, jint max_ndims, jlongArray dims) -{ - herr_t status = -1; - jlong *theArray; - jboolean isCopy; - hsize_t *da; - int i; - - if (dims == NULL) { - h5nullArgument(env, "H5Pget_chunk: dims is NULL"); - } /* end if */ - else if (ENVPTR->GetArrayLength(ENVPAR dims) < max_ndims) { - h5badArgument(env, "H5Pget_chunk: dims array < max_ndims"); - } /* end else if */ - else { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR dims, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_chunk: input dims not pinned"); - } /* end if */ - else { - da = (hsize_t *)HDmalloc((size_t)max_ndims * sizeof(hsize_t)); - if (da == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, theArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_chunk: dims not converted to hsize_t"); - } /* end if */ - else { - status = H5Pget_chunk((hid_t)plist, (int)max_ndims, da); - - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, theArray, JNI_ABORT); - HDfree (da); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < max_ndims; i++) { - theArray[i] = (jlong)da[i]; - } - HDfree (da); - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + copy_callback = prp_copy; + close_callback = prp_close; + compare_callback = prp_cmp; + set_callback = prp_set; + get_callback = prp_get; + delete_callback = prp_delete; - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1chunk */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pinsert2: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_alignment - * Signature: (JJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1alignment - (JNIEnv *env, jclass clss, jlong plist, jlong threshold, jlong alignment) -{ - herr_t retVal = -1; - long thr = (long)threshold; - long align = (long)alignment; + PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pinsert2: property value buffer not pinned"); - retVal = H5Pset_alignment((hid_t)plist, (hsize_t)thr, (hsize_t)align); - if (retVal < 0) - h5libraryError(env); + if ((status = H5Pinsert2((hid_t)cls_id, cstr, (size_t)prp_size, (void *)propValBuf, + (H5P_prp_set_func_t)H5P_prp_set_cb, (H5P_prp_get_func_t)H5P_prp_get_cb, (H5P_prp_delete_func_t)H5P_prp_delete_cb, + (H5P_prp_copy_func_t)H5P_prp_copy_cb, (H5P_prp_compare_func_t)H5P_prp_compare_cb, (H5P_prp_close_func_t)H5P_prp_close_cb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1alignment */ +done: + if (propValBuf) + UNPIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, (status < 0) ? JNI_ABORT : 0); + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); +} /* end Java_hdf_hdf5lib_H5_H5Pinsert2 */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_alignment - * Signature: (J[J)I + * Method: H5Pinsert2_nocb + * Signature: (JLjava/lang/String;J[B)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1alignment - (JNIEnv *env, jclass clss, jlong plist, jlongArray alignment) +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb + (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, jbyteArray def_value) { - herr_t status = -1; - jlong *theArray; - jboolean isCopy; - hsize_t t; - hsize_t a; - - if (alignment == NULL) { - h5nullArgument(env, "H5Pget_alignment: input alignment is NULL"); - } /* end if */ - else { - if (ENVPTR->GetArrayLength(ENVPAR alignment) < 2) { - h5badArgument(env, "H5Pget_alignment: alignment input array < 2"); - } /* end if */ - else { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR alignment, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_alignment: input array not pinned"); - } /* end if */ - else { - status = H5Pget_alignment((hid_t)plist, &t, &a); - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR alignment, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jlong)t; - theArray[1] = (jlong)a; - ENVPTR->ReleaseLongArrayElements(ENVPAR alignment, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + const char *cstr = NULL; + jboolean isCopy; + herr_t status = FAIL; + jbyte *propValBuf = NULL; - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1alignment */ + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pinsert2_nocb: property name not pinned"); + + PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pinsert2_nocb: property value buffer not pinned"); + + if ((status = H5Pinsert2((hid_t)cls_id, cstr, (size_t)prp_size, (void *)propValBuf, NULL, NULL, NULL, NULL, NULL, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (propValBuf) + UNPIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, (status < 0) ? JNI_ABORT : 0); + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); +} /* end Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_external - * Signature: (JLjava/lang/String;JJ)I + * Method: H5Pset + * Signature: (JLjava/lang/String;I)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1external - (JNIEnv *env, jclass clss, jlong plist, jstring name, jlong offset, jlong size) +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pset + (JNIEnv *env, jclass clss, jlong plid, jstring name, jint val) { - herr_t status = -1; - const char *fileName; - off_t off; - hsize_t sz; - hid_t plid; + const char *cstr = NULL; + hid_t retVal = H5I_INVALID_HID; - plid = (hid_t)plist; - off = (off_t)offset; - sz = (hsize_t)size; + UNUSED(clss); - PIN_JAVA_STRING(name, fileName); - if (fileName != NULL) { - status = H5Pset_external(plid, fileName, off, sz); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pset: property name not pinned"); - UNPIN_JAVA_STRING(name, fileName); + if ((retVal = H5Pset((hid_t)plid, cstr, &val)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (status < 0) - h5libraryError(env); - } +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1external */ + return (jlong)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_external_count - * Signature: (J)I + * Method: H5Pexist + * Signature: (JLjava/lang/String;)Z */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1external_1count - (JNIEnv *env, jclass clss, jlong plist) +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pexist + (JNIEnv *env, jclass clss, jlong plid, jstring name) { - int retVal = -1; + const char *cstr = NULL; + htri_t bval = JNI_FALSE; - retVal = H5Pget_external_count((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1external_1count */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pexist: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_external - * Signature: (JIJ[Ljava/lang/String;[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1external - (JNIEnv *env, jclass clss, jlong plist, jint idx, jlong name_size, - jobjectArray name, jlongArray size) -{ - herr_t status = -1; - jlong *theArray; - jboolean isCopy; - char *file = NULL; - jstring str; - off_t o; - hsize_t s; - - if (name_size < 0) { - h5badArgument(env, "H5Pget_external: name_size < 0"); - } /* end if */ - else if ((size != NULL) && (ENVPTR->GetArrayLength(ENVPAR size) < 2)) { - h5badArgument(env, "H5Pget_external: size input array < 2"); - } /* end else if */ - else { - if (name_size > 0) { - file = (char *)HDmalloc(sizeof(char)*(size_t)name_size); - } /* end else */ - - status = H5Pget_external((hid_t) plist, (unsigned)idx, (size_t)name_size, - file, (off_t *)&o, (hsize_t *)&s); - if (status < 0) { - HDfree(file); - h5libraryError(env); - } /* end if */ - else { - if (size != NULL) { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError( env, "H5Pget_external: size array not pinned"); - } /* end if */ - else { - theArray[0] = o; - theArray[1] = (jlong)s; - ENVPTR->ReleaseLongArrayElements(ENVPAR size, theArray, 0); - } - } /* end if */ - - if (file != NULL) { - /* NewStringUTF may throw OutOfMemoryError */ - str = ENVPTR->NewStringUTF(ENVPAR file); - if (str == NULL) { - HDfree(file); - h5JNIFatalError(env, "H5Pget_external: return array not created"); - } /* end if */ - else { - /* SetObjectArrayElement may raise exceptions */ - ENVPTR->SetObjectArrayElement(ENVPAR name, 0, (jobject)str); - HDfree(file); - } /* end else */ - } /* end if */ - } /* end else */ - } + if ((bval = H5Pexist((hid_t)plid, cstr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1external */ + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); + + return (jboolean)bval; +} /* end Java_hdf_hdf5lib_H5_H5Pexist */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fill_value - * Signature: (JJ[B)I + * Method: H5Pget_size + * Signature: (JLjava/lang/String;)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fill_1value - (JNIEnv *env, jclass clss, jlong plist_id, jlong type_id, jbyteArray value) +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1size + (JNIEnv *env, jclass clss, jlong plid, jstring name) { - jint status = -1; - jbyte *byteP = NULL; - jboolean isCopy; - - if (value != NULL) { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value, &isCopy); - if (byteP == NULL) { - h5JNIFatalError(env, "H5Pget_fill_value: value array not pinned"); - } /* end if */ - else { - status = H5Pset_fill_value((hid_t)plist_id, (hid_t)type_id, byteP); - - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - } - } /* end if */ - else { - status = H5Pset_fill_value((hid_t)plist_id, (hid_t)type_id, byteP); - } + const char *cstr = NULL; + size_t size = 0; + herr_t status = FAIL; - if (status < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fill_1value */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pget_size: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fill_value - * Signature: (JJ[B)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fill_1value - (JNIEnv *env, jclass clss, jlong plist_id, jlong type_id, jbyteArray value) -{ - jint status = -1; - jbyte *byteP; - jboolean isCopy; + if ((status = H5Pget_size((hid_t)plid, cstr, &size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (value == NULL) { - h5badArgument(env, "H5Pget_fill_value: value is NULL"); - } /* end if */ - else { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value, &isCopy); - if (byteP == NULL) { - h5JNIFatalError(env, "H5Pget_fill_value: value array not pinned"); - } /* end if */ - else { - status = H5Pget_fill_value((hid_t)plist_id, (hid_t)type_id, byteP); - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, 0); - } /* end else */ - } /* end else */ +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fill_1value */ + return (jlong) size; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1size */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_filter - * Signature: (JIIJ[I)I + * Method: H5Pget_nprops + * Signature: (J)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1filter - (JNIEnv *env, jclass clss, jlong plist, jint filter, jint flags, - jlong cd_nelmts, jintArray cd_values) +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1nprops + (JNIEnv *env, jclass clss, jlong plid) { - herr_t status = -1; - jint *theArray; - jboolean isCopy; - - if (cd_values == NULL) { - status = H5Pset_filter((hid_t)plist, (H5Z_filter_t)filter, - (unsigned int)flags, (size_t)cd_nelmts, NULL); - if (status < 0) - h5libraryError(env); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR cd_values, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pset_filter: input array not pinned"); - }/* end if */ - else { - status = H5Pset_filter((hid_t)plist, (H5Z_filter_t)filter, - (unsigned int)flags, (size_t)cd_nelmts, (const unsigned int *)theArray); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, theArray, JNI_ABORT); - if (status < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + size_t nprops = 0; - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1filter */ + UNUSED(clss); + + if (H5Pget_nprops((hid_t)plid, &nprops) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)nprops; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1nprops */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nfilters - * Signature: (J)I + * Method: H5Pget_class_name + * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nfilters - (JNIEnv *env, jclass clss, jlong plist) +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1class_1name + (JNIEnv *env, jclass clss, jlong plid) { - int retVal = -1; + char *c_str = NULL; + jstring j_str = NULL; - retVal = H5Pget_nfilters((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1nfilters */ + if (NULL == (c_str = H5Pget_class_name((hid_t)plid))) + H5_LIBRARY_ERROR(ENVONLY); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter - * Signature: (JI[I[J[IJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter - (JNIEnv *env, jclass clss, jlong plist, jint filter_number, jintArray flags, - jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name) -{ - herr_t status = -1; - jint *flagsArray; - jlong *cd_nelmtsArray; - jint *cd_valuesArray; - jint mode = JNI_ABORT; - jboolean isCopy; - jstring str; - char *filter; - - if (namelen <= 0) { - h5badArgument(env, "H5Pget_filter: namelen <= 0"); - } /* end if */ - else if (flags == NULL) { - h5badArgument(env, "H5Pget_filter: flags is NULL"); - } /* end else if */ - else if (cd_nelmts == NULL) { - h5badArgument(env, "H5Pget_filter: cd_nelmts is NULL"); - } /* end else if */ - else if (cd_values == NULL) { - h5badArgument(env, "H5Pget_filter: cd_values is NULL"); - } /* end else if */ - else { - filter = (char *)HDmalloc(sizeof(char)*(size_t)namelen); - if (filter == NULL) { - h5outOfMemory(env, "H5Pget_filter: namelen malloc failed"); - } /* end if */ - else { - flagsArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR flags, &isCopy); - if (flagsArray == NULL) { - h5JNIFatalError(env, "H5Pget_filter: flags array not pinned"); - } /* end if */ - else { - cd_nelmtsArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR cd_nelmts, &isCopy); - if (cd_nelmtsArray == NULL) { - h5JNIFatalError(env, "H5Pget_filter: nelmts array not pinned"); - } /* end if */ - else { - cd_valuesArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR cd_values, &isCopy); - if (cd_valuesArray == NULL) { - h5JNIFatalError(env, "H5Pget_filter: elmts array not pinned"); - } /* end if */ - else { - /* direct cast (size_t *)variable fails on 32-bit environment */ - long long cd_nelmts_temp = *(cd_nelmtsArray); - size_t cd_nelmts_t = (size_t)cd_nelmts_temp; - unsigned int filter_config; - status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, - (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, - (size_t)namelen, filter, &filter_config); - - *cd_nelmtsArray = (jlong)cd_nelmts_t; - /* end direct cast special */ - - if (status < 0) { - h5libraryError(env); - } /* end if */ - else { - mode = 0; - - /* NewStringUTF may throw OutOfMemoryError */ - str = ENVPTR->NewStringUTF(ENVPAR filter); - if (str == NULL) { - h5JNIFatalError(env, "H5Pget_filter: return string not pinned"); - } /* end if */ - else { - /* SetObjectArrayElement may throw exceptiosn */ - ENVPTR->SetObjectArrayElement(ENVPAR name, 0, (jobject)str); - } /* end else */ - } /* end else */ - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, mode); - } - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, mode); - } - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, mode); - } - HDfree(filter); - } - } /* end else */ + if (NULL == (j_str = ENVPTR->NewStringUTF(ENVONLY, c_str))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_class_name: out of memory - unable to construct string from UTF characters"); + } - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter */ +done: + if (c_str) + H5free_memory(c_str); + + return j_str; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1class_1name */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_driver + * Method: H5Pget_class_parent * Signature: (J)J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1driver - (JNIEnv *env, jclass clss, jlong plist) +Java_hdf_hdf5lib_H5_H5Pget_1class_1parent + (JNIEnv *env, jclass clss, jlong plid) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Pget_driver((hid_t) plist); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Pget_class_parent((hid_t)plid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1driver */ +} /* end Java_hdf_hdf5lib_H5_H5Pget_1class_1parent */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_cache - * Signature: (JIJJD)I + * Method: H5Pisa_class + * Signature: (JJ)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1cache - (JNIEnv *env, jclass clss, jlong plist, jint mdc_nelmts, jlong rdcc_nelmts, - jlong rdcc_nbytes, jdouble rdcc_w0) +Java_hdf_hdf5lib_H5_H5Pisa_1class + (JNIEnv *env, jclass clss, jlong plid, jlong pcls) { - herr_t retVal = -1; + htri_t retVal = FAIL; - retVal = H5Pset_cache((hid_t)plist, (int)mdc_nelmts, (size_t)rdcc_nelmts, - (size_t)rdcc_nbytes, (double) rdcc_w0); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1cache */ + if ((retVal = H5Pisa_class((hid_t)plid, (hid_t)pcls)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pisa_1class */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_cache - * Signature: (J[I[J[J[D)I + * Method: H5Pget + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1cache - (JNIEnv *env, jclass clss, jlong plist, jintArray mdc_nelmts, - jlongArray rdcc_nelmts, jlongArray rdcc_nbytes, jdoubleArray rdcc_w0) +Java_hdf_hdf5lib_H5_H5Pget + (JNIEnv *env, jclass clss, jlong plid, jstring name) { - herr_t status = -1; - jint mode; - jdouble *w0Array = (jdouble *)NULL; - jlong *rdcc_nelmtsArray = (jlong *)NULL; - jlong *nbytesArray = (jlong *)NULL; - jboolean isCopy; - - if (rdcc_w0 != NULL) { - w0Array = (jdouble *)ENVPTR->GetDoubleArrayElements(ENVPAR rdcc_w0, &isCopy); - if (w0Array == NULL) { - h5JNIFatalError(env, "H5Pget_cache: w0_array array not pinned"); - return -1; - } /* end if */ - } /* end else */ - - if (rdcc_nelmts != NULL) { - rdcc_nelmtsArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR rdcc_nelmts, &isCopy); - if (rdcc_nelmtsArray == NULL) { - /* exception -- out of memory */ - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, JNI_ABORT); - } - h5JNIFatalError(env, "H5Pget_cache: rdcc_nelmts array not pinned"); - return -1; - } /* end if */ - } /* end else */ - - if (rdcc_nbytes != NULL) { - nbytesArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR rdcc_nbytes, &isCopy); - if (nbytesArray == NULL) { - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, JNI_ABORT); - } /* end if */ - if (rdcc_nelmtsArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nelmts, rdcc_nelmtsArray, JNI_ABORT); - } /* end if */ - h5JNIFatalError(env, "H5Pget_cache: nbytesArray array not pinned"); - return -1; - } /* end if */ - } /* end else */ - - { /* direct cast (size_t *)variable fails on 32-bit environment */ - long long rdcc_nelmts_temp = *(rdcc_nelmtsArray); - size_t rdcc_nelmts_t = (size_t)rdcc_nelmts_temp; - long long nbytes_temp = *(nbytesArray); - size_t nbytes_t = (size_t)nbytes_temp; - - status = H5Pget_cache((hid_t)plist, (int *)NULL, &rdcc_nelmts_t, - &nbytes_t, (double *)w0Array); - - *rdcc_nelmtsArray = (jlong)rdcc_nelmts_t; - *nbytesArray = (jlong)nbytes_t; - } /* end direct cast special */ - - - if (status < 0) { - mode = JNI_ABORT; - } /* end if */ - else { - mode = 0; /* commit and free */ - } /* end else */ + const char *cstr = NULL; + jint val; + herr_t status = FAIL; - if (rdcc_nelmtsArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nelmts, rdcc_nelmtsArray, mode); - } /* end if */ + UNUSED(clss); - if (nbytesArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nbytes, nbytesArray, mode); - } /* end if */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pget: property name not pinned"); - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, mode); - } /* end if */ + if ((status = H5Pget((hid_t)plid, cstr, &val)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (status < 0) { - h5libraryError(env); - } /* end if */ +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1cache */ + return (jint)val; +} /* end Java_hdf_hdf5lib_H5_H5Pget */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_buffer - * Signature: (JJ[B[B)I + * Method: H5Pequal + * Signature: (JJ)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1buffer - (JNIEnv *env, jclass clss, jlong plist, jlong size, jbyteArray tconv, jbyteArray bkg) +Java_hdf_hdf5lib_H5_H5Pequal + (JNIEnv *env, jclass clss, jlong plid1, jlong plid2) { - h5unimplemented(env, "H5Pset_buffer: not implemented"); - return -1; -#ifdef notdef - -/* DON'T IMPLEMENT THIS!!! */ - jint status = -1; - jbyte *tconvP; - jbyte *bkgP; - jboolean isCopy; - - if (tconv == NULL) - tconvP = (jbyte *)NULL; - else { - tconvP = ENVPTR->GetByteArrayElements(ENVPAR tconv, &isCopy); - if (tconvP == NULL) { - h5JNIFatalError(env, "H5Pset_buffer: tconv not pinned"); - return -1; - } - } - if (bkg == NULL) - bkgP = (jbyte *)NULL; - else { - bkgP = ENVPTR->GetByteArrayElements(ENVPAR bkg, &isCopy); - if (bkgP == NULL) { - h5JNIFatalError(env, "H5Pset_buffer: bkg not pinned"); - return -1; - } - } + htri_t retVal = FAIL; - status = H5Pset_buffer((hid_t)plist, (size_t)size, tconvP, bkgP); - if (status < 0) { - if (tconv != NULL) - ENVPTR->ReleaseByteArrayElements(ENVPAR tconv, tconvP, JNI_ABORT); - if (bkg != NULL) - ENVPTR->ReleaseByteArrayElements(ENVPAR bkg, bkgP, JNI_ABORT); - h5libraryError(env); - return -1; - } + UNUSED(clss); - if (tconv != NULL) - ENVPTR->ReleaseByteArrayElements(ENVPAR tconv, tconvP, 0); - if (bkg != NULL) - ENVPTR->ReleaseByteArrayElements(ENVPAR bkg, bkgP, 0); + if ((retVal = H5Pequal((hid_t)plid1, (hid_t)plid2)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)status; -#endif -} /* end Java_hdf_hdf5lib_H5_H5Pset_1buffer */ +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pequal */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_buffer - * Signature: (J[B[B)I + * Method: H5Piterate + * Signature: (J[ILjava/lang/Object;Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1buffer - (JNIEnv *env, jclass clss, jlong plist, jbyteArray tconv, jbyteArray bkg) +Java_hdf_hdf5lib_H5_H5Piterate + (JNIEnv *env, jclass clss, jlong prop_id, jintArray idx, jobject callback_op, jobject op_data) { - h5unimplemented(env, "H5Pget_buffer: not implemented"); - return -1; -#ifdef notdef - -/* DON'T IMPLEMENT THIS!!! */ - jlong status = -1; - jbyte *tconvP; - jbyte *bkgP; - jboolean isCopy; - - if (tconv == NULL) { - h5nullArgument(env, "H5Pget_buffer: tconv input array is NULL"); - return -1; - } - tconvP = ENVPTR->GetByteArrayElements(ENVPAR tconv, &isCopy); - if (tconvP == NULL) { - h5JNIFatalError(env, "H5Pget_buffer: tconv not pinned"); - return -1; - } - if (bkg == NULL) { - h5nullArgument(env, "H5Pget_buffer: bkg array is NULL"); - return -1; - } - bkgP = ENVPTR->GetByteArrayElements(ENVPAR bkg, &isCopy); - if (bkgP == NULL) { - h5JNIFatalError(env, "H5Pget_buffer: bkg not pinned"); - return -1; + cb_wrapper wrapper = { callback_op, op_data }; + jboolean isCopy; + jint *theArray = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + ENVPTR->GetJavaVM(ENVONLY, &jvm); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == op_data) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Piterate: op_data is NULL"); + if (NULL == callback_op) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Piterate: callback_op is NULL"); + + if (NULL == idx) { + if ((status = H5Piterate((hid_t)prop_id, NULL, (H5P_iterate_t)H5P_iterate_cb, (void *)&wrapper)) < 0) + H5_LIBRARY_ERROR(ENVONLY); } + else { + PIN_INT_ARRAY(ENVONLY, idx, theArray, &isCopy, "H5Piterate: idx not pinned"); - status = H5Pget_buffer((hid_t)plist, tconvP, bkgP); - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR tconv, tconvP, JNI_ABORT); - ENVPTR->ReleaseByteArrayElements(ENVPAR bkg, bkgP, JNI_ABORT); - h5libraryError(env); - return -1; + if ((status = H5Piterate((hid_t)prop_id, (int *)&theArray[0], (H5P_iterate_t)H5P_iterate_cb, (void *)&wrapper)) < 0) + H5_LIBRARY_ERROR(ENVONLY); } - ENVPTR->ReleaseByteArrayElements(ENVPAR tconv, tconvP, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bkg, bkgP, 0); - return (jint)status; -#endif -} /* end Java_hdf_hdf5lib_H5_H5Pget_1buffer */ +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, idx, theArray, (status < 0) ? JNI_ABORT : 0); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_buffer_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size - (JNIEnv *env, jclass clss, jlong plist, jlong size) -{ - if (H5Pset_buffer((hid_t)plist, (size_t)size, NULL, NULL) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size */ + return (jint)status; +} /* end Java_hdf_hdf5lib_H5_H5Piterate */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_buffer_size - * Signature: (J)J + * Method: H5Pcopy_prop + * Signature: (JJLjava/lang/String;)I */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size - (JNIEnv *env, jclass clss, jlong plist) +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pcopy_1prop + (JNIEnv *env, jclass clss, jlong dst_plid, jlong src_plid, jstring name) { - size_t size = 0; + const char *cstr = NULL; + herr_t retVal = FAIL; - size = H5Pget_buffer((hid_t)plist, NULL, NULL); - if (size == 0) - h5libraryError(env); + UNUSED(clss); - return (jlong)size; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pcopy_prop: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_preserve - * Signature: (JZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1preserve - (JNIEnv *env, jclass clss, jlong plist, jboolean status) -{ - hbool_t st; - herr_t retVal = -1; - - if (status == JNI_TRUE) { - st = TRUE; - } /* end if */ - else if (status == JNI_FALSE) { - st = false; - } /* end else if */ - else { - h5badArgument(env, "H5Pset_preserve: status not TRUE or FALSE"); - return -1; - } /* end else */ + if ((retVal = H5Pcopy_prop((hid_t)dst_plid, (hid_t)src_plid, cstr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - retVal = H5Pset_preserve((hid_t)plist, st); - if (retVal < 0) - h5libraryError(env); +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1preserve */ +} /* end Java_hdf_hdf5lib_H5_H5Pcopy_1prop */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_preserve - * Signature: (J)I + * Method: H5Premove + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1preserve - (JNIEnv *env, jclass clss, jlong plist) +Java_hdf_hdf5lib_H5_H5Premove + (JNIEnv *env, jclass clss, jlong plid, jstring name) { - herr_t retVal = -1; + const char *cstr = NULL; + herr_t retVal = FAIL; - retVal = H5Pget_preserve((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1preserve */ + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Premove: property name not pinned"); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_deflate - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1deflate - (JNIEnv *env, jclass clss, jlong plist, jint level) -{ - herr_t retVal = -1; + if ((retVal = H5Premove((hid_t)plid, cstr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - retVal = H5Pset_deflate((hid_t)plist, (unsigned)level); - if (retVal < 0) - h5libraryError(env); +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1deflate */ +} /* end Java_hdf_hdf5lib_H5_H5Premove */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_gc_references - * Signature: (JZ)I + * Method: H5Punregister + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1gc_1references - (JNIEnv *env, jclass clss, jlong fapl_id, jboolean gc_ref) +Java_hdf_hdf5lib_H5_H5Punregister + (JNIEnv *env, jclass clss, jlong plid, jstring name) { - herr_t retVal = -1; - unsigned gc_ref_val; + const char *cstr = NULL; + herr_t retVal = FAIL; - if (gc_ref == JNI_TRUE) - gc_ref_val = 1; - else - gc_ref_val = 0; + UNUSED(clss); - retVal = H5Pset_gc_references((hid_t)fapl_id, gc_ref_val); - if (retVal < 0) - h5libraryError(env); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Punregister: property name not pinned"); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1gc_1references */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_gc_references - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1gc_1references - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - unsigned gc_ref_val = 0; - jboolean bval = JNI_FALSE; + if ((retVal = H5Punregister((hid_t)plid, cstr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (H5Pget_gc_references((hid_t)fapl_id, (unsigned *)&gc_ref_val) < 0) { - h5libraryError(env); - } /* end if */ - else { - if (gc_ref_val == 1) - bval = JNI_TRUE; - } /* end else */ +done: + if (cstr) + UNPIN_JAVA_STRING(ENVONLY, name, cstr); - return bval; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1gc_1references */ + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Punregister */ /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_btree_ratios - * Signature: (JDDD)I + * Method: _H5Pclose_class + * Signature: (J)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios - (JNIEnv *env, jclass clss, jlong plist_id, jdouble left, jdouble middle, jdouble right) +Java_hdf_hdf5lib_H5__1H5Pclose_1class + (JNIEnv *env, jclass clss, jlong plid) { - herr_t status = -1; + herr_t retVal = FAIL; - status = H5Pset_btree_ratios((hid_t)plist_id, (double)left,(double)middle, (double)right); - if (status < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios */ + if ((retVal = H5Pclose_class((hid_t)plid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_btree_ratios - * Signature: (J[D[D[D)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios - (JNIEnv *env, jclass clss, jlong plist_id, jdoubleArray left, - jdoubleArray middle, jdoubleArray right) +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5__1H5Pclose_1class */ + +static herr_t +H5P_cls_create_cb + (hid_t prop_id, void *create_data) { - herr_t status = -1; - jdouble *leftP; - jdouble *middleP; - jdouble *rightP; - jboolean isCopy; - - if (left == NULL) { - h5nullArgument(env, "H5Pget_btree_ratios: left input array is NULL"); - } /* end if */ - else if (middle == NULL) { - h5nullArgument(env, "H5Pget_btree_ratios: middle input array is NULL"); - } /* end else if */ - else if (right == NULL) { - h5nullArgument(env, "H5Pget_btree_ratios: right input array is NULL"); - } /* end else if */ - else { - leftP = (jdouble *)ENVPTR->GetDoubleArrayElements(ENVPAR left, &isCopy); - if (leftP == NULL) { - h5JNIFatalError(env, "H5Pget_btree_ratios: left not pinned"); - } /* end if */ - else { - middleP = (jdouble *)ENVPTR->GetDoubleArrayElements(ENVPAR middle, &isCopy); - if (middleP == NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR left, leftP, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_btree_ratios: middle not pinned"); - } /* end if */ - else { - rightP = (jdouble *)ENVPTR->GetDoubleArrayElements(ENVPAR right, &isCopy); - if (rightP == NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR left, leftP, JNI_ABORT); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR middle, middleP, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_btree_ratios: middle not pinned"); - } /* end if */ - else { - status = H5Pget_btree_ratios((hid_t)plist_id, (double *)leftP, - (double *)middleP, (double *)rightP); - if (status < 0) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR left, leftP, JNI_ABORT); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR middle, middleP, JNI_ABORT); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR right, rightP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR left, leftP, 0); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR middle, middleP, 0); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR right, rightP, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jmethodID mid; + JNIEnv *cbenv = NULL; + jclass cls; + jint status = -1; - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_cls_create_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_small_data_block_size - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size - (JNIEnv *env, jclass clss, jlong plist, jlong size) -{ - long sz = (long)size; - herr_t retVal = -1; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, create_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_small_data_block_size((hid_t)plist, (hsize_t)sz); - if (retVal < 0) - h5libraryError(env); + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLhdf/hdf5lib/callbacks/H5P_cls_create_func_t;)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size */ + status = CBENVPTR->CallIntMethod(CBENVONLY, create_callback, mid, prop_id, create_data); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_small_data_block_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size - (JNIEnv *env, jclass clss, jlong plist) +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); + + return (herr_t)status; +} /* end H5P_cls_create_cb */ + +static herr_t +H5P_cls_copy_cb + (hid_t new_prop_id, hid_t old_prop_id, void *copy_data) { - hsize_t s; + jmethodID mid; + JNIEnv *cbenv = NULL; + jclass cls; + jint status = -1; - if (H5Pget_small_data_block_size((hid_t)plist, &s) < 0) - h5libraryError(env); + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_cls_copy_cb: failed to attach current thread to JVM"); + } - return (jlong)s; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size */ + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, copy_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_alloc_time - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time - (JNIEnv *env, jclass clss, jlong plist, jint alloc_time) -{ - herr_t retVal = -1; + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JJLhdf/hdf5lib/callbacks/H5P_cls_copy_func_t;)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_alloc_time((hid_t)plist, (H5D_alloc_time_t)alloc_time); - if (retVal < 0) - h5libraryError(env); + status = CBENVPTR->CallIntMethod(CBENVONLY, copy_callback, mid, new_prop_id, old_prop_id, copy_data); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time */ +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_alloc_time - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time - (JNIEnv *env, jclass clss, jlong plist, jintArray alloc_time) + return (herr_t)status; +} /* end H5P_cls_copy_cb */ + +static herr_t +H5P_cls_close_cb + (hid_t prop_id, void *close_data) { - herr_t retVal = -1; - jint *theArray; - jboolean isCopy; - H5D_alloc_time_t time; - - if (alloc_time == NULL) { - /* exception ? */ - h5nullArgument(env, "H5Pget_alloc_time: alloc_time is NULL"); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR alloc_time, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_alloc_time: alloc_time not pinned"); - } /* end if */ - else { - retVal = H5Pget_alloc_time((hid_t)plist, &time); - if (retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR alloc_time, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = time; - ENVPTR->ReleaseIntArrayElements(ENVPAR alloc_time, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ + jmethodID mid; + JNIEnv *cbenv = NULL; + jclass cls; + jint status = -1; - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_cls_close_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fill_time - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fill_1time - (JNIEnv *env, jclass clss, jlong plist, jint fill_time) -{ - herr_t retVal = -1; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, close_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_fill_time((hid_t)plist, (H5D_fill_time_t)fill_time); - if (retVal < 0) - h5libraryError(env); + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLhdf/hdf5lib/callbacks/H5P_cls_close_func_t;)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fill_1time */ + status = CBENVPTR->CallIntMethod(CBENVONLY, close_callback, mid, prop_id, close_data); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fill_time - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fill_1time - (JNIEnv *env, jclass clss, jlong plist, jintArray fill_time) -{ - herr_t retVal = -1; - jint *theArray; - jboolean isCopy; - H5D_fill_time_t time; - - if (fill_time == NULL) { - /* exception ? */ - h5nullArgument(env, "H5Pget_fill_time: fill_time is NULL"); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR fill_time, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_fill_time: fill_time not pinned"); - } /* end if */ - else { - retVal = H5Pget_fill_time((hid_t)plist, &time); - if (retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR fill_time, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jint)time; - ENVPTR->ReleaseIntArrayElements(ENVPAR fill_time, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fill_1time */ + return (herr_t)status; +} /* end H5P_cls_close_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pfill_value_defined - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined - (JNIEnv *env, jclass clss, jlong plist, jintArray status) +static herr_t +H5P_prp_create_cb + (const char *name, size_t size, void *value) { - herr_t retVal = -1; - jint *theArray; - jboolean isCopy; - H5D_fill_value_t value; - - if (status == NULL) { - /* exception ? */ - h5nullArgument(env, "H5Pfill_value_defined: status is NULL"); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR status, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pfill_value_defined: status not pinned"); - } /* end if */ - else { - retVal = H5Pfill_value_defined((hid_t)plist, &value); - if (retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR status, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = value; - ENVPTR->ReleaseIntArrayElements(ENVPAR status, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ + jmethodID mid; + jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_create_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fletcher32 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 - (JNIEnv *env, jclass clss, jlong plist) -{ - herr_t retVal = -1; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, create_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_fletcher32((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(Ljava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 */ + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_edc_check - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1edc_1check - (JNIEnv *env, jclass clss, jlong plist, jint check) -{ - herr_t retVal = -1; + status = CBENVPTR->CallIntMethod(CBENVONLY, create_callback, mid, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_edc_check((hid_t)plist, (H5Z_EDC_t)check); - if (retVal < 0) - h5libraryError(env); +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1edc_1check */ + return (herr_t)status; +} /* end H5P_prp_create_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_edc_check - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1edc_1check - (JNIEnv *env, jclass clss, jlong plist) +static herr_t +H5P_prp_set_cb + (hid_t prop_id, const char *name, size_t size, void *value) { - H5Z_EDC_t retVal = -1; - - retVal = H5Pget_edc_check((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + jmethodID mid; + jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1edc_1check */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_set_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shuffle - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shuffle - (JNIEnv *env, jclass clss, jlong plist) -{ - herr_t retVal = -1; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, set_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_shuffle((hid_t)plist); - if (retVal < 0) - h5libraryError(env); + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1shuffle */ + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_szip - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1szip - (JNIEnv *env, jclass clss, jlong plist, jint options_mask, jint pixels_per_block) -{ - herr_t retVal = -1; + status = CBENVPTR->CallIntMethod(CBENVONLY, set_callback, mid, prop_id, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_szip((hid_t)plist, (unsigned int)options_mask, (unsigned int)pixels_per_block); - if (retVal < 0) - h5libraryError(env); +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1szip */ + return (herr_t)status; +} /* end H5P_prp_set_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_hyper_vector_size - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size - (JNIEnv *env, jclass clss, jlong plist, jlong vector_size) +static herr_t +H5P_prp_get_cb + (hid_t prop_id, const char *name, size_t size, void *value) { - herr_t retVal = -1; + jmethodID mid; + jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - retVal = H5Pset_hyper_vector_size((hid_t)plist, (size_t)vector_size); - if (retVal < 0) - h5libraryError(env); + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_get_cb: failed to attach current thread to JVM"); + } - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size */ + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, get_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_hyper_vector_size - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size - (JNIEnv *env, jclass clss, jlong plist, jlongArray vector_size) -{ - herr_t retVal = -1; - jlong *theArray; - size_t size; - jboolean isCopy; - - if (vector_size == NULL) { - /* exception ? */ - h5nullArgument(env, "H5Pget_hyper_vector_size: vector_size is NULL"); - } /* end if */ - else { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR vector_size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_hyper_vector_size: vector_size not pinned"); - } /* end if */ - else { - retVal = H5Pget_hyper_vector_size((hid_t)plist, &size); - if (retVal < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR vector_size, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jlong)size; - ENVPTR->ReleaseLongArrayElements(ENVPAR vector_size, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size */ + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pall_filters_avail - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail - (JNIEnv *env, jclass clss, jlong dcpl_id) -{ - htri_t bval = JNI_FALSE; - - bval = H5Pall_filters_avail((hid_t)dcpl_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); - - return (jboolean)bval; -} /* end Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pmodify_filter - * Signature: (JIIJ[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pmodify_1filter - (JNIEnv *env, jclass clss, jlong plist, jint filter, - jint flags, jlong cd_nelmts, jintArray cd_values) -{ - herr_t status = -1; - jint *cd_valuesP; - jboolean isCopy; - - if (cd_values == NULL) { - h5nullArgument(env, "H5Pmodify_filter: cd_values is NULL"); - } /* end if */ - else { - cd_valuesP = ENVPTR->GetIntArrayElements(ENVPAR cd_values,&isCopy); - if (cd_valuesP == NULL) { - h5JNIFatalError(env, "H5Pmodify_filter: cd_values not pinned"); - } /* end if */ - else { - status = H5Pmodify_filter((hid_t)plist, (H5Z_filter_t)filter,(const unsigned int)flags, - (size_t)cd_nelmts, (unsigned int *)cd_valuesP); - - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesP, JNI_ABORT); - - if (status < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pmodify_1filter */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter_by_id - * Signature: (JI[I[J[IJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id - (JNIEnv *env, jclass clss, jlong plist, jint filter, - jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name) -{ - jboolean isCopy; - herr_t status = -1; - jint *cd_valuesArray; - jint *flagsArray; - jlong *cd_nelmtsArray; - jstring str; - char *aName; - int i = 0; - int rank; - long bs; - - bs = (long)namelen; - if (bs <= 0) { - h5badArgument(env, "H5Pget_filter_by_id: namelen <= 0"); - } /* end if */ - else if (flags == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: flags is NULL"); - } /* end else if */ - else if (cd_nelmts == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: cd_nelms is NULL"); - } /* end else if */ - else if (cd_values == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: cd_values is NULL"); - } /* end else if */ - else if (name == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: name is NULL"); - } /* end else if */ - else { - aName = (char*)HDmalloc(sizeof(char) * (size_t)bs); - if (aName == NULL) { - h5outOfMemory(env, "H5Pget_filter_by_id: malloc failed"); - return -1; - } /* end if */ - - flagsArray = ENVPTR->GetIntArrayElements(ENVPAR flags, &isCopy); - if (flagsArray == NULL) { - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: flags not pinned"); - return -1; - } /* end if */ - - cd_nelmtsArray = ENVPTR->GetLongArrayElements(ENVPAR cd_nelmts, &isCopy); - if (cd_nelmtsArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: cd_nelms not pinned"); - return -1; - } /* end if */ - - cd_valuesArray = ENVPTR->GetIntArrayElements(ENVPAR cd_values, &isCopy); - rank = ENVPTR->GetArrayLength(ENVPAR cd_values); - if (cd_valuesArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, JNI_ABORT); - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: cd_values array not converted to unsigned int."); - return -1; - } /* end if */ - - { /* direct cast (size_t *)variable fails on 32-bit environment */ - long long cd_nelmts_temp = *(cd_nelmtsArray); - size_t cd_nelmts_t = (size_t)cd_nelmts_temp; - unsigned int filter_config; - - status = H5Pget_filter_by_id2( (hid_t)plist, (H5Z_filter_t)filter, - (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, - (size_t)namelen, (char *)aName, &filter_config); - - *cd_nelmtsArray = (jlong)cd_nelmts_t; - } /* end direct cast special */ - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, JNI_ABORT); - HDfree(aName); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR aName); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, 0); - - HDfree(aName); - } /* end else */ - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fclose_degree - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree - (JNIEnv *env, jclass clss, jlong plist, jint fc_degree) -{ - herr_t retVal = -1; - - retVal = H5Pset_fclose_degree((hid_t)plist, (H5F_close_degree_t)fc_degree); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fclose_degree - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree - (JNIEnv *env, jclass clss, jlong plist) -{ - H5F_close_degree_t degree; - - if (H5Pget_fclose_degree((hid_t)plist, °ree) < 0) - h5libraryError(env); - - return (jint)degree; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree */ - - -/********************************************************************** - * * - * File access properties * - * * - **********************************************************************/ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_family - * Signature: (JJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family - (JNIEnv *env, jclass clss, jlong plist, jlong memb_size, jlong memb_plist) -{ - long ms = (long)memb_size; - herr_t retVal = -1; - - retVal = H5Pset_fapl_family((hid_t)plist, (hsize_t)ms, (hid_t)memb_plist); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_family - * Signature: (J[J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family - (JNIEnv *env, jclass clss, jlong tid, jlongArray memb_size, jlongArray memb_plist) -{ - herr_t status = -1; - jlong *sizeArray; - jlong *plistArray; - jint mode = JNI_ABORT; - jboolean isCopy; - hsize_t *sa; - size_t i; - size_t rank; - - if (memb_size == NULL) { - h5nullArgument(env, "H5Pget_family: memb_size is NULL"); - } /* end if */ - else if (memb_plist == NULL) { - h5nullArgument(env, "H5Pget_family: memb_plist is NULL"); - } /* end else if */ - else { - sizeArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR memb_size, &isCopy); - if (sizeArray == NULL) { - h5JNIFatalError(env, "H5Pget_family: sizeArray not pinned"); - } /* end if */ - else { - rank = (size_t)ENVPTR->GetArrayLength(ENVPAR memb_size); - sa = (hsize_t *)HDmalloc(rank * sizeof(hsize_t)); - if (sa == NULL) { - h5JNIFatalError(env, "H5Screate-simple: dims not converted to hsize_t"); - } /* end if */ - else { - plistArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR memb_plist, &isCopy); - if (plistArray == NULL) { - h5JNIFatalError(env, "H5Pget_family: plistArray not pinned"); - } /* end if */ - else { - status = H5Pget_fapl_family ((hid_t)tid, sa, (hid_t *)plistArray); - - if (status < 0) { - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < rank; i++) { - sizeArray[i] = (jlong)sa[i]; - } /* end for */ - mode = 0; - } /* end else */ - ENVPTR->ReleaseLongArrayElements(ENVPAR memb_plist, plistArray, mode); - } - HDfree(sa); - } - ENVPTR->ReleaseLongArrayElements(ENVPAR memb_size, sizeArray, mode); - } - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_core - * Signature: (JJZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core - (JNIEnv *env, jclass clss, jlong fapl_id, jlong increment, jboolean backing_store) -{ - herr_t retVal = -1; - - retVal = H5Pset_fapl_core((hid_t)fapl_id, (size_t)increment, (hbool_t)backing_store); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_core - * Signature: (J[J[Z)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core - (JNIEnv *env, jclass clss, jlong fapl_id, jlongArray increment, jbooleanArray backing_store) -{ - herr_t status = -1; - jint mode = JNI_ABORT; - jlong *incArray; - jboolean *backArray; - jboolean isCopy; - - if (increment == NULL) { - h5nullArgument(env, "H5Pget_fapl_core: increment is NULL"); - } /* end if */ - else if (backing_store == NULL) { - h5nullArgument(env, "H5Pget_fapl_core: backing_store is NULL"); - } /* end else if */ - else { - incArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR increment, &isCopy); - if (incArray == NULL) { - h5JNIFatalError(env, "H5Pget_fapl_core: incArray not pinned"); - } /* end if */ - else { - backArray = (jboolean *)ENVPTR->GetBooleanArrayElements(ENVPAR backing_store, &isCopy); - if (backArray == NULL) { - h5JNIFatalError(env, "H5Pget_fapl_core: backArray not pinned"); - } /* end if */ - else { - /* direct cast (size_t *)variable fails on 32-bit environment */ - long long inc_temp = *(incArray); - size_t inc_t = (size_t)inc_temp; - - status = H5Pget_fapl_core((hid_t)fapl_id, &inc_t, (hbool_t *)backArray); - - *incArray = (jlong)inc_t; - /* end direct cast special */ - - if (status < 0) { - h5libraryError(env); - } /* end if */ - else { - mode = 0; - } /* end else */ - ENVPTR->ReleaseBooleanArrayElements(ENVPAR backing_store, backArray, mode); - } - ENVPTR->ReleaseLongArrayElements(ENVPAR increment, incArray, mode); - } - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_family_offset - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1family_1offset - (JNIEnv *env, jclass clss, jlong fapl_id, jlong offset) -{ - herr_t retVal = -1; - - retVal = H5Pset_family_offset ((hid_t)fapl_id, (hsize_t)offset); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1family_1offset */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_family_offset - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1family_1offset - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - hsize_t offset = 0; - herr_t retVal = -1; - - retVal = H5Pget_family_offset ((hid_t)fapl_id, &offset); - if (retVal < 0) - h5libraryError(env); - - return (jlong)offset; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1family_1offset */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_log - * Signature: (JLjava/lang/String;JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log - (JNIEnv *env, jclass clss, jlong fapl_id, jstring logfile, jlong flags, jlong buf_size) -{ - herr_t retVal = -1; - const char *pLogfile; - - PIN_JAVA_STRING(logfile, pLogfile); - if (pLogfile != NULL) { - retVal = H5Pset_fapl_log( (hid_t)fapl_id, pLogfile, (unsigned long long)flags, (size_t)buf_size ); - - UNPIN_JAVA_STRING(logfile, pLogfile); - - if (retVal < 0) - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Premove_filter - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5P1remove_1filter - (JNIEnv *env, jclass clss, jlong obj_id, jint filter) -{ - herr_t status = -1; - - status = H5Premove_filter ((hid_t)obj_id, (H5Z_filter_t)filter); - if (status < 0) - h5libraryError(env); - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5P1remove_1filter */ - - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset - * Signature: (JLjava/lang/String;I)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pset - (JNIEnv *env, jclass clss, jlong plid, jstring name, jint val) -{ - hid_t retVal = -1; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Pset((hid_t)plid, cstr, &val); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jlong)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pexist - * Signature: (JLjava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pexist - (JNIEnv *env, jclass clss, jlong plid, jstring name) -{ - htri_t bval = JNI_FALSE; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - bval = H5Pexist((hid_t)plid, cstr); - - UNPIN_JAVA_STRING(name, cstr); - - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); - } - - return (jboolean)bval; -} /* end Java_hdf_hdf5lib_H5_H5Pexist */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_size - * Signature: (JLjava/lang/String;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1size - (JNIEnv *env, jclass clss, jlong plid, jstring name) -{ - hid_t retVal = -1; - const char *cstr; - size_t size = 0; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Pget_size((hid_t)plid, cstr, &size); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jlong) size; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nprops - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nprops - (JNIEnv *env, jclass clss, jlong plid) -{ - size_t nprops; - - if (H5Pget_nprops((hid_t)plid, &nprops) < 0) - h5libraryError(env); - - return (jlong)nprops; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1nprops */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_class_name - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1class_1name - (JNIEnv *env, jclass clss, jlong plid) -{ - char *c_str; - jstring j_str = NULL; - - c_str = H5Pget_class_name((hid_t)plid); - if (c_str == NULL) { - h5libraryError(env); - } /* end if */ - else { - j_str = ENVPTR->NewStringUTF(ENVPAR c_str); - H5free_memory(c_str); - - if (j_str == NULL) - h5JNIFatalError(env,"H5Pget_class_name: return string failed"); - } /* end else */ - return j_str; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1class_1name */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_class_parent - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1class_1parent - (JNIEnv *env, jclass clss, jlong plid) -{ - hid_t retVal = -1; - - retVal = H5Pget_class_parent((hid_t)plid); - if (retVal < 0) - h5libraryError(env); - - return (jlong)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1class_1parent */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pisa_class - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pisa_1class - (JNIEnv *env, jclass clss, jlong plid, jlong pcls) -{ - htri_t retVal = -1; - - retVal = H5Pisa_class((hid_t)plid, (hid_t)pcls); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pisa_1class */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget - (JNIEnv *env, jclass clss, jlong plid, jstring name) -{ - herr_t retVal = -1; - const char *cstr; - jint val; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Pget((hid_t)plid, cstr, &val); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jint)val; -} /* end Java_hdf_hdf5lib_H5_H5Pget */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pequal - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pequal - (JNIEnv *env, jclass clss, jlong plid1, jlong plid2) -{ - htri_t retVal = -1; - - retVal = H5Pequal((hid_t)plid1, (hid_t)plid2); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pequal */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pcopy_prop - * Signature: (JJLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pcopy_1prop - (JNIEnv *env, jclass clss, jlong dst_plid, jlong src_plid, jstring name) -{ - herr_t retVal = -1; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Pcopy_prop((hid_t)dst_plid, (hid_t)src_plid, cstr); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pcopy_1prop */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Premove - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Premove - (JNIEnv *env, jclass clss, jlong plid, jstring name) -{ - herr_t retVal = -1; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Premove((hid_t)plid, cstr); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Premove */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Punregister - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Punregister - (JNIEnv *env, jclass clss, jlong plid, jstring name) -{ - herr_t retVal = -1; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - retVal = H5Punregister((hid_t)plid, cstr); - - UNPIN_JAVA_STRING(name, cstr); - - if (retVal < 0) - h5libraryError(env); - } - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Punregister */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pclose_class - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5__1H5Pclose_1class - (JNIEnv *env, jclass clss, jlong plid) -{ - herr_t retVal = -1; - - retVal = H5Pclose_class((hid_t)plid); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5__1H5Pclose_1class */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter2 - * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter2 - (JNIEnv *env, jclass clss, jlong plist, jint filter_number, - jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, - jobjectArray name, jintArray filter_config) -{ - herr_t status = -1; - jint *flagsArray; - jlong *cd_nelmtsArray; - jint *cd_valuesArray; - jint *filter_configArray; - jboolean isCopy; - char *filter; - jstring str; - - if (namelen <= 0) { - h5badArgument(env, "H5Pget_filter: namelen <= 0"); - } /* end if */ - else if (flags == NULL) { - h5badArgument(env, "H5Pget_filter: flags is NULL"); - } /* end else if */ - else if (cd_nelmts == NULL) { - h5badArgument(env, "H5Pget_filter: cd_nelmts is NULL"); - } /* end else if */ - else if (filter_config == NULL) { - h5badArgument(env, "H5Pget_filter: filter_config is NULL"); - } /* end else if */ - else { - filter = (char*)HDmalloc(sizeof(char)*(size_t)namelen); - if (filter == NULL) { - h5outOfMemory(env, "H5Pget_filter: namelent malloc failed"); - return -1; - } /* end if */ - flagsArray = (jint*)ENVPTR->GetIntArrayElements(ENVPAR flags, &isCopy); - if (flagsArray == NULL) { - HDfree(filter); - h5JNIFatalError(env, "H5Pget_filter: flags array not pinned"); - return -1; - } /* end if */ - - cd_nelmtsArray = (jlong*)ENVPTR->GetLongArrayElements(ENVPAR cd_nelmts, &isCopy); - if (cd_nelmtsArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(filter); - h5JNIFatalError(env, "H5Pget_filter: nelmts array not pinned"); - return -1; - } /* end if */ - filter_configArray = (jint*)ENVPTR->GetIntArrayElements(ENVPAR filter_config, &isCopy); - if (filter_configArray == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(filter); - h5JNIFatalError(env, "H5Pget_filter: filter_config array not pinned"); - return -1; - } /* end if */ - - if (*cd_nelmtsArray == 0 && cd_values == NULL) { - /* direct cast (size_t *)variable fails on 32-bit environment */ - long long cd_nelmts_temp = 0; - size_t cd_nelmts_t = (size_t)cd_nelmts_temp; - - status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, - (unsigned int *)flagsArray, &cd_nelmts_t, NULL, - (size_t)namelen, filter, (unsigned int *)filter_configArray); - - *cd_nelmtsArray = (jlong)cd_nelmts_t; - } /* end if */ - else { - if (cd_values == NULL) { - h5badArgument(env, "H5Pget_filter: cd_values is NULL"); - return -1; - } /* end if */ - cd_valuesArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR cd_values, &isCopy); - if (cd_valuesArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR filter_config, filter_configArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(filter); - h5JNIFatalError(env, "H5Pget_filter: elmts array not pinned"); - return -1; - } /* end if */ - - { /* direct cast (size_t *)variable fails on 32-bit environment */ - long long cd_nelmts_temp = *(cd_nelmtsArray); - size_t cd_nelmts_t = (size_t)cd_nelmts_temp; - - status = H5Pget_filter2((hid_t)plist, (unsigned)filter_number, - (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, - (size_t)namelen, filter, (unsigned int *)filter_configArray); - - *cd_nelmtsArray = (jlong)cd_nelmts_t; - } /* end direct cast special */ - } /* end else */ - - if (status < 0) { - if (cd_values) - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR filter_config, filter_configArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(filter); - h5libraryError(env); - } /* end if */ - else { - if (cd_values) - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR filter_config, filter_configArray, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, 0); - /* NewStringUTF may throw OutOfMemoryError */ - str = ENVPTR->NewStringUTF(ENVPAR filter); - HDfree(filter); - if (str == NULL) - h5JNIFatalError(env, "H5Pget_filter: return string not pinned"); - else - ENVPTR->SetObjectArrayElement(ENVPAR name, 0, (jobject)str); - } /* end else */ - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter2 */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter_by_id2 - * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 - (JNIEnv *env, jclass clss, jlong plist, jint filter, - jintArray flags, jlongArray cd_nelmts, jintArray cd_values, jlong namelen, jobjectArray name, jintArray filter_config) -{ - herr_t status = -1; - int i = 0; - jint *cd_valuesArray; - jint *flagsArray; - jint *filter_configArray; - jlong *cd_nelmtsArray; - jboolean isCopy; - long bs; - char *aName; - jstring str; - - bs = (long)namelen; - if (bs <= 0) { - h5badArgument(env, "H5Pget_filter_by_id: namelen <= 0"); - } /* end if */ - else if (flags == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: flags is NULL"); - } /* end else if */ - else if (cd_nelmts == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: cd_nelms is NULL"); - } /* end else if */ - else if (cd_values == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: cd_values is NULL"); - } /* end else if */ - else if (name == NULL) { - h5nullArgument(env, "H5Pget_filter_by_id: name is NULL"); - } /* end else if */ - else if (filter_config == NULL) { - h5badArgument(env, "H5Pget_filter_by_id: filter_config is NULL"); - } /* end else if */ - else { - aName = (char*)HDmalloc(sizeof(char) * (size_t)bs); - if (aName == NULL) { - h5outOfMemory(env, "H5Pget_filter_by_id: malloc failed"); - return -1; - } /* end if */ - flagsArray = ENVPTR->GetIntArrayElements(ENVPAR flags,&isCopy); - if (flagsArray == NULL) { - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: flags not pinned"); - return -1; - } /* end if */ - cd_nelmtsArray = ENVPTR->GetLongArrayElements(ENVPAR cd_nelmts, &isCopy); - if (cd_nelmtsArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: cd_nelms not pinned"); - return -1; - } /* end if */ - cd_valuesArray = ENVPTR->GetIntArrayElements(ENVPAR cd_values, &isCopy); - if (cd_valuesArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: cd_values array not converted to unsigned int."); - return -1; - } /* end if */ - filter_configArray = ENVPTR->GetIntArrayElements(ENVPAR filter_config, &isCopy); - if (filter_configArray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, JNI_ABORT); - HDfree(aName); - h5JNIFatalError(env, "H5Pget_filter_by_id: flags not pinned"); - return -1; - } /* end if */ - - { /* direct cast (size_t *)variable fails on 32-bit environment */ - long long cd_nelmts_temp = *(cd_nelmtsArray); - size_t cd_nelmts_t = (size_t)cd_nelmts_temp; - - status = H5Pget_filter_by_id2((hid_t)plist, (H5Z_filter_t)filter, - (unsigned int *)flagsArray, &cd_nelmts_t, (unsigned int *)cd_valuesArray, - (size_t)namelen, (char *)aName, (unsigned int *)filter_configArray); - - *cd_nelmtsArray = (jlong)cd_nelmts_t; - } /* end direct cast special handling */ - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR filter_config, filter_configArray, JNI_ABORT); - HDfree(aName); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR aName); - HDfree(aName); - ENVPTR->ReleaseIntArrayElements(ENVPAR flags, flagsArray, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR cd_nelmts, cd_nelmtsArray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR cd_values, cd_valuesArray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR filter_config, filter_configArray, 0); - } /* end else */ - } /* end else */ - - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nlinks - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nlinks - (JNIEnv *env, jclass clss, jlong lapl_id) -{ - size_t nlinks; - if (H5Pget_nlinks((hid_t)lapl_id, &nlinks) < 0) - h5libraryError(env); - - return (jlong) nlinks; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1nlinks */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_nlinks - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1nlinks - (JNIEnv *env, jclass clss, jlong lapl_id, jlong nlinks) -{ - herr_t retVal = -1; - - if (nlinks <= 0) { - h5badArgument(env, "H5Pset_1nlinks: nlinks_l <= 0"); - } /* end if */ - else { - retVal = H5Pset_nlinks((hid_t)lapl_id, (size_t)nlinks); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1nlinks */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_libver_bounds - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds - (JNIEnv *env, jclass clss, jlong fapl_id, jintArray libver) -{ - herr_t retVal = -1; - H5F_libver_t *theArray = NULL; - jboolean isCopy; - - if (libver == NULL) { - h5nullArgument(env, "H5Pget_libver_bounds: libversion bounds is NULL"); - } /* end if */ - else { - theArray = (H5F_libver_t*)ENVPTR->GetIntArrayElements(ENVPAR libver, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_libver_bounds: input not pinned"); - } /* end if */ - else { - retVal = H5Pget_libver_bounds((hid_t)fapl_id, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR libver, (jint*)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR libver, (jint*)theArray, 0); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_libver_bounds - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds - (JNIEnv *env, jclass clss, jlong fapl_id, jint low, jint high) -{ - herr_t retVal = -1; - - retVal = H5Pset_libver_bounds((hid_t)fapl_id, (H5F_libver_t)low, (H5F_libver_t)high); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_link_creation_order - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order - (JNIEnv *env, jclass clss, jlong gcpl_id) -{ - unsigned crt_order_flags; - - if(H5Pget_link_creation_order((hid_t)gcpl_id, &crt_order_flags) < 0) - h5libraryError(env); - - return (jint)crt_order_flags; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_link_creation_order - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order - (JNIEnv *env, jclass clss, jlong gcpl_id, jint crt_order_flags) -{ - herr_t retVal = -1; - - retVal = H5Pset_link_creation_order((hid_t)gcpl_id, (unsigned)crt_order_flags); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_attr_creation_order - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order - (JNIEnv *env, jclass clss, jlong ocpl_id) -{ - unsigned crt_order_flags; - - if(H5Pget_attr_creation_order((hid_t)ocpl_id, &crt_order_flags) < 0) - h5libraryError(env); - - return (jint)crt_order_flags; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_attr_creation_order - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order - (JNIEnv *env, jclass clss, jlong ocpl_id, jint crt_order_flags) -{ - herr_t retVal = -1; - - retVal = H5Pset_attr_creation_order((hid_t)ocpl_id, (unsigned)crt_order_flags); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_copy_object - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1copy_1object - (JNIEnv *env, jclass clss, jlong ocp_plist_id, jint copy_options) -{ - herr_t retVal = -1; - - retVal = H5Pset_copy_object((hid_t)ocp_plist_id, (unsigned)copy_options); - if(retVal < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1copy_1object */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_copy_object - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1copy_1object - (JNIEnv *env, jclass clss, jlong ocp_plist_id) -{ - unsigned copy_options; - - if(H5Pget_copy_object((hid_t)ocp_plist_id, ©_options) < 0) - h5libraryError(env); - - return (jint)copy_options; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1copy_1object */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_create_intermediate_group - * Signature: (JZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group - (JNIEnv *env, jclass clss, jlong lcpl_id, jboolean crt_intermed_group) -{ - herr_t retVal = -1; - - retVal = H5Pset_create_intermediate_group((hid_t)lcpl_id, (unsigned)crt_intermed_group); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_create_intermediate_group - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group - (JNIEnv *env, jclass clss, jlong lcpl_id) -{ - unsigned crt_intermed_group; - - if(H5Pget_create_intermediate_group((hid_t)lcpl_id, &crt_intermed_group) < 0) - h5libraryError(env); - - return (jboolean)crt_intermed_group; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_data_transform - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1data_1transform - (JNIEnv *env, jclass clss, jlong plist_id, jstring expression) -{ - herr_t retVal = -1; - const char *express; - - PIN_JAVA_STRING(expression, express); - if (express != NULL) { - retVal = H5Pset_data_transform((hid_t)plist_id, express); - - UNPIN_JAVA_STRING(expression, express); - - if (retVal < 0) - h5libraryError(env); - } - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1data_1transform */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_data_transform - * Signature: (J[Ljava/lang/String;J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1data_1transform - (JNIEnv *env, jclass clss, jlong plist_id, jobjectArray expression, jlong size) -{ - size_t buf_size; - char *express; - jlong express_size = -1; - jstring str = NULL; - - if (size <= 0) { - h5badArgument(env, "H5Pget_data_transform: size <= 0"); - } /* end if */ - else { - express_size = (jlong)H5Pget_data_transform((hid_t)plist_id, (char*)NULL, (size_t)size); - if(express_size < 0) { - h5libraryError(env); - } /* end if */ - else { - buf_size = (size_t)express_size + 1;/* add extra space for the null terminator */ - express = (char*)HDmalloc(sizeof(char) * buf_size); - if (express == NULL) { - h5outOfMemory(env, "H5Pget_data_transform: malloc failed "); - } /* end if */ - else { - express_size = (jlong)H5Pget_data_transform((hid_t)plist_id, express, (size_t)size); - if (express_size < 0) { - HDfree(express); - h5libraryError(env); - } - else { - str = ENVPTR->NewStringUTF(ENVPAR express); - HDfree(express); - if (str == NULL) - h5JNIFatalError(env, "H5Pget_data_transform: return string not created"); - else - ENVPTR->SetObjectArrayElement(ENVPAR expression, 0, str); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - return express_size; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1data_1transform */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_acc_flags - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags - (JNIEnv *env, jclass clss, jlong lapl_id) -{ - unsigned flags; - - if(H5Pget_elink_acc_flags((hid_t)lapl_id, &flags) < 0) - h5libraryError(env); - - return (jint)flags; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_acc_flags - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags - (JNIEnv *env, jclass clss, jlong lapl_id, jint flags) -{ - herr_t retVal = -1; - - retVal = H5Pset_elink_acc_flags((hid_t)lapl_id, (unsigned)flags); - if (retVal < 0) - h5libraryError(env); - - return (jint) retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_link_phase_change - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change - (JNIEnv *env, jclass clss, jlong gcpl_id, jint max_compact, jint min_dense) -{ - herr_t retVal = -1; - - if(max_compact < min_dense) { - h5badArgument(env, "H5Pset_link_phase_change: max compact value must be >= min dense value"); - } /* end if */ - else if(max_compact > 65535) { - h5badArgument(env, "H5Pset_link_phase_change: max compact value must be < 65536"); - } /* end else if */ - else if(min_dense > 65535) { - h5badArgument(env, "H5Pset_link_phase_change: min dense value must be < 65536"); - } /* end else if */ - else { - retVal = H5Pset_link_phase_change((hid_t)gcpl_id, (unsigned)max_compact, (unsigned)min_dense); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_link_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change - (JNIEnv *env, jclass clss, jlong gcpl_id, jintArray links) -{ - herr_t retVal = -1; - unsigned *theArray = NULL; - jboolean isCopy; - - if (links == NULL) { - h5nullArgument( env, "H5Pget_link_phase_change: links is NULL"); - } /* end if */ - else { - theArray = (unsigned *)ENVPTR->GetIntArrayElements(ENVPAR links, &isCopy); - if (theArray == NULL) { - h5JNIFatalError( env, "H5Pget_link_phase_change: input not pinned"); - } /* end if */ - else { - retVal = H5Pget_link_phase_change((hid_t)gcpl_id, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR links, (jint *)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR links, (jint *)theArray, 0); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_attr_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change - (JNIEnv *env, jclass clss, jlong ocpl_id, jintArray attributes) -{ - herr_t retVal = -1; - unsigned *theArray = NULL; - jboolean isCopy; - - if (attributes == NULL) { - h5nullArgument(env, "H5Pget_attr_phase_change: attributes is NULL"); - } /* end if */ - else { - theArray = (unsigned *)ENVPTR->GetIntArrayElements(ENVPAR attributes, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_attr_phase_change: input not pinned"); - } /* end if */ - else { - retVal = H5Pget_attr_phase_change((hid_t)ocpl_id, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR attributes, (jint *)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR attributes, (jint *)theArray, 0); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_attr_phase_change - * Signature: (JII)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change - (JNIEnv *env, jclass clss, jlong ocpl_id, jint max_compact, jint min_dense) -{ - herr_t retVal = -1; - - retVal = H5Pset_attr_phase_change((hid_t)ocpl_id, (unsigned)max_compact, (unsigned)min_dense); - if(retVal < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change - (JNIEnv *env, jclass clss, jlong fcpl_id, jintArray size) -{ - herr_t retVal = -1; - unsigned *theArray = NULL; - jboolean isCopy; - - if (size == NULL) { - h5nullArgument(env, "H5Pget_shared_mesg_phase_change: size is NULL"); - } /* end if */ - else { - theArray = (unsigned *)ENVPTR->GetIntArrayElements(ENVPAR size, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_shared_mesg_phase_change: input not pinned"); - } /* end if */ - else { - retVal = H5Pget_shared_mesg_phase_change((hid_t)fcpl_id, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR size, (jint *)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR size, (jint *)theArray, 0); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_phase_change - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change - (JNIEnv *env, jclass clss, jlong fcpl_id, jint max_list, jint min_btree) -{ - herr_t retVal = -1; - - /* Check that values are sensible. The min_btree value must be no greater - * than the max list plus one. - * - * Range check to make certain they will fit into encoded form. - */ - - if(max_list + 1 < min_btree) { - h5badArgument(env, "H5Pset_shared_mesg_phase_change: minimum B-tree value is greater than maximum list value"); - } /* end if */ - else if(max_list > H5O_SHMESG_MAX_LIST_SIZE) { - h5badArgument(env, "H5Pset_shared_mesg_phase_change: max list value is larger than H5O_SHMESG_MAX_LIST_SIZE"); - } /* end else if */ - else if(min_btree > H5O_SHMESG_MAX_LIST_SIZE) { - h5badArgument(env, "H5Pset_shared_mesg_phase_change: min btree value is larger than H5O_SHMESG_MAX_LIST_SIZE"); - } /* end else if */ - else { - retVal = H5Pset_shared_mesg_phase_change((hid_t)fcpl_id, (unsigned)max_list, (unsigned)min_btree); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_nindexes - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes - (JNIEnv *env, jclass clss, jlong fcpl_id) -{ - unsigned nindexes; - - if(H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes) < 0) - h5libraryError(env); - - return (jint)nindexes; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_nindexes - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes - (JNIEnv *env, jclass clss, jlong plist_id, jint nindexes) -{ - herr_t retVal = -1; - - if (nindexes > H5O_SHMESG_MAX_NINDEXES) { - h5badArgument(env, "H5Pset_shared_mesg_nindexes: number of indexes is greater than H5O_SHMESG_MAX_NINDEXES"); - } /* end if */ - else { - retVal = H5Pset_shared_mesg_nindexes((hid_t)plist_id, (unsigned)nindexes); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_index - * Signature: (JIII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index - (JNIEnv *env, jclass clss, jlong fcpl_id, jint index_num, - jint mesg_type_flags, jint min_mesg_size) -{ - herr_t retVal = -1; - unsigned nindexes;/* Number of SOHM indexes */ - - /* Check arguments */ - if(mesg_type_flags > H5O_SHMESG_ALL_FLAG) { - h5badArgument(env, "H5Pset_shared_mesg_index: unrecognized flags in mesg_type_flags"); - } /* end if */ - else if(H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes) < 0) { /* Read the current number of indexes */ - h5libraryError(env); - } /* end else if */ - else { - /* Range check */ - if((unsigned)index_num >= nindexes) { - h5badArgument(env, "H5Pset_shared_mesg_index: index_num is too large; no such index"); - } /* end if */ - else { - retVal = H5Pset_shared_mesg_index((hid_t)fcpl_id, (unsigned)index_num, (unsigned) mesg_type_flags, (unsigned) min_mesg_size); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_index - * Signature: (JI[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index - (JNIEnv *env, jclass clss, jlong fcpl_id, jint index_num, jintArray mesg_info) -{ - herr_t retVal = -1; - unsigned nindexes;/* Number of SOHM indexes */ - unsigned *theArray = NULL; - jboolean isCopy; - - /* Read the current number of indexes */ - if(H5Pget_shared_mesg_nindexes((hid_t)fcpl_id, &nindexes)<0) { - h5libraryError(env); - } /* end if */ - else { - /* Range check */ - if((unsigned)index_num >= nindexes) { - h5badArgument(env, "H5Pget_shared_mesg_index: index_num is too large; no such index"); - } /* end if */ - else if (mesg_info == NULL) { - h5nullArgument(env, "H5Pget_shared_mesg_index: mesg_info is NULL"); - } /* end else if */ - else { - theArray = (unsigned *)ENVPTR->GetIntArrayElements(ENVPAR mesg_info, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_shared_mesg_index: input not pinned"); - } /* end if */ - else { - retVal = H5Pget_shared_mesg_index((hid_t)fcpl_id, (unsigned)index_num, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR mesg_info, (jint*)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR mesg_info, (jint*)theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_local_heap_size_hint - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint - (JNIEnv *env, jclass clss, jlong gcpl_id, jlong size_hint) -{ - herr_t retVal = -1; - - retVal = H5Pset_local_heap_size_hint((hid_t)gcpl_id, (size_t)size_hint); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_local_heap_size_hint - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint - (JNIEnv *env, jclass clss, jlong gcpl_id) -{ - size_t size_hint; - - if(H5Pget_local_heap_size_hint((hid_t)gcpl_id, &size_hint) < 0) - h5libraryError(env); - - return (jlong)size_hint; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_nbit - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1nbit - (JNIEnv *env, jclass clss, jlong plist_id) -{ - herr_t retVal = -1; - - retVal = H5Pset_nbit((hid_t)plist_id); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1nbit */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_scaleoffset - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset - (JNIEnv *env, jclass clss, jlong plist_id, jint scale_type, jint scale_factor) -{ - herr_t retVal = -1; - - /* Check arguments */ - if(scale_factor < 0) { - h5badArgument(env, "H5Pset_scaleoffset: scale factor must be > 0"); - } /* end if */ - else { - if(scale_type != H5Z_SO_FLOAT_DSCALE && scale_type != H5Z_SO_FLOAT_ESCALE && scale_type != H5Z_SO_INT){ - h5badArgument(env, "H5Pset_scaleoffset: invalid scale type"); - } /* end if */ - else { - retVal = H5Pset_scaleoffset((hid_t)plist_id, (H5Z_SO_scale_type_t)scale_type, scale_factor); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_est_link_info - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info - (JNIEnv *env, jclass clss, jlong gcpl_id, jint est_num_entries, jint est_name_len) -{ - herr_t retVal = -1; - - /* Range check values */ - if((est_num_entries > 65535) || (est_name_len > 65535)) { - h5badArgument(env, "H5Pset_est_link_info: est. name length or number of entries must be < 65536"); - } /* end if */ - else { - retVal = H5Pset_est_link_info((hid_t)gcpl_id, (unsigned)est_num_entries, (unsigned)est_name_len); - if(retVal < 0) - h5libraryError(env); - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_est_link_info - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info - (JNIEnv *env, jclass clss, jlong gcpl_id, jintArray link_info) -{ - herr_t retVal = -1; - unsigned *theArray = NULL; - jboolean isCopy; - - if (link_info == NULL) { - h5nullArgument(env, "H5Pget_est_link_info: link_info is NULL"); - } /* end if */ - else { - theArray = (unsigned *)ENVPTR->GetIntArrayElements(ENVPAR link_info,&isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_est_link_info: input not pinned"); - } /* end if */ - else { - retVal= H5Pget_est_link_info((hid_t)gcpl_id, &(theArray[0]), &(theArray[1])); - if(retVal < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR link_info, (jint *)theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR link_info, (jint *)theArray, 0); - } /* end else */ - } /* end else */ - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_fapl - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl - (JNIEnv *env, jclass clss, jlong lapl_id, jlong fapl_id) -{ - herr_t retVal = -1; - - retVal = H5Pset_elink_fapl((hid_t)lapl_id, (hid_t)fapl_id); - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pget_elink_fapl - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl - (JNIEnv *env, jclass clss, jlong lapl_id) -{ - hid_t retVal = -1; - - retVal = H5Pget_elink_fapl((hid_t)lapl_id); - if (retVal < 0) - h5libraryError(env); - - return (jlong)retVal; -} /* end Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_prefix - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix - (JNIEnv *env, jclass clss, jlong lapl_id, jstring prefix) -{ - herr_t retVal = -1; - const char *aName; - - PIN_JAVA_STRING(prefix, aName); - if (aName != NULL) { - retVal = H5Pset_elink_prefix((hid_t)lapl_id, aName); - - UNPIN_JAVA_STRING(prefix, aName); - - if(retVal < 0) - h5libraryError(env); - } - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_prefix - * Signature: (J[Ljava/lang/String;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix - (JNIEnv *env, jclass clss, jlong lapl_id, jobjectArray prefix) -{ - size_t size = 0; - char *pre; - jlong prefix_size = -1; - jstring str = NULL; - - if (prefix == NULL) { - h5nullArgument(env, "H5Pget_elink_prefix: prefix is NULL"); - } /* end if */ - else { - prefix_size = (jlong)H5Pget_elink_prefix((hid_t)lapl_id, (char*)NULL, size); - if(prefix_size < 0) { - h5libraryError(env); - } /* end if */ - else { - size = (size_t)prefix_size + 1;/* add extra space for the null terminator */ - pre = (char*)HDmalloc(sizeof(char)*size); - if (pre == NULL) { - h5outOfMemory(env, "H5Pget_elink_prefix: malloc failed "); - } /* end if */ - else { - prefix_size = (jlong)H5Pget_elink_prefix((hid_t)lapl_id, (char*)pre, size); - - if (prefix_size < 0) { - HDfree(pre); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR pre); - HDfree(pre); - if (str == NULL) { - h5JNIFatalError(env, "H5Pget_elink_prefix: return string not created"); - } /* end if */ - else - ENVPTR->SetObjectArrayElement(ENVPAR prefix, 0, str); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - - return prefix_size; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_direct - * Signature: (JJJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct - (JNIEnv *env, jclass clss, jlong fapl_id, jlong alignment, - jlong block_size, jlong cbuf_size) -{ - herr_t retVal = -1; - -#ifdef H5_HAVE_DIRECT - retVal = H5Pset_fapl_direct((hid_t)fapl_id, (size_t)alignment, (size_t)block_size, (size_t)cbuf_size); -#endif - if(retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_direct - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct - (JNIEnv *env, jclass clss, jlong fapl_id, jlongArray info) -{ - herr_t retVal = -1; - -#ifdef H5_HAVE_DIRECT - size_t alignment = 0; - size_t block_size = 0; - size_t cbuf_size = 0; - jlong *theArray; - jboolean isCopy; - if (info == NULL) { - h5nullArgument(env, "H5Pget_fapl_direct: info input array is NULL"); - } /* end if */ - else { - if (ENVPTR->GetArrayLength(ENVPAR info) < 3) { - h5badArgument( env, "H5Pget_fapl_direct: info input array < 4"); - } /* end if */ - else { - theArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR info, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Pget_fapl_direct: info not pinned"); - } /* end if */ - else { - retVal = H5Pget_fapl_direct((hid_t)fapl_id, &alignment, &block_size, &cbuf_size); - if(retVal < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR info, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - theArray[0] = (jlong)alignment; - theArray[1] = (jlong)block_size; - theArray[2] = (jlong)cbuf_size; - ENVPTR->ReleaseLongArrayElements(ENVPAR info, theArray, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ -#else - if (retVal < 0) - h5libraryError(env); -#endif - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_sec2 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - herr_t retVal = -1; - - retVal = H5Pset_fapl_sec2((hid_t) fapl_id); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_stdio - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - herr_t retVal = -1; - - retVal = H5Pset_fapl_stdio((hid_t) fapl_id); - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_windows - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - herr_t retVal = -1; - -#ifdef H5_HAVE_WINDOWS - retVal = H5Pset_fapl_windows((hid_t) fapl_id); -#endif - if (retVal < 0) - h5libraryError(env); - - return (jint)retVal; -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_muti - * Signature: (J[I[J[Ljava/lang/String;[J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi - (JNIEnv *env, jclass clss, jlong tid, jintArray memb_map, - jlongArray memb_fapl, jobjectArray memb_name, jlongArray memb_addr) -{ - herr_t status = -1; - int i; - jint *themapArray = NULL; - jlong *thefaplArray = NULL; - jlong *theaddrArray = NULL; - char **mName = NULL; - jstring str; - jboolean isCopy; - int relax = 0; - - if (memb_map) { - themapArray = (jint*)ENVPTR->GetIntArrayElements(ENVPAR memb_map, &isCopy); - if (themapArray == NULL) { - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_map not pinned"); - return 0; - } /* end if */ - } /* end if */ - - if (memb_fapl) { - thefaplArray = (jlong*)ENVPTR->GetLongArrayElements(ENVPAR memb_fapl, &isCopy); - if (thefaplArray == NULL) { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_fapl not pinned"); - return 0; - } /* end if */ - } /* end if */ - - if (memb_addr) { - theaddrArray = (jlong*)ENVPTR->GetLongArrayElements(ENVPAR memb_addr, &isCopy); - if (theaddrArray == NULL) { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - if (memb_fapl) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_addr not pinned"); - return 0; - } /* end if */ - } /* end if */ - - if (memb_name) - mName = (char**)HDcalloc(H5FD_MEM_NTYPES, sizeof (*mName)); - - status = H5Pget_fapl_multi((hid_t)tid, (H5FD_mem_t*)themapArray, (hid_t*)thefaplArray, mName, (haddr_t*)theaddrArray, (hbool_t*)&relax); - - if (status < 0) { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - if (memb_fapl) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, JNI_ABORT); - if (memb_addr) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_addr, theaddrArray, JNI_ABORT); - if (memb_name) h5str_array_free(mName, H5FD_MEM_NTYPES); - h5libraryError(env); - } /* end if */ - else { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, 0); - if (memb_fapl) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, 0); - if (memb_addr) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_addr, theaddrArray, 0); - - if (memb_name) { - if (mName) { - for (i = 0; i < H5FD_MEM_NTYPES; i++) { - if (*(mName + i)) { - str = ENVPTR->NewStringUTF(ENVPAR *(mName+i)); - ENVPTR->SetObjectArrayElement(ENVPAR memb_name, i, (jobject)str); - } /* end if */ - } /* for (i=0; iGetIntArrayElements(ENVPAR memb_map, &isCopy); - if (themapArray == NULL) { - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_map not pinned"); - return; - } /* end if */ - } /* end if */ - - if (memb_fapl) { - thefaplArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR memb_fapl, &isCopy); - if (thefaplArray == NULL) { - if (memb_map) - ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_fapl not pinned"); - return; - } /* end if */ - } /* end if */ - - if (memb_addr) { - theaddrArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR memb_addr, &isCopy); - if (theaddrArray == NULL) { - if (memb_map) - ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - if (memb_fapl) - ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_fapl_muti: memb_addr not pinned"); - return; - } /* end if */ - } /* end if */ - - HDmemset(member_name, 0, H5FD_MEM_NTYPES * sizeof(char*)); - if (memb_name) { - int i; - for (i = 0; i < H5FD_MEM_NTYPES; i++) { - jstring obj = (jstring) ENVPTR->GetObjectArrayElement(ENVPAR (jobjectArray) memb_name, i); - if (obj != 0) { - jsize length = ENVPTR->GetStringUTFLength(ENVPAR obj); - const char *utf8 = ENVPTR->GetStringUTFChars(ENVPAR obj, 0); - - if (utf8) { - member_name[i] = (char*)HDmalloc(HDstrlen(utf8) + 1); - if (member_name[i]) { - strcpy(member_name[i], utf8); - } /* end if */ - } /* end if */ - - ENVPTR->ReleaseStringUTFChars(ENVPAR obj, utf8); - ENVPTR->DeleteLocalRef(ENVPAR obj); - } /* end if */ - } /* end for */ - mName = (const char **)member_name; - } /* end if */ - - status = H5Pset_fapl_multi((hid_t)tid, (const H5FD_mem_t *)themapArray, (const hid_t *)thefaplArray, mName, (const haddr_t *)theaddrArray, (hbool_t)relax); - - if (status < 0) { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, JNI_ABORT); - if (memb_fapl) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, JNI_ABORT); - if (memb_addr) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_addr, theaddrArray, JNI_ABORT); - if (memb_name) { - int i; - for (i = 0; i < H5FD_MEM_NTYPES; i++) - HDfree(member_name[i]); - } /* end if */ - h5libraryError(env); - } /* end if */ - else { - if (memb_map) ENVPTR->ReleaseIntArrayElements(ENVPAR memb_map, themapArray, 0); - if (memb_fapl) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_fapl, thefaplArray, 0); - if (memb_addr) ENVPTR->ReleaseLongArrayElements(ENVPAR memb_addr, theaddrArray, 0); - if (memb_name) { - if (mName != NULL) { - int i; - Sjc = ENVPTR->FindClass(ENVPAR "java/lang/String"); - if (Sjc != NULL) { - for (i = 0; i < H5FD_MEM_NTYPES; i++) { - rstring = ENVPTR->NewStringUTF(ENVPAR member_name[i]); - o = ENVPTR->GetObjectArrayElement(ENVPAR memb_name, i); - if (o != NULL) { - bb = ENVPTR->IsInstanceOf(ENVPAR o, Sjc); - if (bb == JNI_TRUE) { - ENVPTR->SetObjectArrayElement(ENVPAR memb_name, i, (jobject)rstring); - } /* end if */ - ENVPTR->DeleteLocalRef(ENVPAR o); - } /* end if */ - HDfree(member_name[i]); - } /* end for */ - } /* end if */ - } /* end if */ - } /* end if */ - } /* end else */ -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_split - * Signature: (JLjava/lang/String;JLjava/lang/String;J)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split - (JNIEnv *env, jclass clss, jlong fapl_id, jstring metaext, jlong meta_pl_id, jstring rawext, jlong raw_pl_id) -{ - herr_t retVal = -1; - const char *mstr; - const char *rstr; - - PIN_JAVA_STRING_TWO(metaext, mstr, rawext, rstr); - if (mstr != NULL && rstr != NULL) { - retVal = H5Pset_fapl_split((hid_t)fapl_id, mstr, (hid_t)meta_pl_id, rstr, (hid_t)raw_pl_id); - - UNPIN_JAVA_STRING_TWO(metaext, mstr, rawext, rstr); - - if (retVal < 0) - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_meta_block_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size - (JNIEnv *env, jclass clss, jlong plist, jlong size) -{ - long sz = (long)size; - - if (H5Pset_meta_block_size((hid_t)plist, (hsize_t)sz) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_meta_block_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size - (JNIEnv *env, jclass clss, jlong plist) -{ - hsize_t s; - - if (H5Pget_meta_block_size((hid_t)plist, &s) < 0) - h5libraryError(env); - - return (jlong)s; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sieve_buf_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size - (JNIEnv *env, jclass clss, jlong plist, jlong size) -{ - size_t sz = (size_t)size; - - if (H5Pset_sieve_buf_size((hid_t)plist, (size_t)sz) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sieve_buf_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size - (JNIEnv *env, jclass clss, jlong plist) -{ - size_t s; - - if (H5Pget_sieve_buf_size((hid_t)plist, &s) < 0) - h5libraryError(env); - - return (jlong)s; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_file_cache_size - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size - (JNIEnv *env, jclass clss, jlong plist, jint size) -{ - unsigned sz = (unsigned)size; - - if (H5Pset_elink_file_cache_size((hid_t)plist, (unsigned)sz) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_file_cache_size - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size - (JNIEnv *env, jclass clss, jlong plist) -{ - unsigned s; - - if (H5Pget_elink_file_cache_size((hid_t)plist, &s) < 0) - h5libraryError(env); - - return (jint)s; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size */ - - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_mdc_config - * Signature: (J)Lhdf/hdf5lib/structs/H5AC_cache_config_t; - */ -JNIEXPORT jobject JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config - (JNIEnv *env, jclass clss, jlong plist) -{ - H5AC_cache_config_t cacheinfo; - herr_t status = -1; - jvalue args[30]; - jstring j_str = NULL; - jobject ret_obj = NULL; - - HDmemset(&cacheinfo, 0, sizeof(H5AC_cache_config_t)); - cacheinfo.version = H5AC__CURR_CACHE_CONFIG_VERSION; - - status = H5Pget_mdc_config((hid_t)plist, &cacheinfo); - - if (status < 0) { - h5libraryError(env); - } /* end if */ - else { - args[0].i = cacheinfo.version; - args[1].z = cacheinfo.rpt_fcn_enabled; - args[2].z = cacheinfo.open_trace_file; - args[3].z = cacheinfo.close_trace_file; - if (cacheinfo.trace_file_name != NULL) { - j_str = ENVPTR->NewStringUTF(ENVPAR cacheinfo.trace_file_name); - } /* end if */ - args[4].l = j_str; - args[5].z = cacheinfo.evictions_enabled; - args[6].z = cacheinfo.set_initial_size; - args[7].j = (jlong)cacheinfo.initial_size; - args[8].d = cacheinfo.min_clean_fraction; - args[9].j = (jlong)cacheinfo.max_size; - args[10].j = (jlong)cacheinfo.min_size; - args[11].j = cacheinfo.epoch_length; - args[12].i = cacheinfo.incr_mode; - args[13].d = cacheinfo.lower_hr_threshold; - args[14].d = cacheinfo.increment; - args[15].z = cacheinfo.apply_max_increment; - args[16].j = (jlong)cacheinfo.max_increment; - args[17].i = cacheinfo.flash_incr_mode; - args[18].d = cacheinfo.flash_multiple; - args[19].d = cacheinfo.flash_threshold; - args[20].i = cacheinfo.decr_mode; - args[21].d = cacheinfo.upper_hr_threshold; - args[22].d = cacheinfo.decrement; - args[23].z = cacheinfo.apply_max_decrement; - args[24].j = (jlong)cacheinfo.max_decrement; - args[25].i = cacheinfo.epochs_before_eviction; - args[26].z = cacheinfo.apply_empty_reserve; - args[27].d = cacheinfo.empty_reserve; - args[28].j = (jlong)cacheinfo.dirty_bytes_threshold; - args[29].i = cacheinfo.metadata_write_strategy; - CALL_CONSTRUCTOR("hdf/hdf5lib/structs/H5AC_cache_config_t", "(IZZZLjava/lang/String;ZZJDJJJIDDZJIDDIDDZJIZDJI)V", args); - } /* end else */ - return ret_obj; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_mdc_config - * Signature: (JLhdf/hdf5lib/structs/H5AC_cache_config_t;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config - (JNIEnv *env, jclass clss, jlong plist, jobject cache_config) -{ - herr_t status = -1; - jclass cls; - jfieldID fid; - jstring j_str; - const char *str; - H5AC_cache_config_t cacheinfo; - - cls = ENVPTR->GetObjectClass(ENVPAR cache_config); - fid = ENVPTR->GetFieldID(ENVPAR cls, "version", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: version"); - return; - } /* end if */ - cacheinfo.version = ENVPTR->GetIntField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading version failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "rpt_fcn_enabled", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: rpt_fcn_enabled"); - return; - } /* end if */ - cacheinfo.rpt_fcn_enabled = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading rpt_fcn_enabled failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "open_trace_file", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: open_trace_file"); - return; - } /* end if */ - cacheinfo.open_trace_file = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading open_trace_file failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "close_trace_file", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: close_trace_file"); - return; - } /* end if */ - cacheinfo.close_trace_file = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading close_trace_file failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "trace_file_name", "Ljava/lang/String;"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: trace_file_name"); - return; - } /* end if */ - j_str = (jstring)ENVPTR->GetObjectField(ENVPAR cache_config, fid); - str = ENVPTR->GetStringUTFChars(ENVPAR j_str, NULL); - if (str == NULL) { - h5JNIFatalError(env, "H5Pset_mdc_config: out of memory trace_file_name"); - return; - } /* end if */ - HDstrncpy(cacheinfo.trace_file_name, str, 1025); - ENVPTR->ReleaseStringUTFChars(ENVPAR j_str, str); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading trace_file_name failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "evictions_enabled", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: evictions_enabled"); - return; - } /* end if */ - cacheinfo.evictions_enabled = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading evictions_enabled failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "set_initial_size", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: set_initial_size"); - return; - } /* end if */ - cacheinfo.set_initial_size = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading set_initial_size failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "initial_size", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: initial_size"); - return; - } /* end if */ - cacheinfo.initial_size = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading initial_size failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "min_clean_fraction", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: min_clean_fraction"); - return; - } /* end if */ - cacheinfo.min_clean_fraction = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading min_clean_fraction failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "max_size", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: max_size"); - return; - } /* end if */ - cacheinfo.max_size = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading max_size failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "min_size", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: min_size"); - return; - } /* end if */ - cacheinfo.min_size = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading min_size failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "epoch_length", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: epoch_length"); - return; - } - cacheinfo.epoch_length = (long int)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading epoch_length failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "incr_mode", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: incr_mode"); - return; - } /* end if */ - cacheinfo.incr_mode = ENVPTR->GetIntField(ENVPAR cache_config, fid); /*(enum H5C_cache_incr_mode) */ - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading incr_mode failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "lower_hr_threshold", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: lower_hr_threshold"); - return; - } /* end if */ - cacheinfo.lower_hr_threshold = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading lower_hr_threshold failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "increment", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: increment"); - return; - } /* end if */ - cacheinfo.increment = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading increment failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "apply_max_increment", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: apply_max_increment"); - return; - } /* end if */ - cacheinfo.apply_max_increment = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading apply_max_increment failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "max_increment", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: max_increment"); - return; - } /* end if */ - cacheinfo.max_increment = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading max_increment failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "flash_incr_mode", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: flash_incr_mode"); - return; - } /* end if */ - cacheinfo.flash_incr_mode = ENVPTR->GetIntField(ENVPAR cache_config, fid); /*(enum H5C_cache_flash_incr_mode) */ - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading flash_incr_mode failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "flash_multiple", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: flash_multiple"); - return; - } /* end if */ - cacheinfo.flash_multiple = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading flash_multiple failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "flash_threshold", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: flash_threshold"); - return; - } /* end if */ - cacheinfo.flash_threshold = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading flash_threshold failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "decr_mode", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: decr_mode"); - return; - } /* end if */ - cacheinfo.decr_mode = ENVPTR->GetIntField(ENVPAR cache_config, fid); /*(enum H5C_cache_decr_mode) */ - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading decr_mode failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "upper_hr_threshold", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: upper_hr_threshold"); - return; - } /* end if */ - cacheinfo.upper_hr_threshold = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading upper_hr_threshold failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "decrement", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: decrement"); - return; - } /* end if */ - cacheinfo.decrement = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading decrement failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "apply_max_decrement", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: apply_max_decrement"); - return; - } /* end if */ - cacheinfo.apply_max_decrement = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading apply_max_decrement failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "max_decrement", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: max_decrement"); - return; - } /* end if */ - cacheinfo.max_decrement = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading max_decrement failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "epochs_before_eviction", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: epochs_before_eviction"); - return; - } /* end if */ - cacheinfo.epochs_before_eviction = ENVPTR->GetIntField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading epochs_before_eviction failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "apply_empty_reserve", "Z"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: apply_empty_reserve"); - return; - } /* end if */ - cacheinfo.apply_empty_reserve = ENVPTR->GetBooleanField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading apply_empty_reserve failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "empty_reserve", "D"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: empty_reserve"); - return; - } /* end if */ - cacheinfo.empty_reserve = ENVPTR->GetDoubleField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading empty_reserve failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "dirty_bytes_threshold", "J"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: dirty_bytes_threshold"); - return; - } /* end if */ - cacheinfo.dirty_bytes_threshold = (size_t)ENVPTR->GetLongField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading dirty_bytes_threshold failed"); - return; - } /* end if */ - - fid = ENVPTR->GetFieldID(ENVPAR cls, "metadata_write_strategy", "I"); - if(fid == 0) { - h5badArgument(env, "H5Pset_mdc_config: metadata_write_strategy"); - return; - } /* end if */ - cacheinfo.metadata_write_strategy = ENVPTR->GetIntField(ENVPAR cache_config, fid); - if(ENVPTR->ExceptionOccurred(ENVONLY)) { - h5JNIFatalError(env, "H5Pset_mdc_config: loading metadata_write_strategy failed"); - } /* end if */ - else { - status = H5Pset_mdc_config((hid_t)plist, &cacheinfo); - - if (status < 0) - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk_cache - * Signature: (JJJD)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk_1cache - (JNIEnv *env, jclass clss, jlong dapl, jlong rdcc_nslots, - jlong rdcc_nbytes, jdouble rdcc_w0) -{ - if (H5Pset_chunk_cache((hid_t)dapl, (size_t)rdcc_nslots, (size_t)rdcc_nbytes, (double) rdcc_w0) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1chunk_1cache */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk_cache - * Signature: (J[J[J[D)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk_1cache - (JNIEnv *env, jclass clss, jlong dapl, jlongArray rdcc_nslots, - jlongArray rdcc_nbytes, jdoubleArray rdcc_w0) -{ - herr_t status = -1; - jint mode; - jdouble *w0Array = (jdouble *)NULL; - jlong *rdcc_nslotsArray = (jlong *)NULL; - jlong *nbytesArray = (jlong *)NULL; - jboolean isCopy; - - if (rdcc_w0 != NULL) { - w0Array = (jdouble *)ENVPTR->GetDoubleArrayElements(ENVPAR rdcc_w0, &isCopy); - if (w0Array == NULL) { - h5JNIFatalError(env, "H5Pget_chunk_cache: w0_array array not pinned"); - return; - } /* end if */ - } /* end else */ - - if (rdcc_nslots != NULL) { - rdcc_nslotsArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR rdcc_nslots, &isCopy); - if (rdcc_nslotsArray == NULL) { - /* exception -- out of memory */ - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, JNI_ABORT); - } /* end if */ - h5JNIFatalError(env, "H5Pget_chunk_cache: rdcc_nslots array not pinned"); - return; - } /* end if */ - } /* end else */ - - if (rdcc_nbytes != NULL) { - nbytesArray = (jlong *)ENVPTR->GetLongArrayElements(ENVPAR rdcc_nbytes, &isCopy); - if (nbytesArray == NULL) { - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, JNI_ABORT); - } /* end if */ - if (rdcc_nslotsArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nslots, rdcc_nslotsArray, JNI_ABORT); - } /* end if */ - h5JNIFatalError(env, "H5Pget_chunk_cache: nbytesArray array not pinned"); - return; - } /* end if */ - } /* end else */ - - { /* direct cast (size_t *)variable fails on 32-bit environment */ - long long rdcc_nslots_temp = *(rdcc_nslotsArray); - size_t rdcc_nslots_t = (size_t)rdcc_nslots_temp; - long long nbytes_temp = *(nbytesArray); - size_t nbytes_t = (size_t)nbytes_temp; - - status = H5Pget_chunk_cache((hid_t)dapl, &rdcc_nslots_t, &nbytes_t, (double *)w0Array); - - *rdcc_nslotsArray = (jlong)rdcc_nslots_t; - *nbytesArray = (jlong)nbytes_t; - } /* end direct cast special handling */ - - if (status < 0) { - mode = JNI_ABORT; - } /* end if */ - else { - mode = 0; /* commit and free */ - } /* end else */ - - if (rdcc_nslotsArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nslots, rdcc_nslotsArray, mode); - } - /* end if */ - if (nbytesArray != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR rdcc_nbytes, nbytesArray, mode); - } /* end if */ - - if (w0Array != NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rdcc_w0, w0Array, mode); - } /* end if */ - - if (status < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pget_1chunk_1cache */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_obj_track_times - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times - (JNIEnv *env, jclass clss, jlong objplid) -{ - hbool_t track_times; - - if (H5Pget_obj_track_times((hid_t)objplid, &track_times) < 0) { - h5libraryError(env); - return JNI_FALSE; - } /* end if */ - if (track_times == 1) { - return JNI_TRUE; - } /* end if */ - return JNI_FALSE; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_obj_track_times - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times - (JNIEnv *env, jclass clss, jlong objplid, jboolean track_times) -{ - hbool_t track; - - if (track_times == JNI_TRUE) { - track = 1; - } /* end if */ - else { - track = 0; - } /* end else */ - - if (H5Pset_obj_track_times((hid_t)objplid, track) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_char_encoding - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding - (JNIEnv *env, jclass clss, jlong acpl) -{ - H5T_cset_t encoding; - - if (H5Pget_char_encoding((hid_t)acpl, &encoding) < 0) - h5libraryError(env); - - return encoding; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_char_encoding - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding - (JNIEnv *env, jclass clss, jlong acpl, jint encoding) -{ - if (H5Pset_char_encoding((hid_t)acpl, (H5T_cset_t)encoding) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual - * Signature: (JJLjava/lang/String;Ljava/lang/String;J)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual - (JNIEnv *env, jclass clss, jlong dcpl_id, jlong vspace_id, - jstring src_file_name, jstring src_dset_name, jlong src_space_id) -{ - herr_t retVal = -1; - const char *fstr; - const char *dstr; - - PIN_JAVA_STRING_TWO(src_file_name, fstr, src_dset_name, dstr); - if (fstr != NULL && dstr != NULL) { - retVal = H5Pset_virtual((hid_t)dcpl_id, (hid_t)vspace_id, fstr, dstr, (hid_t)src_space_id); - - UNPIN_JAVA_STRING_TWO(src_file_name, fstr, src_dset_name, dstr); - - if (retVal < 0) - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_count - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count - (JNIEnv *env, jclass clss, jlong dcpl_id) -{ - size_t s; - - if (H5Pget_virtual_count((hid_t)dcpl_id, &s) < 0) - h5libraryError(env); - - return (jlong)s; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_vspace - * Signature: (JJ)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace - (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) -{ - hid_t space_id = -1; - - space_id = H5Pget_virtual_vspace((hid_t)dcpl_id, (size_t)index); - if (space_id < 0) - h5libraryError(env); - - return (jlong)space_id; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_srcspace - * Signature: (JJ)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace - (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) -{ - hid_t space_id = -1; - - space_id = H5Pget_virtual_srcspace((hid_t)dcpl_id, (size_t)index); - if (space_id < 0) - h5libraryError(env); - - return (jlong)space_id; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_filename - * Signature: (JJ)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename - (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) -{ - char *fname; - ssize_t buf_size; - ssize_t status; - jstring str = NULL; - - /* get the length of the filename */ - buf_size = H5Pget_virtual_filename((hid_t)dcpl_id, (size_t)index, NULL, 0); - if (buf_size < 0) { - h5badArgument( env, "H5Pget_virtual_filename: buf_size < 0"); - } /* end if */ - else if (buf_size >= 0) { - buf_size++; /* add extra space for the null terminator */ - fname = (char *)HDmalloc(sizeof(char) * (size_t)buf_size); - if (fname == NULL) { - h5outOfMemory( env, "H5Pget_virtual_filename: malloc failed"); - } /* end if */ - else { - status = H5Pget_virtual_filename((hid_t)dcpl_id, (size_t)index, fname, (size_t)buf_size); - - if (status >= 0) { - str = ENVPTR->NewStringUTF(ENVPAR fname); - HDfree(fname); - if (str == NULL) - h5JNIFatalError( env, "H5Pget_virtual_filename: return string not allocated"); - } /* end if */ - else { - HDfree(fname); - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else if */ - - return (jstring)str; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_dsetname - * Signature: (JJ)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname - (JNIEnv *env, jclass clss, jlong dcpl_id, jlong index) -{ - char *dname; - ssize_t buf_size; - ssize_t status; - jstring str = NULL; - - /* get the length of the filename */ - buf_size = H5Pget_virtual_dsetname((hid_t)dcpl_id, (size_t)index, NULL, 0); - if (buf_size < 0) { - h5badArgument( env, "H5Pget_virtual_dsetname: buf_size < 0"); - } /* end if */ - else if (buf_size > 0) { - buf_size++; /* add extra space for the null terminator */ - dname = (char *)HDmalloc(sizeof(char) * (size_t)buf_size); - if (dname == NULL) { - h5outOfMemory( env, "H5Pget_virtual_dsetname: malloc failed"); - } /* end if */ - else { - status = H5Pget_virtual_dsetname((hid_t)dcpl_id, (size_t)index, dname, (size_t)buf_size); - - if (status >= 0) { - str = ENVPTR->NewStringUTF(ENVPAR dname); - HDfree(dname); - if (str == NULL) - h5JNIFatalError( env, "H5Pget_virtual_dsetname: return string not allocated"); - } /* end if */ - else { - HDfree(dname); - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else if */ - return (jstring)str; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_view - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1view - (JNIEnv *env, jclass clss, jlong dapl_id) -{ - H5D_vds_view_t virtual_view; - - if (H5Pget_virtual_view((hid_t)dapl_id, &virtual_view) < 0) - h5libraryError(env); - - return (jint)virtual_view; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1view */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_view - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1view - (JNIEnv *env, jclass clss, jlong dapl_id, jint view) -{ - if (H5Pset_virtual_view((hid_t)dapl_id, (H5D_vds_view_t)view) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual_1view */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_printf_gap - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1printf_1gap - (JNIEnv *env, jclass clss, jlong dapl_id) -{ - hsize_t gap_size; - - if (H5Pget_virtual_printf_gap((hid_t)dapl_id, &gap_size) < 0) - h5libraryError(env); - - return (jlong)gap_size; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1printf_1gap */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_printf_gap - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1printf_1gap - (JNIEnv *env, jclass clss, jlong dapl_id, jlong gap_size) -{ - if (H5Pset_virtual_printf_gap((hid_t)dapl_id, (hsize_t)gap_size) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual_1printf_1gap */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy - * Signature: (J[Z[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy - (JNIEnv *env, jclass clss, jlong fcpl_id, jbooleanArray persist, jlongArray threshold) -{ - herr_t status = -1; - H5F_fspace_strategy_t thestrategy = H5F_FSPACE_STRATEGY_FSM_AGGR; /* Library default */ - jlong *thethresholdArray = NULL; - jboolean *thepersistArray = NULL; - jboolean isCopy; - - if (persist) { - thepersistArray = (jboolean*)ENVPTR->GetBooleanArrayElements(ENVPAR persist, &isCopy); - if (thepersistArray == NULL) { - h5JNIFatalError(env, "H5Pget_file_space: persist not pinned"); - return -1; - } - } - - if (threshold) { - thethresholdArray = (jlong*)ENVPTR->GetLongArrayElements(ENVPAR threshold, &isCopy); - if (thethresholdArray == NULL) { - if (persist) ENVPTR->ReleaseBooleanArrayElements(ENVPAR persist, thepersistArray, JNI_ABORT); - h5JNIFatalError(env, "H5Pget_file_space: threshold not pinned"); - return -1; - } /* end if */ - } /* end if */ - - status = H5Pget_file_space_strategy((hid_t)fcpl_id, &thestrategy, (hbool_t*)thepersistArray, (hsize_t*)thethresholdArray); - - if (status < 0) { - if (persist) ENVPTR->ReleaseBooleanArrayElements(ENVPAR persist, thepersistArray, JNI_ABORT); - if (threshold) ENVPTR->ReleaseLongArrayElements(ENVPAR threshold, thethresholdArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - if (persist) ENVPTR->ReleaseBooleanArrayElements(ENVPAR persist, thepersistArray, 0); - if (threshold) ENVPTR->ReleaseLongArrayElements(ENVPAR threshold, thethresholdArray, 0); - } /* end else */ - return (jint)thestrategy; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy_persist - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist - (JNIEnv *env, jclass clss, jlong fcpl_id) -{ - herr_t status = -1; - hbool_t thepersist = FALSE; - - status = H5Pget_file_space_strategy((hid_t)fcpl_id, NULL, &thepersist, NULL); - - if (status < 0) - h5libraryError(env); - - return (jboolean)thepersist; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy_threshold - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1threshold - (JNIEnv *env, jclass clss, jlong fcpl_id) -{ - herr_t status = -1; - hsize_t thethreshold; - - status = H5Pget_file_space_strategy((hid_t)fcpl_id, NULL, NULL, &thethreshold); - - if (status < 0) - h5libraryError(env); - - return (jlong)thethreshold; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1threshold */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_file_space_strategy - * Signature: (JIZJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1strategy - (JNIEnv *env, jclass clss, jlong fcpl_id, jint strategy, jboolean persist, jlong threshold) -{ - if (H5Pset_file_space_strategy((hid_t)fcpl_id, (H5F_fspace_strategy_t)strategy, (hbool_t)persist, (hsize_t)threshold) < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_file_space_strategy */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_file_space_page_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1page_1size - (JNIEnv *env, jclass clss, jlong fcpl_id, jlong fsp_size) -{ - if (H5Pset_file_space_page_size((hid_t)fcpl_id, (hsize_t)fsp_size) < 0) - h5libraryError(env); -} - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_page_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1page_1size - (JNIEnv *env, jclass clss, jlong fcpl_id) -{ - hsize_t fsp_size = 0; - if (H5Pget_file_space_page_size((hid_t)fcpl_id, &fsp_size) < 0) - h5libraryError(env); - return (jlong)fsp_size; -} - -static herr_t -H5P_cls_create_cb - (hid_t prop_id, void *create_data) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR create_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLhdf/hdf5lib/callbacks/H5P_cls_create_func_t;)I"); - if (mid != 0) { - /* fprintf(stderr, "JNI H5P_cls_create_func_cb execute\n"); fflush(stderr); */ - status = CBENVPTR->CallIntMethod(CBENVPAR create_callback, mid, prop_id, create_data); - /* fprintf(stderr, "\nJNI H5P_cls_create_func_cb status: %d\n", status); fflush(stderr); */ - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_cls_create_cb */ - -static herr_t -H5P_cls_copy_cb - (hid_t new_prop_id, hid_t old_prop_id, void *copy_data) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR copy_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JJLhdf/hdf5lib/callbacks/H5P_cls_copy_func_t;)I"); - if (mid != 0) { - status = CBENVPTR->CallIntMethod(CBENVPAR copy_callback, mid, new_prop_id, old_prop_id, copy_data); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_cls_copy_cb */ - -static herr_t -H5P_cls_close_cb - (hid_t prop_id, void *close_data) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR close_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLhdf/hdf5lib/callbacks/H5P_cls_close_func_t;)I"); - if (mid != 0) { - status = CBENVPTR->CallIntMethod(CBENVPAR close_callback, mid, prop_id, close_data); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_cls_close_cb */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_mdc_log_options - * Signature: (JZLjava/lang/String;Z)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options - (JNIEnv *env, jclass clss, jlong fapl_id, jboolean is_enabled, jstring location, jboolean start_on_access) -{ - herr_t retVal = -1; - const char *lstr; - - PIN_JAVA_STRING(location, lstr); - - retVal = H5Pset_mdc_log_options((hid_t)fapl_id, (hbool_t)is_enabled, lstr, (hbool_t)start_on_access); - - UNPIN_JAVA_STRING(location, lstr); - - if (retVal < 0) { - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_mdc_log_options - * Signature: (J[Z)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options - (JNIEnv *env, jclass clss, jlong fapl_id, jbooleanArray mdc_log_options) -{ - hbool_t is_enabled; - hbool_t start_on_access; - jboolean *mdc_log_options_ptr; - char *lname; - size_t location_size; - ssize_t status; - jstring str = NULL; - jint size; - jboolean isCopy; - - if (mdc_log_options == NULL) { - h5nullArgument(env, "H5Fget_mdc_log_options: mdc_log_options is NULL"); - } /* end if */ - else { - size = (int)ENVPTR->GetArrayLength(ENVPAR mdc_log_options); - if (size < 2) { - h5badArgument(env, "H5Fget_mdc_log_options: length of mdc_log_options < 2."); - } /* end if */ - else { - /* get the length of the filename */ - H5Pget_mdc_log_options((hid_t)fapl_id, &is_enabled, NULL, &location_size, &start_on_access); - if (location_size == 0) { - h5badArgument(env, "H5Pget_mdc_log_options: location_size is 0"); - }/* end if */ - else if (location_size > 0) { - location_size++; /* add extra space for the null terminator */ - lname = (char *)HDmalloc(sizeof(char) * location_size); - if (lname == NULL) { - h5outOfMemory(env, "H5Pget_mdc_log_options: malloc failed"); - } /* end if */ - else { - status = H5Pget_mdc_log_options((hid_t)fapl_id, &is_enabled, lname, &location_size, &start_on_access); - - if (status < 0) { - HDfree(lname); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR lname); - HDfree(lname); - if (str == NULL) { - h5JNIFatalError(env, "H5Pget_mdc_log_options: return string not allocated"); - } /* end if */ - else { - mdc_log_options_ptr = ENVPTR->GetBooleanArrayElements(ENVPAR mdc_log_options, &isCopy); - mdc_log_options_ptr[0] = (jboolean)is_enabled; - mdc_log_options_ptr[1] = (jboolean)start_on_access; - ENVPTR->ReleaseBooleanArrayElements(ENVPAR mdc_log_options, mdc_log_options_ptr, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else if*/ - } /* end else */ - } /* end else */ - - return (jstring)str; -} /* end if */ - -static herr_t -H5D_append_cb - (hid_t dataset_id, hsize_t *cur_dims, void *cb_data) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jlongArray cur_dimsArray; - cb_wrapper *wrapper = (cb_wrapper *)cb_data; - void *op_data = (void *)wrapper->op_data; - jobject visit_callback = wrapper->visit_callback; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) != 0) { - JVMPTR->DetachCurrentThread(JVMPAR); - return -1; - } /* end if */ - cls = CBENVPTR->GetObjectClass(CBENVPAR visit_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(J[JLhdf/hdf5lib/callbacks/H5D_append_t;)I"); - if (mid != 0) { - if (cur_dims != NULL) { - cur_dimsArray = CBENVPTR->NewLongArray(CBENVPAR 2); - if (cur_dimsArray != NULL) { - CBENVPTR->SetLongArrayRegion(CBENVPAR cur_dimsArray, 0, 2, (const jlong *)cur_dims); - - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, dataset_id, cur_dims, op_data); - } - } - } - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - - return (herr_t)status; -} /* end H5D_append_cb */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_append_flush - * Signature: (JI[JLjava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1append_1flush - (JNIEnv *env, jclass clss, jlong plist_id, jint ndims, jlongArray boundary, jobject callback_op, jobject op_data) -{ - herr_t status = -1; - cb_wrapper wrapper = {callback_op, op_data}; - - ENVPTR->GetJavaVM(ENVPAR &jvm); - - if (op_data == NULL) { - h5nullArgument(env, "H5Pset_append_flush: op_data is NULL"); - } /* end if */ - else if (callback_op == NULL) { - h5nullArgument(env, "H5Pset_append_flush: callback_op is NULL"); - } /* end if */ - else { - status = H5Pset_append_flush((hid_t)plist_id, (unsigned)ndims, (const hsize_t*)boundary, (H5D_append_cb_t)H5D_append_cb, (void*)&wrapper); - - if (status < 0) - h5libraryError(env); - } /* end else */ -} /* end Java_hdf_hdf5lib_H5_H5Pset_1append_1flush */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pcreate_class_nocb - * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb - (JNIEnv *env, jclass clss, jlong parent_class, jstring name) -{ - hid_t class_id = -1; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - class_id = H5Pcreate_class((hid_t)parent_class, cstr, NULL, NULL, NULL, NULL, NULL, NULL); - - UNPIN_JAVA_STRING(name, cstr); - - if (class_id < 0) - h5libraryError(env); - } - - return (jlong)class_id; -} /* end Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pcreate_class - * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pcreate_1class - (JNIEnv *env, jclass clss, jlong parent_class, jstring name, jobject create_op, - jobject create_data, jobject copy_op, jobject copy_data, jobject close_op, jobject close_data) -{ - hid_t class_id = -1; - const char *cstr; - copy_callback = copy_op; - close_callback = close_op; - create_callback = create_op; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - class_id = H5Pcreate_class((hid_t)parent_class, cstr, (H5P_cls_create_func_t)H5P_cls_create_cb, (void*) create_data, - (H5P_cls_copy_func_t)H5P_cls_copy_cb, (void*) copy_data, (H5P_cls_close_func_t)H5P_cls_close_cb, (void*) close_data); - - UNPIN_JAVA_STRING(name, cstr); - - if (class_id < 0) - h5libraryError(env); - } - - return (jlong)class_id; -} /* end Java_hdf_hdf5lib_H5__1H5Pcreate_1class */ - -static herr_t -H5P_prp_create_cb - (const char *name, size_t size, void *value) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jstring str; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR create_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(Ljava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR create_callback, mid, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_create_cb */ - -static herr_t -H5P_prp_copy_cb - (const char *name, size_t size, void *value) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jstring str; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR copy_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(Ljava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR copy_callback, mid, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_copy_cb */ - -static herr_t -H5P_prp_close_cb - (const char *name, size_t size, void *value) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jstring str; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR close_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(Ljava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR close_callback, mid, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_close_cb */ - -static int -H5P_prp_compare_cb - (void *value1, void *value2, size_t size) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR compare_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "([B[BJ)I"); - if (mid != 0) { - status = CBENVPTR->CallIntMethod(CBENVPAR compare_callback, mid, value1, value2, size); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_compare_cb */ + status = CBENVPTR->CallIntMethod(CBENVONLY, get_callback, mid, prop_id, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -static herr_t -H5P_prp_get_cb - (hid_t prop_id, const char *name, size_t size, void *value) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jstring str; +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR get_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLjava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR get_callback, mid, prop_id, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); return (herr_t)status; } /* end H5P_prp_get_cb */ static herr_t -H5P_prp_set_cb - (hid_t prop_id, const char *name, size_t size, void *value) -{ - JNIEnv *cbenv; - jint status = -1; - jclass cls; - jmethodID mid; - jstring str; - - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR set_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLjava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR set_callback, mid, prop_id, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_set_cb */ - -static herr_t H5P_prp_delete_cb (hid_t prop_id, const char *name, size_t size, void *value) { - JNIEnv *cbenv; - jint status = -1; - jclass cls; jmethodID mid; jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) == 0) { - cls = CBENVPTR->GetObjectClass(CBENVPAR delete_callback); - if (cls != 0) { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLjava/lang/String;J[B)I"); - if (mid != 0) { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - status = CBENVPTR->CallIntMethod(CBENVPAR delete_callback, mid, prop_id, str, size, value); - } /* end if */ - } /* end if */ - } /* end if */ - JVMPTR->DetachCurrentThread(JVMPAR); - return (herr_t)status; -} /* end H5P_prp_delete_cb */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pregister2_nocb - * Signature: (JLjava/lang/String;J[B)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pregister2_1nocb - (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, jbyteArray def_value) -{ - herr_t status = -1; - jbyte *buffP; - jboolean isCopy2; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - buffP = ENVPTR->GetByteArrayElements(ENVPAR def_value, &isCopy2); - if (buffP == NULL) { - h5JNIFatalError(env, "H5Pregister2: buf not pinned"); - } /* end if */ - else { - status = H5Pregister2((hid_t)cls_id, cstr, (size_t)prp_size, (void*)buffP, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, 0); - } /* end else */ - } /* end else */ - UNPIN_JAVA_STRING(name, cstr); + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_delete_cb: failed to attach current thread to JVM"); } -} /* end Java_hdf_hdf5lib_H5_H5Pregister2_1nocb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pregister2 - * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pregister2 - (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, - jbyteArray def_value, jobject prp_create, jobject prp_set, jobject prp_get, jobject prp_delete, - jobject prp_copy, jobject prp_cmp, jobject prp_close) -{ - herr_t status = -1; - jbyte *buffP; - jboolean isCopy2; - const char *cstr; - copy_callback = prp_copy; - close_callback = prp_close; - create_callback = prp_create; - compare_callback = prp_cmp; - set_callback = prp_set; - get_callback = prp_get; - delete_callback = prp_delete; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, delete_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - buffP = ENVPTR->GetByteArrayElements(ENVPAR def_value, &isCopy2); - if (buffP == NULL) { - h5JNIFatalError(env, "H5Pregister2: buf not pinned"); - } /* end if */ - else { - status = H5Pregister2((hid_t)cls_id, cstr, (size_t)prp_size, (void*)buffP, (H5P_prp_create_func_t)H5P_prp_create_cb, - (H5P_prp_set_func_t)H5P_prp_set_cb, (H5P_prp_get_func_t)H5P_prp_get_cb, (H5P_prp_delete_func_t)H5P_prp_delete_cb, - (H5P_prp_copy_func_t)H5P_prp_copy_cb, (H5P_prp_compare_func_t)H5P_prp_compare_cb, (H5P_prp_close_func_t)H5P_prp_close_cb); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, 0); - } /* end else */ - } /* end else */ - UNPIN_JAVA_STRING(name, cstr); - } -} /* end Java_hdf_hdf5lib_H5_H5Pregister2 */ + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pinsert2_nocb - * Signature: (JLjava/lang/String;J[B)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb - (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, jbyteArray def_value) -{ - herr_t status = -1; - jbyte *buffP; - jboolean isCopy2; - const char *cstr; - - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - buffP = ENVPTR->GetByteArrayElements(ENVPAR def_value, &isCopy2); - if (buffP == NULL) { - h5JNIFatalError(env, "H5Pinsert2: buf not pinned"); - } /* end if */ - else { - status = H5Pinsert2((hid_t)cls_id, cstr, (size_t)prp_size, (void*)buffP, NULL, NULL, NULL, NULL, NULL, NULL); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, 0); - } /* end else */ - } /* end else */ - UNPIN_JAVA_STRING(name, cstr); - } -} /* end Java_hdf_hdf5lib_H5_H5Pinsert2 */ + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); + status = CBENVPTR->CallIntMethod(CBENVONLY, delete_callback, mid, prop_id, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pinsert2 - * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pinsert2 - (JNIEnv *env, jclass clss, jlong cls_id, jstring name, jlong prp_size, - jbyteArray def_value, jobject prp_set, jobject prp_get, jobject prp_delete, - jobject prp_copy, jobject prp_cmp, jobject prp_close) -{ - herr_t status = -1; - jbyte *buffP; - jboolean isCopy2; - const char *cstr; - copy_callback = prp_copy; - close_callback = prp_close; - compare_callback = prp_cmp; - set_callback = prp_set; - get_callback = prp_get; - delete_callback = prp_delete; +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - PIN_JAVA_STRING(name, cstr); - if (cstr != NULL) { - buffP = ENVPTR->GetByteArrayElements(ENVPAR def_value, &isCopy2); - if (buffP == NULL) { - UNPIN_JAVA_STRING(name, cstr); - h5JNIFatalError(env, "H5Pinsert2: buf not pinned"); - } /* end if */ - else { - status = H5Pinsert2((hid_t)cls_id, cstr, (size_t)prp_size, (void*)buffP, - (H5P_prp_set_func_t)H5P_prp_set_cb, (H5P_prp_get_func_t)H5P_prp_get_cb, (H5P_prp_delete_func_t)H5P_prp_delete_cb, - (H5P_prp_copy_func_t)H5P_prp_copy_cb, (H5P_prp_compare_func_t)H5P_prp_compare_cb, (H5P_prp_close_func_t)H5P_prp_close_cb); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseByteArrayElements(ENVPAR def_value, buffP, 0); - } /* end else */ - } /* end else */ - UNPIN_JAVA_STRING(name, cstr); - } -} /* end Java_hdf_hdf5lib_H5_H5Pinsert2 */ + return (herr_t)status; +} /* end H5P_prp_delete_cb */ static herr_t -H5P_iterate_cb - (hid_t prop_id, const char *name, void *cb_data) +H5P_prp_copy_cb + (const char *name, size_t size, void *value) { - JNIEnv *cbenv; - jint status = -1; - jclass cls; jmethodID mid; jstring str; - cb_wrapper *wrapper = (cb_wrapper *)cb_data; - void *op_data = (void *)wrapper->op_data; - jobject visit_callback = wrapper->visit_callback; - - /* fprintf(stderr, "\nJNI H5P_iterate_cb entered\n"); fflush(stderr); */ - if(JVMPTR->AttachCurrentThread(JVMPAR2 (void**)&cbenv, NULL) != 0) { - /* fprintf(stderr, "\nJNI H5P_iterate_cb error: AttachCurrentThread failed\n"); fflush(stderr); */ - JVMPTR->DetachCurrentThread(JVMPAR); - } /* end if */ - else { - cls = CBENVPTR->GetObjectClass(CBENVPAR visit_callback); - if (cls == 0) { - /* fprintf(stderr, "\nJNI H5P_iterate_cb error: GetObjectClass failed\n"); fflush(stderr); */ - JVMPTR->DetachCurrentThread(JVMPAR); - } /* end if */ - else { - mid = CBENVPTR->GetMethodID(CBENVPAR cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/callbacks/H5P_iterate_t;)I"); - if (mid == 0) { - /* fprintf(stderr, "\nJNI H5P_iterate_cb error: GetMethodID failed\n"); fflush(stderr); */ - JVMPTR->DetachCurrentThread(JVMPAR); - } /* end if */ - else { - str = CBENVPTR->NewStringUTF(CBENVPAR name); - - /* fprintf(stderr, "JNI H5P_iterate_cb execute\n"); fflush(stderr); */ - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, prop_id, str, op_data); - /* fprintf(stderr, "\nJNI H5P_iterate_cb status: %d\n", status); fflush(stderr); */ - } /* end else */ - } /* end else */ - } /* end else */ - - JVMPTR->DetachCurrentThread(JVMPAR); - /* fprintf(stderr, "\nJNI H5P_iterate_cb leave\n"); fflush(stderr); */ + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - return status; -} /* end H5P_iterate_cb */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_copy_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Piterate - * Signature: (J[ILjava/lang/Object;Ljava/lang/Object;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Piterate - (JNIEnv *env, jclass clss, jlong prop_id, jintArray idx, jobject callback_op, jobject op_data) -{ - herr_t status = -1; - jint *theArray = NULL; - jboolean isCopy; - cb_wrapper wrapper = {callback_op, op_data}; - - ENVPTR->GetJavaVM(ENVPAR &jvm); - - if (op_data == NULL) { - h5nullArgument(env, "H5Piterate: op_data is NULL"); - } /* end if */ - else if (callback_op == NULL) { - h5nullArgument(env, "H5Piterate: callback_op is NULL"); - } /* end else if */ - else { - if (idx == NULL) { - status = H5Piterate((hid_t)prop_id, NULL, (H5P_iterate_t)H5P_iterate_cb, (void*)&wrapper); - } /* end if */ - else { - theArray = (jint *)ENVPTR->GetIntArrayElements(ENVPAR idx, &isCopy); - if (theArray == NULL) { - h5JNIFatalError(env, "H5Piterate: idx not pinned"); - } /* end if */ - else - status = H5Piterate((hid_t)prop_id, (int*)&theArray[0], (H5P_iterate_t)H5P_iterate_cb, (void*)&wrapper); - } /* end else */ - - if (status < 0) { - if(idx) - ENVPTR->ReleaseIntArrayElements(ENVPAR idx, theArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else if (idx) - ENVPTR->ReleaseIntArrayElements(ENVPAR idx, theArray, 0); - } /* end else */ + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, copy_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jint)status; -} /* end Java_hdf_hdf5lib_H5_H5Piterate */ + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(Ljava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_metadata_read_attempts - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts - (JNIEnv *env, jclass clss, jlong plist_id) -{ - unsigned attempts; - if (H5Pget_metadata_read_attempts((hid_t)plist_id, &attempts) < 0) - h5libraryError(env); + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return (jlong) attempts; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts */ + status = CBENVPTR->CallIntMethod(CBENVONLY, copy_callback, mid, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_metadata_read_attempts - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts - (JNIEnv *env, jclass clss, jlong plist_id, jlong attempts) -{ - if (attempts <= 0) { - h5badArgument(env, "H5Pset_metadata_read_attempts: attempts <= 0"); - } /* end if */ - else { - if(H5Pset_metadata_read_attempts((hid_t)plist_id, (unsigned)attempts) < 0) - h5libraryError(env); - } /* end else */ -} /* end Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts */ +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); + return (herr_t)status; +} /* end H5P_prp_copy_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_prefix - * Signature: (JLjava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix - (JNIEnv *env, jclass clss, jlong dapl_id, jstring prefix) +static int +H5P_prp_compare_cb + (void *value1, void *value2, size_t size) { - herr_t retVal = -1; - const char *aName; - - PIN_JAVA_STRING(prefix, aName); - if (aName != NULL) { - retVal = H5Pset_virtual_prefix((hid_t)dapl_id, aName); - - UNPIN_JAVA_STRING(prefix, aName); + jmethodID mid; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - if(retVal < 0) - h5libraryError(env); + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_compare_cb: failed to attach current thread to JVM"); } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix */ - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_prefix - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix - (JNIEnv *env, jclass clss, jlong dapl_id) -{ - size_t size = 0; - char *pre; - jlong prefix_size = -1; - jstring str = NULL; - - prefix_size = (jlong)H5Pget_virtual_prefix((hid_t)dapl_id, (char*)NULL, size); - if(prefix_size < 0) { - h5libraryError(env); - } /* end if */ - else { - size = (size_t)prefix_size + 1;/* add extra space for the null terminator */ - pre = (char*)HDmalloc(sizeof(char)*size); - if (pre == NULL) { - h5outOfMemory(env, "H5Pget_virtual_prefix: malloc failed "); - } /* end if */ - else { - prefix_size = (jlong)H5Pget_virtual_prefix((hid_t)dapl_id, (char*)pre, size); - - if (prefix_size >= 0) { - str = ENVPTR->NewStringUTF(ENVPAR pre); - HDfree(pre); - if (str == NULL) - h5JNIFatalError( env, "H5Pget_virtual_prefix: return string not allocated"); - } /* end if */ - else { - HDfree(pre); - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ - - return (jstring)str; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_efile_prefix - * Signature: (JLjava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1efile_1prefix - (JNIEnv *env, jclass clss, jlong dapl_id, jstring prefix) -{ - herr_t retVal = -1; - const char *aName; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, compare_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - PIN_JAVA_STRING(prefix, aName); - if (aName != NULL) { - retVal = H5Pset_efile_prefix((hid_t)dapl_id, aName); + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "([B[BJ)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - UNPIN_JAVA_STRING(prefix, aName); + status = CBENVPTR->CallIntMethod(CBENVONLY, compare_callback, mid, value1, value2, size); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if(retVal < 0) - h5libraryError(env); - } -} /* end Java_hdf_hdf5lib_H5_H5Pset_1efile_1prefix */ +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_efile_prefix - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1efile_1prefix - (JNIEnv *env, jclass clss, jlong dapl_id) -{ - size_t size = 0; - char *pre; - jlong prefix_size = -1; - jstring str = NULL; - - prefix_size = (jlong)H5Pget_efile_prefix((hid_t)dapl_id, (char*)NULL, size); - if(prefix_size < 0) { - h5libraryError(env); - } /* end if */ - else { - size = (size_t)prefix_size + 1;/* add extra space for the null terminator */ - pre = (char*)HDmalloc(sizeof(char)*size); - if (pre == NULL) { - h5outOfMemory(env, "H5Pget_efile_prefix: malloc failed "); - } /* end if */ - else { - prefix_size = (jlong)H5Pget_efile_prefix((hid_t)dapl_id, (char*)pre, size); - - if (prefix_size >= 0) { - str = ENVPTR->NewStringUTF(ENVPAR pre); - HDfree(pre); - if (str == NULL) - h5JNIFatalError( env, "H5Pget_efile_prefix: return string not allocated"); - } /* end if */ - else { - HDfree(pre); - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ - - return (jstring)str; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1efile_1prefix */ + return (herr_t)status; +} /* end H5P_prp_compare_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_evict_on_close - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close - (JNIEnv *env, jclass clss, jlong fapl_id, jboolean evict_on_close) +static herr_t +H5P_prp_close_cb + (const char *name, size_t size, void *value) { - herr_t retVal = -1; - hbool_t evict_on_close_val; + jmethodID mid; + jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + jint status = -1; - if (evict_on_close == JNI_TRUE) - evict_on_close_val = TRUE; - else - evict_on_close_val = FALSE; + if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_prp_close_cb: failed to attach current thread to JVM"); + } - retVal = H5Pset_evict_on_close((hid_t)fapl_id, (hbool_t)evict_on_close_val); - if (retVal < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close */ + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, close_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_evict_on_close - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close - (JNIEnv *env, jclass clss, jlong fapl_id) -{ - hbool_t evict_on_close_val = FALSE; - jboolean bval = JNI_FALSE; + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(Ljava/lang/String;J[B)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (H5Pget_evict_on_close((hid_t)fapl_id, (hbool_t *)&evict_on_close_val) < 0) { - h5libraryError(env); - } /* end if */ - else { - if (evict_on_close_val == TRUE) - bval = JNI_TRUE; - } /* end else */ + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - return bval; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close */ + status = CBENVPTR->CallIntMethod(CBENVONLY, close_callback, mid, str, size, value); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk_opts - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts - (JNIEnv *env, jclass clss, jlong dcpl_id, jint opts) -{ - herr_t retVal = -1; +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - retVal = H5Pset_chunk_opts((hid_t)dcpl_id, (unsigned)opts); - if (retVal < 0) - h5libraryError(env); -} /* end Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts */ + return (herr_t)status; +} /* end H5P_prp_close_cb */ -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk_opts - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts - (JNIEnv *env, jclass clss, jlong dcpl_id) +static herr_t +H5P_iterate_cb + (hid_t prop_id, const char *name, void *cb_data) { - unsigned opts = 0; - - if (H5Pget_chunk_opts((hid_t)dcpl_id, opts) < 0) - h5libraryError(env); + cb_wrapper *wrapper = (cb_wrapper *) cb_data; + jmethodID mid; + jobject visit_callback = wrapper->visit_callback; + jstring str; + jclass cls; + JNIEnv *cbenv = NULL; + void *op_data = (void *) wrapper->op_data; + jint status = -1; - return (jint)opts; -} /* end Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts */ + if (JVMPTR->AttachCurrentThread(JVMPAR, (void**)&cbenv, NULL) < 0) { + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(CBENVONLY, "H5P_iterate_cb: failed to attach current thread to JVM"); + } -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_dset_no_attrs_hint - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1dset_1no_1attrs_1hint -(JNIEnv *env, jclass clss, jlong dcpl_id, jboolean minimize) -{ - herr_t retVal = -1; - hbool_t minimize_val; + if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, visit_callback))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (minimize == JNI_TRUE) - minimize_val = TRUE; - else - minimize_val = FALSE; + if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/callbacks/H5P_iterate_t;)I"))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - retVal = H5Pset_dset_no_attrs_hint((hid_t)dcpl_id, (hbool_t)minimize_val); - if (retVal < 0) - h5libraryError(env); -} + if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name))) + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_dset_no_attrs_hint - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1dset_1no_1attrs_1hint -(JNIEnv *env, jclass clss, jlong dcpl_id) -{ - hbool_t minimize = FALSE; - jboolean bval = JNI_FALSE; + status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, prop_id, str, op_data); + CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE); - if (H5Pget_dset_no_attrs_hint((hid_t)dcpl_id, (hbool_t *)&minimize) < 0) { - h5libraryError(env); - } - else { - if (minimize == TRUE) - bval = JNI_TRUE; - } /* end else */ +done: + if (cbenv) + JVMPTR->DetachCurrentThread(JVMPAR); - return bval; -} + return status; +} /* end H5P_iterate_cb */ #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5pImp.h b/java/src/jni/h5pImp.h index 056c569..8318be4 100644 --- a/java/src/jni/h5pImp.h +++ b/java/src/jni/h5pImp.h @@ -11,12 +11,13 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include /* Header for class hdf_hdf5lib_H5_H5_H5P */ #ifndef _Included_hdf_hdf5lib_H5_H5P #define _Included_hdf_hdf5lib_H5_H5P +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -32,15 +33,6 @@ Java_hdf_hdf5lib_H5__1H5Pcreate /* * Class: hdf_hdf5lib_H5 - * Method: H5Pclose - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5__1H5Pclose -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 * Method: H5Pget_class * Signature: (J)J */ @@ -59,1571 +51,201 @@ Java_hdf_hdf5lib_H5__1H5Pcopy /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_userblock - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1userblock -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_userblock - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1userblock -(JNIEnv *, jclass, jlong, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sizes - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sizes -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sizes - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sizes -(JNIEnv *, jclass, jlong, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sym_k - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sym_1k -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sym_k - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sym_1k -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_istore_k - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1istore_1k -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_istore_k - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1istore_1k -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_layout - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1layout -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_layout + * Method: H5Pclose * Signature: (J)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1layout +Java_hdf_hdf5lib_H5__1H5Pclose (JNIEnv *, jclass, jlong); /* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk - * Signature: (JI[B)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk -(JNIEnv *, jclass, jlong, jint, jbyteArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk - * Signature: (JI[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk -(JNIEnv *, jclass, jlong, jint, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_alignment - * Signature: (JJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1alignment -(JNIEnv *, jclass, jlong, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_alignment - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1alignment -(JNIEnv *, jclass, jlong, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_external - * Signature: (JLjava/lang/String;JJ)I + * TODO: H5Pencode */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1external -(JNIEnv *, jclass, jlong, jstring, jlong, jlong); /* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_external_count - * Signature: (J)I + * TODO: H5Pdecode */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1external_1count -(JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_external - * Signature: (JIJ[Ljava/lang/String;[J)I + * Method: _H5Pcreate_class + * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1external -(JNIEnv *, jclass, jlong, jint, jlong, jobjectArray, jlongArray); +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pcreate_1class + (JNIEnv*, jclass, jlong, jstring, jobject, jobject, jobject, jobject, jobject, jobject); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fill_value - * Signature: (JJ[B)I + * Method: _H5Pcreate_class_nocb + * Signature: (JLjava/lang/String;)J */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fill_1value -(JNIEnv *, jclass, jlong, jlong, jbyteArray); +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb + (JNIEnv*, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fill_value - * Signature: (JJ[B)I + * Method: H5Pregister2 + * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fill_1value -(JNIEnv *, jclass, jlong, jlong, jbyteArray); +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pregister2 + (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray, jobject, jobject, jobject, jobject, jobject, jobject, jobject); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_filter - * Signature: (JIIJ[I)I + * Method: H5Pregister2_nocb + * Signature: (JLjava/lang/String;J[B)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1filter -(JNIEnv *, jclass, jlong, jint, jint, jlong, jintArray); +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pregister2_1nocb + (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nfilters - * Signature: (J)I + * Method: H5Pinsert2 + * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nfilters -(JNIEnv *, jclass, jlong); +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pinsert2 + (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray, jobject, jobject, jobject, jobject, jobject, jobject); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter - * Signature: (JI[I[J[IJ[Ljava/lang/String;)I + * Method: H5Pinsert2_nocb + * Signature: (JLjava/lang/String;J[B)V */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter -(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray); +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb + (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_driver - * Signature: (J)J + * Method: H5Pset + * Signature: (JLjava/lang/String;I)J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1driver -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_cache - * Signature: (JIJJD)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1cache -(JNIEnv *, jclass, jlong, jint, jlong, jlong, jdouble); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_cache - * Signature: (J[I[J[J[D)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1cache -(JNIEnv *, jclass, jlong, jintArray, jlongArray, jlongArray, jdoubleArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_buffer - * Signature: (JJ[B[B)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1buffer -(JNIEnv *, jclass, jlong, jlong, jbyteArray, jbyteArray); +Java_hdf_hdf5lib_H5_H5Pset +(JNIEnv *, jclass, jlong, jstring, jint); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_buffer - * Signature: (J[B[B)I + * Method: H5Pexist + * Signature: (JLjava/lang/String;)Z */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1buffer -(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray); +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pexist +(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_buffer_size - * Signature: (JJ)V + * Method: H5Pget_size + * Signature: (JLjava/lang/String;)J */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1buffer_1size -(JNIEnv *, jclass, jlong, jlong); +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1size +(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_buffer_size + * Method: H5Pget_nprops * Signature: (J)J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1buffer_1size -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_preserve - * Signature: (JZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1preserve -(JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_preserve - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1preserve +Java_hdf_hdf5lib_H5_H5Pget_1nprops (JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_deflate - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1deflate -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_gc_references - * Signature: (JZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1gc_1references -(JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_gc_references - * Signature: (J)Z + * Method: H5Pget_class_name + * Signature: (J)Ljava/lang/String; */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1gc_1references +JNIEXPORT jstring JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1class_1name (JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_btree_ratios - * Signature: (JDDD)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1btree_1ratios -(JNIEnv *, jclass, jlong, jdouble, jdouble, jdouble); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_btree_ratios - * Signature: (J[D[D[D)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1btree_1ratios -(JNIEnv *, jclass, jlong, jdoubleArray, jdoubleArray, jdoubleArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_small_data_block_size - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1small_1data_1block_1size -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_small_data_block_size + * Method: H5Pget_class_parent * Signature: (J)J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1small_1data_1block_1size +Java_hdf_hdf5lib_H5_H5Pget_1class_1parent (JNIEnv *, jclass, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_alloc_time - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1alloc_1time -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_alloc_time - * Signature: (J[I)I + * Method: H5Pisa_class + * Signature: (JJ)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1alloc_1time -(JNIEnv *, jclass, jlong, jintArray); +Java_hdf_hdf5lib_H5_H5Pisa_1class +(JNIEnv *, jclass, jlong, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fill_time - * Signature: (JI)I + * Method: H5Pget + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fill_1time -(JNIEnv *, jclass, jlong, jint); +Java_hdf_hdf5lib_H5_H5Pget +(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fill_time - * Signature: (J[I)I + * Method: H5Pequal + * Signature: (JJ)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fill_1time -(JNIEnv *, jclass, jlong, jintArray); +Java_hdf_hdf5lib_H5_H5Pequal +(JNIEnv *, jclass, jlong, jlong); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pfill_value_defined - * Signature: (J[I)I + * Method: H5Piterate + * Signature: (J[ILjava/lang/Object;Ljava/lang/Object;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pfill_1value_1defined -(JNIEnv *, jclass, jlong, jintArray); +Java_hdf_hdf5lib_H5_H5Piterate + (JNIEnv*, jclass, jlong, jintArray, jobject, jobject); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fletcher32 - * Signature: (J)I + * Method: H5Pcopy_prop + * Signature: (JJLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fletcher32 -(JNIEnv *, jclass, jlong); +Java_hdf_hdf5lib_H5_H5Pcopy_1prop +(JNIEnv *, jclass, jlong, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_edc_check - * Signature: (JI)I + * Method: H5Premove + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1edc_1check -(JNIEnv *, jclass, jlong, jint); +Java_hdf_hdf5lib_H5_H5Premove +(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pget_edc_check - * Signature: (J)I + * Method: H5Punregister + * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1edc_1check -(JNIEnv *, jclass, jlong); +Java_hdf_hdf5lib_H5_H5Punregister +(JNIEnv *, jclass, jlong, jstring); /* * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shuffle + * Method: _H5Pclose_class * Signature: (J)I */ JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shuffle +Java_hdf_hdf5lib_H5__1H5Pclose_1class (JNIEnv *, jclass, jlong); -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_szip - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1szip -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_hyper_vector_size - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1hyper_1vector_1size -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_hyper_vector_size - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1hyper_1vector_1size -(JNIEnv *, jclass, jlong, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pall_filters_avail - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pall_1filters_1avail -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pmodify_filter - * Signature: (JIIJ[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pmodify_1filter -(JNIEnv *, jclass, jlong, jint, jint, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter_by_id - * Signature: (JI[I[J[IJ[Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id -(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fclose_degree - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fclose_1degree -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fclose_degree - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fclose_1degree -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_family - * Signature: (JJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1family -(JNIEnv *, jclass, jlong, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_family - * Signature: (J[J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1family -(JNIEnv *, jclass, jlong, jlongArray, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_core - * Signature: (JJZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1core -(JNIEnv *, jclass, jlong, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_core - * Signature: (J[J[Z)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1core -(JNIEnv *, jclass, jlong, jlongArray, jbooleanArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_family_offset - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1family_1offset -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_family_offset - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1family_1offset -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_log - * Signature: (JLjava/lang/String;JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log -(JNIEnv *, jclass, jlong, jstring, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Premove_filter - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5P1remove_1filter -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset - * Signature: (JLjava/lang/String;I)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pset -(JNIEnv *, jclass, jlong, jstring, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pexist - * Signature: (JLjava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pexist -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_size - * Signature: (JLjava/lang/String;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1size -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nprops - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nprops -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_class_name - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1class_1name -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_class_parent - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1class_1parent -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pisa_class - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pisa_1class -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pequal - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pequal -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pcopy_prop - * Signature: (JJLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pcopy_1prop -(JNIEnv *, jclass, jlong, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Premove - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Premove -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Punregister - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Punregister -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pclose_class - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5__1H5Pclose_1class -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter2 - * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter2 -(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_filter_by_id2 - * Signature: (JI[I[J[IJ[Ljava/lang/String;[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1filter_1by_1id2 -(JNIEnv *, jclass, jlong, jint, jintArray, jlongArray, jintArray, jlong, jobjectArray, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_nlinks - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1nlinks -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_nlinks - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1nlinks -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_libver_bounds - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1libver_1bounds -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_libver_bounds - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1libver_1bounds -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_link_creation_order - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1link_1creation_1order -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_link_creation_order - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1link_1creation_1order -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_attr_creation_order - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_attr_creation_order - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_copy_object - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1copy_1object -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_copy_object - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1copy_1object -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_create_intermediate_group - * Signature: (JZ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group -(JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_create_intermediate_group - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_data_transform - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1data_1transform -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_data_transform - * Signature: (J[Ljava/lang/String;J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1data_1transform -(JNIEnv *, jclass, jlong, jobjectArray, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_acc_flags - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_acc_flags - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_link_phase_change - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1link_1phase_1change -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_link_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1link_1phase_1change -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_attr_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_attr_phase_change - * Signature: (JII)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_phase_change - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1phase_1change -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_phase_change - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1phase_1change -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_nindexes - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1nindexes -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_nindexes - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1nindexes -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_shared_mesg_index - * Signature: (JIII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1shared_1mesg_1index -(JNIEnv *, jclass, jlong, jint, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_shared_mesg_index - * Signature: (JI[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1shared_1mesg_1index -(JNIEnv *, jclass, jlong, jint, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_local_heap_size_hint - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1local_1heap_1size_1hint -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_local_heap_size_hint - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1local_1heap_1size_1hint -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_nbit - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1nbit -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_scaleoffset - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_est_link_info - * Signature: (JII)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1est_1link_1info -(JNIEnv *, jclass, jlong, jint, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_est_link_info - * Signature: (J[I)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1est_1link_1info -(JNIEnv *, jclass, jlong, jintArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_fapl - * Signature: (JJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pget_elink_fapl - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_prefix - * Signature: (JLjava/lang/String;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_prefix - * Signature: (J[Ljava/lang/String;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix -(JNIEnv *, jclass, jlong, jobjectArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_direct - * Signature: (JJJJ)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1direct -(JNIEnv *, jclass, jlong, jlong, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_direct - * Signature: (J[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1direct -(JNIEnv *, jclass, jlong, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_sec2 - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1sec2 -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_stdio - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1stdio -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_windows - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1windows -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_fapl_muti - * Signature: (J[I[J[Ljava/lang/String;[J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1fapl_1multi -(JNIEnv *, jclass, jlong, jintArray, jlongArray, jobjectArray, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_muti - * Signature: (J[I[J[Ljava/lang/String;[JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi -(JNIEnv *, jclass, jlong, jintArray, jlongArray, jobjectArray, jlongArray, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_fapl_split - * Signature: (JLjava/lang/String;JLjava/lang/String;J)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split -(JNIEnv *, jclass, jlong, jstring, jlong, jstring, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_meta_block_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1meta_1block_1size -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_meta_block_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1meta_1block_1size -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_sieve_buf_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1sieve_1buf_1size -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_sieve_buf_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1sieve_1buf_1size -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_elink_file_cache_size - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1elink_1file_1cache_1size -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_elink_file_cache_size - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1elink_1file_1cache_1size -(JNIEnv *, jclass, jlong); - - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_mdc_config - * Signature: (J)Lhdf/hdf5lib/structs/H5AC_cache_config_t; - */ -JNIEXPORT jobject JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_mdc_config - * Signature: (JLhdf/hdf5lib/structs/H5AC_cache_config_t;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config -(JNIEnv *, jclass, jlong, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk_cache - * Signature: (JJJD)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk_1cache -(JNIEnv *, jclass, jlong, jlong, jlong, jdouble); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk_cache - * Signature: (J[J[J[D)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk_1cache -(JNIEnv *, jclass, jlong, jlongArray, jlongArray, jdoubleArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_obj_track_times - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_obj_track_times - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times -(JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_char_encoding - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_char_encoding - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual - * Signature: (JJLjava/lang/String;Ljava/lang/String;J)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual -(JNIEnv *, jclass, jlong, jlong, jstring, jstring, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_count - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1count -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_vspace - * Signature: (JJ)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1vspace -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_srcspace - * Signature: (JJ)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1srcspace -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_filename - * Signature: (JJ)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1filename -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_dsetname - * Signature: (JJ)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1dsetname -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_view - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1view -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_view - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1view -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_printf_gap - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1printf_1gap -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_printf_gap - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1printf_1gap -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy - * Signature: (J[Z[J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy -(JNIEnv *, jclass, jlong, jbooleanArray, jlongArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy_persist - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1persist -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_strategy_threshold - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1strategy_1threshold -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_file_space_strategy - * Signature: (JIZJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1strategy -(JNIEnv *, jclass, jlong, jint, jboolean, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_file_space_page_size - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1file_1space_1page_1size -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_file_space_page_size - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1file_1space_1page_1size -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_mdc_log_options - * Signature: (JZLjava/lang/String;Z)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options -(JNIEnv *, jclass, jlong, jboolean, jstring, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_mdc_log_options - * Signature: (J[Z)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1mdc_1log_1options -(JNIEnv *, jclass, jlong, jbooleanArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_append_flush - * Signature: (JI[JLjava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1append_1flush - (JNIEnv*, jclass, jlong, jint, jlongArray, jobject, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pcreate_class_nocb - * Signature: (JLjava/lang/String;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb - (JNIEnv*, jclass, jlong, jstring); -/* - * Class: hdf_hdf5lib_H5 - * Method: _H5Pcreate_class - * Signature: (JLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5__1H5Pcreate_1class - (JNIEnv*, jclass, jlong, jstring, jobject, jobject, jobject, jobject, jobject, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pregister2_nocb - * Signature: (JLjava/lang/String;J[B)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pregister2_1nocb - (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pregister2 - * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pregister2 - (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray, jobject, jobject, jobject, jobject, jobject, jobject, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pinsert2_nocb - * Signature: (JLjava/lang/String;J[B)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb - (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pinsert2 - * Signature: (JLjava/lang/String;J[BLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pinsert2 - (JNIEnv*, jclass, jlong, jstring, jlong, jbyteArray, jobject, jobject, jobject, jobject, jobject, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Piterate - * Signature: (J[ILjava/lang/Object;Ljava/lang/Object;)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Piterate - (JNIEnv*, jclass, jlong, jintArray, jobject, jobject); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_metadata_read_attempts - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1metadata_1read_1attempts -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_metadata_read_attempts - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1metadata_1read_1attempts -(JNIEnv *, jclass, jlong, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_virtual_prefix - * Signature: (JLjava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_virtual_prefix - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1virtual_1prefix -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_efile_prefix - * Signature: (JLjava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1efile_1prefix -(JNIEnv *, jclass, jlong, jstring); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_efile_prefix - * Signature: (J)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1efile_1prefix -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_evict_on_close - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1evict_1on_1close -(JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_evict_on_close - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1evict_1on_1close -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_chunk_opts - * Signature: (JI)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1chunk_1opts -(JNIEnv *, jclass, jlong, jint); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_chunk_opts - * Signature: (J)I - */ -JNIEXPORT jint JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1chunk_1opts -(JNIEnv *, jclass, jlong); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pset_dset_no_attrs_hint - * Signature: (JZ)V - */ -JNIEXPORT void JNICALL -Java_hdf_hdf5lib_H5_H5Pset_1dset_1no_1attrs_1hint - (JNIEnv *, jclass, jlong, jboolean); - -/* - * Class: hdf_hdf5lib_H5 - * Method: H5Pget_dset_no_attrs_hint - * Signature: (J)Z - */ -JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5Pget_1dset_1no_1attrs_1hint - (JNIEnv *, jclass, jlong); - - #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ diff --git a/java/src/jni/h5pLAPLImp.c b/java/src/jni/h5pLAPLImp.c new file mode 100644 index 0000000..c4502d5 --- /dev/null +++ b/java/src/jni/h5pLAPLImp.c @@ -0,0 +1,237 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pLAPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_nlinks + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1nlinks + (JNIEnv *env, jclass clss, jlong lapl_id, jlong nlinks) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if (nlinks <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_nlinks: nlinks <= 0"); + + if ((retVal = H5Pset_nlinks((hid_t)lapl_id, (size_t)nlinks)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1nlinks */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_nlinks + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1nlinks + (JNIEnv *env, jclass clss, jlong lapl_id) +{ + size_t nlinks = 0; + + UNUSED(clss); + + if (H5Pget_nlinks((hid_t)lapl_id, &nlinks) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong) nlinks; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1nlinks */ + +/* + * TODO: H5Pset_elink_cb + */ + +/* + * TODO: H5Pget_elink_cb + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_prefix + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix + (JNIEnv *env, jclass clss, jlong lapl_id, jstring prefix) +{ + const char *linkPrefix = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + PIN_JAVA_STRING(ENVONLY, prefix, linkPrefix, NULL, "H5Pset_elink_prefix: link prefix not pinned"); + + if ((retVal = H5Pset_elink_prefix((hid_t)lapl_id, linkPrefix)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (linkPrefix) + UNPIN_JAVA_STRING(ENVONLY, prefix, linkPrefix); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_prefix + * Signature: (J[Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix + (JNIEnv *env, jclass clss, jlong lapl_id, jobjectArray prefix) +{ + ssize_t prefix_size = -1; + size_t size = 0; + char *pre = NULL; + jstring str = NULL; + + UNUSED(clss); + + if (NULL == prefix) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_elink_prefix: prefix is NULL"); + + if ((prefix_size = H5Pget_elink_prefix((hid_t)lapl_id, (char *)NULL, size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (pre = (char *) HDmalloc(sizeof(char) * (size_t) prefix_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: memory allocation failed"); + + if (H5Pget_elink_prefix((hid_t)lapl_id, (char *)pre, (size_t) prefix_size + 1) < 0) + H5_LIBRARY_ERROR(ENVONLY); + pre[prefix_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, pre))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_JNI_FATAL_ERROR(ENVONLY, "H5Pget_elink_prefix: out of memory - unable to construct string from UTF characters"); + } + + ENVPTR->SetObjectArrayElement(ENVONLY, prefix, 0, str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (pre) + HDfree(pre); + + return (jlong)prefix_size; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_fapl + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl + (JNIEnv *env, jclass clss, jlong lapl_id, jlong fapl_id) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_elink_fapl((hid_t)lapl_id, (hid_t)fapl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: _H5Pget_elink_fapl + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl + (JNIEnv *env, jclass clss, jlong lapl_id) +{ + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if ((retVal = H5Pget_elink_fapl((hid_t)lapl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jlong)retVal; +} /* end Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_acc_flags + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags + (JNIEnv *env, jclass clss, jlong lapl_id, jint flags) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_elink_acc_flags((hid_t)lapl_id, (unsigned)flags)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint) retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_acc_flags + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags + (JNIEnv *env, jclass clss, jlong lapl_id) +{ + unsigned flags; + + UNUSED(clss); + + if (H5Pget_elink_acc_flags((hid_t)lapl_id, &flags) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)flags; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pLAPLImp.h b/java/src/jni/h5pLAPLImp.h new file mode 100644 index 0000000..8efcfb5 --- /dev/null +++ b/java/src/jni/h5pLAPLImp.h @@ -0,0 +1,107 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PLAPL +#define _Included_hdf_hdf5lib_H5_H5PLAPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_nlinks + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1nlinks +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_nlinks + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1nlinks +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Pset_elink_cb + */ + +/* + * TODO: H5Pget_elink_cb + */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_prefix + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix +(JNIEnv *, jclass, jlong, jstring); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_prefix + * Signature: (J[Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1prefix +(JNIEnv *, jclass, jlong, jobjectArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_fapl + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1fapl +(JNIEnv *, jclass, jlong, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: _H5Pget_elink_fapl + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL +Java_hdf_hdf5lib_H5__1H5Pget_1elink_1fapl +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_elink_acc_flags + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1elink_1acc_1flags +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_elink_acc_flags + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1elink_1acc_1flags +(JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PLAPL */ diff --git a/java/src/jni/h5pLCPLImp.c b/java/src/jni/h5pLCPLImp.c new file mode 100644 index 0000000..7c79796 --- /dev/null +++ b/java/src/jni/h5pLCPLImp.c @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pLCPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pLCPLImp.h b/java/src/jni/h5pLCPLImp.h new file mode 100644 index 0000000..009d1b4 --- /dev/null +++ b/java/src/jni/h5pLCPLImp.h @@ -0,0 +1,27 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PLCPL +#define _Included_hdf_hdf5lib_H5_H5PLCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PLCPL */ diff --git a/java/src/jni/h5pOCPLImp.c b/java/src/jni/h5pOCPLImp.c new file mode 100644 index 0000000..241842e --- /dev/null +++ b/java/src/jni/h5pOCPLImp.c @@ -0,0 +1,211 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pOCPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_create_intermediate_group + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group + (JNIEnv *env, jclass clss, jlong lcpl_id, jboolean crt_intermed_group) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_create_intermediate_group((hid_t)lcpl_id, (unsigned)crt_intermed_group)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_create_intermediate_group + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group + (JNIEnv *env, jclass clss, jlong lcpl_id) +{ + unsigned crt_intermed_group = 0; + + UNUSED(clss); + + if (H5Pget_create_intermediate_group((hid_t)lcpl_id, &crt_intermed_group) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jboolean)crt_intermed_group; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_obj_track_times + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times + (JNIEnv *env, jclass clss, jlong objplid, jboolean track_times) +{ + hbool_t track = FALSE; + + UNUSED(clss); + + track = (JNI_TRUE == track_times) ? 1 : 0; + + if (H5Pset_obj_track_times((hid_t)objplid, track) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_obj_track_times + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times + (JNIEnv *env, jclass clss, jlong objplid) +{ + hbool_t track_times = FALSE; + jboolean retVal = JNI_FALSE; + + UNUSED(clss); + + if (H5Pget_obj_track_times((hid_t)objplid, &track_times) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + retVal = (track_times == TRUE) ? JNI_TRUE : JNI_FALSE; + +done: + return retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_attr_phase_change + * Signature: (JII)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change + (JNIEnv *env, jclass clss, jlong ocpl_id, jint max_compact, jint min_dense) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_attr_phase_change((hid_t)ocpl_id, (unsigned)max_compact, (unsigned)min_dense)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_attr_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change + (JNIEnv *env, jclass clss, jlong ocpl_id, jintArray attributes) +{ + jboolean isCopy; + jint *theArray = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (NULL == attributes) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_attr_phase_change: attributes is NULL"); + + PIN_INT_ARRAY(ENVONLY, attributes, theArray, &isCopy, "H5Pget_attr_phase_change: input not pinned"); + + if ((retVal = H5Pget_attr_phase_change((hid_t)ocpl_id, (unsigned *)&(theArray[0]), (unsigned *)&(theArray[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (theArray) + UNPIN_INT_ARRAY(ENVONLY, attributes, theArray, (retVal < 0) ? JNI_ABORT : 0); + + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_attr_creation_order + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order + (JNIEnv *env, jclass clss, jlong ocpl_id, jint crt_order_flags) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_attr_creation_order((hid_t)ocpl_id, (unsigned)crt_order_flags)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_attr_creation_order + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order + (JNIEnv *env, jclass clss, jlong ocpl_id) +{ + unsigned crt_order_flags = 0; + + UNUSED(clss); + + if (H5Pget_attr_creation_order((hid_t)ocpl_id, &crt_order_flags) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)crt_order_flags; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pOCPLImp.h b/java/src/jni/h5pOCPLImp.h new file mode 100644 index 0000000..fe01f06 --- /dev/null +++ b/java/src/jni/h5pOCPLImp.h @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5POCPL +#define _Included_hdf_hdf5lib_H5_H5POCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_create_intermediate_group + * Signature: (JZ)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1create_1intermediate_1group +(JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_create_intermediate_group + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1create_1intermediate_1group +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_obj_track_times + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1obj_1track_1times +(JNIEnv *, jclass, jlong, jboolean); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_obj_track_times + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1obj_1track_1times +(JNIEnv *, jclass, jlong); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_attr_phase_change + * Signature: (JII)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1attr_1phase_1change +(JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_attr_phase_change + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1attr_1phase_1change +(JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_attr_creation_order + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1attr_1creation_1order +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_attr_creation_order + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1attr_1creation_1order +(JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5POCPL */ diff --git a/java/src/jni/h5pOCpyPLImp.c b/java/src/jni/h5pOCpyPLImp.c new file mode 100644 index 0000000..9481f91 --- /dev/null +++ b/java/src/jni/h5pOCpyPLImp.c @@ -0,0 +1,92 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pOCpyPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_copy_object + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1copy_1object + (JNIEnv *env, jclass clss, jlong ocp_plist_id, jint copy_options) +{ + herr_t retVal = FAIL; + + UNUSED(clss); + + if ((retVal = H5Pset_copy_object((hid_t)ocp_plist_id, (unsigned)copy_options)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1copy_1object */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_copy_object + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1copy_1object + (JNIEnv *env, jclass clss, jlong ocp_plist_id) +{ + unsigned copy_options = 0; + + UNUSED(clss); + + if (H5Pget_copy_object((hid_t)ocp_plist_id, ©_options) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)copy_options; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1copy_1object */ + +/* + * TODO: H5Padd_merge_committed_dtype_path + */ + +/* + * TODO: H5Pfree_merge_committed_dtype_paths + */ + +/* + * TODO: H5Pset_mcdt_search_cb + */ + +/* + * TODO: H5Pget_mcdt_search_cb + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pOCpyPLImp.h b/java/src/jni/h5pOCpyPLImp.h new file mode 100644 index 0000000..f1dca58 --- /dev/null +++ b/java/src/jni/h5pOCpyPLImp.h @@ -0,0 +1,61 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5POCpyPL +#define _Included_hdf_hdf5lib_H5_H5POCpyPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_copy_object + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1copy_1object +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_copy_object + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1copy_1object +(JNIEnv *, jclass, jlong); + +/* + * TODO: H5Padd_merge_committed_dtype_path + */ + +/* + * TODO: H5Pfree_merge_committed_dtype_paths + */ + +/* + * TODO: H5Pset_mcdt_search_cb + */ + +/* + * TODO: H5Pget_mcdt_search_cb + */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5POCpyPL */ diff --git a/java/src/jni/h5pStrCPLImp.c b/java/src/jni/h5pStrCPLImp.c new file mode 100644 index 0000000..e69847d --- /dev/null +++ b/java/src/jni/h5pStrCPLImp.c @@ -0,0 +1,74 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * For details of the HDF libraries, see the HDF Documentation at: + * http://hdfgroup.org/HDF5/doc/ + * + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "hdf5.h" +#include "h5jni.h" +#include "h5pStrCPLImp.h" + +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_char_encoding + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding + (JNIEnv *env, jclass clss, jlong acpl, jint encoding) +{ + UNUSED(clss); + + if (H5Pset_char_encoding((hid_t)acpl, (H5T_cset_t)encoding) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; +} /* end Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_char_encoding + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding + (JNIEnv *env, jclass clss, jlong acpl) +{ + H5T_cset_t encoding = H5T_CSET_ERROR; + + UNUSED(clss); + + if (H5Pget_char_encoding((hid_t)acpl, &encoding) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return encoding; +} /* end Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding */ + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ diff --git a/java/src/jni/h5pStrCPLImp.h b/java/src/jni/h5pStrCPLImp.h new file mode 100644 index 0000000..6e140d3 --- /dev/null +++ b/java/src/jni/h5pStrCPLImp.h @@ -0,0 +1,45 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef _Included_hdf_hdf5lib_H5_H5PStrCPL +#define _Included_hdf_hdf5lib_H5_H5PStrCPL + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pset_char_encoding + * Signature: (JI)V + */ +JNIEXPORT void JNICALL +Java_hdf_hdf5lib_H5_H5Pset_1char_1encoding +(JNIEnv *, jclass, jlong, jint); + +/* + * Class: hdf_hdf5lib_H5 + * Method: H5Pget_char_encoding + * Signature: (J)I + */ +JNIEXPORT jint JNICALL +Java_hdf_hdf5lib_H5_H5Pget_1char_1encoding +(JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif /* __cplusplus */ + +#endif /* _Included_hdf_hdf5lib_H5_H5PStrCPL */ diff --git a/java/src/jni/h5plImp.c b/java/src/jni/h5plImp.c index d551120..4e096f1 100644 --- a/java/src/jni/h5plImp.c +++ b/java/src/jni/h5plImp.c @@ -26,7 +26,10 @@ extern "C" { #include "h5jni.h" #include "h5plImp.h" -extern JavaVM *jvm; +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ /* * Class: hdf_hdf5lib_H5 @@ -37,9 +40,13 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLset_1loading_1state (JNIEnv *env, jclass clss, jint plugin_flags) { - if (H5PLset_loading_state((unsigned int)plugin_flags) < 0) { - h5libraryError(env); - } + UNUSED(clss); + + if (H5PLset_loading_state((unsigned int)plugin_flags) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; } /* end Java_hdf_hdf5lib_H5_H5PLset_1loading_1state */ /* @@ -52,9 +59,13 @@ Java_hdf_hdf5lib_H5_H5PLget_1loading_1state (JNIEnv *env, jclass clss) { unsigned int plugin_type = 0; - if (H5PLget_loading_state(&plugin_type) < 0) { - h5libraryError(env); - } + + UNUSED(clss); + + if (H5PLget_loading_state(&plugin_type) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)plugin_type; } /* end Java_hdf_hdf5lib_H5_H5PLget_1loading_1state */ @@ -67,18 +78,19 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLappend (JNIEnv *env, jclass clss, jobjectArray plugin_path) { - const char *aName; - herr_t retVal = -1; + const char *newPath = NULL; + herr_t retVal = FAIL; - PIN_JAVA_STRING(plugin_path, aName); - if (aName != NULL) { - retVal = H5PLappend(aName); + UNUSED(clss); - UNPIN_JAVA_STRING(plugin_path, aName); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLappend: new path not pinned"); - if (retVal < 0) - h5libraryError(env); - } + if ((retVal = H5PLappend(newPath)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (newPath) + UNPIN_JAVA_STRING(ENVONLY, plugin_path, newPath); } /* end Java_hdf_hdf5lib_H5_H5PLappend */ /* * Class: hdf_hdf5lib_H5 @@ -89,18 +101,19 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLprepend (JNIEnv *env, jclass clss, jobjectArray plugin_path) { - const char *aName; - herr_t retVal = -1; + const char *newPath = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); - PIN_JAVA_STRING(plugin_path, aName); - if (aName != NULL) { - retVal = H5PLprepend(aName); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLprepend: new path not pinned"); - UNPIN_JAVA_STRING(plugin_path, aName); + if ((retVal = H5PLprepend(newPath)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retVal < 0) - h5libraryError(env); - } +done: + if (newPath) + UNPIN_JAVA_STRING(ENVONLY, plugin_path, newPath); } /* end Java_hdf_hdf5lib_H5_H5PLprepend */ /* @@ -112,18 +125,22 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLreplace (JNIEnv *env, jclass clss, jobjectArray plugin_path, jint index) { - const char *aName; - herr_t retVal = -1; + const char *newPath = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); - PIN_JAVA_STRING(plugin_path, aName); - if (aName != NULL) { - retVal = H5PLreplace(aName, index); + if (index < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLreplace: index < 0"); - UNPIN_JAVA_STRING(plugin_path, aName); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLreplace: new path not pinned"); - if (retVal < 0) - h5libraryError(env); - } + if ((retVal = H5PLreplace(newPath, (unsigned) index)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (newPath) + UNPIN_JAVA_STRING(ENVONLY, plugin_path, newPath); } /* end Java_hdf_hdf5lib_H5_H5PLreplace */ /* @@ -135,18 +152,22 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLinsert (JNIEnv *env, jclass clss, jobjectArray plugin_path, jint index) { - const char *aName; - herr_t retVal = -1; + const char *newPath = NULL; + herr_t retVal = FAIL; + + UNUSED(clss); + + if (index < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLinsert: index < 0"); - PIN_JAVA_STRING(plugin_path, aName); - if (aName != NULL) { - retVal = H5PLinsert(aName, index); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLinsert: new path not pinned"); - UNPIN_JAVA_STRING(plugin_path, aName); + if ((retVal = H5PLinsert(newPath, (unsigned) index)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retVal < 0) - h5libraryError(env); - } +done: + if (newPath) + UNPIN_JAVA_STRING(ENVONLY, plugin_path, newPath); } /* end Java_hdf_hdf5lib_H5_H5PLinsert */ /* @@ -158,8 +179,16 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5PLremove (JNIEnv *env, jclass clss, jint index) { - if (H5PLremove(index) < 0) - h5libraryError(env); + UNUSED(clss); + + if (index < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLremove: index < 0"); + + if (H5PLremove((unsigned) index) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; } /* end Java_hdf_hdf5lib_H5_H5PLremove */ /* @@ -171,33 +200,33 @@ JNIEXPORT jstring JNICALL Java_hdf_hdf5lib_H5_H5PLget (JNIEnv *env, jclass clss, jint index) { - char *aName; jstring str = NULL; ssize_t buf_size; + char *aName = NULL; + + UNUSED(clss); + + if (index < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLget: index < 0"); + + /* Get the length of the name */ + if ((buf_size = H5PLget((unsigned) index, NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5PLget: failed to allocate plugin name buffer"); + + if ((H5PLget((unsigned) index, aName, (size_t)buf_size + 1)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + aName[buf_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (aName) + HDfree(aName); - /* get the length of the name */ - buf_size = H5PLget(index, NULL, 0); - - if (buf_size <= 0) { - h5badArgument(env, "H5PLget: buf_size <= 0"); - } /* end if */ - else { - buf_size++; /* add extra space for the null terminator */ - aName = (char*)HDmalloc(sizeof(char) * (size_t)buf_size); - if (aName == NULL) { - h5outOfMemory(env, "H5PLget: malloc failed"); - } /* end if */ - else { - buf_size = H5PLget(index, aName, (size_t)buf_size); - if (buf_size < 0) { - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR aName); - } - HDfree(aName); - } - } return str; } /* end Java_hdf_hdf5lib_H5_H5PLget */ @@ -211,9 +240,13 @@ Java_hdf_hdf5lib_H5_H5PLsize (JNIEnv *env, jclass clss) { unsigned int listsize = 0; - if (H5PLsize(&listsize) < 0) { - h5libraryError(env); - } + + UNUSED(clss); + + if (H5PLsize(&listsize) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)listsize; } /* end Java_hdf_hdf5lib_H5_H5PLsize */ diff --git a/java/src/jni/h5rImp.c b/java/src/jni/h5rImp.c index 5f2b86d..9278113 100644 --- a/java/src/jni/h5rImp.c +++ b/java/src/jni/h5rImp.c @@ -26,8 +26,10 @@ extern "C" { #include "h5jni.h" #include "h5rImp.h" -extern JavaVM *jvm; - +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ /* * Class: hdf_hdf5lib_H5 @@ -38,47 +40,42 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Rcreate (JNIEnv *env, jclass clss, jbyteArray ref, jlong loc_id, jstring name, jint ref_type, jlong space_id) { - const char *rName; - herr_t status = -1; - jbyte *refP; - jboolean isCopy2; - - PIN_JAVA_STRING(name, rName); - if (rName != NULL) { - if (ref == NULL) { - h5nullArgument( env, "H5Rcreate: ref is NULL"); - } /* end if */ - else { - if ((ref_type == H5R_OBJECT) && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_OBJ_REF_BUF_SIZE) { - h5badArgument( env, "H5Rcreate: ref input array != H5R_OBJ_REF_BUF_SIZE"); - } /* end if */ - else if ((ref_type == H5R_DATASET_REGION) && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_DSET_REG_REF_BUF_SIZE) { - h5badArgument( env, "H5Rcreate: region ref input array != H5R_DSET_REG_REF_BUF_SIZE"); - } /* end else if */ - else if ((ref_type != H5R_OBJECT) && (ref_type != H5R_DATASET_REGION)) { - h5badArgument( env, "H5Rcreate: ref_type unknown type "); - } /* end else if */ - else { - refP = (jbyte*)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy2); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rcreate: ref not pinned"); - } /* end if */ - else { - status = H5Rcreate(refP, (hid_t)loc_id, rName, (H5R_type_t)ref_type, (hid_t)space_id); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - UNPIN_JAVA_STRING(name, rName); + const char *refName = NULL; + jboolean isCopy; + jbyte *refBuf = NULL; + jsize refBufLen; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: reference is NULL"); + + if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: ref array length < 0"); } + if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: reference input array length != H5R_OBJ_REF_BUF_SIZE") + else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: unknown reference type"); + + PIN_JAVA_STRING(ENVONLY, name, refName, NULL, "H5Rcreate: reference name not pinned"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rcreate: reference buffer not pinned"); + + if ((status = H5Rcreate(refBuf, (hid_t)loc_id, refName, (H5R_type_t)ref_type, (hid_t)space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, (status < 0) ? JNI_ABORT : 0); + if (refName) + UNPIN_JAVA_STRING(ENVONLY, name, refName); + return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Rcreate */ @@ -91,33 +88,36 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Rdereference (JNIEnv *env, jclass clss, jlong dataset, jlong access_list, jint ref_type, jbyteArray ref) { - jboolean isCopy; - jbyte *refP; - hid_t retVal = -1; - - if (ref == NULL) { - h5nullArgument( env, "H5Rdereference: ref is NULL"); - } /* end if */ - else if ((ref_type == H5R_OBJECT) && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_OBJ_REF_BUF_SIZE) { - h5badArgument( env, "H5Rdereference: obj ref input array != H5R_OBJ_REF_BUF_SIZE"); - } /* end else if */ - else if ((ref_type == H5R_DATASET_REGION) && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_DSET_REG_REF_BUF_SIZE) { - h5badArgument( env, "H5Rdereference: region ref input array != H5R_DSET_REG_REF_BUF_SIZE"); - } /* end else if */ - else { - refP = (jbyte*)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rderefernce: ref not pinned"); - } /* end if */ - else { - retVal = H5Rdereference2((hid_t)dataset, (hid_t)access_list, (H5R_type_t)ref_type, refP); - - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - - if (retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + jboolean isCopy; + jbyte *refBuf = NULL; + jsize refBufLen; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: reference buffer is NULL"); + + if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: ref array length < 0"); + } + + if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: reference input array length != H5R_OBJ_REF_BUF_SIZE") + else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rdereference: unknown reference type"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rderefernce: reference buffer not pinned"); + + if ((retVal = H5Rdereference2((hid_t)dataset, (hid_t)access_list, (H5R_type_t)ref_type, refBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, (retVal < 0) ? JNI_ABORT : 0); return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Rdereference */ @@ -131,33 +131,34 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Rget_1region (JNIEnv *env, jclass clss, jlong dataset, jint ref_type, jbyteArray ref) { - hid_t retVal = -1; - jboolean isCopy; - jbyte *refP; - - if (ref_type != H5R_DATASET_REGION) { - h5badArgument( env, "H5Rget_region: bad ref_type "); - } /* end if */ - else if (ref == NULL) { - h5nullArgument( env, "H5Rget_region: ref is NULL"); - } /* end if */ - else if ( ENVPTR->GetArrayLength(ENVPAR ref) != H5R_DSET_REG_REF_BUF_SIZE) { - h5badArgument( env, "H5Rget_region: region ref input array != H5R_DSET_REG_REF_BUF_SIZE"); - } /* end if */ - else { - refP = (jbyte*)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rget_region: ref not pinned"); - } /* end if */ - else { - retVal = H5Rget_region((hid_t)dataset, (H5R_type_t)ref_type, refP); - - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - - if (retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + jboolean isCopy; + jbyte *refBuf = NULL; + jsize refBufLen; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if (H5R_DATASET_REGION != ref_type) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_region: bad reference type"); + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_region: reference buffer is NULL"); + + if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_region: ref array length < 0"); + } + + if (refBufLen != H5R_DSET_REG_REF_BUF_SIZE) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_region: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_region: reference buffer not pinned"); + + if ((retVal = H5Rget_region((hid_t)dataset, (H5R_type_t)ref_type, refBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, (retVal < 0) ? JNI_ABORT : 0); return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Rget_1region */ @@ -171,31 +172,27 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Rget_1obj_1type (JNIEnv *env, jclass clss, jlong loc_id, jint ref_type, jbyteArray ref) { - int retVal =-1; - jboolean isCopy; - jbyte *refP; - H5O_type_t object_info; - - - if (ref == NULL) { - h5nullArgument( env, "H5Rget_object_type: ref is NULL"); - } /* end if */ - else { - refP = (jbyte*)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rget_object_type: ref not pinned"); - } /* end if */ - else { - retVal = H5Rget_obj_type2((hid_t)loc_id, (H5R_type_t)ref_type, refP, &object_info); - if(retVal >= 0) - retVal = object_info; - - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - - if (retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + H5O_type_t object_info; + jboolean isCopy; + jbyte *refBuf = NULL; + int retVal = -1; + + UNUSED(clss); + + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_obj_type: reference buffer is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_obj_type: reference buffer not pinned"); + + if ((retVal = H5Rget_obj_type2((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, &object_info)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (retVal >= 0) + retVal = object_info; + +done: + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, (retVal < 0) ? JNI_ABORT : 0); return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Rget_1obj_1type */ @@ -209,46 +206,33 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Rget_1obj_1type2 (JNIEnv *env, jclass clss, jlong loc_id, jint ref_type, jbyteArray ref, jintArray ref_obj) { + jboolean isCopy, isCopy2; + jbyte *refBuf = NULL; + jint *ref_objP = NULL; + jint status; + int retVal = -1; + + UNUSED(clss); + + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_obj_type: reference buffer is NULL"); + if (NULL == ref_obj) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_obj_type: reference object is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_obj_type: reference buffer not pinned"); - jint status; - jboolean isCopy; - jbyte *refP; - jint *ref_objP; - int retVal = -1; - - - if (ref == NULL) { - h5nullArgument( env, "H5Rget_object_type: ref is NULL"); - } /* end if */ - else if (ref_obj == NULL) { - h5nullArgument( env, "H5Rget_object_type: ref_obj is NULL"); - } /* end else if */ - else { - refP = (jbyte *)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rget_object_type: ref not pinned"); - } /* end if */ - else { - ref_objP = (jint *)ENVPTR->GetIntArrayElements(ENVPAR ref_obj, &isCopy); - if (ref_objP == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR ref,refP,0); - h5JNIFatalError(env, "H5Rget_object_type: ref_obj not pinned"); - } /* end if */ - else { - status = H5Rget_obj_type2((hid_t)loc_id, (H5R_type_t)ref_type, refP, (H5O_type_t*)ref_objP); - retVal = ref_objP[0]; - - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR ref_obj,ref_objP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - ENVPTR->ReleaseIntArrayElements(ENVPAR ref_obj, ref_objP, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + PIN_INT_ARRAY(ENVONLY, ref_obj, ref_objP, &isCopy2, "H5Rget_obj_type: reference object array not pinned"); + + if ((status = H5Rget_obj_type2((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, (H5O_type_t *)ref_objP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + retVal = ref_objP[0]; + +done: + if (ref_objP) + UNPIN_INT_ARRAY(ENVONLY, ref_obj, ref_objP, (status < 0) ? JNI_ABORT : 0); + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, JNI_ABORT); return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Rget_1obj_1type2 */ @@ -262,57 +246,52 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Rget_1name (JNIEnv *env, jclass clss, jlong loc_id, jint ref_type, jbyteArray ref, jobjectArray name, jlong size) { - jlong ret_val = -1; - jbyte *refP; - jboolean isCopy; - char *aName = NULL; - jstring str; - size_t bs; - - bs = (size_t)size; - if (bs <= 0) { - h5badArgument(env, "H5Rget_name: size <= 0"); - } /* end if */ - else if (ref == NULL) { - h5nullArgument(env, "H5Rget_name: ref is NULL"); - } /* end else if */ - else { - if ((ref_type == H5R_OBJECT) && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_OBJ_REF_BUF_SIZE) { - h5badArgument(env, "H5Rget_name: obj ref input array != H5R_OBJ_REF_BUF_SIZE"); - } /* end if */ - else if ((ref_type == H5R_DATASET_REGION) - && ENVPTR->GetArrayLength(ENVPAR ref) != H5R_DSET_REG_REF_BUF_SIZE) { - h5badArgument(env, "H5Rget_name: region ref input array != H5R_DSET_REG_REF_BUF_SIZE"); - } /* end else if */ - else { - refP = (jbyte *)ENVPTR->GetByteArrayElements(ENVPAR ref, &isCopy); - if (refP == NULL) { - h5JNIFatalError(env, "H5Rget_name: ref not pinned"); - } /* end if */ - else { - aName = (char*)HDmalloc(sizeof(char)*bs); - if (aName == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - h5outOfMemory(env, "H5Rget_name: malloc failed"); - } /* end if */ - else { - ret_val = (jlong)H5Rget_name((hid_t)loc_id, (H5R_type_t)ref_type, refP, aName, bs) ; - - ENVPTR->ReleaseByteArrayElements(ENVPAR ref, refP, JNI_ABORT); - if (ret_val < 0) { - HDfree(aName); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR aName); - ENVPTR->SetObjectArrayElement(ENVPAR name, 0, str); - - HDfree(aName); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + jstring str; + jsize refBufLen; + jbyte *refBuf = NULL; + char *aName = NULL; + jlong ret_val = -1; + + UNUSED(clss); + + if (size <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: size <= 0"); + if (NULL == ref) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference buffer is NULL"); + + if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: ref array length < 0"); + } + + if ((H5R_OBJECT == ref_type) && (refBufLen != H5R_OBJ_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: reference input array length != H5R_OBJ_REF_BUF_SIZE") + else if ((H5R_DATASET_REGION == ref_type) && (refBufLen != H5R_DSET_REG_REF_BUF_SIZE)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: region reference input array length != H5R_DSET_REG_REF_BUF_SIZE") + else if ((H5R_OBJECT != ref_type) && (H5R_DATASET_REGION != ref_type)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Rget_name: unknown reference type"); + + PIN_BYTE_ARRAY(ENVONLY, ref, refBuf, &isCopy, "H5Rget_name: reference buffer not pinned"); + + if (NULL == (aName = (char *) HDmalloc(sizeof(char) * (size_t)size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Rget_name: failed to allocate referenced object name buffer"); + + if ((ret_val = (jlong)H5Rget_name((hid_t)loc_id, (H5R_type_t)ref_type, refBuf, aName, (size_t)size + 1)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + aName[(size_t)size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, aName))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, name, (jsize) 0, str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (aName) + HDfree(aName); + if (refBuf) + UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, JNI_ABORT); return ret_val; } /* end Java_hdf_hdf5lib_H5_H5Rget_1name */ diff --git a/java/src/jni/h5sImp.c b/java/src/jni/h5sImp.c index 65cdd7b..67ea59d 100644 --- a/java/src/jni/h5sImp.c +++ b/java/src/jni/h5sImp.c @@ -26,7 +26,10 @@ extern "C" { #include "h5jni.h" #include "h5sImp.h" -extern JavaVM *jvm; +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ /* * Class: hdf_hdf5lib_H5 @@ -37,12 +40,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Screate (JNIEnv *env, jclass clss, jint type) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Screate((H5S_class_t) type); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Screate((H5S_class_t) type)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Screate */ @@ -55,98 +60,83 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Screate_1simple (JNIEnv *env, jclass clss, jint rank, jlongArray dims, jlongArray maxdims) { - hid_t retVal = -1; - jlong *dimsP, *maxdimsP; - jboolean isCopy; - hsize_t *sa = NULL; - hsize_t *msa = NULL; - int i; - int drank, mrank; - hsize_t *lp; - jlong *jlp; - - if (rank < 0) { - h5badArgument(env, "H5Screate_simple: rank is invalid"); - } /* end if */ - else if (dims == NULL) { - h5nullArgument(env, "H5Screate_simple: dims is NULL"); - } /* end else if */ + jboolean isCopy; + hsize_t *sa = NULL; + hsize_t *msa = NULL; + hsize_t *lp = NULL; + jlong *dimsP = NULL, *maxdimsP = NULL; + jlong *jlp = NULL; + jsize drank, mrank; + int i; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if (rank < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: rank is invalid"); + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: dims is NULL"); + + if ((drank = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: dims array length < 0"); + } + + if (drank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: dims rank is invalid"); + + if (NULL != maxdims) { + if ((mrank = ENVPTR->GetArrayLength(ENVONLY, maxdims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: maxdims array length < 0"); + } + + if (mrank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Screate_simple: maxdims rank is invalid"); + } + + PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Screate_simple: dims not pinned"); + + if (NULL == (sa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Screate_simple: failed to allocate dims buffer") + + jlp = (jlong *) dimsP; + for (i = 0; i < rank; i++) { + *lp = (hsize_t) *jlp; + lp++; + jlp++; + } /* end for */ + + if (NULL == maxdims) { + maxdimsP = NULL; + msa = (hsize_t *)maxdimsP; + } else { - drank = (int)ENVPTR->GetArrayLength(ENVPAR dims); - if (drank != rank) { - h5badArgument(env, "H5Screate_simple: dims rank is invalid"); - return -1; - } /* end if */ - if (maxdims != NULL) { - mrank = (int)ENVPTR->GetArrayLength(ENVPAR maxdims); - if (mrank != rank) { - h5badArgument(env, "H5Screate_simple: maxdims rank is invalid"); - return -1; - } /* end if */ - } /* end if */ - dimsP = ENVPTR->GetLongArrayElements(ENVPAR dims, &isCopy); - if (dimsP == NULL) { - h5JNIFatalError(env, "H5Screate_simple: dims not pinned"); - return -1; - } /* end if */ + PIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, &isCopy, "H5Screate_simple: maxdims not pinned"); - sa = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (sa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Screate_simple: dims not converted to hsize_t"); - return -1; - } /* end if */ + if (NULL == (msa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Screate_simple: failed to allocate maxdims buffer") - jlp = (jlong *) dimsP; - for (i = 0; i < rank; i++) { + jlp = (jlong *) maxdimsP; + for (i = 0; i < mrank; i++) { *lp = (hsize_t) *jlp; lp++; jlp++; } /* end for */ + } - if (maxdims == NULL) { - maxdimsP = NULL; - msa = (hsize_t *)maxdimsP; - } /* end if */ - else { - maxdimsP = ENVPTR->GetLongArrayElements(ENVPAR maxdims, &isCopy); - if (maxdimsP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - h5JNIFatalError(env, "H5Screate_simple: maxdims not pinned"); - return -1; - } /* end if */ - msa = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (msa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - HDfree(sa); - h5JNIFatalError(env, "H5Screate_simple: dims not converted to hsize_t"); - return -1; - } /* end if */ - jlp = (jlong *)maxdimsP; - for (i = 0; i < mrank; i++) { - *lp = (hsize_t)*jlp; - lp++; - jlp++; - } /* end for */ - } /* end else */ - - retVal = H5Screate_simple(rank, (const hsize_t *)sa, (const hsize_t *)msa); - - if (maxdimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - if (msa) - HDfree(msa); - } /* end if */ + if ((retVal = H5Screate_simple(rank, (const hsize_t *)sa, (const hsize_t *)msa)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - if (sa) - HDfree(sa); - - if (retVal < 0) - h5libraryError(env); - } /* end else */ +done: + if (msa) + HDfree(msa); + if (maxdimsP) + UNPIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, JNI_ABORT); + if (sa) + HDfree(sa); + if (dimsP) + UNPIN_LONG_ARRAY(ENVONLY, dims, dimsP, JNI_ABORT); return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Screate_1simple */ @@ -160,12 +150,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Scopy (JNIEnv *env, jclass clss, jlong space_id) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Scopy(space_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Scopy(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Scopy */ @@ -185,41 +177,37 @@ Java_hdf_hdf5lib_H5__1H5Scopy */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sselect_1elements - (JNIEnv *env, jclass clss, jlong space_id, jint op, jint num_elemn, jlongArray coord) + (JNIEnv *env, jclass clss, jlong space_id, jint op, jint num_elemn, jlongArray coords) { - herr_t status = -1; - jint i; - jlong *P; - jboolean isCopy; - hssize_t *sa; - int rank; - - if (coord == NULL) { - h5nullArgument( env, "H5Sselect_elements: coord is NULL"); - return -1; - } /* end if */ + jboolean isCopy; + hssize_t *sa = NULL; + jlong *P = NULL; + jint i; + int rank; + herr_t status = FAIL; - P = ENVPTR->GetLongArrayElements(ENVPAR env,coord,&isCopy); - if (P == NULL) { - h5JNIFatalError(env, "H5Sselect_elements: coord not pinned"); - return -1; - } /* end if */ - sa = (hssize_t *)HDmalloc( (size_t)num_elems * 2 * sizeof(hssize_t)); - if (sa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR env,coord,P,JNI_ABORT); - h5JNIFatalError(env, "H5Sselect_elements: coord array not converted to hssize_t"); - return -1; - } /* end if */ - for (i= 0; i < (num_elsms * 2); i++) { + UNUSED(clss); + + if (NULL == coords) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coords is NULL"); + + PIN_LONG_ARRAY(ENVONLY, coords, P, &isCopy, "H5Sselect_elements: coords not pinned"); + + if (NULL == (sa = (hssize_t *) HDmalloc( (size_t)num_elemn * 2 * sizeof(hssize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); + + for (i = 0; i < (num_elemn * 2); i++) { sa[i] = P[i]; } /* end for */ - status = H5Sselect_elements (space_id, (H5S_seloper_t)op, num_elemn, (const hssize_t **)&sa); - ENVPTR->ReleaseLongArrayElements(ENVPAR env, coord, P, JNI_ABORT); - HDfree(sa); + if ((status = H5Sselect_elements(space_id, (H5S_seloper_t)op, num_elemn, (const hssize_t **)&sa)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (status < 0) - h5libraryError(env); +done: + if (sa) + HDfree(sa); + if (P) + UNPIN_LONG_ARRAY(ENVONLY, coords, P, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1elements */ @@ -232,49 +220,51 @@ Java_hdf_hdf5lib_H5_H5Sselect_1elements */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sselect_1elements - (JNIEnv *env, jclass clss, jlong space_id, jint op, jint num_elemn, jbyteArray coord) + (JNIEnv *env, jclass clss, jlong space_id, jint op, jint num_elemn, jbyteArray coords) { - int ii; - hsize_t *lp = NULL; - hsize_t *llp; - jlong *jlp; - herr_t status = -1; - jbyte *P; - jboolean isCopy; - jsize size; - int nlongs; - - if (coord == NULL) { - h5nullArgument(env, "H5Sselect_elements: coord is NULL"); - } /* end if */ - else { - P = ENVPTR->GetByteArrayElements(ENVPAR coord, &isCopy); - if (P == NULL) { - h5JNIFatalError(env, "H5Sselect_elements: coord not pinned"); - } /* end if */ - else { - size = (int)ENVPTR->GetArrayLength(ENVPAR coord); - nlongs = (int)((size_t)size / sizeof(jlong)); - lp = (hsize_t *)HDmalloc((size_t)nlongs * sizeof(hsize_t)); - jlp = (jlong *) P; - llp = lp; - for (ii = 0; ii < nlongs; ii++) { - *lp = (hsize_t) *jlp; - lp++; - jlp++; - } /* end for */ - - status = H5Sselect_elements(space_id, (H5S_seloper_t)op, (size_t)num_elemn, (const hsize_t *)llp); - - ENVPTR->ReleaseByteArrayElements(ENVPAR coord, P, JNI_ABORT); - - if (llp) - HDfree(llp); - - if (status < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *lp = NULL; + hsize_t *llp = NULL; + jlong *jlp = NULL; + jbyte *P = NULL; + jsize size; + int ii; + int nlongs; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == coords) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coords is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, coords, P, &isCopy, "H5Sselect_elements: coords not pinned"); + + if ((size = ENVPTR->GetArrayLength(ENVONLY, coords)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coords array length < 0"); + } + + nlongs = (int)((size_t)size / sizeof(jlong)); + + if (NULL == (lp = (hsize_t *) HDmalloc((size_t)nlongs * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); + + jlp = (jlong *) P; + llp = lp; + for (ii = 0; ii < nlongs; ii++) { + *lp = (hsize_t) *jlp; + lp++; + jlp++; + } /* end for */ + + if ((status = H5Sselect_elements(space_id, (H5S_seloper_t)op, (size_t)num_elemn, (const hsize_t *)llp)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (llp) + HDfree(llp); + if (P) + UNPIN_BYTE_ARRAY(ENVONLY, coords, P, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1elements */ @@ -288,12 +278,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sselect_1all (JNIEnv *env, jclass clss, jlong space_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Sselect_all(space_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Sselect_all(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1all */ @@ -306,12 +298,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sselect_1none (JNIEnv *env, jclass clss, jlong space_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Sselect_none(space_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Sselect_none(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1none */ @@ -326,12 +320,14 @@ Java_hdf_hdf5lib_H5_H5Sselect_1valid { htri_t bval = JNI_FALSE; - bval = H5Sselect_valid(space_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + if ((bval = H5Sselect_valid(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1valid */ @@ -344,11 +340,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1npoints (JNIEnv *env, jclass clss, jlong space_id) { - hssize_t retVal = H5Sget_simple_extent_npoints(space_id); + hssize_t retVal = -1; + + UNUSED(clss); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Sget_simple_extent_npoints(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1npoints */ @@ -361,11 +360,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Sget_1select_1npoints (JNIEnv *env, jclass clss, jlong space_id) { - hssize_t retVal = H5Sget_select_npoints(space_id); + hssize_t retVal = -1; + + UNUSED(clss); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Sget_select_npoints(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1npoints */ @@ -380,10 +382,12 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1type { int retVal = -1; - retVal = H5Sget_select_type(space_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if (H5S_SEL_ERROR == (retVal = H5Sget_select_type(space_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1type */ @@ -398,10 +402,12 @@ Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1ndims { int retVal = -1; - retVal = H5Sget_simple_extent_ndims(space_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + + if ((retVal = H5Sget_simple_extent_ndims(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint) retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1ndims */ @@ -414,100 +420,78 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1dims (JNIEnv *env, jclass clss, jlong space_id, jlongArray dims, jlongArray maxdims) { - int status = -1; - jlong *dimsP, *maxdimsP; - jboolean isCopy; - hsize_t *sa; - hsize_t *msa; - int i; - int rank = -1; - int mrank; - - if (dims == NULL) { + jboolean isCopy; + hsize_t *sa = NULL; + hsize_t *msa = NULL; + jlong *dimsP = NULL, *maxdimsP = NULL; + int i; + int rank = -1; + int mrank; + int status = -1; + + UNUSED(clss); + + if (NULL == dims) { dimsP = NULL; sa = (hsize_t *) dimsP; - } /* end if */ + } else { - dimsP = ENVPTR->GetLongArrayElements(ENVPAR dims, &isCopy); - if (dimsP == NULL) { - h5JNIFatalError(env, "H5Pget_simple_extent_dims: dims not pinned"); - return -1; - } /* end if */ - rank = (int)ENVPTR->GetArrayLength(ENVPAR dims); - sa = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (sa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_simple_extent_dims: dims not converted to hsize_t"); - return -1; - } /* end if */ - } /* end else */ - if (maxdims == NULL) { + PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Sget_simple_extent_dims: dims not pinned"); + + if ((rank = (int)ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_simple_extent_dims: dims array length < 0"); + } + + if (NULL == (sa = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate dimension buffer"); + } + + if (NULL == maxdims) { maxdimsP = NULL; msa = (hsize_t *) maxdimsP; - } /* end if */ + } else { - maxdimsP = ENVPTR->GetLongArrayElements(ENVPAR maxdims, &isCopy); - if (maxdimsP == NULL) { - if (dimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - } /* end if */ - h5JNIFatalError(env, "H5Pget_simple_extent_dims: maxdims not pinned"); - return -1; - } /* end if */ - mrank = (int) ENVPTR->GetArrayLength(ENVPAR maxdims); + PIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, &isCopy, "H5Sget_simple_extent_dims: maxdims not pinned"); + + if ((mrank = (int) ENVPTR->GetArrayLength(ENVONLY, maxdims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_simple_extent_dims: maxdims array length < 0"); + } + if (rank < 0) rank = mrank; - else if (mrank != rank) { - if (dimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - } /* end if */ - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_simple_extent_dims: maxdims rank not same as dims"); - return -1; - } /* end else if */ - msa = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (msa == NULL) { - if (dimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - } /* end if */ - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_simple_extent_dims: maxdims not converted to hsize_t"); - return -1; - } /* end if */ - } /* end else */ + else if (mrank != rank) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: maxdims rank not same as dims"); - status = H5Sget_simple_extent_dims(space_id, (hsize_t *)sa, (hsize_t *)msa); + if (NULL == (msa = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_simple_extent_dims: failed to allocate maximum dimension buffer"); + } - if (status < 0) { - if (dimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - } /* end if */ - if (maxdimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - HDfree(msa); - } /* end if */ - h5libraryError(env); - return -1; - } /* end if */ + if ((status = H5Sget_simple_extent_dims(space_id, (hsize_t *)sa, (hsize_t *)msa)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (dimsP != NULL) { + if (NULL != dimsP) { for (i = 0; i < rank; i++) { dimsP[i] = (jlong)sa[i]; } /* end for */ - HDfree(sa); - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, 0); - } /* end if */ - if (maxdimsP != NULL) { + } + + if (NULL != maxdimsP) { for (i = 0; i < rank; i++) { maxdimsP[i] = (jlong)msa[i]; } /* end for */ + } + +done: + if (msa) HDfree(msa); - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, 0); - } /* end if */ + if (maxdimsP) + UNPIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, (status < 0) ? JNI_ABORT : 0); + if (sa) + HDfree(sa); + if (dimsP) + UNPIN_LONG_ARRAY(ENVONLY, dims, dimsP, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1dims */ @@ -523,11 +507,15 @@ Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1type { H5S_class_t retVal = H5S_NO_CLASS; + UNUSED(clss); + if (space_id < 0) - h5libraryError(env); + H5_LIBRARY_ERROR(ENVONLY); - retVal = H5Sget_simple_extent_type(space_id); + if (H5S_NO_CLASS == (retVal = H5Sget_simple_extent_type(space_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1type */ @@ -540,87 +528,81 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sset_1extent_1simple (JNIEnv *env, jclass clss, jlong space_id, jint rank, jlongArray dims, jlongArray maxdims) { - herr_t status = -1; - jlong *dimsP, *maxdimsP; - jboolean isCopy; - hsize_t *sa; - hsize_t *msa; - int i; - int drank, mrank; - hsize_t *lp; - jlong *jlp; - - if (dims == NULL) { - h5nullArgument(env, "H5Sset_simple_extent: dims is NULL"); - return -1; - } /* end if */ - drank = (int) ENVPTR->GetArrayLength(ENVPAR dims); - if (drank != rank) { - h5badArgument(env, "H5Screate_simple: dims rank is invalid"); - return -1; - } /* end if */ - if (maxdims != NULL) { - mrank = (int) ENVPTR->GetArrayLength(ENVPAR maxdims); - if (mrank != rank) { - h5badArgument(env, "H5Screate_simple: maxdims rank is invalid"); - return -1; - } /* end if */ - } /* end if */ - dimsP = ENVPTR->GetLongArrayElements(ENVPAR dims, &isCopy); - if (dimsP == NULL) { - h5JNIFatalError(env, "H5Pset_simple_extent: dims not pinned"); - return -1; - } /* end if */ - sa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)); - if (sa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Sset_simple_extent: dims not converted to hsize_t"); - return -1; - } /* end if */ + jboolean isCopy; + hsize_t *sa = NULL; + hsize_t *msa = NULL; + hsize_t *lp = NULL; + jlong *dimsP = NULL, *maxdimsP = NULL; + jlong *jlp = NULL; + jsize drank, mrank; + int i; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sset_extent_simple: dims is NULL"); + + if ((drank = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sset_extent_simple: dims array length < 0"); + } + + if (drank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sset_extent_simple: dims rank is invalid"); + + if (NULL != maxdims) { + if ((mrank = ENVPTR->GetArrayLength(ENVONLY, maxdims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sset_extent_simple: maxdims array length < 0"); + } + + if (mrank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sset_extent_simple: maxdims rank is invalid"); + } + + PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Sset_extent_simple: dims not pinned"); + + if (NULL == (sa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate dimension buffer"); + jlp = (jlong *) dimsP; for (i = 0; i < rank; i++) { *lp = (hsize_t) *jlp; lp++; jlp++; } /* end for */ - if (maxdims == NULL) { + + if (NULL == maxdims) { maxdimsP = NULL; msa = (hsize_t *) maxdimsP; - } /* end if */ + } else { - maxdimsP = ENVPTR->GetLongArrayElements(ENVPAR maxdims, &isCopy); - if (maxdimsP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5JNIFatalError(env, "H5Pset_simple_extent: maxdims not pinned"); - return -1; - } /* end if */ - msa = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (msa == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); - HDfree(sa); - h5JNIFatalError(env, "H5Sset_simple_extent: maxdims not converted to hsize_t"); - return -1; - } /* end if */ + PIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, &isCopy, "H5Sset_extent_simple: maxdims not pinned"); + + if (NULL == (msa = lp = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sset_extent_simple: failed to allocate maximum dimension buffer"); + jlp = (jlong *) maxdimsP; for (i = 0; i < rank; i++) { *lp = (hsize_t) *jlp; lp++; jlp++; } /* end for */ - } /* end else */ + } - status = H5Sset_extent_simple(space_id, rank, (hsize_t *) sa, (hsize_t *) msa); + if ((status = H5Sset_extent_simple(space_id, rank, (hsize_t *) sa, (hsize_t *) msa)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - HDfree(sa); - if (maxdimsP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR maxdims, maxdimsP, JNI_ABORT); +done: + if (msa) HDfree(msa); - } /* end if */ - - if (status < 0) - h5libraryError(env); + if (maxdimsP) + UNPIN_LONG_ARRAY(ENVONLY, maxdims, maxdimsP, JNI_ABORT); + if (sa) + HDfree(sa); + if (dimsP) + UNPIN_LONG_ARRAY(ENVONLY, dims, dimsP, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sset_1extent_1simple */ @@ -636,12 +618,14 @@ Java_hdf_hdf5lib_H5_H5Sis_1simple { htri_t bval = JNI_FALSE; - bval = H5Sis_simple(space_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Sis_simple(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Sis_1simple */ @@ -654,49 +638,50 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Soffset_1simple (JNIEnv *env, jclass clss, jlong space_id, jbyteArray offset) { - herr_t status; - jbyte *P = NULL; jboolean isCopy; - hssize_t *sa; + hssize_t *sa = NULL; + hssize_t *lp = NULL; size_t rank; - size_t i; - hssize_t *lp; - jlong *jlp; - - if (offset != NULL) { - P = ENVPTR->GetByteArrayElements(ENVPAR offset, &isCopy); - if (P == NULL) { - h5JNIFatalError(env, "H5Soffset_simple: offset not pinned"); - return -1; - } /* end if */ - i = (size_t)ENVPTR->GetArrayLength(ENVPAR offset); - rank = i / sizeof(jlong); - sa = lp = (hssize_t *)HDmalloc((size_t)rank * sizeof(hssize_t)); - if (sa == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR offset, P, JNI_ABORT); - h5JNIFatalError(env, "H5Soffset_simple: offset not converted to hssize_t"); - return -1; - } /* end if */ + jsize i; + jbyte *P = NULL; + jlong *jlp = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL != offset) { + PIN_BYTE_ARRAY(ENVONLY, offset, P, &isCopy, "H5Soffset_simple: offset not pinned"); + + if ((i = ENVPTR->GetArrayLength(ENVONLY, offset)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Soffset_simple: offset array length < 0"); + } + + rank = (size_t) i / sizeof(jlong); + + if (NULL == (sa = lp = (hssize_t *) HDmalloc((size_t)rank * sizeof(hssize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Soffset_simple: failed to allocate offset buffer"); + jlp = (jlong *) P; - for (i = 0; i < rank; i++) { + for (i = 0; (size_t) i < rank; i++) { *lp = (hssize_t) *jlp; lp++; jlp++; } /* end for */ - } /* end if */ + } else { P = NULL; sa = (hssize_t *) P; - } /* end else */ + } - status = H5Soffset_simple(space_id, sa); - if (P != NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR offset, P, JNI_ABORT); - HDfree(sa); - } /* end if */ + if ((status = H5Soffset_simple(space_id, sa)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (status < 0) - h5libraryError(env); +done: + if (sa) + HDfree(sa); + if (P) + UNPIN_BYTE_ARRAY(ENVONLY, offset, P, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Soffset_1simple */ @@ -710,12 +695,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sextent_1copy (JNIEnv *env, jclass clss, jlong space_id, jlong src_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Sextent_copy(space_id, src_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Sextent_copy(space_id, src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Sextent_1copy */ @@ -730,12 +717,14 @@ Java_hdf_hdf5lib_H5_H5Sextent_1equal { htri_t bval = JNI_FALSE; - bval = H5Sextent_equal(space_id, src_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Sextent_equal(space_id, src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Sextent_1equal */ @@ -748,12 +737,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sset_1extent_1none (JNIEnv *env, jclass clss, jlong space_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Sset_extent_none(space_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Sset_extent_none(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Sset_1extent_1none */ @@ -766,162 +757,131 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab (JNIEnv *env, jclass clss, jlong space_id, jint op, jlongArray start, jlongArray stride, jlongArray count, jlongArray block) { - herr_t status = -1; - jlong *startP, *strideP, *countP, *blockP; - jboolean isCopy; - hsize_t *strt; - hsize_t *strd; - hsize_t *cnt; - hsize_t *blk; - int rank; - int i; - hsize_t *lp; - jlong *jlp; - - if (start == NULL) { - h5nullArgument(env, "H5Sselect_hyperslab: start is NULL"); + jboolean isCopy; + hsize_t *strt = NULL, *strd = NULL, *cnt = NULL, *blk = NULL; + hsize_t *lp = NULL; + jlong *startP = NULL, *strideP = NULL, *countP = NULL, *blockP = NULL; + jlong *jlp = NULL; + jsize start_rank, stride_rank, count_rank, block_rank; + int i; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == start) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: start is NULL"); + if (NULL == count) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: count is NULL"); + + if ((start_rank = ENVPTR->GetArrayLength(ENVONLY, start)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: start array length < 0"); + } + if ((count_rank = ENVPTR->GetArrayLength(ENVONLY, count)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: count array length < 0"); + } + + if (start_rank != count_rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: count and start have different rank!"); + + PIN_LONG_ARRAY(ENVONLY, start, startP, &isCopy, "H5Sselect_hyperslab: start not pinned"); + + if (NULL == (strt = lp = (hsize_t *) HDmalloc((size_t)start_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate start buffer"); + + jlp = (jlong *) startP; + for (i = 0; i < start_rank; i++) { + *lp = (hsize_t) *jlp; + lp++; + jlp++; } /* end if */ - else if (count == NULL) { - h5nullArgument(env, "H5Sselect_hyperslab: count is NULL"); + + PIN_LONG_ARRAY(ENVONLY, count, countP, &isCopy, "H5Sselect_hyperslab: count not pinned"); + + if (NULL == (cnt = lp = (hsize_t *) HDmalloc((size_t)count_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate count buffer"); + + jlp = (jlong *) countP; + for (i = 0; i < count_rank; i++) { + *lp = (hsize_t) *jlp; + lp++; + jlp++; } /* end if */ + + if (NULL == stride) { + strideP = NULL; + strd = (hsize_t *) strideP; + } else { - rank = (int) ENVPTR->GetArrayLength(ENVPAR start); - if (rank != ENVPTR->GetArrayLength(ENVPAR count)) { - h5badArgument(env, "H5Sselect_hyperslab: count and start have different rank!"); - return -1; - } /* end if */ + if ((stride_rank = ENVPTR->GetArrayLength(ENVONLY, stride)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: stride array length < 0"); + } - startP = ENVPTR->GetLongArrayElements(ENVPAR start, &isCopy); - if (startP == NULL) { - h5JNIFatalError(env, "H5Sselect_hyperslab: start not pinned"); - return -1; - } /* end if */ - strt = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (strt == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - h5JNIFatalError(env, "H5Sselect_hyperslab: start not converted to hsize_t"); - return -1; - } /* end if */ + if (stride_rank != start_rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: stride and start have different rank!"); - jlp = (jlong *) startP; - for (i = 0; i < rank; i++) { + PIN_LONG_ARRAY(ENVONLY, stride, strideP, &isCopy, "H5Sselect_hyperslab: stride not pinned"); + + if (NULL == (strd = lp = (hsize_t *) HDmalloc((size_t)stride_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate stride buffer"); + + jlp = (jlong *) strideP; + for (i = 0; i < stride_rank; i++) { *lp = (hsize_t) *jlp; lp++; jlp++; } /* end if */ + } - countP = ENVPTR->GetLongArrayElements(ENVPAR count, &isCopy); - if (countP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(strt); - h5JNIFatalError(env, "H5Sselect_hyperslab: count not pinned"); - return -1; - } /* end if */ - cnt = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (cnt == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - HDfree(strt); - h5JNIFatalError(env, "H5Sselect_hyperslab: count not converted to hsize_t"); - return -1; - } /* end if */ + if (NULL == block) { + blockP = NULL; + blk = (hsize_t *) blockP; + } + else { + if ((block_rank = ENVPTR->GetArrayLength(ENVONLY, block)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: block array length < 0"); + } - jlp = (jlong *) countP; - for (i = 0; i < rank; i++) { + if (block_rank != start_rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_hyperslab: block and start have different rank!"); + + PIN_LONG_ARRAY(ENVONLY, block, blockP, &isCopy, "H5Sselect_hyperslab: block not pinned"); + + if (NULL == (blk = lp = (hsize_t *) HDmalloc((size_t)block_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sselect_hyperslab: failed to allocate block buffer"); + + jlp = (jlong *) blockP; + for (i = 0; i < block_rank; i++) { *lp = (hsize_t) *jlp; lp++; jlp++; - } /* end if */ - if (stride == NULL) { - strideP = NULL; - strd = (hsize_t *) strideP; - } /* end if */ - else { - strideP = ENVPTR->GetLongArrayElements(ENVPAR stride, &isCopy); - if (strideP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - h5badArgument(env, "H5Sselect_hyperslab: stride not pinned"); - return -1; - } /* end if */ - strd = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (strd == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - h5JNIFatalError(env, "H5Sselect_hyperslab: stride not converted to hsize_t"); - return -1; - } /* end if */ - jlp = (jlong *) strideP; - for (i = 0; i < rank; i++) { - *lp = (hsize_t) *jlp; - lp++; - jlp++; - } /* end if */ - } /* end if */ - if (block == NULL) { - blockP = NULL; - blk = (hsize_t *) blockP; - } /* end if */ - else { - blockP = ENVPTR->GetLongArrayElements(ENVPAR block, &isCopy); - if (blockP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - if (strd != NULL) - free(strd); - - h5JNIFatalError(env, "H5Sselect_hyperslab: block not pinned"); - return -1; - } /* end if */ - blk = lp = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (blk == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR block, blockP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - if (strd != NULL) - free(strd); - - h5JNIFatalError(env, "H5Sget_simple_extent: block not converted to hsize_t"); - return -1; - } /* end if */ - jlp = (jlong *) blockP; - for (i = 0; i < rank; i++) { - *lp = (hsize_t) *jlp; - lp++; - jlp++; - } /* end for */ - } /* end else */ - - status = H5Sselect_hyperslab(space_id, (H5S_seloper_t) op, (const hsize_t *) strt, (const hsize_t *) strd, - (const hsize_t *) cnt, (const hsize_t *) blk); - - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - HDfree(strt); + } /* end for */ + } + + if ((status = H5Sselect_hyperslab(space_id, (H5S_seloper_t) op, (const hsize_t *) strt, (const hsize_t *) strd, + (const hsize_t *) cnt, (const hsize_t *) blk)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (blk) + HDfree(blk); + if (blockP) + UNPIN_LONG_ARRAY(ENVONLY, block, blockP, JNI_ABORT); + if (strd) + HDfree(strd); + if (strideP) + UNPIN_LONG_ARRAY(ENVONLY, stride, strideP, JNI_ABORT); + if (cnt) HDfree(cnt); - if (strideP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - HDfree(strd); - } /* end if */ - if (blockP != NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR block, blockP, JNI_ABORT); - HDfree(blk); - } /* end if */ - - if (status < 0) - h5libraryError(env); - } /* end else */ + if (countP) + UNPIN_LONG_ARRAY(ENVONLY, count, countP, JNI_ABORT); + if (strt) + HDfree(strt); + if (startP) + UNPIN_LONG_ARRAY(ENVONLY, start, startP, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1hyperslab */ @@ -935,12 +895,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5__1H5Sclose (JNIEnv *env, jclass clss, jlong space_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Sclose(space_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Sclose(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Sclose */ @@ -955,10 +917,12 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1hyper_1nblocks { hssize_t retVal = -1; - retVal = H5Sget_select_hyper_nblocks((hid_t) spaceid); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + + if ((retVal = H5Sget_select_hyper_nblocks((hid_t) spaceid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1hyper_1nblocks */ @@ -973,10 +937,12 @@ Java_hdf_hdf5lib_H5_H5Sget_1select_1elem_1npoints { hssize_t retVal = -1; - retVal = H5Sget_select_elem_npoints((hid_t) spaceid); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Sget_select_elem_npoints((hid_t) spaceid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1elem_1npoints */ @@ -989,58 +955,53 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sget_1select_1hyper_1blocklist (JNIEnv *env, jclass clss, jlong spaceid, jlong startblock, jlong numblocks, jlongArray buf) { - herr_t status = -1; - jlong *bufP; - jboolean isCopy; - hsize_t *ba; - int i; - int rank; - hsize_t st; - hsize_t nb; - - st = (hsize_t) startblock; - nb = (hsize_t) numblocks; - - if (buf == NULL) { - h5nullArgument(env, "H5Sget_select_hyper_blocklist: buf is NULL"); - } /* end if */ - else { - rank = H5Sget_simple_extent_ndims(spaceid); - if (rank <= 0) - rank = 1; - if (ENVPTR->GetArrayLength(ENVPAR buf) < (numblocks * rank)) { - h5badArgument(env, "H5Sget_select_hyper_blocklist: buf input array too small"); - } /* end if */ - else { - bufP = ENVPTR->GetLongArrayElements(ENVPAR buf, &isCopy); - if (bufP == NULL) { - h5JNIFatalError(env, "H5Sget_select_hyper_blocklist: buf not pinned"); - } /* end if */ - else { - ba = (hsize_t *) HDmalloc((size_t)nb * 2 * (size_t)rank * sizeof(hsize_t)); - if (ba == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, JNI_ABORT); - h5JNIFatalError(env, "H5Screate-simple: buffer not converted to hsize_t"); - } /* end if */ - else { - status = H5Sget_select_hyper_blocklist((hid_t)spaceid, st, nb, (hsize_t *)ba); - - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, JNI_ABORT); - free(ba); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < (numblocks * 2 * rank); i++) { - bufP[i] = (jlong)ba[i]; - } /* end for */ - free(ba); - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *ba = NULL; + size_t i, buf_size; + jlong *bufP = NULL; + jsize buflen; + int rank; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: buf is NULL"); + if (numblocks < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: numblocks < 0"); + + if ((rank = H5Sget_simple_extent_ndims(spaceid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (rank == 0) + rank = 1; + + if ((buflen = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: buf array length < 0"); + } + + if (buflen < (numblocks * rank)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: buffer input array too small"); + + PIN_LONG_ARRAY(ENVONLY, buf, bufP, &isCopy, "H5Sget_select_hyper_blocklist: buffer not pinned"); + + buf_size = (size_t) numblocks * (size_t) 2 * (size_t) rank * sizeof(hsize_t); + if (NULL == (ba = (hsize_t *) HDmalloc(buf_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_hyper_blocklist: failed to allocate block list buffer"); + + if ((status = H5Sget_select_hyper_blocklist((hid_t)spaceid, (hsize_t) startblock, (hsize_t) numblocks, (hsize_t *)ba)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (buf_size / sizeof(hsize_t)); i++) { + bufP[i] = (jlong) ba[i]; + } /* end for */ + +done: + if (ba) + HDfree(ba); + if (bufP) + UNPIN_LONG_ARRAY(ENVONLY, buf, bufP, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1hyper_1blocklist */ @@ -1054,53 +1015,49 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sget_1select_1elem_1pointlist (JNIEnv *env, jclass clss, jlong spaceid, jlong startpoint, jlong numpoints, jlongArray buf) { - herr_t status = -1; - jlong *bufP; - jboolean isCopy; - hsize_t *ba; - int i; - int rank; - - if (buf == NULL) { - h5nullArgument(env, "H5Sget_select_elem_pointlist: buf is NULL"); - } /* end if */ - else { - rank = H5Sget_simple_extent_ndims(spaceid); - if (rank <= 0) - rank = 1; - if (ENVPTR->GetArrayLength(ENVPAR buf) < (numpoints * rank)) { - h5badArgument(env, "H5Sget_select_elem_pointlist: buf input array too small"); - } /* end if */ - else { - bufP = ENVPTR->GetLongArrayElements(ENVPAR buf, &isCopy); - if (bufP == NULL) { - h5JNIFatalError(env, "H5Sget_select_elem_pointlist: buf not pinned"); - } /* end if */ - else { - ba = (hsize_t *)HDmalloc(((size_t)numpoints * (size_t)rank) * sizeof(hsize_t)); - if (ba == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_select_elem_pointlist: buf not converted to hsize_t"); - } /* end if */ - else { - status = H5Sget_select_elem_pointlist((hid_t) spaceid, (hsize_t)startpoint, (hsize_t)numpoints, (hsize_t *)ba); - - if (status < 0) { - HDfree(ba); - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < (numpoints * rank); i++) { - bufP[i] = (jlong)ba[i]; - } /* end for */ - HDfree(ba); - ENVPTR->ReleaseLongArrayElements(ENVPAR buf, bufP, 0); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *ba = NULL; + jlong *bufP = NULL; + jsize buflen; + int i, rank; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: buffer is NULL"); + + if ((rank = H5Sget_simple_extent_ndims(spaceid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (rank == 0) + rank = 1; + + if ((buflen = ENVPTR->GetArrayLength(ENVONLY, buf)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: buf array length < 0"); + } + + if (buflen < (numpoints * rank)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: buffer input array too small"); + + PIN_LONG_ARRAY(ENVONLY, buf, bufP, &isCopy, "H5Sget_select_elem_pointlist: buffer not pinned"); + + if (NULL == (ba = (hsize_t *) HDmalloc(((size_t)numpoints * (size_t)rank) * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_elem_pointlist: failed to allocate point list buffer"); + + if ((status = H5Sget_select_elem_pointlist((hid_t)spaceid, (hsize_t)startpoint, (hsize_t)numpoints, (hsize_t *)ba)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (numpoints * rank); i++) { + bufP[i] = (jlong) ba[i]; + } /* end for */ + +done: + if (ba) + HDfree(ba); + if (bufP) + UNPIN_LONG_ARRAY(ENVONLY, buf, bufP, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end if */ @@ -1114,70 +1071,53 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Sget_1select_1bounds (JNIEnv *env, jclass clss, jlong spaceid, jlongArray start, jlongArray end) { - herr_t status = -1; - jlong *startP, *endP; - jboolean isCopy; - hsize_t *strt; - hsize_t *en; - int rank; - int i; - - if (start == NULL) { - h5nullArgument(env, "H5Sget_select_bounds: start is NULL"); - } /* end if */ - else if (end == NULL) { - h5nullArgument(env, "H5Sget_select_bounds: end is NULL"); - } /* end else if */ - else { - startP = ENVPTR->GetLongArrayElements(ENVPAR start, &isCopy); - if (startP == NULL) { - h5JNIFatalError(env, "H5Sget_select_bounds: start not pinned"); - return -1; - } /* end if */ - rank = (int) ENVPTR->GetArrayLength(ENVPAR start); - strt = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (strt == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_select_bounds: start not converted to hsize_t"); - return -1; - } /* end if */ + jboolean isCopy; + hsize_t *strt = NULL; + hsize_t *en = NULL; + size_t i; + jlong *startP = NULL, *endP = NULL; + jsize rank; + herr_t status = FAIL; - endP = ENVPTR->GetLongArrayElements(ENVPAR end, &isCopy); - if (endP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - free(strt); - h5JNIFatalError(env, "H5Sget_select_bounds: end not pinned"); - return -1; - } /* end if */ - en = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (en == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR end, endP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(strt); - h5JNIFatalError(env, "H5Sget_simple_extent: dims not converted to hsize_t"); - return -1; - } /* end if */ + UNUSED(clss); - status = H5Sget_select_bounds((hid_t) spaceid, (hsize_t *) strt, (hsize_t *) en); + if (NULL == start) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_bounds: start is NULL"); + if (NULL == end) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_bounds: end is NULL"); - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR end, endP, JNI_ABORT); - HDfree(strt); - HDfree(en); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < rank; i++) { - startP[i] = (jlong)strt[i]; - endP[i] = (jlong)en[i]; - } /* end for */ - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR end, endP, 0); - HDfree(strt); - HDfree(en); - } /* end else */ - } /* end else */ + PIN_LONG_ARRAY(ENVONLY, start, startP, &isCopy, "H5Sget_select_bounds: start not pinned"); + + if ((rank = ENVPTR->GetArrayLength(ENVONLY, start)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_select_bounds: start array length < 0"); + } + + if (NULL == (strt = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate start buffer"); + + PIN_LONG_ARRAY(ENVONLY, end, endP, &isCopy, "H5Sget_select_bounds: end not pinned"); + + if (NULL == (en = (hsize_t *) HDmalloc((size_t)rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_select_bounds: failed to allocate end buffer"); + + if ((status = H5Sget_select_bounds((hid_t) spaceid, (hsize_t *) strt, (hsize_t *) en)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (size_t) rank; i++) { + startP[i] = (jlong) strt[i]; + endP[i] = (jlong) en[i]; + } /* end for */ + +done: + if (en) + HDfree(en); + if (endP) + UNPIN_LONG_ARRAY(ENVONLY, end, endP, (status < 0) ? JNI_ABORT : 0); + if (strt) + HDfree(strt); + if (startP) + UNPIN_LONG_ARRAY(ENVONLY, start, startP, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sget_1select_1bounds */ @@ -1191,43 +1131,37 @@ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_H5_H5Sencode (JNIEnv *env, jclass cls, jlong obj_id) { - herr_t status = -1; - unsigned char *bufPtr; - size_t buf_size = 0; - jbyteArray returnedArray = NULL; - - if (obj_id < 0) { - h5badArgument(env, "H5Sencode: invalid argument"); - } /* end if */ - else { - status = H5Sencode(obj_id, NULL, &buf_size); + unsigned char *bufPtr = NULL; + size_t buf_size = 0; + herr_t status = FAIL; + jbyteArray returnedArray = NULL; - if (status < 0) { - h5libraryError(env); - } /* end else if */ - else if (buf_size == 0) { - h5badArgument(env, "H5Sencode: buf_size = 0"); - } /* end if */ - else { - bufPtr = (unsigned char*)HDcalloc((size_t) 1, buf_size); - if (bufPtr == NULL) { - h5outOfMemory(env, "H5Sencode: calloc failed"); - } /* end if */ - else { - status = H5Sencode((hid_t) obj_id, bufPtr, &buf_size); - - if (status < 0) { - HDfree(bufPtr); - h5libraryError(env); - } /* end if */ - else { - returnedArray = ENVPTR->NewByteArray(ENVPAR (jsize)buf_size); - ENVPTR->SetByteArrayRegion(ENVPAR returnedArray, 0, (jsize)buf_size, (jbyte*) bufPtr); - HDfree(bufPtr); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + UNUSED(cls); + + if (obj_id < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sencode: invalid object ID"); + + if ((status = H5Sencode(obj_id, NULL, &buf_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (buf_size == 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sencode: buf_size = 0"); + + if (NULL == (bufPtr = (unsigned char *) HDcalloc((size_t) 1, buf_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sencode: failed to allocate encoding buffer"); + + if ((status = H5Sencode((hid_t) obj_id, bufPtr, &buf_size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (returnedArray = ENVPTR->NewByteArray(ENVONLY, (jsize) buf_size))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetByteArrayRegion(ENVONLY, returnedArray, 0, (jsize) buf_size, (jbyte *) bufPtr); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (bufPtr) + HDfree(bufPtr); return returnedArray; } /* end Java_hdf_hdf5lib_H5_H5Sencode */ @@ -1241,27 +1175,23 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Sdecode (JNIEnv *env, jclass cls, jbyteArray buf) { - hid_t sid = -1; - jbyte *bufP; - jboolean isCopy; + jboolean isCopy; + jbyte *bufP = NULL; + hid_t sid = H5I_INVALID_HID; - if (buf == NULL) { - h5nullArgument(env, "H5Sdecode: buf is NULL"); - } /* end if */ - else { - bufP = ENVPTR->GetByteArrayElements(ENVPAR buf, &isCopy); - if (bufP == NULL) { - h5JNIFatalError( env, "H5Sdecode: buf not pinned"); - } /* end if */ - else { - sid = H5Sdecode(bufP); + UNUSED(cls); + + if (NULL == buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sdecode: buffer is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, buf, bufP, &isCopy, "H5Sdecode: buffer not pinned"); - ENVPTR->ReleaseByteArrayElements(ENVPAR buf, bufP, JNI_ABORT); + if ((sid = H5Sdecode(bufP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (sid < 0) - h5libraryError(env); - } /* end else if */ - } /* end else if */ +done: + if (bufP) + UNPIN_BYTE_ARRAY(ENVONLY, buf, bufP, JNI_ABORT); return (jlong)sid; } /* end Java_hdf_hdf5lib_H5_H5Sdecode */ @@ -1277,12 +1207,14 @@ Java_hdf_hdf5lib_H5_H5Sis_1regular_1hyperslab { htri_t bval = JNI_FALSE; - bval = H5Sis_regular_hyperslab((hid_t)obj_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(cls); + if ((bval = H5Sis_regular_hyperslab((hid_t)obj_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Sis_1regular_1hyperslab */ @@ -1295,131 +1227,126 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab (JNIEnv *env, jclass clss, jlong space_id, jlongArray start, jlongArray stride, jlongArray count, jlongArray block) { - herr_t status; - jlong *startP, *strideP, *countP, *blockP; - jboolean isCopy; - hsize_t *strt; - hsize_t *strd; - hsize_t *cnt; - hsize_t *blk; - int rank; - int i; - - if (start == NULL) { - h5nullArgument(env, "H5Sget_regular_hyperslab: start is NULL"); - } /* end if */ - else if (count == NULL) { - h5nullArgument(env, "H5Sget_regular_hyperslab: count is NULL"); - } /* end else if */ + jboolean isCopy; + hsize_t *strt = NULL, *strd = NULL, *cnt = NULL, *blk = NULL; + jlong *startP = NULL, *strideP = NULL, *countP = NULL, *blockP = NULL; + jsize start_rank = -1, stride_rank = -1, count_rank = -1, block_rank = -1; + int i, rank = -1; + herr_t status = FAIL; + + UNUSED(clss); + + if (space_id < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: invalid dataspace ID"); + + if ((rank = H5Sget_simple_extent_ndims(space_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == start) { + startP = NULL; + strt = (hsize_t *) startP; + } else { - rank = (int) ENVPTR->GetArrayLength(ENVPAR start); - if (rank != ENVPTR->GetArrayLength(ENVPAR count)) { - h5badArgument(env, "H5Sget_regular_hyperslab: count and start have different rank!"); - return; - } /* end if */ + if ((start_rank = ENVPTR->GetArrayLength(ENVONLY, start)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: start array length < 0"); + } - startP = ENVPTR->GetLongArrayElements(ENVPAR start, &isCopy); - if (startP == NULL) { - h5JNIFatalError(env, "H5Sget_regular_hyperslab: start not pinned"); - return; - } /* end if */ - strt = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (strt == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: start not converted to hsize_t"); - return; - } /* end if */ + if (start_rank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: start rank doesn't match dataspace rank!"); - countP = ENVPTR->GetLongArrayElements(ENVPAR count, &isCopy); - if (countP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(strt); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: count not pinned"); - return; - } /* end if */ - cnt = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (cnt == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - HDfree(strt); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: count not converted to hsize_t"); - return; - } /* end if */ + PIN_LONG_ARRAY(ENVONLY, start, startP, &isCopy, "H5Sget_regular_hyperslab: start not pinned"); - strideP = ENVPTR->GetLongArrayElements(ENVPAR stride, &isCopy); - if (strideP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - h5badArgument(env, "H5Sget_regular_hyperslab: stride not pinned"); - return; - } /* end if */ - strd = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (strd == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: stride not converted to hsize_t"); - return; - } /* end if */ + if (NULL == (strt = (hsize_t *) HDmalloc((size_t)start_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate start buffer"); + } - blockP = ENVPTR->GetLongArrayElements(ENVPAR block, &isCopy); - if (blockP == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - HDfree(strd); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: block not pinned"); - return; - } /* end if */ - blk = (hsize_t *)HDmalloc((size_t)rank * sizeof(hsize_t)); - if (blk == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR block, blockP, JNI_ABORT); - HDfree(cnt); - HDfree(strt); - HDfree(strd); - h5JNIFatalError(env, "H5Sget_regular_hyperslab: block not converted to hsize_t"); - return; - } /* end if */ + if (NULL == stride) { + strideP = NULL; + strd = (hsize_t *) strideP; + } + else { + if ((stride_rank = ENVPTR->GetArrayLength(ENVONLY, stride)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: stride array length < 0"); + } - status = H5Sget_regular_hyperslab(space_id, (hsize_t *) strt, (hsize_t *) strd, (hsize_t *) cnt, (hsize_t *) blk); - - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR block, blockP, JNI_ABORT); - HDfree(strt); - HDfree(cnt); - HDfree(strd); - HDfree(blk); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < (rank); i++) { - startP[i] = (jlong)strt[i]; - countP[i] = (jlong)cnt[i]; - strideP[i] = (jlong)strd[i]; - blockP[i] = (jlong)blk[i]; - } /* end for */ - HDfree(strt); - HDfree(cnt); - HDfree(strd); - HDfree(blk); - ENVPTR->ReleaseLongArrayElements(ENVPAR start, startP, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR count, countP, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR stride, strideP, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR block, blockP, 0); - } /* end else */ - } /* end else */ + if (stride_rank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: stride rank doesn't match dataspace rank!"); + + PIN_LONG_ARRAY(ENVONLY, stride, strideP, &isCopy, "H5Sget_regular_hyperslab: stride not pinned"); + + if (NULL == (strd = (hsize_t *) HDmalloc((size_t)stride_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate stride buffer"); + } + + if (NULL == count) { + countP = NULL; + cnt = (hsize_t *) countP; + } + else { + if ((count_rank = ENVPTR->GetArrayLength(ENVONLY, count)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: count array length < 0"); + } + + if (count_rank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: count rank doesn't match dataspace rank!"); + + PIN_LONG_ARRAY(ENVONLY, count, countP, &isCopy, "H5Sget_regular_hyperslab: count not pinned"); + + if (NULL == (cnt = (hsize_t *) HDmalloc((size_t)count_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate count buffer"); + } + + if (NULL == block) { + blockP = NULL; + blk = (hsize_t *) blockP; + } + else { + if ((block_rank = ENVPTR->GetArrayLength(ENVONLY, block)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: block array length < 0"); + } + + if (block_rank != rank) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_regular_hyperslab: block rank doesn't match dataspace rank!"); + + PIN_LONG_ARRAY(ENVONLY, block, blockP, &isCopy, "H5Sget_regular_hyperslab: block not pinned"); + + if (NULL == (blk = (hsize_t *) HDmalloc((size_t)block_rank * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Sget_regular_hyperslab: failed to allocate block buffer"); + } + + if ((status = H5Sget_regular_hyperslab(space_id, (hsize_t *) strt, (hsize_t *) strd, (hsize_t *) cnt, (hsize_t *) blk)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < start_rank; i++) { + startP[i] = (jlong) strt[i]; + countP[i] = (jlong) cnt[i]; + strideP[i] = (jlong) strd[i]; + blockP[i] = (jlong) blk[i]; + } /* end for */ + +done: + if (blk) + HDfree(blk); + if (blockP) + UNPIN_LONG_ARRAY(ENVONLY, block, blockP, (status < 0) ? JNI_ABORT : 0); + if (cnt) + HDfree(cnt); + if (countP) + UNPIN_LONG_ARRAY(ENVONLY, count, countP, (status < 0) ? JNI_ABORT : 0); + if (strd) + HDfree(strd); + if (strideP) + UNPIN_LONG_ARRAY(ENVONLY, stride, strideP, (status < 0) ? JNI_ABORT : 0); + if (strt) + HDfree(strt); + if (startP) + UNPIN_LONG_ARRAY(ENVONLY, start, startP, (status < 0) ? JNI_ABORT : 0); + + return; } /* end Java_hdf_hdf5lib_H5_H5Sget_1regular_1hyperslab */ #ifdef __cplusplus diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index 307f1a5..08ddf85 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -29,7 +29,10 @@ extern "C" { #include "h5jni.h" #include "h5tImp.h" -extern JavaVM *jvm; +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ +/* extern JavaVM *jvm; */ /* * Class: hdf_hdf5lib_H5 @@ -40,18 +43,19 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Topen2 (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong access_plist) { - hid_t status = -1; - const char *tName; + const char *datatypeName = NULL; + hid_t status = H5I_INVALID_HID; - PIN_JAVA_STRING(name, tName); - if (tName != NULL) { - status = H5Topen2((hid_t)loc_id, tName, (hid_t)access_plist); + UNUSED(clss); - UNPIN_JAVA_STRING(name, tName); + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Topen2: datatype name not pinned"); - if (status < 0) - h5libraryError(env); - } + if ((status = H5Topen2((hid_t)loc_id, datatypeName, (hid_t)access_plist)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (datatypeName) + UNPIN_JAVA_STRING(ENVONLY, name, datatypeName); return (jlong)status; } /* end Java_hdf_hdf5lib_H5__1H5Topen2 */ @@ -67,12 +71,14 @@ Java_hdf_hdf5lib_H5_H5Tcommitted { htri_t bval = JNI_FALSE; - bval = H5Tcommitted(type_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Tcommitted(type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Tcommitted */ @@ -85,12 +91,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tcreate (JNIEnv *env, jclass clss, jint dclass, jlong size) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; - retVal = H5Tcreate((H5T_class_t )dclass, (size_t)size); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tcreate((H5T_class_t )dclass, (size_t)size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tcreate */ @@ -103,12 +111,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tcopy (JNIEnv *env, jclass clss, jlong type_id) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Tcopy((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tcopy((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tcopy */ @@ -123,12 +133,14 @@ Java_hdf_hdf5lib_H5_H5Tequal { htri_t bval = JNI_FALSE; - bval = H5Tequal((hid_t)type_id1, (hid_t)type_id2); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Tequal((hid_t)type_id1, (hid_t)type_id2)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Tequal */ @@ -141,12 +153,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tlock (JNIEnv *env, jclass clss, jlong type_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tlock((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tlock((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tlock */ @@ -161,10 +175,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1class { H5T_class_t retVal = H5T_NO_CLASS; - retVal = H5Tget_class((hid_t)type_id); - if (retVal == H5T_NO_CLASS) - h5libraryError(env); + UNUSED(clss); + if (H5T_NO_CLASS == (retVal = H5Tget_class((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1class */ @@ -179,10 +195,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1size { size_t retVal = 0; - retVal = H5Tget_size((hid_t)type_id); - if (retVal == 0) - h5libraryError(env); + UNUSED(clss); + + if (!(retVal = H5Tget_size((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1size*/ @@ -196,12 +214,14 @@ Java_hdf_hdf5lib_H5_H5Tset_1size (JNIEnv *env, jclass clss, jlong type_id, jlong size) { size_t tsize = (size_t)size; - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_size((hid_t)type_id, tsize); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_size((hid_t)type_id, tsize)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end ifJava_hdf_hdf5lib_H5_H5Tset_1size */ @@ -216,10 +236,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1order { H5T_order_t retVal = H5T_ORDER_ERROR; - retVal = H5Tget_order((hid_t)type_id); - if (retVal == H5T_ORDER_ERROR) - h5libraryError(env); + UNUSED(clss); + if (H5T_ORDER_ERROR == (retVal = H5Tget_order((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1order */ @@ -232,12 +254,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1order (JNIEnv *env, jclass clss, jlong type_id, jint order) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_order((hid_t)type_id, (H5T_order_t)order); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_order((hid_t)type_id, (H5T_order_t)order)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1order */ @@ -252,10 +276,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1precision { size_t retVal = 0; - retVal = H5Tget_precision((hid_t)type_id); - if (retVal == 0) - h5libraryError(env); + UNUSED(clss); + + if (!(retVal = H5Tget_precision((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1precision */ @@ -270,10 +296,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1precision_1long { size_t retVal = 0; - retVal = H5Tget_precision((hid_t)type_id); - if (retVal == 0) - h5libraryError(env); + UNUSED(clss); + if (!(retVal = H5Tget_precision((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1precision_1long */ @@ -286,12 +314,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1precision (JNIEnv *env, jclass clss, jlong type_id, jlong precision) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_precision((hid_t)type_id, (size_t)precision); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_precision((hid_t)type_id, (size_t)precision)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1precision */ @@ -306,10 +336,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1offset { int retVal = -1; - retVal = H5Tget_offset((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + + if ((retVal = H5Tget_offset((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1offset */ @@ -322,12 +354,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1offset (JNIEnv *env, jclass clss, jlong type_id, jlong offset) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Tset_offset((hid_t)type_id, (size_t)offset); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tset_offset((hid_t)type_id, (size_t)offset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1offset */ @@ -340,29 +374,23 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1pad (JNIEnv *env, jclass clss, jlong type_id, jintArray pad) { - herr_t status = -1; - jboolean isCopy; - jint *P; - - if (pad == NULL) { - h5nullArgument(env, "H5Tget_pad: pad is NULL"); - } /* end if */ - else { - P = ENVPTR->GetIntArrayElements(ENVPAR pad, &isCopy); - if (P == NULL) { - h5JNIFatalError(env, "H5Tget_pad: pad not pinned"); - } /* end if */ - else { - status = H5Tget_pad((hid_t)type_id, (H5T_pad_t *)&(P[0]), (H5T_pad_t *)&(P[1])); - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR pad, P, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR pad, P, 0); - } /* end else */ - } /* end else */ + jboolean isCopy; + jint *P = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == pad) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_pad: pad is NULL"); + + PIN_INT_ARRAY(ENVONLY, pad, P, &isCopy, "H5Tget_pad: pad not pinned"); + + if ((status = H5Tget_pad((hid_t)type_id, (H5T_pad_t *)&(P[0]), (H5T_pad_t *)&(P[1]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (P) + UNPIN_INT_ARRAY(ENVONLY, pad, P, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tget_1pad */ @@ -376,12 +404,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1pad (JNIEnv *env, jclass clss, jlong type_id, jint lsb, jint msb) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_pad((hid_t)type_id, (H5T_pad_t)lsb, (H5T_pad_t)msb); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_pad((hid_t)type_id, (H5T_pad_t)lsb, (H5T_pad_t)msb)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1pad */ @@ -396,10 +426,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1sign { H5T_sign_t retVal = H5T_SGN_ERROR; - retVal = H5Tget_sign((hid_t)type_id); - if (retVal == H5T_SGN_ERROR) - h5libraryError(env); + UNUSED(clss); + + if (H5T_SGN_ERROR == (retVal = H5Tget_sign((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1sign */ @@ -412,12 +444,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1sign (JNIEnv *env, jclass clss, jlong type_id, jint sign) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Tset_sign((hid_t)type_id, (H5T_sign_t)sign); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tset_sign((hid_t)type_id, (H5T_sign_t)sign)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1sign */ @@ -430,32 +464,31 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1fields_1int (JNIEnv *env, jclass clss, jlong type_id, jintArray fields) { - herr_t status; - jboolean isCopy; - jint *P; - - if (fields == NULL) { - h5nullArgument(env, "H5Tget_fields: fields is NULL"); - } /* end if */ - else if (ENVPTR->GetArrayLength(ENVPAR fields) < 5) { - h5badArgument(env, "H5Tget_fields: fields input array < order 5"); - } /* end else if */ - else { - P = ENVPTR->GetIntArrayElements(ENVPAR fields, &isCopy); - if (P == NULL) { - h5JNIFatalError(env, "H5Tget_fields: fields not pinned"); - } /* end if */ - else { - status = H5Tget_fields((hid_t)type_id, (size_t *)&(P[0]), (size_t *)&(P[1]), (size_t *)&(P[2]), (size_t *)&(P[3]), (size_t *)&(P[4])); - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR fields, P, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR fields, P, 0); - } /* end else */ - } /* end else */ + jboolean isCopy; + jsize arrLen; + jint *P = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == fields) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields_int: fields is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, fields)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields_int: fields array length < 0"); + } + if (arrLen < 5) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields_int: fields input array < order 5"); + + PIN_INT_ARRAY(ENVONLY, fields, P, &isCopy, "H5Tget_fields_int: fields not pinned"); + + if ((status = H5Tget_fields((hid_t)type_id, (size_t *)&(P[0]), (size_t *)&(P[1]), (size_t *)&(P[2]), (size_t *)&(P[3]), (size_t *)&(P[4]))) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (P) + UNPIN_INT_ARRAY(ENVONLY, fields, P, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tget_1fields_1int */ @@ -469,56 +502,57 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tget_1fields (JNIEnv *env, jclass clss, jlong type_id, jlongArray fields) { - herr_t status; - jboolean isCopy; - jlong *fieldsArray; - - if (fields == NULL) { - h5nullArgument(env, "H5Tget_fields: fields is NULL"); - } /* end if */ - else if (ENVPTR->GetArrayLength(ENVPAR fields) < 5) { - h5badArgument(env, "H5Tget_fields: fields input array < order 5"); - } /* end else if */ - else { - fieldsArray = ENVPTR->GetLongArrayElements(ENVPAR fields, &isCopy); - if (fieldsArray == NULL) { - h5JNIFatalError(env, "H5Tget_fields: fields not pinned"); - } /* end if */ - else { - { /* direct cast (size_t *)variable fails on 32-bit environment */ - size_t spos_t = 0; - size_t epos_t = 0; - size_t esize_t = 0; - size_t mpos_t = 0; - size_t msize_t = 0; - long long fields_temp = *(&fieldsArray[0]); - spos_t = (size_t)fields_temp; - fields_temp = *(&fieldsArray[1]); - epos_t = (size_t)fields_temp; - fields_temp = *(&fieldsArray[2]); - esize_t = (size_t)fields_temp; - fields_temp = *(&fieldsArray[3]); - mpos_t = (size_t)fields_temp; - fields_temp = *(&fieldsArray[4]); - msize_t = (size_t)fields_temp; - - status = H5Tget_fields((hid_t)type_id, &spos_t, &epos_t, &esize_t, &mpos_t, &msize_t); - - *(&fieldsArray[0]) = (jlong)spos_t; - *(&fieldsArray[1]) = (jlong)epos_t; - *(&fieldsArray[2]) = (jlong)esize_t; - *(&fieldsArray[3]) = (jlong)mpos_t; - *(&fieldsArray[4]) = (jlong)msize_t; - } /* end direct cast special handling */ - - if (status < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR fields, fieldsArray, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseLongArrayElements(ENVPAR fields, fieldsArray, 0); - } /* end else */ - } /* end else */ + jboolean isCopy; + jlong *fieldsArray = NULL; + jsize arrLen; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == fields) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields: fields is NULL"); + + if ((arrLen = ENVPTR->GetArrayLength(ENVONLY, fields)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields: fields array length < 0"); + } + if (arrLen < 5) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields: fields input array < order 5"); + + PIN_LONG_ARRAY(ENVONLY, fields, fieldsArray, &isCopy, "H5Tget_fields: fields not pinned"); + + { /* Direct cast (size_t *)variable fails on 32-bit environment */ + size_t spos_t = 0; + size_t epos_t = 0; + size_t esize_t = 0; + size_t mpos_t = 0; + size_t msize_t = 0; + long long fields_temp = *(&fieldsArray[0]); + spos_t = (size_t)fields_temp; + fields_temp = *(&fieldsArray[1]); + epos_t = (size_t)fields_temp; + fields_temp = *(&fieldsArray[2]); + esize_t = (size_t)fields_temp; + fields_temp = *(&fieldsArray[3]); + mpos_t = (size_t)fields_temp; + fields_temp = *(&fieldsArray[4]); + msize_t = (size_t)fields_temp; + + if ((status = H5Tget_fields((hid_t)type_id, &spos_t, &epos_t, &esize_t, &mpos_t, &msize_t)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + *(&fieldsArray[0]) = (jlong)spos_t; + *(&fieldsArray[1]) = (jlong)epos_t; + *(&fieldsArray[2]) = (jlong)esize_t; + *(&fieldsArray[3]) = (jlong)mpos_t; + *(&fieldsArray[4]) = (jlong)msize_t; + } /* end direct cast special handling */ + +done: + if (fieldsArray) + UNPIN_LONG_ARRAY(ENVONLY, fields, fieldsArray, (status < 0) ? JNI_ABORT : 0); + + return; } /* end Java_hdf_hdf5lib_H5_H5Tget_1fields */ /* @@ -531,8 +565,13 @@ Java_hdf_hdf5lib_H5_H5Tset_1fields (JNIEnv *env, jclass clss, jlong type_id, jlong spos, jlong epos, jlong esize, jlong mpos, jlong msize) { + UNUSED(clss); + if (H5Tset_fields((hid_t)type_id, (size_t)spos, (size_t)epos, (size_t)esize, (size_t)mpos, (size_t)msize) < 0) - h5libraryError(env); + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; } /* end Java_hdf_hdf5lib_H5_H5Tset_1fields */ /* @@ -546,10 +585,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1ebias { size_t retVal = 0; - retVal = H5Tget_ebias((hid_t)type_id); - if (retVal == 0) - h5libraryError(env); + UNUSED(clss); + + if (!(retVal = H5Tget_ebias((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1ebias */ @@ -564,10 +605,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1ebias_1long { size_t retVal = 0; - retVal = H5Tget_ebias((hid_t)type_id); - if (retVal == 0) - h5libraryError(env); + UNUSED(clss); + if (!(retVal = H5Tget_ebias((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1ebias_1long */ @@ -580,12 +623,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1ebias (JNIEnv *env, jclass clss, jlong type_id, jlong ebias) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_ebias((hid_t)type_id, (size_t)ebias); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_ebias((hid_t)type_id, (size_t)ebias)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1ebias */ @@ -600,10 +645,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1norm { H5T_norm_t retVal = H5T_NORM_ERROR; - retVal = H5Tget_norm((hid_t)type_id); - if (retVal == H5T_NORM_ERROR) - h5libraryError(env); + UNUSED(clss); + + if (H5T_NORM_ERROR == (retVal = H5Tget_norm((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1norm */ @@ -616,12 +663,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1norm (JNIEnv *env, jclass clss, jlong type_id, jint norm) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Tset_norm((hid_t)type_id, (H5T_norm_t )norm); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tset_norm((hid_t)type_id, (H5T_norm_t )norm)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1norm */ @@ -636,10 +685,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1inpad { H5T_pad_t retVal = H5T_PAD_ERROR; - retVal = H5Tget_inpad((hid_t)type_id ); - if (retVal == H5T_PAD_ERROR) - h5libraryError(env); + UNUSED(clss); + + if (H5T_PAD_ERROR == (retVal = H5Tget_inpad((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1inpad */ @@ -652,12 +703,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1inpad (JNIEnv *env, jclass clss, jlong type_id, jint inpad) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_inpad((hid_t)type_id, (H5T_pad_t) inpad); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_inpad((hid_t)type_id, (H5T_pad_t) inpad)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1inpad */ @@ -672,10 +725,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1cset { H5T_cset_t retVal = H5T_CSET_ERROR; - retVal = H5Tget_cset((hid_t)type_id); - if (retVal == H5T_CSET_ERROR) - h5libraryError(env); + UNUSED(clss); + if (H5T_CSET_ERROR == (retVal = H5Tget_cset((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1cset */ @@ -688,12 +743,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1cset (JNIEnv *env, jclass clss, jlong type_id, jint cset) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tset_cset((hid_t)type_id, (H5T_cset_t)cset); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tset_cset((hid_t)type_id, (H5T_cset_t)cset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1cset */ @@ -708,10 +765,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1strpad { H5T_str_t retVal = H5T_STR_ERROR; - retVal = H5Tget_strpad((hid_t)type_id); - if (retVal == H5T_STR_ERROR) - h5libraryError(env); + UNUSED(clss); + + if (H5T_STR_ERROR == (retVal = H5Tget_strpad((hid_t)type_id))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1strpad */ @@ -724,12 +783,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1strpad (JNIEnv *env, jclass clss, jlong type_id, jint strpad) { - herr_t retVal = -1; + herr_t retVal = FAIL; - retVal = H5Tset_strpad((hid_t)type_id, (H5T_str_t)strpad); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tset_strpad((hid_t)type_id, (H5T_str_t)strpad)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tset_1strpad */ @@ -744,10 +805,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1nmembers { int retVal = -1; - retVal = H5Tget_nmembers((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + + if ((retVal = H5Tget_nmembers((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1nmembers */ @@ -760,17 +823,20 @@ JNIEXPORT jstring JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1name (JNIEnv *env, jclass clss, jlong type_id, jint field_idx) { - char *name; - jstring str = NULL; + char *member_name = NULL; + jstring str = NULL; - name = H5Tget_member_name((hid_t)type_id, (unsigned)field_idx); - if (name != NULL) { - str = ENVPTR->NewStringUTF(ENVPAR name); - H5free_memory(name); + UNUSED(clss); - if (str == NULL) - h5JNIFatalError(env, "H5Tget_member_name: returned string not created"); - } /* end if */ + if (NULL == (member_name = H5Tget_member_name((hid_t)type_id, (unsigned)field_idx))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, member_name))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (member_name) + H5free_memory(member_name); return str; } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1name */ @@ -784,18 +850,19 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1index (JNIEnv *env, jclass clss, jlong type_id, jstring field_name) { - const char *tName; + const char *datatypeName = NULL; int index = -1; - PIN_JAVA_STRING(field_name, tName); - if (tName != NULL) { - index = H5Tget_member_index((hid_t)type_id, tName); + UNUSED(clss); - UNPIN_JAVA_STRING(field_name, tName); + PIN_JAVA_STRING(ENVONLY, field_name, datatypeName, NULL, "H5Tget_member_index: datatype name not pinned"); - if (index < 0) - h5libraryError(env); - } + if ((index = H5Tget_member_index((hid_t)type_id, datatypeName)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (datatypeName) + UNPIN_JAVA_STRING(ENVONLY, field_name, datatypeName); return (jint)index; } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1index */ @@ -809,12 +876,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tget_1member_1type (JNIEnv *env, jclass clss, jlong type_id, jint field_idx) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Tget_member_type((hid_t)type_id, (unsigned)field_idx); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tget_member_type((hid_t)type_id, (unsigned)field_idx)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tget_1member_1type */ @@ -827,6 +896,9 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1offset (JNIEnv *env, jclass clss, jlong type_id, jint memno) { + UNUSED(env); + UNUSED(clss); + return (jlong)H5Tget_member_offset((hid_t)type_id, (unsigned)memno); } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1offset */ @@ -839,12 +911,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1class (JNIEnv *env, jclass clss, jlong type_id, jint memno) { - int retVal = -1; + H5T_class_t retVal = H5T_NO_CLASS; + + UNUSED(clss); - retVal = H5Tget_member_class((hid_t)type_id, (unsigned)memno); - if (retVal < 0) - h5libraryError(env); + if (H5T_NO_CLASS == (retVal = H5Tget_member_class((hid_t)type_id, (unsigned)memno))) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1class */ @@ -857,18 +931,20 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tinsert (JNIEnv *env, jclass clss, jlong type_id, jstring name, jlong offset, jlong field_id) { - herr_t status = -1; - const char *tName; + const char *datatypeName = NULL; long off = (long)offset; + herr_t status = FAIL; - PIN_JAVA_STRING(name, tName); - if (tName != NULL) { - status = H5Tinsert((hid_t)type_id, tName, (size_t)off, field_id); + UNUSED(clss); - UNPIN_JAVA_STRING(name,tName); - if (status < 0) - h5libraryError(env); - } + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Tinsert: datatype name not pinned"); + + if ((status = H5Tinsert((hid_t)type_id, datatypeName, (size_t)off, field_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (datatypeName) + UNPIN_JAVA_STRING(ENVONLY, name, datatypeName); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tinsert */ @@ -882,12 +958,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tpack (JNIEnv *env, jclass clss, jlong type_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tpack((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tpack((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Tpack */ @@ -900,12 +978,14 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5__1H5Tclose (JNIEnv *env, jclass clss, jlong type_id) { - herr_t retVal = -1; + herr_t retVal = FAIL; + + UNUSED(clss); - retVal = H5Tclose((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tclose((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tclose */ @@ -918,12 +998,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tvlen_1create (JNIEnv *env, jclass clss, jlong base_id) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; - retVal = H5Tvlen_create((hid_t)base_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tvlen_create((hid_t)base_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tvlen_1create */ @@ -936,18 +1018,19 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tset_1tag (JNIEnv *env, jclass clss, jlong type, jstring tag) { - herr_t status = -1; - const char *tagP; + const char *tagBuf = NULL; + herr_t status = FAIL; - PIN_JAVA_STRING(tag, tagP); - if (tagP != NULL) { - status = H5Tset_tag((hid_t)type, tagP); + UNUSED(clss); - UNPIN_JAVA_STRING(tag,tagP); + PIN_JAVA_STRING(ENVONLY, tag, tagBuf, NULL, "H5Tset_tag: tag buffer not pinned"); - if (status < 0) - h5libraryError(env); - } + if ((status = H5Tset_tag((hid_t)type, tagBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (tagBuf) + UNPIN_JAVA_STRING(ENVONLY, tag, tagBuf); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tset_1tag */ @@ -961,17 +1044,20 @@ JNIEXPORT jstring JNICALL Java_hdf_hdf5lib_H5_H5Tget_1tag (JNIEnv *env, jclass clss, jlong type) { - jstring str = NULL; - char *tag; + jstring str = NULL; + char *tag = NULL; - tag = H5Tget_tag((hid_t)type); - if (tag != NULL) { - str = ENVPTR->NewStringUTF(ENVPAR tag); - H5free_memory(tag); + UNUSED(clss); + + if (NULL == (tag = H5Tget_tag((hid_t)type))) + H5_LIBRARY_ERROR(ENVONLY); - if (str == NULL) - h5JNIFatalError(env, "H5Tget_tag: returned string not created"); - } /* end if */ + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, tag))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (tag) + H5free_memory(tag); return str; } /* end Java_hdf_hdf5lib_H5_H5Tget_1tag */ @@ -985,12 +1071,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tget_1super (JNIEnv *env, jclass clss, jlong type_id) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); - retVal = H5Tget_super((hid_t)type_id); - if (retVal < 0) - h5libraryError(env); + if ((retVal = H5Tget_super((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tget_1super */ @@ -1003,12 +1091,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tenum_1create (JNIEnv *env, jclass clss, jlong base_id) { - hid_t retVal = -1; + hid_t retVal = H5I_INVALID_HID; - retVal = H5Tenum_create((hid_t)base_id); - if (retVal < 0) - h5libraryError(env); + UNUSED(clss); + if ((retVal = H5Tenum_create((hid_t)base_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tenum_1create */ @@ -1021,32 +1111,28 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tenum_1insert_1int (JNIEnv *env, jclass clss, jlong type_id, jstring name, jintArray value) { - herr_t status = -1; - jint *intP; - const char *nameP; - jboolean isCopy2; - - if (value == NULL ) { - h5nullArgument(env, "H5Tenum_insert: value is NULL"); - } /* end if */ - else { - PIN_JAVA_STRING(name, nameP); - if (nameP != NULL) { - intP = ENVPTR->GetIntArrayElements(ENVPAR value, &isCopy2); - if (intP == NULL) { - h5JNIFatalError(env, "H5Tenum_insert: value not pinned"); - } /* end if */ - else { - status = H5Tenum_insert((hid_t)type_id, nameP, intP); - - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, JNI_ABORT); - - if (status < 0) - h5libraryError(env); - } /* end else */ - UNPIN_JAVA_STRING(name, nameP); - } - } /* end else */ + const char *memberName = NULL; + jboolean isCopy; + jint *intBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert: value is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, memberName, NULL, "H5Tenum_insert: member name not pinned"); + + PIN_INT_ARRAY(ENVONLY, value, intBuf, &isCopy, "H5Tenum_insert: int buffer not pinned"); + + if ((status = H5Tenum_insert((hid_t)type_id, memberName, intBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (intBuf) + UNPIN_INT_ARRAY(ENVONLY, value, intBuf, (status < 0) ? JNI_ABORT : 0); + if (memberName) + UNPIN_JAVA_STRING(ENVONLY, name, memberName); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tenum_1insert_1int */ @@ -1060,32 +1146,28 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tenum_1insert (JNIEnv *env, jclass clss, jlong type_id, jstring name, jbyteArray value) { - herr_t status = -1; - jbyte *byteP; - const char *nameP; - jboolean isCopy2; - - if (value == NULL) { - h5nullArgument(env, "H5Tenum_insert: value is NULL"); - } /* end if */ - else { - PIN_JAVA_STRING(name, nameP); - if (nameP != NULL) { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value, &isCopy2); - if (byteP == NULL) { - h5JNIFatalError(env, "H5Tenum_insert: value not pinned"); - } /* end if */ - else { - status = H5Tenum_insert((hid_t)type_id, nameP, byteP); - - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - - if (status < 0) - h5libraryError(env); - } /* end else */ - UNPIN_JAVA_STRING(name, nameP); - } - } /* end else */ + const char *memberName = NULL; + jboolean isCopy; + jbyte *memberBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert: value is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, memberName, NULL, "H5Tenum_insert: member name not pinned"); + + PIN_BYTE_ARRAY(ENVONLY, value, memberBuf, &isCopy, "H5Tenum_insert: member buffer not pinned"); + + if ((status = H5Tenum_insert((hid_t)type_id, memberName, memberBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (memberBuf) + UNPIN_BYTE_ARRAY(ENVONLY, value, memberBuf, (status < 0) ? JNI_ABORT : 0); + if (memberName) + UNPIN_JAVA_STRING(ENVONLY, name, memberName); } /* end Java_hdf_hdf5lib_H5_H5Tenum_1insert */ /* @@ -1098,51 +1180,39 @@ Java_hdf_hdf5lib_H5_H5Tenum_1nameof_1int (JNIEnv *env, jclass clss, jlong type_id, jintArray value, jobjectArray name, jint size) { - herr_t status = -1; - jint *intP; - char *nameP; - jboolean isCopy; - jstring str; - - if (size <= 0) { - h5badArgument(env, "H5Tenum_nameof: name size < 0"); - } /* end if */ - else if (value == NULL) { - h5nullArgument(env, "H5Tenum_nameof: value is NULL"); - } /* end if */ - else { - nameP = (char*)HDmalloc(sizeof(char) * (size_t)size); - if (nameP == NULL) { - /* exception -- out of memory */ - h5outOfMemory(env, "H5Tenum_nameof: malloc name size"); - } /* end if */ - else { - intP = ENVPTR->GetIntArrayElements(ENVPAR value, &isCopy); - if (intP == NULL) { - HDfree(nameP); - h5JNIFatalError(env, "H5Tenum_nameof: value not pinned"); - } /* end if */ - else { - status = H5Tenum_nameof((hid_t)type_id, intP, nameP, (size_t)size); - - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, JNI_ABORT); - - if (status < 0) { - HDfree(nameP); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR nameP); - HDfree(nameP); - if (str == NULL) { - h5JNIFatalError(env, "H5Tenum_nameof: return array not created"); - } /* end if */ - else - ENVPTR->SetObjectArrayElement(ENVPAR name, 0, (jobject)str); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + jstring str; + jint *intP = NULL; + char *nameP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof_int: value is NULL"); + if (size <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof_int: name size < 0"); + + if (NULL == (nameP = (char *) HDmalloc(sizeof(char) * (size_t)size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tenum_nameof_int: failed to allocate name buffer"); + + PIN_INT_ARRAY(ENVONLY, value, intP, &isCopy, "H5Tenum_nameof_int: value not pinned"); + + if ((status = H5Tenum_nameof((hid_t)type_id, intP, nameP, (size_t)size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + nameP[(size_t)size - 1] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, nameP))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, name, 0, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (intP) + UNPIN_INT_ARRAY(ENVONLY, value, intP, JNI_ABORT); + if (nameP) + HDfree(nameP); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tenum_1nameof_1int */ @@ -1156,49 +1226,36 @@ JNIEXPORT jstring JNICALL Java_hdf_hdf5lib_H5_H5Tenum_1nameof (JNIEnv *env, jclass clss, jlong type_id, jbyteArray value, jlong size) { - herr_t status = -1; - jbyte *byteP; - char *nameP; - jboolean isCopy; - jstring str = NULL; - - if (size <= 0) { - h5badArgument(env, "H5Tenum_nameof: name size < 0"); - } /* end if */ - else if (value == NULL ) { - h5nullArgument(env, "H5Tenum_nameof: value is NULL"); - } /* end if */ - else { - nameP = (char*)HDmalloc(sizeof(char) * (size_t)size); - if (nameP == NULL) { - h5outOfMemory(env, "H5Tenum_nameof: malloc name size"); - } /* end if */ - else { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value, &isCopy); - if (byteP == NULL) { - HDfree(nameP); - h5JNIFatalError(env, "H5Tenum_nameof: value not pinned"); - } /* end if */ - else { - status = H5Tenum_nameof((hid_t)type_id, byteP, nameP, (size_t)size); - - /* free the buffer without copying back */ - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - - if (status < 0) { - HDfree(nameP); - h5libraryError(env); - } /* end if */ - else { - str = ENVPTR->NewStringUTF(ENVPAR nameP); - HDfree(nameP); - if (str == NULL) { - h5JNIFatalError(env, "H5Tenum_nameof: return array not created"); - } /* end if */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + jstring str = NULL; + jbyte *byteP = NULL; + char *nameP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: value is NULL"); + if (size <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: name size < 0"); + + if (NULL == (nameP = (char *) HDmalloc(sizeof(char) * (size_t)size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tenum_nameof: failed to allocate name buffer"); + + PIN_BYTE_ARRAY(ENVONLY, value, byteP, &isCopy, "H5Tenum_nameof: value not pinned"); + + if ((status = H5Tenum_nameof((hid_t)type_id, byteP, nameP, (size_t)size)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + nameP[(size_t)size - 1] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, nameP))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + +done: + if (byteP) + UNPIN_BYTE_ARRAY(ENVONLY, value, byteP, JNI_ABORT); + if (nameP) + HDfree(nameP); return str; } /* end Java_hdf_hdf5lib_H5_H5Tenum_1nameof */ @@ -1212,34 +1269,28 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tenum_1valueof_1int (JNIEnv *env, jclass clss, jlong type_id, jstring name, jintArray value) { - herr_t status = -1; - jint *intP; - const char *nameP; - jboolean isCopy2; - - if (value == NULL) { - h5nullArgument(env, "H5Tenum_valueof: value is NULL"); - } /* end if */ - else { - PIN_JAVA_STRING(name, nameP); - if (nameP != NULL) { - intP = ENVPTR->GetIntArrayElements(ENVPAR value, &isCopy2); - if (intP == NULL) { - h5JNIFatalError(env, "H5Tenum_valueof: value not pinned"); - } /* end if */ - else { - status = H5Tenum_valueof((hid_t)type_id, nameP, intP); - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, 0); - } /* end else */ - UNPIN_JAVA_STRING(name, nameP); - } - } /* end else */ + const char *enumValue = NULL; + jboolean isCopy; + jint *enumValueBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof_int: value is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, enumValue, NULL, "H5Tenum_valueof_int: enum value not pinned"); + + PIN_INT_ARRAY(ENVONLY, value, enumValueBuf, &isCopy, "H5Tenum_valueof_int: enum value buffer not pinned"); + + if ((status = H5Tenum_valueof((hid_t)type_id, enumValue, enumValueBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (enumValueBuf) + UNPIN_INT_ARRAY(ENVONLY, value, enumValueBuf, (status < 0) ? JNI_ABORT : 0); + if (enumValue) + UNPIN_JAVA_STRING(ENVONLY, name, enumValue); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tenum_1valueof_1int */ @@ -1253,34 +1304,28 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tenum_1valueof (JNIEnv *env, jclass clss, jlong type_id, jstring name, jbyteArray value) { - herr_t status = -1; - jbyte *byteP; - const char *nameP; - jboolean isCopy2; - - if (value == NULL) { - h5nullArgument(env, "H5Tenum_valueof: value is NULL"); - } /* end if */ - else { - PIN_JAVA_STRING(name, nameP); - if (nameP != NULL) { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value, &isCopy2); - if (byteP == NULL) { - h5JNIFatalError(env, "H5Tenum_valueof: value not pinned"); - } /* end if */ - else { - status = H5Tenum_valueof((hid_t)type_id, nameP, byteP); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, 0); - } /* end else */ - UNPIN_JAVA_STRING(name, nameP); - } - } /* end else */ + const char *enumValue = NULL; + jboolean isCopy; + jbyte *enumValueBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof: value is NULL"); + + PIN_JAVA_STRING(ENVONLY, name, enumValue, NULL, "H5Tenum_valueof: enum value not pinned"); + + PIN_BYTE_ARRAY(ENVONLY, value, enumValueBuf, &isCopy, "H5Tenum_valueof: enum value buffer not pinned"); + + if ((status = H5Tenum_valueof((hid_t)type_id, enumValue, enumValueBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (enumValueBuf) + UNPIN_BYTE_ARRAY(ENVONLY, value, enumValueBuf, (status < 0) ? JNI_ABORT : 0); + if (enumValue) + UNPIN_JAVA_STRING(ENVONLY, name, enumValue); } /* end Java_hdf_hdf5lib_H5_H5Tenum_1valueof */ /* @@ -1292,30 +1337,23 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1value_1int (JNIEnv *env, jclass clss, jlong type_id, jint membno, jintArray value) { - herr_t status = -1; - jint *intP; - jboolean isCopy; - - if (value == NULL) { - h5nullArgument(env, "H5Tget_member_value: value is NULL"); - } /* end if */ - else { - intP = ENVPTR->GetIntArrayElements(ENVPAR value, &isCopy); - if (intP == NULL) { - h5JNIFatalError(env, "H5Tget_member_value: value not pinned"); - } /* end if */ - else { - status = H5Tget_member_value((hid_t)type_id, (unsigned)membno, intP); - - - if (status < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseIntArrayElements(ENVPAR value, intP, 0); - } /* end else */ - } /* end else */ + jboolean isCopy; + jint *intP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_member_value: value is NULL"); + + PIN_INT_ARRAY(ENVONLY, value, intP, &isCopy, "H5Tget_member_value: value not pinned"); + + if ((status = H5Tget_member_value((hid_t)type_id, (unsigned)membno, intP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (intP) + UNPIN_INT_ARRAY(ENVONLY, value, intP, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1value_1int */ @@ -1329,29 +1367,23 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tget_1member_1value (JNIEnv *env, jclass clss, jlong type_id, jint membno, jbyteArray value) { - herr_t status = -1; - jbyte *byteP; - jboolean isCopy; - - if (value == NULL) { - h5nullArgument( env, "H5Tget_member_value: value is NULL"); - } /* end if */ - else { - byteP = ENVPTR->GetByteArrayElements(ENVPAR value,&isCopy); - if (byteP == NULL) { - h5JNIFatalError(env, "H5Tget_member_value: value not pinned"); - } /* end if */ - else { - status = H5Tget_member_value((hid_t)type_id, (unsigned)membno, byteP); - - if (status < 0) { - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else - ENVPTR->ReleaseByteArrayElements(ENVPAR value, byteP, 0); - } /* end else */ - } /* end else */ + jboolean isCopy; + jbyte *byteP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_member_value: value is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, value, byteP, &isCopy, "H5Tget_member_value: value not pinned"); + + if ((status = H5Tget_member_value((hid_t)type_id, (unsigned)membno, byteP)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (byteP) + UNPIN_BYTE_ARRAY(ENVONLY, value, byteP, (status < 0) ? JNI_ABORT : 0); } /* end Java_hdf_hdf5lib_H5_H5Tget_1member_1value */ /* @@ -1365,10 +1397,12 @@ Java_hdf_hdf5lib_H5_H5Tget_1array_1ndims { int ndims = -1; - ndims = H5Tget_array_ndims((hid_t)type_id); - if (ndims < 0) - h5libraryError(env); + UNUSED(clss); + + if ((ndims = H5Tget_array_ndims((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)ndims; } /* end Java_hdf_hdf5lib_H5_H5Tget_1array_1ndims */ @@ -1381,41 +1415,41 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1array_1dims (JNIEnv *env, jclass clss, jlong type_id, jintArray dims, jintArray perms) { - int ndims = -1; - int dlen; - int i; - jint *dimsP; - hsize_t *cdims = NULL; - jboolean isCopy; - - if (dims == NULL) { - h5nullArgument( env, "H5Tget_array_dims: value is NULL"); - } /* end if */ - else { - dimsP = ENVPTR->GetIntArrayElements(ENVPAR dims, &isCopy); - if (dimsP == NULL) { - h5JNIFatalError(env, "H5Tget_array_dims: dimsP not pinned"); - } /* end if */ - else { - dlen = ENVPTR->GetArrayLength(ENVPAR dims); - cdims = (hsize_t*)HDmalloc((size_t)dlen * sizeof(hsize_t)); - - ndims = H5Tget_array_dims2((hid_t)type_id, cdims); - - if (ndims < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < dlen; i++) { - dimsP[i] = (jint) cdims[i]; - } /* end for */ - ENVPTR->ReleaseIntArrayElements(ENVPAR dims, dimsP, 0); - - if (cdims) HDfree(cdims); - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *cdims = NULL; + size_t i; + jsize dlen; + jint *dimsP = NULL; + int ndims = -1; + + UNUSED(clss); + UNUSED(perms); + + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_array_dims: dims array is NULL"); + + PIN_INT_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Tget_array_dims: dimsP not pinned"); + + if ((dlen = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_array_dims: dims array length < 0"); + } + + if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tget_array_dims: failed to allocate dimension buffer"); + + if ((ndims = H5Tget_array_dims2((hid_t)type_id, cdims)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (size_t) dlen; i++) { + dimsP[i] = (jint) cdims[i]; + } /* end for */ + +done: + if (cdims) + HDfree(cdims); + if (dimsP) + UNPIN_INT_ARRAY(ENVONLY, dims, dimsP, (ndims < 0) ? JNI_ABORT : 0); return (jint)ndims; } /* end Java_hdf_hdf5lib_H5_H5Tget_1array_1dims */ @@ -1431,12 +1465,14 @@ Java_hdf_hdf5lib_H5_H5Tis_1variable_1str { htri_t bval = JNI_FALSE; - bval = H5Tis_variable_str((hid_t)type_id); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Tis_variable_str((hid_t)type_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Tis_1variable_1str */ @@ -1449,13 +1485,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tget_1native_1type (JNIEnv *env, jclass clss, jlong type_id, jint direction) { - hid_t native_tid = -1; + hid_t native_tid = H5I_INVALID_HID; - native_tid = H5Tget_native_type((hid_t)type_id, (H5T_direction_t)direction); + UNUSED(clss); - if (native_tid < 0) - h5libraryError(env); + if ((native_tid = H5Tget_native_type((hid_t)type_id, (H5T_direction_t)direction)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)native_tid; } /* end Java_hdf_hdf5lib_H5__1H5Tget_1native_1type */ @@ -1470,12 +1507,14 @@ Java_hdf_hdf5lib_H5_H5Tdetect_1class { htri_t bval = JNI_FALSE; - bval = H5Tdetect_class((hid_t)type_id, (H5T_class_t)dtype_class); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); + UNUSED(clss); + + if ((bval = H5Tdetect_class((hid_t)type_id, (H5T_class_t)dtype_class)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; +done: return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5Tdetect_1class */ @@ -1489,18 +1528,19 @@ Java_hdf_hdf5lib_H5_H5Tcommit (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong type, jlong link_plist_id, jlong create_plist_id, jlong access_plist_id) { - herr_t status = -1; - const char *tName; + const char *datatypeName = NULL; + herr_t status = FAIL; - PIN_JAVA_STRING(name, tName); - if (tName != NULL) { - status = H5Tcommit2((hid_t)loc_id, tName, (hid_t)type, (hid_t)link_plist_id, (hid_t)create_plist_id, (hid_t)access_plist_id); + UNUSED(clss); - UNPIN_JAVA_STRING(name, tName); + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Tcommit: datatype name not pinned"); - if (status < 0) - h5libraryError(env); - } + if ((status = H5Tcommit2((hid_t)loc_id, datatypeName, (hid_t)type, (hid_t)link_plist_id, (hid_t)create_plist_id, (hid_t)access_plist_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (datatypeName) + UNPIN_JAVA_STRING(ENVONLY, name, datatypeName); } /* end Java_hdf_hdf5lib_H5_H5Tcommit */ /* @@ -1512,45 +1552,45 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5__1H5Tarray_1create2 (JNIEnv *env, jclass clss, jlong base_id, jint rank, jlongArray dims) { - hid_t retVal = -1; - jlong *dimsP; - int dlen; - hsize_t *cdims = NULL; - jboolean isCopy; - int i; - - if (rank <= 0) { - h5badArgument(env, "H5Tarray_create: rank is < 1"); - } /* end if */ - else if (dims == NULL) { - h5nullArgument(env, "H5Tarray_create: dims is NULL"); - } /* end else if */ - else { - dimsP = ENVPTR->GetLongArrayElements(ENVPAR dims, &isCopy); - if (dimsP == NULL) { - h5JNIFatalError( env, "H5Tarray_create: dimsP not pinned"); - } /* end if */ - else { - dlen = ENVPTR->GetArrayLength(ENVPAR dims); - if (dlen != rank) { - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - } /* end if */ - else { - cdims = (hsize_t*)HDmalloc((size_t)dlen * sizeof(hsize_t)); - for (i = 0; i < dlen; i++) { - cdims[i] = (hsize_t)dimsP[i]; - } /* end for */ - - retVal = H5Tarray_create2((hid_t)base_id, (unsigned)rank, (const hsize_t*)cdims); - - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, 0); - - HDfree(cdims); - if (retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *cdims = NULL; + size_t i; + jlong *dimsP = NULL; + jsize dlen; + hid_t retVal = H5I_INVALID_HID; + + UNUSED(clss); + + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: dims is NULL"); + if (rank <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: rank is < 1"); + + PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Tarray_create: dimsP not pinned"); + + if ((dlen = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: dims array length < 0"); + } + + if (dlen != rank) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_create: dimension array length != array rank"); + + if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_create: failed to allocate dimension buffer"); + + for (i = 0; i < (size_t) dlen; i++) { + cdims[i] = (hsize_t)dimsP[i]; + } /* end for */ + + if ((retVal = H5Tarray_create2((hid_t)base_id, (unsigned)rank, (const hsize_t *)cdims)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (cdims) + HDfree(cdims); + if (dimsP) + UNPIN_LONG_ARRAY(ENVONLY, dims, dimsP, (retVal < 0) ? JNI_ABORT : 0); return (jlong)retVal; } /* end Java_hdf_hdf5lib_H5__1H5Tarray_1create2 */ @@ -1564,44 +1604,40 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Tget_1array_1dims2 (JNIEnv *env, jclass clss, jlong type_id, jlongArray dims) { - int ndims = -1; - int dlen; - int i; - jlong *dimsP; - hsize_t *cdims=NULL; - jboolean isCopy; - - if (dims == NULL) { - h5nullArgument(env, "H5Tget_array_dims: value is NULL"); - } /* end if */ - else { - dimsP = ENVPTR->GetLongArrayElements(ENVPAR dims,&isCopy); - if (dimsP == NULL) { - h5JNIFatalError(env, "H5Tget_array_dims: dimsP not pinned"); - } /* end if */ - else { - dlen = ENVPTR->GetArrayLength(ENVPAR dims); - cdims = (hsize_t*)HDmalloc((size_t)dlen * sizeof(hsize_t)); - - ndims = H5Tget_array_dims2((hid_t)type_id, (hsize_t*)cdims); - - if (ndims < 0) { - if (cdims) - free(cdims); - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, JNI_ABORT); - h5libraryError(env); - } /* end if */ - else { - for (i = 0; i < dlen; i++) { - dimsP[i] = (jlong) cdims[i]; - } /* end for */ - ENVPTR->ReleaseLongArrayElements(ENVPAR dims, dimsP, 0); - - if (cdims) - HDfree(cdims); - } /* end else */ - } /* end else */ - } /* end else */ + jboolean isCopy; + hsize_t *cdims = NULL; + size_t i; + jlong *dimsP = NULL; + jsize dlen; + int ndims = -1; + + UNUSED(clss); + + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tarray_get_dims2: value is NULL"); + + PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Tarray_get_dims2: dimsP not pinned"); + + if ((dlen = ENVPTR->GetArrayLength(ENVONLY, dims)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tarray_get_dims2: dims array length < 0"); + } + + if (NULL == (cdims = (hsize_t *) HDmalloc((size_t)dlen * sizeof(hsize_t)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Tarray_get_dims2: failed to allocate dimension buffer"); + + if ((ndims = H5Tget_array_dims2((hid_t)type_id, (hsize_t*)cdims)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0; i < (size_t) dlen; i++) { + dimsP[i] = (jlong) cdims[i]; + } /* end for */ + +done: + if (cdims) + HDfree(cdims); + if (dimsP) + UNPIN_LONG_ARRAY(ENVONLY, dims, dimsP, (ndims < 0) ? JNI_ABORT : 0); return (jint)ndims; } /* end Java_hdf_hdf5lib_H5_H5Tget_1array_1dims2 */ @@ -1616,34 +1652,29 @@ Java_hdf_hdf5lib_H5_H5Tconvert (JNIEnv *env, jclass clss, jlong src_id, jlong dst_id, jlong nelmts, jbyteArray buf, jbyteArray background, jlong plist_id) { - herr_t status; - jbyte *bufP; - jbyte *bgP = NULL; - jboolean isCopy; - - if (nelmts <= 0) { - h5badArgument(env, "H5Tconvert: name nelmts < 0"); - } /* end if */ - else { - bufP = ENVPTR->GetByteArrayElements(ENVPAR buf, &isCopy); - if (bufP == NULL) { - h5JNIFatalError(env, "H5Tconvert: value not pinned"); - } /* end if */ - else { - if (background) - bgP = ENVPTR->GetByteArrayElements(ENVPAR background, &isCopy); - - status = H5Tconvert((hid_t)src_id, (hid_t)dst_id, (size_t)nelmts, (void *)bufP, (void *)bgP, (hid_t)plist_id) ; - - ENVPTR->ReleaseByteArrayElements(ENVPAR buf, bufP, 0); - - if (bgP) - ENVPTR->ReleaseByteArrayElements(ENVPAR background, bgP, 0); - - if (status < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ + jboolean isCopy; + jbyte *bufP = NULL; + jbyte *bgP = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + if (nelmts <= 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tconvert: nelmts < 0"); + + PIN_BYTE_ARRAY(ENVONLY, buf, bufP, &isCopy, "H5Tconvert: buffer not pinned"); + + if (background) + PIN_BYTE_ARRAY(ENVONLY, background, bgP, &isCopy, "H5Tconvert: background buffer not pinned"); + + if ((status = H5Tconvert((hid_t)src_id, (hid_t)dst_id, (size_t)nelmts, (void *)bufP, (void *)bgP, (hid_t)plist_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (bgP) + UNPIN_BYTE_ARRAY(ENVONLY, background, bgP, (status < 0) ? JNI_ABORT : 0); + if (bufP) + UNPIN_BYTE_ARRAY(ENVONLY, buf, bufP, (status < 0) ? JNI_ABORT : 0); } /* end Java_hdf_hdf5lib_H5_H5Tconvert */ /* @@ -1654,8 +1685,13 @@ Java_hdf_hdf5lib_H5_H5Tconvert JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Tflush(JNIEnv *env, jclass clss, jlong loc_id) { + UNUSED(clss); + if (H5Tflush((hid_t)loc_id) < 0) - h5libraryError(env); + H5_LIBRARY_ERROR(ENVONLY); + +done: + return; } /* @@ -1666,10 +1702,14 @@ Java_hdf_hdf5lib_H5_H5Tflush(JNIEnv *env, jclass clss, jlong loc_id) JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5Trefresh(JNIEnv *env, jclass clss, jlong loc_id) { + UNUSED(clss); + if (H5Trefresh((hid_t)loc_id) < 0) - h5libraryError(env); -} + H5_LIBRARY_ERROR(ENVONLY); +done: + return; +} #ifdef __cplusplus diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index fd34ba1..4208ce1 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -32,7 +32,11 @@ extern "C" { hsize_t H5TOOLS_BUFSIZE = (32 * 1024 * 1024); /* 32 MB */ int H5TOOLS_TEXT_BLOCK = 16; /* Number of elements on a line in a text export file */ +/* + * Pointer to the JNI's Virtual Machine; used for callback functions. + */ JavaVM *jvm; + jobject copy_callback; jobject close_callback; jobject create_callback; @@ -41,22 +45,22 @@ jobject get_callback; jobject set_callback; jobject delete_callback; -H5E_auto2_t efunc; -void *edata; +H5E_auto2_t efunc; +void *edata; /********************/ /* Local Prototypes */ /********************/ -static int h5str_dump_region_blocks(h5str_t *str, hid_t region, hid_t region_obj); -static int h5str_dump_region_points(h5str_t *str, hid_t region, hid_t region_obj); +static int h5str_dump_region_blocks(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj); +static int h5str_dump_region_points(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj); static int h5str_is_zero(const void *_mem, size_t size); static hid_t h5str_get_native_type(hid_t type); static hid_t h5str_get_little_endian_type(hid_t type); static hid_t h5str_get_big_endian_type(hid_t type); static htri_t h5str_detect_vlen(hid_t tid); static htri_t h5str_detect_vlen_str(hid_t tid); -static int h5tools_dump_simple_data(FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts); +static int h5tools_dump_simple_data(JNIEnv *env, FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts); static int h5str_render_bin_output(FILE *stream, hid_t container, hid_t tid, void *_mem, hsize_t block_nelmts); static int render_bin_output_region_data_blocks(FILE *stream, hid_t region_id, hid_t container, int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata); @@ -78,9 +82,10 @@ h5str_array_free return; for (i = 0; i < len; i++) { - if (*(strs + i)) - HDfree(*(strs + i)); + if (strs[i]) + HDfree(strs[i]); } /* for (i=0; imax == new_len) return; - new_str = (char *)HDmalloc(new_len); + if (NULL == (new_str = (char *) HDmalloc(new_len))) + return; + if (new_len > str->max) /* increase memory */ HDstrcpy(new_str, str->s); else @@ -152,860 +162,1044 @@ h5str_append return HDstrcat(str->s, cstr); } /* end h5str_append */ -/** print value of a vlen data point into string. - Return Value: - On success, the total number of characters printed is returned. - On error, a negative number is returned. +/* + * Converts the given data point string into a real data point. + * + * Returns: + * SUCCESS: Length of string token processed + * FAILURE: 0 */ size_t -h5str_vlconvert - (char *str, hid_t container, hid_t tid, hvl_t *ptr, int expand_data) +h5str_convert + (JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_buf, size_t out_buf_offset) { - unsigned char tmp_uchar = 0; - char tmp_char = 0; - unsigned short tmp_ushort = 0; - short tmp_short = 0; - unsigned int tmp_uint = 0; - int tmp_int = 0; - unsigned long tmp_ulong = 0; - long tmp_long = 0; - unsigned long long tmp_ullong = 0; - long long tmp_llong = 0; - float tmp_float = 0.0; - double tmp_double = 0.0; - long double tmp_ldouble = 0.0; - static char fmt_llong[8], fmt_ullong[8]; - - hid_t mtid = -1; - size_t offset; - size_t nll; - char *this_str; - size_t this_strlen; - int n; - H5T_class_t tclass = H5Tget_class(tid); - size_t size = H5Tget_size(tid); - H5T_sign_t nsign = H5Tget_sign(tid); - int bdata_print = 0; - - if (!str || !ptr) - return 0; - - this_str = NULL; - this_strlen = 0; + unsigned char *ucptr = NULL; + static char fmt_llong[8], fmt_ullong[8]; + H5T_class_t tclass = H5T_NO_CLASS; + const char delimiter[] = " ," H5_COMPOUND_BEGIN_INDICATOR H5_COMPOUND_END_INDICATOR \ + H5_ARRAY_BEGIN_INDICATOR H5_ARRAY_END_INDICATOR \ + H5_VLEN_BEGIN_INDICATOR H5_VLEN_END_INDICATOR; + size_t typeSize = 0; + hid_t mtid = H5I_INVALID_HID; + char *this_str = NULL; + char *token; + char *cptr = NULL; + int n; + size_t retVal = 0; + + if (!in_str) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_convert: in_str is NULL"); + if (!out_buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_convert: out_buf is NULL"); + + this_str = *in_str; + cptr = &(((char *) out_buf)[out_buf_offset]); + ucptr = &(((unsigned char *) out_buf)[out_buf_offset]); + + if (H5T_NO_CLASS == (tclass = H5Tget_class(tid))) + H5_LIBRARY_ERROR(ENVONLY); + if (!(typeSize = H5Tget_size(tid))) + H5_LIBRARY_ERROR(ENVONLY); + + /* Build default formats for long long types */ + if (!fmt_llong[0]) { + if (HDsprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsprintf failure"); + if (HDsprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: HDsprintf failure"); + } /* end if */ switch (tclass) { - case H5T_COMPOUND: + case H5T_FLOAT: { - unsigned i; - n = H5Tget_nmembers(tid); + token = HDstrtok(this_str, delimiter); - /* remove compound indicators */ - if (str[0] == ' ') - str++; - if (str[0] == '{') - str++; + switch (typeSize) { + case sizeof(float): + { + float tmp_float = 0.0; - ptr->p = HDcalloc((size_t)1, size); - ptr->len = size; - for (i = 0; i < n; i++) { - offset = H5Tget_member_offset(tid, i); - mtid = H5Tget_member_type(tid, i); - str += offset; - h5str_convert(&str, container, mtid, ptr, 0, expand_data); - /* remove compound indicators */ - if (str[0] == ',') - str++; - if (str[0] == ' ') - str++; - H5Tclose(mtid); + sscanf(token, "%f", &tmp_float); + HDmemcpy(cptr, &tmp_float, sizeof(float)); + break; + } + + case sizeof(double): + { + double tmp_double = 0.0; + + sscanf(token, "%lf", &tmp_double); + HDmemcpy(cptr, &tmp_double, sizeof(double)); + break; + } +#if H5_SIZEOF_LONG_DOUBLE != 0 + case sizeof(long double): + { + long double tmp_ldouble = 0.0; + + sscanf(token, "%Lf", &tmp_ldouble); + HDmemcpy(cptr, &tmp_ldouble, sizeof(long double)); + break; + } +#endif + + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_convert: floating-point datatype size didn't match any of expected sizes"); + break; } - /* remove compound indicators */ - if (str[0] == '}') - str++; - if (str[0] == ' ') - str++; + + retVal = typeSize; + + break; } - break; - case H5T_ARRAY: + + case H5T_STRING: { - int rank = 0; - hsize_t i, dims[H5S_MAX_RANK], total_elmts; + size_t len = HDstrlen(this_str); - /* remove array indicators */ - if (str[0] == '[') - str++; - if (str[0] == ' ') - str++; + if (len > 0) { + HDstrncpy(cptr, this_str, typeSize); + retVal = typeSize; + } + else { + cptr = NULL; + } - mtid = H5Tget_super(tid); - size = H5Tget_size(mtid); - rank = H5Tget_array_ndims(tid); + break; + } - H5Tget_array_dims2(tid, dims); + case H5T_INTEGER: + { + H5T_sign_t nsign = H5T_SGN_ERROR; - total_elmts = 1; - for (i = 0; i < rank; i++) - total_elmts *= dims[i]; + if (H5T_SGN_ERROR == (nsign = H5Tget_sign(tid))) + H5_LIBRARY_ERROR(ENVONLY); - ptr->p = HDcalloc((size_t)total_elmts, size); - ptr->len = total_elmts; - h5str_convert(&str, container, mtid, ptr, 0, expand_data); - H5Tclose(mtid); - /* remove array indicators */ - if (str[0] == ' ') - str++; - if (str[0] == ']') - str++; - if (str[0] == ' ') - str++; - } - break; - default: - ptr->len = size; - ptr->p = HDcalloc(1, size); - this_strlen = h5str_convert(&str, container, tid, ptr, 0, expand_data); - break; - } /* end switch */ + token = HDstrtok(this_str, delimiter); - return this_strlen; -} /* end h5str_vlconvert */ + switch (typeSize) { + case sizeof(char): + { + unsigned char tmp_uchar = 0; + signed char tmp_char = 0; -/** print value of a data point into string. - Return Value: - On success, the total number of characters printed is returned. - On error, a negative number is returned. - */ -size_t -h5str_convert - (char **str, hid_t container, hid_t tid, hvl_t *ptr, int ptroffset, int expand_data) -{ - unsigned char tmp_uchar = 0; - char tmp_char = 0; - unsigned short tmp_ushort = 0; - short tmp_short = 0; - unsigned int tmp_uint = 0; - int tmp_int = 0; - unsigned long tmp_ulong = 0; - long tmp_long = 0; - unsigned long long tmp_ullong = 0; - long long tmp_llong = 0; - float tmp_float = 0.0; - double tmp_double = 0.0; - long double tmp_ldouble = 0.0; - static char fmt_llong[8], fmt_ullong[8]; - const char delimiter[] = " ,}]"; - - char *token; - hid_t mtid = -1; - size_t offset; - size_t nll; - char *this_str = *str; - size_t this_strlen; - int n; - char *cptr = ((char*) ((hvl_t *) ptr)->p) + ptroffset; - unsigned char *ucptr = ((unsigned char*) ((hvl_t *) ptr)->p) + ptroffset; - H5T_class_t tclass = H5Tget_class(tid); - size_t size = H5Tget_size(tid); - H5T_sign_t nsign = H5Tget_sign(tid); - int bdata_print = 0; - - if (!str || !ptr) - return 0; + if (H5T_SGN_NONE == nsign) { + sscanf(token, "%hhu", &tmp_uchar); + HDmemcpy(cptr, &tmp_uchar, sizeof(unsigned char)); + } + else { + sscanf(token, "%hhd", &tmp_char); + HDmemcpy(cptr, &tmp_char, sizeof(char)); + } - /* Build default formats for long long types */ - if (!fmt_llong[0]) { - sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); - sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); - } /* end if */ + break; + } - this_strlen = HDstrlen(this_str); + case sizeof(short): + { + unsigned short tmp_ushort = 0; + short tmp_short = 0; - switch (tclass) { - case H5T_FLOAT: - token = HDstrtok (this_str, delimiter); - if (sizeof(float) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_FLOAT)) */ - tmp_float = 0; - sscanf(token, "%f", &tmp_float); - HDmemcpy(cptr, &tmp_float, sizeof(float)); - } - else if (sizeof(double) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) */ - tmp_double = 0; - sscanf(token, "%%lf", &tmp_double); - HDmemcpy(cptr, &tmp_double, sizeof(double)); - } -#if H5_SIZEOF_LONG_DOUBLE !=0 - else if (sizeof(long double) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) */ - tmp_ldouble = 0; - sscanf(token, "%Lf", &tmp_ldouble); - HDmemcpy(cptr, &tmp_ldouble, sizeof(long double)); - } + if (H5T_SGN_NONE == nsign) { + sscanf(token, "%hu", &tmp_ushort); + HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); + } + else { + sscanf(token, "%hd", &tmp_short); + HDmemcpy(&tmp_short, cptr, sizeof(short)); + } + + break; + } + + case sizeof(int): + { + unsigned int tmp_uint = 0; + int tmp_int = 0; + + if (H5T_SGN_NONE == nsign) { + sscanf(token, "%u", &tmp_uint); + HDmemcpy(cptr, &tmp_uint, sizeof(unsigned int)); + } + else { + sscanf(token, "%d", &tmp_int); + HDmemcpy(cptr, &tmp_int, sizeof(int)); + } + + break; + } + + case sizeof(long): + { + unsigned long tmp_ulong = 0; + long tmp_long = 0; + + if (H5T_SGN_NONE == nsign) { + sscanf(token, "%lu", &tmp_ulong); + HDmemcpy(cptr, &tmp_ulong, sizeof(unsigned long)); + } + else { + sscanf(token, "%ld", &tmp_long); + HDmemcpy(cptr, &tmp_long, sizeof(long)); + } + + break; + } + +#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG + case sizeof(long long): + { + unsigned long long tmp_ullong = 0; + long long tmp_llong = 0; + + if (H5T_SGN_NONE == nsign) { + sscanf(token, fmt_ullong, &tmp_ullong); + HDmemcpy(cptr, &tmp_ullong, sizeof(unsigned long long)); + } + else { + sscanf(token, fmt_llong, &tmp_llong); + HDmemcpy(cptr, &tmp_llong, sizeof(long long)); + } + + break; + } #endif - break; - case H5T_STRING: - { - if (this_strlen > 0) { - HDstrncpy(cptr, this_str, size); - } - else { - cptr = NULL; - } - } - break; - case H5T_INTEGER: - token = HDstrtok (this_str, delimiter); - if (sizeof(char) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_UCHAR)) */ - tmp_uchar = 0; - sscanf(token, "%hu", &tmp_uchar); - HDmemcpy(cptr, &tmp_uchar, sizeof(unsigned char)); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_SCHAR)) */ - tmp_char = 0; - sscanf(token, "%hd", &tmp_char); - HDmemcpy(cptr, &tmp_char, sizeof(char)); - } - } - else if (sizeof(int) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_UINT)) */ - tmp_uint = 0; - sscanf(token, "%u", &tmp_uint); - HDmemcpy(cptr, &tmp_uint, sizeof(unsigned int)); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_INT)) */ - tmp_int = 0; - sscanf(token, "%d", &tmp_int); - HDmemcpy(cptr, &tmp_int, sizeof(int)); - } - } - else if (sizeof(short) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_USHORT)) */ - tmp_ushort = 0; - sscanf(token, "%u", &tmp_ushort); - HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_SHORT)) */ - tmp_short = 0; - sscanf(token, "%d", &tmp_short); - HDmemcpy(&tmp_short, cptr, sizeof(short)); - } - } - else if (sizeof(long) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_ULONG)) */ - tmp_ulong = 0; - sscanf(token, "%lu", &tmp_ulong); - HDmemcpy(cptr, &tmp_ulong, sizeof(unsigned long)); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_LONG)) */ - tmp_long = 0; - sscanf(token, "%ld", &tmp_long); - HDmemcpy(cptr, &tmp_long, sizeof(long)); + + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_convert: integer datatype size didn't match any of expected sizes"); + break; } + + retVal = typeSize; + + break; } - else if (sizeof(long long) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_ULLONG)) */ - tmp_ullong = 0; - sscanf(token, fmt_ullong, &tmp_ullong); - HDmemcpy(cptr, &tmp_ullong, sizeof(unsigned long long)); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_LLONG)) */ - tmp_llong = 0; - sscanf(token, fmt_llong, &tmp_llong); - HDmemcpy(cptr, &tmp_llong, sizeof(long long)); + + case H5T_COMPOUND: + { + unsigned i; + size_t member_offset; + + if ((n = H5Tget_nmembers(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* Skip whitespace and compound indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == '{') this_str++; + while (*this_str == ' ') this_str++; + + for (i = 0; i < (unsigned) n; i++) { + member_offset = H5Tget_member_offset(tid, i); + + if ((mtid = H5Tget_member_type(tid, i)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_convert(ENVONLY, &this_str, container, mtid, out_buf, member_offset)) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + goto done; + } + + /* Skip whitespace and commas */ + while (*this_str == ' ') this_str++; + if (*this_str == ',') this_str++; + while (*this_str == ' ') this_str++; + + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; } + + /* Skip whitespace and compound indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == '}') this_str++; + while (*this_str == ' ') this_str++; + + retVal = typeSize * (size_t) n; + + break; } - break; - case H5T_COMPOUND: - { - unsigned i; - n = H5Tget_nmembers(tid); - /* remove compound indicators */ - if ((*str)[0] == ' ') - (*str)++; - if ((*str)[0] == '{') - (*str)++; - - for (i = 0; i < n; i++) { - offset = H5Tget_member_offset(tid, i); - mtid = H5Tget_member_type(tid, i); - h5str_convert(str, container, mtid, ptr, offset, expand_data); - /* remove compound indicators */ - if ((*str)[0] == ',') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - H5Tclose(mtid); - } - /* remove compound indicators */ - if ((*str)[0] == '}') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - } - break; - case H5T_ENUM: - { - char enum_name[1024]; - void *value; - if (sizeof(char) == size) { - tmp_uchar = 0; - value = &tmp_uchar; - } - else if (sizeof(short) == size) { - tmp_ushort = 0; - value = &tmp_ushort; - } - else if (sizeof(long) == size) { - tmp_ulong = 0; - value = &tmp_ulong; - } - else if (sizeof(long long) == size) { - tmp_ullong = 0; - value = &tmp_ullong; - } - else { - tmp_uint = 0; - value = &tmp_uint; - } - token = HDstrtok (this_str, delimiter); - H5Tenum_valueof(tid, token, value); - HDmemcpy(ucptr, value, size); - } - break; - case H5T_REFERENCE: + /* TODO handle reference writing */ - cptr = NULL; - break; - case H5T_ARRAY: - { - int rank = 0; - hsize_t i, dims[H5S_MAX_RANK], total_elmts; - /* remove array indicators */ - if ((*str)[0] == '[') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - - mtid = H5Tget_super(tid); - offset = H5Tget_size(mtid); - rank = H5Tget_array_ndims(tid); - - H5Tget_array_dims2(tid, dims); - - total_elmts = 1; - for (i = 0; i < rank; i++) - total_elmts *= dims[i]; - - cptr = HDcalloc((size_t)total_elmts, offset); - for (i = 0; i < total_elmts; i++) { - h5str_convert(str, container, mtid, cptr + (i*offset), offset, expand_data); - /* remove array indicators */ - if ((*str)[0] == ',') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - } - H5Tclose(mtid); - /* remove array indicators */ - if ((*str)[0] == ' ') - (*str)++; - if ((*str)[0] == ']') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - } - break; - case H5T_VLEN: + case H5T_REFERENCE: + cptr = NULL; + break; + + case H5T_ENUM: { - unsigned int i; - mtid = H5Tget_super(tid); - offset = H5Tget_size(mtid); - - /* remove vlen indicators */ - if ((*str)[0] == '{') - (*str)++; - cptr = HDcalloc(offset, sizeof(hvl_t)); - for (i = 0; (i*offset) < (int)size; i++) { - h5str_convert(str, container, mtid, cptr + (i*offset), offset, expand_data); - /* remove vlen indicators */ - if ((*str)[0] == ',') - (*str)++; - if ((*str)[0] == ' ') - (*str)++; - if ((*str)[0] == '}') + void *value; + + token = HDstrtok(this_str, delimiter); + + switch (typeSize) { + case sizeof(char): + { + unsigned char tmp_uchar = 0; + value = &tmp_uchar; + break; + } + + case sizeof(short): + { + unsigned short tmp_ushort = 0; + value = &tmp_ushort; + break; + } + + case sizeof(long): + { + unsigned long tmp_ulong = 0; + value = &tmp_ulong; + break; + } + +#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG + case sizeof(long long): + { + unsigned long long tmp_ullong = 0; + value = &tmp_ullong; + break; + } +#endif + + default: + { + unsigned int tmp_uint = 0; + value = &tmp_uint; break; + } } - H5Tclose(mtid); - /* remove vlen indicators */ - if ((*str)[0] == '}') - (*str)++; + + if (H5Tenum_valueof(tid, token, value) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + HDmemcpy(ucptr, value, typeSize); + + retVal = typeSize; + + break; } - break; - default: - { - /* All other types get copied raw */ - HDmemcpy(ucptr, this_str, size); - } - break; - } /* end switch */ + case H5T_ARRAY: + { + hsize_t i, dims[H5S_MAX_RANK], total_elmts; + size_t baseTypeSize; + int rank = 0; - return this_strlen; -} /* end h5str_convert */ + /* Skip whitespace and array indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == '[') this_str++; + while (*this_str == ' ') this_str++; -/** print value of a vlen data point into string. - Return Value: - On success, the total number of characters printed is returned. - On error, a negative number is returned. - */ -size_t -h5str_vlsprintf - (h5str_t *str, hid_t container, hid_t tid, hvl_t *ptr, int expand_data) -{ - unsigned char tmp_uchar = 0; - char tmp_char = 0; - unsigned short tmp_ushort = 0; - short tmp_short = 0; - unsigned int tmp_uint = 0; - int tmp_int = 0; - unsigned long tmp_ulong = 0; - long tmp_long = 0; - unsigned long long tmp_ullong = 0; - long long tmp_llong = 0; - float tmp_float = 0.0; - double tmp_double = 0.0; - long double tmp_ldouble = 0.0; - static char fmt_llong[8], fmt_ullong[8]; - - hid_t mtid = -1; - size_t offset; - size_t nll; - char *this_str; - size_t this_strlen; - int n; - H5T_class_t tclass = H5Tget_class(tid); - size_t size = H5Tget_size(tid); - H5T_sign_t nsign = H5Tget_sign(tid); - int bdata_print = 0; - - if (!str || !ptr) - return 0; + if ((mtid = H5Tget_super(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - /* Build default formats for long long types */ - if (!fmt_llong[0]) { - sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); - sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); - } /* end if */ + if (!(baseTypeSize = H5Tget_size(mtid))) + H5_LIBRARY_ERROR(ENVONLY); - this_str = NULL; - this_strlen = 0; + if ((rank = H5Tget_array_ndims(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - switch (tclass) { - case H5T_COMPOUND: - { - unsigned i; - n = H5Tget_nmembers(tid); - h5str_append(str, " {"); + if (H5Tget_array_dims2(tid, dims) < 0) + H5_LIBRARY_ERROR(ENVONLY); - for (i = 0; i < n; i++) { - offset = H5Tget_member_offset(tid, i); - mtid = H5Tget_member_type(tid, i); - h5str_sprintf(str, container, mtid, ((char *) (ptr->p)) + offset, ptr->len, expand_data); - if ((i + 1) < n) - h5str_append(str, ", "); - H5Tclose(mtid); + for (i = 0, total_elmts = 1; i < (hsize_t) rank; i++) + total_elmts *= dims[i]; + + if (NULL == (cptr = (char *) HDcalloc((size_t)total_elmts, baseTypeSize))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to allocate array buffer"); + + for (i = 0; i < total_elmts; i++) { + if (!(h5str_convert(ENVONLY, &this_str, container, mtid, out_buf, i * baseTypeSize))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + goto done; + } + + /* Skip whitespace and commas */ + while (*this_str == ' ') this_str++; + if (*this_str == ',') this_str++; + while (*this_str == ' ') this_str++; } - h5str_append(str, "} "); + + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; + + /* Skip whitespace and array indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == ']') this_str++; + while (*this_str == ' ') this_str++; + + retVal = typeSize * total_elmts; + + break; } - break; - case H5T_ARRAY: + + case H5T_VLEN: { - int rank = 0; - hsize_t i, dims[H5S_MAX_RANK], total_elmts; - h5str_append(str, "[ "); + size_t i, baseTypeSize; + hvl_t *vl_buf = (hvl_t *) out_buf; + char cur_char; + + if ((mtid = H5Tget_super(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(baseTypeSize = H5Tget_size(mtid))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (vl_buf->p = HDmalloc(baseTypeSize))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to allocate vlen buffer"); + vl_buf->len = 1; + + /* Skip whitespace and vlen indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == '(') this_str++; + while (*this_str == ' ') this_str++; + + cur_char = *this_str; + for (i = 0; cur_char != ')' && cur_char != '\0'; i++) { + if (i >= vl_buf->len) { + char *tmp_realloc; + + if (NULL == (tmp_realloc = (char *) HDrealloc(vl_buf->p, vl_buf->len * 2 * baseTypeSize))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_convert: failed to reallocate vlen buffer"); + vl_buf->len *= 2; + vl_buf->p = tmp_realloc; + } - mtid = H5Tget_super(tid); - size = H5Tget_size(mtid); - rank = H5Tget_array_ndims(tid); + if (!(h5str_convert(ENVONLY, &this_str, container, mtid, vl_buf->p, i * baseTypeSize))) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + vl_buf->len = i; + goto done; + } - H5Tget_array_dims2(tid, dims); + /* Skip whitespace and commas */ + while (*this_str == ' ') this_str++; + if (*this_str == ',') this_str++; + while (*this_str == ' ') this_str++; + } - total_elmts = 1; - for (i = 0; i < rank; i++) - total_elmts *= dims[i]; + vl_buf->len = i; - h5str_sprintf(str, container, mtid, ((char *) (ptr->p)), ptr->len, expand_data); - H5Tclose(mtid); - h5str_append(str, " ] "); + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; + + /* Skip whitespace and vlen indicators */ + while (*this_str == ' ') this_str++; + if (*this_str == ')') this_str++; + while (*this_str == ' ') this_str++; + + retVal = typeSize; + + break; + } + + case H5T_NCLASSES: + case H5T_NO_CLASS: + { + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_convert: invalid datatype class"); + break; + } + + case H5T_TIME: + case H5T_BITFIELD: + case H5T_OPAQUE: + default: + { + /* All other types get copied raw */ + HDmemcpy(ucptr, this_str, typeSize); + + retVal = typeSize; + + break; } - break; - default: - this_strlen = h5str_sprintf(str, container, tid, ((char *) (ptr->p)), ptr->len, expand_data); - break; } /* end switch */ - return this_strlen; -} /* end h5str_vlsprintf */ +done: + if (mtid >= 0) + H5Tclose(mtid); + + return retVal; +} /* end h5str_convert */ -/** print value of a data point into string. - Return Value: - On success, the total number of characters printed is returned. - On error, a negative number is returned. +/* + * Prints the value of a data point into a string. + * + * Returns: + * SUCCESS: Total number of characters printed + * FAILURE: 0 */ size_t h5str_sprintf - (h5str_t *str, hid_t container, hid_t tid, void *ptr, int ptr_len, int expand_data) + (JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *in_buf, size_t in_buf_len, int expand_data) { - unsigned char tmp_uchar = 0; - char tmp_char = 0; - unsigned short tmp_ushort = 0; - short tmp_short = 0; - unsigned int tmp_uint = 0; - int tmp_int = 0; - unsigned long tmp_ulong = 0; - long tmp_long = 0; - unsigned long long tmp_ullong = 0; - long long tmp_llong = 0; - float tmp_float = 0.0; - double tmp_double = 0.0; - long double tmp_ldouble = 0.0; - static char fmt_llong[8], fmt_ullong[8]; - - hid_t mtid = -1; - size_t offset; - size_t nll; - char *this_str; - size_t this_strlen; - int n; - char *cptr = (char*) (ptr); - unsigned char *ucptr = (unsigned char*) (ptr); - H5T_class_t tclass = H5Tget_class(tid); - size_t size = H5Tget_size(tid); - H5T_sign_t nsign = H5Tget_sign(tid); - int bdata_print = 0; - - if (!str || !ptr) - return 0; + unsigned char *ucptr = (unsigned char *) in_buf; + static char fmt_llong[8], fmt_ullong[8]; + H5T_class_t tclass = H5T_NO_CLASS; + size_t typeSize = 0; + hid_t mtid = H5I_INVALID_HID; + char *cptr = (char *) in_buf; + char *this_str = NULL; + int n; + size_t retVal = 0; + + if (!out_str) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: out_str is NULL"); + if (!in_buf) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: in_buf is NULL"); + + if (H5T_NO_CLASS == (tclass = H5Tget_class(tid))) + H5_LIBRARY_ERROR(ENVONLY); + if (!(typeSize = H5Tget_size(tid))) + H5_LIBRARY_ERROR(ENVONLY); /* Build default formats for long long types */ if (!fmt_llong[0]) { - sprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH); - sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); + if (HDsprintf(fmt_llong, "%%%sd", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: sprintf failure"); + if (HDsprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: sprintf failure"); } /* end if */ - this_str = NULL; - this_strlen = 0; - switch (tclass) { - case H5T_FLOAT: - if (sizeof(float) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_FLOAT)) */ - HDmemcpy(&tmp_float, cptr, sizeof(float)); - this_str = (char*)HDmalloc(25); - sprintf(this_str, "%g", tmp_float); - } - else if (sizeof(double) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) */ - HDmemcpy(&tmp_double, cptr, sizeof(double)); - this_str = (char*)HDmalloc(25); - sprintf(this_str, "%g", tmp_double); - } -#if H5_SIZEOF_LONG_DOUBLE !=0 - else if (sizeof(long double) == size) { - /* if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) */ - HDmemcpy(&tmp_ldouble, cptr, sizeof(long double)); - this_str = (char*)HDmalloc(27); - sprintf(this_str, "%Lf", tmp_ldouble); - } -#endif - break; - case H5T_STRING: - { - char *tmp_str; - size = 0; + case H5T_FLOAT: + { + switch (typeSize) { + case sizeof(float): + { + float tmp_float = 0.0; - if (H5Tis_variable_str(tid)) { - tmp_str = *(char**) ptr; - if (tmp_str != NULL) - size = HDstrlen(tmp_str); - } - else { - tmp_str = cptr; - } + HDmemcpy(&tmp_float, cptr, sizeof(float)); - /* Check for NULL pointer for string */ - if (tmp_str == NULL) { - this_str = (char *)HDmalloc(5); - HDstrncpy(this_str, "NULL", 4); - } - else { - if (size > 0) { - this_str = (char *)HDmalloc(size+1); - HDstrncpy(this_str, tmp_str, size); - } - } - } - break; - case H5T_INTEGER: - if (sizeof(char) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_UCHAR)) */ - HDmemcpy(&tmp_uchar, cptr, sizeof(unsigned char)); - this_str = (char*)HDmalloc(7); - sprintf(this_str, "%u", tmp_uchar); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_SCHAR)) */ - HDmemcpy(&tmp_char, cptr, sizeof(char)); - this_str = (char*)HDmalloc(7); - sprintf(this_str, "%hhd", tmp_char); - } - } - else if (sizeof(int) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_UINT)) */ - HDmemcpy(&tmp_uint, cptr, sizeof(unsigned int)); - this_str = (char*)HDmalloc(14); - sprintf(this_str, "%u", tmp_uint); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_INT)) */ - HDmemcpy(&tmp_int, cptr, sizeof(int)); - this_str = (char*)HDmalloc(14); - sprintf(this_str, "%d", tmp_int); + if (NULL == (this_str = (char *) HDmalloc(25))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%g", tmp_float) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + + break; + } + + case sizeof(double): + { + double tmp_double = 0.0; + + HDmemcpy(&tmp_double, cptr, sizeof(double)); + + if (NULL == (this_str = (char *) HDmalloc(25))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%g", tmp_double) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + + break; + } +#if H5_SIZEOF_LONG_DOUBLE != 0 + case sizeof(long double): + { + long double tmp_ldouble = 0.0; + + HDmemcpy(&tmp_ldouble, cptr, sizeof(long double)); + + if (NULL == (this_str = (char *) HDmalloc(27))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%Lf", tmp_ldouble) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + + break; + } +#endif + + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: floating-point datatype size didn't match any of expected sizes"); + break; } + + break; } - else if (sizeof(short) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_USHORT)) */ - HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); - this_str = (char*)HDmalloc(9); - sprintf(this_str, "%u", tmp_ushort); + + case H5T_STRING: + { + htri_t is_variable; + char *tmp_str; + + typeSize = 0; + + if ((is_variable = H5Tis_variable_str(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (is_variable) { + if (NULL != (tmp_str = *(char **) in_buf)) + typeSize = HDstrlen(tmp_str); } else { - /* if (H5Tequal(tid, H5T_NATIVE_SHORT)) */ - HDmemcpy(&tmp_short, cptr, sizeof(short)); - this_str = (char*)HDmalloc(9); - sprintf(this_str, "%d", tmp_short); + tmp_str = cptr; } - } - else if (sizeof(long) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_ULONG)) */ - HDmemcpy(&tmp_ulong, cptr, sizeof(unsigned long)); - this_str = (char*)HDmalloc(23); - sprintf(this_str, "%lu", tmp_ulong); + + /* Check for NULL pointer for string */ + if (!tmp_str) { + if (NULL == (this_str = (char *) HDmalloc(5))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + HDstrncpy(this_str, "NULL", 5); } else { - /* if (H5Tequal(tid, H5T_NATIVE_LONG)) */ - HDmemcpy(&tmp_long, cptr, sizeof(long)); - this_str = (char*)HDmalloc(23); - sprintf(this_str, "%ld", tmp_long); + if (typeSize > 0) { + if (NULL == (this_str = (char *) HDmalloc(typeSize + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + HDstrncpy(this_str, tmp_str, typeSize); + } } + + break; } - else if (sizeof(long long) == size) { - if(H5T_SGN_NONE == nsign) { - /* if (H5Tequal(tid, H5T_NATIVE_ULLONG)) */ - HDmemcpy(&tmp_ullong, cptr, sizeof(unsigned long long)); - this_str = (char*)HDmalloc(25); - sprintf(this_str, fmt_ullong, tmp_ullong); - } - else { - /* if (H5Tequal(tid, H5T_NATIVE_LLONG)) */ - HDmemcpy(&tmp_llong, cptr, sizeof(long long)); - this_str = (char*)HDmalloc(25); - sprintf(this_str, fmt_llong, tmp_llong); + + case H5T_INTEGER: + { + H5T_sign_t nsign = H5T_SGN_ERROR; + + if (H5T_SGN_ERROR == (nsign = H5Tget_sign(tid))) + H5_LIBRARY_ERROR(ENVONLY); + + switch (typeSize) { + case sizeof(char): + { + unsigned char tmp_uchar = 0; + char tmp_char = 0; + + if (H5T_SGN_NONE == nsign) { + HDmemcpy(&tmp_uchar, cptr, sizeof(unsigned char)); + + if (NULL == (this_str = (char *) HDmalloc(7))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%u", tmp_uchar) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + HDmemcpy(&tmp_char, cptr, sizeof(char)); + + if (NULL == (this_str = (char *) HDmalloc(7))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%hhd", tmp_char) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; + } + + case sizeof(short): + { + unsigned short tmp_ushort = 0; + short tmp_short = 0; + + if (H5T_SGN_NONE == nsign) { + HDmemcpy(&tmp_ushort, cptr, sizeof(unsigned short)); + + if (NULL == (this_str = (char *) HDmalloc(9))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%u", tmp_ushort) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + HDmemcpy(&tmp_short, cptr, sizeof(short)); + + if (NULL == (this_str = (char *) HDmalloc(9))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%d", tmp_short) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; + } + + case sizeof(int): + { + unsigned int tmp_uint = 0; + int tmp_int = 0; + + if (H5T_SGN_NONE == nsign) { + HDmemcpy(&tmp_uint, cptr, sizeof(unsigned int)); + + if (NULL == (this_str = (char *) HDmalloc(14))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%u", tmp_uint) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + HDmemcpy(&tmp_int, cptr, sizeof(int)); + + if (NULL == (this_str = (char *) HDmalloc(14))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%d", tmp_int) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; + } + + case sizeof(long): + { + unsigned long tmp_ulong = 0; + long tmp_long = 0; + + if (H5T_SGN_NONE == nsign) { + HDmemcpy(&tmp_ulong, cptr, sizeof(unsigned long)); + + if (NULL == (this_str = (char *) HDmalloc(23))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%lu", tmp_ulong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + HDmemcpy(&tmp_long, cptr, sizeof(long)); + + if (NULL == (this_str = (char *) HDmalloc(23))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, "%ld", tmp_long) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; + } + +#if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG + case sizeof(long long): + { + unsigned long long tmp_ullong = 0; + long long tmp_llong = 0; + + if (H5T_SGN_NONE == nsign) { + HDmemcpy(&tmp_ullong, cptr, sizeof(unsigned long long)); + + if (NULL == (this_str = (char *) HDmalloc(25))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, fmt_ullong, tmp_ullong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + HDmemcpy(&tmp_llong, cptr, sizeof(long long)); + + if (NULL == (this_str = (char *) HDmalloc(25))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (HDsprintf(this_str, fmt_llong, tmp_llong) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; + } +#endif + + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: integer datatype size didn't match any of expected sizes"); + break; } + + break; } - break; - case H5T_COMPOUND: - { - unsigned i; - n = H5Tget_nmembers(tid); - h5str_append(str, " {"); - - for (i = 0; i < n; i++) { - offset = H5Tget_member_offset(tid, i); - mtid = H5Tget_member_type(tid, i); - h5str_sprintf(str, container, mtid, cptr + offset, ptr_len, expand_data); - if ((i + 1) < n) - h5str_append(str, ", "); - H5Tclose(mtid); - } - h5str_append(str, "} "); - } - break; - case H5T_ENUM: - { - char enum_name[1024]; - if (H5Tenum_nameof(tid, cptr, enum_name, sizeof enum_name) >= 0) { - h5str_append(str, enum_name); + + case H5T_COMPOUND: + { + unsigned i; + size_t offset; + + if ((n = H5Tget_nmembers(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_append(out_str, H5_COMPOUND_BEGIN_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + for (i = 0; i < (unsigned) n; i++) { + offset = H5Tget_member_offset(tid, i); + + if ((mtid = H5Tget_member_type(tid, i)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &cptr[offset], in_buf_len, expand_data)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((i + 1) < (unsigned) n) + if (!h5str_append(out_str, ", ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; + } + + if (!h5str_append(out_str, H5_COMPOUND_END_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + break; } - else { - size_t i; - nll = H5Tget_size(tid); - this_str = (char*)HDmalloc(4 * (nll + 1)); - if (1 == nll) { - sprintf(this_str, "%#02x", ucptr[0]); + case H5T_ENUM: + { + char enum_name[1024]; + + if (H5Tenum_nameof(tid, cptr, enum_name, sizeof enum_name) >= 0) { + if (!h5str_append(out_str, enum_name)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } else { - for (i = 0; i < (int)nll; i++) - sprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]); + size_t i; + + if (NULL == (this_str = (char *) HDmalloc(4 * (typeSize + 1)))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (1 == typeSize) { + if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + for (i = 0; i < typeSize; i++) + if (HDsprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } } + + break; } - } - break; - case H5T_REFERENCE: - if (h5str_is_zero(cptr, size)) { - h5str_append(str, "NULL"); - } - else { - if (H5R_DSET_REG_REF_BUF_SIZE == size) { - /* if (H5Tequal(tid, H5T_STD_REF_DSETREG)) */ + + case H5T_REFERENCE: + { + if (h5str_is_zero(cptr, 99)) { + if (!h5str_append(out_str, "NULL")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + break; + } + + if (H5R_DSET_REG_REF_BUF_SIZE == typeSize) { + H5S_sel_type region_type = H5S_SEL_ERROR; + hid_t region_obj = H5I_INVALID_HID; + hid_t region = H5I_INVALID_HID; + char ref_name[1024]; + /* * Dataset region reference -- * show the type and the referenced object */ - char ref_name[1024]; - hid_t region_obj; - hid_t region; - H5S_sel_type region_type; - /* get name of the dataset the region reference points to using H5Rget_name */ - region_obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, cptr); - if (region_obj >= 0) { - region = H5Rget_region(container, H5R_DATASET_REGION, cptr); - if (region >= 0) { - if(expand_data) { - region_type = H5Sget_select_type(region); - if(region_type==H5S_SEL_POINTS) { - h5str_dump_region_points_data(str, region, region_obj); - } - else { - h5str_dump_region_blocks_data(str, region, region_obj); - } - } - else { - if(H5Rget_name(region_obj, H5R_DATASET_REGION, cptr, (char*)ref_name, 1024) >= 0) { - h5str_append(str, ref_name); - } - - region_type = H5Sget_select_type(region); - - if(region_type==H5S_SEL_POINTS) { - h5str_append(str, " REGION_TYPE POINT"); - h5str_dump_region_points(str, region, region_obj); - } - else { - h5str_append(str, " REGION_TYPE BLOCK"); - h5str_dump_region_blocks(str, region, region_obj); - } - } + /* Get name of the dataset the region reference points to using H5Rget_name */ + if ((region_obj = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, cptr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((region = H5Rget_region(container, H5R_DATASET_REGION, cptr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (expand_data) { + if (H5S_SEL_ERROR == (region_type = H5Sget_select_type(region))) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5S_SEL_POINTS == region_type) { + if (h5str_dump_region_points_data(ENVONLY, out_str, region, region_obj) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else { + if (h5str_dump_region_blocks_data(ENVONLY, out_str, region, region_obj) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + } + else { + if (H5Rget_name(region_obj, H5R_DATASET_REGION, cptr, (char *)ref_name, 1024) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_append(out_str, ref_name)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (H5S_SEL_ERROR == (region_type = H5Sget_select_type(region))) + H5_LIBRARY_ERROR(ENVONLY); - H5Sclose(region); + if (H5S_SEL_POINTS == region_type) { + if (!h5str_append(out_str, " REGION_TYPE POINT")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (h5str_dump_region_points(ENVONLY, out_str, region, region_obj) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else { + if (!h5str_append(out_str, " REGION_TYPE BLOCK")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (h5str_dump_region_blocks(ENVONLY, out_str, region, region_obj) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } - H5Dclose(region_obj); } + + if (H5Sclose(region) < 0) + H5_LIBRARY_ERROR(ENVONLY); + region = H5I_INVALID_HID; + + if (H5Dclose(region_obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + region_obj = H5I_INVALID_HID; } - else if (H5R_OBJ_REF_BUF_SIZE == size) { - /* if (H5Tequal(tid, H5T_STD_REF_OBJ)) */ + else if (H5R_OBJ_REF_BUF_SIZE == typeSize) { + H5O_info_t oi; + hid_t obj = H5I_INVALID_HID; + /* * Object references -- show the type and OID of the referenced * object. */ - H5O_info_t oi; - hid_t obj; - this_str = (char*)HDmalloc(64); - obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, cptr); - H5Oget_info2(obj, &oi, H5O_INFO_ALL); + if (NULL == (this_str = (char *) HDmalloc(64))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if ((obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, cptr)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Oget_info2(obj, &oi, H5O_INFO_ALL) < 0) + H5_LIBRARY_ERROR(ENVONLY); /* Print object data and close object */ - sprintf(this_str, "%u-%lu", (unsigned) oi.type, oi.addr); - H5Oclose(obj); + if (HDsprintf(this_str, "%u-%lu", (unsigned) oi.type, oi.addr) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + + if (H5Oclose(obj) < 0) + H5_LIBRARY_ERROR(ENVONLY); + obj = H5I_INVALID_HID; } + + break; } - break; - case H5T_ARRAY: - { - int rank = 0; - hsize_t i, dims[H5S_MAX_RANK], total_elmts; - h5str_append(str, "[ "); - mtid = H5Tget_super(tid); - size = H5Tget_size(mtid); - rank = H5Tget_array_ndims(tid); + case H5T_ARRAY: + { + hsize_t dims[H5S_MAX_RANK], i, total_elmts; + size_t baseSize; + int rank = 0; + + if (!h5str_append(out_str, H5_ARRAY_BEGIN_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((mtid = H5Tget_super(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(baseSize = H5Tget_size(mtid))) + H5_LIBRARY_ERROR(ENVONLY); + + if ((rank = H5Tget_array_ndims(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Tget_array_dims2(tid, dims) < 0) + H5_LIBRARY_ERROR(ENVONLY); - H5Tget_array_dims2(tid, dims); + for (i = 0, total_elmts = 1; i < (hsize_t) rank; i++) + total_elmts *= dims[i]; + + for (i = 0; i < total_elmts; i++) { + if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &(cptr[i * baseSize]), in_buf_len, expand_data)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((i + 1) < total_elmts) + if (!h5str_append(out_str, ", ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + + if (!h5str_append(out_str, H5_ARRAY_END_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - total_elmts = 1; - for (i = 0; i < rank; i++) - total_elmts *= dims[i]; + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; - for (i = 0; i < total_elmts; i++) { - h5str_sprintf(str, container, mtid, cptr + i * size, ptr_len, expand_data); - if ((i + 1) < total_elmts) - h5str_append(str, ", "); + break; } - H5Tclose(mtid); - h5str_append(str, " ] "); - } - break; - case H5T_VLEN: + + case H5T_VLEN: { - unsigned int i; - mtid = H5Tget_super(tid); - size = H5Tget_size(mtid); - - h5str_append(str, "{"); - for (i = 0; i < (int)ptr_len; i++) { - h5str_sprintf(str, container, mtid, cptr + i * size, ptr_len, expand_data); - if ((i + 1) < (int)ptr_len) - h5str_append(str, ", "); + unsigned int i; + size_t baseSize; + hvl_t *vl_buf = (hvl_t *) in_buf; + + if ((mtid = H5Tget_super(tid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(baseSize = H5Tget_size(mtid))) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_append(out_str, H5_VLEN_BEGIN_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + for (i = 0; i < (unsigned) vl_buf->len; i++) { + if (!h5str_sprintf(ENVONLY, out_str, container, mtid, &(((char *) vl_buf->p)[i * baseSize]), vl_buf->len, expand_data)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if ((i + 1) < (unsigned) vl_buf->len) + if (!h5str_append(out_str, ", ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } - H5Tclose(mtid); - h5str_append(str, "}"); - } - break; - default: - { - /* All other types get printed as hexadecimal */ - size_t i; - nll = H5Tget_size(tid); - this_str = (char*)HDmalloc(4 * (nll + 1)); + if (!h5str_append(out_str, H5_VLEN_END_INDICATOR)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (1 == nll) { - sprintf(this_str, "%#02x", ucptr[0]); + if (H5Tclose(mtid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + mtid = H5I_INVALID_HID; + + break; } - else { - for (i = 0; i < (int)nll; i++) - sprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]); + + case H5T_NO_CLASS: + case H5T_NCLASSES: + { + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_sprintf: invalid datatype class"); + break; + } + + case H5T_TIME: + case H5T_BITFIELD: + case H5T_OPAQUE: + default: + { + size_t i; + + /* All other types get printed as hexadecimal */ + + if (NULL == (this_str = (char *) HDmalloc(4 * (typeSize + 1)))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); + + if (1 == typeSize) { + if (HDsprintf(this_str, "%#02x", ucptr[0]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + else { + for (i = 0; i < typeSize; i++) + if (HDsprintf(this_str, "%s%02x", i ? ":" : "", ucptr[i]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: HDsprintf failure"); + } + + break; } } - break; - } /* end switch */ if (this_str) { - h5str_append(str, this_str); - this_strlen = HDstrlen(str->s); + if (!h5str_append(out_str, this_str)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + HDfree(this_str); + this_str = NULL; } /* end if */ - return this_strlen; + retVal = HDstrlen(out_str->s); + +done: + if (mtid >= 0) + H5Tclose(mtid); + + return retVal; } /* end h5str_sprintf */ /*------------------------------------------------------------------------- @@ -1020,113 +1214,115 @@ h5str_sprintf */ static int h5str_print_region_data_blocks - (hid_t region_id, h5str_t *str, int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata) + (JNIEnv *env, hid_t region_id, h5str_t *str, int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata) { - hsize_t *dims1 = NULL; - hsize_t *start = NULL; - hsize_t *count = NULL; - hsize_t blkndx; - hsize_t total_size[H5S_MAX_RANK]; - hsize_t numelem; - hsize_t numindex; - size_t jndx; - unsigned indx; - size_t type_size; - int ret_value = SUCCEED; - hid_t mem_space = -1; - hid_t sid1 = -1; - void *region_buf = NULL; + unsigned indx; + hsize_t *dims1 = NULL; + hsize_t *start = NULL; + hsize_t *count = NULL; + hsize_t blkndx; + hsize_t total_size[H5S_MAX_RANK]; + hsize_t numelem; + hsize_t numindex; + size_t jndx; + size_t type_size; + hid_t mem_space = H5I_INVALID_HID; + hid_t sid1 = H5I_INVALID_HID; + void *region_buf = NULL; + int ret_value = FAIL; + + if (ndims < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_blocks: ndims < 0"); + if (nblocks < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_blocks: nblocks < 0"); /* Get the dataspace of the dataset */ - if((sid1 = H5Dget_space(region_id)) >= 0) { + if ((sid1 = H5Dget_space(region_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - /* Allocate space for the dimension array */ - if((dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - - /* find the dimensions of each data space from the block coordinates */ - numelem = 1; - for (jndx = 0; jndx < ndims; jndx++) { - dims1[jndx] = ptdata[jndx + (size_t)ndims] - ptdata[jndx] + 1; - numelem = dims1[jndx] * numelem; - } /* end for */ - - /* Create dataspace for reading buffer */ - if((mem_space = H5Screate_simple(ndims, dims1, NULL)) >= 0) { - if((type_size = H5Tget_size(type_id)) > 0) { - if((region_buf = HDmalloc(type_size * (size_t)numelem)) != NULL) { - /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ - /* 1 2 n 1 2 n */ - if((start = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - if((count = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - for (blkndx = 0; blkndx < nblocks; blkndx++) { - for (indx = 0; indx < ndims; indx++) { - start[indx] = ptdata[indx + blkndx * (hsize_t)ndims * 2]; - count[indx] = dims1[indx]; - } /* end for */ - - if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) >= 0) { - if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) >= 0) { - if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) { - for (numindex = 0; numindex < numelem; numindex++) { - h5str_sprintf(str, region_id, type_id, ((char*)region_buf + numindex * type_size), 0, 1); - - if (numindex + 1 < numelem) - h5str_append(str, ", "); - } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, ctx.cur_elmt++) */ - } /* end if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) */ - } /* end if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) >= 0) */ - } /* end if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) >= 0) */ - } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ - - HDfree(count); - } /* end if((count = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - - HDfree(start); - } /* end if((start = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; + /* Allocate space for the dimension array */ + if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate dimension array buffer"); - HDfree(region_buf); - } /* end if((region_buf = HDmalloc(type_size * (size_t)numelem)) != NULL) */ - else - ret_value = -1; - } /* end if((type_size = H5Tget_size(type_id)) > 0) */ - else - ret_value = -1; - - if(H5Sclose(mem_space) < 0) - ret_value = -1; - } /* end if((mem_space = H5Screate_simple(ndims, dims1, NULL)) >= 0) */ - else - ret_value = -1; - - HDfree(dims1); - } /* end if((dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - - if(H5Sclose(sid1) < 0) - ret_value = -1; - } /* end if((sid1 = H5Dget_space(region_id)) >= 0) */ - else - ret_value = -1; + /* Find the dimensions of each data space from the block coordinates */ + for (jndx = 0, numelem = 1; jndx < (size_t) ndims; jndx++) { + dims1[jndx] = ptdata[jndx + (size_t)ndims] - ptdata[jndx] + 1; + numelem = dims1[jndx] * numelem; + } /* end for */ + + /* Create dataspace for reading buffer */ + if ((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!(type_size = H5Tget_size(type_id))) + H5_LIBRARY_ERROR(ENVONLY); + + if (NULL == (region_buf = HDmalloc(type_size * (size_t)numelem))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate region buffer"); + + /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ + /* 1 2 n 1 2 n */ + if (NULL == (start = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab start buffer"); + + if (NULL == (count = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_blocks: failed to allocate hyperslab count buffer"); + + for (blkndx = 0; blkndx < (hsize_t) nblocks; blkndx++) { + for (indx = 0; indx < (unsigned) ndims; indx++) { + start[indx] = ptdata[indx + blkndx * (hsize_t)ndims * 2]; + count[indx] = dims1[indx]; + } /* end for */ + + if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + for (numindex = 0; numindex < numelem; numindex++) { + if (!h5str_sprintf(ENVONLY, str, region_id, type_id, ((char *)region_buf + numindex * type_size), 0, 1)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (numindex + 1 < numelem) + if (!h5str_append(str, ", ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } /* end for (jndx = 0; jndx < numelem; jndx++, region_elmtno++, ctx.cur_elmt++) */ + } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ + + ret_value = SUCCEED; + +done: + if (count) + HDfree(count); + if (start) + HDfree(start); + if (region_buf) + HDfree(region_buf); + if (mem_space >= 0) + H5Sclose(mem_space); + if (dims1) + HDfree(dims1); + if (sid1 >= 0) + H5Sclose(sid1); return ret_value; } /* end h5str_print_region_data_blocks */ int h5str_dump_region_blocks_data - (h5str_t *str, hid_t region, hid_t region_id) + (JNIEnv *env, h5str_t *str, hid_t region, hid_t region_id) { - int ret_value = 0; - hssize_t nblocks; - hsize_t alloc_size; - hsize_t *ptdata; - hid_t dtype = -1; - hid_t type_id = -1; - int ndims = H5Sget_simple_extent_ndims(region); + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + hid_t dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + int ndims = -1; + int ret_value = FAIL; /* * This function fails if the region does not have blocks. @@ -1135,50 +1331,56 @@ h5str_dump_region_blocks_data nblocks = H5Sget_select_hyper_nblocks(region); } H5E_END_TRY; + if (nblocks < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((ndims = H5Sget_simple_extent_ndims(region)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + /* Print block information */ - if (nblocks > 0) { - alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); - if (alloc_size == (hsize_t)((size_t) alloc_size)) { - ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); - H5Sget_select_hyper_blocklist(region, (hsize_t) 0, - (hsize_t) nblocks, ptdata); + alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); + if (alloc_size == (hsize_t)((size_t) alloc_size)) { + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks_data: failed to allocate region block buffer"); + if (H5Sget_select_hyper_blocklist(region, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if((dtype = H5Dget_type(region_id)) >= 0) { - if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) { + if ((dtype = H5Dget_type(region_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - h5str_print_region_data_blocks(region_id, str, ndims, type_id, nblocks, ptdata); + if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if(H5Tclose(type_id) < 0) - ret_value = -1; - } /* end if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) */ - else - ret_value = -1; + if (h5str_print_region_data_blocks(ENVONLY, region_id, str, ndims, type_id, nblocks, ptdata) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } /* if (alloc_size == (hsize_t)((size_t)alloc_size)) */ - if(H5Tclose(dtype) < 0) - ret_value = -1; - } /* end if((dtype = H5Dget_type(region_id)) >= 0) */ - else - ret_value = -1; - HDfree(ptdata); - } /* if (alloc_size == (hsize_t)((size_t)alloc_size)) */ - } /* if (nblocks > 0) */ + ret_value = SUCCEED; + +done: + if (type_id >= 0) + H5Tclose(type_id); + if (dtype >= 0) + H5Tclose(dtype); + if (ptdata) + HDfree(ptdata); return ret_value; } /* end h5str_dump_region_blocks_data */ static int h5str_dump_region_blocks - (h5str_t *str, hid_t region, hid_t region_id) + (JNIEnv *env, h5str_t *str, hid_t region, hid_t region_id) { - int ret_value = 0; - hssize_t nblocks; - hsize_t alloc_size; - hsize_t *ptdata; - hid_t dtype = -1; - hid_t type_id = -1; - char tmp_str[256]; - int ndims = H5Sget_simple_extent_ndims(region); + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + char tmp_str[256]; + int ndims = -1; + int ret_value = FAIL; + + UNUSED(region_id); /* * This function fails if the region does not have blocks. @@ -1187,44 +1389,70 @@ h5str_dump_region_blocks nblocks = H5Sget_select_hyper_nblocks(region); } H5E_END_TRY; + if (nblocks < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((ndims = H5Sget_simple_extent_ndims(region)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + /* Print block information */ - if (nblocks > 0) { + alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); + if (alloc_size == (hsize_t)((size_t) alloc_size)) { int i; - alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); - if (alloc_size == (hsize_t)((size_t) alloc_size)) { - ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); - H5Sget_select_hyper_blocklist(region, (hsize_t) 0, - (hsize_t) nblocks, ptdata); + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: failed to allocate region block buffer"); - h5str_append(str, " {"); - for (i = 0; i < nblocks; i++) { - int j; + if (H5Sget_select_hyper_blocklist(region, (hsize_t) 0, (hsize_t) nblocks, ptdata) < 0) + H5_LIBRARY_ERROR(ENVONLY); - h5str_append(str, " "); + if (!h5str_append(str, " {")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - /* Start coordinates and opposite corner */ - for (j = 0; j < ndims; j++) { - tmp_str[0] = '\0'; - sprintf(tmp_str, "%s%lu", j ? "," : "(", - (unsigned long) ptdata[i * 2 * ndims + j]); - h5str_append(str, tmp_str); - } + for (i = 0; i < nblocks; i++) { + int j; - for (j = 0; j < ndims; j++) { - tmp_str[0] = '\0'; - sprintf(tmp_str, "%s%lu", j ? "," : ")-(", - (unsigned long) ptdata[i * 2 * ndims + j + ndims]); - h5str_append(str, tmp_str); - } - h5str_append(str, ") "); + if (!h5str_append(str, " ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + /* Start coordinates and opposite corner */ + for (j = 0; j < ndims; j++) { + tmp_str[0] = '\0'; + + if (HDsprintf(tmp_str, "%s%lu", j ? "," : "(", + (unsigned long) ptdata[i * 2 * ndims + j]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsprintf failure"); + + if (!h5str_append(str, tmp_str)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + + for (j = 0; j < ndims; j++) { tmp_str[0] = '\0'; + + if (HDsprintf(tmp_str, "%s%lu", j ? "," : ")-(", + (unsigned long) ptdata[i * 2 * ndims + j + ndims]) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_blocks: HDsprintf failure"); + + if (!h5str_append(str, tmp_str)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } - h5str_append(str, " }"); - HDfree(ptdata); - } /* if (alloc_size == (hsize_t)((size_t)alloc_size)) */ - } /* if (nblocks > 0) */ + if (!h5str_append(str, ") ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + tmp_str[0] = '\0'; + } + + if (!h5str_append(str, " }")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } /* if (alloc_size == (hsize_t)((size_t)alloc_size)) */ + + ret_value = SUCCEED; + +done: + if (ptdata) + HDfree(ptdata); return ret_value; } /* end h5str_dump_region_blocks */ @@ -1241,76 +1469,76 @@ h5str_dump_region_blocks */ static int h5str_print_region_data_points - (hid_t region_space, hid_t region_id, h5str_t *str, int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata) + (JNIEnv *env, hid_t region_space, hid_t region_id, h5str_t *str, int ndims, hid_t type_id, hssize_t npoints, hsize_t *ptdata) { - hsize_t *dims1 = NULL; - hsize_t total_size[H5S_MAX_RANK]; - size_t jndx; - size_t type_size; - int ret_value = SUCCEED; - hid_t mem_space = -1; - void *region_buf = NULL; + hsize_t *dims1 = NULL; + hsize_t total_size[H5S_MAX_RANK]; + size_t jndx; + size_t type_size; + hid_t mem_space = H5I_INVALID_HID; + void *region_buf = NULL; + int ret_value = FAIL; + + UNUSED(ptdata); + + if (npoints < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_print_region_data_points: npoints < 0"); /* Allocate space for the dimension array */ - if((dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { + if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate dimension array buffer"); - dims1[0] = (hsize_t)npoints; + dims1[0] = (hsize_t)npoints; - /* Create dataspace for reading buffer */ - if((mem_space = H5Screate_simple(1, dims1, NULL)) >= 0) { + /* Create dataspace for reading buffer */ + if ((mem_space = H5Screate_simple(1, dims1, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if((type_size = H5Tget_size(type_id)) > 0) { + if (!(type_size = H5Tget_size(type_id))) + H5_LIBRARY_ERROR(ENVONLY); - if((region_buf = HDmalloc(type_size * (size_t)npoints)) != NULL) { + if (NULL == (region_buf = HDmalloc(type_size * (size_t)npoints))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_print_region_data_points: failed to allocate region buffer"); - if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) >= 0) { + if (H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); - for (jndx = 0; jndx < npoints; jndx++) { - if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) { + for (jndx = 0; jndx < (size_t) npoints; jndx++) { + if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); - h5str_sprintf(str, region_id, type_id, ((char*)region_buf + jndx * type_size), 0, 1); + if (!h5str_sprintf(ENVONLY, str, region_id, type_id, ((char *)region_buf + jndx * type_size), 0, 1)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (jndx + 1 < npoints) - h5str_append(str, ", "); + if (jndx + 1 < (size_t) npoints) + if (!h5str_append(str, ", ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } /* end for (jndx = 0; jndx < npoints; jndx++, elmtno++) */ - } /* end if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) */ - } /* end for (jndx = 0; jndx < npoints; jndx++, elmtno++) */ - } /* end if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) >= 0) */ - else - ret_value = -1; + ret_value = SUCCEED; - HDfree(region_buf); - } /* end if((region_buf = HDmalloc(type_size * (size_t)npoints)) != NULL) */ - else - ret_value = -1; - } /* end if((type_size = H5Tget_size(type_id)) > 0) */ - else - ret_value = -1; - - if(H5Sclose(mem_space) < 0) - ret_value = -1; - } /* end if((mem_space = H5Screate_simple(1, dims1, NULL)) >= 0) */ - else - ret_value = -1; +done: + if (region_buf) + HDfree(region_buf); + if (mem_space >= 0) + H5Sclose(mem_space); + if (dims1) HDfree(dims1); - } /* end if((dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; return ret_value; } /* end h5str_print_region_data_points */ int h5str_dump_region_points_data - (h5str_t *str, hid_t region, hid_t region_id) + (JNIEnv *env, h5str_t *str, hid_t region, hid_t region_id) { - int ret_value = 0; - hssize_t npoints; - hsize_t alloc_size; - hsize_t *ptdata; - hid_t dtype = -1; - hid_t type_id = -1; - int ndims = H5Sget_simple_extent_ndims(region); + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + hid_t dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + int ndims = -1; + int ret_value = FAIL; /* * This function fails if the region does not have points. @@ -1319,50 +1547,59 @@ h5str_dump_region_points_data npoints = H5Sget_select_elem_npoints(region); } H5E_END_TRY; + if (npoints < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((ndims = H5Sget_simple_extent_ndims(region)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + /* Print point information */ if (npoints > 0) { alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); if (alloc_size == (hsize_t)((size_t) alloc_size)) { - ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); - H5Sget_select_elem_pointlist(region, (hsize_t) 0, - (hsize_t) npoints, ptdata); + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points_data: failed to allocate region point data buffer"); - if((dtype = H5Dget_type(region_id)) >= 0) { - if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) { + if (H5Sget_select_elem_pointlist(region, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) + H5_LIBRARY_ERROR(ENVONLY); - h5str_print_region_data_points(region, region_id, - str, ndims, type_id, npoints, ptdata); + if ((dtype = H5Dget_type(region_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if(H5Tclose(type_id) < 0) - ret_value = -1; - } /* end if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) */ - else - ret_value = -1; - - if(H5Tclose(dtype) < 0) - ret_value = -1; - } /* end if((dtype = H5Dget_type(region_id)) >= 0) */ - else - ret_value = -1; - HDfree(ptdata); + if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (h5str_print_region_data_points(ENVONLY, region, region_id, + str, ndims, type_id, npoints, ptdata) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } } + ret_value = SUCCEED; + +done: + if (type_id >= 0) + H5Tclose(type_id); + if (dtype >= 0) + H5Tclose(dtype); + if (ptdata) + HDfree(ptdata); + return ret_value; } /* end h5str_dump_region_points_data */ static int h5str_dump_region_points - (h5str_t *str, hid_t region, hid_t region_id) + (JNIEnv *env, h5str_t *str, hid_t region, hid_t region_id) { - int ret_value = 0; - hssize_t npoints; - hsize_t alloc_size; - hsize_t *ptdata; - char tmp_str[256]; - hid_t dtype = -1; - hid_t type_id = -1; - int ndims = H5Sget_simple_extent_ndims(region); + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + char tmp_str[256]; + int ndims = -1; + int ret_value = FAIL; + + UNUSED(region_id); /* * This function fails if the region does not have points. @@ -1371,37 +1608,59 @@ h5str_dump_region_points npoints = H5Sget_select_elem_npoints(region); } H5E_END_TRY; + if (npoints < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((ndims = H5Sget_simple_extent_ndims(region)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + /* Print point information */ if (npoints > 0) { int i; alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); if (alloc_size == (hsize_t)((size_t) alloc_size)) { - ptdata = (hsize_t *)HDmalloc((size_t) alloc_size); - H5Sget_select_elem_pointlist(region, (hsize_t) 0, - (hsize_t) npoints, ptdata); + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t) alloc_size))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points: failed to allocate region point buffer"); + + if (H5Sget_select_elem_pointlist(region, (hsize_t) 0, (hsize_t) npoints, ptdata) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (!h5str_append(str, " {")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - h5str_append(str, " {"); for (i = 0; i < npoints; i++) { int j; - h5str_append(str, " "); + if (!h5str_append(str, " ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); for (j = 0; j < ndims; j++) { tmp_str[0] = '\0'; - sprintf(tmp_str, "%s%lu", j ? "," : "(", - (unsigned long) (ptdata[i * ndims + j])); - h5str_append(str, tmp_str); + + if (HDsprintf(tmp_str, "%s%lu", j ? "," : "(", + (unsigned long) (ptdata[i * ndims + j])) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_region_points: HDsprintf failure"); + + if (!h5str_append(str, tmp_str)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } /* end for (j = 0; j < ndims; j++) */ - h5str_append(str, ") "); + if (!h5str_append(str, ") ")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } /* end for (i = 0; i < npoints; i++) */ - h5str_append(str, " }"); - HDfree(ptdata); + if (!h5str_append(str, " }")) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); } /* end if (alloc_size == (hsize_t)((size_t) alloc_size)) */ } /* end if (npoints > 0) */ + ret_value = SUCCEED; + +done: + if (ptdata) + HDfree(ptdata); + return ret_value; } /* end h5str_dump_region_points */ @@ -1419,6 +1678,37 @@ h5str_is_zero } /* end h5str_is_zero */ /*------------------------------------------------------------------------- + * Function: h5str_detect_vlen + * + * Purpose: Recursive check for any variable length data in given type. + * + * Return: + * 1 : type contains any variable length data + * 0 : type doesn't contain any variable length data + * Negative value: error occurred + *------------------------------------------------------------------------- + */ +static htri_t +h5str_detect_vlen + (hid_t tid) +{ + htri_t ret = FAIL; + + /* Recursively detect any vlen data values in type (compound, array ...) */ + ret = H5Tdetect_class(tid, H5T_VLEN); + if ((ret == 1) || (ret < 0)) + goto done; + + /* Recursively detect any vlen string in type (compound, array ...) */ + ret = h5str_detect_vlen_str(tid); + if ((ret == 1) || (ret < 0)) + goto done; + +done: + return ret; +} /* end h5str_detect_vlen */ + +/*------------------------------------------------------------------------- * Function: h5str_detect_vlen_str * * Purpose: Recursive check for variable length string of a datatype. @@ -1459,12 +1749,10 @@ h5str_detect_vlen_str unsigned i = 0; int n = H5Tget_nmembers(tid); - if(n < 0) { - n = ret; + if (n < 0) goto done; - } /* end if */ - for(i = 0; i < n; i++) { + for(i = 0; i < (unsigned) n; i++) { hid_t mtid = H5Tget_member_type(tid, i); ret = h5str_detect_vlen_str(mtid); @@ -1494,15 +1782,18 @@ static hid_t h5str_get_native_type (hid_t type) { - hid_t p_type; H5T_class_t type_class; + hid_t p_type = H5I_INVALID_HID; + + if ((type_class = H5Tget_class(type)) < 0) + goto done; - type_class = H5Tget_class(type); - if(type_class==H5T_BITFIELD) - p_type=H5Tcopy(type); + if (type_class == H5T_BITFIELD) + p_type = H5Tcopy(type); else - p_type = H5Tget_native_type(type,H5T_DIR_DEFAULT); + p_type = H5Tget_native_type(type, H5T_DIR_DEFAULT); +done: return(p_type); } /* end h5str_get_native_type */ @@ -1520,73 +1811,89 @@ static hid_t h5str_get_little_endian_type (hid_t tid) { - hid_t p_type=-1; H5T_class_t type_class; - size_t size; H5T_sign_t sign; + size_t size; + hid_t p_type = H5I_INVALID_HID; - type_class = H5Tget_class(tid); - size = H5Tget_size(tid); - sign = H5Tget_sign(tid); + if ((type_class = H5Tget_class(tid)) < 0) + goto done; - switch( type_class ) - { - case H5T_INTEGER: - { - if ( size == 1 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I8LE); - else if ( size == 2 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I16LE); - else if ( size == 4 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I32LE); - else if ( size == 8 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I64LE); - else if ( size == 1 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U8LE); - else if ( size == 2 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U16LE); - else if ( size == 4 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U32LE); - else if ( size == 8 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U64LE); - } - break; + if (!(size = H5Tget_size(tid))) + goto done; - case H5T_FLOAT: - if ( size == 4) - p_type=H5Tcopy(H5T_IEEE_F32LE); - else if ( size == 8) - p_type=H5Tcopy(H5T_IEEE_F64LE); - break; + if ((sign = H5Tget_sign(tid)) < 0) + goto done; - case H5T_BITFIELD: - { - if ( size == 1) - p_type=H5Tcopy(H5T_STD_B8LE); - else if ( size == 2) - p_type=H5Tcopy(H5T_STD_B16LE); - else if ( size == 4) - p_type=H5Tcopy(H5T_STD_B32LE); - else if ( size == 8) - p_type=H5Tcopy(H5T_STD_B64LE); - } - break; + switch ( type_class ) { + case H5T_INTEGER: + { + if ( size == 1 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I8LE); + else if ( size == 2 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I16LE); + else if ( size == 4 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I32LE); + else if ( size == 8 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I64LE); + else if ( size == 1 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U8LE); + else if ( size == 2 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U16LE); + else if ( size == 4 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U32LE); + else if ( size == 8 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U64LE); + + break; + } + + case H5T_FLOAT: + { + if ( size == 4 ) + p_type = H5Tcopy(H5T_IEEE_F32LE); + else if ( size == 8 ) + p_type = H5Tcopy(H5T_IEEE_F64LE); - case H5T_TIME: - case H5T_OPAQUE: - case H5T_STRING: - case H5T_COMPOUND: - case H5T_REFERENCE: - case H5T_ENUM: - case H5T_VLEN: - case H5T_ARRAY: - break; + break; + } + + case H5T_BITFIELD: + { + if ( size == 1 ) + p_type = H5Tcopy(H5T_STD_B8LE); + else if ( size == 2 ) + p_type = H5Tcopy(H5T_STD_B16LE); + else if ( size == 4 ) + p_type = H5Tcopy(H5T_STD_B32LE); + else if ( size == 8 ) + p_type = H5Tcopy(H5T_STD_B64LE); + + break; + } - default: - break; + case H5T_NO_CLASS: + case H5T_NCLASSES: + { + goto done; + break; + } + case H5T_TIME: + case H5T_OPAQUE: + case H5T_STRING: + case H5T_COMPOUND: + case H5T_REFERENCE: + case H5T_ENUM: + case H5T_VLEN: + case H5T_ARRAY: + break; + + default: + break; } +done: return(p_type); } /* end h5str_get_little_endian_type */ @@ -1594,115 +1901,100 @@ h5str_get_little_endian_type * Function: h5str_get_big_endian_type * * Purpose: Get a big endian type from a file type - * - * Return: Success: datatype ID - * Failure: FAIL - *------------------------------------------------------------------------- - */ -static hid_t -h5str_get_big_endian_type - (hid_t tid) -{ - hid_t p_type=-1; - H5T_class_t type_class; - size_t size; - H5T_sign_t sign; - - type_class = H5Tget_class(tid); - size = H5Tget_size(tid); - sign = H5Tget_sign(tid); - - switch( type_class ) - { - case H5T_INTEGER: - { - if ( size == 1 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I8BE); - else if ( size == 2 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I16BE); - else if ( size == 4 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I32BE); - else if ( size == 8 && sign == H5T_SGN_2) - p_type=H5Tcopy(H5T_STD_I64BE); - else if ( size == 1 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U8BE); - else if ( size == 2 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U16BE); - else if ( size == 4 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U32BE); - else if ( size == 8 && sign == H5T_SGN_NONE) - p_type=H5Tcopy(H5T_STD_U64BE); - } - break; - - case H5T_FLOAT: - if ( size == 4) - p_type=H5Tcopy(H5T_IEEE_F32BE); - else if ( size == 8) - p_type=H5Tcopy(H5T_IEEE_F64BE); - break; - - case H5T_BITFIELD: - { - if ( size == 1) - p_type=H5Tcopy(H5T_STD_B8BE); - else if ( size == 2) - p_type=H5Tcopy(H5T_STD_B16BE); - else if ( size == 4) - p_type=H5Tcopy(H5T_STD_B32BE); - else if ( size == 8) - p_type=H5Tcopy(H5T_STD_B64BE); - } - break; - - case H5T_TIME: - case H5T_OPAQUE: - case H5T_STRING: - case H5T_COMPOUND: - case H5T_REFERENCE: - case H5T_ENUM: - case H5T_VLEN: - case H5T_ARRAY: - break; - - default: - break; - - } - - return(p_type); -} /* end h5str_get_big_endian_type */ - -/*------------------------------------------------------------------------- - * Function: h5str_detect_vlen - * - * Purpose: Recursive check for any variable length data in given type. - * - * Return: - * 1 : type conatains any variable length data - * 0 : type doesn't contain any variable length data - * Negative value: error occur + * + * Return: Success: datatype ID + * Failure: FAIL *------------------------------------------------------------------------- */ -static htri_t -h5str_detect_vlen +static hid_t +h5str_get_big_endian_type (hid_t tid) { - htri_t ret; + H5T_class_t type_class; + H5T_sign_t sign; + size_t size; + hid_t p_type = H5I_INVALID_HID; - /* recursive detect any vlen data values in type (compound, array ...) */ - ret = H5Tdetect_class(tid, H5T_VLEN); - if((ret == 1) || (ret < 0)) + if ((type_class = H5Tget_class(tid)) < 0) goto done; - /* recursive detect any vlen string in type (compound, array ...) */ - ret = h5str_detect_vlen_str(tid); - if((ret == 1) || (ret < 0)) + if (!(size = H5Tget_size(tid))) + goto done; + + if ((sign = H5Tget_sign(tid)) < 0) goto done; + switch ( type_class ) { + case H5T_INTEGER: + { + if ( size == 1 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I8BE); + else if ( size == 2 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I16BE); + else if ( size == 4 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I32BE); + else if ( size == 8 && sign == H5T_SGN_2 ) + p_type = H5Tcopy(H5T_STD_I64BE); + else if ( size == 1 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U8BE); + else if ( size == 2 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U16BE); + else if ( size == 4 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U32BE); + else if ( size == 8 && sign == H5T_SGN_NONE ) + p_type = H5Tcopy(H5T_STD_U64BE); + + break; + } + + case H5T_FLOAT: + { + if ( size == 4 ) + p_type = H5Tcopy(H5T_IEEE_F32BE); + else if ( size == 8 ) + p_type = H5Tcopy(H5T_IEEE_F64BE); + + break; + } + + case H5T_BITFIELD: + { + if ( size == 1 ) + p_type = H5Tcopy(H5T_STD_B8BE); + else if ( size == 2 ) + p_type = H5Tcopy(H5T_STD_B16BE); + else if ( size == 4 ) + p_type = H5Tcopy(H5T_STD_B32BE); + else if ( size == 8 ) + p_type = H5Tcopy(H5T_STD_B64BE); + + break; + } + + case H5T_NO_CLASS: + case H5T_NCLASSES: + { + goto done; + break; + } + + case H5T_TIME: + case H5T_OPAQUE: + case H5T_STRING: + case H5T_COMPOUND: + case H5T_REFERENCE: + case H5T_ENUM: + case H5T_VLEN: + case H5T_ARRAY: + break; + + default: + break; + } + done: - return ret; -} /* end h5str_detect_vlen */ + return(p_type); +} /* end h5str_get_big_endian_type */ /*------------------------------------------------------------------------- * Function: render_bin_output @@ -1717,201 +2009,261 @@ static int h5str_render_bin_output (FILE *stream, hid_t container, hid_t tid, void *_mem, hsize_t block_nelmts) { - int ret_value = 0; - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - hsize_t block_index; - H5T_class_t type_class; - - if((size = H5Tget_size(tid)) > 0) { - - if((type_class = H5Tget_class(tid)) >= 0) { - - switch (type_class) { - case H5T_INTEGER: - case H5T_FLOAT: - case H5T_ENUM: - block_index = block_nelmts * size; - while(block_index > 0) { - size_t bytes_in = 0; /* # of bytes to write */ - size_t bytes_wrote = 0; /* # of bytes written */ - size_t item_size = size; /* size of items in bytes */ - - if(block_index > sizeof(size_t)) - bytes_in = sizeof(size_t); - else - bytes_in = (size_t)block_index; + unsigned char *mem = (unsigned char*)_mem; + H5T_class_t type_class; + hsize_t block_index; + size_t size; /* datum size */ + int ret_value = 0; + + if (!(size = H5Tget_size(tid))) { + ret_value = FAIL; + goto done; + } + + if ((type_class = H5Tget_class(tid)) < 0) { + ret_value = FAIL; + goto done; + } - bytes_wrote = fwrite(mem, 1, bytes_in, stream); + switch (type_class) { + case H5T_INTEGER: + case H5T_FLOAT: + case H5T_ENUM: + { + block_index = block_nelmts * size; + while (block_index > 0) { + size_t bytes_in = 0; /* # of bytes to write */ + size_t bytes_wrote = 0; /* # of bytes written */ - if(bytes_wrote != bytes_in || (0 == bytes_wrote && ferror(stream))) { - ret_value = -1; - break; - } + if (block_index > sizeof(size_t)) + bytes_in = sizeof(size_t); + else + bytes_in = (size_t)block_index; - block_index -= (hsize_t)bytes_wrote; - mem = mem + bytes_wrote; - } + bytes_wrote = fwrite(mem, 1, bytes_in, stream); + + if (bytes_wrote != bytes_in || (0 == bytes_wrote && ferror(stream))) { + ret_value = FAIL; break; - case H5T_STRING: - { - unsigned int i; - H5T_str_t pad; - char *s; - unsigned char tempuchar; + } - pad = H5Tget_strpad(tid); + block_index -= (hsize_t)bytes_wrote; + mem = mem + bytes_wrote; + } - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; + break; + } - if (H5Tis_variable_str(tid)) { - s = *(char**) mem; - if (s != NULL) - size = HDstrlen(s); - } - else { - s = (char *) mem; - } - for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { - HDmemcpy(&tempuchar, &s[i], sizeof(unsigned char)); - if (1 != fwrite(&tempuchar, sizeof(unsigned char), 1, stream)) { - ret_value = -1; - break; - } - } /* i */ - if(ret_value < 0) - break; - } /* for (block_index = 0; block_index < block_nelmts; block_index++) */ + case H5T_STRING: + { + unsigned char tempuchar; + unsigned int i; + H5T_str_t pad; + char *s; + + if ((pad = H5Tget_strpad(tid)) < 0) { + ret_value = FAIL; + goto done; + } + + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char *)_mem) + block_index * size; + + if (H5Tis_variable_str(tid)) { + s = *(char**) mem; + if (s != NULL) + size = HDstrlen(s); } - break; - case H5T_COMPOUND: - { - unsigned j; - hid_t memb; - unsigned nmembs; - size_t offset; - - nmembs = (unsigned)H5Tget_nmembers(tid); - - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; - for (j = 0; j < nmembs; j++) { - offset = H5Tget_member_offset(tid, j); - memb = H5Tget_member_type(tid, j); - - if (h5str_render_bin_output(stream, container, memb, mem + offset, 1) < 0) { - H5Tclose(memb); - ret_value = -1; - break; - } - - H5Tclose(memb); - } - if(ret_value < 0) - break; - } + else { + s = (char *) mem; } - break; - case H5T_ARRAY: - { - int k, ndims; - hsize_t dims[H5S_MAX_RANK], temp_nelmts, nelmts; - hid_t memb; - - /* get the array's base datatype for each element */ - memb = H5Tget_super(tid); - ndims = H5Tget_array_ndims(tid); - H5Tget_array_dims2(tid, dims); - - /* calculate the number of array elements */ - for (k = 0, nelmts = 1; k < ndims; k++) { - temp_nelmts = nelmts; - temp_nelmts *= dims[k]; - nelmts = (size_t) temp_nelmts; + for (i = 0; i < size && (s[i] || pad != H5T_STR_NULLTERM); i++) { + HDmemcpy(&tempuchar, &s[i], sizeof(unsigned char)); + if (1 != fwrite(&tempuchar, sizeof(unsigned char), 1, stream)) { + ret_value = FAIL; + break; } + } /* i */ + if (ret_value < 0) + break; + } /* for (block_index = 0; block_index < block_nelmts; block_index++) */ - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; - /* dump the array element */ - if (h5str_render_bin_output(stream, container, memb, mem, nelmts) < 0) { - ret_value = -1; - break; - } + break; + } + + case H5T_COMPOUND: + { + unsigned j; + size_t offset; + hid_t memb = H5I_INVALID_HID; + int nmembs; + + if ((nmembs = H5Tget_nmembers(tid)) < 0) { + ret_value = FAIL; + goto done; + } + + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char*)_mem) + block_index * size; + for (j = 0; j < (unsigned) nmembs; j++) { + offset = H5Tget_member_offset(tid, j); + memb = H5Tget_member_type(tid, j); + + if (h5str_render_bin_output(stream, container, memb, mem + offset, 1) < 0) { + H5Tclose(memb); + ret_value = FAIL; + break; } + H5Tclose(memb); } - break; - case H5T_VLEN: - { - hsize_t nelmts; - hid_t memb; - /* get the VL sequences's base datatype for each element */ - memb = H5Tget_super(tid); + if (ret_value < 0) + break; + } + + break; + } - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; - /* Get the number of sequence elements */ - nelmts = ((hvl_t *) mem)->len; + case H5T_ARRAY: + { + hsize_t dims[H5S_MAX_RANK], temp_nelmts, nelmts; + hid_t memb; + int k, ndims; - /* dump the array element */ - if (h5str_render_bin_output(stream, container, memb, ((char *) (((hvl_t *) mem)->p)), nelmts) < 0) { - ret_value = -1; - break; - } - } - H5Tclose(memb); + /* Get the array's base datatype for each element */ + if ((memb = H5Tget_super(tid)) < 0) { + ret_value = FAIL; + goto done; + } + + if ((ndims = H5Tget_array_ndims(tid)) < 0) { + ret_value = FAIL; + goto done; + } + + if (H5Tget_array_dims2(tid, dims) < 0) { + ret_value = FAIL; + goto done; + } + + /* Calculate the number of array elements */ + for (k = 0, nelmts = 1; k < ndims; k++) { + temp_nelmts = nelmts; + temp_nelmts *= dims[k]; + nelmts = (size_t) temp_nelmts; + } + + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char*)_mem) + block_index * size; + + /* dump the array element */ + if (h5str_render_bin_output(stream, container, memb, mem, nelmts) < 0) { + ret_value = FAIL; + break; } - break; - case H5T_REFERENCE: - { - if (H5Tequal(tid, H5T_STD_REF_DSETREG)) { - /* region data */ - hid_t region_id, region_space; - H5S_sel_type region_type; - - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; - region_id = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, mem); - if (region_id >= 0) { - region_space = H5Rget_region(container, H5R_DATASET_REGION, mem); - if (region_space >= 0) { - region_type = H5Sget_select_type(region_space); - if(region_type == H5S_SEL_POINTS) - ret_value = render_bin_output_region_points(stream, region_space, region_id, container); - else - ret_value = render_bin_output_region_blocks(stream, region_space, region_id, container); - H5Sclose(region_space); - } /* end if (region_space >= 0) */ - H5Dclose(region_id); - } /* end if (region_id >= 0) */ - if(ret_value < 0) - break; - } + } + + H5Tclose(memb); + + break; + } + + case H5T_VLEN: + { + hsize_t nelmts; + hid_t memb; + + /* Get the VL sequences's base datatype for each element */ + if ((memb = H5Tget_super(tid)) < 0) { + ret_value = FAIL; + goto done; + } + + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char*)_mem) + block_index * size; + + /* Get the number of sequence elements */ + nelmts = ((hvl_t *) mem)->len; + + /* dump the array element */ + if (h5str_render_bin_output(stream, container, memb, ((char *) (((hvl_t *) mem)->p)), nelmts) < 0) { + ret_value = FAIL; + break; + } + } + + H5Tclose(memb); + + break; + } + + case H5T_REFERENCE: + { + if (H5Tequal(tid, H5T_STD_REF_DSETREG)) { + H5S_sel_type region_type; + hid_t region_id, region_space; + + /* Region data */ + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char*)_mem) + block_index * size; + + if ((region_id = H5Rdereference2(container, H5P_DEFAULT, H5R_DATASET_REGION, mem)) < 0) + continue; + + if ((region_space = H5Rget_region(container, H5R_DATASET_REGION, mem)) < 0) { + H5Dclose(region_id); + continue; } - else if (H5Tequal(tid, H5T_STD_REF_OBJ)) { - ; + + if ((region_type = H5Sget_select_type(region_space)) < 0) { + H5Sclose(region_space); + H5Dclose(region_id); + continue; } + + if (region_type == H5S_SEL_POINTS) + ret_value = render_bin_output_region_points(stream, region_space, region_id, container); + else + ret_value = render_bin_output_region_blocks(stream, region_space, region_id, container); + + H5Sclose(region_space); + H5Dclose(region_id); + + if (ret_value < 0) + break; } - break; - default: - for (block_index = 0; block_index < block_nelmts; block_index++) { - mem = ((unsigned char*)_mem) + block_index * size; - if (size != fwrite(mem, sizeof(char), size, stream)) { - ret_value = -1; - break; - } - } + } + else if (H5Tequal(tid, H5T_STD_REF_OBJ)) { + ; + } + + break; + } + + case H5T_NO_CLASS: + case H5T_NCLASSES: + { + ret_value = FAIL; + goto done; + break; + } + + case H5T_TIME: + case H5T_BITFIELD: + case H5T_OPAQUE: + default: + for (block_index = 0; block_index < block_nelmts; block_index++) { + mem = ((unsigned char*)_mem) + block_index * size; + if (size != fwrite(mem, sizeof(char), size, stream)) { + ret_value = FAIL; break; + } } - } /* end if((type_class = H5Tget_class(tid)) >= 0) */ - else - ret_value = -1; - } /* end if((size = H5Tget_size(tid)) > 0) */ - else - ret_value = -1; + break; + } +done: return ret_value; } /* end h5str_render_bin_output */ @@ -1930,96 +2282,107 @@ static int render_bin_output_region_data_blocks (FILE *stream, hid_t region_id, hid_t container, int ndims, hid_t type_id, hssize_t nblocks, hsize_t *ptdata) { - hsize_t *dims1 = NULL; - hsize_t *start = NULL; - hsize_t *count = NULL; - hsize_t numelem; - hsize_t total_size[H5S_MAX_RANK]; - int jndx; - size_t type_size; - hid_t mem_space = -1; - void *region_buf = NULL; - int blkndx; - hid_t sid1 = -1; - int ret_value = SUCCEED; + hsize_t *dims1 = NULL; + hsize_t *start = NULL; + hsize_t *count = NULL; + hsize_t numelem; + hsize_t total_size[H5S_MAX_RANK]; + size_t type_size; + hid_t sid1 = H5I_INVALID_HID; + hid_t mem_space = H5I_INVALID_HID; + void *region_buf = NULL; + int blkndx; + int jndx; + int ret_value = SUCCEED; /* Get the dataspace of the dataset */ - if((sid1 = H5Dget_space(region_id)) >= 0) { - /* Allocate space for the dimension array */ - if((dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - /* find the dimensions of each data space from the block coordinates */ - numelem = 1; - for (jndx = 0; jndx < ndims; jndx++) { - dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1; - numelem = dims1[jndx] * numelem; - } + if ((sid1 = H5Dget_space(region_id)) < 0) { + ret_value = FAIL; + goto done; + } - /* Create dataspace for reading buffer */ - if((mem_space = H5Screate_simple(ndims, dims1, NULL)) >= 0) { - if((type_size = H5Tget_size(type_id)) > 0) { - if((region_buf = HDmalloc(type_size * (size_t)numelem)) != NULL) { - /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ - /* 1 2 n 1 2 n */ - if((start = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - if((count = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - for (blkndx = 0; blkndx < nblocks; blkndx++) { - for (jndx = 0; jndx < ndims; jndx++) { - start[jndx] = ptdata[jndx + blkndx * ndims * 2]; - count[jndx] = dims1[jndx]; - } - - if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) >= 0) { - if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) >= 0) { - if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) { - ret_value = h5str_render_bin_output(stream, container, type_id, (char*)region_buf, numelem); - } /* end if(H5Sget_simple_extent_dims(mem_space, total_size, NULL) >= 0) */ - else { - ret_value = -1; - break; - } - } /* end if(H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) >= 0) */ - else { - ret_value = -1; - break; - } - } /* end if(H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) >= 0) */ - else { - ret_value = -1; - break; - } - /* Render the region data element end */ - } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ - - HDfree(count); - } /* end if((count = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - HDfree(start); - } /* end if((start = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - HDfree(region_buf); - } /* end if((region_buf = HDmalloc(type_size * (size_t)numelem)) != NULL) */ - else - ret_value = -1; - } /* end if((type_size = H5Tget_size(type_id)) > 0) */ - else - ret_value = -1; - - if(H5Sclose(mem_space) < 0) - ret_value = -1; - } /* end if((mem_space = H5Screate_simple(ndims, dims1, NULL)) >= 0) */ - else - ret_value = -1; - HDfree(dims1); - } /* end if((dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - if(H5Sclose(sid1) < 0) - ret_value = -1; - } /* end if((sid1 = H5Dget_space(region_id)) >= 0) */ - else - ret_value = -1; + /* Allocate space for the dimension array */ + if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) { + ret_value = FAIL; + goto done; + } + + /* Find the dimensions of each data space from the block coordinates */ + for (jndx = 0, numelem = 1; jndx < ndims; jndx++) { + dims1[jndx] = ptdata[jndx + ndims] - ptdata[jndx] + 1; + numelem = dims1[jndx] * numelem; + } + + /* Create dataspace for reading buffer */ + if ((mem_space = H5Screate_simple(ndims, dims1, NULL)) < 0) { + ret_value = FAIL; + goto done; + } + + if (!(type_size = H5Tget_size(type_id))) { + ret_value = FAIL; + goto done; + } + + if (NULL == (region_buf = HDmalloc(type_size * (size_t)numelem))) { + ret_value = FAIL; + goto done; + } + + /* Select (x , x , ..., x ) x (y , y , ..., y ) hyperslab for reading memory dataset */ + /* 1 2 n 1 2 n */ + if (NULL == (start = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) { + ret_value = FAIL; + goto done; + } + + if (NULL == (count = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) { + ret_value = FAIL; + goto done; + } + + for (blkndx = 0; blkndx < nblocks; blkndx++) { + for (jndx = 0; jndx < ndims; jndx++) { + start[jndx] = ptdata[jndx + blkndx * ndims * 2]; + count[jndx] = dims1[jndx]; + } + + if (H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL) < 0) { + ret_value = FAIL; + goto done; + } + + if (H5Dread(region_id, type_id, mem_space, sid1, H5P_DEFAULT, region_buf) < 0) { + ret_value = FAIL; + goto done; + } + + if (H5Sget_simple_extent_dims(mem_space, total_size, NULL) < 0) { + ret_value = FAIL; + goto done; + } + + if (h5str_render_bin_output(stream, container, type_id, (char *)region_buf, numelem) < 0) { + ret_value = FAIL; + goto done; + } + + /* Render the region data element end */ + } /* end for (blkndx = 0; blkndx < nblocks; blkndx++) */ + +done: + if (count) + HDfree(count); + if (start) + HDfree(start); + if (region_buf) + HDfree(region_buf); + if (mem_space >= 0) + H5Sclose(mem_space); + if (dims1) + HDfree(dims1); + if (sid1 >= 0) + H5Sclose(sid1); return ret_value; } /* end render_bin_output_region_data_blocks */ @@ -2039,50 +2402,62 @@ static int render_bin_output_region_blocks (FILE *stream, hid_t region_space, hid_t region_id, hid_t container) { - int ret_value = SUCCEED; - hssize_t nblocks; - hsize_t alloc_size; - hsize_t *ptdata = NULL; - int ndims; - hid_t dtype; - hid_t type_id; - - if((nblocks = H5Sget_select_hyper_nblocks(region_space)) > 0) { + hssize_t nblocks; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + hid_t dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + int ndims; + int ret_value = SUCCEED; + + if ((nblocks = H5Sget_select_hyper_nblocks(region_space)) < 0) { + ret_value = FAIL; + goto done; + } + + if (nblocks > 0) { /* Print block information */ - if((ndims = H5Sget_simple_extent_ndims(region_space)) >= 0) { - alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); - if((ptdata = (hsize_t*)HDmalloc((size_t)alloc_size)) != NULL) { - if(H5Sget_select_hyper_blocklist(region_space, (hsize_t)0, (hsize_t)nblocks, ptdata) >= 0) { - if((dtype = H5Dget_type(region_id)) >= 0) { - if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) { - ret_value = render_bin_output_region_data_blocks(stream, region_id, container, ndims, - type_id, nblocks, ptdata); - - if(H5Tclose(type_id) < 0) - ret_value = -1; - } /* end if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) */ - else - ret_value = -1; + if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) { + ret_value = FAIL; + goto done; + } - if(H5Tclose(dtype) < 0) - ret_value = -1; - } /* end if((dtype = H5Dget_type(region_id)) >= 0) */ - else - ret_value = -1; - } /* end if(H5Sget_select_hyper_blocklist(region_space, (hsize_t) 0, (hsize_t) nblocks, ptdata) >= 0) */ - else - ret_value = -1; - - HDfree(ptdata); - } /* end if((ptdata = (hsize_t*) HDmalloc((size_t) alloc_size)) != NULL) */ - else - ret_value = -1; - } /* end if((ndims = H5Sget_simple_extent_ndims(region_space)) >= 0) */ - else - ret_value = -1; - } /* end if((nblocks = H5Sget_select_hyper_nblocks(region_space)) > 0) */ - else - ret_value = -1; + alloc_size = (hsize_t)nblocks * (hsize_t)ndims * 2 * (hsize_t)sizeof(ptdata[0]); + + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t)alloc_size))) { + ret_value = FAIL; + goto done; + } + + if (H5Sget_select_hyper_blocklist(region_space, (hsize_t)0, (hsize_t)nblocks, ptdata) < 0) { + ret_value = FAIL; + goto done; + } + + if ((dtype = H5Dget_type(region_id)) < 0) { + ret_value = FAIL; + goto done; + } + + if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) { + ret_value = FAIL; + goto done; + } + + if (render_bin_output_region_data_blocks(stream, region_id, container, + ndims, type_id, nblocks, ptdata) < 0) { + ret_value = FAIL; + goto done; + } + } + +done: + if (type_id >= 0) + H5Tclose(type_id); + if (dtype >= 0) + H5Tclose(dtype); + if (ptdata) + HDfree(ptdata); return ret_value; } /* end render_bin_output_region_blocks */ @@ -2105,43 +2480,57 @@ render_bin_output_region_data_points { hsize_t *dims1 = NULL; size_t type_size; - hid_t mem_space = -1; + hid_t mem_space = H5I_INVALID_HID; void *region_buf = NULL; int ret_value = SUCCEED; - if((type_size = H5Tget_size(type_id)) > 0) { - if((region_buf = HDmalloc(type_size * (size_t)npoints)) != NULL) { - /* Allocate space for the dimension array */ - if((dims1 = (hsize_t *)HDmalloc(sizeof(hsize_t) * (size_t)ndims)) != NULL) { - dims1[0] = (hsize_t)npoints; - if((mem_space = H5Screate_simple(1, dims1, NULL)) >= 0) { - if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) >= 0) { - if(H5Sget_simple_extent_dims(region_space, dims1, NULL) >= 0) { - ret_value = h5str_render_bin_output(stream, container, type_id, (char*)region_buf, (hsize_t)npoints); - } /* end if(H5Sget_simple_extent_dims(region_space, dims1, NULL) >= 0) */ - else - ret_value = -1; - } /* end if(H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) >= 0) */ - else - ret_value = -1; - } /* end if((mem_space = H5Screate_simple(1, dims1, NULL)) >= 0) */ - else - ret_value = -1; - - HDfree(dims1); - } /* end if((dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * ndims)) != NULL) */ - else - ret_value = -1; - HDfree(region_buf); - } /* end if((region_buf = HDmalloc(type_size * (size_t)npoints)) != NULL) */ - else - ret_value = -1; - - if(H5Sclose(mem_space) < 0) - ret_value = -1; - } /* end if((type_size = H5Tget_size(type_id)) > 0) */ - else - ret_value = -1; + UNUSED(ptdata); + + if (!(type_size = H5Tget_size(type_id))) { + ret_value = FAIL; + goto done; + } + + if (NULL == (region_buf = HDmalloc(type_size * (size_t)npoints))) { + ret_value = FAIL; + goto done; + } + + /* Allocate space for the dimension array */ + if (NULL == (dims1 = (hsize_t *) HDmalloc(sizeof(hsize_t) * (size_t)ndims))) { + ret_value = FAIL; + goto done; + } + + dims1[0] = (hsize_t)npoints; + + if ((mem_space = H5Screate_simple(1, dims1, NULL)) < 0) { + ret_value = FAIL; + goto done; + } + + if (H5Dread(region_id, type_id, mem_space, region_space, H5P_DEFAULT, region_buf) < 0) { + ret_value = FAIL; + goto done; + } + + if (H5Sget_simple_extent_dims(region_space, dims1, NULL) < 0) { + ret_value = FAIL; + goto done; + } + + if (h5str_render_bin_output(stream, container, type_id, (char *)region_buf, (hsize_t)npoints) < 0) { + ret_value = FAIL; + goto done; + } + +done: + if (dims1) + HDfree(dims1); + if (mem_space >= 0) + H5Sclose(mem_space); + if (region_buf) + HDfree(region_buf); return ret_value; } /* end render_bin_output_region_data_points */ @@ -2161,248 +2550,343 @@ static int render_bin_output_region_points (FILE *stream, hid_t region_space, hid_t region_id, hid_t container) { - int ret_value = SUCCEED; - hssize_t npoints; - hsize_t alloc_size; - hsize_t *ptdata; - int ndims; - hid_t dtype; - hid_t type_id; - - if((npoints = H5Sget_select_elem_npoints(region_space)) > 0) { + hssize_t npoints; + hsize_t alloc_size; + hsize_t *ptdata = NULL; + hid_t dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + int ndims; + int ret_value = SUCCEED; + + if ((npoints = H5Sget_select_elem_npoints(region_space)) < 0) { + ret_value = FAIL; + goto done; + } + + if (npoints > 0) { /* Allocate space for the dimension array */ - if((ndims = H5Sget_simple_extent_ndims(region_space)) >= 0) { - alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); - if(NULL != (ptdata = (hsize_t *)HDmalloc((size_t)alloc_size))) { - if(H5Sget_select_elem_pointlist(region_space, (hsize_t)0, (hsize_t)npoints, ptdata) >= 0) { - if((dtype = H5Dget_type(region_id)) >= 0) { - if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) { - ret_value = render_bin_output_region_data_points(stream, region_space, region_id, - container, ndims, type_id, npoints, ptdata); - - if(H5Tclose(type_id) < 0) - ret_value = -1; - } /* end if((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) >= 0) */ - else - ret_value = -1; + if ((ndims = H5Sget_simple_extent_ndims(region_space)) < 0) { + ret_value = FAIL; + goto done; + } - if(H5Tclose(dtype) < 0) - ret_value = -1; - } /* end if((dtype = H5Dget_type(region_id)) >= 0) */ - else - ret_value = -1; - } /* end if(H5Sget_select_elem_pointlist(region_space, (hsize_t) 0, (hsize_t) npoints, ptdata) >= 0) */ - else - ret_value = -1; + alloc_size = (hsize_t)npoints * (hsize_t)ndims * (hsize_t)sizeof(ptdata[0]); - HDfree(ptdata); - } /* end if(NULL != (ptdata = (hsize_t *)HDmalloc((size_t) alloc_size))) */ - else - ret_value = -1; - } /* end if((ndims = H5Sget_simple_extent_ndims(region_space)) >= 0) */ - else - ret_value = -1; + if (NULL == (ptdata = (hsize_t *) HDmalloc((size_t)alloc_size))) { + ret_value = FAIL; + goto done; + } - } /* end if((npoints = H5Sget_select_elem_npoints(region_space)) > 0) */ - else - ret_value = -1; + if (H5Sget_select_elem_pointlist(region_space, (hsize_t)0, (hsize_t)npoints, ptdata) < 0) { + ret_value = FAIL; + goto done; + } + + if ((dtype = H5Dget_type(region_id)) < 0) { + ret_value = FAIL; + goto done; + } + + if ((type_id = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) { + ret_value = FAIL; + goto done; + } + + if (render_bin_output_region_data_points(stream, region_space, region_id, + container, ndims, type_id, npoints, ptdata) < 0) { + ret_value = FAIL; + goto done; + } + } + +done: + if (type_id >= 0) + H5Tclose(type_id); + if (dtype >= 0) + H5Tclose(dtype); + if (ptdata) + HDfree(ptdata); return ret_value; } /* end render_bin_output_region_points */ int h5str_dump_simple_dset - (FILE *stream, hid_t dset, int binary_order) + (JNIEnv *env, FILE *stream, hid_t dset, int binary_order) { - int ret_value = SUCCEED; - hid_t f_space = -1; /* file data space */ - hsize_t elmtno; /* counter */ - size_t i; /* counter */ - int ndims; - int carry; /* counter carry value */ - hsize_t zero[8]; /* vector of zeros */ - hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ + hsize_t elmtno; /* counter */ + hsize_t zero[8]; /* vector of zeros */ + hsize_t total_size[H5S_MAX_RANK]; /* total size of dataset*/ + size_t i; /* counter */ + hid_t f_space = H5I_INVALID_HID; /* file data space */ + int ndims; + int carry; /* counter carry value */ /* Print info */ - size_t p_type_nbytes; /* size of memory type */ - hsize_t p_nelmts; /* total selected elmts */ + hsize_t p_nelmts; /* total selected elmts */ + size_t p_type_nbytes; /* size of memory type */ /* Stripmine info */ - hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ - hsize_t sm_nbytes; /* bytes per stripmine */ - hsize_t sm_nelmts; /* elements per stripmine*/ - unsigned char *sm_buf = NULL; /* buffer for raw data */ - hid_t sm_space = -1; /* stripmine data space */ + unsigned char *sm_buf = NULL; /* buffer for raw data */ + hsize_t sm_size[H5S_MAX_RANK]; /* stripmine size */ + hsize_t sm_nbytes; /* bytes per stripmine */ + hsize_t sm_nelmts; /* elements per stripmine */ + hid_t sm_space = H5I_INVALID_HID; /* stripmine data space */ /* Hyperslab info */ - hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ - hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ - hsize_t hs_nelmts; /* elements in request */ + hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ + hsize_t hs_size[H5S_MAX_RANK]; /* size this pass */ + hsize_t hs_nelmts; /* elements in request */ /* VL data special information */ - unsigned int vl_data = 0; /* contains VL datatypes */ - hid_t p_type = -1; - hid_t f_type = -1; - - if(dset < 0) return -1; - f_type = H5Dget_type(dset); - if (binary_order == 1) - p_type = h5str_get_native_type(f_type); - else if (binary_order == 2) - p_type = h5str_get_little_endian_type(f_type); - else if (binary_order == 3) - p_type = h5str_get_big_endian_type(f_type); - else - p_type = H5Tcopy(f_type); + unsigned int vl_data = 0; /* contains VL datatypes */ + hid_t p_type = H5I_INVALID_HID; + hid_t f_type = H5I_INVALID_HID; - H5Tclose(f_type); + int ret_value = FAIL; - if (p_type >= 0) { - if((f_space = H5Dget_space(dset)) >= 0) { - ndims = H5Sget_simple_extent_ndims(f_space); + if (dset < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "h5str_dump_simple_dset: dset ID < 0"); - if ((size_t)ndims <= (sizeof(sm_size)/sizeof(sm_size[0]))) { - H5Sget_simple_extent_dims(f_space, total_size, NULL); + if ((f_type = H5Dget_type(dset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - /* calculate the number of elements we're going to print */ - p_nelmts = 1; + switch (binary_order) { + case 1: + { + if ((p_type = h5str_get_native_type(f_type)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + break; + } + + case 2: + { + if ((p_type = h5str_get_little_endian_type(f_type)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + break; + } + + case 3: + { + if ((p_type = h5str_get_big_endian_type(f_type)) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + break; + } + + default: + { + if ((p_type = H5Tcopy(f_type)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + break; + } + } - if (ndims > 0) { - for (i = 0; i < ndims; i++) - p_nelmts *= total_size[i]; - } /* end if */ + if ((f_space = H5Dget_space(dset)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (p_nelmts > 0) { - /* Check if we have VL data in the dataset's datatype */ - if (h5str_detect_vlen(p_type) != 0) - vl_data = 1; + if ((ndims = H5Sget_simple_extent_ndims(f_space)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - /* - * Determine the strip mine size and allocate a buffer. The strip mine is - * a hyperslab whose size is manageable. - */ - sm_nbytes = p_type_nbytes = H5Tget_size(p_type); + if ((size_t)ndims <= (sizeof(sm_size) / sizeof(sm_size[0]))) { + if (H5Sget_simple_extent_dims(f_space, total_size, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + /* Calculate the number of elements we're going to print */ + p_nelmts = 1; + + if (ndims > 0) { + for (i = 0; i < (size_t) ndims; i++) + p_nelmts *= total_size[i]; + } /* end if */ + + if (p_nelmts > 0) { + /* Check if we have VL data in the dataset's datatype */ + if (h5str_detect_vlen(p_type) != 0) + vl_data = 1; + + /* + * Determine the strip mine size and allocate a buffer. The strip mine is + * a hyperslab whose size is manageable. + */ + if (!(sm_nbytes = p_type_nbytes = H5Tget_size(p_type))) + H5_LIBRARY_ERROR(ENVONLY); + + if (ndims > 0) { + for (i = (size_t)ndims; i > 0; --i) { + hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; + if ( size == 0 ) /* datum size > H5TOOLS_BUFSIZE */ + size = 1; + sm_size[i - 1] = (((total_size[i - 1]) < (size)) ? (total_size[i - 1]) : (size)); + sm_nbytes *= sm_size[i - 1]; + } + } + + if (sm_nbytes > 0) { + if (NULL == (sm_buf = (unsigned char *) HDmalloc((size_t)sm_nbytes))) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_dset: failed to allocate sm_buf"); + + sm_nelmts = sm_nbytes / p_type_nbytes; + + if ((sm_space = H5Screate_simple(1, &sm_nelmts, NULL)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + /* The stripmine loop */ + HDmemset(hs_offset, 0, sizeof hs_offset); + HDmemset(zero, 0, sizeof zero); + + for (elmtno = 0; elmtno < p_nelmts; elmtno += hs_nelmts) { + /* Calculate the hyperslab size */ if (ndims > 0) { - for (i = (size_t)ndims; i > 0; --i) { - hsize_t size = H5TOOLS_BUFSIZE / sm_nbytes; - if ( size == 0) /* datum size > H5TOOLS_BUFSIZE */ - size = 1; - sm_size[i - 1] = (((total_size[i - 1]) < (size)) ? (total_size[i - 1]) : (size)); - sm_nbytes *= sm_size[i - 1]; + for (i = 0, hs_nelmts = 1; i < (size_t) ndims; i++) { + hs_size[i] = (((total_size[i] - hs_offset[i]) < (sm_size[i])) ? (total_size[i] - hs_offset[i]) : (sm_size[i])); + hs_nelmts *= hs_size[i]; } + + if (H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL) < 0) + H5_LIBRARY_ERROR(ENVONLY); } + else { + if (H5Sselect_all(f_space) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if(sm_nbytes > 0) { - sm_buf = (unsigned char *)HDmalloc((size_t)sm_nbytes); - - sm_nelmts = sm_nbytes / p_type_nbytes; - sm_space = H5Screate_simple(1, &sm_nelmts, NULL); - - /* The stripmine loop */ - HDmemset(hs_offset, 0, sizeof hs_offset); - HDmemset(zero, 0, sizeof zero); - - for (elmtno = 0; elmtno < p_nelmts; elmtno += hs_nelmts) { - /* Calculate the hyperslab size */ - if (ndims > 0) { - for (i = 0, hs_nelmts = 1; i < ndims; i++) { - hs_size[i] = (((total_size[i] - hs_offset[i]) < (sm_size[i])) ? (total_size[i] - hs_offset[i]) : (sm_size[i])); - hs_nelmts *= hs_size[i]; - } - - H5Sselect_hyperslab(f_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL); - H5Sselect_hyperslab(sm_space, H5S_SELECT_SET, zero, NULL, &hs_nelmts, NULL); - } - else { - H5Sselect_all(f_space); - H5Sselect_all(sm_space); - hs_nelmts = 1; - } - - /* Read the data */ - if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) >= 0) { - - if (binary_order == 99) - ret_value = h5tools_dump_simple_data(stream, dset, p_type, sm_buf, hs_nelmts); - else - ret_value = h5str_render_bin_output(stream, dset, p_type, sm_buf, hs_nelmts); - - /* Reclaim any VL memory, if necessary */ - if (vl_data) - H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); - } - else { - ret_value = -1; - break; - } - - if(ret_value < 0) break; - - /* Calculate the next hyperslab offset */ - for (i = (size_t)ndims, carry = 1; i > 0 && carry; --i) { - hs_offset[i - 1] += hs_size[i - 1]; - - if (hs_offset[i - 1] == total_size[i - 1]) - hs_offset[i - 1] = 0; - else - carry = 0; - } - } + if (H5Sselect_all(sm_space) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + hs_nelmts = 1; + } - if(sm_buf) - HDfree(sm_buf); + /* Read the data */ + if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (binary_order == 99) { + if (h5tools_dump_simple_data(ENVONLY, stream, dset, p_type, sm_buf, hs_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + else { + if (h5str_render_bin_output(stream, dset, p_type, sm_buf, hs_nelmts) < 0) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + + /* Reclaim any VL memory, if necessary */ + if (vl_data) { + if (H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf) < 0) + H5_LIBRARY_ERROR(ENVONLY); + } + + /* Calculate the next hyperslab offset */ + for (i = (size_t)ndims, carry = 1; i > 0 && carry; --i) { + hs_offset[i - 1] += hs_size[i - 1]; + + if (hs_offset[i - 1] == total_size[i - 1]) + hs_offset[i - 1] = 0; + else + carry = 0; } - if(sm_space >= 0 && H5Sclose(sm_space) < 0) - ret_value = -1; } } - if(f_space >= 0 && H5Sclose(f_space) < 0) - ret_value = -1; - } /* end if((f_space = H5Dget_space(dset)) >= 0) */ - else - ret_value = -1; - - if (p_type >= 0) - H5Tclose(p_type); + } } + + ret_value = SUCCEED; + +done: + if (sm_space >= 0) + H5Sclose(sm_space); + if (sm_buf) + HDfree(sm_buf); + if (f_space >= 0) + H5Sclose(f_space); + if (p_type >= 0) + H5Tclose(p_type); + if (f_type >= 0) + H5Tclose(f_type); + return ret_value; } /* end h5str_dump_simple_dset */ +htri_t +H5Tdetect_variable_str(hid_t tid) { + htri_t ret_val = 0; + + if (H5Tget_class(tid) == H5T_COMPOUND) { + unsigned i; + unsigned nm = (unsigned)H5Tget_nmembers(tid); + for(i = 0; i < nm; i++) { + htri_t status = 0; + hid_t mtid = 0; + if((mtid = H5Tget_member_type(tid, i)) < 0) + return FAIL; /* exit immediately on error */ + if((status = H5Tdetect_variable_str(mtid)) < 0) + return status; /* exit immediately on error */ + ret_val |= status; + H5Tclose (mtid); + } /* end for */ + } /* end if */ + else + ret_val = H5Tis_variable_str(tid); + + return ret_val; +} /* end H5Tdetect_variable_str */ + static int h5tools_dump_simple_data - (FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts) + (JNIEnv *env, FILE *stream, hid_t container, hid_t type, void *_mem, hsize_t nelmts) { - int ret_value = 0; - int line_count; - unsigned char *mem = (unsigned char*)_mem; - size_t size; /* datum size */ - hsize_t i; /*element counter */ - h5str_t buffer; /*string into which to render */ - - if((size = H5Tget_size(type)) > 0) { - for (i = 0, line_count = 0; i < nelmts; i++, line_count++) { - size_t bytes_in = 0; /* # of bytes to write */ - size_t bytes_wrote = 0; /* # of bytes written */ - void* memref = mem + i * size; - - /* Render the data element*/ - h5str_new(&buffer, 32 * size); - bytes_in = h5str_sprintf(&buffer, container, type, memref, 0, 1); - if(i > 0) { - HDfprintf(stream, ", "); - if (line_count >= H5TOOLS_TEXT_BLOCK) { - line_count = 0; - HDfprintf(stream, "\n"); - } + unsigned char *mem = (unsigned char *)_mem; + h5str_t buffer; /* string into which to render */ + hsize_t i; /* element counter */ + size_t size; /* datum size */ + int line_count; + int ret_value = 0; + + if (!(size = H5Tget_size(type))) + H5_LIBRARY_ERROR(ENVONLY); + + for (i = 0, line_count = 0; i < nelmts; i++, line_count++) { + size_t bytes_in = 0; /* # of bytes to write */ + void *memref = mem + i * size; + + /* Render the data element*/ + h5str_new(&buffer, 32 * size); + + if (!buffer.s) + H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: failed to allocate buffer"); + + if (!(bytes_in = h5str_sprintf(ENVONLY, &buffer, container, type, memref, 0, 1))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (i > 0) { + if (HDfprintf(stream, ", ") < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: HDfprintf failure"); + + if (line_count >= H5TOOLS_TEXT_BLOCK) { + line_count = 0; + + if (HDfprintf(stream, "\n") < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: HDfprintf failure"); } - HDfprintf(stream, "%s", buffer.s); - h5str_free(&buffer); - } /* end for (i = 0; i < nelmts... */ - HDfprintf(stream, "\n"); - } /* end if((size = H5Tget_size(tid)) > 0) */ - else - ret_value = -1; + } + + if (HDfprintf(stream, "%s", buffer.s) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: HDfprintf failure"); + + h5str_free(&buffer); + } /* end for (i = 0; i < nelmts... */ + + if (HDfprintf(stream, "\n") < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5tools_dump_simple_data: HDfprintf failure"); + +done: + if (buffer.s) + h5str_free(&buffer); return ret_value; } /* end h5tools_dump_simple_data */ @@ -2421,53 +2905,68 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadComplex (JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { - herr_t status = -1; - int i; - int n; - char *rdata; - size_t max_len = 0; - size_t size; - h5str_t h5str; - hid_t p_type = -1; - jstring jstr; + h5str_t h5str; + jstring jstr; + size_t size; + size_t i; + hid_t p_type = H5I_INVALID_HID; + jsize n; + char *readBuf = NULL; + herr_t status = FAIL; + + UNUSED(clss); + + HDmemset(&h5str, 0, sizeof(h5str_t)); + + if ((p_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - p_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT); size = (((H5Tget_size(mem_type_id))>(H5Tget_size(p_type))) ? (H5Tget_size(mem_type_id)) : (H5Tget_size(p_type))); - H5Tclose(p_type); - n = ENVPTR->GetArrayLength(ENVPAR buf); - rdata = (char *)HDmalloc((size_t)n * size); - if (rdata == NULL) { - h5JNIFatalError(env, "H5AreadComplex: failed to allocate buff for read"); - } /* end if */ - else { - status = H5Aread(attr_id, mem_type_id, rdata); - if (status < 0) { - h5JNIFatalError(env, "H5AreadComplex: failed to read data"); - } /* end if */ - else { - HDmemset(&h5str, 0, sizeof(h5str_t)); - h5str_new(&h5str, 4 * size); - if (h5str.s == NULL) { - h5JNIFatalError(env, "H5AreadComplex: failed to allocate string buf"); - } /* end if */ - else { - for (i = 0; i < n; i++) { - h5str.s[0] = '\0'; - h5str_sprintf(&h5str, attr_id, mem_type_id, rdata + ((size_t)i * size), 0, 0); - jstr = ENVPTR->NewStringUTF(ENVPAR h5str.s); - ENVPTR->SetObjectArrayElement(ENVPAR buf, i, jstr); - } /* end for */ - } /* end else */ - h5str_free(&h5str); - } /* end else */ - HDfree(rdata); - } /* end else */ + if ((n = ENVPTR->GetArrayLength(ENVONLY, buf)) <= 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5AreadComplex: read buffer length <= 0"); + } + + if (NULL == (readBuf = (char *) HDmalloc((size_t)n * size))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadComplex: failed to allocate read buffer"); + + if ((status = H5Aread(attr_id, mem_type_id, readBuf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + h5str_new(&h5str, 4 * size); + + if (!h5str.s) + H5_JNI_FATAL_ERROR(ENVONLY, "H5AreadComplex: failed to allocate string buffer"); + + for (i = 0; i < (size_t) n; i++) { + h5str.s[0] = '\0'; + + if (!h5str_sprintf(ENVONLY, &h5str, attr_id, mem_type_id, readBuf + (i * size), 0, 0)) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + if (NULL == (jstr = ENVPTR->NewStringUTF(ENVONLY, h5str.s))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, buf, (jsize) i, jstr); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->DeleteLocalRef(ENVONLY, jstr); + } /* end for */ + +done: + if (h5str.s) + h5str_free(&h5str); + if (readBuf) + HDfree(readBuf); + if (p_type >= 0) + H5Tclose(p_type); + return status; } /* - * Copies the content of one dataset to another dataset + * Copies the content of one attribute to another attribute * Class: hdf_hdf5lib_H5 * Method: H5Acopy * Signature: (JJ)I @@ -2476,62 +2975,51 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Acopy (JNIEnv *env, jclass clss, jlong src_id, jlong dst_id) { - jbyte *buf; - herr_t retVal = -1; - hid_t src_did = (hid_t)src_id; - hid_t dst_did = (hid_t)dst_id; - hid_t tid = -1; - hid_t sid = -1; - hsize_t total_size = 0; - - - sid = H5Aget_space(src_did); - if (sid < 0) { - h5libraryError(env); - } /* end if */ - else { - tid = H5Aget_type(src_did); - if (tid < 0) { - H5Sclose(sid); - h5libraryError(env); - } /* end if */ - else { - total_size = (hsize_t)H5Sget_simple_extent_npoints(sid) * (hsize_t)H5Tget_size(tid); + hssize_t npoints; + hsize_t total_size = 0; + size_t type_size; + jbyte *buf = NULL; + hid_t tid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + herr_t retVal = FAIL; - H5Sclose(sid); + UNUSED(clss); - buf = (jbyte *)HDmalloc( (size_t)total_size * sizeof(jbyte)); - if (buf == NULL) { - H5Tclose(tid); - h5outOfMemory( env, "H5Acopy: malloc failed"); - } /* end if */ - else { - retVal = H5Aread(src_did, tid, buf); - H5Tclose(tid); + if ((sid = H5Aget_space((hid_t)src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retVal < 0) { - HDfree(buf); - h5libraryError(env); - } /* end if */ - else { - tid = H5Aget_type(dst_did); - if (tid < 0) { - HDfree(buf); - h5libraryError(env); - } /* end if */ - else { - retVal = H5Awrite(dst_did, tid, buf); + if ((tid = H5Aget_type((hid_t)src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - H5Tclose(tid); - HDfree(buf); + if ((npoints = H5Sget_simple_extent_npoints(sid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(type_size = H5Tget_size(tid))) + H5_LIBRARY_ERROR(ENVONLY); + total_size = (hsize_t)npoints * (hsize_t)type_size; - if (retVal < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + if (NULL == (buf = (jbyte *) HDmalloc((size_t)total_size * sizeof(jbyte)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Acopy: failed to allocate buffer"); + + if ((retVal = H5Aread((hid_t)src_id, tid, buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (H5Tclose(tid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + tid = H5I_INVALID_HID; + + if ((tid = H5Aget_type((hid_t)dst_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((retVal = H5Awrite((hid_t)dst_id, tid, buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (buf) + HDfree(buf); + if (tid >= 0) + H5Tclose(tid); + if (sid >= 0) + H5Sclose(sid); return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Acopy */ @@ -2546,64 +3034,54 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Dcopy (JNIEnv *env, jclass clss, jlong src_id, jlong dst_id) { - jbyte *buf; - herr_t retVal = -1; - hid_t src_did = (hid_t)src_id; - hid_t dst_did = (hid_t)dst_id; - hid_t tid = -1; - hid_t sid = -1; - hsize_t total_size = 0, total_allocated_size; - - total_allocated_size = H5Dget_storage_size(src_did); - if (total_allocated_size <=0) - return 0; // nothing to write; - - sid = H5Dget_space(src_did); - if (sid < 0) { - h5libraryError(env); - return -1; - } /* end if */ + hssize_t npoints; + hsize_t total_size = 0, total_allocated_size; + size_t type_size; + jbyte *buf = NULL; + hid_t tid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + herr_t retVal = FAIL; - tid = H5Dget_type(src_did); - if (tid < 0) { - H5Sclose(sid); - h5libraryError(env); - return -1; - } /* end if */ + UNUSED(clss); - total_size = (hsize_t)H5Sget_simple_extent_npoints(sid) * (hsize_t)H5Tget_size(tid); + if (!(total_allocated_size = H5Dget_storage_size((hid_t)src_id))) + return 0; // nothing to write - H5Sclose(sid); + if ((sid = H5Dget_space((hid_t)src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - buf = (jbyte*)HDmalloc((size_t)total_size * sizeof(jbyte)); - if (buf == NULL) { - H5Tclose(tid); - h5outOfMemory(env, "H5Dcopy: malloc failed"); - return -1; - } /* end if */ + if ((tid = H5Dget_type((hid_t)src_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - retVal = H5Dread(src_did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); - H5Tclose(tid); + if ((npoints = H5Sget_simple_extent_npoints(sid)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + if (!(type_size = H5Tget_size(tid))) + H5_LIBRARY_ERROR(ENVONLY); + total_size = (hsize_t)npoints * (hsize_t)type_size; - if (retVal < 0) { - HDfree(buf); - h5libraryError(env); - return (jint)retVal; - } /* end if */ + if (NULL == (buf = (jbyte *) HDmalloc((size_t)total_size * sizeof(jbyte)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Dcopy: failed to allocate buffer"); - tid = H5Dget_type(dst_did); - if (tid < 0) { - HDfree(buf); - h5libraryError(env); - return -1; - } /* end if */ - retVal = H5Dwrite(dst_did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); - H5Tclose(tid); - HDfree(buf); + if ((retVal = H5Dread((hid_t)src_id, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retVal < 0) { - h5libraryError(env); - } /* end if */ + if (H5Tclose(tid) < 0) + H5_LIBRARY_ERROR(ENVONLY); + tid = H5I_INVALID_HID; + + if ((tid = H5Dget_type((hid_t)dst_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if ((retVal = H5Dwrite((hid_t)dst_id, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (buf) + HDfree(buf); + if (tid >= 0) + H5Tclose(tid); + if (sid >= 0) + H5Sclose(sid); return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Dcopy */ @@ -2613,7 +3091,7 @@ Java_hdf_hdf5lib_H5_H5Dcopy // // // Add these methods so that we don't need to call H5Gget_objtype_by_idx -// in a loop to get information for all the object in a group, which takes +// in a loop to get information for all the objects in a group, which takes // a lot of time to finish if the number of objects is more than 10,000 // ///////////////////////////////////////////////////////////////////////////////// @@ -2648,152 +3126,103 @@ typedef struct info_all * Method: H5Gget_obj_info_full * Signature: (JLjava/lang/String;[Ljava/lang/String;[I[I[J[JIII)I */ +/* + * NOTE: This is a dangerous call! The caller can supply any value they'd like + * for 'n' and if it exceeds the number of links in the group, we will most likely + * end up overwriting memory heap-tracking info. + */ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1full (JNIEnv *env, jclass clss, jlong loc_id, jstring group_name, jobjectArray objName, jintArray oType, jintArray lType, jlongArray fNo, jlongArray oRef, jint n, jint indx_type, jint indx_order) { - herr_t ret_val = -1; - const char *gName = NULL; - char **oName = NULL; - jboolean isCopy; - jstring str; - jint *otarr; - jint *ltarr; - jlong *refP; - jlong *fnoP; - unsigned long *refs=NULL; - unsigned long *fnos=NULL; - hid_t gid = (hid_t)loc_id; - int i; - int indexType = indx_type; - int indexOrder = indx_order; - - if (oType == NULL) { - h5nullArgument(env, "H5Gget_obj_info_full: oType is NULL"); - } - else if (lType == NULL) { - h5nullArgument(env, "H5Gget_obj_info_full: lType is NULL"); - } - else if (oRef == NULL) { - h5nullArgument(env, "H5Gget_obj_info_full: oRef is NULL"); - } - else if (fNo == NULL) { - h5nullArgument(env, "H5Gget_obj_info_full: fNo is NULL"); + unsigned long *refs = NULL; + unsigned long *fnos = NULL; + const char *gName = NULL; + char **oName = NULL; + jboolean isCopy; + jstring str; + jint *otarr = NULL; + jint *ltarr = NULL; + jlong *refP = NULL; + jlong *fnoP = NULL; + hid_t gid = (hid_t)loc_id; + int i; + int indexType = indx_type; + int indexOrder = indx_order; + herr_t ret_val = FAIL; + + UNUSED(clss); + + if (NULL == oType) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oType is NULL"); + if (NULL == lType) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: lType is NULL"); + if (NULL == oRef) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: oRef is NULL"); + if (NULL == fNo) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_full: fNo is NULL"); + + PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_full: oType not pinned"); + PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_full: lType not pinned"); + PIN_LONG_ARRAY(ENVONLY, oRef, refP, &isCopy, "H5Gget_obj_info_full: oRef not pinned"); + PIN_LONG_ARRAY(ENVONLY, fNo, fnoP, &isCopy, "H5Gget_obj_info_full: fNo not pinned"); + + if (NULL == (oName = (char **) HDcalloc((size_t)n, sizeof(*oName)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for object name"); + + if (NULL == (refs = (unsigned long *) HDcalloc((size_t)n, sizeof(unsigned long)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for ref. info"); + + if (NULL == (fnos = (unsigned long *) HDcalloc((size_t)n, sizeof(unsigned long)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: failed to allocate buffer for file number info"); + + if (group_name) { + PIN_JAVA_STRING(ENVONLY, group_name, gName, &isCopy, "H5Gget_obj_info_full: group_name not pinned"); + + if ((gid = H5Gopen2((hid_t)loc_id, gName, H5P_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); } - else { - otarr = ENVPTR->GetIntArrayElements(ENVPAR oType, &isCopy); - if (otarr == NULL) { - h5JNIFatalError(env, "H5Gget_obj_info_full: otype not pinned"); - return -1; - } /* end if */ - ltarr = ENVPTR->GetIntArrayElements(ENVPAR lType, &isCopy); - if (ltarr == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_full: ltype not pinned"); - return -1; - } /* end if */ - refP = ENVPTR->GetLongArrayElements(ENVPAR oRef, &isCopy); - if (refP == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_full: oRef not pinned"); - return -1; - } /* end if */ - fnoP = ENVPTR->GetLongArrayElements(ENVPAR fNo, &isCopy); - if (fnoP == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_full: fNo not pinned"); - return -1; - } /* end if */ - oName = (char **)HDcalloc((size_t)n, sizeof(*oName)); - if (!oName) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR fNo, fnoP, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_full: oName not allocated"); - return -1; - } /* end if */ - - refs = (unsigned long *)HDcalloc((size_t)n, sizeof(unsigned long)); - fnos = (unsigned long *)HDcalloc((size_t)n, sizeof(unsigned long)); - if (!refs || !fnos) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR fNo, fnoP, JNI_ABORT); - h5str_array_free(oName, (size_t)n); - if (refs) - HDfree(refs); - if (fnos) - HDfree(fnos); - h5JNIFatalError(env, "H5Gget_obj_info_full: result arrays not allocated"); - return -1; - } /* end if */ - if (group_name != NULL) { - gid = -1; - gName = ENVPTR->GetStringUTFChars(ENVPAR group_name, &isCopy); - if (gName != NULL) { - gid = H5Gopen2((hid_t)loc_id, gName, H5P_DEFAULT); - - ENVPTR->ReleaseStringUTFChars(ENVPAR group_name, gName); - } /* end if */ - if(gid < 0) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR fNo, fnoP, JNI_ABORT); - h5str_array_free(oName, (size_t)n); - HDfree(refs); - HDfree(fnos); - h5JNIFatalError(env, "H5Gget_obj_info_full: could not get group identifier"); - return -1; - } /* end if */ - } /* end if */ + if ((ret_val = H5Gget_obj_info_full(gid, oName, (int *)otarr, (int *)ltarr, fnos, refs, indexType, indexOrder)) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_full: retrieval of object info failed"); - ret_val = H5Gget_obj_info_full(gid, oName, (int *)otarr, (int *)ltarr, fnos, refs, indexType, indexOrder); + for (i = 0; i < n; i++) { + refP[i] = (jlong)refs[i]; + fnoP[i] = (jlong)fnos[i]; - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, 0); + if (oName[i]) { + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, oName[i]))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (group_name != NULL) - H5Gclose(gid); + ENVPTR->SetObjectArrayElement(ENVONLY, objName, i, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - if (ret_val < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR fNo, fnoP, JNI_ABORT); - h5str_array_free(oName, (size_t)n); - HDfree(refs); - HDfree(fnos); - h5libraryError(env); + ENVPTR->DeleteLocalRef(ENVONLY, str); } /* end if */ - else { - for (i=0; iReleaseLongArrayElements(ENVPAR oRef, refP, 0); - - for (i=0; iReleaseLongArrayElements(ENVPAR fNo, fnoP, 0); - - for (i=0; iNewStringUTF(ENVPAR *(oName+i)); - ENVPTR->SetObjectArrayElement(ENVPAR objName, i, (jobject)str); - } /* end if */ - } /* for (i=0; iGetIntArrayElements(ENVPAR oType, &isCopy); - if (otarr == NULL) { - h5JNIFatalError(env, "H5Gget_obj_info_max: otype not pinned"); - return -1; - } /* end if */ + unsigned long *refs = NULL; + jboolean isCopy; + jstring str; + jlong *refP = NULL; + char **oName = NULL; + jint *otarr = NULL; + jint *ltarr = NULL; + int i; + herr_t ret_val = FAIL; - ltarr = ENVPTR->GetIntArrayElements(ENVPAR lType, &isCopy); - if (ltarr == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_max: ltype not pinned"); - return -1; - } /* end if */ + UNUSED(clss); - refP = ENVPTR->GetLongArrayElements(ENVPAR oRef, &isCopy); - if (refP == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_max: oRef not pinned"); - return -1; - } /* end if */ + if (NULL == oType) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oType is NULL"); + if (NULL == lType) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: lType is NULL"); + if (NULL == oRef) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_obj_info_max: oRef is NULL"); - oName = (char **)HDcalloc((size_t)n, sizeof(*oName)); - if (!oName) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - h5JNIFatalError(env, "H5Gget_obj_info_max: oName not allocated"); - return -1; - } /* end if */ - refs = (unsigned long *)HDcalloc((size_t)n, sizeof(unsigned long)); - if (!refs) { - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, JNI_ABORT); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, JNI_ABORT); - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - h5str_array_free(oName, (size_t)n); - h5JNIFatalError(env, "H5Gget_obj_info_max: result array not allocated"); - return -1; - } /* end if */ + PIN_INT_ARRAY(ENVONLY, oType, otarr, &isCopy, "H5Gget_obj_info_max: oType not pinned"); + PIN_INT_ARRAY(ENVONLY, lType, ltarr, &isCopy, "H5Gget_obj_info_max: lType not pinned"); + PIN_LONG_ARRAY(ENVONLY, oRef, refP, &isCopy, "H5Gget_obj_info_max: oRef not pinned"); - ret_val = H5Gget_obj_info_max((hid_t)loc_id, oName, (int*)otarr, (int*)ltarr, refs, maxnum ); - ENVPTR->ReleaseIntArrayElements(ENVPAR lType, ltarr, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR oType, otarr, 0); + if (NULL == (oName = (char **) HDcalloc((size_t)n, sizeof(*oName)))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5Gget_obj_info_max: failed to allocate buffer for object name"); - if (ret_val < 0) { - ENVPTR->ReleaseLongArrayElements(ENVPAR oRef, refP, JNI_ABORT); - h5str_array_free(oName, (size_t)n); - HDfree(refs); - h5libraryError(env); - } /* end if */ - else { - for (i=0; iReleaseLongArrayElements(ENVPAR oRef, refP, 0); - - for (i=0; iNewStringUTF(ENVPAR *(oName+i)); - ENVPTR->SetObjectArrayElement(ENVPAR objName, i, (jobject)str); - } - } /* for (i=0; iNewStringUTF(ENVONLY, oName[i]))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->SetObjectArrayElement(ENVONLY, objName, i, (jobject)str); + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + ENVPTR->DeleteLocalRef(ENVONLY, str); + } + } /* end for */ + +done: + if (refs) + HDfree(refs); + if (oName) + h5str_array_free(oName, (size_t)n); + if (refP) + UNPIN_LONG_ARRAY(ENVONLY, oRef, refP, (ret_val < 0) ? JNI_ABORT : 0); + if (ltarr) + UNPIN_INT_ARRAY(ENVONLY, lType, ltarr, (ret_val < 0) ? JNI_ABORT : 0); + if (otarr) + UNPIN_INT_ARRAY(ENVONLY, oType, otarr, (ret_val < 0) ? JNI_ABORT : 0); return ret_val; } /* end Java_hdf_hdf5lib_H5_H5Gget_1obj_1info_1max */ @@ -2902,6 +3307,7 @@ H5Gget_obj_info_full (hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *fno, unsigned long *objno, int indexType, int indexOrder) { info_all_t info; + info.objname = objname; info.otype = otype; info.ltype = ltype; @@ -2910,11 +3316,22 @@ H5Gget_obj_info_full info.objno = objno; info.count = 0; - if(H5Literate(loc_id, (H5_index_t)indexType, (H5_iter_order_t)indexOrder, NULL, obj_info_all, (void *)&info) < 0) { - /* iterate failed, try normal alphabetical order */ - if(H5Literate(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, obj_info_all, (void *)&info) < 0) + if (H5Literate(loc_id, (H5_index_t)indexType, (H5_iter_order_t)indexOrder, NULL, obj_info_all, (void *)&info) < 0) { + /* + * Reset info stats; most importantly, reset the count. + */ + info.objname = objname; + info.otype = otype; + info.ltype = ltype; + info.idxnum = 0; + info.fno = fno; + info.objno = objno; + info.count = 0; + + /* Iteration failed, try normal alphabetical order */ + if (H5Literate(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, obj_info_all, (void *)&info) < 0) return -1; - } /* end if */ + } return info.count; } /* end H5Gget_obj_info_full */ @@ -2924,6 +3341,7 @@ H5Gget_obj_info_max (hid_t loc_id, char **objname, int *otype, int *ltype, unsigned long *objno, long maxnum) { info_all_t info; + info.objname = objname; info.otype = otype; info.ltype = ltype; @@ -2931,7 +3349,7 @@ H5Gget_obj_info_max info.objno = objno; info.count = 0; - if(H5Lvisit(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, obj_info_max, (void *)&info) < 0) + if (H5Lvisit(loc_id, H5_INDEX_NAME, H5_ITER_NATIVE, obj_info_max, (void *)&info) < 0) return -1; return info.count; @@ -2941,75 +3359,87 @@ herr_t obj_info_all (hid_t loc_id, const char *name, const H5L_info_t *info, void *op_data) { - int type = -1; - hid_t oid = -1; - herr_t retVal = -1; - info_all_t *datainfo = (info_all_t*)op_data; + info_all_t *datainfo = (info_all_t *)op_data; H5O_info_t object_info; + htri_t object_exists; + size_t str_len; - retVal = H5Oget_info_by_name2(loc_id, name, &object_info, H5O_INFO_ALL, H5P_DEFAULT); + datainfo->otype[datainfo->count] = -1; + datainfo->ltype[datainfo->count] = -1; + datainfo->objno[datainfo->count] = (unsigned long)-1; - if (retVal < 0) { - *(datainfo->otype+datainfo->count) = -1; - *(datainfo->ltype+datainfo->count) = -1; - *(datainfo->objname+datainfo->count) = (char *)HDmalloc(HDstrlen(name)+1); - HDstrcpy(*(datainfo->objname+datainfo->count), name); - *(datainfo->objno+datainfo->count) = (unsigned long)-1; - } /* end if */ - else { - *(datainfo->otype+datainfo->count) = object_info.type; - *(datainfo->ltype+datainfo->count) = info->type; - *(datainfo->objname+datainfo->count) = (char *)HDmalloc(HDstrlen(name)+1); - HDstrcpy(*(datainfo->objname+datainfo->count), name); - - *(datainfo->fno+datainfo->count) = object_info.fileno; - *(datainfo->objno+datainfo->count) = (unsigned long)object_info.addr; - /* - if(info->type==H5L_TYPE_HARD) - *(datainfo->objno+datainfo->count) = (unsigned long)info->u.address; - else - *(datainfo->objno+datainfo->count) = info->u.val_size; - */ - } /* end else */ + str_len = HDstrlen(name); + if (NULL == (datainfo->objname[datainfo->count] = (char *) HDmalloc(str_len + 1))) + goto done; + + HDstrncpy(datainfo->objname[datainfo->count], name, str_len); + (datainfo->objname[datainfo->count])[str_len] = '\0'; + + if ((object_exists = H5Oexists_by_name(loc_id, name, H5P_DEFAULT)) < 0) + goto done; + + if (object_exists) { + if (H5Oget_info_by_name2(loc_id, name, &object_info, H5O_INFO_ALL, H5P_DEFAULT) < 0) + goto done; + + datainfo->otype[datainfo->count] = object_info.type; + datainfo->ltype[datainfo->count] = info->type; + datainfo->fno[datainfo->count] = object_info.fileno; + datainfo->objno[datainfo->count] = (unsigned long)object_info.addr; + } + + /* + if (info->type == H5L_TYPE_HARD) + datainfo->objno[datainfo->count] = (unsigned long)info->u.address; + else + datainfo->objno[datainfo->count] = info->u.val_size; + */ +done: datainfo->count++; - return 0; + return SUCCEED; } /* end obj_info_all */ herr_t obj_info_max (hid_t loc_id, const char *name, const H5L_info_t *info, void *op_data) { - int type = -1; - herr_t retVal = 0; - info_all_t *datainfo = (info_all_t*)op_data; + info_all_t *datainfo = (info_all_t *)op_data; H5O_info_t object_info; + size_t str_len; - retVal = H5Oget_info2(loc_id, &object_info, H5O_INFO_ALL); - if (retVal < 0) { - *(datainfo->otype+datainfo->count) = -1; - *(datainfo->ltype+datainfo->count) = -1; - *(datainfo->objname+datainfo->count) = NULL; - *(datainfo->objno+datainfo->count) = (unsigned long)-1; - return 1; - } /* end if */ - else { - *(datainfo->otype+datainfo->count) = object_info.type; - *(datainfo->ltype+datainfo->count) = info->type; - /* this will be freed by h5str_array_free(oName, n)*/ - *(datainfo->objname+datainfo->count) = (char *)HDmalloc(HDstrlen(name)+1); - strcpy(*(datainfo->objname+datainfo->count), name); - if(info->type==H5L_TYPE_HARD) - *(datainfo->objno+datainfo->count) = (unsigned long)info->u.address; - else - *(datainfo->objno+datainfo->count) = info->u.val_size; - } /* end else */ - datainfo->count++; - if(datainfo->count < (int)datainfo->idxnum) - return 0; + datainfo->otype[datainfo->count] = -1; + datainfo->ltype[datainfo->count] = -1; + datainfo->objname[datainfo->count] = NULL; + datainfo->objno[datainfo->count] = (unsigned long)-1; + + /* This will be freed by h5str_array_free(oName, n) */ + str_len = HDstrlen(name); + if (NULL == (datainfo->objname[datainfo->count] = (char *) HDmalloc(str_len + 1))) + goto done; + + HDstrncpy(datainfo->objname[datainfo->count], name, str_len); + (datainfo->objname[datainfo->count])[str_len] = '\0'; + + if (H5Oget_info2(loc_id, &object_info, H5O_INFO_ALL) < 0) + goto done; + + datainfo->otype[datainfo->count] = object_info.type; + datainfo->ltype[datainfo->count] = info->type; + + if (info->type == H5L_TYPE_HARD) + datainfo->objno[datainfo->count] = (unsigned long)info->u.address; else + datainfo->objno[datainfo->count] = info->u.val_size; + +done: + datainfo->count++; + + if (datainfo->count >= (int)datainfo->idxnum) return 1; + else + return SUCCEED; } /* end obj_info_max */ /* @@ -3021,68 +3451,62 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5export_1dataset (JNIEnv *env, jclass cls, jstring file_export_name, jstring file_name, jstring object_path, jint binary_order) { - herr_t status = -1; - herr_t ret_val = -1; - hid_t file_id = -1; - hid_t dataset_id = -1; + const char *file_export = NULL; + const char *object_name = NULL; + const char *fileName = NULL; + jboolean isCopy; + herr_t ret_val = FAIL; + hid_t file_id = H5I_INVALID_HID; + hid_t dataset_id = H5I_INVALID_HID; FILE *stream; - const char *file_export; - const char *object_name; - const char *fileName; - jboolean isCopy2; - if (file_export_name == NULL) { - h5nullArgument(env, "HDF5Library_export_data: file_export_name is NULL"); - } /* end if */ - else if (object_path == NULL) { - h5nullArgument(env, "HDF5Library_export_data: object_path is NULL"); - } /* end else if */ - else { - PIN_JAVA_STRING(file_name, fileName); - if (fileName != NULL) { - file_id = H5Fopen(fileName, (unsigned)H5F_ACC_RDWR, (hid_t)H5P_DEFAULT); - - UNPIN_JAVA_STRING(file_name, fileName); - - if (file_id < 0) { - /* throw exception */ - h5libraryError(env); - } /* end if */ - else { - object_name = ENVPTR->GetStringUTFChars(ENVPAR object_path, &isCopy2); - if (object_name == NULL) { - h5JNIFatalError( env, "H5Dopen: object name not pinned"); - } /* end if */ - else { - dataset_id = H5Dopen2(file_id, object_name, H5P_DEFAULT); + UNUSED(cls); - ENVPTR->ReleaseStringUTFChars(ENVPAR object_path, object_name); + if (NULL == file_export_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: file_export_name is NULL"); - if (dataset_id < 0) { - H5Fclose(file_id); - h5libraryError(env); - } /* end if */ - else { - file_export = ENVPTR->GetStringUTFChars(ENVPAR file_export_name, 0); - stream = HDfopen(file_export, "w+"); - ENVPTR->ReleaseStringUTFChars(ENVPAR file_export_name, file_export); + if (NULL == file_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: file_name is NULL"); - ret_val = h5str_dump_simple_dset(stream, dataset_id, binary_order); + if (NULL == object_path) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5export_dataset: object_path is NULL"); - if (stream) - HDfclose(stream); + PIN_JAVA_STRING(ENVONLY, file_name, fileName, NULL, "H5export_dataset: file name not pinned"); - H5Dclose(dataset_id); + if ((file_id = H5Fopen(fileName, (unsigned)H5F_ACC_RDWR, (hid_t)H5P_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - H5Fclose(file_id); + PIN_JAVA_STRING(ENVONLY, object_path, object_name, &isCopy, "H5export_dataset: object_path not pinned"); - if (ret_val < 0) - h5libraryError(env); - } /* end else */ - } /* end else */ - } /* end else */ - } - } /* end else */ + if ((dataset_id = H5Dopen2(file_id, object_name, H5P_DEFAULT)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + PIN_JAVA_STRING(ENVONLY, file_export_name, file_export, NULL, "H5export_dataset: file_export name not pinned"); + + if (NULL == (stream = HDfopen(file_export, "w+"))) + H5_JNI_FATAL_ERROR(ENVONLY, "HDfopen failed"); + + if ((ret_val = h5str_dump_simple_dset(ENVONLY, stream, dataset_id, binary_order)) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_dump_simple_dset failed"); + + if (stream) { + HDfclose(stream); + stream = NULL; + } + +done: + if (stream) + HDfclose(stream); + if (file_export) + UNPIN_JAVA_STRING(ENVONLY, file_export_name, file_export); + if (object_name) + UNPIN_JAVA_STRING(ENVONLY, object_path, object_name); + if (fileName) + UNPIN_JAVA_STRING(ENVONLY, file_name, fileName); + if (dataset_id >= 0) + H5Dclose(dataset_id); + if (file_id >= 0) + H5Fclose(file_id); } /* end Java_hdf_hdf5lib_H5_H5export_1dataset */ #ifdef __cplusplus diff --git a/java/src/jni/h5util.h b/java/src/jni/h5util.h index 23bc424..e5f0d0b 100644 --- a/java/src/jni/h5util.h +++ b/java/src/jni/h5util.h @@ -35,18 +35,29 @@ typedef struct h5str_t { size_t max; /* the allocated size of the string */ } h5str_t; -extern void h5str_new (h5str_t *str, size_t len); -extern void h5str_free (h5str_t *str); -extern void h5str_resize (h5str_t *str, size_t new_len); -extern char* h5str_append (h5str_t *str, const char* cstr); -extern size_t h5str_vlsprintf(h5str_t *str, hid_t container, hid_t tid, hvl_t *buf, int expand_data); -extern size_t h5str_sprintf(h5str_t *str, hid_t container, hid_t tid, void *buf, int ptrlen, int expand_data); -extern size_t h5str_vlsconvert(char *str, hid_t container, hid_t tid, hvl_t *buf, int expand_data); -extern size_t h5str_convert(char **str, hid_t container, hid_t tid, hvl_t *buf, int ptroffset, int expand_data); +extern void h5str_new(h5str_t *str, size_t len); +extern void h5str_free(h5str_t *str); +extern void h5str_resize(h5str_t *str, size_t new_len); +extern char* h5str_append(h5str_t *str, const char* cstr); +extern size_t h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_buf, size_t out_buf_offset); +extern size_t h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *in_buf, size_t in_buf_len, int expand_data); extern void h5str_array_free(char **strs, size_t len); -extern int h5str_dump_simple_dset(FILE *stream, hid_t dset, int binary_order); -extern int h5str_dump_region_blocks_data(h5str_t *str, hid_t region, hid_t region_obj); -extern int h5str_dump_region_points_data(h5str_t *str, hid_t region, hid_t region_obj); +extern int h5str_dump_simple_dset(JNIEnv *env, FILE *stream, hid_t dset, int binary_order); +extern int h5str_dump_region_blocks_data(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj); +extern int h5str_dump_region_points_data(JNIEnv *env, h5str_t *str, hid_t region, hid_t region_obj); + +extern htri_t H5Tdetect_variable_str(hid_t tid); + +/* + * Symbols used to format the output of h5str_sprintf and + * to interpret the input to h5str_convert. + */ +#define H5_COMPOUND_BEGIN_INDICATOR "{" +#define H5_COMPOUND_END_INDICATOR "}" +#define H5_ARRAY_BEGIN_INDICATOR "[" +#define H5_ARRAY_END_INDICATOR "]" +#define H5_VLEN_BEGIN_INDICATOR "(" +#define H5_VLEN_END_INDICATOR ")" /* * Class: hdf_hdf5lib_H5 diff --git a/java/src/jni/h5vlImp.c b/java/src/jni/h5vlImp.c index 89ea703..c816abf 100644 --- a/java/src/jni/h5vlImp.c +++ b/java/src/jni/h5vlImp.c @@ -21,9 +21,9 @@ extern "C" { #endif /* __cplusplus */ -#include "hdf5.h" #include #include +#include "hdf5.h" #include "h5jni.h" #include "h5vlImp.h" @@ -36,18 +36,19 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1name (JNIEnv *env, jclass clss, jobject connector_name, jlong vipl_id) { - hid_t status = -1; - const char *vlName; + const char *volName = NULL; + hid_t status = H5I_INVALID_HID; - PIN_JAVA_STRING(connector_name, vlName); - if (vlName != NULL) { - status = H5VLregister_connector_by_name(vlName, (hid_t)vipl_id); + UNUSED(clss); - UNPIN_JAVA_STRING(connector_name, vlName); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLregister_connector_by_name: VOL connector name not pinned"); - if (status < 0) - h5libraryError(env); - } + if ((status = H5VLregister_connector_by_name(volName, (hid_t)vipl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (volName) + UNPIN_JAVA_STRING(ENVONLY, connector_name, volName); return (jlong)status; } /* end Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1name */ @@ -61,11 +62,14 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1value (JNIEnv *env, jclass clss, jint connector_value, jlong vipl_id) { - hid_t status = H5VLregister_connector_by_value((H5VL_class_value_t)connector_value, (hid_t)vipl_id); + hid_t status = H5I_INVALID_HID; + + UNUSED(clss); - if (status < 0) - h5libraryError(env); + if ((status = H5VLregister_connector_by_value((H5VL_class_value_t)connector_value, (hid_t)vipl_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jlong)status; } /* end Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1value */ @@ -78,20 +82,21 @@ JNIEXPORT jboolean JNICALL Java_hdf_hdf5lib_H5_H5VLis_1connector_1registered (JNIEnv *env, jclass clss, jobject connector_name) { + const char *volName = NULL; htri_t bval = JNI_FALSE; - const char *vlName; - PIN_JAVA_STRING(connector_name, vlName); - if (vlName != NULL) { - bval = H5VLis_connector_registered(vlName); + UNUSED(clss); - UNPIN_JAVA_STRING(connector_name, vlName); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLis_connector_registered: VOL connector name not pinned"); - if (bval > 0) - bval = JNI_TRUE; - else if (bval < 0) - h5libraryError(env); - } + if ((bval = H5VLis_connector_registered(volName)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + bval = (bval > 0) ? JNI_TRUE : JNI_FALSE; + +done: + if (volName) + UNPIN_JAVA_STRING(ENVONLY, connector_name, volName); return (jboolean)bval; } /* end Java_hdf_hdf5lib_H5_H5VLis_1connector_1registered */ @@ -105,18 +110,19 @@ JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_H5_H5VLget_1connector_1id (JNIEnv *env, jclass clss, jobject connector_name) { - hid_t status = -1; - const char *vlName; + const char *volName = NULL; + hid_t status = H5I_INVALID_HID; - PIN_JAVA_STRING(connector_name, vlName); - if (vlName != NULL) { - status = H5VLget_connector_id(vlName); + UNUSED(clss); - UNPIN_JAVA_STRING(connector_name, vlName); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLget_connector_id: VOL connector name not pinned"); - if (status < 0) - h5libraryError(env); - } + if ((status = H5VLget_connector_id(volName)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + if (volName) + UNPIN_JAVA_STRING(ENVONLY, connector_name, volName); return (jlong)status; } /* end Java_hdf_hdf5lib_H5_H5VLget_1connector_1id */ @@ -131,41 +137,31 @@ JNIEXPORT jobject JNICALL Java_hdf_hdf5lib_H5_H5VLget_1connector_1name (JNIEnv *env, jclass clss, jlong object_id) { - char *vlName; - ssize_t buf_size; - ssize_t status; + ssize_t buf_size, status; + char *volName = NULL; jstring str = NULL; - /* get the length of the comment */ - buf_size = H5VLget_connector_name((hid_t)object_id, NULL, 0); - if (buf_size < 0) { - H5Eprint2(H5E_DEFAULT, NULL); - - h5badArgument(env, "H5VLget_connector_name: buf_size < 0"); - } /* end if */ - else if (buf_size > 0) { - buf_size++; /* add extra space for the null terminator */ - vlName = (char *)HDmalloc(sizeof(char) * (size_t)buf_size); - if (vlName == NULL) { - /* exception -- out of memory */ - h5outOfMemory(env, "H5VLget_connector_name: malloc failed"); - } /* end if */ - else { - status = H5VLget_connector_name((hid_t)object_id, vlName, (size_t)buf_size); - - if (status < 0) { - h5libraryError(env); - } /* end if */ - else { - /* may throw OutOfMemoryError */ - str = ENVPTR->NewStringUTF(ENVPAR vlName); - if (str == NULL) { - h5JNIFatalError(env, "H5VLget_connector_name: return string not allocated"); - } /* end if */ - } /* end else */ - HDfree(vlName); - } - } /* end else if */ + UNUSED(clss); + + /* Get the length of the comment */ + if ((buf_size = H5VLget_connector_name((hid_t)object_id, NULL, 0)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + + if (buf_size > 0) { + if (NULL == (volName = (char *) HDmalloc(sizeof(char) * (size_t)buf_size + 1))) + H5_JNI_FATAL_ERROR(ENVONLY, "H5VLget_connector_name: failed to allocated VOL connector name buffer"); + + if ((status = H5VLget_connector_name((hid_t)object_id, volName, (size_t)buf_size + 1)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + volName[buf_size] = '\0'; + + if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, volName))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + } + +done: + if (volName) + HDfree(volName); return (jstring)str; } /* end Java_hdf_hdf5lib_H5_H5VLget_1connector_1name */ @@ -179,10 +175,15 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5VLclose (JNIEnv *env, jclass clss, jlong connector_id) { - herr_t retValue = H5VLclose((hid_t)connector_id); + herr_t retValue = FAIL; + + UNUSED(clss); + + if ((retValue = H5VLclose((hid_t)connector_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retValue < 0) - h5libraryError(env); +done: + return; } /* end Java_hdf_hdf5lib_H5_H5VLclose */ /* @@ -194,10 +195,15 @@ JNIEXPORT void JNICALL Java_hdf_hdf5lib_H5_H5VLunregister_1connector (JNIEnv *env, jclass clss, jlong connector_id) { - herr_t retValue = H5VLunregister_connector((hid_t)connector_id); + herr_t retValue = FAIL; + + UNUSED(clss); + + if ((retValue = H5VLunregister_connector((hid_t)connector_id)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - if (retValue < 0) - h5libraryError(env); +done: + return; } /* end Java_hdf_hdf5lib_H5_H5VLunregister_1connector */ diff --git a/java/src/jni/h5vlImp.h b/java/src/jni/h5vlImp.h index af824a9..207efa5 100644 --- a/java/src/jni/h5vlImp.h +++ b/java/src/jni/h5vlImp.h @@ -44,7 +44,7 @@ Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1value * Signature: (Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL -Java_hdf_hdf5lib_H5_H5VLis_connector_registered +Java_hdf_hdf5lib_H5_H5VLis_1connector_1registered (JNIEnv *, jclass, jobject); /* diff --git a/java/src/jni/h5zImp.c b/java/src/jni/h5zImp.c index a5e6cd8..a1c8517 100644 --- a/java/src/jni/h5zImp.c +++ b/java/src/jni/h5zImp.c @@ -36,12 +36,15 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Zunregister (JNIEnv *env, jclass clss, jint filter) { - herr_t retValue = H5Zunregister((H5Z_filter_t)filter); + herr_t retVal = FAIL; - if (retValue < 0) - h5libraryError(env); + UNUSED(clss); - return (jint)retValue; + if ((retVal = H5Zunregister((H5Z_filter_t)filter)) < 0) + H5_LIBRARY_ERROR(ENVONLY); + +done: + return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Zunregister */ /* @@ -53,12 +56,15 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Zfilter_1avail (JNIEnv *env, jclass clss, jint filter) { - herr_t retValue = H5Zfilter_avail((H5Z_filter_t)filter); + herr_t retVal = FAIL; + + UNUSED(clss); - if (retValue < 0) - h5libraryError(env); + if ((retVal = H5Zfilter_avail((H5Z_filter_t)filter)) < 0) + H5_LIBRARY_ERROR(ENVONLY); - return (jint)retValue; +done: + return (jint)retVal; } /* end Java_hdf_hdf5lib_H5_H5Zfilter_1avail */ /* @@ -73,9 +79,12 @@ Java_hdf_hdf5lib_H5_H5Zget_1filter_1info { unsigned int flags = 0; - if (H5Zget_filter_info ((H5Z_filter_t) filter, (unsigned *) &flags) < 0) - h5libraryError(env); + UNUSED(clss); + + if (H5Zget_filter_info((H5Z_filter_t) filter, (unsigned *) &flags) < 0) + H5_LIBRARY_ERROR(ENVONLY); +done: return (jint)flags; } /* end Java_hdf_hdf5lib_H5_H5Zget_1filter_1info */ diff --git a/java/src/jni/nativeData.c b/java/src/jni/nativeData.c index 33f4953..947f843 100644 --- a/java/src/jni/nativeData.c +++ b/java/src/jni/nativeData.c @@ -50,54 +50,49 @@ JNIEXPORT jintArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B (JNIEnv *env, jclass clss, jbyteArray bdata) /* IN: array of bytes */ { - jbyte *barr; - jintArray rarray = NULL; - int blen; - jint *iarray; - jboolean bb; - char *bp; - jint *iap; - int ii; - int len; - - if (bdata == NULL) { - h5nullArgument( env, "byteToInt: bdata is NULL?"); - } /* end if */ - else { - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToInt: pin failed"); - } /* end if */ - else { - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - - len = blen/(int)sizeof(jint); - rarray = ENVPTR->NewIntArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToInt" ); - return NULL; - } /* end if */ - - iarray = ENVPTR->GetIntArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToInt: pin iarray failed"); - return NULL; - } /* end if */ - - bp = (char *)barr; - iap = iarray; - for (ii = 0; ii < len; ii++) { - *iap = *(jint *)bp; - iap++; - bp += sizeof(jint); - } /* end for */ - - ENVPTR->ReleaseIntArrayElements(ENVPAR rarray,iarray, 0); - } /* end else */ - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - } /* end else */ + jintArray rarray = NULL; + jboolean bb; + jbyte *barr = NULL; + jint *iarray = NULL; + jint *iap = NULL; + char *bp = NULL; + int blen; + int ii; + int len; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToInt: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToInt: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: bdata length < 0"); + } + + len = blen / (int)sizeof(jint); + + if (NULL == (rarray = ENVPTR->NewIntArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_INT_ARRAY(ENVONLY, rarray, iarray, &bb, "byteToInt: int array not pinned"); + + bp = (char *)barr; + iap = iarray; + for (ii = 0; ii < len; ii++) { + *iap = *(jint *)bp; + iap++; + bp += sizeof(jint); + } /* end for */ + +done: + if (iarray) + UNPIN_INT_ARRAY(ENVONLY, rarray, iarray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); + return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B */ @@ -106,40 +101,34 @@ JNIEXPORT jfloatArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B (JNIEnv *env, jclass clss, jbyteArray bdata) /* IN: array of bytes */ { - jbyte *barr; - jfloatArray rarray; - int blen; - jfloat *farray; - jboolean bb; - char *bp; - jfloat *iap; - int ii; - int len; - - if (bdata == NULL) { - h5nullArgument( env, "byteToFloat: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToFloat: pin failed"); - return NULL; - } /* end if */ - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - - len = blen/(int)sizeof(jfloat); - rarray = ENVPTR->NewFloatArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToFloat" ); - return NULL; - } /* end if */ - farray = ENVPTR->GetFloatArrayElements(ENVPAR rarray,&bb); - if (farray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToFloat: pin farray failed"); - return NULL; - } /* end if */ + jfloatArray rarray; + jboolean bb; + jfloat *farray = NULL; + jfloat *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + int len; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); + } + + len = blen / (int)sizeof(jfloat); + + if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); bp = (char *)barr; iap = farray; @@ -149,8 +138,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B bp += sizeof(jfloat); } /* end for */ - ENVPTR->ReleaseFloatArrayElements(ENVPAR rarray,farray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (farray) + UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B */ @@ -160,42 +152,34 @@ JNIEXPORT jshortArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B (JNIEnv *env, jclass clss, jbyteArray bdata) /* IN: array of bytes */ { - jbyte *barr; - jshortArray rarray; - int blen; - jshort *sarray; - jboolean bb; - char *bp; - jshort *iap; - int ii; - int len; - - if (bdata == NULL) { - h5nullArgument( env, "byteToShort: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToShort: pin failed"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - - len = blen/(int)sizeof(jshort); - rarray = ENVPTR->NewShortArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToShort" ); - return NULL; - } /* end if */ - - sarray = ENVPTR->GetShortArrayElements(ENVPAR rarray,&bb); - if (sarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToShort: pin sarray failed"); - return NULL; - } /* end if */ + jshortArray rarray; + jboolean bb; + jshort *sarray = NULL; + jshort *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + int len; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToShort: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToShort: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: bdata length < 0"); + } + + len = blen / (int)sizeof(jshort); + + if (NULL == (rarray = ENVPTR->NewShortArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_SHORT_ARRAY(ENVONLY, rarray, sarray, &bb, "byteToShort: short array not pinned"); bp = (char *)barr; iap = sarray; @@ -205,53 +189,48 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B bp += sizeof(jshort); } /* end for */ - ENVPTR->ReleaseShortArrayElements(ENVPAR rarray,sarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (sarray) + UNPIN_SHORT_ARRAY(ENVONLY, rarray, sarray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B */ - /* returns long [] */ JNIEXPORT jlongArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B (JNIEnv *env, jclass clss, jbyteArray bdata) /* IN: array of bytes */ { - jbyte *barr; - jlongArray rarray; - int blen; - jlong *larray; - jboolean bb; - char *bp; - jlong *iap; - int ii; - int len; - - if (bdata == NULL) { - h5nullArgument( env, "byteToLong: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToLong: pin failed"); - return NULL; - } /* end if */ - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - - len = blen/(int)sizeof(jlong); - rarray = ENVPTR->NewLongArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToLong" ); - return NULL; - } /* end if */ - - larray = ENVPTR->GetLongArrayElements(ENVPAR rarray,&bb); - if (larray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToLong: pin larray failed"); - return NULL; - } /* end if */ + jlongArray rarray; + jboolean bb; + jlong *larray = NULL; + jlong *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + int len; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToLong: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToLong: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: bdata length < 0"); + } + + len = blen / (int)sizeof(jlong); + + if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_LONG_ARRAY(ENVONLY, rarray, larray, &bb, "byteToLong: long array not pinned"); bp = (char *)barr; iap = larray; @@ -260,53 +239,49 @@ Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B iap++; bp += sizeof(jlong); } /* end for */ - ENVPTR->ReleaseLongArrayElements(ENVPAR rarray,larray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); + +done: + if (larray) + UNPIN_LONG_ARRAY(ENVONLY, rarray, larray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B */ - /* returns double [] */ JNIEXPORT jdoubleArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B (JNIEnv *env, jclass clss, jbyteArray bdata) /* IN: array of bytes */ { - jbyte *barr; - jdoubleArray rarray; - int blen; - jdouble *darray; - jboolean bb; - char *bp; - jdouble *iap; - int ii; - int len; - - if (bdata == NULL) { - h5nullArgument( env, "byteToDouble: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToDouble: pin failed"); - return NULL; - } /* end if */ - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - - len = blen/(int)sizeof(jdouble); - rarray = ENVPTR->NewDoubleArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToDouble" ); - return NULL; - } /* end if */ - - darray = ENVPTR->GetDoubleArrayElements(ENVPAR rarray,&bb); - if (darray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToDouble: pin darray failed"); - return NULL; - } /* end if */ + jdoubleArray rarray; + jboolean bb; + jdouble *darray = NULL; + jdouble *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + int len; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToDouble: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToDouble: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: bdata length < 0"); + } + + len = blen / (int)sizeof(jdouble); + + if (NULL == (rarray = ENVPTR->NewDoubleArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, &bb, "byteToDouble: double array not pinned"); bp = (char *)barr; iap = darray; @@ -316,59 +291,50 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B bp += sizeof(jdouble); } /* end for */ - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rarray,darray,0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (darray) + UNPIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B */ - /* returns int [] */ JNIEXPORT jintArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B (JNIEnv *env, jclass clss, jint start, jint len, jbyteArray bdata) /* IN: array of bytes */ { - char *bp; - jbyte *barr; - jintArray rarray; - int blen; - jint *iarray; - jint *iap; - int ii; - jboolean bb; - - if (bdata == NULL) { - h5nullArgument( env, "byteToInt: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError(env, "byteToInt: pin failed"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - if ((start < 0) || ((int)(start + (len*(int)sizeof(jint))) > blen)) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToInt: getLen failed"); - return NULL; - } /* end if */ + jintArray rarray; + jboolean bb; + jint *iarray = NULL; + jint *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToInt: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToInt: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: bdata length < 0"); + } + + if ((start < 0) || ((int)(start + (len * (int)sizeof(jint))) > blen)) + H5_JNI_FATAL_ERROR(ENVONLY, "byteToInt: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; - rarray = ENVPTR->NewIntArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToInt" ); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewIntArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - iarray = ENVPTR->GetIntArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError(env, "byteToInt: pin iarray failed"); - return NULL; - } /* end if */ + PIN_INT_ARRAY(ENVONLY, rarray, iarray, &bb, "byteToInt: int array not pinned"); iap = iarray; for (ii = 0; ii < len; ii++) { @@ -377,8 +343,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B bp += sizeof(jint); } /* end for */ - ENVPTR->ReleaseIntArrayElements(ENVPAR rarray,iarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (iarray) + UNPIN_INT_ARRAY(ENVONLY, rarray, iarray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B */ @@ -388,57 +357,49 @@ JNIEXPORT jshortArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B (JNIEnv *env, jclass clss, jint start, jint len, jbyteArray bdata) /* IN: array of bytes */ { - char *bp; - jbyte *barr; - jshortArray rarray; - int blen; - jshort *iarray; - jshort *iap; - int ii; - jboolean bb; - - if (bdata == NULL) { - h5nullArgument( env, "byteToShort: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError( env, "byteToShort: getByte failed?"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - if ((start < 0) || ((int)(start + (len*(int)sizeof(jshort))) > blen)) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5badArgument( env, "byteToShort: start or len is out of bounds"); - return NULL; - } /* end if */ + jshortArray rarray; + jboolean bb; + jshort *sarray = NULL; + jshort *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToShort: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToShort: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: bdata length < 0"); + } + + if ((start < 0) || ((int)(start + (len * (int)sizeof(jshort))) > blen)) + H5_JNI_FATAL_ERROR(ENVONLY, "byteToShort: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; - rarray = ENVPTR->NewShortArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToShort" ); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewShortArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - iarray = ENVPTR->GetShortArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError( env, "byteToShort: getShort failed?"); - return NULL; - } /* end if */ + PIN_SHORT_ARRAY(ENVONLY, rarray, sarray, &bb, "byteToShort: short array not pinned"); - iap = iarray; + iap = sarray; for (ii = 0; ii < len; ii++) { *iap = *(jshort *)bp; iap++; bp += sizeof(jshort); } /* end for */ - ENVPTR->ReleaseShortArrayElements(ENVPAR rarray,iarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (sarray) + UNPIN_SHORT_ARRAY(ENVONLY, rarray, sarray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B */ @@ -448,57 +409,49 @@ JNIEXPORT jfloatArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B (JNIEnv *env, jclass clss, jint start, jint len, jbyteArray bdata) /* IN: array of bytes */ { - char *bp; - jbyte *barr; - jfloatArray rarray; - int blen; - jfloat *iarray; - jfloat *iap; - int ii; - jboolean bb; - - if (bdata == NULL) { - h5nullArgument( env, "byteToFloat: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError( env, "byteToFloat: getByte failed?"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - if ((start < 0) || ((int)(start + (len*(int)sizeof(jfloat))) > blen)) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5badArgument( env, "byteToFloat: start or len is out of bounds"); - return NULL; - } /* end if */ + jfloatArray rarray; + jboolean bb; + jfloat *farray = NULL; + jfloat *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); + } + + if ((start < 0) || ((int)(start + (len * (int)sizeof(jfloat))) > blen)) + H5_JNI_FATAL_ERROR(ENVONLY, "byteToFloat: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; - rarray = ENVPTR->NewFloatArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToFloat" ); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - iarray = ENVPTR->GetFloatArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError( env, "byteToFloat: getFloat failed?"); - return NULL; - } /* end if */ + PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); - iap = iarray; + iap = farray; for (ii = 0; ii < len; ii++) { *iap = *(jfloat *)bp; iap++; bp += sizeof(jfloat); } /* end for */ - ENVPTR->ReleaseFloatArrayElements(ENVPAR rarray,iarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (farray) + UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B */ @@ -508,58 +461,49 @@ JNIEXPORT jlongArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B (JNIEnv *env, jclass clss, jint start, jint len, jbyteArray bdata) /* IN: array of bytes */ { - char *bp; - jbyte *barr; - jlongArray rarray; - int blen; - jlong *iarray; - jlong *iap; - int ii; - jboolean bb; - - if (bdata == NULL) { - h5nullArgument( env, "byteToLong: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError( env, "byteToLong: getByte failed?"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - if ((start < 0) || ((int)(start + (len*(int)sizeof(jlong))) > blen)) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5badArgument( env, "byteToLong: start or len is out of bounds"); - return NULL; - } /* end if */ + jlongArray rarray; + jboolean bb; + jlong *larray = NULL; + jlong *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToLong: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToLong: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: bdata length < 0"); + } + + if ((start < 0) || ((int)(start + (len * (int)sizeof(jlong))) > blen)) + H5_JNI_FATAL_ERROR(ENVONLY, "byteToLong: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; - rarray = ENVPTR->NewLongArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToLong" ); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - iarray = ENVPTR->GetLongArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError( env, "byteToLong: getLong failed?"); - return NULL; - } /* end if */ + PIN_LONG_ARRAY(ENVONLY, rarray, larray, &bb, "byteToLong: long array not pinned"); - iap = iarray; + iap = larray; for (ii = 0; ii < len; ii++) { - *iap = *(jlong *)bp; iap++; bp += sizeof(jlong); } /* end for */ - ENVPTR->ReleaseLongArrayElements(ENVPAR rarray,iarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (larray) + UNPIN_LONG_ARRAY(ENVONLY, rarray, larray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B */ @@ -569,57 +513,49 @@ JNIEXPORT jdoubleArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToDouble__II_3B (JNIEnv *env, jclass clss, jint start, jint len, jbyteArray bdata) /* IN: array of bytes */ { - char *bp; - jbyte *barr; - jdoubleArray rarray; - int blen; - jdouble *iarray; - jdouble *iap; - int ii; - jboolean bb; - - if (bdata == NULL) { - h5nullArgument( env, "byteToDouble: bdata is NULL?"); - return NULL; - } /* end if */ - barr = ENVPTR->GetByteArrayElements(ENVPAR bdata,&bb); - if (barr == NULL) { - h5JNIFatalError( env, "byteToDouble: getByte failed?"); - return NULL; - } /* end if */ - - blen = ENVPTR->GetArrayLength(ENVPAR bdata); - if ((start < 0) || ((int)(start + (len*(int)sizeof(jdouble))) > blen)) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5badArgument( env, "byteToDouble: start or len is out of bounds"); - return NULL; - } /* end if */ + jdoubleArray rarray; + jboolean bb; + jdouble *darray = NULL; + jdouble *iap = NULL; + jbyte *barr = NULL; + char *bp = NULL; + int blen; + int ii; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToDouble: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToDouble: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: bdata length < 0"); + } + + if ((start < 0) || ((int)(start + (len * (int)sizeof(jdouble))) > blen)) + H5_JNI_FATAL_ERROR(ENVONLY, "byteToDouble: start < 0 or len exceeded buffer length"); bp = (char *)barr + start; - rarray = ENVPTR->NewDoubleArray(ENVPAR len); - if (rarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5outOfMemory( env, "byteToDouble" ); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewDoubleArray(ENVONLY, len))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - iarray = ENVPTR->GetDoubleArrayElements(ENVPAR rarray,&bb); - if (iarray == NULL) { - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); - h5JNIFatalError( env, "byteToDouble: getDouble failed?"); - return NULL; - } /* end if */ + PIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, &bb, "byteToDouble: double array not pinned"); - iap = iarray; + iap = darray; for (ii = 0; ii < len; ii++) { *iap = *(jdouble *)bp; iap++; bp += sizeof(jdouble); } /* end for */ - ENVPTR->ReleaseDoubleArrayElements(ENVPAR rarray,iarray, 0); - ENVPTR->ReleaseByteArrayElements(ENVPAR bdata,barr,JNI_ABORT); +done: + if (darray) + UNPIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToDouble__II_3B */ @@ -629,67 +565,59 @@ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_intToByte__II_3I (JNIEnv *env, jclass clss, jint start, jint len, jintArray idata) /* IN: array of int */ { - jint *ip; - jint *iarr; - int ilen; - jbyteArray rarray; - int blen; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ii; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + jint *ip = NULL; + jint *iarr = NULL; + int ilen; + int blen; + int ii; + int ij; union things { int ival; char bytes[4]; } u; - if (idata == NULL) { - h5nullArgument( env, "intToByte: idata is NULL?"); - return NULL; - } /* end if */ + UNUSED(clss); + + if (NULL == idata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "intToByte: int array is NULL"); - iarr = ENVPTR->GetIntArrayElements(ENVPAR idata,&bb); - if (iarr == NULL) { - h5JNIFatalError( env, "intToByte: getInt failed?"); - return NULL; - } /* end if */ + PIN_INT_ARRAY(ENVONLY, idata, iarr, &bb, "intToByte: int array not pinned"); - ilen = ENVPTR->GetArrayLength(ENVPAR idata); - if ((start < 0) || (((start + len)) > ilen)) { - ENVPTR->ReleaseIntArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5badArgument( env, "intToByte: start or len is out of bounds"); - return NULL; - } /* end if */ + if ((ilen = ENVPTR->GetArrayLength(ENVONLY, idata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "intToByte: idata length < 0"); + } + + if ((start < 0) || (((start + len)) > ilen)) + H5_JNI_FATAL_ERROR(ENVONLY, "intToByte: start < 0 or len exceeded buffer length"); ip = iarr + start; blen = ilen * (int)sizeof(jint); - rarray = ENVPTR->NewByteArray(ENVPAR blen); - if (rarray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5outOfMemory( env, "intToByte" ); - return NULL; - } /* end if */ - - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - ENVPTR->ReleaseIntArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5JNIFatalError( env, "intToByte: getByte failed?"); - return NULL; - } /* end if */ + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, blen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "intToByte: byte array not pinned"); bap = barray; for (ii = 0; ii < len; ii++) { u.ival = *ip++; - for (ij = 0; ij < sizeof(jint); ij++) { + for (ij = 0; (size_t) ij < sizeof(jint); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); - ENVPTR->ReleaseIntArrayElements(ENVPAR idata,iarr,JNI_ABORT); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, rarray ? 0 : JNI_ABORT); + if (iarr) + UNPIN_INT_ARRAY(ENVONLY, idata, iarr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_intToByte__II_3I */ @@ -697,68 +625,61 @@ Java_hdf_hdf5lib_HDFNativeData_intToByte__II_3I /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_shortToByte__II_3S - (JNIEnv *env, jclass clss, jint start, jint len, jshortArray idata) /* IN: array of short */ + (JNIEnv *env, jclass clss, jint start, jint len, jshortArray sdata) /* IN: array of short */ { - jshort *ip; - jshort *iarr; - int ilen; - jbyteArray rarray; - int blen; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ii; - int ij; + jbyteArray rarray; + jboolean bb; + jshort *ip = NULL; + jshort *sarr = NULL; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ilen; + int blen; + int ii; + int ij; union things { short ival; char bytes[4]; } u; - if (idata == NULL) { - h5nullArgument( env, "shortToByte: idata is NULL?"); - return NULL; - } /* end if */ - iarr = ENVPTR->GetShortArrayElements(ENVPAR idata,&bb); - if (iarr == NULL) { - h5JNIFatalError( env, "shortToByte: getShort failed?"); - return NULL; - } /* end if */ - - ilen = ENVPTR->GetArrayLength(ENVPAR idata); - if ((start < 0) || (((start + len)) > ilen)) { - ENVPTR->ReleaseShortArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5badArgument( env, "shortToByte: start or len is out of bounds"); - return NULL; - } /* end if */ + UNUSED(clss); - ip = iarr + start; + if (NULL == sdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "shortToByte: short array is NULL"); + + PIN_SHORT_ARRAY(ENVONLY, sdata, sarr, &bb, "shortToByte: short array not pinned"); + + if ((ilen = ENVPTR->GetArrayLength(ENVONLY, sdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "shortToByte: sdata length < 0"); + } + + if ((start < 0) || (((start + len)) > ilen)) + H5_JNI_FATAL_ERROR(ENVONLY, "shortToByte: start < 0 or len exceeded buffer length"); + + ip = sarr + start; blen = ilen * (int)sizeof(jshort); - rarray = ENVPTR->NewByteArray(ENVPAR blen); - if (rarray == NULL) { - ENVPTR->ReleaseShortArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5outOfMemory( env, "shortToByte" ); - return NULL; - } /* end if */ - - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - ENVPTR->ReleaseShortArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5JNIFatalError( env, "shortToByte: getByte failed?"); - return NULL; - } /* end if */ + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, blen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "shortToByte: byte array not pinned"); bap = barray; for (ii = 0; ii < len; ii++) { u.ival = *ip++; - for (ij = 0; ij < sizeof(jshort); ij++) { + for (ij = 0; (size_t) ij < sizeof(jshort); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); - ENVPTR->ReleaseShortArrayElements(ENVPAR idata,iarr,JNI_ABORT); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, rarray ? 0 : JNI_ABORT); + if (sarr) + UNPIN_SHORT_ARRAY(ENVONLY, sdata, sarr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_shortToByte__II_3S */ @@ -766,68 +687,61 @@ Java_hdf_hdf5lib_HDFNativeData_shortToByte__II_3S /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_floatToByte__II_3F - (JNIEnv *env, jclass clss, jint start, jint len, jfloatArray idata) /* IN: array of float */ + (JNIEnv *env, jclass clss, jint start, jint len, jfloatArray fdata) /* IN: array of float */ { - jfloat *ip; - jfloat *iarr; - int ilen; - jbyteArray rarray; - int blen; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ii; - int ij; + jbyteArray rarray; + jboolean bb; + jfloat *ip = NULL; + jfloat *farr = NULL; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ilen; + int blen; + int ii; + int ij; union things { float ival; char bytes[4]; } u; - if (idata == NULL) { - h5nullArgument( env, "floatToByte: idata is NULL?"); - return NULL; - } /* end if */ - iarr = ENVPTR->GetFloatArrayElements(ENVPAR idata,&bb); - if (iarr == NULL) { - h5JNIFatalError( env, "floatToByte: getFloat failed?"); - return NULL; - } /* end if */ - - ilen = ENVPTR->GetArrayLength(ENVPAR idata); - if ((start < 0) || (((start + len)) > ilen)) { - ENVPTR->ReleaseFloatArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5badArgument( env, "floatToByte: start or len is out of bounds"); - return NULL; - } /* end if */ + UNUSED(clss); - ip = iarr + start; + if (NULL == fdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "floatToByte: float array is NULL"); + + PIN_FLOAT_ARRAY(ENVONLY, fdata, farr, &bb, "floatToByte: float array not pinned"); + + if ((ilen = ENVPTR->GetArrayLength(ENVONLY, fdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "floatToByte: fdata length < 0"); + } + + if ((start < 0) || (((start + len)) > ilen)) + H5_JNI_FATAL_ERROR(ENVONLY, "floatToByte: start < 0 or len exceeded buffer length"); + + ip = farr + start; blen = ilen * (int)sizeof(jfloat); - rarray = ENVPTR->NewByteArray(ENVPAR blen); - if (rarray == NULL) { - ENVPTR->ReleaseFloatArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5outOfMemory( env, "floatToByte" ); - return NULL; - } /* end if */ - - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - ENVPTR->ReleaseFloatArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5JNIFatalError( env, "floatToByte: getByte failed?"); - return NULL; - } /* end if */ + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, blen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "floatToByte: byte array not pinned"); bap = barray; for (ii = 0; ii < len; ii++) { u.ival = *ip++; - for (ij = 0; ij < sizeof(jfloat); ij++) { + for (ij = 0; (size_t) ij < sizeof(jfloat); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); - ENVPTR->ReleaseFloatArrayElements(ENVPAR idata,iarr,JNI_ABORT); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, rarray ? 0 : JNI_ABORT); + if (farr) + UNPIN_FLOAT_ARRAY(ENVONLY, fdata, farr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_floatToByte__II_3F */ @@ -835,178 +749,159 @@ Java_hdf_hdf5lib_HDFNativeData_floatToByte__II_3F /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_doubleToByte__II_3D - (JNIEnv *env, jclass clss, jint start, jint len, jdoubleArray idata) /* IN: array of double */ + (JNIEnv *env, jclass clss, jint start, jint len, jdoubleArray ddata) /* IN: array of double */ { - jdouble *ip; - jdouble *iarr; - int ilen; - jbyteArray rarray; - int blen; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ii; - int ij; + jbyteArray rarray; + jboolean bb; + jdouble *ip = NULL; + jdouble *darr = NULL; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ilen; + int blen; + int ii; + int ij; union things { double ival; char bytes[8]; } u; - if (idata == NULL) { - h5nullArgument( env, "doubleToByte: idata is NULL?"); - return NULL; - } /* end if */ - iarr = ENVPTR->GetDoubleArrayElements(ENVPAR idata,&bb); - if (iarr == NULL) { - h5JNIFatalError( env, "doubleToByte: getDouble failed?"); - return NULL; - } /* end if */ - - ilen = ENVPTR->GetArrayLength(ENVPAR idata); - if ((start < 0) || (((start + len)) > ilen)) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5badArgument( env, "doubleToByte: start or len is out of bounds"); - return NULL; - } /* end if */ + UNUSED(clss); - ip = iarr + start; + if (NULL == ddata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "doubleToByte: double array is NULL"); + + PIN_DOUBLE_ARRAY(ENVONLY, ddata, darr, &bb, "doubleToByte: double array not pinned"); + + if ((ilen = ENVPTR->GetArrayLength(ENVONLY, ddata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "doubleToByte: ddata length < 0"); + } + + if ((start < 0) || (((start + len)) > ilen)) + H5_JNI_FATAL_ERROR(ENVONLY, "doubleToByte: start < 0 or len exceeded buffer length"); + + ip = darr + start; blen = ilen * (int)sizeof(jdouble); - rarray = ENVPTR->NewByteArray(ENVPAR blen); - if (rarray == NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5outOfMemory( env, "doubleToByte" ); - return NULL; - } /* end if */ - - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - ENVPTR->ReleaseDoubleArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5JNIFatalError( env, "doubleToByte: getByte failed?"); - return NULL; - } /* end if */ + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, blen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "doubleToByte: byte array not pinned"); bap = barray; for (ii = 0; ii < len; ii++) { u.ival = *ip++; - for (ij = 0; ij < sizeof(jdouble); ij++) { + for (ij = 0; (size_t) ij < sizeof(jdouble); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); - ENVPTR->ReleaseDoubleArrayElements(ENVPAR idata,iarr,JNI_ABORT); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, rarray ? 0 : JNI_ABORT); + if (darr) + UNPIN_DOUBLE_ARRAY(ENVONLY, ddata, darr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_doubleToByte__II_3D */ - /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_longToByte__II_3J - (JNIEnv *env, jclass clss, jint start, jint len, jlongArray idata) /* IN: array of long */ + (JNIEnv *env, jclass clss, jint start, jint len, jlongArray ldata) /* IN: array of long */ { - jlong *ip; - jlong *iarr; - int ilen; - jbyteArray rarray; - int blen; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ii; - int ij; + jbyteArray rarray; + jboolean bb; + jlong *ip = NULL; + jlong *larr = NULL; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ilen; + int blen; + int ii; + int ij; union things { jlong ival; char bytes[8]; } u; - if (idata == NULL) { - h5nullArgument( env, "longToByte: idata is NULL?"); - return NULL; - } /* end if */ - iarr = ENVPTR->GetLongArrayElements(ENVPAR idata,&bb); - if (iarr == NULL) { - h5JNIFatalError( env, "longToByte: getLong failed?"); - return NULL; - } /* end if */ - - ilen = ENVPTR->GetArrayLength(ENVPAR idata); - if ((start < 0) || (((start + len)) > ilen)) { - ENVPTR->ReleaseLongArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5badArgument( env, "longToByte: start or len is out of bounds?\n"); - return NULL; - } /* end if */ + UNUSED(clss); - ip = iarr + start; + if (NULL == ldata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "longToByte: long array is NULL"); + + PIN_LONG_ARRAY(ENVONLY, ldata, larr, &bb, "longToByte: long array not pinned"); + + if ((ilen = ENVPTR->GetArrayLength(ENVONLY, ldata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "longToByte: ldata length < 0"); + } + + if ((start < 0) || (((start + len)) > ilen)) + H5_JNI_FATAL_ERROR(ENVONLY, "longToByte: start < 0 or len exceeded buffer length"); + + ip = larr + start; blen = ilen * (int)sizeof(jlong); - rarray = ENVPTR->NewByteArray(ENVPAR blen); - if (rarray == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5outOfMemory( env, "longToByte" ); - return NULL; - } /* end if */ - - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - ENVPTR->ReleaseLongArrayElements(ENVPAR idata,iarr,JNI_ABORT); - h5JNIFatalError( env, "longToByte: getByte failed?"); - return NULL; - } /* end if */ + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, blen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "longToByte: byte array not pinned"); bap = barray; for (ii = 0; ii < len; ii++) { u.ival = *ip++; - for (ij = 0; ij < sizeof(jlong); ij++) { + for (ij = 0; (size_t) ij < sizeof(jlong); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); - ENVPTR->ReleaseLongArrayElements(ENVPAR idata,iarr,JNI_ABORT); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, rarray ? 0 : JNI_ABORT); + if (larr) + UNPIN_LONG_ARRAY(ENVONLY, ldata, larr, JNI_ABORT); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_longToByte__II_3J */ - /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_intToByte__I (JNIEnv *env, jclass clss, jint idata) /* IN: int */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - int ij; - jboolean bb; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { int ival; char bytes[sizeof(int)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jint)); - if (rarray == NULL) { - h5outOfMemory( env, "intToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jint)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "intToByte: getByte failed?"); - return NULL; - } /* end if */ + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "intToByte: byte array not pinned"); bap = barray; u.ival = idata; - for (ij = 0; ij < sizeof(jint); ij++) { + for (ij = 0; (size_t) ij < sizeof(jint); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_intToByte__I */ @@ -1014,38 +909,35 @@ Java_hdf_hdf5lib_HDFNativeData_intToByte__I /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_floatToByte__F - (JNIEnv *env, jclass clss, jfloat idata) /* IN: int */ + (JNIEnv *env, jclass clss, jfloat fdata) /* IN: float */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { float ival; char bytes[sizeof(float)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jfloat)); - if (rarray == NULL) { - h5outOfMemory( env, "floatToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "floatToByte: getByte failed?"); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jfloat)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "floatToByte: byte array not pinned"); bap = barray; - u.ival = idata; - for (ij = 0; ij < sizeof(jfloat); ij++) { + u.ival = fdata; + for (ij = 0; (size_t) ij < sizeof(jfloat); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,(jbyte *)barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_floatToByte__F */ @@ -1053,118 +945,107 @@ Java_hdf_hdf5lib_HDFNativeData_floatToByte__F /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_shortToByte__S - (JNIEnv *env, jclass clss, jshort idata) /* IN: short */ + (JNIEnv *env, jclass clss, jshort sdata) /* IN: short */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { short ival; char bytes[sizeof(short)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jshort)); - if (rarray == NULL) { - h5outOfMemory( env, "shortToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "shortToByte: getShort failed?"); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jshort)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "shortToByte: byte array not pinned"); bap = barray; - u.ival = idata; - for (ij = 0; ij < sizeof(jshort); ij++) { + u.ival = sdata; + for (ij = 0; (size_t) ij < sizeof(jshort); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,(jbyte *)barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_shortToByte__S */ - /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_doubleToByte__D - (JNIEnv *env, jclass clss, jdouble idata) /* IN: double */ + (JNIEnv *env, jclass clss, jdouble ddata) /* IN: double */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { double ival; char bytes[sizeof(double)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jdouble)); - if (rarray == NULL) { - h5outOfMemory( env, "doubleToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); + + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jdouble)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "doubleToByte: getDouble failed?"); - return NULL; - } /* end if */ + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "doubleToByte: byte array not pinned"); bap = barray; - u.ival = idata; - for (ij = 0; ij < sizeof(jdouble); ij++) { + u.ival = ddata; + for (ij = 0; (size_t) ij < sizeof(jdouble); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,(jbyte *)barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_doubleToByte__D */ - /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_longToByte__J - (JNIEnv *env, jclass clss, jlong idata) /* IN: array of long */ + (JNIEnv *env, jclass clss, jlong ldata) /* IN: long */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { jlong ival; char bytes[sizeof(jlong)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jlong)); - if (rarray == NULL) { - h5outOfMemory( env, "longToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "longToByte: getLong failed?"); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jlong)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "longToByte: byte array not pinned"); bap = barray; - u.ival = idata; - for (ij = 0; ij < sizeof(jlong); ij++) { + u.ival = ldata; + for (ij = 0; (size_t) ij < sizeof(jlong); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,(jbyte *)barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_longToByte__J */ @@ -1172,38 +1053,35 @@ Java_hdf_hdf5lib_HDFNativeData_longToByte__J /* returns byte [] */ JNIEXPORT jbyteArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToByte__B - (JNIEnv *env, jclass clss, jbyte idata) /* IN: array of long */ + (JNIEnv *env, jclass clss, jbyte bdata) /* IN: byte */ { - jbyteArray rarray; - jbyte *barray; - jbyte *bap; - jboolean bb; - int ij; + jbyteArray rarray; + jboolean bb; + jbyte *barray = NULL; + jbyte *bap = NULL; + int ij; union things { jbyte ival; char bytes[sizeof(jbyte)]; } u; - rarray = ENVPTR->NewByteArray(ENVPAR sizeof(jbyte)); - if (rarray == NULL) { - h5outOfMemory( env, "byteToByte" ); - return NULL; - } /* end if */ + UNUSED(clss); - barray = ENVPTR->GetByteArrayElements(ENVPAR rarray,&bb); - if (barray == NULL) { - h5JNIFatalError( env, "byteToByte: getByte failed?"); - return NULL; - } /* end if */ + if (NULL == (rarray = ENVPTR->NewByteArray(ENVONLY, sizeof(jbyte)))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_BYTE_ARRAY(ENVONLY, rarray, barray, &bb, "byteToByte: byte array not pinned"); bap = barray; - u.ival = idata; - for (ij = 0; ij < sizeof(jbyte); ij++) { + u.ival = bdata; + for (ij = 0; (size_t) ij < sizeof(jbyte); ij++) { *bap = u.bytes[ij]; bap++; } /* end for */ - ENVPTR->ReleaseByteArrayElements(ENVPAR rarray,(jbyte *)barray, 0); +done: + if (barray) + UNPIN_BYTE_ARRAY(ENVONLY, rarray, barray, 0); return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToByte__B */ diff --git a/java/test/TestH5.java b/java/test/TestH5.java index 54603ca..c59101b 100644 --- a/java/test/TestH5.java +++ b/java/test/TestH5.java @@ -177,6 +177,23 @@ public class TestH5 { for (int i = 0; i < 2; i++) assertFalse(libversion[i] == 0); } + + /** + * Test method for {@link hdf.hdf5lib.H5#H5get_libversion(int[])} + * to ensure a null libversion parameter causes the function to + * fail. + */ + @Test + public void testH5get_libversion_null_param() { + try { + H5.H5get_libversion(null); + } + catch (Throwable err) { + return; + } + + fail("H5.H5get_libversion: succeeded with a null libversion parameter!"); + } /** * Test method for diff --git a/java/test/testfiles/JUnit-TestH5.txt b/java/test/testfiles/JUnit-TestH5.txt index 37c5b65..b282a91 100644 --- a/java/test/testfiles/JUnit-TestH5.txt +++ b/java/test/testfiles/JUnit-TestH5.txt @@ -1,4 +1,5 @@ JUnit version 4.11 +.testH5get_libversion_null_param .testJ2C .testIsSerializable .testH5garbage_collect @@ -11,5 +12,5 @@ JUnit version 4.11 Time: XXXX -OK (9 tests) +OK (10 tests) diff --git a/src/H5Torder.c b/src/H5Torder.c index d687d03..62662d6 100644 --- a/src/H5Torder.c +++ b/src/H5Torder.c @@ -100,11 +100,11 @@ H5Tget_order(hid_t type_id) /* Check args */ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_ORDER_ERROR, "not a datatype") + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, H5T_ORDER_ERROR, "not a datatype") /* Get order */ if(H5T_ORDER_ERROR == (ret_value = H5T_get_order(dt))) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "cant't get order for specified datatype") + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "can't get order for specified datatype") done: FUNC_LEAVE_API(ret_value) -- cgit v0.12 From d98faf57030a2843511047fa701acf379569a2d6 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 11 Feb 2019 11:09:43 -0600 Subject: Rename parallel tests to start with PAR_ --- examples/CMakeTests.cmake | 4 ++-- fortran/examples/CMakeTests.cmake | 4 ++-- fortran/testpar/CMakeTests.cmake | 2 +- testpar/CMakeTests.cmake | 10 +++++----- testpar/CMakeVFDTests.cmake | 2 +- tools/test/h5diff/CMakeTests.cmake | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index dd1e03b..9fc12eb 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -181,9 +181,9 @@ ### Windows pops up a modal permission dialog on this test if (H5_HAVE_PARALLEL AND NOT WIN32) if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME EXAMPLES_PAR-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME PAR_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) else () - add_test (NAME EXAMPLES_PAR-ph5example COMMAND "${CMAKE_COMMAND}" + add_test (NAME PAR_EXAMPLES-ph5example COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" diff --git a/fortran/examples/CMakeTests.cmake b/fortran/examples/CMakeTests.cmake index 323cf91..3dd5d6a 100644 --- a/fortran/examples/CMakeTests.cmake +++ b/fortran/examples/CMakeTests.cmake @@ -151,8 +151,8 @@ foreach (example ${F2003_examples}) endforeach () if (H5_HAVE_PARALLEL AND MPI_Fortran_FOUND) - add_test (NAME f90_ex_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME PAR_f90_ex_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) if (BUILD_SHARED_LIBS) - add_test (NAME f90_ex-shared_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME PAR_f90_ex-shared_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) endif () endif () diff --git a/fortran/testpar/CMakeTests.cmake b/fortran/testpar/CMakeTests.cmake index d00a6fc..12fd13b 100644 --- a/fortran/testpar/CMakeTests.cmake +++ b/fortran/testpar/CMakeTests.cmake @@ -15,4 +15,4 @@ ### T E S T I N G ### ############################################################################## ############################################################################## -add_test (NAME FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME PAR_FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) diff --git a/testpar/CMakeTests.cmake b/testpar/CMakeTests.cmake index a0d7f59..a7c606d 100644 --- a/testpar/CMakeTests.cmake +++ b/testpar/CMakeTests.cmake @@ -16,16 +16,16 @@ ############################################################################## ############################################################################## -add_test (NAME TEST_PAR_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME PAR_TEST_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) foreach (testp ${H5P_TESTS}) - add_test (NAME TEST_PAR_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME PAR_TEST_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) endforeach () # The t_pflush1 test is hard-coded to fail. -set_tests_properties (TEST_PAR_t_pflush1 PROPERTIES WILL_FAIL "true") -#set_property (TEST TEST_PAR_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") -set_tests_properties (TEST_PAR_t_pflush2 PROPERTIES DEPENDS TEST_PAR_t_pflush1) +set_tests_properties (PAR_TEST_t_pflush1 PROPERTIES WILL_FAIL "true") +#set_property (TEST PAR_TEST_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") +set_tests_properties (PAR_TEST_t_pflush2 PROPERTIES DEPENDS PAR_TEST_t_pflush1) ############################################################################## ############################################################################## diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index b6b065f..ed6c898 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -37,7 +37,7 @@ if (NOT HDF5_ENABLE_USING_MEMCHECKER) foreach (test ${H5P_VFD_TESTS}) add_test ( - NAME TEST_PAR_VFD-${vfdname}-${test} + NAME PAR_TEST_VFD-${vfdname}-${test} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 24646b0..fc0018b 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -394,7 +394,7 @@ macro (ADD_PH5_TEST resultfile resultcode) # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME PH5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) + add_test (NAME PAR_H5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) set_tests_properties (PH5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles") if (NOT "${resultcode}" STREQUAL "0") set_tests_properties (PH5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") -- cgit v0.12 From edcbc9966f5c742970ad32eb50a7925fcf7ab677 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 11 Feb 2019 12:01:25 -0600 Subject: Refactor parallel test names --- bin/batch/cori_ctestP.sl.in.cmake | 2 +- bin/batch/cori_ctestS.sl.in.cmake | 2 +- bin/batch/cori_knl_ctestP.sl.in.cmake | 2 +- bin/batch/cori_knl_ctestS.sl.in.cmake | 2 +- bin/batch/ctestP.sl.in.cmake | 2 +- bin/batch/ctestS.sl.in.cmake | 2 +- bin/batch/knl_ctestP.sl.in.cmake | 2 +- bin/batch/knl_ctestS.sl.in.cmake | 2 +- bin/batch/ray_ctestP.lsf.in.cmake | 2 +- bin/batch/ray_ctestS.lsf.in.cmake | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bin/batch/cori_ctestP.sl.in.cmake b/bin/batch/cori_ctestP.sl.in.cmake index 6aa4916..af43410 100644 --- a/bin/batch/cori_ctestP.sl.in.cmake +++ b/bin/batch/cori_ctestP.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R TEST_PAR|PH5DIFF|PERFORM|ph5example -E t_cache_image -C Release -T test" +CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/cori_ctestS.sl.in.cmake b/bin/batch/cori_ctestS.sl.in.cmake index cf68826..be9267a 100644 --- a/bin/batch/cori_ctestS.sl.in.cmake +++ b/bin/batch/cori_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E TEST_PAR|PH5DIFF|PERFORM|ph5example -C Release -j 32 -T test" +CMD="ctest . -E PAR_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/cori_knl_ctestP.sl.in.cmake b/bin/batch/cori_knl_ctestP.sl.in.cmake index 90dd52a..38fa81d 100644 --- a/bin/batch/cori_knl_ctestP.sl.in.cmake +++ b/bin/batch/cori_knl_ctestP.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R TEST_PAR|PH5DIFF|PERFORM|ph5example -E t_cache_image -C Release -T test" +CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/cori_knl_ctestS.sl.in.cmake b/bin/batch/cori_knl_ctestS.sl.in.cmake index 7db4483..5474672 100644 --- a/bin/batch/cori_knl_ctestS.sl.in.cmake +++ b/bin/batch/cori_knl_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E TEST_PAR|PH5DIFF|PERFORM|ph5example -C Release -j 32 -T test" +CMD="ctest . -E PAR_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/ctestP.sl.in.cmake b/bin/batch/ctestP.sl.in.cmake index 9fed14d..eadf336 100644 --- a/bin/batch/ctestP.sl.in.cmake +++ b/bin/batch/ctestP.sl.in.cmake @@ -8,7 +8,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R TEST_PAR|PH5DIFF|PERFORM|ph5example -E t_cache_image -C Release -T test" +CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/ctestS.sl.in.cmake b/bin/batch/ctestS.sl.in.cmake index 98c1bcd..6f97d2b 100644 --- a/bin/batch/ctestS.sl.in.cmake +++ b/bin/batch/ctestS.sl.in.cmake @@ -8,7 +8,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E TEST_PAR|PH5DIFF|PERFORM|ph5example -C Release -j 32 -T test" +CMD="ctest . -E PAR_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/knl_ctestP.sl.in.cmake b/bin/batch/knl_ctestP.sl.in.cmake index 5c7c83f..3e5cbe5 100644 --- a/bin/batch/knl_ctestP.sl.in.cmake +++ b/bin/batch/knl_ctestP.sl.in.cmake @@ -10,7 +10,7 @@ cd @HDF5_BINARY_DIR@ #run parallel tests except t_cache_image test -CMD="ctest . -R TEST_PAR|PH5DIFF|PERFORM|ph5example -E t_cache_image -C Release -T test" +CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/knl_ctestS.sl.in.cmake b/bin/batch/knl_ctestS.sl.in.cmake index 0dae31f..d099666 100644 --- a/bin/batch/knl_ctestS.sl.in.cmake +++ b/bin/batch/knl_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E TEST_PAR|PH5DIFF|PERFORM|ph5example -C Release -j 32 -T test" +CMD="ctest . -E PAR_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/ray_ctestP.lsf.in.cmake b/bin/batch/ray_ctestP.lsf.in.cmake index 6b5316a..8ffaf8c 100644 --- a/bin/batch/ray_ctestP.lsf.in.cmake +++ b/bin/batch/ray_ctestP.lsf.in.cmake @@ -15,6 +15,6 @@ cd @HDF5_BINARY_DIR@ echo "Run parallel test command. Test output will be in build/ctestP.out" -ctest . -R 'TEST_PAR|PH5DIFF|PERFORM|ph5example' -E t_cache_image -C Release -T test >& ctestP.out +ctest . -R 'PAR_' -E t_cache_image -C Release -T test >& ctestP.out echo "Done running ctest parallel command." diff --git a/bin/batch/ray_ctestS.lsf.in.cmake b/bin/batch/ray_ctestS.lsf.in.cmake index d23a513..5bd5c83 100644 --- a/bin/batch/ray_ctestS.lsf.in.cmake +++ b/bin/batch/ray_ctestS.lsf.in.cmake @@ -11,7 +11,7 @@ cd @HDF5_BINARY_DIR@ echo "Run command. Test output will be in build/ctestS.out" -ctest . -E 'TEST_PAR|PH5DIFF|PERFORM|ph5example' -C Release -j 32 -T test >& ctestS.out +ctest . -E 'PAR_' -C Release -j 32 -T test >& ctestS.out ##$CMD >& ctestS.out echo "Done running command." -- cgit v0.12 From 6f71b2cdcf3326b1d7bc67cf664b56d2f4056bfd Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 11 Feb 2019 12:42:19 -0600 Subject: Refactor mpi test names --- bin/batch/cori_ctestP.sl.in.cmake | 2 +- bin/batch/cori_ctestS.sl.in.cmake | 2 +- bin/batch/cori_knl_ctestP.sl.in.cmake | 2 +- bin/batch/cori_knl_ctestS.sl.in.cmake | 2 +- bin/batch/ctestP.sl.in.cmake | 2 +- bin/batch/ctestS.sl.in.cmake | 2 +- bin/batch/knl_ctestP.sl.in.cmake | 2 +- bin/batch/knl_ctestS.sl.in.cmake | 2 +- bin/batch/ray_ctestP.lsf.in.cmake | 2 +- bin/batch/ray_ctestS.lsf.in.cmake | 2 +- examples/CMakeTests.cmake | 18 +++++++++--------- fortran/examples/CMakeTests.cmake | 4 ++-- fortran/testpar/CMakeTests.cmake | 2 +- testpar/CMakeTests.cmake | 10 +++++----- testpar/CMakeVFDTests.cmake | 2 +- tools/test/h5diff/CMakeTests.cmake | 16 ++++++++-------- tools/test/perform/CMakeTests.cmake | 4 ++-- 17 files changed, 38 insertions(+), 38 deletions(-) diff --git a/bin/batch/cori_ctestP.sl.in.cmake b/bin/batch/cori_ctestP.sl.in.cmake index af43410..287fe3c 100644 --- a/bin/batch/cori_ctestP.sl.in.cmake +++ b/bin/batch/cori_ctestP.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" +CMD="ctest . -R MPI_TEST_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/cori_ctestS.sl.in.cmake b/bin/batch/cori_ctestS.sl.in.cmake index be9267a..50bef6b 100644 --- a/bin/batch/cori_ctestS.sl.in.cmake +++ b/bin/batch/cori_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E PAR_ -C Release -j 32 -T test" +CMD="ctest . -E MPI_TEST_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/cori_knl_ctestP.sl.in.cmake b/bin/batch/cori_knl_ctestP.sl.in.cmake index 38fa81d..82378ec 100644 --- a/bin/batch/cori_knl_ctestP.sl.in.cmake +++ b/bin/batch/cori_knl_ctestP.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" +CMD="ctest . -R MPI_TEST_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/cori_knl_ctestS.sl.in.cmake b/bin/batch/cori_knl_ctestS.sl.in.cmake index 5474672..bcb4881 100644 --- a/bin/batch/cori_knl_ctestS.sl.in.cmake +++ b/bin/batch/cori_knl_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E PAR_ -C Release -j 32 -T test" +CMD="ctest . -E MPI_TEST_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/ctestP.sl.in.cmake b/bin/batch/ctestP.sl.in.cmake index eadf336..8d216d6 100644 --- a/bin/batch/ctestP.sl.in.cmake +++ b/bin/batch/ctestP.sl.in.cmake @@ -8,7 +8,7 @@ #SBATCH --job-name=h5_ctestP cd @HDF5_BINARY_DIR@ -CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" +CMD="ctest . -R MPI_TEST_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/ctestS.sl.in.cmake b/bin/batch/ctestS.sl.in.cmake index 6f97d2b..4f96bb9 100644 --- a/bin/batch/ctestS.sl.in.cmake +++ b/bin/batch/ctestS.sl.in.cmake @@ -8,7 +8,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E PAR_ -C Release -j 32 -T test" +CMD="ctest . -E MPI_TEST_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/knl_ctestP.sl.in.cmake b/bin/batch/knl_ctestP.sl.in.cmake index 3e5cbe5..79dfb89 100644 --- a/bin/batch/knl_ctestP.sl.in.cmake +++ b/bin/batch/knl_ctestP.sl.in.cmake @@ -10,7 +10,7 @@ cd @HDF5_BINARY_DIR@ #run parallel tests except t_cache_image test -CMD="ctest . -R PAR_ -E t_cache_image -C Release -T test" +CMD="ctest . -R MPI_TEST_ -E t_cache_image -C Release -T test" echo "Run $CMD. Test output will be in build/ctestP.out" $CMD >& ctestP.out diff --git a/bin/batch/knl_ctestS.sl.in.cmake b/bin/batch/knl_ctestS.sl.in.cmake index d099666..af6353b 100644 --- a/bin/batch/knl_ctestS.sl.in.cmake +++ b/bin/batch/knl_ctestS.sl.in.cmake @@ -9,7 +9,7 @@ #SBATCH --job-name=h5_ctestS cd @HDF5_BINARY_DIR@ -CMD="ctest . -E PAR_ -C Release -j 32 -T test" +CMD="ctest . -E MPI_TEST_ -C Release -j 32 -T test" echo "Run $CMD. Test output will be in build/ctestS.out" $CMD >& ctestS.out diff --git a/bin/batch/ray_ctestP.lsf.in.cmake b/bin/batch/ray_ctestP.lsf.in.cmake index 8ffaf8c..082276a 100644 --- a/bin/batch/ray_ctestP.lsf.in.cmake +++ b/bin/batch/ray_ctestP.lsf.in.cmake @@ -15,6 +15,6 @@ cd @HDF5_BINARY_DIR@ echo "Run parallel test command. Test output will be in build/ctestP.out" -ctest . -R 'PAR_' -E t_cache_image -C Release -T test >& ctestP.out +ctest . -R 'MPI_TEST_' -E t_cache_image -C Release -T test >& ctestP.out echo "Done running ctest parallel command." diff --git a/bin/batch/ray_ctestS.lsf.in.cmake b/bin/batch/ray_ctestS.lsf.in.cmake index 5bd5c83..da20438 100644 --- a/bin/batch/ray_ctestS.lsf.in.cmake +++ b/bin/batch/ray_ctestS.lsf.in.cmake @@ -11,7 +11,7 @@ cd @HDF5_BINARY_DIR@ echo "Run command. Test output will be in build/ctestS.out" -ctest . -E 'PAR_' -C Release -j 32 -T test >& ctestS.out +ctest . -E 'MPI_TEST_' -C Release -j 32 -T test >& ctestS.out ##$CMD >& ctestS.out echo "Done running command." diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index 9fc12eb..cb47c78 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -181,9 +181,9 @@ ### Windows pops up a modal permission dialog on this test if (H5_HAVE_PARALLEL AND NOT WIN32) if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME PAR_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) else () - add_test (NAME PAR_EXAMPLES-ph5example COMMAND "${CMAKE_COMMAND}" + add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" @@ -195,14 +195,14 @@ ) endif () if (NOT "${last_test}" STREQUAL "") - set_tests_properties (EXAMPLES_PAR-ph5example PROPERTIES DEPENDS ${last_test}) + set_tests_properties (MPI_TEST_EXAMPLES-ph5example PROPERTIES DEPENDS ${last_test}) endif () - set (last_test "EXAMPLES_PAR-ph5example") + set (last_test "MPI_TEST_EXAMPLES-ph5example") if (BUILD_SHARED_LIBS) if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME EXAMPLES_PAR-shared-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_EXAMPLES-shared-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) else () - add_test (NAME EXAMPLES_PAR-shared-ph5example COMMAND "${CMAKE_COMMAND}" + add_test (NAME MPI_TEST_EXAMPLES-shared-ph5example COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" @@ -213,10 +213,10 @@ -P "${HDF_RESOURCES_EXT_DIR}/grepTest.cmake" ) endif () - set_tests_properties (EXAMPLES_PAR-shared-ph5example PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/H5EX-shared) + set_tests_properties (MPI_TEST_EXAMPLES-shared-ph5example PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/H5EX-shared) if (NOT "${last_test}" STREQUAL "") - set_tests_properties (EXAMPLES_PAR-shared-ph5example PROPERTIES DEPENDS ${last_test}) + set_tests_properties (MPI_TEST_EXAMPLES-shared-ph5example PROPERTIES DEPENDS ${last_test}) endif () - set (last_test "EXAMPLES_PAR-shared-ph5example") + set (last_test "MPI_TEST_EXAMPLES-shared-ph5example") endif () endif () diff --git a/fortran/examples/CMakeTests.cmake b/fortran/examples/CMakeTests.cmake index 3dd5d6a..face086 100644 --- a/fortran/examples/CMakeTests.cmake +++ b/fortran/examples/CMakeTests.cmake @@ -151,8 +151,8 @@ foreach (example ${F2003_examples}) endforeach () if (H5_HAVE_PARALLEL AND MPI_Fortran_FOUND) - add_test (NAME PAR_f90_ex_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_f90_ex_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) if (BUILD_SHARED_LIBS) - add_test (NAME PAR_f90_ex-shared_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_f90_ex-shared_ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) endif () endif () diff --git a/fortran/testpar/CMakeTests.cmake b/fortran/testpar/CMakeTests.cmake index 12fd13b..d0abe0e 100644 --- a/fortran/testpar/CMakeTests.cmake +++ b/fortran/testpar/CMakeTests.cmake @@ -15,4 +15,4 @@ ### T E S T I N G ### ############################################################################## ############################################################################## -add_test (NAME PAR_FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME MPI_TEST_FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) diff --git a/testpar/CMakeTests.cmake b/testpar/CMakeTests.cmake index a7c606d..b71e7bc 100644 --- a/testpar/CMakeTests.cmake +++ b/testpar/CMakeTests.cmake @@ -16,16 +16,16 @@ ############################################################################## ############################################################################## -add_test (NAME PAR_TEST_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME MPI_TEST_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) foreach (testp ${H5P_TESTS}) - add_test (NAME PAR_TEST_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) endforeach () # The t_pflush1 test is hard-coded to fail. -set_tests_properties (PAR_TEST_t_pflush1 PROPERTIES WILL_FAIL "true") -#set_property (TEST PAR_TEST_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") -set_tests_properties (PAR_TEST_t_pflush2 PROPERTIES DEPENDS PAR_TEST_t_pflush1) +set_tests_properties (MPI_TEST_t_pflush1 PROPERTIES WILL_FAIL "true") +#set_property (TEST MPI_TEST_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") +set_tests_properties (MPI_TEST_t_pflush2 PROPERTIES DEPENDS MPI_TEST_t_pflush1) ############################################################################## ############################################################################## diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index ed6c898..e2bf88a 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -37,7 +37,7 @@ if (NOT HDF5_ENABLE_USING_MEMCHECKER) foreach (test ${H5P_VFD_TESTS}) add_test ( - NAME PAR_TEST_VFD-${vfdname}-${test} + NAME MPI_TEST_VFD-${vfdname}-${test} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index fc0018b..1376e0d 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -394,28 +394,28 @@ macro (ADD_PH5_TEST resultfile resultcode) # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME PAR_H5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) - set_tests_properties (PH5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles") + add_test (NAME MPI_TEST_H5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles") if (NOT "${resultcode}" STREQUAL "0") - set_tests_properties (PH5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") endif () if (NOT "${last_test}" STREQUAL "") - set_tests_properties (PH5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () # Remove any output file left over from previous test run add_test ( - NAME PH5DIFF-${resultfile}-clear-objects + NAME MPI_TEST_H5DIFF-${resultfile}-clear-objects COMMAND ${CMAKE_COMMAND} -E remove PAR/testfiles/${resultfile}.out PAR/testfiles/${resultfile}.out.err ) if (NOT "${last_test}" STREQUAL "") - set_tests_properties (PH5DIFF-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( - NAME PH5DIFF-${resultfile} + NAME MPI_TEST_H5DIFF-${resultfile} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=${ARGN}" @@ -429,7 +429,7 @@ -D "TEST_SORT_COMPARE=TRUE" -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) - set_tests_properties (PH5DIFF-${resultfile} PROPERTIES DEPENDS PH5DIFF-${resultfile}-clear-objects) + set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES DEPENDS MPI_TEST_H5DIFF-${resultfile}-clear-objects) set (last_test "PH5DIFF-${resultfile}") endif () endmacro () diff --git a/tools/test/perform/CMakeTests.cmake b/tools/test/perform/CMakeTests.cmake index 02dc15d..36172d1 100644 --- a/tools/test/perform/CMakeTests.cmake +++ b/tools/test/perform/CMakeTests.cmake @@ -170,9 +170,9 @@ endif () set_tests_properties (PERFORM_zip_perf PROPERTIES DEPENDS "PERFORM_zip_perf_help;PERFORM_h5perform-clearall-objects") if (H5_HAVE_PARALLEL) - add_test (NAME PAR_PERFORM_h5perf COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_PERFORM_h5perf COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) if (HDF5_BUILD_PERFORM_STANDALONE) - add_test (NAME PAR_PERFORM_h5perf_alone COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_PERFORM_h5perf_alone COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) endif () endif () -- cgit v0.12 From 65a820ae8981a84fe7fbac87c48482e9f82b35f4 Mon Sep 17 00:00:00 2001 From: Jordan Henderson Date: Fri, 25 Jan 2019 15:32:51 -0600 Subject: Fix some collective metadata read issues --- release_docs/RELEASE.txt | 16 +++ src/H5C.c | 55 ++------ src/H5CX.c | 4 +- src/H5Cimage.c | 4 +- src/H5Dchunk.c | 22 +--- src/H5Dmpio.c | 6 +- src/H5Z.c | 2 +- testpar/t_cache.c | 16 +-- testpar/t_coll_md_read.c | 336 +++++++++++++++++++++++++++++++++++++++++++++-- testpar/testphdf5.c | 5 +- testpar/testphdf5.h | 2 + 11 files changed, 381 insertions(+), 87 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 2dfcfc1..9e63045 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -264,6 +264,22 @@ Bug Fixes since HDF5-1.10.3 release Library ------- + - Fix hangs with collective metadata reads during chunked dataset I/O + + In the parallel library, it was discovered that when a particular + sequence of operations following a pattern of: + + "write to chunked dataset" -> "flush file" -> "read from dataset" + + occurred with collective metadata reads enabled, hangs could be + observed due to certain MPI ranks not participating in the collective + metadata reads. + + To fix the issue, collective metadata reads are now disabled during + chunked dataset raw data I/O. + + (JTH - 2019/02/11, HDFFV-10563, HDFFV-10688) + - Deleting attributes in dense storage The library aborts with "infinite loop closing library" after diff --git a/src/H5C.c b/src/H5C.c index b5dc6a5..70eb7ba 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -1482,31 +1482,17 @@ H5C_insert_entry(H5F_t * f, H5C__UPDATE_STATS_FOR_INSERTION(cache_ptr, entry_ptr) #ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) { - coll_access = (H5P_USER_TRUE == f->coll_md_read ? TRUE : FALSE); - - /* If not explicitly disabled, get the cmdr setting from the API context */ - if(!coll_access && H5P_FORCE_FALSE != f->coll_md_read) - coll_access = H5CX_get_coll_metadata_read(); - } /* end if */ + if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) + coll_access = H5CX_get_coll_metadata_read(); entry_ptr->coll_access = coll_access; if(coll_access) { H5C__INSERT_IN_COLL_LIST(cache_ptr, entry_ptr, FAIL) /* Make sure the size of the collective entries in the cache remain in check */ - if(H5P_USER_TRUE == f->coll_md_read) { - if(cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100) { - if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries") - } /* end if */ - } /* end if */ - else { - if(cache_ptr->max_cache_size * 40 < cache_ptr->coll_list_size * 100) { - if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries") - } /* end if */ - } /* end else */ + if(cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100) + if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't clear collective metadata entries") } /* end if */ #endif @@ -2242,13 +2228,8 @@ H5C_protect(H5F_t * f, ring = H5CX_get_ring(); #ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) { - coll_access = (H5P_USER_TRUE == f->coll_md_read ? TRUE : FALSE); - - /* If not explicitly disabled, get the cmdr setting from the API context */ - if(!coll_access && H5P_FORCE_FALSE != f->coll_md_read) - coll_access = H5CX_get_coll_metadata_read(); - } /* end if */ + if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) + coll_access = H5CX_get_coll_metadata_read(); #endif /* H5_HAVE_PARALLEL */ /* first check to see if the target is in cache */ @@ -2285,7 +2266,7 @@ H5C_protect(H5F_t * f, the entry in their cache still have to participate in the bcast. */ #ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI) && coll_access) { + if(coll_access) { if(!(entry_ptr->is_dirty) && !(entry_ptr->coll_access)) { MPI_Comm comm; /* File MPI Communicator */ int mpi_code; /* MPI error code */ @@ -2600,21 +2581,11 @@ H5C_protect(H5F_t * f, } /* end if */ #ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) { - /* Make sure the size of the collective entries in the cache remain in check */ - if(coll_access) { - if(H5P_USER_TRUE == f->coll_md_read) { - if(cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100) - if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries") - } /* end if */ - else { - if(cache_ptr->max_cache_size * 40 < cache_ptr->coll_list_size * 100) - if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries") - } /* end else */ - } /* end if */ - } /* end if */ + /* Make sure the size of the collective entries in the cache remain in check */ + if(coll_access) + if(cache_ptr->max_cache_size * 80 < cache_ptr->coll_list_size * 100) + if(H5C_clear_coll_entries(cache_ptr, TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "can't clear collective metadata entries") #endif /* H5_HAVE_PARALLEL */ done: diff --git a/src/H5CX.c b/src/H5CX.c index 0d20132..f945df0 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -815,8 +815,8 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, #ifdef H5_HAVE_PARALLEL /* If this routine is not guaranteed to be collective (i.e. it doesn't - * modify the structural metadata in a file), check if we should use - * a collective metadata read. + * modify the structural metadata in a file), check if the application + * specified a collective metadata read for just this operation. */ if(!is_collective) { H5P_genplist_t *plist; /* Property list pointer */ diff --git a/src/H5Cimage.c b/src/H5Cimage.c index bdab1a3..4684630 100644 --- a/src/H5Cimage.c +++ b/src/H5Cimage.c @@ -1065,9 +1065,9 @@ H5C__read_cache_image(H5F_t *f, H5C_t *cache_ptr) H5C__UPDATE_STATS_FOR_CACHE_IMAGE_READ(cache_ptr) #ifdef H5_HAVE_PARALLEL - if ( aux_ptr ) { + if ( aux_ptr ) { - /* Broadcast cache image */ + /* Broadcast cache image */ if ( MPI_SUCCESS != (mpi_result = MPI_Bcast(cache_ptr->image_buffer, (int)cache_ptr->image_len, MPI_BYTE, diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index e165569..af8ff91 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -2914,9 +2914,6 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, /* Check for cached information */ if(!H5D__chunk_cinfo_cache_found(&dset->shared->cache.chunk.last, udata)) { H5D_chk_idx_info_t idx_info; /* Chunked index info */ -#ifdef H5_HAVE_PARALLEL - H5P_coll_md_read_flag_t temp_cmr; /* Temp value to hold the coll metadata read setting */ -#endif /* H5_HAVE_PARALLEL */ /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; @@ -2925,25 +2922,18 @@ H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, idx_info.storage = &dset->shared->layout.storage.u.chunk; #ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) { - /* disable collective metadata read for chunk indexes - as it is highly unlikely that users would read the - same chunks from all processes. MSC - might turn on - for root node? */ - temp_cmr = H5F_COLL_MD_READ(idx_info.f); - H5F_set_coll_md_read(idx_info.f, H5P_FORCE_FALSE); - } /* end if */ + /* Disable collective metadata read for chunk indexes as it is + * highly unlikely that users would read the same chunks from all + * processes. + */ + if(H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) + H5CX_set_coll_metadata_read(FALSE); #endif /* H5_HAVE_PARALLEL */ /* Go get the chunk information */ if((dset->shared->layout.storage.u.chunk.ops->get_addr)(&idx_info, udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query chunk address") -#ifdef H5_HAVE_PARALLEL - if(H5F_HAS_FEATURE(idx_info.f, H5FD_FEAT_HAS_MPI)) - H5F_set_coll_md_read(idx_info.f, temp_cmr); -#endif /* H5_HAVE_PARALLEL */ - /* * Cache the information retrieved. * diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index f5da33d..0423006 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -800,6 +800,10 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf HDassert(type_info); HDassert(fm); + /* Disable collective metadata reads for chunked dataset I/O operations + * in order to prevent potential hangs */ + H5CX_set_coll_metadata_read(FALSE); + /* Check the optional property list for the collective chunk IO optimization option */ if(H5CX_get_mpio_chunk_opt_mode(&chunk_opt_mode) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get chunk optimization option") @@ -2313,7 +2317,7 @@ if(H5DEBUG(D)) /* Broadcasting the MPI_IO option info. and chunk address info. */ if(MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array, (int)(sizeof(haddr_t) * fm->layout->u.chunk.nchunks), MPI_BYTE, (int)0, io_info->comm))) - HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code) } /* end if */ /* Start at first node in chunk skip list */ diff --git a/src/H5Z.c b/src/H5Z.c index f41588f..0e2a7ba 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -611,7 +611,7 @@ H5Z__flush_file_cb(void *obj_ptr, hid_t H5_ATTR_UNUSED obj_id, void *key) /* Sanity check for collectively calling H5Zunregister, if requested */ /* (Sanity check assumes that a barrier on one file's comm * is sufficient (i.e. that there aren't different comms for - * different files). -QAK, 2018/02/14 + * different files). -QAK, 2018/02/14) */ if(H5_coll_api_sanity_check_g && !object->sanity_checked) { MPI_Comm mpi_comm; /* File's communicator */ diff --git a/testpar/t_cache.c b/testpar/t_cache.c index 7488728..41c95e2 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -7225,7 +7225,7 @@ smoke_check_6(int metadata_write_strategy) /* some error occured in the server -- report failure */ nerrors++; if ( verbose ) { - HDfprintf(stdout, "%d:%s: server_main() failed.\n", + HDfprintf(stdout, "%d:%s: server_main() failed.\n", world_mpi_rank, FUNC); } } @@ -7241,7 +7241,7 @@ smoke_check_6(int metadata_write_strategy) fid = -1; cache_ptr = NULL; if ( verbose ) { - HDfprintf(stdout, "%d:%s: setup_cache_for_test() failed.\n", + HDfprintf(stdout, "%d:%s: setup_cache_for_test() failed.\n", world_mpi_rank, FUNC); } } @@ -7250,7 +7250,7 @@ smoke_check_6(int metadata_write_strategy) virt_num_data_entries = NUM_DATA_ENTRIES; /* insert the first half collectively */ - file_ptr->coll_md_read = H5P_USER_TRUE; + H5CX_set_coll_metadata_read(TRUE); for ( i = 0; i < virt_num_data_entries/2; i++ ) { struct datum * entry_ptr; @@ -7271,7 +7271,7 @@ smoke_check_6(int metadata_write_strategy) } /* insert the other half independently */ - file_ptr->coll_md_read = H5P_USER_FALSE; + H5CX_set_coll_metadata_read(FALSE); for ( i = virt_num_data_entries/2; i < virt_num_data_entries; i++ ) { struct datum * entry_ptr; @@ -7291,7 +7291,7 @@ smoke_check_6(int metadata_write_strategy) HDassert(cache_ptr->max_cache_size*0.8 > cache_ptr->coll_list_size); } - /* flush the file */ + /* flush the file */ if ( H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0 ) { nerrors++; if ( verbose ) { @@ -7301,7 +7301,7 @@ smoke_check_6(int metadata_write_strategy) } /* Protect the first half of the entries collectively */ - file_ptr->coll_md_read = H5P_USER_TRUE; + H5CX_set_coll_metadata_read(TRUE); for ( i = 0; i < (virt_num_data_entries / 2); i++ ) { struct datum * entry_ptr; @@ -7322,13 +7322,13 @@ smoke_check_6(int metadata_write_strategy) } /* protect the other half independently */ - file_ptr->coll_md_read = H5P_USER_FALSE; + H5CX_set_coll_metadata_read(FALSE); for ( i = virt_num_data_entries/2; i < virt_num_data_entries; i++ ) { struct datum * entry_ptr; entry_ptr = &(data[i]); - lock_entry(file_ptr, i); + lock_entry(file_ptr, i); if(FALSE != entry_ptr->header.coll_access) { nerrors++; diff --git a/testpar/t_coll_md_read.c b/testpar/t_coll_md_read.c index f945d2b..912388c 100644 --- a/testpar/t_coll_md_read.c +++ b/testpar/t_coll_md_read.c @@ -32,6 +32,14 @@ #define PARTIAL_NO_SELECTION_Y_DIM_SCALE 5 #define PARTIAL_NO_SELECTION_X_DIM_SCALE 5 +#define MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS 2 + +#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_NO_SEL_PROCESS (mpi_rank == mpi_size - 1) +#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DATASET_NAME "linked_chunk_io_sort_chunk_issue" +#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_Y_DIM_SCALE 20000 +#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE 1 +#define LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS 1 + /* * A test for issue HDFFV-10501. A parallel hang was reported which occurred * in linked-chunk I/O when collective metadata reads are enabled and some ranks @@ -57,13 +65,13 @@ void test_partial_no_selection_coll_md_read(void) hsize_t stride[PARTIAL_NO_SELECTION_DATASET_NDIMS]; hsize_t count[PARTIAL_NO_SELECTION_DATASET_NDIMS]; hsize_t block[PARTIAL_NO_SELECTION_DATASET_NDIMS]; - hid_t file_id = -1; - hid_t fapl_id = -1; - hid_t dset_id = -1; - hid_t dcpl_id = -1; - hid_t dxpl_id = -1; - hid_t fspace_id = -1; - hid_t mspace_id = -1; + hid_t file_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; int mpi_rank, mpi_size; void *data = NULL; void *read_buf = NULL; @@ -86,7 +94,7 @@ void test_partial_no_selection_coll_md_read(void) file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); VRFY((file_id >= 0), "H5Fcreate succeeded"); - dataset_dims = malloc(PARTIAL_NO_SELECTION_DATASET_NDIMS * sizeof(*dataset_dims)); + dataset_dims = HDmalloc(PARTIAL_NO_SELECTION_DATASET_NDIMS * sizeof(*dataset_dims)); VRFY((dataset_dims != NULL), "malloc succeeded"); dataset_dims[0] = PARTIAL_NO_SELECTION_Y_DIM_SCALE * mpi_size; @@ -129,7 +137,7 @@ void test_partial_no_selection_coll_md_read(void) mspace_id = H5Screate_simple(1, sel_dims, NULL); VRFY((mspace_id >= 0), "H5Screate_simple succeeded"); - data = calloc(1, count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int)); + data = HDcalloc(1, count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int)); VRFY((data != NULL), "calloc succeeded"); dxpl_id = H5Pcreate(H5P_DATASET_XFER); @@ -151,7 +159,7 @@ void test_partial_no_selection_coll_md_read(void) */ VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_ONE_IO) >= 0), "H5Pset_dxpl_mpio_chunk_opt succeeded"); - read_buf = malloc(count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int)); + read_buf = HDmalloc(count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int)); VRFY((read_buf != NULL), "malloc succeeded"); /* @@ -171,21 +179,321 @@ void test_partial_no_selection_coll_md_read(void) * Check data integrity just to be sure. */ if (!PARTIAL_NO_SELECTION_NO_SEL_PROCESS) { - VRFY((!memcmp(data, read_buf, count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int))), "memcmp succeeded"); + VRFY((!HDmemcmp(data, read_buf, count[1] * (PARTIAL_NO_SELECTION_Y_DIM_SCALE * PARTIAL_NO_SELECTION_X_DIM_SCALE) * sizeof(int))), "memcmp succeeded"); + } + + if (dataset_dims) { + HDfree(dataset_dims); + dataset_dims = NULL; } + if (data) { + HDfree(data); + data = NULL; + } + + if (read_buf) { + HDfree(read_buf); + read_buf = NULL; + } + + VRFY((H5Sclose(fspace_id) >= 0), "H5Sclose succeeded"); + VRFY((H5Sclose(mspace_id) >= 0), "H5Sclose succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Dclose(dset_id) >= 0), "H5Dclose succeeded"); + VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded"); +} + +/* + * A test for HDFFV-10562 which attempts to verify that using multi-chunk + * I/O with collective metadata reads enabled doesn't causes issues due to + * collective metadata reads being made only by process 0 in H5D__chunk_addrmap(). + * + * Failure in this test may either cause a hang, or, due to how the MPI calls + * pertaining to this issue might mistakenly match up, may cause an MPI error + * message similar to: + * + * #008: H5Dmpio.c line 2546 in H5D__obtain_mpio_mode(): MPI_BCast failed + * major: Internal error (too specific to document in detail) + * minor: Some MPI function failed + * #009: H5Dmpio.c line 2546 in H5D__obtain_mpio_mode(): Message truncated, error stack: + *PMPI_Bcast(1600)..................: MPI_Bcast(buf=0x1df98e0, count=18, MPI_BYTE, root=0, comm=0x84000006) failed + *MPIR_Bcast_impl(1452).............: + *MPIR_Bcast(1476)..................: + *MPIR_Bcast_intra(1249)............: + *MPIR_SMP_Bcast(1088)..............: + *MPIR_Bcast_binomial(239)..........: + *MPIDI_CH3U_Receive_data_found(131): Message from rank 0 and tag 2 truncated; 2616 bytes received but buffer size is 18 + * major: Internal error (too specific to document in detail) + * minor: MPI Error String + * + */ +void test_multi_chunk_io_addrmap_issue(void) +{ + const char *filename; + hsize_t start[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS]; + hsize_t stride[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS]; + hsize_t count[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS]; + hsize_t block[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS]; + hsize_t dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {10, 5}; + hsize_t chunk_dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {5, 5}; + hsize_t max_dims[MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hid_t file_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + void *read_buf = NULL; + int mpi_rank; + int data[5][5] = { {0, 1, 2, 3, 4}, + {0, 1, 2, 3, 4}, + {0, 1, 2, 3, 4}, + {0, 1, 2, 3, 4}, + {0, 1, 2, 3, 4} }; + + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + filename = GetTestParameters(); + + fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type); + VRFY((fapl_id >= 0), "create_faccess_plist succeeded"); + + /* + * Even though the testphdf5 framework currently sets collective metadata reads + * on the FAPL, we call it here just to be sure this is futureproof, since + * demonstrating this issue relies upon it. + */ + VRFY((H5Pset_all_coll_metadata_ops(fapl_id, true) >= 0), "Set collective metadata reads succeeded"); + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + VRFY((file_id >= 0), "H5Fcreate succeeded"); + + space_id = H5Screate_simple(MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS, dims, max_dims); + VRFY((space_id >= 0), "H5Screate_simple succeeded"); + + dcpl_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((dcpl_id >= 0), "H5Pcreate succeeded"); + + VRFY((H5Pset_chunk(dcpl_id, MULTI_CHUNK_IO_ADDRMAP_ISSUE_DIMS, chunk_dims) >= 0), "H5Pset_chunk succeeded"); + + dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, space_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "H5Dcreate2 succeeded"); + + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "H5Pcreate succeeded"); + + VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) >= 0), "H5Pset_dxpl_mpio succeeded"); + VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_MULTI_IO) >= 0), "H5Pset_dxpl_mpio_chunk_opt succeeded"); + + start[1] = 0; + stride[0] = stride[1] = 1; + count[0] = count[1] = 5; + block[0] = block[1] = 1; + + if (mpi_rank == 0) + start[0] = 0; + else + start[0] = 5; + + VRFY((H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start, stride, count, block) >= 0), "H5Sselect_hyperslab succeeded"); + if (mpi_rank != 0) + VRFY((H5Sselect_none(space_id) >= 0), "H5Sselect_none succeeded"); + + VRFY((H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, space_id, dxpl_id, data) >= 0), "H5Dwrite succeeded"); + + VRFY((H5Fflush(file_id, H5F_SCOPE_GLOBAL) >= 0), "H5Fflush succeeded"); + + read_buf = HDmalloc(50 * sizeof(int)); + VRFY((read_buf != NULL), "malloc succeeded"); + + VRFY((H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, read_buf) >= 0), "H5Dread succeeded"); + + if (read_buf) { + HDfree(read_buf); + read_buf = NULL; + } + + VRFY((H5Sclose(space_id) >= 0), "H5Sclose succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Dclose(dset_id) >= 0), "H5Dclose succeeded"); + VRFY((H5Pclose(fapl_id) >= 0), "H5Pclose succeeded"); + VRFY((H5Fclose(file_id) >= 0), "H5Fclose succeeded"); +} + +/* + * A test for HDFFV-10562 which attempts to verify that using linked-chunk + * I/O with collective metadata reads enabled doesn't cause issues due to + * collective metadata reads being made only by process 0 in H5D__sort_chunk(). + * + * NOTE: Due to the way that the threshold value which pertains to this test + * is currently calculated within HDF5, there are several conditions that this + * test must maintain. Refer to the function H5D__sort_chunk in H5Dmpio.c for + * a better idea of why. + * + * Condition 1: We need to make sure that the test always selects every single + * chunk in the dataset. It is fine if the selection is split up among multiple + * ranks, but their combined selection must cover the whole dataset. + * + * Condition 2: The number of chunks in the dataset divided by the number of MPI + * ranks must exceed or equal 10000. In other words, each MPI rank must be + * responsible for 10000 or more unique chunks. + * + * Condition 3: This test will currently only be reliably reproducable for 2 or 3 + * MPI ranks. The threshold value calculated reduces to a constant 100 / mpi_size, + * and is compared against a default value of 30%. + * + * Failure in this test may either cause a hang, or, due to how the MPI calls + * pertaining to this issue might mistakenly match up, may cause an MPI error + * message similar to: + * + * #008: H5Dmpio.c line 2338 in H5D__sort_chunk(): MPI_BCast failed + * major: Internal error (too specific to document in detail) + * minor: Some MPI function failed + * #009: H5Dmpio.c line 2338 in H5D__sort_chunk(): Other MPI error, error stack: + *PMPI_Bcast(1600)........: MPI_Bcast(buf=0x7eae610, count=320000, MPI_BYTE, root=0, comm=0x84000006) failed + *MPIR_Bcast_impl(1452)...: + *MPIR_Bcast(1476)........: + *MPIR_Bcast_intra(1249)..: + *MPIR_SMP_Bcast(1088)....: + *MPIR_Bcast_binomial(250): message sizes do not match across processes in the collective routine: Received 2096 but expected 320000 + * major: Internal error (too specific to document in detail) + * minor: MPI Error String + */ +void test_link_chunk_io_sort_chunk_issue(void) +{ + const char *filename; + hsize_t *dataset_dims = NULL; + hsize_t max_dataset_dims[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS]; + hsize_t sel_dims[1]; + hsize_t chunk_dims[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS] = { LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS }; + hsize_t start[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS]; + hsize_t stride[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS]; + hsize_t count[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS]; + hsize_t block[LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS]; + hid_t file_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; + int mpi_rank, mpi_size; + void *data = NULL; + void *read_buf = NULL; + + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + + filename = GetTestParameters(); + + fapl_id = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, facc_type); + VRFY((fapl_id >= 0), "create_faccess_plist succeeded"); + + /* + * Even though the testphdf5 framework currently sets collective metadata reads + * on the FAPL, we call it here just to be sure this is futureproof, since + * demonstrating this issue relies upon it. + */ + VRFY((H5Pset_all_coll_metadata_ops(fapl_id, true) >= 0), "Set collective metadata reads succeeded"); + + file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + VRFY((file_id >= 0), "H5Fcreate succeeded"); + + dataset_dims = HDmalloc(LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS * sizeof(*dataset_dims)); + VRFY((dataset_dims != NULL), "malloc succeeded"); + + dataset_dims[0] = LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE * mpi_size * LINK_CHUNK_IO_SORT_CHUNK_ISSUE_Y_DIM_SCALE; + max_dataset_dims[0] = H5S_UNLIMITED; + + fspace_id = H5Screate_simple(LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS, dataset_dims, max_dataset_dims); + VRFY((fspace_id >= 0), "H5Screate_simple succeeded"); + + /* + * Set up chunking on the dataset in order to reproduce the problem. + */ + dcpl_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((dcpl_id >= 0), "H5Pcreate succeeded"); + + VRFY((H5Pset_chunk(dcpl_id, LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DIMS, chunk_dims) >= 0), "H5Pset_chunk succeeded"); + + dset_id = H5Dcreate2(file_id, LINK_CHUNK_IO_SORT_CHUNK_ISSUE_DATASET_NAME, H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "H5Dcreate2 succeeded"); + + /* + * Setup hyperslab selection to split the dataset among the ranks. + * + * The ranks will write rows across the dataset. + */ + stride[0] = LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE; + count[0] = (dataset_dims[0] / LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE) / mpi_size; + start[0] = count[0] * mpi_rank; + block[0] = LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE; + + VRFY((H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) >= 0), "H5Sselect_hyperslab succeeded"); + + sel_dims[0] = count[0] * (LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE); + + mspace_id = H5Screate_simple(1, sel_dims, NULL); + VRFY((mspace_id >= 0), "H5Screate_simple succeeded"); + + data = HDcalloc(1, count[0] * (LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE) * sizeof(int)); + VRFY((data != NULL), "calloc succeeded"); + + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "H5Pcreate succeeded"); + + /* + * Enable collective access for the data transfer. + */ + VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) >= 0), "H5Pset_dxpl_mpio succeeded"); + + VRFY((H5Dwrite(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, data) >= 0), "H5Dwrite succeeded"); + + VRFY((H5Fflush(file_id, H5F_SCOPE_GLOBAL) >= 0), "H5Fflush succeeded"); + + /* + * Ensure that linked-chunk I/O is performed since this is + * the particular code path where the issue lies and we don't + * want the library doing multi-chunk I/O behind our backs. + */ + VRFY((H5Pset_dxpl_mpio_chunk_opt(dxpl_id, H5FD_MPIO_CHUNK_ONE_IO) >= 0), "H5Pset_dxpl_mpio_chunk_opt succeeded"); + + read_buf = HDmalloc(count[0] * (LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE) * sizeof(int)); + VRFY((read_buf != NULL), "malloc succeeded"); + + VRFY((H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) >= 0), "H5Sselect_hyperslab succeeded"); + + sel_dims[0] = count[0] * (LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE); + + VRFY((H5Sclose(mspace_id) >= 0), "H5Sclose succeeded"); + + mspace_id = H5Screate_simple(1, sel_dims, NULL); + VRFY((mspace_id >= 0), "H5Screate_simple succeeded"); + + read_buf = HDrealloc(read_buf, count[0] * (LINK_CHUNK_IO_SORT_CHUNK_ISSUE_CHUNK_SIZE) * sizeof(int)); + VRFY((read_buf != NULL), "realloc succeeded"); + + /* + * Finally have each rank read their section of data back from the dataset. + */ + VRFY((H5Dread(dset_id, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl_id, read_buf) >= 0), "H5Dread succeeded"); + if (dataset_dims) { - free(dataset_dims); + HDfree(dataset_dims); dataset_dims = NULL; } if (data) { - free(data); + HDfree(data); data = NULL; } if (read_buf) { - free(read_buf); + HDfree(read_buf); read_buf = NULL; } diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 69b66ae..999e17a 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -549,7 +549,10 @@ int main(int argc, char **argv) AddTest("noselcollmdread", test_partial_no_selection_coll_md_read, NULL, "Collective Metadata read with some ranks having no selection", PARATESTFILE); - + AddTest("MC coll MD read", test_multi_chunk_io_addrmap_issue, NULL, + "Collective MD read with multi chunk I/O (H5D__chunk_addrmap)", PARATESTFILE); + AddTest("LC coll MD read", test_link_chunk_io_sort_chunk_issue, NULL, + "Collective MD read with link chunk I/O (H5D__sort_chunk)", PARATESTFILE); /* Display testing information */ TestInfo(argv[0]); diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h index 176574e..4409221 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -295,6 +295,8 @@ void compress_readAll(void); #endif /* H5_HAVE_FILTER_DEFLATE */ void test_dense_attr(void); void test_partial_no_selection_coll_md_read(void); +void test_multi_chunk_io_addrmap_issue(void); +void test_link_chunk_io_sort_chunk_issue(void); /* commonly used prototypes */ hid_t create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type); -- cgit v0.12 From 8f447bd3564a88738b9a26b1b0ac3bba785efd39 Mon Sep 17 00:00:00 2001 From: Jordan Henderson Date: Mon, 11 Feb 2019 19:15:56 -0600 Subject: Add RELEASE.txt note for collective metadata read fixes --- release_docs/RELEASE.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index ef3bda0..316798d 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -264,6 +264,22 @@ Bug Fixes since HDF5-1.10.3 release Library ------- + - Fix hangs with collective metadata reads during chunked dataset I/O + + In the parallel library, it was discovered that when a particular + sequence of operations following a pattern of: + + "write to chunked dataset" -> "flush file" -> "read from dataset" + + occurred with collective metadata reads enabled, hangs could be + observed due to certain MPI ranks not participating in the collective + metadata reads. + + To fix the issue, collective metadata reads are now disabled during + chunked dataset raw data I/O. + + (JTH - 2019/02/11, HDFFV-10563, HDFFV-10688) + - Performance issue when closing an object The slow down is due to the search of the "tag_list" to find -- cgit v0.12 From 3acd486b83f319579b1c6884c90289b0eb1d44a6 Mon Sep 17 00:00:00 2001 From: Jordan Henderson Date: Tue, 12 Feb 2019 11:41:55 -0600 Subject: Fixes for JNI updates --- MANIFEST | 26 ++++++++++++++++++ java/src/jni/h5aImp.c | 63 +++++++++++++++++++++++++++++++++++++++++++ java/src/jni/h5dImp.c | 12 +++++++++ java/src/jni/h5eImp.c | 23 +++++++++++++--- java/src/jni/h5fImp.c | 18 +++++++++++++ java/src/jni/h5gImp.c | 12 +++++++++ java/src/jni/h5lImp.c | 55 +++++++++++++++++++++++++++++++++++++ java/src/jni/h5oImp.c | 31 +++++++++++++++++++++ java/src/jni/h5pDAPLImp.c | 3 +++ java/src/jni/h5pDCPLImp.c | 15 +++++++++-- java/src/jni/h5pDXPLImp.c | 3 +++ java/src/jni/h5pFAPLImp.c | 41 +++++++++++++++++++++------- java/src/jni/h5pImp.c | 39 +++++++++++++++++++++++++++ java/src/jni/h5pLAPLImp.c | 3 +++ java/src/jni/h5plImp.c | 12 +++++++++ java/src/jni/h5rImp.c | 2 ++ java/src/jni/h5sImp.c | 2 +- java/src/jni/h5tImp.c | 39 +++++++++++++++++++++------ java/src/jni/h5util.c | 18 ++++++++----- java/src/jni/h5vlImp.c | 9 +++++++ java/test/TestH5Edefault.java | 2 +- java/test/TestH5Oparams.java | 4 +-- java/test/TestH5Sbasic.java | 2 +- 23 files changed, 399 insertions(+), 35 deletions(-) diff --git a/MANIFEST b/MANIFEST index 2b48295..6c2018a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -2900,6 +2900,32 @@ ./java/src/jni/h5oImp.h ./java/src/jni/h5pImp.c ./java/src/jni/h5pImp.h +./java/src/jni/h5pACPLImp.c +./java/src/jni/h5pACPLImp.h +./java/src/jni/h5pDAPLImp.c +./java/src/jni/h5pDAPLImp.h +./java/src/jni/h5pDCPLImp.c +./java/src/jni/h5pDCPLImp.h +./java/src/jni/h5pDXPLImp.c +./java/src/jni/h5pDXPLImp.h +./java/src/jni/h5pFAPLImp.c +./java/src/jni/h5pFAPLImp.h +./java/src/jni/h5pFCPLImp.c +./java/src/jni/h5pFCPLImp.h +./java/src/jni/h5pGAPLImp.c +./java/src/jni/h5pGAPLImp.h +./java/src/jni/h5pGCPLImp.c +./java/src/jni/h5pGCPLImp.h +./java/src/jni/h5pLAPLImp.c +./java/src/jni/h5pLAPLImp.h +./java/src/jni/h5pLCPLImp.c +./java/src/jni/h5pLCPLImp.h +./java/src/jni/h5pOCPLImp.c +./java/src/jni/h5pOCPLImp.h +./java/src/jni/h5pOCpyPLImp.c +./java/src/jni/h5pOCpyPLImp.h +./java/src/jni/h5pStrCPLImp.c +./java/src/jni/h5pStrCPLImp.h ./java/src/jni/h5plImp.c ./java/src/jni/h5plImp.h ./java/src/jni/h5rImp.c diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 666626f..e47515d 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -1533,6 +1533,9 @@ Java_hdf_hdf5lib_H5_H5Adelete UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Adelete: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, attrName, NULL, "H5Adelete: attribute name not pinned"); if ((status = H5Adelete((hid_t)loc_id, attrName)) < 0) @@ -1580,6 +1583,9 @@ Java_hdf_hdf5lib_H5__1H5Acreate2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Acreate2: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, attrName, NULL, "H5Acreate2: attribute name not pinned"); if ((status = H5Acreate2((hid_t)loc_id, attrName, (hid_t)type_id, @@ -1608,6 +1614,9 @@ Java_hdf_hdf5lib_H5__1H5Aopen UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aopen: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, attrName, NULL, "H5Aopen: attribute name not pinned"); if ((retVal = H5Aopen((hid_t)obj_id, attrName, (hid_t)access_plist)) < 0) @@ -1634,6 +1643,9 @@ Java_hdf_hdf5lib_H5__1H5Aopen_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aopen_by_idx: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Aopen_by_idx: object name not pinned"); if ((retVal = H5Aopen_by_idx((hid_t)loc_id, objName, (H5_index_t)idx_type, @@ -1662,6 +1674,11 @@ Java_hdf_hdf5lib_H5__1H5Acreate_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Acreate_by_name: object name is NULL"); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Acreate_by_name: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Acreate_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Acreate_by_name: attribute name not pinned"); @@ -1693,6 +1710,11 @@ Java_hdf_hdf5lib_H5_H5Aexists_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aexists_by_name: object name is NULL"); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aexists_by_name: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Aexists_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Aexists_by_name: attribute name not pinned"); @@ -1725,6 +1747,11 @@ Java_hdf_hdf5lib_H5_H5Arename UNUSED(clss); + if (NULL == old_attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Arename: old attribute name is NULL"); + if (NULL == new_attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Arename: new attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, old_attr_name, oldAttrName, NULL, "H5Arename: old attribute name not pinned"); PIN_JAVA_STRING(ENVONLY, new_attr_name, newAttrName, NULL, "H5Arename: new attribute name not pinned"); @@ -1756,6 +1783,13 @@ Java_hdf_hdf5lib_H5_H5Arename_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Arename_by_name: object name is NULL"); + if (NULL == old_attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Arename_by_name: old attribute name is NULL"); + if (NULL == new_attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Arename_by_name: new attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Arename_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, old_attr_name, oldAttrName, NULL, "H5Arename_by_name: old attribute name not pinned"); PIN_JAVA_STRING(ENVONLY, new_attr_name, newAttrName, NULL, "H5Arename_by_name: new attribute name not pinned"); @@ -1790,6 +1824,9 @@ Java_hdf_hdf5lib_H5_H5Aget_1name_1by_1idx UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aget_name_by_idx: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Aget_name_by_idx: object name not pinned"); /* Get the length of the attribute name */ @@ -1883,6 +1920,9 @@ Java_hdf_hdf5lib_H5_H5Aget_1info_1by_1idx UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aget_info_by_idx: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Aget_info_by_idx: object name not pinned"); if ((status = H5Aget_info_by_idx((hid_t)loc_id, objName, (H5_index_t)idx_type, @@ -1921,6 +1961,11 @@ Java_hdf_hdf5lib_H5_H5Aget_1info_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aget_info_by_name: object name is NULL"); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aget_info_by_name: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Aget_info_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Aget_info_by_name: attribute name not pinned"); @@ -1958,6 +2003,11 @@ Java_hdf_hdf5lib_H5_H5Adelete_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Adelete_by_name: object name is NULL"); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Adelete_by_name: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Adelete_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Adelete_by_name: attribute name not pinned"); @@ -1987,6 +2037,9 @@ Java_hdf_hdf5lib_H5_H5Aexists UNUSED(clss); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aexists: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Aexists: attribute name not pinned"); if ((bval = H5Aexists((hid_t)obj_id, attrName)) < 0) @@ -2015,6 +2068,9 @@ Java_hdf_hdf5lib_H5_H5Adelete_1by_1idx UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Adelete_by_idx: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Adelete_by_idx: object name not pinned"); if ((status = H5Adelete_by_idx((hid_t)loc_id, objName, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t)n, (hid_t)lapl_id)) < 0) @@ -2041,6 +2097,11 @@ Java_hdf_hdf5lib_H5__1H5Aopen_1by_1name UNUSED(clss); + if (NULL == obj_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aopen_by_name: object name is NULL"); + if (NULL == attr_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aopen_by_name: attribute name is NULL"); + PIN_JAVA_STRING(ENVONLY, obj_name, objName, NULL, "H5Aopen_by_name: object name not pinned"); PIN_JAVA_STRING(ENVONLY, attr_name, attrName, NULL, "H5Aopen_by_name: attribute name not pinned"); @@ -2187,6 +2248,8 @@ Java_hdf_hdf5lib_H5_H5Aiterate_1by_1name H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aiterate_by_name: op_data is NULL"); if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aiterate_by_name: callback_op is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Aiterate_by_name: object name is NULL"); PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Aiterate_by_name: object name not pinned"); diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 0ed3b6e..92a3723 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -69,6 +69,9 @@ Java_hdf_hdf5lib_H5__1H5Dcreate UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dcreate: dataset name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, dsetName, NULL, "H5Dcreate: dataset name not pinned"); if ((dset_id = H5Dcreate2((hid_t)loc_id, dsetName, (hid_t)type_id, (hid_t)space_id, H5P_DEFAULT, (hid_t)create_plist_id, H5P_DEFAULT)) < 0) @@ -95,6 +98,9 @@ Java_hdf_hdf5lib_H5__1H5Dopen UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dopen: dataset name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, dsetName, NULL, "H5Dopen: dataset name not pinned"); if ((dset_id = H5Dopen2((hid_t)loc_id, dsetName, H5P_DEFAULT))) @@ -1677,6 +1683,9 @@ Java_hdf_hdf5lib_H5__1H5Dcreate2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dcreate2: dataset name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, dsetName, NULL, "H5Dcreate2: dataset name not pinned"); if ((dset_id = H5Dcreate2((hid_t)loc_id, dsetName, (hid_t)type_id, (hid_t)space_id, (hid_t)link_plist_id, (hid_t)create_plist_id, (hid_t)access_plist_id)) < 0) @@ -1703,6 +1712,9 @@ Java_hdf_hdf5lib_H5__1H5Dopen2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Dopen2: dataset name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, dsetName, NULL, "H5Dopen2: dataset name not pinned"); if ((dset_id = H5Dopen2((hid_t)loc_id, dsetName, (hid_t)access_plist)) < 0) diff --git a/java/src/jni/h5eImp.c b/java/src/jni/h5eImp.c index 1c5a5a9..4ab00df 100644 --- a/java/src/jni/h5eImp.c +++ b/java/src/jni/h5eImp.c @@ -94,6 +94,13 @@ Java_hdf_hdf5lib_H5_H5Eregister_1class UNUSED(cls); + if (NULL == cls_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Eregister_class: class name is NULL"); + if (NULL == lib_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Eregister_class: lib name is NULL"); + if (NULL == version) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Eregister_class: version string is NULL"); + PIN_JAVA_STRING(ENVONLY, cls_name, the_cls_name, NULL, "H5Eregister_class: class name not pinned"); PIN_JAVA_STRING(ENVONLY, lib_name, the_lib_name, NULL, "H5Eregister_class: lib name not pinned"); PIN_JAVA_STRING(ENVONLY, version, the_version, NULL, "H5Eregister_class: version string not pinned"); @@ -171,6 +178,8 @@ Java_hdf_hdf5lib_H5_H5Ecreate_1msg if (err_id < 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Ecreate_msg: invalid error class ID"); + if (NULL == err_msg) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ecreate_msg: error message string is NULL"); PIN_JAVA_STRING(ENVONLY, err_msg, the_err_msg, NULL, "H5Ecreate_msg: error message string not pinned"); @@ -376,13 +385,19 @@ Java_hdf_hdf5lib_H5_H5Epush2 UNUSED(cls); if (stk_id < 0) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush: invalid error stack ID"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush2: invalid error stack ID"); if (class_id < 0) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush: invalid error class ID"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush2: invalid error class ID"); if (major_id < 0) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush: invalid major error class ID"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush2: invalid major error class ID"); if (minor_id < 0) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush: invalid minor error class ID"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Epush2: invalid minor error class ID"); + if (NULL == filename) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Epush2: filename is NULL"); + if (NULL == funcname) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Epush2: function name is NULL"); + if (NULL == err_desc) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Epush2: error message is NULL"); PIN_JAVA_STRING(ENVONLY, filename, fName, NULL, "H5Epush2: filename not pinned"); PIN_JAVA_STRING(ENVONLY, funcname, fncName, NULL, "H5Epush2: function name not pinned"); diff --git a/java/src/jni/h5fImp.c b/java/src/jni/h5fImp.c index 624c788..d145c6a 100644 --- a/java/src/jni/h5fImp.c +++ b/java/src/jni/h5fImp.c @@ -47,6 +47,9 @@ Java_hdf_hdf5lib_H5__1H5Fopen UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fopen: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Fopen: file name not pinned"); if ((status = H5Fopen(fileName, (unsigned)flags, (hid_t)access_id)) < 0) @@ -73,6 +76,9 @@ Java_hdf_hdf5lib_H5__1H5Fcreate UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fcreate: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Fcreate: file name not pinned"); if ((status = H5Fcreate(fileName, (unsigned)flags, create_id, access_id)) < 0) @@ -159,6 +165,9 @@ Java_hdf_hdf5lib_H5_H5Fis_1hdf5 H5_UNIMPLEMENTED(ENVONLY, "H5Fis_hdf5: not implemented"); #endif + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fis_hdf5: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Fis_hdf5: file name not pinned"); if ((bval = H5Fis_hdf5(fileName)) < 0) @@ -187,6 +196,9 @@ Java_hdf_hdf5lib_H5_H5Fis_1accessible UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fis_accessible: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Fis_accessible: file name not pinned"); if ((bval = H5Fis_accessible(fileName, (hid_t)file_id)) < 0) @@ -295,6 +307,9 @@ Java_hdf_hdf5lib_H5_H5Fmount UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Fmount: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Fmount: file name not pinned"); if ((status = H5Fmount((hid_t)loc_id, fileName, (hid_t)child_id, (hid_t)plist_id)) < 0) @@ -321,6 +336,9 @@ Java_hdf_hdf5lib_H5_H5Funmount UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Funmount: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Funmount: file name not pinned"); if ((status = H5Funmount((hid_t)loc_id, fileName)) < 0) diff --git a/java/src/jni/h5gImp.c b/java/src/jni/h5gImp.c index 8adabca..b579f31 100644 --- a/java/src/jni/h5gImp.c +++ b/java/src/jni/h5gImp.c @@ -126,6 +126,9 @@ Java_hdf_hdf5lib_H5__1H5Gcreate2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gcreate2: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Gcreate2: group name not pinned"); if ((group_id = H5Gcreate2((hid_t)loc_id, grpName, (hid_t)link_plist_id, (hid_t)create_plist_id, (hid_t)access_plist_id)) < 0) @@ -172,6 +175,9 @@ Java_hdf_hdf5lib_H5__1H5Gopen2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gopen2: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Gopen2: group name not pinned"); if ((group_id = H5Gopen2((hid_t)loc_id, grpName, (hid_t)access_plist_id)) < 0) @@ -245,6 +251,9 @@ Java_hdf_hdf5lib_H5_H5Gget_1info_1by_1name UNUSED(cls); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_info_by_name: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Gget_info_by_name: group name not pinned"); if ((ret_val = H5Gget_info_by_name((hid_t)loc_id, grpName, &group_info, (hid_t)lapl_id)) < 0) @@ -281,6 +290,9 @@ Java_hdf_hdf5lib_H5_H5Gget_1info_1by_1idx UNUSED(cls); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Gget_info_by_idx: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Gget_info_by_idx: group name not pinned"); if ((ret_val = H5Gget_info_by_idx((hid_t)loc_id, grpName, cindex_type, diff --git a/java/src/jni/h5lImp.c b/java/src/jni/h5lImp.c index 5999270..af6c8ba 100644 --- a/java/src/jni/h5lImp.c +++ b/java/src/jni/h5lImp.c @@ -59,6 +59,11 @@ Java_hdf_hdf5lib_H5_H5Lcopy UNUSED(clss); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcopy: src name is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcopy: dest name is NULL"); + PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcopy: src name not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcopy: dest name not pinned"); @@ -89,6 +94,13 @@ Java_hdf_hdf5lib_H5_H5Lcreate_1external UNUSED(clss); + if (NULL == file_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: file name is NULL"); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: object name is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, file_name, lFileName, NULL, "H5Lcreate_external: file name not pinned"); PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcreate_external: object name not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcreate_external: link name not pinned"); @@ -121,6 +133,11 @@ Java_hdf_hdf5lib_H5_H5Lcreate_1hard UNUSED(clss); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_hard: object name is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_hard: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcreate_hard: object name not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcreate_hard: link name not pinned"); @@ -150,6 +167,11 @@ Java_hdf_hdf5lib_H5_H5Lcreate_1soft UNUSED(clss); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_soft: link target is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_soft: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, cur_name, linkTarget, NULL, "H5Lcreate_soft: link target not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, linkName, NULL, "H5Lcreate_soft: link name not pinned"); @@ -177,6 +199,9 @@ Java_hdf_hdf5lib_H5_H5Ldelete UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ldelete: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Ldelete: link name not pinned"); if ((status = H5Ldelete((hid_t)loc_id, linkName, (hid_t)access_id)) < 0) @@ -203,6 +228,9 @@ Java_hdf_hdf5lib_H5_H5Ldelete_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ldelete_by_idx: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Ldelete_by_idx: group name not pinned"); if ((status = H5Ldelete_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, n, (hid_t)access_id)) < 0) @@ -227,6 +255,9 @@ Java_hdf_hdf5lib_H5_H5Lexists UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lexists: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lexists: link name not pinned"); if ((bval = H5Lexists((hid_t)loc_id, linkName, (hid_t)access_id)) < 0) @@ -258,6 +289,9 @@ Java_hdf_hdf5lib_H5_H5Lget_1info UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_info: link name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_info: link name not pinned"); if ((status = H5Lget_info((hid_t)loc_id, linkName, &infobuf, (hid_t)access_id)) < 0) @@ -296,6 +330,9 @@ Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_info_by_idx: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Lget_info_by_idx: group name not pinned"); if ((status = H5Lget_info_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0) @@ -333,6 +370,9 @@ Java_hdf_hdf5lib_H5_H5Lget_1name_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_name_by_idx: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Lget_name_by_idx: group name not pinned"); /* Get the length of the link name */ @@ -378,6 +418,9 @@ Java_hdf_hdf5lib_H5_H5Lget_1value UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_value: link name is NULL"); + infobuf.type = H5L_TYPE_ERROR; PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_value: link name not pinned"); @@ -465,6 +508,9 @@ Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_val_by_idx: group name is NULL"); + infobuf.type = H5L_TYPE_ERROR; PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lget_val_by_idx: group name not pinned"); @@ -551,6 +597,11 @@ Java_hdf_hdf5lib_H5_H5Lmove UNUSED(clss); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lmove: src name is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lmove: dest name is NULL"); + PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lmove: src name not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lmove: dest name not pinned"); @@ -675,6 +726,8 @@ Java_hdf_hdf5lib_H5_H5Lvisit_1by_1name H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: op_data is NULL"); if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: callback_op is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: group name is NULL"); PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lvisit_by_name: group name not pinned"); @@ -743,6 +796,8 @@ Java_hdf_hdf5lib_H5_H5Literate_1by_1name H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: op_data is NULL"); if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: callback_op is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: group name is NULL"); PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Literate_by_name: group name not pinned"); diff --git a/java/src/jni/h5oImp.c b/java/src/jni/h5oImp.c index 0b1a984..cc88b81 100644 --- a/java/src/jni/h5oImp.c +++ b/java/src/jni/h5oImp.c @@ -56,6 +56,9 @@ Java_hdf_hdf5lib_H5__1H5Oopen UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oopen: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oopen: object name not pinned"); if ((status = H5Oopen((hid_t)loc_id, objName, (hid_t)access_plist_id)) < 0) @@ -104,6 +107,11 @@ Java_hdf_hdf5lib_H5_H5Ocopy UNUSED(clss); + if (NULL == cur_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ocopy: src name is NULL"); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ocopy: dst name is NULL"); + PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Ocopy: src name not pinned"); PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Ocopy: dest name not pinned"); @@ -204,6 +212,9 @@ Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1name UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_name: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oget_info_by_name: object name not pinned"); if ((status = H5Oget_info_by_name2((hid_t)loc_id, objName, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) @@ -278,6 +289,9 @@ Java_hdf_hdf5lib_H5_H5Oget_1info_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_info_by_idx: group name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Oget_info_by_idx: group name not pinned"); if ((status = H5Oget_info_by_idx2((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (unsigned)fields, (hid_t)access_id)) < 0) @@ -346,6 +360,9 @@ Java_hdf_hdf5lib_H5_H5Olink UNUSED(clss); + if (NULL == dst_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Olink: link destination name is NULL"); + PIN_JAVA_STRING(ENVONLY, dst_name, linkDstName, NULL, "H5Olink: link destination name not pinned"); if ((status = H5Olink((hid_t)cur_loc_id, (hid_t)dst_loc_id, linkDstName, (hid_t)create_id, (hid_t)access_id)) < 0) @@ -525,6 +542,8 @@ Java_hdf_hdf5lib_H5_H5Ovisit_1by_1name H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ovisit_by_name: op_data is NULL"); if (NULL == callback_op) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ovisit_by_name: callback_op is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ovisit_by_name: object name is NULL"); PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Ovisit_by_name: object name not pinned"); @@ -580,6 +599,9 @@ Java_hdf_hdf5lib_H5_H5Oset_1comment_1by_1name UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oset_comment_by_name: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oset_comment_by_name: object name not pinned"); if (NULL != comment) @@ -651,6 +673,9 @@ Java_hdf_hdf5lib_H5_H5Oget_1comment_1by_1name UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oget_comment_by_name: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oget_comment_by_name: object name not pinned"); /* Get the length of the comment */ @@ -692,6 +717,9 @@ Java_hdf_hdf5lib_H5_H5Oexists_1by_1name UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oexists_by_name: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, objName, NULL, "H5Oexists_by_name: object name not pinned"); if ((bval = H5Oexists_by_name((hid_t)loc_id, objName, (hid_t)access_id)) < 0) @@ -777,6 +805,9 @@ Java_hdf_hdf5lib_H5__1H5Oopen_1by_1idx UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Oopen_by_idx: object name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Oopen_by_idx: object name not pinned"); if ((retVal = H5Oopen_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (hid_t)lapl_id)) < 0) diff --git a/java/src/jni/h5pDAPLImp.c b/java/src/jni/h5pDAPLImp.c index 0afbbd6..fb39b84 100644 --- a/java/src/jni/h5pDAPLImp.c +++ b/java/src/jni/h5pDAPLImp.c @@ -119,6 +119,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1efile_1prefix UNUSED(clss); + if (NULL == prefix) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_efile_prefix: external file prefix is NULL"); + PIN_JAVA_STRING(ENVONLY, prefix, extFilePrefix, NULL, "H5Pset_efile_prefix: external file prefix not pinned"); if ((retVal = H5Pset_efile_prefix((hid_t)dapl_id, extFilePrefix)) < 0) diff --git a/java/src/jni/h5pDCPLImp.c b/java/src/jni/h5pDCPLImp.c index 0671843..7559c3b 100644 --- a/java/src/jni/h5pDCPLImp.c +++ b/java/src/jni/h5pDCPLImp.c @@ -1008,8 +1008,8 @@ Java_hdf_hdf5lib_H5_H5Pset_1scaleoffset UNUSED(clss); - if (scale_factor <= 0) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_scaleoffset: scale factor must be > 0"); + if (scale_factor < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_scaleoffset: scale factor must be >= 0"); if (scale_type != H5Z_SO_FLOAT_DSCALE && scale_type != H5Z_SO_FLOAT_ESCALE && scale_type != H5Z_SO_INT) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_scaleoffset: invalid scale type"); @@ -1074,6 +1074,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1external UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_external: file name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, fileName, NULL, "H5Pset_external: file name not pinned"); if ((status = H5Pset_external((hid_t)plist, fileName, (off_t)offset, (hsize_t)size)) < 0) @@ -1189,6 +1192,11 @@ Java_hdf_hdf5lib_H5_H5Pset_1virtual UNUSED(clss); + if (NULL == src_file_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_virtual: src_file_name is NULL"); + if (NULL == src_dset_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_virtual: src_dset_name is NULL"); + PIN_JAVA_STRING(ENVONLY, src_file_name, fstr, NULL, "H5Pset_virtual: src_file_name not pinned"); PIN_JAVA_STRING(ENVONLY, src_dset_name, dstr, NULL, "H5Pset_virtual: src_dset_name not pinned"); @@ -1352,6 +1360,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1virtual_1prefix UNUSED(clss); + if (NULL == prefix) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_virtual_prefix: virtual prefix is NULL"); + PIN_JAVA_STRING(ENVONLY, prefix, virtPrefix, NULL, "H5Pset_virtual_prefix: virtual prefix not pinned"); if ((retVal = H5Pset_virtual_prefix((hid_t)dapl_id, virtPrefix)) < 0) diff --git a/java/src/jni/h5pDXPLImp.c b/java/src/jni/h5pDXPLImp.c index 2bdc36b..323fa8c 100644 --- a/java/src/jni/h5pDXPLImp.c +++ b/java/src/jni/h5pDXPLImp.c @@ -273,6 +273,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1data_1transform UNUSED(clss); + if (NULL == expression) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_data_transform: data transform expression is NULL"); + PIN_JAVA_STRING(ENVONLY, expression, express, NULL, "H5Pset_data_transform: data transform expression not pinned"); if ((retVal = H5Pset_data_transform((hid_t)plist_id, express)) < 0) diff --git a/java/src/jni/h5pFAPLImp.c b/java/src/jni/h5pFAPLImp.c index aec6581..acfc853 100644 --- a/java/src/jni/h5pFAPLImp.c +++ b/java/src/jni/h5pFAPLImp.c @@ -384,6 +384,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1log UNUSED(clss); + if (NULL == logfile) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_fapl_log: log file name is NULL"); + PIN_JAVA_STRING(ENVONLY, logfile, pLogfile, NULL, "H5Pset_fapl_log: log file name not pinned"); if ((retVal = H5Pset_fapl_log((hid_t)fapl_id, pLogfile, (unsigned long long)flags, (size_t)buf_size)) < 0) @@ -421,10 +424,12 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi jlongArray memb_fapl, jobjectArray memb_name, jlongArray memb_addr, jboolean relax) { const char * const *mName = NULL; + const char *utf8 = NULL; jboolean isCopy; jboolean bb; jobject o; jstring rstring; + jstring obj; jclass Sjc; size_t i; jlong *thefaplArray = NULL; @@ -445,11 +450,8 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi PIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, &isCopy, "H5Pset_fapl_multi: memb_addr not pinned"); if (memb_name) { - jstring obj; - for (i = 0; i < H5FD_MEM_NTYPES; i++) { - const char *utf8 = NULL; - size_t str_len; + size_t str_len; if (NULL == (obj = (jstring) ENVPTR->GetObjectArrayElement(ENVONLY, (jobjectArray) memb_name, (jsize) i))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); @@ -474,6 +476,7 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: memory allocation failed"); HDstrncpy(member_name[i], utf8, str_len + 1); + (member_name[i])[str_len] = '\0'; UNPIN_JAVA_STRING(ENVONLY, obj, utf8); utf8 = NULL; @@ -493,6 +496,8 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); for (i = 0; i < H5FD_MEM_NTYPES; i++) { + if (!member_name[i]) continue; + if (NULL == (rstring = ENVPTR->NewStringUTF(ENVONLY, member_name[i]))) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); H5_JNI_FATAL_ERROR(ENVONLY, "H5Pset_fapl_multi: out of memory - unable to construct string from UTF characters"); @@ -522,7 +527,12 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1multi } done: - h5str_array_free(member_name, H5FD_MEM_NTYPES); + for (i = 0; i < H5FD_MEM_NTYPES; i++) { + if (member_name[i]) + HDfree(member_name[i]); + } + if (utf8) + UNPIN_JAVA_STRING(ENVONLY, obj, utf8); if (theaddrArray) UNPIN_LONG_ARRAY(ENVONLY, memb_addr, theaddrArray, (status < 0) ? JNI_ABORT : 0); if (thefaplArray) @@ -621,6 +631,11 @@ Java_hdf_hdf5lib_H5_H5Pset_1fapl_1split UNUSED(clss); + if (NULL == metaext) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_fapl_split: metaext is NULL"); + if (NULL == rawext) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_fapl_split: rawext is NULL"); + PIN_JAVA_STRING(ENVONLY, metaext, mstr, NULL, "H5Pset_fapl_split: metaext not pinned"); PIN_JAVA_STRING(ENVONLY, rawext, rstr, NULL, "H5Pset_fapl_split: rawext not pinned"); @@ -1125,12 +1140,17 @@ Java_hdf_hdf5lib_H5_H5Pset_1mdc_1config if (NULL == (j_str = (jstring)ENVPTR->GetObjectField(ENVONLY, cache_config, fid))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - PIN_JAVA_STRING(ENVONLY, j_str, str, NULL, "H5Pset_mdc_config: cache_config not pinned"); + if (j_str) { + PIN_JAVA_STRING(ENVONLY, j_str, str, NULL, "H5Pset_mdc_config: cache_config not pinned"); - HDstrncpy(cacheinfo.trace_file_name, str, H5AC__MAX_TRACE_FILE_NAME_LEN + 1); + HDstrncpy(cacheinfo.trace_file_name, str, H5AC__MAX_TRACE_FILE_NAME_LEN + 1); + cacheinfo.trace_file_name[H5AC__MAX_TRACE_FILE_NAME_LEN] = '\0'; - UNPIN_JAVA_STRING(ENVONLY, j_str, str); - str = NULL; + UNPIN_JAVA_STRING(ENVONLY, j_str, str); + str = NULL; + } + else + HDmemset(cacheinfo.trace_file_name, 0, H5AC__MAX_TRACE_FILE_NAME_LEN + 1); if (NULL == (fid = ENVPTR->GetFieldID(ENVONLY, cls, "evictions_enabled", "Z"))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); @@ -1383,6 +1403,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1mdc_1log_1options UNUSED(clss); + if (NULL == location) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_mdc_log_options: location string is NULL"); + PIN_JAVA_STRING(ENVONLY, location, locStr, NULL, "H5Pset_mdc_log_options: location string not pinned"); if ((retVal = H5Pset_mdc_log_options((hid_t)fapl_id, (hbool_t)is_enabled, locStr, (hbool_t)start_on_access)) < 0) diff --git a/java/src/jni/h5pImp.c b/java/src/jni/h5pImp.c index bed23c9..726e08c 100644 --- a/java/src/jni/h5pImp.c +++ b/java/src/jni/h5pImp.c @@ -174,6 +174,9 @@ Java_hdf_hdf5lib_H5__1H5Pcreate_1class close_callback = close_op; copy_callback = copy_op; + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "_H5Pcreate_class: class name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "_H5Pcreate_class: class name not pinned"); if ((class_id = H5Pcreate_class((hid_t)parent_class, cstr, (H5P_cls_create_func_t)H5P_cls_create_cb, (void *) create_data, @@ -201,6 +204,9 @@ Java_hdf_hdf5lib_H5__1H5Pcreate_1class_1nocb UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "_H5Pcreate_class_nocb: class name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "_H5Pcreate_class_nocb: class name not pinned"); if ((class_id = H5Pcreate_class((hid_t)parent_class, cstr, NULL, NULL, NULL, NULL, NULL, NULL)) < 0) @@ -239,6 +245,9 @@ Java_hdf_hdf5lib_H5_H5Pregister2 get_callback = prp_get; delete_callback = prp_delete; + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pregister2: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pregister2: property name not pinned"); PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pregister2: default property value buffer not pinned"); @@ -271,6 +280,9 @@ Java_hdf_hdf5lib_H5_H5Pregister2_1nocb UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pregister2_nocb: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pregister2_nocb: property name not pinned"); PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pregister2_nocb: default property value buffer not pinned"); @@ -310,6 +322,9 @@ Java_hdf_hdf5lib_H5_H5Pinsert2 get_callback = prp_get; delete_callback = prp_delete; + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pinsert2: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pinsert2: property name not pinned"); PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pinsert2: property value buffer not pinned"); @@ -342,6 +357,9 @@ Java_hdf_hdf5lib_H5_H5Pinsert2_1nocb UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pinsert2_nocb: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pinsert2_nocb: property name not pinned"); PIN_BYTE_ARRAY(ENVONLY, def_value, propValBuf, &isCopy, "H5Pinsert2_nocb: property value buffer not pinned"); @@ -370,6 +388,9 @@ Java_hdf_hdf5lib_H5_H5Pset UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pset: property name not pinned"); if ((retVal = H5Pset((hid_t)plid, cstr, &val)) < 0) @@ -396,6 +417,9 @@ Java_hdf_hdf5lib_H5_H5Pexist UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pexist: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pexist: property name not pinned"); if ((bval = H5Pexist((hid_t)plid, cstr)) < 0) @@ -425,6 +449,9 @@ Java_hdf_hdf5lib_H5_H5Pget_1size UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget_size: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pget_size: property name not pinned"); if ((status = H5Pget_size((hid_t)plid, cstr, &size)) < 0) @@ -541,6 +568,9 @@ Java_hdf_hdf5lib_H5_H5Pget UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pget: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pget: property name not pinned"); if ((status = H5Pget((hid_t)plid, cstr, &val)) < 0) @@ -629,6 +659,9 @@ Java_hdf_hdf5lib_H5_H5Pcopy_1prop UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pcopy_prop: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Pcopy_prop: property name not pinned"); if ((retVal = H5Pcopy_prop((hid_t)dst_plid, (hid_t)src_plid, cstr)) < 0) @@ -655,6 +688,9 @@ Java_hdf_hdf5lib_H5_H5Premove UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Premove: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Premove: property name not pinned"); if ((retVal = H5Premove((hid_t)plid, cstr)) < 0) @@ -681,6 +717,9 @@ Java_hdf_hdf5lib_H5_H5Punregister UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Punregister: property name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, cstr, NULL, "H5Punregister: property name not pinned"); if ((retVal = H5Punregister((hid_t)plid, cstr)) < 0) diff --git a/java/src/jni/h5pLAPLImp.c b/java/src/jni/h5pLAPLImp.c index c4502d5..f2cb80a 100644 --- a/java/src/jni/h5pLAPLImp.c +++ b/java/src/jni/h5pLAPLImp.c @@ -96,6 +96,9 @@ Java_hdf_hdf5lib_H5_H5Pset_1elink_1prefix UNUSED(clss); + if (NULL == prefix) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Pset_elink_prefix: prefix is NULL"); + PIN_JAVA_STRING(ENVONLY, prefix, linkPrefix, NULL, "H5Pset_elink_prefix: link prefix not pinned"); if ((retVal = H5Pset_elink_prefix((hid_t)lapl_id, linkPrefix)) < 0) diff --git a/java/src/jni/h5plImp.c b/java/src/jni/h5plImp.c index 4e096f1..90d78fe 100644 --- a/java/src/jni/h5plImp.c +++ b/java/src/jni/h5plImp.c @@ -83,6 +83,9 @@ Java_hdf_hdf5lib_H5_H5PLappend UNUSED(clss); + if (NULL == plugin_path) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5PLappend: new path is NULL"); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLappend: new path not pinned"); if ((retVal = H5PLappend(newPath)) < 0) @@ -106,6 +109,9 @@ Java_hdf_hdf5lib_H5_H5PLprepend UNUSED(clss); + if (NULL == plugin_path) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5PLprepend: new path is NULL"); + PIN_JAVA_STRING(ENVONLY, plugin_path, newPath, NULL, "H5PLprepend: new path not pinned"); if ((retVal = H5PLprepend(newPath)) < 0) @@ -130,6 +136,9 @@ Java_hdf_hdf5lib_H5_H5PLreplace UNUSED(clss); + if (NULL == plugin_path) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5PLreplace: new path is NULL"); + if (index < 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLreplace: index < 0"); @@ -157,6 +166,9 @@ Java_hdf_hdf5lib_H5_H5PLinsert UNUSED(clss); + if (NULL == plugin_path) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5PLinsert: new path is NULL"); + if (index < 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5PLinsert: index < 0"); diff --git a/java/src/jni/h5rImp.c b/java/src/jni/h5rImp.c index 9278113..83e2216 100644 --- a/java/src/jni/h5rImp.c +++ b/java/src/jni/h5rImp.c @@ -50,6 +50,8 @@ Java_hdf_hdf5lib_H5_H5Rcreate if (NULL == ref) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: reference is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Rcreate: name is NULL"); if ((refBufLen = ENVPTR->GetArrayLength(ENVONLY, ref)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); diff --git a/java/src/jni/h5sImp.c b/java/src/jni/h5sImp.c index 67ea59d..a91dab2 100644 --- a/java/src/jni/h5sImp.c +++ b/java/src/jni/h5sImp.c @@ -510,7 +510,7 @@ Java_hdf_hdf5lib_H5_H5Sget_1simple_1extent_1type UNUSED(clss); if (space_id < 0) - H5_LIBRARY_ERROR(ENVONLY); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sget_simple_extent_type: space_id < 0"); if (H5S_NO_CLASS == (retVal = H5Sget_simple_extent_type(space_id))) H5_LIBRARY_ERROR(ENVONLY); diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index 08ddf85..313ca8b 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -48,6 +48,9 @@ Java_hdf_hdf5lib_H5__1H5Topen2 UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Topen2: datatype name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Topen2: datatype name not pinned"); if ((status = H5Topen2((hid_t)loc_id, datatypeName, (hid_t)access_plist)) < 0) @@ -855,7 +858,10 @@ Java_hdf_hdf5lib_H5_H5Tget_1member_1index UNUSED(clss); - PIN_JAVA_STRING(ENVONLY, field_name, datatypeName, NULL, "H5Tget_member_index: datatype name not pinned"); + if (NULL == field_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tget_member_index: field name is NULL"); + + PIN_JAVA_STRING(ENVONLY, field_name, datatypeName, NULL, "H5Tget_member_index: field name not pinned"); if ((index = H5Tget_member_index((hid_t)type_id, datatypeName)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -937,6 +943,9 @@ Java_hdf_hdf5lib_H5_H5Tinsert UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tinsert: datatype name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Tinsert: datatype name not pinned"); if ((status = H5Tinsert((hid_t)type_id, datatypeName, (size_t)off, field_id)) < 0) @@ -1023,6 +1032,9 @@ Java_hdf_hdf5lib_H5_H5Tset_1tag UNUSED(clss); + if (NULL == tag) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tset_tag: tag is NULL"); + PIN_JAVA_STRING(ENVONLY, tag, tagBuf, NULL, "H5Tset_tag: tag buffer not pinned"); if ((status = H5Tset_tag((hid_t)type, tagBuf)) < 0) @@ -1119,11 +1131,13 @@ Java_hdf_hdf5lib_H5_H5Tenum_1insert_1int UNUSED(clss); if (NULL == value) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert: value is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert_int: value is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert_int: member name is NULL"); - PIN_JAVA_STRING(ENVONLY, name, memberName, NULL, "H5Tenum_insert: member name not pinned"); + PIN_JAVA_STRING(ENVONLY, name, memberName, NULL, "H5Tenum_insert_int: member name not pinned"); - PIN_INT_ARRAY(ENVONLY, value, intBuf, &isCopy, "H5Tenum_insert: int buffer not pinned"); + PIN_INT_ARRAY(ENVONLY, value, intBuf, &isCopy, "H5Tenum_insert_int: int buffer not pinned"); if ((status = H5Tenum_insert((hid_t)type_id, memberName, intBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1155,6 +1169,8 @@ Java_hdf_hdf5lib_H5_H5Tenum_1insert if (NULL == value) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert: value is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_insert: member name is NULL"); PIN_JAVA_STRING(ENVONLY, name, memberName, NULL, "H5Tenum_insert: member name not pinned"); @@ -1234,10 +1250,10 @@ Java_hdf_hdf5lib_H5_H5Tenum_1nameof UNUSED(clss); - if (NULL == value) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: value is NULL"); if (size <= 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: name size < 0"); + if (NULL == value) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_nameof: value is NULL"); if (NULL == (nameP = (char *) HDmalloc(sizeof(char) * (size_t)size))) H5_JNI_FATAL_ERROR(ENVONLY, "H5Tenum_nameof: failed to allocate name buffer"); @@ -1278,6 +1294,8 @@ Java_hdf_hdf5lib_H5_H5Tenum_1valueof_1int if (NULL == value) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof_int: value is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof_int: enum value name is NULL"); PIN_JAVA_STRING(ENVONLY, name, enumValue, NULL, "H5Tenum_valueof_int: enum value not pinned"); @@ -1313,6 +1331,8 @@ Java_hdf_hdf5lib_H5_H5Tenum_1valueof if (NULL == value) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof: value is NULL"); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tenum_valueof: enum value name is NULL"); PIN_JAVA_STRING(ENVONLY, name, enumValue, NULL, "H5Tenum_valueof: enum value not pinned"); @@ -1533,6 +1553,9 @@ Java_hdf_hdf5lib_H5_H5Tcommit UNUSED(clss); + if (NULL == name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tcommit: datatype name is NULL"); + PIN_JAVA_STRING(ENVONLY, name, datatypeName, NULL, "H5Tcommit: datatype name not pinned"); if ((status = H5Tcommit2((hid_t)loc_id, datatypeName, (hid_t)type, (hid_t)link_plist_id, (hid_t)create_plist_id, (hid_t)access_plist_id)) < 0) @@ -1561,10 +1584,10 @@ Java_hdf_hdf5lib_H5__1H5Tarray_1create2 UNUSED(clss); - if (NULL == dims) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: dims is NULL"); if (rank <= 0) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: rank is < 1"); + if (NULL == dims) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Tarray_create: dims is NULL"); PIN_LONG_ARRAY(ENVONLY, dims, dimsP, &isCopy, "H5Tarray_create: dimsP not pinned"); diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 4208ce1..fce969e 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -232,7 +232,7 @@ h5str_convert HDmemcpy(cptr, &tmp_double, sizeof(double)); break; } -#if H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != 0 && H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { long double tmp_ldouble = 0.0; @@ -259,6 +259,8 @@ h5str_convert if (len > 0) { HDstrncpy(cptr, this_str, typeSize); + cptr[typeSize - 1] = '\0'; + retVal = typeSize; } else { @@ -329,6 +331,7 @@ h5str_convert break; } +#if H5_SIZEOF_LONG != H5_SIZEOF_INT case sizeof(long): { unsigned long tmp_ulong = 0; @@ -345,7 +348,7 @@ h5str_convert break; } - +#endif #if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG case sizeof(long long): { @@ -444,14 +447,14 @@ h5str_convert value = &tmp_ushort; break; } - +#if H5_SIZEOF_LONG != H5_SIZEOF_INT case sizeof(long): { unsigned long tmp_ulong = 0; value = &tmp_ulong; break; } - +#endif #if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG case sizeof(long long): { @@ -694,7 +697,7 @@ h5str_sprintf break; } -#if H5_SIZEOF_LONG_DOUBLE != 0 +#if H5_SIZEOF_LONG_DOUBLE != 0 && H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { long double tmp_ldouble = 0.0; @@ -750,6 +753,7 @@ h5str_sprintf H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); HDstrncpy(this_str, tmp_str, typeSize); + this_str[typeSize] = '\0'; } } @@ -844,7 +848,7 @@ h5str_sprintf break; } - +#if H5_SIZEOF_LONG != H5_SIZEOF_INT case sizeof(long): { unsigned long tmp_ulong = 0; @@ -871,7 +875,7 @@ h5str_sprintf break; } - +#endif #if H5_SIZEOF_LONG_LONG != H5_SIZEOF_LONG case sizeof(long long): { diff --git a/java/src/jni/h5vlImp.c b/java/src/jni/h5vlImp.c index c816abf..92e456e 100644 --- a/java/src/jni/h5vlImp.c +++ b/java/src/jni/h5vlImp.c @@ -41,6 +41,9 @@ Java_hdf_hdf5lib_H5_H5VLregister_1connector_1by_1name UNUSED(clss); + if (NULL == connector_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5VLregister_connector_by_name: VOL connector name is NULL"); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLregister_connector_by_name: VOL connector name not pinned"); if ((status = H5VLregister_connector_by_name(volName, (hid_t)vipl_id)) < 0) @@ -87,6 +90,9 @@ Java_hdf_hdf5lib_H5_H5VLis_1connector_1registered UNUSED(clss); + if (NULL == connector_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5VLis_connector_registered: VOL connector name is NULL"); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLis_connector_registered: VOL connector name not pinned"); if ((bval = H5VLis_connector_registered(volName)) < 0) @@ -115,6 +121,9 @@ Java_hdf_hdf5lib_H5_H5VLget_1connector_1id UNUSED(clss); + if (NULL == connector_name) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5VLget_connector_id: VOL connector name is NULL"); + PIN_JAVA_STRING(ENVONLY, connector_name, volName, NULL, "H5VLget_connector_id: VOL connector name not pinned"); if ((status = H5VLget_connector_id(volName)) < 0) diff --git a/java/test/TestH5Edefault.java b/java/test/TestH5Edefault.java index 591793f..ee2850b 100644 --- a/java/test/TestH5Edefault.java +++ b/java/test/TestH5Edefault.java @@ -243,7 +243,7 @@ public class TestH5Edefault { H5.H5Eget_class_name(-1); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = HDF5LibraryException.class) public void testH5Eget_class_name_invalid_classname() throws Throwable { H5.H5Eget_class_name(HDF5Constants.H5E_DEFAULT); } diff --git a/java/test/TestH5Oparams.java b/java/test/TestH5Oparams.java index 8b3c673..d340ee7 100644 --- a/java/test/TestH5Oparams.java +++ b/java/test/TestH5Oparams.java @@ -124,7 +124,7 @@ public class TestH5Oparams { H5.H5Oset_comment(-1, "Bogus"); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = HDF5LibraryException.class) public void testH5Oget_comment_invalid() throws Throwable { H5.H5Oget_comment(-1); } @@ -139,7 +139,7 @@ public class TestH5Oparams { H5.H5Oset_comment_by_name(-1, null, null, -1); } - @Test(expected = IllegalArgumentException.class) + @Test(expected = HDF5LibraryException.class) public void testH5Oget_comment_by_name_invalid() throws Throwable { H5.H5Oget_comment_by_name(-1, "Bogus", -1); } diff --git a/java/test/TestH5Sbasic.java b/java/test/TestH5Sbasic.java index 3007495..2173647 100644 --- a/java/test/TestH5Sbasic.java +++ b/java/test/TestH5Sbasic.java @@ -49,7 +49,7 @@ public class TestH5Sbasic { H5.H5Screate(-1); } - @Test(expected = HDF5LibraryException.class) + @Test(expected = IllegalArgumentException.class) public void testH5Sget_simple_extent_type_invalid() throws Throwable { H5.H5Sget_simple_extent_type(-1); } -- cgit v0.12 From 8c22f4180195b63b77c5b27a704b8158a422b793 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Tue, 12 Feb 2019 15:51:42 -0600 Subject: KNL option for batch scripts --- config/cmake/scripts/HPC/sbatch-HDF5options.cmake | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/config/cmake/scripts/HPC/sbatch-HDF5options.cmake b/config/cmake/scripts/HPC/sbatch-HDF5options.cmake index 5316f41..dc97b3a 100644 --- a/config/cmake/scripts/HPC/sbatch-HDF5options.cmake +++ b/config/cmake/scripts/HPC/sbatch-HDF5options.cmake @@ -28,22 +28,24 @@ if (DEFINED MPI) endif () ############################################################################################# ### options to run test scripts in batch commands +if (DEFINED KNL) + ### some additions and alternatives to cross compile on haswell for knl + set (COMPILENODE_HWCOMPILE_MODULE "craype-haswell") + set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") + set (LOCAL_BATCH_SCRIPT_NAME "knl_ctestS.sl") + set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "knl_ctestP.sl") +else () + set (LOCAL_BATCH_SCRIPT_NAME "ctestS.sl") + set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ctestP.sl") +endif () set (LOCAL_BATCH_SCRIPT_COMMAND "sbatch") set (LOCAL_BATCH_TEST "TRUE") -set (LOCAL_BATCH_SCRIPT_NAME "ctestS.sl") -set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ctestP.sl") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_TEST:BOOL=ON") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=ctestS.sl") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=ctestP.sl") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=${LOCAL_BATCH_SCRIPT_NAME}") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_EXECUTABLE:STRING=srun") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_NUMPROC_FLAG:STRING=-n") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_MAX_NUMPROCS:STRING=6") ############################################################################################# -### some additions and alternatives to cross compile on haswell for knl -#set (COMPILENODE_HWCOMPILE_MODULE "craype-haswell") -#set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") -#set (SITE_BUILDNAME_SUFFIX "knl-intel17-SHARED" -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=knl_ctestS.sl") -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=knl_ctestP.sl") ############################################################################################# -- cgit v0.12 From b5305b25a67c41f0d87352d39e799b603ed10c69 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 12 Feb 2019 21:51:15 -0600 Subject: Align develop with incoming hyperslab_updates branch changes. --- src/H5CX.c | 2 +- src/H5Dchunk.c | 89 ++-- src/H5Dmpio.c | 72 +-- src/H5Osdspace.c | 8 +- src/H5S.c | 391 +++++----------- src/H5Sall.c | 100 ++-- src/H5Sdbg.c | 10 +- src/H5Shyper.c | 354 +++++++------- src/H5Smpio.c | 811 +++++++++++++++------------------ src/H5Snone.c | 393 ++++++++-------- src/H5Spkg.h | 23 +- src/H5Spoint.c | 503 ++++++++++---------- src/H5Sprivate.h | 24 +- src/H5Spublic.h | 69 ++- src/H5Sselect.c | 319 ++++++++----- src/H5Stest.c | 57 ++- test/objcopy.c | 4 +- test/tselect.c | 1214 +++++++++++++++++++++++++------------------------ testpar/t_shapesame.c | 32 +- testpar/t_span_tree.c | 28 +- 20 files changed, 2256 insertions(+), 2247 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index f945df0..d90fec1 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -53,7 +53,7 @@ * each thread individually. The association of contexts to threads will * be handled by the pthread library. * - * In order for this macro to work, H5E__get_my_stack() must be preceeded + * In order for this macro to work, H5CX_get_my_context() must be preceeded * by "H5CX_node_t *ctx =". */ #define H5CX_get_my_context() H5CX__get_context() diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index af8ff91..6d1067b 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1073,21 +1073,19 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf if((file_space_normalized = H5S_hyper_normalize_offset((H5S_t *)file_space, old_offset)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to normalize selection") - /* Decide the number of chunks in each dimension*/ - for(u = 0; u < f_ndims; u++) { + /* Decide the number of chunks in each dimension */ + for(u = 0; u < f_ndims; u++) /* Keep the size of the chunk dimensions as hsize_t for various routines */ fm->chunk_dim[u] = fm->layout->u.chunk.dim[u]; - } /* end for */ #ifdef H5_HAVE_PARALLEL /* Calculate total chunk in file map*/ fm->select_chunk = NULL; if(io_info->using_mpi_vfd) { H5_CHECK_OVERFLOW(fm->layout->u.chunk.nchunks, hsize_t, size_t); - if(fm->layout->u.chunk.nchunks) { + if(fm->layout->u.chunk.nchunks) if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->layout->u.chunk.nchunks * sizeof(H5D_chunk_info_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") - } } /* end if */ #endif /* H5_HAVE_PARALLEL */ @@ -1129,10 +1127,9 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf HDassert(fm->single_space); /* Allocate the single chunk information */ - if(NULL == dataset->shared->cache.chunk.single_chunk_info) { + if(NULL == dataset->shared->cache.chunk.single_chunk_info) if(NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") - } /* end if */ fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info; HDassert(fm->single_chunk_info); @@ -1147,10 +1144,9 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf hbool_t sel_hyper_flag; /* Whether file selection is a hyperslab */ /* Initialize skip list for chunk selections */ - if(NULL == dataset->shared->cache.chunk.sel_chunks) { + if(NULL == dataset->shared->cache.chunk.sel_chunks) if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections") - } /* end if */ fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks; HDassert(fm->sel_chunks); @@ -1245,10 +1241,9 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf fm->mchunk_tmpl = tmp_mspace; /* Create temporary datatypes for selection iteration */ - if(!file_type) { + if(!file_type) if(NULL == (file_type = H5T_copy(dataset->shared->type, H5T_COPY_ALL))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype") - } /* end if */ /* Create selection iterator for memory selection */ if(0 == (elmt_size = H5T_get_size(mem_type))) @@ -1540,7 +1535,7 @@ done: /*------------------------------------------------------------------------- * Function: H5D__create_chunk_file_map_hyper * - * Purpose: Create all chunk selections in file. + * Purpose: Create all chunk selections in file, for a hyperslab selection. * * Return: Non-negative on success/Negative on failure * @@ -1556,8 +1551,8 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t #endif /* H5_HAVE_PARALLEL */ *io_info) { - hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ + hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ + hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ hsize_t sel_points; /* Number of elements in file selection */ hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */ hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */ @@ -1572,7 +1567,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t FUNC_ENTER_STATIC /* Sanity check */ - HDassert(fm->f_ndims>0); + HDassert(fm->f_ndims > 0); /* Get number of elements selected in file */ sel_points = fm->nelmts; @@ -1596,7 +1591,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Iterate through each chunk in the dataset */ while(sel_points) { - /* Check for intersection of temporary chunk and file selection */ + /* Check for intersection of current chunk and file selection */ /* (Casting away const OK - QAK) */ if(TRUE == H5S_hyper_intersect_block((H5S_t *)fm->file_space, coords, end)) { H5S_t *tmp_fchunk; /* Temporary file dataspace */ @@ -1634,7 +1629,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Add temporary chunk to the list of chunks */ /* Allocate the file & memory chunk information */ - if (NULL==(new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) { + if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) { (void)H5S_close(tmp_fchunk); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") } /* end if */ @@ -1642,7 +1637,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Initialize the chunk information */ /* Set the chunk index */ - new_chunk_info->index=chunk_index; + new_chunk_info->index = chunk_index; #ifdef H5_HAVE_PARALLEL /* Store chunk selection information, for multi-chunk I/O */ @@ -1655,16 +1650,13 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t new_chunk_info->fspace_shared = FALSE; /* Set the memory chunk dataspace */ - new_chunk_info->mspace=NULL; + new_chunk_info->mspace = NULL; new_chunk_info->mspace_shared = FALSE; /* Copy the chunk's scaled coordinates */ HDmemcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); new_chunk_info->scaled[fm->f_ndims] = 0; - /* Copy the chunk's scaled coordinates */ - HDmemcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); - /* Insert the new chunk into the skip list */ if(H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) { H5D__free_chunk_info(new_chunk_info, NULL, NULL); @@ -1688,12 +1680,11 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t chunk_index++; /* Set current increment dimension */ - curr_dim=(int)fm->f_ndims-1; + curr_dim = (int)fm->f_ndims - 1; /* Increment chunk location in fastest changing dimension */ - H5_CHECK_OVERFLOW(fm->chunk_dim[curr_dim],hsize_t,hssize_t); - coords[curr_dim]+=fm->chunk_dim[curr_dim]; - end[curr_dim]+=fm->chunk_dim[curr_dim]; + coords[curr_dim] += fm->chunk_dim[curr_dim]; + end[curr_dim] += fm->chunk_dim[curr_dim]; scaled[curr_dim]++; /* Bring chunk location back into bounds, if necessary */ @@ -1707,11 +1698,14 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Decrement current dimension */ curr_dim--; - /* Increment chunk location in current dimension */ - scaled[curr_dim]++; - coords[curr_dim] += fm->chunk_dim[curr_dim]; - end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1; - } while(coords[curr_dim] > sel_end[curr_dim]); + /* Check for valid current dim */ + if(curr_dim >= 0) { + /* Increment chunk location in current dimension */ + scaled[curr_dim]++; + coords[curr_dim] += fm->chunk_dim[curr_dim]; + end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1; + } /* end if */ + } while(curr_dim >= 0 && (coords[curr_dim] > sel_end[curr_dim])); /* Re-calculate the index of this chunk */ chunk_index = H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, scaled); @@ -1743,12 +1737,12 @@ static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) { H5SL_node_t *curr_node; /* Current node in skip list */ - hsize_t file_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t file_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - hsize_t mem_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t mem_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - hssize_t adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to all file chunks */ - hssize_t chunk_adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to a particular chunk */ + hsize_t file_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ + hsize_t file_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ + hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ + hsize_t mem_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ + hssize_t adjust[H5S_MAX_RANK]; /* Adjustment to make to all file chunks */ + hssize_t chunk_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1762,7 +1756,7 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ /* Get the node */ - curr_node=H5SL_first(fm->sel_chunks); + curr_node = H5SL_first(fm->sel_chunks); /* Get pointer to chunk's information */ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); @@ -1785,15 +1779,15 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") /* Calculate the adjustment for memory selection from file selection */ - HDassert(fm->m_ndims==fm->f_ndims); - for(u=0; uf_ndims; u++) { - H5_CHECK_OVERFLOW(file_sel_start[u],hsize_t,hssize_t); - H5_CHECK_OVERFLOW(mem_sel_start[u],hsize_t,hssize_t); - adjust[u]=(hssize_t)file_sel_start[u]-(hssize_t)mem_sel_start[u]; + HDassert(fm->m_ndims == fm->f_ndims); + for(u = 0; u < fm->f_ndims; u++) { + H5_CHECK_OVERFLOW(file_sel_start[u], hsize_t, hssize_t); + H5_CHECK_OVERFLOW(mem_sel_start[u], hsize_t, hssize_t); + adjust[u] = (hssize_t)file_sel_start[u] - (hssize_t)mem_sel_start[u]; } /* end for */ /* Iterate over each chunk in the chunk list */ - curr_node=H5SL_first(fm->sel_chunks); + curr_node = H5SL_first(fm->sel_chunks); while(curr_node) { H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ @@ -1832,7 +1826,7 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection") /* Get the next chunk node in the skip list */ - curr_node=H5SL_next(curr_node); + curr_node = H5SL_next(curr_node); } /* end while */ } /* end else */ @@ -1976,7 +1970,7 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u { H5D_chunk_map_t *fm = (H5D_chunk_map_t *)_fm; /* File<->memory chunk mapping info */ H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */ - hsize_t coords_in_mem[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */ + hsize_t coords_in_mem[H5S_MAX_RANK]; /* Coordinates of element in memory */ hsize_t chunk_index; /* Chunk index */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2001,11 +1995,10 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, H5_ITER_ERROR, "can't locate chunk in skip list") /* Check if the chunk already has a memory space */ - if(NULL == chunk_info->mspace) { + if(NULL == chunk_info->mspace) /* Copy the template memory chunk dataspace */ if(NULL == (chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy file space") - } /* end else */ /* Update the "last chunk seen" information */ fm->last_index = chunk_index; diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 0423006..01cf932 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -2841,30 +2841,30 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty size_t mod_data_size; /* Look up the chunk and get its file and memory dataspaces */ - if (NULL == (chunk_info = (H5D_chunk_info_t *) H5SL_search(fm->sel_chunks, &chunk_entry->index))) + if(NULL == (chunk_info = (H5D_chunk_info_t *) H5SL_search(fm->sel_chunks, &chunk_entry->index))) HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list") /* Determine size of serialized chunk file dataspace, plus the size of * the data being written */ - if (H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0) + if(H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to get encoded dataspace size") - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") mod_data_size += (size_t) iter_nelmts * type_info->src_type_size; - if (NULL == (mod_data[num_send_requests] = (unsigned char *) H5MM_malloc(mod_data_size))) + if(NULL == (mod_data[num_send_requests] = (unsigned char *) H5MM_malloc(mod_data_size))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk modification send buffer") /* Serialize the chunk's file dataspace into the buffer */ mod_data_p = mod_data[num_send_requests]; - if (H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0) + if(H5S_encode(chunk_info->fspace, &mod_data_p, &mod_data_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to encode dataspace") /* Initialize iterator for memory selection */ - if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; @@ -2875,11 +2875,11 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty /* Send modification data to new owner */ H5_CHECK_OVERFLOW(mod_data_size, size_t, int) H5_CHECK_OVERFLOW(chunk_entry->index, hsize_t, int) - if (MPI_SUCCESS != (mpi_code = MPI_Isend(mod_data[num_send_requests], (int) mod_data_size, MPI_BYTE, + if(MPI_SUCCESS != (mpi_code = MPI_Isend(mod_data[num_send_requests], (int) mod_data_size, MPI_BYTE, chunk_entry->owners.new_owner, (int) chunk_entry->index, io_info->comm, &send_requests[num_send_requests]))) HMPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code) - if (mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0) + if(mem_iter_init && H5S_SELECT_ITER_RELEASE(mem_iter) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release memory selection iterator") mem_iter_init = FALSE; @@ -3048,11 +3048,11 @@ H5D__mpio_filtered_collective_write_type(H5D_filtered_collective_io_info_t *chun } /* end if */ done: - if (write_buf_array) + if(write_buf_array) H5MM_free(write_buf_array); - if (file_offset_array) + if(file_offset_array) H5MM_free(file_offset_array); - if (length_array) + if(length_array) H5MM_free(length_array); FUNC_LEAVE_NOAPI(ret_value) @@ -3170,7 +3170,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if (NULL == (mem_iter = (H5S_sel_iter_t *) H5MM_malloc(sizeof(H5S_sel_iter_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate memory iterator") - if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; @@ -3180,53 +3180,53 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk * from the current process, then apply any modifications from other processes. Finally, * filter the newly-updated chunk. */ - switch (io_info->op_type) { + switch(io_info->op_type) { case H5D_IO_OP_READ: - if (NULL == (file_iter = (H5S_sel_iter_t *) H5MM_malloc(sizeof(H5S_sel_iter_t)))) + if(NULL == (file_iter = (H5S_sel_iter_t *) H5MM_malloc(sizeof(H5S_sel_iter_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate file iterator") - if (H5S_select_iter_init(file_iter, chunk_info->fspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(file_iter, chunk_info->fspace, type_info->src_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") file_iter_init = TRUE; - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - if (NULL == (tmp_gath_buf = H5MM_malloc((hsize_t) iter_nelmts * type_info->src_type_size))) + if(NULL == (tmp_gath_buf = H5MM_malloc((hsize_t) iter_nelmts * type_info->src_type_size))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer") - if (!H5D__gather_mem(chunk_entry->buf, chunk_info->fspace, file_iter, (size_t) iter_nelmts, tmp_gath_buf)) + if(!H5D__gather_mem(chunk_entry->buf, chunk_info->fspace, file_iter, (size_t) iter_nelmts, tmp_gath_buf)) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't gather from chunk buffer") - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - if (H5D__scatter_mem(tmp_gath_buf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, io_info->u.rbuf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to read buffer") + if(H5D__scatter_mem(tmp_gath_buf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, io_info->u.rbuf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to read buffer") break; case H5D_IO_OP_WRITE: - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - if (NULL == (tmp_gath_buf = H5MM_malloc((hsize_t) iter_nelmts * type_info->src_type_size))) + if(NULL == (tmp_gath_buf = H5MM_malloc((hsize_t) iter_nelmts * type_info->src_type_size))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer") /* Gather modification data from the application write buffer into a temporary buffer */ if(!H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, tmp_gath_buf)) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't gather from write buffer") - if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0) + if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator") mem_iter_init = FALSE; /* Initialize iterator for file selection */ - if (H5S_select_iter_init(mem_iter, chunk_info->fspace, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->fspace, type_info->dst_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information") mem_iter_init = TRUE; - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") /* Scatter the owner's modification data into the chunk data buffer according to @@ -3235,44 +3235,44 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if(H5D__scatter_mem(tmp_gath_buf, chunk_info->fspace, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to chunk data buffer") - if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0) + if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator") mem_iter_init = FALSE; - if (MPI_SUCCESS != (mpi_code = MPI_Waitall(chunk_entry->async_info.num_receive_requests, + if(MPI_SUCCESS != (mpi_code = MPI_Waitall(chunk_entry->async_info.num_receive_requests, chunk_entry->async_info.receive_requests_array, MPI_STATUSES_IGNORE))) HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code) /* For each asynchronous receive call previously posted, receive the chunk modification * buffer from another rank and update the chunk data */ - for (i = 0; i < (size_t) chunk_entry->async_info.num_receive_requests; i++) { + for(i = 0; i < (size_t) chunk_entry->async_info.num_receive_requests; i++) { const unsigned char *mod_data_p; /* Decode the process' chunk file dataspace */ mod_data_p = chunk_entry->async_info.receive_buffer_array[i]; - if (NULL == (dataspace = H5S_decode(&mod_data_p))) + if(NULL == (dataspace = H5S_decode(&mod_data_p))) HGOTO_ERROR(H5E_DATASET, H5E_CANTDECODE, FAIL, "unable to decode dataspace") - if (H5S_select_iter_init(mem_iter, dataspace, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, dataspace, type_info->dst_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; - if ((iter_nelmts = H5S_GET_SELECT_NPOINTS(dataspace)) < 0) + if((iter_nelmts = H5S_GET_SELECT_NPOINTS(dataspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") /* Update the chunk data with the received modification data */ if(H5D__scatter_mem(mod_data_p, dataspace, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't scatter to write buffer") - if (H5S_SELECT_ITER_RELEASE(mem_iter) < 0) + if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "couldn't release selection iterator") mem_iter_init = FALSE; - if (dataspace) { - if (H5S_close(dataspace) < 0) + if(dataspace) { + if(H5S_close(dataspace) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") dataspace = NULL; - } + } /* end if */ H5MM_free(chunk_entry->async_info.receive_buffer_array[i]); } /* end for */ diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 74fa72e..b7f70d1 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -189,7 +189,7 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, done: if(!ret_value && sdim) { - H5S_extent_release(sdim); + H5S__extent_release(sdim); sdim = H5FL_FREE(H5S_extent_t, sdim); } /* end if */ @@ -310,7 +310,7 @@ H5O_sdspace_copy(const void *_mesg, void *_dest) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy extent information */ - if(H5S_extent_copy_real(dest, mesg, TRUE) < 0) + if(H5S__extent_copy_real(dest, mesg, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent") /* Set return value */ @@ -391,7 +391,7 @@ H5O__sdspace_reset(void *_mesg) FUNC_ENTER_STATIC_NOERR - H5S_extent_release(mesg); + H5S__extent_release(mesg); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O__sdspace_reset() */ @@ -470,7 +470,7 @@ H5O_sdspace_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "dataspace extent allocation failed") /* Create a copy of the dataspace extent */ - if(H5S_extent_copy_real(udata->src_space_extent, src_space_extent, TRUE) < 0) + if(H5S__extent_copy_real(udata->src_space_extent, src_space_extent, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent") } /* end if */ diff --git a/src/H5S.c b/src/H5S.c index 2faf540..3a917bc 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -46,7 +46,12 @@ /********************/ /* Local Prototypes */ /********************/ -static htri_t H5S_is_simple(const H5S_t *sdim); +static htri_t H5S__is_simple(const H5S_t *sdim); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ /*********************/ @@ -63,15 +68,6 @@ const unsigned H5O_sdspace_ver_bounds[] = { H5O_SDSPACE_VERSION_LATEST /* H5F_LIBVER_LATEST */ }; -/*****************************/ -/* Library Private Variables */ -/*****************************/ - - -/*******************/ -/* Local Variables */ -/*******************/ - /* Declare a free list to manage the H5S_extent_t struct */ H5FL_DEFINE(H5S_extent_t); @@ -81,6 +77,11 @@ H5FL_DEFINE(H5S_t); /* Declare a free list to manage the array's of hsize_t's */ H5FL_ARR_DEFINE(hsize_t, H5S_MAX_RANK); + +/*******************/ +/* Local Variables */ +/*******************/ + /* Dataspace ID class */ static const H5I_class_t H5I_DATASPACE_CLS[1] = {{ H5I_DATASPACE, /* ID class value */ @@ -112,9 +113,9 @@ H5S__init_package(void) FUNC_ENTER_PACKAGE - /* Initialize the atom group for the file IDs */ + /* Initialize the atom group for the dataspace IDs */ if(H5I_register_type(H5I_DATASPACE_CLS) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize dataspace ID class") /* Mark "top" of interface as initialized, too */ H5S_top_package_initialize_s = TRUE; @@ -329,10 +330,9 @@ H5S_create(H5S_class_t type) ret_value = new_ds; done: - if(ret_value == NULL) { + if(ret_value == NULL) if(new_ds && H5S_close(new_ds) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, NULL, "unable to release dataspace") - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_create() */ @@ -359,7 +359,7 @@ done: hid_t H5Screate(H5S_class_t type) { - H5S_t *new_ds=NULL; /* New dataspace structure */ + H5S_t *new_ds = NULL; /* New dataspace structure */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -373,21 +373,20 @@ H5Screate(H5S_class_t type) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace") /* Atomize */ - if((ret_value = H5I_register (H5I_DATASPACE, new_ds, TRUE)) < 0) + if((ret_value = H5I_register(H5I_DATASPACE, new_ds, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") done: - if(ret_value < 0) { + if(ret_value < 0) if(new_ds && H5S_close(new_ds) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") - } /* end if */ FUNC_LEAVE_API(ret_value) } /* end H5Screate() */ /*------------------------------------------------------------------------- - * Function: H5S_extent_release + * Function: H5S__extent_release * * Purpose: Releases all memory associated with a dataspace extent. * @@ -396,16 +395,12 @@ done: * Programmer: Quincey Koziol * Thursday, July 23, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t -H5S_extent_release(H5S_extent_t *extent) +H5S__extent_release(H5S_extent_t *extent) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE_NOERR HDassert(extent); @@ -417,9 +412,8 @@ H5S_extent_release(H5S_extent_t *extent) extent->max = H5FL_ARR_FREE(hsize_t, extent->max); } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_extent_release() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__extent_release() */ /*------------------------------------------------------------------------- @@ -445,11 +439,11 @@ H5S_close(H5S_t *ds) /* Release selection (this should come before the extent release) */ if(H5S_SELECT_RELEASE(ds) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace selection") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace selection") /* Release extent */ - if(H5S_extent_release(&ds->extent) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent") + if(H5S__extent_release(&ds->extent) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent") /* Release the main structure */ ds = H5FL_FREE(H5S_t, ds); @@ -466,13 +460,9 @@ done: * * Return: Non-negative on success/Negative on failure * - * Errors: - * * Programmer: Robb Matzke * Tuesday, December 9, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -484,7 +474,7 @@ H5Sclose(hid_t space_id) H5TRACE1("e", "i", space_id); /* Check args */ - if (NULL == H5I_object_verify(space_id,H5I_DATASPACE)) + if(NULL == H5I_object_verify(space_id, H5I_DATASPACE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") /* When the reference count reaches zero the resources are freed */ @@ -502,14 +492,11 @@ done: * Purpose: Copies a dataspace. * * Return: Success: ID of the new dataspace - * * Failure: Negative * * Programmer: Robb Matzke * Friday, January 30, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t @@ -535,10 +522,9 @@ H5Scopy(hid_t space_id) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") done: - if(ret_value < 0) { + if(ret_value < 0) if(dst && H5S_close(dst) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") - } /* end if */ FUNC_LEAVE_API(ret_value) } /* end H5Scopy() */ @@ -554,8 +540,6 @@ done: * Programmer: Quincey Koziol * Thursday, July 23, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -593,8 +577,6 @@ done: * Programmer: Neil Fortner * Monday, February 23, 2015 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -608,7 +590,7 @@ H5S_extent_copy(H5S_t *dst, const H5S_t *src) HDassert(src); /* Copy extent */ - if(H5S_extent_copy_real(&(dst->extent), &(src->extent), TRUE) < 0) + if(H5S__extent_copy_real(&(dst->extent), &(src->extent), TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent") /* If the selection is 'all', update the number of elements selected in the @@ -623,7 +605,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5S_extent_copy_real + * Function: H5S__extent_copy_real * * Purpose: Copies a dataspace extent * @@ -632,20 +614,18 @@ done: * Programmer: Quincey Koziol * Wednesday, June 3, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t -H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) +H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) { unsigned u; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Release destination extent before we copy over it */ - if(H5S_extent_release(dst) < 0) + if(H5S__extent_release(dst) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent") /* Copy the regular fields */ @@ -690,7 +670,7 @@ H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_ma done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_extent_copy_real() */ +} /* end H5S__extent_copy_real() */ /*------------------------------------------------------------------------- @@ -704,14 +684,11 @@ done: * selection) * * Return: Success: A pointer to a new copy of SRC - * * Failure: NULL * * Programmer: Robb Matzke * Thursday, December 4, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ H5S_t * @@ -726,7 +703,7 @@ H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the source dataspace's extent */ - if(H5S_extent_copy_real(&(dst->extent), &(src->extent), copy_max) < 0) + if(H5S__extent_copy_real(&(dst->extent), &(src->extent), copy_max) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent") /* Copy the source dataspace's selection */ @@ -751,7 +728,6 @@ done: * Purpose: Determines how many data points a dataset extent has. * * Return: Success: Number of data points in the dataset extent. - * * Failure: negative * * Programmer: Robb Matzke @@ -761,9 +737,6 @@ done: * pattern, don't call it directly, use the appropriate macro * defined in H5Sprivate.h. * - * Modifications: - * Changed Name - QAK 7/7/98 - * *------------------------------------------------------------------------- */ hssize_t @@ -790,15 +763,11 @@ done: * Purpose: Determines how many data points a dataset extent has. * * Return: Success: Number of data points in the dataset. - * * Failure: negative * * Programmer: Robb Matzke * Tuesday, December 9, 1997 * - * Modifications: - * Changed Name - QAK 7/7/98 - * *------------------------------------------------------------------------- */ hssize_t @@ -832,14 +801,11 @@ done: * * Return: Success: Maximum number of data points the dataspace * may have. - * * Failure: 0 * * Programmer: Robb Matzke * Tuesday, December 9, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ hsize_t @@ -853,7 +819,7 @@ H5S_get_npoints_max(const H5S_t *ds) /* check args */ HDassert(ds); - switch (H5S_GET_EXTENT_TYPE(ds)) { + switch(H5S_GET_EXTENT_TYPE(ds)) { case H5S_NULL: ret_value = 0; break; @@ -863,31 +829,30 @@ H5S_get_npoints_max(const H5S_t *ds) break; case H5S_SIMPLE: - if (ds->extent.max) { - for (ret_value=1, u=0; uextent.rank; u++) { - if (H5S_UNLIMITED==ds->extent.max[u]) { + if(ds->extent.max) { + for(ret_value = 1, u = 0; u < ds->extent.rank; u++) { + if(H5S_UNLIMITED == ds->extent.max[u]) { ret_value = HSIZET_MAX; break; - } + } /* end if */ else ret_value *= ds->extent.max[u]; - } - } - else { - for (ret_value=1, u=0; uextent.rank; u++) + } /* end for */ + } /* end if */ + else + for(ret_value = 1, u = 0; u < ds->extent.rank; u++) ret_value *= ds->extent.size[u]; - } break; case H5S_NO_CLASS: default: HDassert("unknown dataspace class" && 0); HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0, "internal error (unknown dataspace class)") - } + } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5S_get_npoints_max() */ /*------------------------------------------------------------------------- @@ -896,21 +861,18 @@ done: * Purpose: Determines the dimensionality of a dataspace. * * Return: Success: The number of dimensions in a dataspace. - * * Failure: Negative * * Programmer: Robb Matzke * Thursday, December 11, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ int H5Sget_simple_extent_ndims(hid_t space_id) { - H5S_t *ds; - int ret_value; + H5S_t *ds; + int ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("Is", "i", space_id); @@ -933,7 +895,6 @@ done: * * Return: Success: Non-negative number of dimensions. Zero * implies a scalar. - * * Failure: Negative * * Programmer: Robb Matzke @@ -943,8 +904,6 @@ done: * pattern, don't call it directly, use the appropriate macro * defined in H5Sprivate.h. * - * Modifications: - * *------------------------------------------------------------------------- */ int @@ -979,43 +938,36 @@ done: * Function: H5Sget_simple_extent_dims * * Purpose: Returns the size and maximum sizes in each dimension of - * a dataspace DS through the DIMS and MAXDIMS arguments. + * a dataspace DS through the DIMS and MAXDIMS arguments. * * Return: Success: Number of dimensions, the same value as * returned by H5Sget_simple_extent_ndims(). - * * Failure: Negative * * Programmer: Robb Matzke * Thursday, December 11, 1997 * - * Modifications: - * June 18, 1998 Albert Cheng - * Added maxdims argument. Removed dims argument check - * since it can still return ndims even if both dims and - * maxdims are NULLs. - * *------------------------------------------------------------------------- */ int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[]/*out*/, - hsize_t maxdims[]/*out*/) + hsize_t maxdims[]/*out*/) { - H5S_t *ds; - int ret_value; + H5S_t *ds; + int ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("Is", "ixx", space_id, dims, maxdims); /* Check args */ - if (NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") ret_value = H5S_get_simple_extent_dims(ds, dims, maxdims); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Sget_simple_extent_dims() */ /*------------------------------------------------------------------------- @@ -1081,14 +1033,11 @@ done: * function may not be meaningful for all types of dataspaces. * * Return: Success: Number of dimensions. Zero implies scalar. - * * Failure: Negative * * Programmer: Robb Matzke * Thursday, December 11, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ int @@ -1155,13 +1104,6 @@ done: * Programmer: Quincey Koziol * Tuesday, December 31, 2002 * - * Modifications: - * - * John Mainzer, 6/6/05 - * Updated function to use the new dirtied parameter of - * H5AC_unprotect() instead of manipulating the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ herr_t @@ -1191,7 +1133,6 @@ done: * Purpose: Reads the dataspace from an object header. * * Return: Success: Pointer to a new dataspace. - * * Failure: NULL * * Programmer: Robb Matzke @@ -1224,10 +1165,9 @@ H5S_read(const H5O_loc_t *loc) ret_value = ds; done: - if(ret_value == NULL) { + if(ret_value == NULL) if(ds != NULL) ds = H5FL_FREE(H5S_t, ds); - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_read() */ @@ -1235,11 +1175,11 @@ done: /*-------------------------------------------------------------------------- NAME - H5S_is_simple + H5S__is_simple PURPOSE Check if a dataspace is simple (internal) USAGE - htri_t H5S_is_simple(sdim) + htri_t H5S__is_simple(sdim) H5S_t *sdim; IN: Pointer to dataspace object to query RETURNS TRUE/FALSE/FAIL @@ -1248,21 +1188,21 @@ done: has orthogonal, evenly spaced dimensions. --------------------------------------------------------------------------*/ static htri_t -H5S_is_simple(const H5S_t *sdim) +H5S__is_simple(const H5S_t *sdim) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args and all the boring stuff. */ HDassert(sdim); /* H5S_NULL shouldn't be simple dataspace */ ret_value = (H5S_GET_EXTENT_TYPE(sdim) == H5S_SIMPLE || - H5S_GET_EXTENT_TYPE(sdim) == H5S_SCALAR) ? TRUE : FALSE; + H5S_GET_EXTENT_TYPE(sdim) == H5S_SCALAR) ? TRUE : FALSE; FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_is_simple() */ +} /* end H5S__is_simple() */ /*-------------------------------------------------------------------------- @@ -1282,21 +1222,21 @@ H5S_is_simple(const H5S_t *sdim) htri_t H5Sis_simple(hid_t space_id) { - H5S_t *space; /* dataspace to modify */ - htri_t ret_value; + H5S_t *space; /* Dataspace to check */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("t", "i", space_id); /* Check args and all the boring stuff. */ - if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL) + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace") - ret_value = H5S_is_simple(space); + ret_value = H5S__is_simple(space); - done: +done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Sis_simple() */ /*-------------------------------------------------------------------------- @@ -1324,56 +1264,44 @@ H5Sis_simple(hid_t space_id) Currently, only the first dimension in the array (the slowest) may be unlimited in size. - MODIFICATION - A null dataspace cannot be created from simple space with this function. - - Christian Chilan 01/17/2007 - Verifies that each element of DIMS is not equal to H5S_UNLIMITED. - - Raymond Lu 03/30/2011 - We allow 0 dimension size for non-unlimited dimension starting from 1.8.7 - release. --------------------------------------------------------------------------*/ herr_t H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], - const hsize_t max[/*rank*/]) + const hsize_t max[/*rank*/]) { - H5S_t *space; /* dataspace to modify */ - int u; /* local counting variable */ - herr_t ret_value=SUCCEED; /* Return value */ + H5S_t *space; /* Dataspace to modify */ + int u; /* Local counting variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iIs*[a1]h*[a1]h", space_id, rank, dims, max); /* Check args */ - if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL) + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace") - if (rank > 0 && dims == NULL) + if(rank > 0 && dims == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified") - if (rank<0 || rank>H5S_MAX_RANK) + if(rank < 0 || rank > H5S_MAX_RANK) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank") - if (dims) { - for (u=0; uextent) < 0) + if(H5S__extent_release(&space->extent) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "failed to release previous dataspace extent") if(rank == 0) { /* scalar variable */ @@ -1432,12 +1358,11 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, /* Copy the maximum dimensions if specified. Otherwise, the maximal dimensions are the * same as the dimension */ space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank); - if(max != NULL) { + if(max != NULL) HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank); - } else { + else for(u = 0; u < space->extent.rank; u++) space->extent.max[u] = dims[u]; - } } /* end else */ /* Selection related cleanup */ @@ -1453,7 +1378,7 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_set_extent_simple() */ +} /* end H5S_set_extent_simple() */ /*------------------------------------------------------------------------- @@ -1469,26 +1394,20 @@ done: * than the corresponding element of DIMS. * * Return: Success: The ID for the new simple dataspace object. - * * Failure: Negative * * Programmer: Quincey Koziol * Tuesday, January 27, 1998 * - * Modification: - * Raymond Lu 03/30/2011 - * We allow 0-dimension for non-unlimited dimension starting - * from 1.8.7 release. - * *------------------------------------------------------------------------- */ hid_t H5Screate_simple(int rank, const hsize_t dims[/*rank*/], - const hsize_t maxdims[/*rank*/]) + const hsize_t maxdims[/*rank*/]) { H5S_t *space = NULL; int i; - hid_t ret_value; + hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "Is*[a0]h*[a0]h", rank, dims, maxdims); @@ -1514,7 +1433,7 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/], } /* end for */ /* Create the space and set the extent */ - if(NULL == (space = H5S_create_simple((unsigned)rank,dims,maxdims))) + if(NULL == (space = H5S_create_simple((unsigned)rank, dims, maxdims))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") /* Atomize */ @@ -1522,10 +1441,9 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/], HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") done: - if(ret_value < 0) { + if(ret_value < 0) if(space && H5S_close(space) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") - } /* end if */ FUNC_LEAVE_API(ret_value) } /* end H5Screate_simple() */ @@ -1539,32 +1457,26 @@ done: * Return: Success: The ID for the new simple dataspace object. * Failure: Negative * - * Errors: - * * Programmer: Quincey Koziol * Thursday, April 3, 2003 * - * Modifications: - * Extracted from H5Screate_simple - * Quincey Koziol, Thursday, April 3, 2003 - * *------------------------------------------------------------------------- */ H5S_t * H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], - const hsize_t maxdims[/*rank*/]) + const hsize_t maxdims[/*rank*/]) { H5S_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) /* Check arguments */ - HDassert(rank <=H5S_MAX_RANK); + HDassert(rank <= H5S_MAX_RANK); /* Create the space and set the extent */ - if(NULL==(ret_value=H5S_create(H5S_SIMPLE))) + if(NULL == (ret_value = H5S_create(H5S_SIMPLE))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace") - if(H5S_set_extent_simple(ret_value,rank,dims,maxdims)<0) + if(H5S_set_extent_simple(ret_value, rank, dims, maxdims) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "can't set dimensions") done: @@ -1579,15 +1491,12 @@ done: * (including selection) into binary in a buffer. * * Return: Success: non-negative - * * Failure: negative * * Programmer: Raymond Lu * slu@ncsa.uiuc.edu * July 14, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -1600,15 +1509,15 @@ H5Sencode(hid_t obj_id, void *buf, size_t *nalloc) H5TRACE3("e", "i*x*z", obj_id, buf, nalloc); /* Check argument and retrieve object */ - if (NULL == (dspace = (H5S_t *)H5I_object_verify(obj_id, H5I_DATASPACE))) + if(NULL == (dspace = (H5S_t *)H5I_object_verify(obj_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(H5S_encode(dspace, (unsigned char **)&buf, nalloc)<0) + if(H5S_encode(dspace, (unsigned char **)&buf, nalloc) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode dataspace") done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Sencode() */ /*------------------------------------------------------------------------- @@ -1697,7 +1606,6 @@ done: * return a new object handle. * * Return: Success: dataspace ID(non-negative) - * * Failure: negative * * Programmer: Raymond Lu @@ -1737,7 +1645,6 @@ done: * description of dataspace and returns a new object handle. * * Return: Success: dataspace ID(non-negative) - * * Failure: negative * * Programmer: Raymond Lu @@ -1784,11 +1691,11 @@ H5S_decode(const unsigned char **p) pp += extent_size; /* Copy the extent into dataspace structure */ - if((ds = H5FL_CALLOC(H5S_t))==NULL) + if(NULL == (ds = H5FL_CALLOC(H5S_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for dataspace conversion path table") - if(H5O_msg_copy(H5O_SDSPACE_ID, extent, &(ds->extent)) == NULL) + if(NULL == H5O_msg_copy(H5O_SDSPACE_ID, extent, &(ds->extent))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy object") - if(H5S_extent_release(extent) < 0) + if(H5S__extent_release(extent) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, NULL, "can't release previous dataspace") extent = H5FL_FREE(H5S_extent_t, extent); @@ -1819,11 +1726,8 @@ done: * Purpose: Internal function for retrieving the type of extent for a dataspace object * * Return: Success: The class of the dataspace object - * * Failure: N5S_NO_CLASS * - * Errors: - * * Programmer: Quincey Koziol * Thursday, September 28, 2000 * @@ -1831,8 +1735,6 @@ done: * pattern, don't call it directly, use the appropriate macro * defined in H5Sprivate.h. * - * Modifications: - * *------------------------------------------------------------------------- */ H5S_class_t @@ -1844,11 +1746,11 @@ H5S_get_simple_extent_type(const H5S_t *space) HDassert(space); - ret_value=H5S_GET_EXTENT_TYPE(space); + ret_value = H5S_GET_EXTENT_TYPE(space); done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5S_get_simple_extent_type() */ /*------------------------------------------------------------------------- @@ -1857,36 +1759,31 @@ done: * Purpose: Retrieves the type of extent for a dataspace object * * Return: Success: The class of the dataspace object - * * Failure: N5S_NO_CLASS * - * Errors: - * * Programmer: Quincey Koziol * Thursday, July 23, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ H5S_class_t H5Sget_simple_extent_type(hid_t sid) { H5S_t *space; - H5S_class_t ret_value; + H5S_class_t ret_value; /* Return value */ FUNC_ENTER_API(H5S_NO_CLASS) H5TRACE1("Sc", "i", sid); /* Check arguments */ - if (NULL == (space = (H5S_t *)H5I_object_verify(sid, H5I_DATASPACE))) + if(NULL == (space = (H5S_t *)H5I_object_verify(sid, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5S_NO_CLASS, "not a dataspace") - ret_value=H5S_GET_EXTENT_TYPE(space); + ret_value = H5S_GET_EXTENT_TYPE(space); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Sget_simple_extent_type() */ /*-------------------------------------------------------------------------- @@ -1906,68 +1803,25 @@ done: herr_t H5Sset_extent_none(hid_t space_id) { - H5S_t *space; /* dataspace to modify */ - herr_t ret_value=SUCCEED; /* Return value */ + H5S_t *space; /* Dataspace to modify */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", space_id); /* Check args */ - if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace") /* Clear the previous extent from the dataspace */ - if(H5S_extent_release(&space->extent)<0) + if(H5S__extent_release(&space->extent) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, FAIL, "can't release previous dataspace") - space->extent.type=H5S_NO_CLASS; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sset_extent_none() */ - - -/*-------------------------------------------------------------------------- - NAME - H5Soffset_simple - PURPOSE - Changes the offset of a selection within a simple dataspace extent - USAGE - herr_t H5Soffset_simple(space_id, offset) - hid_t space_id; IN: Dataspace object to reset - const hssize_t *offset; IN: Offset to position the selection at - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - This function creates an offset for the selection within an extent, allowing - the same shaped selection to be moved to different locations within a - dataspace without requiring it to be re-defined. ---------------------------------------------------------------------------*/ -herr_t -H5Soffset_simple(hid_t space_id, const hssize_t *offset) -{ - H5S_t *space; /* dataspace to modify */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*Hs", space_id, offset); - - /* Check args */ - if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace") - if (space->extent.rank==0 || (H5S_GET_EXTENT_TYPE(space)==H5S_SCALAR - || H5S_GET_EXTENT_TYPE(space)==H5S_NULL)) - HGOTO_ERROR(H5E_ATOM, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace") - if (offset == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no offset specified") - - /* Set the selection offset */ - if(H5S_select_offset(space,offset)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset") + space->extent.type = H5S_NO_CLASS; done: FUNC_LEAVE_API(ret_value) -} /* end H5Soffset_simple() */ +} /* end H5Sset_extent_none() */ /*------------------------------------------------------------------------- @@ -1996,7 +1850,7 @@ H5S_set_extent(H5S_t *space, const hsize_t *size) HDassert(size); /* Verify that the dimensions being changed are allowed to change */ - for(u = 0; u < space->extent.rank; u++) { + for(u = 0; u < space->extent.rank; u++) if(space->extent.size[u] != size[u]) { /* Check for invalid dimension size modification */ if(space->extent.max && H5S_UNLIMITED != space->extent.max[u] && @@ -2006,7 +1860,6 @@ H5S_set_extent(H5S_t *space, const hsize_t *size) /* Indicate that dimension size can be modified */ ret_value = TRUE; } /* end if */ - } /* end for */ /* Update dimension size(s) */ if(ret_value) @@ -2033,7 +1886,7 @@ done: * *------------------------------------------------------------------------- */ -hbool_t +H5_ATTR_PURE hbool_t H5S_has_extent(const H5S_t *ds) { hbool_t ret_value = FALSE; /* Return value */ @@ -2104,7 +1957,6 @@ done: * Purpose: Determines if two dataspace extents are equal. * * Return: Success: TRUE if equal, FALSE if unequal - * * Failure: Negative * * Programmer: Quincey Koziol @@ -2116,7 +1968,7 @@ htri_t H5Sextent_equal(hid_t space1_id, hid_t space2_id) { const H5S_t *ds1, *ds2; /* Dataspaces to compare */ - htri_t ret_value; + htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("t", "ii", space1_id, space2_id); @@ -2148,7 +2000,7 @@ done: DESCRIPTION Compare two dataspaces if their extents are identical. --------------------------------------------------------------------------*/ -htri_t +H5_ATTR_PURE htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2) { unsigned u; /* Local index variable */ @@ -2209,7 +2061,7 @@ done: * *------------------------------------------------------------------------- */ -hsize_t +H5_ATTR_PURE hsize_t H5S_extent_nelem(const H5S_extent_t *ext) { FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -2257,6 +2109,5 @@ H5S_set_version(H5F_t *f, H5S_t *ds) done: FUNC_LEAVE_NOAPI(ret_value) - } /* end H5S_set_version() */ diff --git a/src/H5Sall.c b/src/H5Sall.c index 3b77b98..76181d1 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -18,16 +18,36 @@ * Purpose: "All" selection dataspace I/O functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* ID Functions */ #include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5VMprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + -/* Static function prototypes */ +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ /* Selection callbacks */ static herr_t H5S__all_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); @@ -60,6 +80,16 @@ static herr_t H5S__all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); static herr_t H5S__all_iter_next_block(H5S_sel_iter_t *sel_iter); static herr_t H5S__all_iter_release(H5S_sel_iter_t *sel_iter); + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + /* Selection properties for "all" selections */ const H5S_select_class_t H5S_sel_all[1] = {{ H5S_SEL_ALL, @@ -85,6 +115,11 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S__all_iter_init, }}; + +/*******************/ +/* Local Variables */ +/*******************/ + /* Iteration properties for "all" selections */ static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{ H5S_SEL_ALL, @@ -99,13 +134,14 @@ static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{ H5S__all_iter_release, }}; + /*------------------------------------------------------------------------- * Function: H5S__all_iter_init * * Purpose: Initializes iteration information for "all" selection. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 @@ -132,7 +168,7 @@ H5S__all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) iter->type = H5S_sel_iter_all; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_iter_init() */ +} /* end H5S__all_iter_init() */ /*------------------------------------------------------------------------- @@ -141,7 +177,7 @@ H5S__all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) * Purpose: Retrieve the current coordinates of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Tuesday, April 22, 2003 @@ -165,7 +201,7 @@ H5S__all_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S__all_iter_coords() */ +} /* end H5S__all_iter_coords() */ /*------------------------------------------------------------------------- @@ -174,7 +210,7 @@ done: * Purpose: Retrieve the current block of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Monday, June 2, 2003 @@ -204,7 +240,7 @@ H5S__all_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) } /* end for */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_iter_block() */ +} /* end H5S__all_iter_block() */ /*------------------------------------------------------------------------- @@ -212,7 +248,7 @@ H5S__all_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) * * Purpose: Return number of elements left to process in iterator * - * Return: non-negative number of elements on success, zero on failure + * Return: Non-negative number of elements on success, zero on failure * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 @@ -228,7 +264,7 @@ H5S__all_iter_nelmts(const H5S_sel_iter_t *iter) HDassert(iter); FUNC_LEAVE_NOAPI(iter->elmt_left) -} /* H5S__all_iter_nelmts() */ +} /* end H5S__all_iter_nelmts() */ /*-------------------------------------------------------------------------- @@ -257,7 +293,7 @@ H5S__all_iter_has_next_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) HDassert(iter); FUNC_LEAVE_NOAPI(FALSE) -} /* H5S__all_iter_has_next_block() */ +} /* end H5S__all_iter_has_next_block() */ /*-------------------------------------------------------------------------- @@ -292,7 +328,7 @@ H5S__all_iter_next(H5S_sel_iter_t *iter, size_t nelem) iter->u.all.byte_offset += (nelem * iter->elmt_size); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_iter_next() */ +} /* end H5S__all_iter_next() */ /*-------------------------------------------------------------------------- @@ -321,7 +357,7 @@ H5S__all_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) HDassert(iter); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S__all_iter_next_block() */ +} /* end H5S__all_iter_next_block() */ /*-------------------------------------------------------------------------- @@ -350,7 +386,7 @@ H5S__all_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED * iter) HDassert(iter); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_iter_release() */ +} /* end H5S__all_iter_release() */ /*-------------------------------------------------------------------------- @@ -382,7 +418,7 @@ H5S__all_release(H5S_t *space) space->select.num_elem = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_release() */ +} /* end H5S__all_release() */ /*-------------------------------------------------------------------------- @@ -391,9 +427,10 @@ H5S__all_release(H5S_t *space) PURPOSE Copy a selection from one dataspace to another USAGE - herr_t H5S__all_copy(dst, src) + herr_t H5S__all_copy(dst, src, share_selection) H5S_t *dst; OUT: Pointer to the destination dataspace H5S_t *src; IN: Pointer to the source dataspace + hbool_t; IN: Whether to share the selection between the dataspaces RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -527,7 +564,7 @@ H5S__all_serialize(const H5S_t *space, uint8_t **p) *p = pp; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_serialize() */ +} /* end H5S__all_serialize() */ /*-------------------------------------------------------------------------- @@ -572,7 +609,7 @@ H5S__all_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_A done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S__all_deserialize() */ +} /* end H5S__all_deserialize() */ /*-------------------------------------------------------------------------- @@ -622,7 +659,7 @@ H5S__all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) } /* end for */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_bounds() */ +} /* end H5S__all_bounds() */ /*-------------------------------------------------------------------------- @@ -657,7 +694,7 @@ H5S__all_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset) *offset = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_offset() */ +} /* end H5S__all_offset() */ /*-------------------------------------------------------------------------- @@ -716,7 +753,7 @@ H5S__all_is_contiguous(const H5S_t H5_ATTR_UNUSED *space) HDassert(space); FUNC_LEAVE_NOAPI(TRUE) -} /* H5S__all_is_contiguous() */ +} /* end H5S__all_is_contiguous() */ /*-------------------------------------------------------------------------- @@ -745,7 +782,7 @@ H5S__all_is_single(const H5S_t H5_ATTR_UNUSED *space) HDassert(space); FUNC_LEAVE_NOAPI(TRUE) -} /* H5S__all_is_single() */ +} /* end H5S__all_is_single() */ /*-------------------------------------------------------------------------- @@ -776,7 +813,7 @@ H5S__all_is_regular(const H5S_t H5_ATTR_UNUSED *space) HDassert(space); FUNC_LEAVE_NOAPI(TRUE) -} /* H5S__all_is_regular() */ +} /* end H5S__all_is_regular() */ /*-------------------------------------------------------------------------- @@ -807,7 +844,7 @@ H5S__all_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *off HDassert(offset); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_adjust_u() */ +} /* end H5S__all_adjust_u() */ /*------------------------------------------------------------------------- @@ -816,7 +853,7 @@ H5S__all_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *off * Purpose: Projects a single element 'all' selection into a scalar * dataspace * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -836,7 +873,7 @@ H5S__all_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset) *offset = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__all_project_scalar() */ +} /* end H5S__all_project_scalar() */ /*------------------------------------------------------------------------- @@ -845,7 +882,7 @@ H5S__all_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset) * Purpose: Projects an 'all' selection onto/into a simple dataspace * of a different rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -853,7 +890,8 @@ H5S__all_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset) *------------------------------------------------------------------------- */ static herr_t -H5S__all_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset) +H5S__all_project_simple(const H5S_t H5_ATTR_UNUSED *base_space, + H5S_t *new_space, hsize_t H5_ATTR_UNUSED *offset) { herr_t ret_value = SUCCEED; /* Return value */ @@ -870,7 +908,7 @@ H5S__all_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offs done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S__all_project_simple() */ +} /* end H5S__all_project_simple() */ /*-------------------------------------------------------------------------- @@ -914,7 +952,7 @@ H5S_select_all(H5S_t *space, hbool_t rel_prev) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_all() */ +} /* end H5S_select_all() */ /*-------------------------------------------------------------------------- @@ -953,7 +991,7 @@ H5Sselect_all(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sselect_all() */ +} /* end H5Sselect_all() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Sdbg.c b/src/H5Sdbg.c index ebd05ce..b13e921 100644 --- a/src/H5Sdbg.c +++ b/src/H5Sdbg.c @@ -57,16 +57,16 @@ /********************/ -/*********************/ -/* Package Variables */ -/*********************/ - - /*****************************/ /* Library Private Variables */ /*****************************/ +/*********************/ +/* Package Variables */ +/*********************/ + + /*******************/ /* Local Variables */ /*******************/ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 88c570d..e9354ca 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -18,21 +18,37 @@ * Purpose: Hyperslab selection dataspace I/O functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* ID Functions */ #include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5VMprivate.h" /* Vector functions */ + +/****************/ /* Local Macros */ +/****************/ + -/* Local datatypes */ +/******************/ +/* Local Typedefs */ +/******************/ -/* Static function prototypes */ + +/********************/ +/* Local Prototypes */ +/********************/ static H5S_hyper_span_t *H5S__hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next); static herr_t H5S__hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size); @@ -64,7 +80,6 @@ static herr_t H5S__hyper_generate_spans(H5S_t *space); static herr_t H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]); -/* Needed for use in hyperslab code (H5Shyper.c) */ #ifdef NEW_HYPERSLAB_API static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); #endif /*NEW_HYPERSLAB_API*/ @@ -111,6 +126,15 @@ static hbool_t H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab_info[], unsigned rank); static hbool_t H5S__hyper_rebuild(H5S_t *space); +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + /* Selection properties for hyperslab selections */ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S_SEL_HYPERSLABS, @@ -136,6 +160,11 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S__hyper_iter_init, }}; + +/*******************/ +/* Local Variables */ +/*******************/ + /* Iteration properties for hyperslab selections */ static const H5S_sel_iter_class_t H5S_sel_iter_hyper[1] = {{ H5S_SEL_HYPERSLABS, @@ -153,16 +182,16 @@ static const H5S_sel_iter_class_t H5S_sel_iter_hyper[1] = {{ /* Static variables */ /* Arrays for default stride, block, etc. */ -static const hsize_t H5S_hyper_zeros_g[H5O_LAYOUT_NDIMS] = { +static const hsize_t H5S_hyper_zeros_g[H5S_MAX_RANK] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, - 0,0,0,0, 0,0,0,0,0}; -static const hsize_t H5S_hyper_ones_g[H5O_LAYOUT_NDIMS] = { + 0,0,0,0, 0,0,0,0}; +static const hsize_t H5S_hyper_ones_g[H5S_MAX_RANK] = { 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, - 1,1,1,1, 1,1,1,1,1}; + 1,1,1,1, 1,1,1,1}; /* Declare a free list to manage the H5S_hyper_sel_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_sel_t); @@ -261,9 +290,9 @@ H5S__hyper_print_diminfo(FILE *f, const H5S_t *space) /*------------------------------------------------------------------------- * Function: H5S__hyper_iter_init * - * Purpose: Initializes iteration information for hyperslab span tree selection. + * Purpose: Initializes iteration information for hyperslab selection. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Saturday, February 24, 2001 @@ -334,7 +363,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Check if the regular selection can be "flattened" */ if(cont_dim > 0) { hsize_t acc; /* Accumulator for "flattened" dimension's sizes */ - unsigned last_dim_flattened = 1; /* Flag to indicate that the last dimension was flattened */ + hbool_t last_dim_flattened = TRUE; /* Flag to indicate that the last dimension was flattened */ unsigned flat_rank = rank-cont_dim; /* Number of dimensions after flattening */ unsigned curr_dim; /* Current dimension */ int i; /* Index variable */ @@ -351,7 +380,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) acc *= mem_size[i]; /* Indicate that the dimension was flattened */ - last_dim_flattened = 1; + last_dim_flattened = TRUE; } /* end if */ else { if(last_dim_flattened) { @@ -369,7 +398,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) iter->u.hyp.sel_off[curr_dim] = space->select.offset[i] * (hssize_t)acc; /* Reset the "last dim flattened" flag to avoid flattened any further dimensions */ - last_dim_flattened = 0; + last_dim_flattened = FALSE; /* Reset the "accumulator" for possible further dimension flattening */ acc = 1; @@ -414,10 +443,9 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Initialize irregular region information also (for release) */ iter->u.hyp.spans = NULL; } /* end if */ - else { + else { /* Initialize the information needed for non-regular hyperslab I/O */ H5S_hyper_span_info_t *spans; /* Pointer to hyperslab span info node */ -/* Initialize the information needed for non-regular hyperslab I/O */ HDassert(space->select.sel_info.hslab->span_lst); /* Make a copy of the span tree to iterate over */ iter->u.hyp.spans = H5S__hyper_copy_span(space->select.sel_info.hslab->span_lst); @@ -459,7 +487,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) * Purpose: Retrieve the current coordinates of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Tuesday, April 22, 2003 @@ -544,7 +572,7 @@ H5S__hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords) * Purpose: Retrieve the current block of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Monday, June 2, 2003 @@ -570,7 +598,7 @@ H5S__hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) /* Check for a single "regular" hyperslab */ if(iter->u.hyp.diminfo_valid) { - /* Compute the end of the block */ + /* Copy the start and compute the end of the block */ for(u = 0; u < iter->rank; u++) { start[u] = iter->u.hyp.off[u]; end[u] = (start[u] + iter->u.hyp.diminfo[u].block) - 1; @@ -595,7 +623,7 @@ H5S__hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) * * Purpose: Return number of elements left to process in iterator * - * Return: non-negative number of elements on success, zero on failure + * Return: Non-negative number of elements on success, zero on failure * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 @@ -631,7 +659,7 @@ H5S__hyper_iter_nelmts(const H5S_sel_iter_t *iter) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static htri_t +static H5_ATTR_PURE htri_t H5S__hyper_iter_has_next_block(const H5S_sel_iter_t *iter) { unsigned u; /* Local index variable */ @@ -689,7 +717,7 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) { unsigned ndims; /* Number of dimensions of dataset */ int fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - unsigned i; /* Counters */ + unsigned u; /* Counters */ FUNC_ENTER_STATIC_NOERR @@ -697,19 +725,17 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) /* (i.e. a regular hyperslab selection */ if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ - hsize_t iter_offset[H5O_LAYOUT_NDIMS]; - hsize_t iter_count[H5O_LAYOUT_NDIMS]; + hsize_t iter_offset[H5S_MAX_RANK]; + hsize_t iter_count[H5S_MAX_RANK]; int temp_dim; /* Temporary rank holder */ /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) { + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) /* Set the aliases for the dimension rank */ ndims = iter->u.hyp.iter_rank; - } /* end if */ - else { + else /* Set the aliases for the dimension rank */ ndims = iter->rank; - } /* end else */ /* Set the fastest dimension rank */ fast_dim = (int)ndims - 1; @@ -718,14 +744,14 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) tdiminfo = iter->u.hyp.diminfo; /* Calculate the offset and block count for each dimension */ - for(i = 0; i < ndims; i++) { - if(tdiminfo[i].count == 1) { - iter_offset[i] = iter->u.hyp.off[i] - tdiminfo[i].start; - iter_count[i] = 0; + for(u = 0; u < ndims; u++) { + if(tdiminfo[u].count == 1) { + iter_offset[u] = iter->u.hyp.off[u] - tdiminfo[u].start; + iter_count[u] = 0; } /* end if */ else { - iter_offset[i] = (iter->u.hyp.off[i] - tdiminfo[i].start) % tdiminfo[i].stride; - iter_count[i] = (iter->u.hyp.off[i] - tdiminfo[i].start) / tdiminfo[i].stride; + iter_offset[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) % tdiminfo[u].stride; + iter_count[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) / tdiminfo[u].stride; } /* end else */ } /* end for */ @@ -750,10 +776,9 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) /* Decrement the number of elements advanced */ nelem -= actual_elem; } /* end if */ - else { + else /* Move to the next row in the current dimension */ iter_offset[temp_dim]++; - } /* end else */ /* If this block is still in the range of blocks to output for the dimension, break out of loop */ if(iter_offset[temp_dim] < tdiminfo[temp_dim].block) @@ -776,8 +801,8 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) } /* end while */ /* Translate current iter_offset and iter_count into iterator position */ - for(i = 0; i < ndims; i++) - iter->u.hyp.off[i] = tdiminfo[i].start + (tdiminfo[i].stride * iter_count[i]) + iter_offset[i]; + for(u = 0; u < ndims; u++) + iter->u.hyp.off[u] = tdiminfo[u].start + (tdiminfo[u].stride * iter_count[u]) + iter_offset[u]; } /* end if */ /* Must be an irregular hyperslab selection */ else { @@ -821,15 +846,13 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) /* Decrement the number of elements advanced */ nelem -= actual_elem; } /* end if */ - else { + else /* Move to the next row in the current dimension */ abs_arr[curr_dim]++; - } /* end else */ /* Check if we are still within the span */ - if(abs_arr[curr_dim] <= curr_span->high) { + if(abs_arr[curr_dim] <= curr_span->high) break; - } /* end if */ /* If we walked off that span, advance to the next span */ else { /* Advance span in this dimension */ @@ -845,10 +868,9 @@ H5S__hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) break; } /* end if */ - else { + else /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ curr_dim--; - } /* end else */ } /* end else */ } /* end while */ @@ -907,22 +929,20 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) FUNC_ENTER_STATIC_NOERR /* Check for the special case of just one H5Sselect_hyperslab call made */ - /* (i.e. a regular hyperslab selection */ + /* (i.e. a regular hyperslab selection) */ if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ - hsize_t iter_offset[H5O_LAYOUT_NDIMS]; - hsize_t iter_count[H5O_LAYOUT_NDIMS]; + hsize_t iter_offset[H5S_MAX_RANK]; + hsize_t iter_count[H5S_MAX_RANK]; int temp_dim; /* Temporary rank holder */ /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) { + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) /* Set the aliases for the dimension rank */ ndims = iter->u.hyp.iter_rank; - } /* end if */ - else { + else /* Set the aliases for the dimension rank */ ndims = iter->rank; - } /* end else */ /* Set the fastest dimension rank */ fast_dim = (int)ndims - 1; @@ -945,14 +965,12 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) /* Advance one block */ temp_dim = fast_dim; /* Start with the fastest changing dimension */ while(temp_dim >= 0) { - if(temp_dim == fast_dim) { + if(temp_dim == fast_dim) /* Move iterator over current block */ iter_offset[temp_dim] += tdiminfo[temp_dim].block; - } /* end if */ - else { + else /* Move to the next row in the current dimension */ iter_offset[temp_dim]++; - } /* end else */ /* If this block is still in the range of blocks to output for the dimension, break out of loop */ if(iter_offset[temp_dim] < tdiminfo[temp_dim].block) @@ -1001,19 +1019,16 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) curr_span = ispan[curr_dim]; /* Increment absolute position */ - if(curr_dim == fast_dim) { + if(curr_dim == fast_dim) /* Move the iterator over rest of element in span */ abs_arr[curr_dim] = curr_span->high + 1; - } /* end if */ - else { + else /* Move to the next row in the current dimension */ abs_arr[curr_dim]++; - } /* end else */ /* Check if we are still within the span */ - if(abs_arr[curr_dim] <= curr_span->high) { + if(abs_arr[curr_dim] <= curr_span->high) break; - } /* end if */ /* If we walked off that span, advance to the next span */ else { /* Advance span in this dimension */ @@ -1029,10 +1044,9 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) break; } /* end if */ - else { + else /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ curr_dim--; - } /* end else */ } /* end else */ } /* end while */ @@ -1063,7 +1077,7 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) } /* end else */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_iter_next() */ +} /* end H5S__hyper_iter_next_block() */ /*-------------------------------------------------------------------------- @@ -1404,6 +1418,7 @@ H5S__hyper_copy_span(H5S_hyper_span_info_t *spans) FUNC_ENTER_STATIC + /* Sanity check */ HDassert(spans); /* Copy the hyperslab span tree */ @@ -1422,23 +1437,24 @@ done: NAME H5S__hyper_cmp_spans PURPOSE - Check if two hyperslab slabs are the same + Check if two hyperslab span trees are the same USAGE hbool_t H5S__hyper_cmp_spans(span1, span2) - H5S_hyper_span_t *span1; IN: First span tree to compare - H5S_hyper_span_t *span2; IN: Second span tree to compare + H5S_hyper_span_info_t *span_info1; IN: First span tree to compare + H5S_hyper_span_info_t *span_info2; IN: Second span tree to compare RETURNS TRUE (1) or FALSE (0) on success, can't fail DESCRIPTION - Compare two hyperslab slabs to determine if they refer to the same - selection. If span1 & span2 are both NULL, that counts as equal + Compare two hyperslab span trees to determine if they refer to the same + selection. If span1 & span2 are both NULL, that counts as equal. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_span_info_t *span_info2) +static H5_ATTR_PURE hbool_t +H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, + const H5S_hyper_span_info_t *span_info2) { hbool_t ret_value = FALSE; /* Return value */ @@ -1610,9 +1626,10 @@ done: PURPOSE Copy a selection from one dataspace to another USAGE - herr_t H5S__hyper_copy(dst, src) + herr_t H5S__hyper_copy(dst, src, share_selection) H5S_t *dst; OUT: Pointer to the destination dataspace H5S_t *src; IN: Pointer to the source dataspace + hbool_t; IN: Whether to share the selection between the dataspaces RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -2045,7 +2062,7 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, HDassert(spans); HDassert(start); HDassert(end); - HDassert(rank < H5O_LAYOUT_NDIMS); + HDassert(rank < H5S_MAX_RANK); HDassert(p && pp); /* Walk through the list of spans, recursing or outputting them */ @@ -2088,7 +2105,7 @@ H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, *p = pp; FUNC_LEAVE_NOAPI_VOID -} /* H5S__hyper_serialize_helper() */ +} /* end H5S__hyper_serialize_helper() */ /*-------------------------------------------------------------------------- @@ -2170,8 +2187,8 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p) /* Check for a "regular" hyperslab selection */ else if(space->select.sel_info.hslab->diminfo_valid) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ - hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ + hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Rank of the dataspace */ unsigned u; /* Local counting variable */ @@ -2261,8 +2278,8 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p) } /* end while */ } /* end if */ else { - hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ - hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */ + hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ + hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ /* Encode number of hyperslabs */ block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); @@ -2318,8 +2335,8 @@ H5S__hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t fl { unsigned rank; /* Rank of points */ const uint8_t *pp; /* Local pointer for decoding */ - hsize_t start[H5O_LAYOUT_NDIMS]; /* Hyperslab start information */ - hsize_t block[H5O_LAYOUT_NDIMS]; /* Hyperslab block information */ + hsize_t start[H5S_MAX_RANK]; /* Hyperslab start information */ + hsize_t block[H5S_MAX_RANK]; /* Hyperslab block information */ unsigned u; /* Local counting variable */ herr_t ret_value = FAIL; /* Return value */ @@ -2337,8 +2354,8 @@ H5S__hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t fl /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ if(flags & H5S_SELECT_FLAG_UNLIM) { - hsize_t stride[H5O_LAYOUT_NDIMS]; /* Hyperslab stride information */ - hsize_t count[H5O_LAYOUT_NDIMS]; /* Hyperslab count information */ + hsize_t stride[H5S_MAX_RANK]; /* Hyperslab stride information */ + hsize_t count[H5S_MAX_RANK]; /* Hyperslab count information */ /* Sanity checks */ HDassert(H5S_UNLIMITED == HSIZE_UNDEF); @@ -2360,7 +2377,7 @@ H5S__hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t fl else { const hsize_t *stride; /* Hyperslab stride information */ const hsize_t *count; /* Hyperslab count information */ - hsize_t end[H5O_LAYOUT_NDIMS]; /* Hyperslab end information */ + hsize_t end[H5S_MAX_RANK]; /* Hyperslab end information */ hsize_t *tstart; /* Temporary hyperslab pointers */ hsize_t *tend; /* Temporary hyperslab pointers */ hsize_t *tblock; /* Temporary hyperslab pointers */ @@ -2447,7 +2464,7 @@ H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], /* Sanity checks */ HDassert(spans); - HDassert(rank < H5O_LAYOUT_NDIMS); + HDassert(rank < H5S_MAX_RANK); HDassert(start); HDassert(end); HDassert(startblock); @@ -2551,8 +2568,8 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo /* Check for a "regular" hyperslab selection */ if(space->select.sel_info.hslab->diminfo_valid) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ - hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ + hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Rank of the dataspace */ hbool_t done; /* Whether we are done with the iteration */ @@ -2662,8 +2679,8 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo } /* end while */ } /* end if */ else { - hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ - hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */ + hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ + hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ ret_value = H5S__hyper_span_blocklist(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &startblock, &numblocks, &buf); } /* end else */ @@ -2771,7 +2788,7 @@ H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offs HDassert(spans); HDassert(offset); - HDassert(rank < H5O_LAYOUT_NDIMS); + HDassert(rank < H5S_MAX_RANK); HDassert(start); HDassert(end); @@ -3075,7 +3092,7 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static htri_t +static H5_ATTR_PURE htri_t H5S__hyper_is_contiguous(const H5S_t *space) { hbool_t small_contiguous, /* Flag for small contiguous block */ @@ -3145,10 +3162,10 @@ H5S__hyper_is_contiguous(const H5S_t *space) /* * For a hyperslab to be contiguous, it must have only one block and - * (either it's size must be the same as the dataspace extent's in all - * but the slowest changing dimension - * OR - * block size must be 1 in all but the fastest changing dimension). + * either it's size must be the same as the dataspace extent's in all + * but the slowest changing dimension + * OR + * block size must be 1 in all but the fastest changing dimension. */ /* Initialize flags */ large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */ @@ -3260,7 +3277,7 @@ H5S__hyper_is_contiguous(const H5S_t *space) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static htri_t +static H5_ATTR_PURE htri_t H5S__hyper_is_single(const H5S_t *space) { htri_t ret_value = TRUE; /* return value */ @@ -4242,7 +4259,7 @@ H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset) * Purpose: Projects a single element hyperslab selection into a scalar * dataspace * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -4305,7 +4322,7 @@ H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset) * Purpose: Projects a hyperslab selection onto/into a simple dataspace * of a lower rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -4352,7 +4369,7 @@ H5S__hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space) * Purpose: Projects a hyperslab selection onto/into a simple dataspace * of a higher rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -4442,7 +4459,7 @@ done: * Purpose: Projects a hyperslab selection onto/into a simple dataspace * of a different rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -4450,7 +4467,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset) +H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, + hsize_t *offset) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4939,9 +4957,10 @@ done: DESCRIPTION Clip one span tree ('a') against another span tree ('b'). Creates span trees for the area defined by the 'a' span tree which does not overlap the - 'b' span tree, the area defined by the overlap of the 'a' hyperslab span - tree and the 'b' span tree, and the area defined by the 'b' hyperslab span - tree which does not overlap the 'a' span tree. + 'b' span tree ("a not b"), the area defined by the overlap of the 'a' + hyperslab span tree and the 'b' span tree ("a and b"), and the area defined + by the 'b' hyperslab span tree which does not overlap the 'a' span + tree ("b not a"). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -5850,12 +5869,12 @@ H5S__hyper_spans_nelem(const H5S_hyper_span_info_t *spans) Create a span tree USAGE H5S_hyper_span_t *H5S__hyper_make_spans(rank, start, stride, count, block) - unsigned rank; IN: # of dimensions of the space - const hsize_t *start; IN: Starting location of the hyperslabs - const hsize_t *stride; IN: Stride from the beginning of one block to + unsigned rank; IN: # of dimensions of the space + const hsize_t *start; IN: Starting location of the hyperslabs + const hsize_t *stride; IN: Stride from the beginning of one block to the next - const hsize_t *count; IN: Number of blocks - const hsize_t *block; IN: Size of hyperslab block + const hsize_t *count; IN: Number of blocks + const hsize_t *block; IN: Size of hyperslab block RETURNS Pointer to new span tree on success, NULL on failure DESCRIPTION @@ -6139,7 +6158,7 @@ done: static hbool_t H5S__hyper_rebuild(H5S_t *space) { - H5S_hyper_dim_t top_span_slab_info[H5O_LAYOUT_NDIMS]; + H5S_hyper_dim_t top_span_slab_info[H5S_MAX_RANK]; unsigned rank, curr_dim; hbool_t ret_value = TRUE; /* Return value */ @@ -6201,12 +6220,12 @@ done: static herr_t H5S__hyper_generate_spans(H5S_t *space) { - hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */ - hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */ - hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */ - hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ + hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ + hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -6247,19 +6266,14 @@ done: * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol (split from HS_select_hyperslab()). + * Programmer: Quincey Koziol * Tuesday, September 12, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S__generate_hyperslab (H5S_t *space, H5S_seloper_t op, - const hsize_t start[], - const hsize_t stride[], - const hsize_t count[], - const hsize_t block[]) +H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], + const hsize_t stride[], const hsize_t count[], const hsize_t block[]) { H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ @@ -6291,7 +6305,7 @@ H5S__generate_hyperslab (H5S_t *space, H5S_seloper_t op, space->select.num_elem = H5S__hyper_spans_nelem(new_spans); /* Indicate that the new_spans are owned */ - new_spans=NULL; + new_spans = NULL; } /* end if */ else { hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */ @@ -6500,9 +6514,9 @@ herr_t H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t *stride, const hsize_t count[], const hsize_t *block) { - hsize_t int_stride[H5O_LAYOUT_NDIMS]; /* Internal storage for stride information */ - hsize_t int_count[H5O_LAYOUT_NDIMS]; /* Internal storage for count information */ - hsize_t int_block[H5O_LAYOUT_NDIMS]; /* Internal storage for block information */ + hsize_t int_stride[H5S_MAX_RANK]; /* Internal storage for stride information */ + hsize_t int_count[H5S_MAX_RANK]; /* Internal storage for count information */ + hsize_t int_block[H5S_MAX_RANK]; /* Internal storage for block information */ const hsize_t *opt_stride; /* Optimized stride information */ const hsize_t *opt_count; /* Optimized count information */ const hsize_t *opt_block; /* Optimized block information */ @@ -6526,9 +6540,7 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], if(block == NULL) block = H5S_hyper_ones_g; - /* - * Check new selection. - */ + /* Check new selection */ for(u = 0; u < space->extent.rank; u++) { /* Check for overlapping hyperslab blocks in new selection. */ if(count[u] > 1 && stride[u] < block[u]) @@ -6564,7 +6576,7 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], if(unlim_dim >= 0) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") else { - if(count[u] == block[u] /* == H5S_UNLIMITED */) + if(count[u] == block[u]) /* Both are H5S_UNLIMITED */ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") unlim_dim = (int)u; } /* end else */ @@ -6793,7 +6805,8 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") /* Patch count and block to remove unlimited and include the - * existing selection */ + * existing selection. + */ H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); HDassert((tmp_count == 1) || (opt_count != H5S_hyper_ones_g)); HDassert((tmp_block == 1) || (opt_block != H5S_hyper_ones_g)); @@ -7193,9 +7206,9 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hsize_t count[], const hsize_t *block) { - hsize_t int_stride[H5O_LAYOUT_NDIMS]; /* Internal storage for stride information */ - hsize_t int_count[H5O_LAYOUT_NDIMS]; /* Internal storage for count information */ - hsize_t int_block[H5O_LAYOUT_NDIMS]; /* Internal storage for block information */ + hsize_t int_stride[H5S_MAX_RANK]; /* Internal storage for stride information */ + hsize_t int_count[H5S_MAX_RANK]; /* Internal storage for count information */ + hsize_t int_block[H5S_MAX_RANK]; /* Internal storage for block information */ const hsize_t *opt_stride; /* Optimized stride information */ const hsize_t *opt_count; /* Optimized count information */ const hsize_t *opt_block; /* Optimized block information */ @@ -7212,11 +7225,11 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); /* Point to the correct stride values */ - if(stride==NULL) + if(stride == NULL) stride = H5S_hyper_ones_g; /* Point to the correct block values */ - if(block==NULL) + if(block == NULL) block = H5S_hyper_ones_g; /* Check for unlimited dimension */ @@ -7236,7 +7249,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, */ for(u=0; uextent.rank; u++) { /* Check for overlapping hyperslab blocks in new selection. */ - if(count[u]>1 && stride[u] 1 && stride[u] < block[u]) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap") /* Detect zero-sized hyperslabs in new selection */ @@ -7364,10 +7377,10 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Convert current "all" selection to "real" hyperslab selection */ /* Then allow operation to proceed */ { - hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */ - hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */ - hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */ - hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */ + hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ + hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ + hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ /* Fill in temporary information for the dimensions */ for(u=0; uextent.rank; u++) { @@ -7657,9 +7670,6 @@ done: * Programmer: Quincey Koziol * Tuesday, October 30, 2001 * - * Chao Mei - * Wednesday, June 29, 2011 - * *------------------------------------------------------------------------- */ static H5S_t * @@ -7789,8 +7799,6 @@ done: * Programmer: Quincey Koziol * Tuesday, October 30, 2001 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t @@ -7892,7 +7900,7 @@ H5Sselect_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces don't have hyperslab selections") /* Go refine the first selection */ - if (H5S_select_select(space1, op, space2)<0) + if(H5S_select_select(space1, op, space2) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to modify hyperslab selection") done: @@ -7938,7 +7946,7 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, { H5S_hyper_span_t *curr_span; /* Current hyperslab span node */ H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */ - hsize_t slab[H5O_LAYOUT_NDIMS]; /* Cumulative size of each dimension in bytes */ + hsize_t slab[H5S_MAX_RANK]; /* Cumulative size of each dimension in bytes */ hsize_t acc; /* Accumulator for computing cumulative sizes */ hsize_t loc_off; /* Element offset in the dataspace */ hsize_t last_span_end = 0; /* The offset of the end of the last span */ @@ -8358,13 +8366,13 @@ H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, hsize_t *off, size_t *len) { hsize_t *mem_size; /* Size of the source buffer */ - hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Coordinate offset in dataspace */ - hsize_t tmp_count[H5O_LAYOUT_NDIMS];/* Temporary block count */ - hsize_t tmp_block[H5O_LAYOUT_NDIMS];/* Temporary block offset */ - hsize_t wrap[H5O_LAYOUT_NDIMS]; /* Bytes to wrap around at the end of a row */ - hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ + hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ + hsize_t tmp_count[H5S_MAX_RANK];/* Temporary block count */ + hsize_t tmp_block[H5S_MAX_RANK];/* Temporary block offset */ + hsize_t wrap[H5S_MAX_RANK]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ hsize_t fast_dim_start, /* Local copies of fastest changing dimension info */ fast_dim_stride, @@ -8807,9 +8815,9 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ const hssize_t *sel_off; /* Selection offset in dataspace */ hsize_t *mem_size; /* Size of the source buffer */ - hsize_t base_offset[H5O_LAYOUT_NDIMS]; /* Base coordinate offset in dataspace */ - hsize_t offset[H5O_LAYOUT_NDIMS]; /* Coordinate offset in dataspace */ - hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hsize_t base_offset[H5S_MAX_RANK]; /* Base coordinate offset in dataspace */ + hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ hsize_t fast_dim_block; /* Local copies of fastest changing dimension info */ hsize_t acc; /* Accumulator */ hsize_t loc; /* Coordinate offset */ @@ -8949,8 +8957,8 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, offset[skip_dim] += tot_blk_count; } /* end if */ else { - hsize_t tmp_block[H5O_LAYOUT_NDIMS];/* Temporary block offset */ - hsize_t skip[H5O_LAYOUT_NDIMS]; /* Bytes to skip between blocks */ + hsize_t tmp_block[H5S_MAX_RANK];/* Temporary block offset */ + hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ int temp_dim; /* Temporary rank holder */ /* Set the starting block location */ @@ -9144,7 +9152,7 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s /* Check if we stopped in the middle of a sequence of elements */ if((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1)) { - hsize_t slab[H5O_LAYOUT_NDIMS]; /* Hyperslab size */ + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ hsize_t loc; /* Coordinate offset */ hsize_t acc; /* Accumulator */ size_t leftover; /* The number of elements left over from the last sequence */ @@ -9249,11 +9257,10 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s DESCRIPTION Projects the intersection of of the selections of src_space and src_intersect_space within the selection of src_space as a selection - within the selection of dst_space. The result is placed in the - selection of proj_space. Note src_space, dst_space, and - src_intersect_space do not need to use hyperslab selections, but they - cannot use point selections. The result is always a hyperslab - selection. + within the selection of dst_space. The result is placed in the selection + of proj_space. Note src_space, dst_space, and src_intersect_space do not + need to use hyperslab selections, but they cannot use point selections. + The result is always a hyperslab selection. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -9312,7 +9319,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HDassert(dst_space); HDassert(src_intersect_space); HDassert(proj_space); - + /* Assert that src_space and src_intersect_space have same extent and there * are no point selections */ HDassert(H5S_GET_EXTENT_NDIMS(src_space) == H5S_GET_EXTENT_NDIMS(src_intersect_space)); @@ -9475,7 +9482,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, * selection and advance any sequences we complete */ if(ss_off[ss_i] >= sis_off[sis_i]) int_sel_off = ss_sel_off; - else + else int_sel_off = sis_off[sis_i] - ss_off[ss_i] + ss_sel_off; if((ss_off[ss_i] + (hsize_t)ss_len[ss_i]) <= (sis_off[sis_i] + (hsize_t)sis_len[sis_i])) { @@ -9599,8 +9606,9 @@ loop_end: /* Set the number of elements in current selection */ proj_space->select.num_elem = H5S__hyper_spans_nelem(proj_space->select.sel_info.hslab->span_lst); - /* Attempt to rebuild "optimized" start/stride/count/block information. - * from resulting hyperslab span tree */ + /* Attempt to build "optimized" start/stride/count/block information + * from resulting hyperslab span tree. + */ H5S__hyper_rebuild(proj_space); } /* end if */ else @@ -9841,7 +9849,7 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) hsize_t orig_count; /* Original count in unlimited dimension */ int orig_unlim_dim; /* Original unliminted dimension */ H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -10225,7 +10233,7 @@ H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index) /* Create output space, copy extent */ if(NULL == (space_out = H5S_create(H5S_SIMPLE))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "unable to create output dataspace") - if(H5S_extent_copy_real(&space_out->extent, &space->extent, TRUE) < 0) + if(H5S__extent_copy_real(&space_out->extent, &space->extent, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "unable to copy destination space extent") /* Select block as defined by start/stride/count/block computed above */ @@ -10352,7 +10360,7 @@ H5Sis_regular_hyperslab(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sis_regular_hyperslab() */ +} /* end H5Sis_regular_hyperslab() */ /*-------------------------------------------------------------------------- @@ -10416,5 +10424,5 @@ H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[], hsize_t stride[], done: FUNC_LEAVE_API(ret_value) -} /* H5Sget_regular_hyperslab() */ +} /* end H5Sget_regular_hyperslab() */ diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 935d279..2ebe987 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -14,15 +14,20 @@ /* * Programmer: rky 980813 * - * Purpose: Functions to read/write directly between app buffer and file. + * Purpose: Create MPI data types for HDF5 selections. * - * Beware of the ifdef'ed print statements. - * I didn't make them portable. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ @@ -37,37 +42,61 @@ #ifdef H5_HAVE_PARALLEL -static herr_t H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, +/****************/ +/* Local Macros */ +/****************/ +#define H5S_MPIO_INITIAL_ALLOC_COUNT 256 +#define TWO_GIG_LIMIT 2147483648 +#ifndef H5S_MAX_MPI_COUNT +#define H5S_MAX_MPI_COUNT 536870911 /* (2^29)-1 */ +#endif + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5S__mpio_all_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S_mpio_none_type(MPI_Datatype *new_type, int *count, +static herr_t H5S__mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S_mpio_create_point_datatype(size_t elmt_size, hsize_t num_points, +static herr_t H5S__mpio_create_point_datatype(size_t elmt_size, hsize_t num_points, MPI_Aint *disp, MPI_Datatype *new_type); -static herr_t H5S_mpio_point_type(const H5S_t *space, size_t elmt_size, +static herr_t H5S__mpio_point_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, hbool_t do_permute, hsize_t **permute_map, hbool_t *is_permuted); -static herr_t H5S_mpio_permute_type(const H5S_t *space, size_t elmt_size, +static herr_t H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute_map, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, +static herr_t H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, +static herr_t H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S_obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span, +static herr_t H5S__obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span, const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size); -static herr_t H5S_mpio_create_large_type (hsize_t, MPI_Aint, MPI_Datatype , MPI_Datatype *); +static herr_t H5S__mpio_create_large_type(hsize_t, MPI_Aint, MPI_Datatype , MPI_Datatype *); -#define H5S_MPIO_INITIAL_ALLOC_COUNT 256 +/*****************************/ +/* Library Private Variables */ +/*****************************/ -#define TWO_GIG_LIMIT 2147483648 -#ifndef H5S_MAX_MPI_COUNT -#define H5S_MAX_MPI_COUNT 536870911 /* (2^29)-1 */ -#endif +/*********************/ +/* Package Variables */ +/*********************/ + +/*******************/ +/* Local Variables */ +/*******************/ static hsize_t bigio_count = H5S_MAX_MPI_COUNT; + /*------------------------------------------------------------------------- * Function: H5S_mpio_set_bigio_count * @@ -75,7 +104,7 @@ static hsize_t bigio_count = H5S_MAX_MPI_COUNT; * when we utilize derived datatypes. This is of * particular interest for allowing nightly testing * - * Return: the current/previous value of bigio_count. + * Return: The current/previous value of bigio_count. * * Programmer: Richard Warren, March 10, 2017 * @@ -85,19 +114,20 @@ hsize_t H5S_mpio_set_bigio_count(hsize_t new_count) { hsize_t orig_count = bigio_count; - if ((new_count > 0) && (new_count < TWO_GIG_LIMIT)) { + + if((new_count > 0) && (new_count < TWO_GIG_LIMIT)) bigio_count = new_count; - } + return orig_count; -} +} /* end H5S_mpio_set_bigio_count() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_all_type + * Function: H5S__mpio_all_type * * Purpose: Translate an HDF5 "all" selection into an MPI type. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -105,16 +135,11 @@ H5S_mpio_set_bigio_count(hsize_t new_count) * *is_derived_type 0 if MPI primitive type, 1 if derived * * Programmer: rky 980813 - * Modifications: - * Mohamad Chaarawi - * Adding support for large datatypes (beyond the limit of a - * 32 bit integer. - * * *------------------------------------------------------------------------- */ static herr_t -H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, +H5S__mpio_all_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { hsize_t total_bytes; @@ -122,7 +147,7 @@ H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, hsize_t nelmts; /* Total number of elmts */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -133,34 +158,33 @@ H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, H5_CHECKED_ASSIGN(nelmts, hsize_t, snelmts, hssize_t); total_bytes = (hsize_t)elmt_size * nelmts; + /* Verify that the size can be expressed as a 32 bit integer */ if(bigio_count >= total_bytes) { - /* fill in the return values */ - *new_type = MPI_BYTE; - H5_CHECKED_ASSIGN(*count, int, total_bytes, hsize_t); - *is_derived_type = FALSE; - } + /* fill in the return values */ + *new_type = MPI_BYTE; + H5_CHECKED_ASSIGN(*count, int, total_bytes, hsize_t); + *is_derived_type = FALSE; + } /* end if */ else { - /* Create a LARGE derived datatype for this transfer */ - if (H5S_mpio_create_large_type (total_bytes, 0, MPI_BYTE, new_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't create a large datatype from the all selection") - } - *count = 1; - *is_derived_type = TRUE; - } + /* Create a LARGE derived datatype for this transfer */ + if(H5S__mpio_create_large_type(total_bytes, 0, MPI_BYTE, new_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large datatype from the all selection") + *count = 1; + *is_derived_type = TRUE; + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_mpio_all_type() */ +} /* H5S__mpio_all_type() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_none_type + * Function: H5S__mpio_none_type * * Purpose: Translate an HDF5 "none" selection into an MPI type. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -172,9 +196,9 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S_mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) +H5S__mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* fill in the return values */ *new_type = MPI_BYTE; @@ -182,15 +206,15 @@ H5S_mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) *is_derived_type = FALSE; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_mpio_none_type() */ +} /* H5S__mpio_none_type() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_create_point_datatype + * Function: H5S__mpio_create_point_datatype * * Purpose: Create a derived datatype for point selections. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * @@ -198,18 +222,23 @@ H5S_mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) * *------------------------------------------------------------------------- */ -static herr_t -H5S_mpio_create_point_datatype (size_t elmt_size, hsize_t num_points, - MPI_Aint *disp, MPI_Datatype *new_type) +static herr_t +H5S__mpio_create_point_datatype(size_t elmt_size, hsize_t num_points, + MPI_Aint *disp, MPI_Datatype *new_type) { MPI_Datatype elmt_type; /* MPI datatype for individual element */ hbool_t elmt_type_created = FALSE; /* Whether the element MPI datatype was created */ - int mpi_code; /* MPI error code */ + int *inner_blocks = NULL; /* Arrays for MPI datatypes when "large" datatype needed */ + MPI_Aint *inner_disps = NULL; + MPI_Datatype *inner_types = NULL; +#if MPI_VERSION < 3 int *blocks = NULL; /* Array of block sizes for MPI hindexed create call */ hsize_t u; /* Local index variable */ +#endif + int mpi_code; /* MPI error code */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Create an MPI datatype for an element */ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type))) @@ -219,146 +248,127 @@ H5S_mpio_create_point_datatype (size_t elmt_size, hsize_t num_points, /* Check whether standard or BIGIO processing will be employeed */ if(bigio_count >= num_points) { #if MPI_VERSION >= 3 - /* Create an MPI datatype for the whole point selection */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block((int)num_points, 1, disp, elmt_type, new_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_indexed_block failed", mpi_code) + /* Create an MPI datatype for the whole point selection */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block((int)num_points, 1, disp, elmt_type, new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_indexed_block failed", mpi_code) #else - /* Allocate block sizes for MPI datatype call */ - if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * num_points))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") + /* Allocate block sizes for MPI datatype call */ + if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * num_points))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") - for(u = 0; u < num_points; u++) - blocks[u] = 1; + for(u = 0; u < num_points; u++) + blocks[u] = 1; - /* Create an MPI datatype for the whole point selection */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_points, blocks, disp, elmt_type, new_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + /* Create an MPI datatype for the whole point selection */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_points, blocks, disp, elmt_type, new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) #endif - /* Commit MPI datatype for later use */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - } - else { - /* use LARGE_DATATYPE:: - * We'll create an hindexed_block type for every 2G point count and then combine - * those and any remaining points into a single large datatype. - */ - int total_types, i; - int remaining_points; - int num_big_types; - hsize_t leftover; - - int *inner_blocks; - MPI_Aint *inner_disps; - MPI_Datatype *inner_types = NULL; + /* Commit MPI datatype for later use */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + } /* end if */ + else { + /* use LARGE_DATATYPE:: + * We'll create an hindexed_block type for every 2G point count and then combine + * those and any remaining points into a single large datatype. + */ + int total_types, i; + int remaining_points; + int num_big_types; + hsize_t leftover; - /* Calculate how many Big MPI datatypes are needed to represent the buffer */ - num_big_types = (int)(num_points/bigio_count); + /* Calculate how many Big MPI datatypes are needed to represent the buffer */ + num_big_types = (int)(num_points / bigio_count); - leftover = (hsize_t)num_points - (hsize_t)num_big_types * (hsize_t)bigio_count; - H5_CHECKED_ASSIGN(remaining_points, int, leftover, hsize_t); + leftover = (hsize_t)num_points - (hsize_t)num_big_types * (hsize_t)bigio_count; + H5_CHECKED_ASSIGN(remaining_points, int, leftover, hsize_t); - total_types = (int)(remaining_points) ? (num_big_types + 1) : num_big_types; + total_types = (int)(remaining_points) ? (num_big_types + 1) : num_big_types; - /* Allocate array if MPI derived types needed */ - if(NULL == (inner_types = (MPI_Datatype *)H5MM_malloc((sizeof(MPI_Datatype) * (size_t)total_types)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") + /* Allocate array if MPI derived types needed */ + if(NULL == (inner_types = (MPI_Datatype *)H5MM_malloc((sizeof(MPI_Datatype) * (size_t)total_types)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") - if(NULL == (inner_blocks = (int *)H5MM_malloc(sizeof(int) * (size_t)total_types))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") + if(NULL == (inner_blocks = (int *)H5MM_malloc(sizeof(int) * (size_t)total_types))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") - if(NULL == (inner_disps = (MPI_Aint *)H5MM_malloc(sizeof(MPI_Aint) * (size_t)total_types))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") + if(NULL == (inner_disps = (MPI_Aint *)H5MM_malloc(sizeof(MPI_Aint) * (size_t)total_types))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") #if MPI_VERSION < 3 - /* Allocate block sizes for MPI datatype call */ - if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * bigio_count))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") + /* Allocate block sizes for MPI datatype call */ + if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * bigio_count))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks") - for(u = 0; u < bigio_count; u++) - blocks[u] = 1; + for(u = 0; u < bigio_count; u++) + blocks[u] = 1; #endif - for(i=0 ; i= 3 - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(bigio_count, - 1, - &disp[i*bigio_count], - elmt_type, - &inner_types[i]))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code); - } + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(bigio_count, + 1, &disp[i*bigio_count], elmt_type, &inner_types[i]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code) #else - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)bigio_count, - blocks, - &disp[i*bigio_count], - elmt_type, - &inner_types[i]))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) - } + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)bigio_count, + blocks, &disp[i*bigio_count], elmt_type, &inner_types[i]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) #endif - inner_blocks[i] = 1; - inner_disps[i] = 0; - } + inner_blocks[i] = 1; + inner_disps[i] = 0; + } /* end for*/ - if(remaining_points) { + if(remaining_points) { #if MPI_VERSION >= 3 - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(remaining_points, - 1, - &disp[num_big_types*bigio_count], - elmt_type, - &inner_types[num_big_types]))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code); - } + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(remaining_points, + 1, &disp[num_big_types*bigio_count], elmt_type, &inner_types[num_big_types]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code) #else - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)remaining_points, - blocks, - &disp[num_big_types*bigio_count], - elmt_type, - &inner_types[num_big_types]))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) - } + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)remaining_points, + blocks, &disp[num_big_types*bigio_count], elmt_type, &inner_types[num_big_types]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) #endif - inner_blocks[num_big_types] = 1; - inner_disps[num_big_types] = 0; - } - - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(total_types, - inner_blocks, - inner_disps, - inner_types, - new_type))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct", mpi_code); - } - for(i=0 ; iselect.sel_info.pnt_lst->head; for(u = 0 ; u < num_points ; u++) { - /* calculate the displacement of the current point */ + /* Calculate the displacement of the current point */ disp[u] = H5VM_array_offset(space->extent.rank, space->extent.size, curr->pnt); disp[u] *= elmt_size; - /* This is a File Space used to set the file view, so adjust the displacements + /* This is a File Space used to set the file view, so adjust the displacements * to have them monotonically non-decreasing. - * Generate the permutation array by indicating at each point being selected, - * the position it will shifted in the new displacement. Example: - * Suppose 4 points with corresponding are selected - * Pt 1: disp=6 ; Pt 2: disp=3 ; Pt 3: disp=0 ; Pt 4: disp=4 + * Generate the permutation array by indicating at each point being selected, + * the position it will shifted in the new displacement. Example: + * Suppose 4 points with corresponding are selected + * Pt 1: disp=6 ; Pt 2: disp=3 ; Pt 3: disp=0 ; Pt 4: disp=4 * The permute map to sort the displacements in order will be: * point 1: map[0] = L, indicating that this point is not moved (1st point selected) - * point 2: map[1] = 0, indicating that this point is moved to the first position, + * point 2: map[1] = 0, indicating that this point is moved to the first position, * since disp_pt1(6) > disp_pt2(3) - * point 3: map[2] = 0, move to position 0, bec it has the lowest disp between + * point 3: map[2] = 0, move to position 0, bec it has the lowest disp between * the points selected so far. - * point 4: map[3] = 2, move the 2nd position since point 1 has a higher disp, + * point 4: map[3] = 2, move the 2nd position since point 1 has a higher disp, * but points 2 and 3 have lower displacements. */ if(do_permute) { @@ -447,7 +457,7 @@ H5S_mpio_point_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type HDmemmove(disp + m + 1, disp + m, (u - m) * sizeof(MPI_Aint)); disp[m] = temp; } /* end if */ - (*permute)[u] = m; + (*permute)[u] = m; } /* end if */ else (*permute)[u] = num_points; @@ -455,7 +465,7 @@ H5S_mpio_point_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type /* this is a memory space, and no permutation is necessary to create the derived datatype */ else { - ;/* do nothing */ + ; /* do nothing */ } /* end else */ /* get the next point */ @@ -463,7 +473,7 @@ H5S_mpio_point_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type } /* end for */ /* Create the MPI datatype for the set of element displacements */ - if(H5S_mpio_create_point_datatype(elmt_size, num_points, disp, new_type) < 0) + if(H5S__mpio_create_point_datatype(elmt_size, num_points, disp, new_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create an MPI Datatype from point selection") /* Set values about MPI datatype created */ @@ -481,11 +491,11 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_mpio_point_type() */ +} /* H5S__mpio_point_type() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_permute_type + * Function: H5S__mpio_permute_type * * Purpose: Translate an HDF5 "all/hyper/point" selection into an MPI type, * while applying the permutation map. This function is called if @@ -496,7 +506,7 @@ done: * Note: This routine is called from H5S_mpio_space_type(), which is * called first for the file dataspace and creates * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -508,7 +518,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S_mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, +H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { MPI_Aint *disp = NULL; /* Datatype displacement for each point*/ @@ -520,7 +530,7 @@ H5S_mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, hsize_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -571,12 +581,12 @@ H5S_mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, /* Set the displacement of the current point */ disp[u] = curr_off; - /* This is a memory displacement, so for each point selected, + /* This is a memory displacement, so for each point selected, * apply the map that was generated by the file selection */ if((*permute)[u] != num_points) { MPI_Aint temp = disp[u]; - HDmemmove(disp + (*permute)[u] + 1, disp + (*permute)[u], + HDmemmove(disp + (*permute)[u] + 1, disp + (*permute)[u], (u - (*permute)[u]) * sizeof(MPI_Aint)); disp[(*permute)[u]] = temp; } /* end if */ @@ -597,7 +607,7 @@ H5S_mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, } /* end while */ /* Create the MPI datatype for the set of element displacements */ - if(H5S_mpio_create_point_datatype(elmt_size, num_points, disp, new_type) < 0) + if(H5S__mpio_create_point_datatype(elmt_size, num_points, disp, new_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create an MPI Datatype from point selection") /* Set values about MPI datatype created */ @@ -619,15 +629,15 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_mpio_permute_type() */ +} /* H5S__mpio_permute_type() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_hyper_type + * Function: H5S__mpio_reg_hyper_type * - * Purpose: Translate an HDF5 hyperslab selection into an MPI type. + * Purpose: Translate a regular HDF5 hyperslab selection into an MPI type. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -635,14 +645,11 @@ done: * *is_derived_type 0 if MPI primitive type, 1 if derived * * Programmer: rky 980813 - * Modifications: - * Mohamad Chaarawi - * Adding support for large datatypes (beyond the limit of a - * 32 bit integer. + * *------------------------------------------------------------------------- */ static herr_t -H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, +H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { H5S_sel_iter_t sel_iter; /* Selection iteration info */ @@ -668,7 +675,7 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -683,16 +690,15 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, diminfo = sel_iter.u.hyp.diminfo; HDassert(diminfo); - /* make a local copy of the dimension info so we can operate with them */ + /* Make a local copy of the dimension info so we can operate with them */ /* Check if this is a "flattened" regular hyperslab selection */ if(sel_iter.u.hyp.iter_rank != 0 && sel_iter.u.hyp.iter_rank < space->extent.rank) { /* Flattened selection */ rank = sel_iter.u.hyp.iter_rank; - HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), "%s: Flattened selection\n",FUNC); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S), "%s: Flattened selection\n",FUNC); #endif for(u = 0; u < rank; ++u) { H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) @@ -701,33 +707,30 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, d[u].block = diminfo[u].block; d[u].count = diminfo[u].count; d[u].xtent = sel_iter.u.hyp.size[u]; + #ifdef H5S_DEBUG - if(H5DEBUG(S)){ - HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); - if (u==0) - HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); - else - HDfprintf(H5DEBUG(S), "\n" ); - } +if(H5DEBUG(S)) { + HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent); + if(u == 0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank); + else + HDfprintf(H5DEBUG(S), "\n"); +} #endif - if(0 == d[u].block) - goto empty; - if(0 == d[u].count) - goto empty; - if(0 == d[u].xtent) - goto empty; + + /* Sanity check */ + HDassert(d[u].block > 0); + HDassert(d[u].count > 0); + HDassert(d[u].xtent > 0); } /* end for */ } /* end if */ else { /* Non-flattened selection */ rank = space->extent.rank; - HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ - if(0 == rank) - goto empty; #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC); #endif for(u = 0; u < rank; ++u) { H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) @@ -736,22 +739,22 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, d[u].block = diminfo[u].block; d[u].count = diminfo[u].count; d[u].xtent = space->extent.size[u]; + #ifdef H5S_DEBUG - if(H5DEBUG(S)){ +if(H5DEBUG(S)) { HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); - if (u==0) - HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent); + if(u == 0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank); else - HDfprintf(H5DEBUG(S), "\n" ); - } + HDfprintf(H5DEBUG(S), "\n"); +} #endif - if(0 == d[u].block) - goto empty; - if(0 == d[u].count) - goto empty; - if(0 == d[u].xtent) - goto empty; + + /* Sanity check */ + HDassert(d[u].block > 0); + HDassert(d[u].count > 0); + HDassert(d[u].xtent > 0); } /* end for */ } /* end else */ @@ -762,56 +765,52 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, offset[rank - 1] = 1; max_xtent[rank - 1] = d[rank - 1].xtent; #ifdef H5S_DEBUG - if(H5DEBUG(S)) { - i = ((int)rank) - 1; - HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", - i, offset[i], i, max_xtent[i]); - } +if(H5DEBUG(S)) { + i = ((int)rank) - 1; + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); +} #endif for(i = ((int)rank) - 2; i >= 0; --i) { offset[i] = offset[i + 1] * d[i + 1].xtent; max_xtent[i] = max_xtent[i + 1] * d[i].xtent; #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", - i, offset[i], i, max_xtent[i]); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); #endif } /* end for */ /* Create a type covering the selected hyperslab. * Multidimensional dataspaces are stored in row-major order. * The type is built from the inside out, going from the - * fastest-changing (i.e., inner) dimension * to the slowest (outer). */ + * fastest-changing (i.e., inner) dimension * to the slowest (outer). + */ /******************************************************* * Construct contig type for inner contig dims: *******************************************************/ #ifdef H5S_DEBUG - if(H5DEBUG(S)) { +if(H5DEBUG(S)) { HDfprintf(H5DEBUG(S), "%s: Making contig type %Zu MPI_BYTEs\n", FUNC, elmt_size); for(i = ((int)rank) - 1; i >= 0; --i) HDfprintf(H5DEBUG(S), "d[%d].xtent=%Hu \n", i, d[i].xtent); - } +} #endif /* LARGE_DATATYPE:: - * Check if the number of elements to form the inner type fits into a 32 bit integer. + * Check if the number of elements to form the inner type fits into a 32 bit integer. * If yes then just create the innertype with MPI_Type_contiguous. * Otherwise create a compound datatype by iterating as many times as needed * for the innertype to be created. */ if(bigio_count >= elmt_size) { - /* Use a single MPI datatype that has a 32 bit size */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &inner_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - else { - /* Create the compound datatype for this operation (> 2GB) */ - if (H5S_mpio_create_large_type (elmt_size, 0, MPI_BYTE, &inner_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't ccreate a large inner datatype in hyper selection") - } - } + /* Use a single MPI datatype that has a 32 bit size */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &inner_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + } /* end if */ + else + /* Create the compound datatype for this operation (> 2GB) */ + if(H5S__mpio_create_large_type(elmt_size, 0, MPI_BYTE, &inner_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large inner datatype in hyper selection") /******************************************************* * Construct the type by walking the hyperslab dims @@ -819,65 +818,57 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, *******************************************************/ for(i = ((int)rank) - 1; i >= 0; --i) { #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n" - "start=%Hd count=%Hu block=%Hu stride=%Hu, xtent=%Hu max_xtent=%d\n", - FUNC, i, d[i].start, d[i].count, d[i].block, d[i].strid, d[i].xtent, max_xtent[i]); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n" + "start=%Hd count=%Hu block=%Hu stride=%Hu, xtent=%Hu max_xtent=%d\n", + FUNC, i, d[i].start, d[i].count, d[i].block, d[i].strid, d[i].xtent, max_xtent[i]); #endif #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i); #endif /**************************************** - * Build vector type of the selection. - ****************************************/ - if (bigio_count >= d[i].count && - bigio_count >= d[i].block && - bigio_count >= d[i].strid) { - - /* All the parameters fit into 32 bit integers so create the vector type normally */ - mpi_code = MPI_Type_vector((int)(d[i].count), /* count */ - (int)(d[i].block), /* blocklength */ - (int)(d[i].strid), /* stride */ - inner_type, /* old type */ - &outer_type); /* new type */ - - MPI_Type_free(&inner_type); - if(mpi_code != MPI_SUCCESS) - HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code) - } + * Build vector type of the selection. + ****************************************/ + if(bigio_count >= d[i].count && + bigio_count >= d[i].block && bigio_count >= d[i].strid) { + /* All the parameters fit into 32 bit integers so create the vector type normally */ + mpi_code = MPI_Type_vector((int)(d[i].count), /* count */ + (int)(d[i].block), /* blocklength */ + (int)(d[i].strid), /* stride */ + inner_type, /* old type */ + &outer_type); /* new type */ + + MPI_Type_free(&inner_type); + if(mpi_code != MPI_SUCCESS) + HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code) + } /* end if */ else { - /* Things get a bit more complicated and require LARGE_DATATYPE processing - * There are two MPI datatypes that need to be created: - * 1) an internal contiguous block; and - * 2) a collection of elements where an element is a contiguous block(1). - * Remember that the input arguments to the MPI-IO functions use integer - * values to represent element counts. We ARE allowed however, in the - * more recent MPI implementations to use constructed datatypes whereby - * the total number of bytes in a transfer could be : - * (2GB-1)number_of_blocks * the_datatype_extent. - */ + /* Things get a bit more complicated and require LARGE_DATATYPE processing + * There are two MPI datatypes that need to be created: + * 1) an internal contiguous block; and + * 2) a collection of elements where an element is a contiguous block(1). + * Remember that the input arguments to the MPI-IO functions use integer + * values to represent element counts. We ARE allowed however, in the + * more recent MPI implementations to use constructed datatypes whereby + * the total number of bytes in a transfer could be : + * (2GB-1)number_of_blocks * the_datatype_extent. + */ MPI_Aint stride_in_bytes, inner_extent; MPI_Datatype block_type; - /* create a contiguous datatype inner_type x number of BLOCKS. - * Again we need to check that the number of BLOCKS can fit into + /* Create a contiguous datatype inner_type x number of BLOCKS. + * Again we need to check that the number of BLOCKS can fit into * a 32 bit integer */ - if (bigio_count < d[i].block) { - if (H5S_mpio_create_large_type(d[i].block, 0, inner_type, - &block_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't ccreate a large block datatype in hyper selection") - } - } - else { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)d[i].block, - inner_type, - &block_type))) + if(bigio_count < d[i].block) { + if(H5S__mpio_create_large_type(d[i].block, 0, inner_type, &block_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large block datatype in hyper selection") + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)d[i].block, inner_type, &block_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } /* As of version 4.0, OpenMPI now turns off MPI-1 API calls by default, * so we're using the MPI-2 version even though we don't need the lb @@ -892,40 +883,38 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, /* If the element count is larger than what a 32 bit integer can hold, * we call the large type creation function to handle that */ - if (bigio_count < d[i].count) { - if (H5S_mpio_create_large_type (d[i].count, stride_in_bytes, block_type, - &outer_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't create a large outer datatype in hyper selection") - } - } + if(bigio_count < d[i].count) { + if(H5S__mpio_create_large_type(d[i].count, stride_in_bytes, block_type, &outer_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large outer datatype in hyper selection") + } /* end if */ /* otherwise a regular create_hvector will do */ - else { - mpi_code = MPI_Type_create_hvector((int)d[i].count, /* count */ - 1, /* blocklength */ - stride_in_bytes, /* stride in bytes*/ - block_type, /* old type */ - &outer_type); /* new type */ - if(MPI_SUCCESS != mpi_code) + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)d[i].count, /* count */ + 1, /* blocklength */ + stride_in_bytes, /* stride in bytes*/ + block_type, /* old type */ + &outer_type))) /* new type */ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - } + MPI_Type_free(&block_type); MPI_Type_free(&inner_type); - } - /**************************************** - * Then build the dimension type as (start, vector type, xtent). - ****************************************/ - /* calculate start and extent values of this dimension */ + } /* end else */ + + /**************************************** + * Then build the dimension type as (start, vector type, xtent). + ****************************************/ + + /* Calculate start and extent values of this dimension */ start_disp = d[i].start * offset[i] * elmt_size; new_extent = (MPI_Aint)elmt_size * max_xtent[i]; if(MPI_SUCCESS != (mpi_code = MPI_Type_get_extent(outer_type, &lb, &extent_len))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_get_extent failed", mpi_code) /************************************************* - * Restructure this datatype ("outer_type") - * so that it still starts at 0, but its extent - * is the full extent in this dimension. - *************************************************/ + * Restructure this datatype ("outer_type") + * so that it still starts at 0, but its extent + * is the full extent in this dimension. + *************************************************/ if(start_disp > 0 || extent_len < new_extent) { MPI_Datatype interm_type; int block_len = 1; @@ -957,13 +946,6 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, /* fill in the remaining return values */ *count = 1; /* only have to move one of these suckers! */ *is_derived_type = TRUE; - HGOTO_DONE(SUCCEED); - -empty: - /* special case: empty hyperslab */ - *new_type = MPI_BYTE; - *count = 0; - *is_derived_type = FALSE; done: /* Release selection iterator */ @@ -972,21 +954,20 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") #ifdef H5S_DEBUG - if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), "Leave %s, count=%ld is_derived_type=%t\n", - FUNC, *count, *is_derived_type ); +if(H5DEBUG(S)) + HDfprintf(H5DEBUG(S), "Leave %s, count=%ld is_derived_type=%t\n", FUNC, *count, *is_derived_type); #endif FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_mpio_hyper_type() */ +} /* end H5S__mpio_reg_hyper_type() */ /*------------------------------------------------------------------------- - * Function: H5S_mpio_span_hyper_type + * Function: H5S__mpio_span_hyper_type * * Purpose: Translate an HDF5 irregular hyperslab selection into an MPI type. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -995,14 +976,10 @@ done: * * Programmer: kyang * - * Modifications: - * Mohamad Chaarawi - * Adding support for large datatypes (beyond the limit of a - * 32 bit integer. *------------------------------------------------------------------------- */ static herr_t -H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, +H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { MPI_Datatype elmt_type; /* MPI datatype for an element */ @@ -1012,7 +989,7 @@ H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -1021,17 +998,13 @@ H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, HDassert(space->select.sel_info.hslab->span_lst->head); /* Create the base type for an element */ - if (bigio_count >= elmt_size) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type))) { - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - } - else { - if (H5S_mpio_create_large_type (elmt_size, 0, MPI_BYTE, &elmt_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't create a large element datatype in span_hyper selection") - } - } + if(bigio_count >= elmt_size) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + } /* end if */ + else + if(H5S__mpio_create_large_type(elmt_size, 0, MPI_BYTE, &elmt_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large element datatype in span_hyper selection") elmt_type_is_derived = TRUE; /* Compute 'down' sizes for each dimension */ @@ -1039,8 +1012,8 @@ H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGETSIZE, FAIL, "couldn't compute 'down' dimension sizes") /* Obtain derived data type */ - if(H5S_obtain_datatype(down, space->select.sel_info.hslab->span_lst->head, &elmt_type, &span_type, elmt_size) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") + if(H5S__obtain_datatype(down, space->select.sel_info.hslab->span_lst->head, &elmt_type, &span_type, elmt_size) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) *new_type = span_type; @@ -1056,16 +1029,15 @@ done: HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_mpio_span_hyper_type() */ +} /* end H5S__mpio_span_hyper_type() */ /*------------------------------------------------------------------------- - * Function: H5S_obtain_datatype + * Function: H5S__obtain_datatype * - * Purpose: Obtain an MPI derived datatype based on span-tree - * implementation + * Purpose: Obtain an MPI derived datatype for span-tree hyperslab selection * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *span_type the MPI type corresponding to the selection * @@ -1074,11 +1046,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, +H5S__obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size) { size_t alloc_count = 0; /* Number of span tree nodes allocated at this level */ - size_t outercount = 0; /* Number of span tree nodes at this level */ + size_t outercount; /* Number of span tree nodes at this level */ MPI_Datatype *inner_type = NULL; hbool_t inner_types_freed = FALSE; /* Whether the inner_type MPI datatypes have been freed */ hbool_t span_type_valid = FALSE; /* Whether the span_type MPI datatypes is valid */ @@ -1089,7 +1061,7 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, int mpi_code; /* MPI return status code */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity check */ HDassert(span); @@ -1129,16 +1101,14 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, blocklen[outercount] = (int)tspan->nelem; tspan = tspan->next; - if (bigio_count < blocklen[outercount]) { + if(bigio_count < blocklen[outercount]) large_block = TRUE; /* at least one block type is large, so set this flag to true */ - } outercount++; } /* end while */ /* Everything fits into integers, so cast them and use hindexed */ - if (bigio_count >= outercount && large_block == FALSE) { - + if(bigio_count >= outercount && large_block == FALSE) { if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)outercount, blocklen, disp, *elmt_type, span_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) span_type_valid = TRUE; @@ -1150,7 +1120,7 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, MPI_Datatype temp_type = MPI_DATATYPE_NULL, outer_type = MPI_DATATYPE_NULL; /* create the block type from elmt_type while checking the 32 bit int limit */ if (blocklen[i] > bigio_count) { - if (H5S_mpio_create_large_type (blocklen[i], 0, *elmt_type, &temp_type) < 0) { + if (H5S__mpio_create_large_type (blocklen[i], 0, *elmt_type, &temp_type) < 0) { HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large element datatype in span_hyper selection") } @@ -1233,7 +1203,7 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, blocklen[outercount] = 1; /* Generate MPI datatype for next dimension down */ - if(H5S_obtain_datatype(down + 1, tspan->down->head, elmt_type, &down_type, elmt_size) < 0) + if(H5S__obtain_datatype(down + 1, tspan->down->head, elmt_type, &down_type, elmt_size) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") /* Build the MPI datatype for this node */ @@ -1291,7 +1261,7 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_obtain_datatype() */ +} /* end H5S__obtain_datatype() */ /*------------------------------------------------------------------------- @@ -1300,7 +1270,7 @@ done: * Purpose: Translate an HDF5 dataspace selection into an MPI type. * Currently handle only hyperslab and "all" selections. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Outputs: *new_type the MPI type corresponding to the selection * *count how many objects of the new_type in selection @@ -1312,7 +1282,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, +H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, hbool_t do_permute, hsize_t **permute_map, hbool_t *is_permuted) { @@ -1333,10 +1303,10 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type * out-of-order point selection, then permute this selection which * should be a memory selection to match the file space permutation. */ - if(TRUE == *is_permuted) { + if(TRUE == *is_permuted) { switch(H5S_GET_SELECT_TYPE(space)) { case H5S_SEL_NONE: - if(H5S_mpio_none_type(new_type, count, is_derived_type) < 0) + if(H5S__mpio_none_type(new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't convert 'none' selection to MPI type") break; @@ -1346,7 +1316,7 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type /* Sanity check */ HDassert(!do_permute); - if(H5S_mpio_permute_type(space, elmt_size, permute_map, new_type, count, is_derived_type) < 0) + if(H5S__mpio_permute_type(space, elmt_size, permute_map, new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't convert 'all' selection to MPI type") break; @@ -1361,29 +1331,28 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type else { switch(H5S_GET_SELECT_TYPE(space)) { case H5S_SEL_NONE: - if(H5S_mpio_none_type(new_type, count, is_derived_type) < 0) + if(H5S__mpio_none_type(new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert 'none' selection to MPI type") break; case H5S_SEL_ALL: - if(H5S_mpio_all_type(space, elmt_size, new_type, count, is_derived_type) < 0) + if(H5S__mpio_all_type(space, elmt_size, new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert 'all' selection to MPI type") break; case H5S_SEL_POINTS: - if(H5S_mpio_point_type(space, elmt_size, new_type, count, is_derived_type, do_permute, permute_map, is_permuted) < 0) + if(H5S__mpio_point_type(space, elmt_size, new_type, count, is_derived_type, do_permute, permute_map, is_permuted) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't convert 'point' selection to MPI type") break; case H5S_SEL_HYPERSLABS: if((H5S_SELECT_IS_REGULAR(space) == TRUE)) { - if(H5S_mpio_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0) + if(H5S__mpio_reg_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert regular 'hyperslab' selection to MPI type") } /* end if */ - else { - if(H5S_mpio_span_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0) + else + if(H5S__mpio_span_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert irregular 'hyperslab' selection to MPI type") - } /* end else */ break; case H5S_SEL_ERROR: @@ -1407,12 +1376,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5S_mpio_create_large_type + * Function: H5S__mpio_create_large_type * - * Purpose: Create a large datatype of size larger than what a 32 bit integer + * Purpose: Create a large datatype of size larger than what a 32 bit integer * can hold. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * *new_type the new datatype created * @@ -1420,10 +1389,9 @@ done: * *------------------------------------------------------------------------- */ -static herr_t H5S_mpio_create_large_type (hsize_t num_elements, - MPI_Aint stride_bytes, - MPI_Datatype old_type, - MPI_Datatype *new_type) +static herr_t +H5S__mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, + MPI_Datatype old_type, MPI_Datatype *new_type) { int num_big_types; /* num times the 2G datatype will be repeated */ int remaining_bytes; /* the number of bytes left that can be held in an int value */ @@ -1434,7 +1402,7 @@ static herr_t H5S_mpio_create_large_type (hsize_t num_elements, MPI_Aint disp[2], old_extent; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Calculate how many Big MPI datatypes are needed to represent the buffer */ num_big_types = (int)(num_elements/bigio_count); @@ -1447,41 +1415,23 @@ static herr_t H5S_mpio_create_large_type (hsize_t num_elements, * use type_hvector to create the type with the displacement provided */ if (0 == stride_bytes) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(bigio_count, - old_type, - &inner_type))) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(bigio_count, old_type, &inner_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - } - else { - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector (bigio_count, - 1, - stride_bytes, - old_type, - &inner_type))) { + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(bigio_count, 1, stride_bytes, old_type, &inner_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - } - } /* Create a contiguous datatype of the buffer (minus the remaining < 2GB part) * If a stride is present, use hvector type */ - if (0 == stride_bytes) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(num_big_types, - inner_type, - &outer_type))) { + if(0 == stride_bytes) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(num_big_types, inner_type, &outer_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - } - else { - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector (num_big_types, - 1, - stride_bytes, - inner_type, - &outer_type))) { + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector(num_big_types, 1, stride_bytes, inner_type, &outer_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - } - } MPI_Type_free(&inner_type); @@ -1489,23 +1439,13 @@ static herr_t H5S_mpio_create_large_type (hsize_t num_elements, * use a struct datatype to encapsulate everything. */ if(remaining_bytes) { - if (stride_bytes == 0) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous (remaining_bytes, - old_type, - &leftover_type))) { + if(stride_bytes == 0) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(remaining_bytes, old_type, &leftover_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - } - else { - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector - ((int)(num_elements - (hsize_t)num_big_types*bigio_count), - 1, - stride_bytes, - old_type, - &leftover_type))) { + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)(num_elements - (hsize_t)num_big_types * bigio_count), 1, stride_bytes, old_type, &leftover_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - } - } /* As of version 4.0, OpenMPI now turns off MPI-1 API calls by default, * so we're using the MPI-2 version even though we don't need the lb @@ -1522,28 +1462,25 @@ static herr_t H5S_mpio_create_large_type (hsize_t num_elements, block_len[0] = 1; block_len[1] = 1; disp[0] = 0; - disp[1] = (old_extent+stride_bytes)*num_big_types*(MPI_Aint)bigio_count; + disp[1] = (old_extent + stride_bytes) * num_big_types * (MPI_Aint)bigio_count; - if(MPI_SUCCESS != (mpi_code = - MPI_Type_create_struct(2, block_len, disp, type, new_type))) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(2, block_len, disp, type, new_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - } MPI_Type_free(&outer_type); MPI_Type_free(&leftover_type); - } - else { + } /* end if */ + else /* There are no remaining bytes so just set the new type to * the outer type created */ *new_type = outer_type; - } if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_mpio_create_large_type */ +} /* end H5S__mpio_create_large_type() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Snone.c b/src/H5Snone.c index a8aaf7e..c867e67 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -18,166 +18,197 @@ * Purpose: "None" selection dataspace I/O functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ -#include "H5private.h" -#include "H5Eprivate.h" -#include "H5Iprivate.h" -#include "H5Spkg.h" -#include "H5VMprivate.h" -#include "H5Dprivate.h" +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ -/* Static function prototypes */ + +/********************/ +/* Local Prototypes */ +/********************/ /* Selection callbacks */ -static herr_t H5S_none_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S_none_get_seq_list(const H5S_t *space, unsigned flags, +static herr_t H5S__none_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); +static herr_t H5S__none_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); -static herr_t H5S_none_release(H5S_t *space); -static htri_t H5S_none_is_valid(const H5S_t *space); -static hssize_t H5S_none_serial_size(const H5S_t *space); -static herr_t H5S_none_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_none_deserialize(H5S_t *space, uint32_t version, uint8_t flags, +static herr_t H5S__none_release(H5S_t *space); +static htri_t H5S__none_is_valid(const H5S_t *space); +static hssize_t H5S__none_serial_size(const H5S_t *space); +static herr_t H5S__none_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S__none_deserialize(H5S_t *space, uint32_t version, uint8_t flags, const uint8_t **p); -static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); -static herr_t H5S_none_offset(const H5S_t *space, hsize_t *off); +static herr_t H5S__none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +static herr_t H5S__none_offset(const H5S_t *space, hsize_t *off); static int H5S__none_unlim_dim(const H5S_t *space); -static htri_t H5S_none_is_contiguous(const H5S_t *space); -static htri_t H5S_none_is_single(const H5S_t *space); -static htri_t H5S_none_is_regular(const H5S_t *space); -static herr_t H5S_none_adjust_u(H5S_t *space, const hsize_t *offset); -static herr_t H5S_none_project_scalar(const H5S_t *space, hsize_t *offset); -static herr_t H5S_none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static htri_t H5S__none_is_contiguous(const H5S_t *space); +static htri_t H5S__none_is_single(const H5S_t *space); +static htri_t H5S__none_is_regular(const H5S_t *space); +static herr_t H5S__none_adjust_u(H5S_t *space, const hsize_t *offset); +static herr_t H5S__none_project_scalar(const H5S_t *space, hsize_t *offset); +static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); +static herr_t H5S__none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ -static herr_t H5S_none_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); -static herr_t H5S_none_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end); -static hsize_t H5S_none_iter_nelmts(const H5S_sel_iter_t *iter); -static htri_t H5S_none_iter_has_next_block(const H5S_sel_iter_t *iter); -static herr_t H5S_none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -static herr_t H5S_none_iter_next_block(H5S_sel_iter_t *sel_iter); -static herr_t H5S_none_iter_release(H5S_sel_iter_t *sel_iter); +static herr_t H5S__none_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); +static herr_t H5S__none_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end); +static hsize_t H5S__none_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S__none_iter_has_next_block(const H5S_sel_iter_t *iter); +static herr_t H5S__none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S__none_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__none_iter_release(H5S_sel_iter_t *sel_iter); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ /* Selection properties for "none" selections */ const H5S_select_class_t H5S_sel_none[1] = {{ H5S_SEL_NONE, /* Methods on selection */ - H5S_none_copy, - H5S_none_get_seq_list, - H5S_none_release, - H5S_none_is_valid, - H5S_none_serial_size, - H5S_none_serialize, - H5S_none_deserialize, - H5S_none_bounds, - H5S_none_offset, + H5S__none_copy, + H5S__none_get_seq_list, + H5S__none_release, + H5S__none_is_valid, + H5S__none_serial_size, + H5S__none_serialize, + H5S__none_deserialize, + H5S__none_bounds, + H5S__none_offset, H5S__none_unlim_dim, NULL, - H5S_none_is_contiguous, - H5S_none_is_single, - H5S_none_is_regular, - H5S_none_adjust_u, - H5S_none_project_scalar, - H5S_none_project_simple, - H5S_none_iter_init, + H5S__none_is_contiguous, + H5S__none_is_single, + H5S__none_is_regular, + H5S__none_adjust_u, + H5S__none_project_scalar, + H5S__none_project_simple, + H5S__none_iter_init, }}; + +/*******************/ +/* Local Variables */ +/*******************/ + /* Iteration properties for "none" selections */ static const H5S_sel_iter_class_t H5S_sel_iter_none[1] = {{ H5S_SEL_NONE, /* Methods on selection iterator */ - H5S_none_iter_coords, - H5S_none_iter_block, - H5S_none_iter_nelmts, - H5S_none_iter_has_next_block, - H5S_none_iter_next, - H5S_none_iter_next_block, - H5S_none_iter_release, + H5S__none_iter_coords, + H5S__none_iter_block, + H5S__none_iter_nelmts, + H5S__none_iter_has_next_block, + H5S__none_iter_next, + H5S__none_iter_next_block, + H5S__none_iter_release, }}; + /*------------------------------------------------------------------------- - * Function: H5S_none_iter_init + * Function: H5S__none_iter_init * * Purpose: Initializes iteration information for "none" selection. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t H5_ATTR_UNUSED *space) +H5S__none_iter_init(H5S_sel_iter_t *iter, const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space && H5S_SEL_NONE==H5S_GET_SELECT_TYPE(space)); + HDassert(space && H5S_SEL_NONE == H5S_GET_SELECT_TYPE(space)); HDassert(iter); /* Initialize type of selection iterator */ iter->type = H5S_sel_iter_none; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_iter_init() */ +} /* end H5S__none_iter_init() */ /*------------------------------------------------------------------------- - * Function: H5S_none_iter_coords + * Function: H5S__none_iter_coords * * Purpose: Retrieve the current coordinates of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Tuesday, April 22, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_none_iter_coords(const H5S_sel_iter_t H5_ATTR_UNUSED *iter, hsize_t H5_ATTR_UNUSED *coords) +H5S__none_iter_coords(const H5S_sel_iter_t H5_ATTR_UNUSED *iter, + hsize_t H5_ATTR_UNUSED *coords) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); HDassert(coords); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_iter_coords() */ +} /* end H5S__none_iter_coords() */ /*------------------------------------------------------------------------- - * Function: H5S_none_iter_block + * Function: H5S__none_iter_block * * Purpose: Retrieve the current block of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Monday, June 2, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_none_iter_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter, hsize_t H5_ATTR_UNUSED *start, hsize_t H5_ATTR_UNUSED *end) +H5S__none_iter_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter, + hsize_t H5_ATTR_UNUSED *start, hsize_t H5_ATTR_UNUSED *end) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); @@ -185,42 +216,40 @@ H5S_none_iter_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter, hsize_t H5_ATTR_U HDassert(end); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_iter_block() */ +} /* end H5S__none_iter_block() */ /*------------------------------------------------------------------------- - * Function: H5S_none_iter_nelmts + * Function: H5S__none_iter_nelmts * * Purpose: Return number of elements left to process in iterator * - * Return: non-negative number of elements on success, zero on failure + * Return: Non-negative number of elements on success, zero on failure * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ static hsize_t -H5S_none_iter_nelmts(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) +H5S__none_iter_nelmts(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(0) -} /* H5S_none_iter_nelmts() */ +} /* end H5S__none_iter_nelmts() */ /*-------------------------------------------------------------------------- NAME - H5S_none_iter_has_next_block + H5S__none_iter_has_next_block PURPOSE Check if there is another block left in the current iterator USAGE - htri_t H5S_none_iter_has_next_block(iter) + htri_t H5S__none_iter_has_next_block(iter) const H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative (TRUE/FALSE) on success/Negative on failure @@ -232,24 +261,24 @@ H5S_none_iter_nelmts(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_none_iter_has_next_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) +H5S__none_iter_has_next_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_iter_has_next_block() */ +} /* end H5S__none_iter_has_next_block() */ /*-------------------------------------------------------------------------- NAME - H5S_none_iter_next + H5S__none_iter_next PURPOSE Increment selection iterator USAGE - herr_t H5S_none_iter_next(iter, nelem) + herr_t H5S__none_iter_next(iter, nelem) H5S_sel_iter_t *iter; IN: Pointer to selection iterator size_t nelem; IN: Number of elements to advance by RETURNS @@ -262,25 +291,25 @@ H5S_none_iter_has_next_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_iter_next(H5S_sel_iter_t H5_ATTR_UNUSED *iter, size_t H5_ATTR_UNUSED nelem) +H5S__none_iter_next(H5S_sel_iter_t H5_ATTR_UNUSED *iter, size_t H5_ATTR_UNUSED nelem) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); - HDassert(nelem>0); + HDassert(nelem > 0); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_iter_next() */ +} /* end H5S__none_iter_next() */ /*-------------------------------------------------------------------------- NAME - H5S_none_iter_next_block + H5S__none_iter_next_block PURPOSE Increment selection iterator to next block USAGE - herr_t H5S_none_iter_next(iter) + herr_t H5S__none_iter_next(iter) H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative on success/Negative on failure @@ -292,24 +321,24 @@ H5S_none_iter_next(H5S_sel_iter_t H5_ATTR_UNUSED *iter, size_t H5_ATTR_UNUSED ne REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) +H5S__none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_iter_next_block() */ +} /* end H5S__none_iter_next_block() */ /*-------------------------------------------------------------------------- NAME - H5S_none_iter_release + H5S__none_iter_release PURPOSE Release "none" selection iterator information for a dataspace USAGE - herr_t H5S_none_iter_release(iter) + herr_t H5S__none_iter_release(iter) H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative on success/Negative on failure @@ -321,24 +350,24 @@ H5S_none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED * iter) +H5S__none_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_iter_release() */ +} /* end H5S__none_iter_release() */ /*-------------------------------------------------------------------------- NAME - H5S_none_release + H5S__none_release PURPOSE Release none selection information for a dataspace USAGE - herr_t H5S_none_release(space) + herr_t H5S__none_release(space) H5S_t *space; IN: Pointer to dataspace RETURNS Non-negative on success/Negative on failure @@ -350,26 +379,27 @@ H5S_none_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED * iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_release(H5S_t H5_ATTR_UNUSED * space) +H5S__none_release(H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_release() */ +} /* end H5S__none_release() */ /*-------------------------------------------------------------------------- NAME - H5S_none_copy + H5S__none_copy PURPOSE Copy a selection from one dataspace to another USAGE - herr_t H5S_none_copy(dst, src) + herr_t H5S__none_copy(dst, src, share_selection) H5S_t *dst; OUT: Pointer to the destination dataspace H5S_t *src; IN: Pointer to the source dataspace + hbool_t; IN: Whether to share the selection between the dataspaces RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -381,9 +411,10 @@ H5S_none_release(H5S_t H5_ATTR_UNUSED * space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_copy(H5S_t *dst, const H5S_t H5_ATTR_UNUSED *src, hbool_t H5_ATTR_UNUSED share_selection) +H5S__none_copy(H5S_t *dst, const H5S_t H5_ATTR_UNUSED *src, + hbool_t H5_ATTR_UNUSED share_selection) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(src); HDassert(dst); @@ -392,17 +423,17 @@ H5S_none_copy(H5S_t *dst, const H5S_t H5_ATTR_UNUSED *src, hbool_t H5_ATTR_UNUSE dst->select.num_elem = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S_none_copy() */ +} /* end H5S__none_copy() */ /*-------------------------------------------------------------------------- NAME - H5S_none_is_valid + H5S__none_is_valid PURPOSE Check whether the selection fits within the extent, with the current offset defined. USAGE - htri_t H5S_none_is_valid(space); + htri_t H5S__none_is_valid(space); H5S_t *space; IN: Dataspace pointer to query RETURNS TRUE if the selection fits within the extent, FALSE if it does not and @@ -416,24 +447,24 @@ H5S_none_copy(H5S_t *dst, const H5S_t H5_ATTR_UNUSED *src, hbool_t H5_ATTR_UNUSE REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_none_is_valid(const H5S_t H5_ATTR_UNUSED *space) +H5S__none_is_valid(const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); FUNC_LEAVE_NOAPI(TRUE) -} /* end H5S_none_is_valid() */ +} /* end H5S__none_is_valid() */ /*-------------------------------------------------------------------------- NAME - H5S_none_serial_size + H5S__none_serial_size PURPOSE Determine the number of bytes needed to store the serialized "none" selection information. USAGE - hssize_t H5S_none_serial_size(space) + hssize_t H5S__none_serial_size(space) H5S_t *space; IN: Dataspace pointer to query RETURNS The number of bytes required on success, negative on an error. @@ -446,9 +477,9 @@ H5S_none_is_valid(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static hssize_t -H5S_none_serial_size(const H5S_t H5_ATTR_UNUSED *space) +H5S__none_serial_size(const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); @@ -457,16 +488,16 @@ H5S_none_serial_size(const H5S_t H5_ATTR_UNUSED *space) * = 16 bytes */ FUNC_LEAVE_NOAPI(16) -} /* end H5S_none_serial_size() */ +} /* end H5S__none_serial_size() */ /*-------------------------------------------------------------------------- NAME - H5S_none_serialize + H5S__none_serialize PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_none_serialize(space, p) + herr_t H5S__none_serialize(space, p) const H5S_t *space; IN: Dataspace with selection to serialize uint8_t **p; OUT: Pointer to buffer to put serialized selection. Will be advanced to end of @@ -482,11 +513,11 @@ H5S_none_serial_size(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_serialize(const H5S_t *space, uint8_t **p) +H5S__none_serialize(const H5S_t *space, uint8_t **p) { uint8_t *pp = (*p); /* Local pointer for decoding */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); @@ -503,16 +534,16 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) *p = pp; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_serialize() */ +} /* end H5S__none_serialize() */ /*-------------------------------------------------------------------------- NAME - H5S_none_deserialize + H5S__none_deserialize PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_none_deserialize(space, version, flags, p) + herr_t H5S__none_deserialize(space, version, flags, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into uint32_t version IN: Selection version @@ -531,12 +562,12 @@ H5S_none_serialize(const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, - const uint8_t H5_ATTR_UNUSED **p) +H5S__none_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, + uint8_t H5_ATTR_UNUSED flags, const uint8_t H5_ATTR_UNUSED **p) { herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC HDassert(space); HDassert(p); @@ -548,16 +579,16 @@ H5S_none_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_A done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_none_deserialize() */ +} /* end H5S__none_deserialize() */ /*-------------------------------------------------------------------------- NAME - H5S_none_bounds + H5S__none_bounds PURPOSE Gets the bounding box containing the selection. USAGE - herr_t H5S_none_bounds(space, start, end) + herr_t H5S__none_bounds(space, start, end) H5S_t *space; IN: Dataspace pointer of selection to query hsize_t *start; OUT: Starting coordinate of bounding box hsize_t *end; OUT: Opposite coordinate of bounding box @@ -577,25 +608,26 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_bounds(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *start, hsize_t H5_ATTR_UNUSED *end) +H5S__none_bounds(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *start, + hsize_t H5_ATTR_UNUSED *end) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); HDassert(start); HDassert(end); FUNC_LEAVE_NOAPI(FAIL) -} /* H5Sget_none_bounds() */ +} /* end H5Sget_none_bounds() */ /*-------------------------------------------------------------------------- NAME - H5S_none_offset + H5S__none_offset PURPOSE Gets the linear offset of the first element for the selection. USAGE - herr_t H5S_none_offset(space, offset) + herr_t H5S__none_offset(space, offset) const H5S_t *space; IN: Dataspace pointer of selection to query hsize_t *offset; OUT: Linear offset of first element in selection RETURNS @@ -610,15 +642,15 @@ H5S_none_bounds(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *start REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *offset) +H5S__none_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *offset) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); HDassert(offset); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_offset() */ +} /* end H5S__none_offset() */ /*-------------------------------------------------------------------------- @@ -651,11 +683,11 @@ H5S__none_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) /*-------------------------------------------------------------------------- NAME - H5S_none_is_contiguous + H5S__none_is_contiguous PURPOSE Check if a "none" selection is contiguous within the dataspace extent. USAGE - htri_t H5S_none_is_contiguous(space) + htri_t H5S__none_is_contiguous(space) H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -668,23 +700,23 @@ H5S__none_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_none_is_contiguous(const H5S_t H5_ATTR_UNUSED *space) +H5S__none_is_contiguous(const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); FUNC_LEAVE_NOAPI(FALSE) -} /* H5S_none_is_contiguous() */ +} /* end H5S__none_is_contiguous() */ /*-------------------------------------------------------------------------- NAME - H5S_none_is_single + H5S__none_is_single PURPOSE Check if a "none" selection is a single block within the dataspace extent. USAGE - htri_t H5S_none_is_single(space) + htri_t H5S__none_is_single(space) H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -697,23 +729,23 @@ H5S_none_is_contiguous(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_none_is_single(const H5S_t H5_ATTR_UNUSED *space) +H5S__none_is_single(const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); FUNC_LEAVE_NOAPI(FALSE) -} /* H5S_none_is_single() */ +} /* end H5S__none_is_single() */ /*-------------------------------------------------------------------------- NAME - H5S_none_is_regular + H5S__none_is_regular PURPOSE Check if a "none" selection is "regular" USAGE - htri_t H5S_none_is_regular(space) + htri_t H5S__none_is_regular(space) const H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -727,15 +759,15 @@ H5S_none_is_single(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_none_is_regular(const H5S_t H5_ATTR_UNUSED *space) +H5S__none_is_regular(const H5S_t H5_ATTR_UNUSED *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); FUNC_LEAVE_NOAPI(TRUE) -} /* H5S_none_is_regular() */ +} /* end H5S__none_is_regular() */ /*-------------------------------------------------------------------------- @@ -744,7 +776,7 @@ H5S_none_is_regular(const H5S_t H5_ATTR_UNUSED *space) PURPOSE Adjust an "none" selection by subtracting an offset USAGE - herr_t H5S_none_adjust_u(space, offset) + herr_t H5S__none_adjust_u(space, offset) H5S_t *space; IN/OUT: Pointer to dataspace to adjust const hsize_t *offset; IN: Offset to subtract RETURNS @@ -757,24 +789,24 @@ H5S_none_is_regular(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *offset) +H5S__none_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *offset) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); HDassert(offset); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_none_adjust_u() */ +} /* end H5S__none_adjust_u() */ /*------------------------------------------------------------------------- - * Function: H5S_none_project_scalar + * Function: H5S__none_project_scalar * * Purpose: Projects a 'none' selection into a scalar dataspace * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -782,25 +814,25 @@ H5S_none_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *off *------------------------------------------------------------------------- */ static herr_t -H5S_none_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *offset) +H5S__none_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSED *offset) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space && H5S_SEL_NONE == H5S_GET_SELECT_TYPE(space)); HDassert(offset); FUNC_LEAVE_NOAPI(FAIL) -} /* H5S_none_project_scalar() */ +} /* end H5S__none_project_scalar() */ /*------------------------------------------------------------------------- - * Function: H5S_none_project_simple + * Function: H5S__none_project_simple * * Purpose: Projects an 'none' selection onto/into a simple dataspace * of a different rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -808,11 +840,12 @@ H5S_none_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t H5_ATTR_UNUSE *------------------------------------------------------------------------- */ static herr_t -H5S_none_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset) +H5S__none_project_simple(const H5S_t H5_ATTR_UNUSED *base_space, + H5S_t *new_space, hsize_t H5_ATTR_UNUSED *offset) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(base_space && H5S_SEL_NONE == H5S_GET_SELECT_TYPE(base_space)); @@ -825,7 +858,7 @@ H5S_none_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offs done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_none_project_simple() */ +} /* end H5S__none_project_simple() */ /*-------------------------------------------------------------------------- @@ -867,7 +900,7 @@ H5S_select_none(H5S_t *space) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_none() */ +} /* end H5S_select_none() */ /*-------------------------------------------------------------------------- @@ -906,16 +939,16 @@ H5Sselect_none(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sselect_none() */ +} /* end H5Sselect_none() */ /*-------------------------------------------------------------------------- NAME - H5S_none_get_seq_list + H5S__none_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S_none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + herr_t H5S__none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) H5S_t *space; IN: Dataspace containing selection to use. unsigned flags; IN: Flags for extra information about operation H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last @@ -941,11 +974,11 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t H5_ATTR_UNUSED *iter, +H5S__none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t H5_ATTR_UNUSED *iter, size_t H5_ATTR_UNUSED maxseq, size_t H5_ATTR_UNUSED maxelem, size_t *nseq, size_t *nelem, hsize_t H5_ATTR_UNUSED *off, size_t H5_ATTR_UNUSED *len) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); @@ -964,5 +997,5 @@ H5S_none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED *nelem = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S_none_get_seq_list() */ +} /* end H5S__none_get_seq_list() */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 9ad97dc..1fbfa35 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -26,8 +26,12 @@ #ifndef _H5Spkg_H #define _H5Spkg_H +/* Get package's private header */ #include "H5Sprivate.h" +/* Other private headers needed by this file */ +#include "H5Oprivate.h" /* Object headers */ + /* Flags to indicate special dataspace features are active */ #define H5S_VALID_MAX 0x01 #define H5S_VALID_PERM 0x02 @@ -77,6 +81,7 @@ struct H5S_extent_t { /* * Dataspace selection information */ + /* Node in point selection list (typedef'd in H5Sprivate.h) */ struct H5S_pnt_node_t { hsize_t *pnt; /* Pointer to a selected point */ @@ -88,9 +93,9 @@ typedef struct { H5S_pnt_node_t *head; /* Pointer to head of point list */ } H5S_pnt_list_t; -/* Information about new-style hyperslab spans */ +/* Information about hyperslab spans */ -/* Information a particular hyperslab span */ +/* Information a particular hyperslab span (typedef'd in H5Sprivate.h) */ struct H5S_hyper_span_t { hsize_t low, high; /* Low & high bounds of span */ hsize_t nelem; /* Number of elements in span (only needed during I/O) */ @@ -217,9 +222,11 @@ struct H5S_t { /* Selection iteration methods */ /* Method to retrieve the current coordinates of iterator for current selection */ -typedef herr_t (*H5S_sel_iter_coords_func_t)(const H5S_sel_iter_t *iter, hsize_t *coords); +typedef herr_t (*H5S_sel_iter_coords_func_t)(const H5S_sel_iter_t *iter, + hsize_t *coords); /* Method to retrieve the current block of iterator for current selection */ -typedef herr_t (*H5S_sel_iter_block_func_t)(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end); +typedef herr_t (*H5S_sel_iter_block_func_t)(const H5S_sel_iter_t *iter, + hsize_t *start, hsize_t *end); /* Method to determine number of elements left in iterator for current selection */ typedef hsize_t (*H5S_sel_iter_nelmts_func_t)(const H5S_sel_iter_t *iter); /* Method to determine if there are more blocks left in the current selection */ @@ -269,8 +276,8 @@ H5_DLLVAR const H5S_select_class_t H5S_sel_point[1]; H5_DLLVAR const unsigned H5O_sdspace_ver_bounds[H5F_LIBVER_NBOUNDS]; /* Extent functions */ -H5_DLL herr_t H5S_extent_release(H5S_extent_t *extent); -H5_DLL herr_t H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, +H5_DLL herr_t H5S__extent_release(H5S_extent_t *extent); +H5_DLL herr_t H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max); /* Operations on selections */ @@ -280,8 +287,8 @@ H5_DLL herr_t H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space); /* Testing functions */ #ifdef H5S_TESTING -H5_DLL htri_t H5S_select_shape_same_test(hid_t sid1, hid_t sid2); -H5_DLL htri_t H5S_get_rebuild_status_test(hid_t space_id); +H5_DLL htri_t H5S__select_shape_same_test(hid_t sid1, hid_t sid2); +H5_DLL htri_t H5S__get_rebuild_status_test(hid_t space_id); #endif /* H5S_TESTING */ #endif /*_H5Spkg_H*/ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index aea7d5c..11cf448 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -18,87 +18,124 @@ * Purpose: Point selection dataspace I/O functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5MMprivate.h" /* Memory Management functions */ -#include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + -/* Static function prototypes */ +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ /* Selection callbacks */ -static herr_t H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S_point_get_seq_list(const H5S_t *space, unsigned flags, +static herr_t H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); +static herr_t H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); -static herr_t H5S_point_release(H5S_t *space); -static htri_t H5S_point_is_valid(const H5S_t *space); -static hssize_t H5S_point_serial_size(const H5S_t *space); -static herr_t H5S_point_serialize(const H5S_t *space, uint8_t **p); -static herr_t H5S_point_deserialize(H5S_t *space, uint32_t version, uint8_t flags, +static herr_t H5S__point_release(H5S_t *space); +static htri_t H5S__point_is_valid(const H5S_t *space); +static hssize_t H5S__point_serial_size(const H5S_t *space); +static herr_t H5S__point_serialize(const H5S_t *space, uint8_t **p); +static herr_t H5S__point_deserialize(H5S_t *space, uint32_t version, uint8_t flags, const uint8_t **p); -static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); -static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off); +static herr_t H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +static herr_t H5S__point_offset(const H5S_t *space, hsize_t *off); static int H5S__point_unlim_dim(const H5S_t *space); -static htri_t H5S_point_is_contiguous(const H5S_t *space); -static htri_t H5S_point_is_single(const H5S_t *space); -static htri_t H5S_point_is_regular(const H5S_t *space); -static herr_t H5S_point_adjust_u(H5S_t *space, const hsize_t *offset); -static herr_t H5S_point_project_scalar(const H5S_t *space, hsize_t *offset); -static herr_t H5S_point_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static htri_t H5S__point_is_contiguous(const H5S_t *space); +static htri_t H5S__point_is_single(const H5S_t *space); +static htri_t H5S__point_is_regular(const H5S_t *space); +static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset); +static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset); +static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space, + hsize_t *offset); +static herr_t H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ -static herr_t H5S_point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); -static herr_t H5S_point_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end); -static hsize_t H5S_point_iter_nelmts(const H5S_sel_iter_t *iter); -static htri_t H5S_point_iter_has_next_block(const H5S_sel_iter_t *iter); -static herr_t H5S_point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -static herr_t H5S_point_iter_next_block(H5S_sel_iter_t *sel_iter); -static herr_t H5S_point_iter_release(H5S_sel_iter_t *sel_iter); +static herr_t H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); +static herr_t H5S__point_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, + hsize_t *end); +static hsize_t H5S__point_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S__point_iter_has_next_block(const H5S_sel_iter_t *iter); +static herr_t H5S__point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S__point_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__point_iter_release(H5S_sel_iter_t *sel_iter); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ /* Selection properties for point selections */ const H5S_select_class_t H5S_sel_point[1] = {{ H5S_SEL_POINTS, /* Methods on selection */ - H5S_point_copy, - H5S_point_get_seq_list, - H5S_point_release, - H5S_point_is_valid, - H5S_point_serial_size, - H5S_point_serialize, - H5S_point_deserialize, - H5S_point_bounds, - H5S_point_offset, + H5S__point_copy, + H5S__point_get_seq_list, + H5S__point_release, + H5S__point_is_valid, + H5S__point_serial_size, + H5S__point_serialize, + H5S__point_deserialize, + H5S__point_bounds, + H5S__point_offset, H5S__point_unlim_dim, NULL, - H5S_point_is_contiguous, - H5S_point_is_single, - H5S_point_is_regular, - H5S_point_adjust_u, - H5S_point_project_scalar, - H5S_point_project_simple, - H5S_point_iter_init, + H5S__point_is_contiguous, + H5S__point_is_single, + H5S__point_is_regular, + H5S__point_adjust_u, + H5S__point_project_scalar, + H5S__point_project_simple, + H5S__point_iter_init, }}; + +/*******************/ +/* Local Variables */ +/*******************/ + /* Iteration properties for point selections */ static const H5S_sel_iter_class_t H5S_sel_iter_point[1] = {{ H5S_SEL_POINTS, /* Methods on selection iterator */ - H5S_point_iter_coords, - H5S_point_iter_block, - H5S_point_iter_nelmts, - H5S_point_iter_has_next_block, - H5S_point_iter_next, - H5S_point_iter_next_block, - H5S_point_iter_release, + H5S__point_iter_coords, + H5S__point_iter_block, + H5S__point_iter_nelmts, + H5S__point_iter_has_next_block, + H5S__point_iter_next, + H5S__point_iter_next_block, + H5S__point_iter_release, }}; /* Declare a free list to manage the H5S_pnt_node_t struct */ @@ -107,93 +144,88 @@ H5FL_DEFINE_STATIC(H5S_pnt_node_t); /* Declare a free list to manage the H5S_pnt_list_t struct */ H5FL_DEFINE_STATIC(H5S_pnt_list_t); + /*------------------------------------------------------------------------- - * Function: H5S_point_iter_init + * Function: H5S__point_iter_init * * Purpose: Initializes iteration information for point selection. * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) +H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space && H5S_SEL_POINTS==H5S_GET_SELECT_TYPE(space)); + HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space)); HDassert(iter); /* Initialize the number of points to iterate over */ - iter->elmt_left=space->select.num_elem; + iter->elmt_left = space->select.num_elem; /* Start at the head of the list of points */ iter->u.pnt.curr=space->select.sel_info.pnt_lst->head; /* Initialize type of selection iterator */ - iter->type=H5S_sel_iter_point; + iter->type = H5S_sel_iter_point; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_init() */ +} /* end H5S__point_iter_init() */ /*------------------------------------------------------------------------- - * Function: H5S_point_iter_coords + * Function: H5S__point_iter_coords * * Purpose: Retrieve the current coordinates of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Tuesday, April 22, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_point_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords) +H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); HDassert(coords); /* Copy the offset of the current point */ - HDmemcpy(coords,iter->u.pnt.curr->pnt,sizeof(hsize_t)*iter->rank); + HDmemcpy(coords, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_coords() */ +} /* end H5S__point_iter_coords() */ /*------------------------------------------------------------------------- - * Function: H5S_point_iter_block + * Function: H5S__point_iter_block * * Purpose: Retrieve the current block of iterator for current * selection * - * Return: non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * * Programmer: Quincey Koziol * Monday, June 2, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5S_point_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) +H5S__point_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); @@ -201,46 +233,44 @@ H5S_point_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) HDassert(end); /* Copy the current point as a block */ - HDmemcpy(start,iter->u.pnt.curr->pnt,sizeof(hsize_t)*iter->rank); - HDmemcpy(end,iter->u.pnt.curr->pnt,sizeof(hsize_t)*iter->rank); + HDmemcpy(start, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); + HDmemcpy(end, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_block() */ +} /* end H5S__point_iter_block() */ /*------------------------------------------------------------------------- - * Function: H5S_point_iter_nelmts + * Function: H5S__point_iter_nelmts * * Purpose: Return number of elements left to process in iterator * - * Return: non-negative number of elements on success, zero on failure + * Return: Non-negative number of elements on success, zero on failure * * Programmer: Quincey Koziol * Tuesday, June 16, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ static hsize_t -H5S_point_iter_nelmts (const H5S_sel_iter_t *iter) +H5S__point_iter_nelmts(const H5S_sel_iter_t *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(iter->elmt_left) -} /* H5S_point_iter_nelmts() */ +} /* end H5S__point_iter_nelmts() */ /*-------------------------------------------------------------------------- NAME - H5S_point_iter_has_next_block + H5S__point_iter_has_next_block PURPOSE Check if there is another block left in the current iterator USAGE - htri_t H5S_point_iter_has_next_block(iter) + htri_t H5S__point_iter_has_next_block(iter) const H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative (TRUE/FALSE) on success/Negative on failure @@ -252,31 +282,31 @@ H5S_point_iter_nelmts (const H5S_sel_iter_t *iter) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_point_iter_has_next_block(const H5S_sel_iter_t *iter) +H5S__point_iter_has_next_block(const H5S_sel_iter_t *iter) { - htri_t ret_value=TRUE; /* Return value */ + htri_t ret_value = TRUE; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); /* Check if there is another point in the list */ - if(iter->u.pnt.curr->next==NULL) + if(iter->u.pnt.curr->next == NULL) HGOTO_DONE(FALSE); done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_iter_has_next_block() */ +} /* end H5S__point_iter_has_next_block() */ /*-------------------------------------------------------------------------- NAME - H5S_point_iter_next + H5S__point_iter_next PURPOSE Increment selection iterator USAGE - herr_t H5S_point_iter_next(iter, nelem) + herr_t H5S__point_iter_next(iter, nelem) H5S_sel_iter_t *iter; IN: Pointer to selection iterator size_t nelem; IN: Number of elements to advance by RETURNS @@ -289,31 +319,31 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_iter_next(H5S_sel_iter_t *iter, size_t nelem) +H5S__point_iter_next(H5S_sel_iter_t *iter, size_t nelem) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); - HDassert(nelem>0); + HDassert(nelem > 0); /* Increment the iterator */ - while(nelem>0) { - iter->u.pnt.curr=iter->u.pnt.curr->next; + while(nelem > 0) { + iter->u.pnt.curr = iter->u.pnt.curr->next; nelem--; } /* end while */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_next() */ +} /* end H5S__point_iter_next() */ /*-------------------------------------------------------------------------- NAME - H5S_point_iter_next_block + H5S__point_iter_next_block PURPOSE Increment selection iterator to next block USAGE - herr_t H5S_point_iter_next_block(iter) + herr_t H5S__point_iter_next_block(iter) H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative on success/Negative on failure @@ -325,27 +355,27 @@ H5S_point_iter_next(H5S_sel_iter_t *iter, size_t nelem) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_iter_next_block(H5S_sel_iter_t *iter) +H5S__point_iter_next_block(H5S_sel_iter_t *iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); /* Increment the iterator */ - iter->u.pnt.curr=iter->u.pnt.curr->next; + iter->u.pnt.curr = iter->u.pnt.curr->next; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_next_block() */ +} /* end H5S__point_iter_next_block() */ /*-------------------------------------------------------------------------- NAME - H5S_point_iter_release + H5S__point_iter_release PURPOSE Release point selection iterator information for a dataspace USAGE - herr_t H5S_point_iter_release(iter) + herr_t H5S__point_iter_release(iter) H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS Non-negative on success/Negative on failure @@ -357,24 +387,24 @@ H5S_point_iter_next_block(H5S_sel_iter_t *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_iter_release (H5S_sel_iter_t H5_ATTR_UNUSED * iter) +H5S__point_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED * iter) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(iter); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_iter_release() */ +} /* end H5S__point_iter_release() */ /*-------------------------------------------------------------------------- NAME - H5S_point_add + H5S__point_add PURPOSE Add a series of elements to a point selection USAGE - herr_t H5S_point_add(space, num_elem, coord) + herr_t H5S__point_add(space, num_elem, coord) H5S_t *space; IN: Dataspace of selection to modify size_t num_elem; IN: Number of elements in COORD array. const hsize_t *coord[]; IN: The location of each element selected @@ -388,14 +418,15 @@ H5S_point_iter_release (H5S_sel_iter_t H5_ATTR_UNUSED * iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *coord) +H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *coord) { H5S_pnt_node_t *top = NULL, *curr = NULL, *new_node = NULL; /* Point selection nodes */ unsigned u; /* Counter */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC + /* Sanity checks */ HDassert(space); HDassert(num_elem > 0); HDassert(coord); @@ -469,16 +500,16 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_add() */ +} /* end H5S__point_add() */ /*-------------------------------------------------------------------------- NAME - H5S_point_release + H5S__point_release PURPOSE Release point selection information for a dataspace USAGE - herr_t H5S_point_release(space) + herr_t H5S__point_release(space) H5S_t *space; IN: Pointer to dataspace RETURNS Non-negative on success/Negative on failure @@ -490,7 +521,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_release (H5S_t *space) +H5S__point_release(H5S_t *space) { H5S_pnt_node_t *curr, *next; /* Point selection nodes */ @@ -515,7 +546,7 @@ H5S_point_release (H5S_t *space) space->select.num_elem = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_release() */ +} /* end H5S__point_release() */ /*-------------------------------------------------------------------------- @@ -539,10 +570,7 @@ H5S_point_release (H5S_t *space) array elements are iterated through when I/O is performed. Duplicate coordinates are not checked for. The selection operator, OP, determines how the new selection is to be combined with the existing selection for - the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces - the existing selection with the one defined in this call. When operators - other than H5S_SELECT_SET are used to combine a new selection with an - existing selection, the selection ordering is reset to 'C' array ordering. + the dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -552,9 +580,9 @@ herr_t H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *coord) { - herr_t ret_value = SUCCEED; /* return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) /* Check args */ HDassert(space); @@ -573,7 +601,7 @@ H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information") /* Add points to selection */ - if(H5S_point_add(space, op, num_elem, coord) < 0) + if(H5S__point_add(space, op, num_elem, coord) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert elements") /* Set selection type */ @@ -581,18 +609,19 @@ H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem, done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_elements() */ +} /* end H5S_select_elements() */ /*-------------------------------------------------------------------------- NAME - H5S_point_copy + H5S__point_copy PURPOSE Copy a selection from one dataspace to another USAGE - herr_t H5S_point_copy(dst, src) + herr_t H5S__point_copy(dst, src, share_selection) H5S_t *dst; OUT: Pointer to the destination dataspace H5S_t *src; IN: Pointer to the source dataspace + hbool_t share_selection; IN: Whether to share the selection between the dataspaces RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -604,12 +633,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection) +H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection) { H5S_pnt_node_t *curr, *new_node, *new_tail; /* Point information nodes */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC HDassert(src); HDassert(dst); @@ -660,18 +689,18 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_point_copy() */ +} /* end H5S__point_copy() */ /*-------------------------------------------------------------------------- NAME - H5S_point_is_valid + H5S__point_is_valid PURPOSE Check whether the selection fits within the extent, with the current offset defined. USAGE - htri_t H5S_point_is_valid(space); - H5S_t *space; IN: Dataspace pointer to query + htri_t H5S__point_is_valid(space); + const H5S_t *space; IN: Dataspace pointer to query RETURNS TRUE if the selection fits within the extent, FALSE if it does not and Negative on an error. @@ -684,13 +713,13 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_point_is_valid (const H5S_t *space) +H5S__point_is_valid(const H5S_t *space) { H5S_pnt_node_t *curr; /* Point information nodes */ unsigned u; /* Counter */ htri_t ret_value = TRUE; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); @@ -711,7 +740,7 @@ H5S_point_is_valid (const H5S_t *space) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_point_is_valid() */ +} /* end H5S__point_is_valid() */ /*-------------------------------------------------------------------------- @@ -750,18 +779,18 @@ H5Sget_select_elem_npoints(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sget_select_elem_npoints() */ +} /* end H5Sget_select_elem_npoints() */ /*-------------------------------------------------------------------------- NAME - H5S_point_serial_size + H5S__point_serial_size PURPOSE Determine the number of bytes needed to store the serialized point selection information. USAGE - hssize_t H5S_point_serial_size(space) - H5S_t *space; IN: Dataspace pointer to query + hssize_t H5S__point_serial_size(space) + const H5S_t *space; IN: Dataspace pointer to query RETURNS The number of bytes required on success, negative on an error. DESCRIPTION @@ -773,11 +802,11 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static hssize_t -H5S_point_serial_size (const H5S_t *space) +H5S__point_serial_size(const H5S_t *space) { hssize_t ret_value = -1; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); @@ -792,16 +821,16 @@ H5S_point_serial_size (const H5S_t *space) ret_value += (4 * space->extent.rank) * (hssize_t)H5S_GET_SELECT_NPOINTS(space); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_point_serial_size() */ +} /* end H5S__point_serial_size() */ /*-------------------------------------------------------------------------- NAME - H5S_point_serialize + H5S__point_serialize PURPOSE Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_point_serialize(space, p) + herr_t H5S__point_serialize(space, p) const H5S_t *space; IN: Dataspace with selection to serialize uint8_t **p; OUT: Pointer to buffer to put serialized selection. Will be advanced to end of @@ -817,15 +846,15 @@ H5S_point_serial_size (const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_serialize (const H5S_t *space, uint8_t **p) +H5S__point_serialize(const H5S_t *space, uint8_t **p) { H5S_pnt_node_t *curr; /* Point information nodes */ uint8_t *pp = (*p); /* Local pointer for decoding */ - uint8_t *lenp; /* pointer to length location for later storage */ - uint32_t len=0; /* number of bytes used */ - unsigned u; /* local counting variable */ + uint8_t *lenp; /* Pointer to length location for later storage */ + uint32_t len = 0; /* Number of bytes used */ + unsigned u; /* Local counting variable */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); @@ -841,23 +870,23 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) /* Encode number of dimensions */ UINT32ENCODE(pp, (uint32_t)space->extent.rank); - len+=4; + len += 4; /* Encode number of elements */ UINT32ENCODE(pp, (uint32_t)space->select.num_elem); - len+=4; + len += 4; /* Encode each point in selection */ - curr=space->select.sel_info.pnt_lst->head; - while(curr!=NULL) { + curr = space->select.sel_info.pnt_lst->head; + while(curr != NULL) { /* Add 4 bytes times the rank for each element selected */ - len+=4*space->extent.rank; + len += 4 * space->extent.rank; /* Encode each point */ - for(u=0; uextent.rank; u++) + for(u = 0; u < space->extent.rank; u++) UINT32ENCODE(pp, (uint32_t)curr->pnt[u]); - curr=curr->next; + curr = curr->next; } /* end while */ /* Encode length */ @@ -867,16 +896,16 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) *p = pp; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_serialize() */ +} /* end H5S__point_serialize() */ /*-------------------------------------------------------------------------- NAME - H5S_point_deserialize + H5S__point_deserialize PURPOSE Deserialize the current selection from a user-provided buffer. USAGE - herr_t H5S_point_deserialize(space, p) + herr_t H5S__point_deserialize(space, p) H5S_t *space; IN/OUT: Dataspace pointer to place selection into uint32_t version IN: Selection version @@ -895,10 +924,9 @@ H5S_point_serialize (const H5S_t *space, uint8_t **p) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, +H5S__point_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ATTR_UNUSED flags, const uint8_t **p) { - H5S_seloper_t op = H5S_SELECT_SET; /* Selection operation */ hsize_t *coord = NULL, *tcoord; /* Pointer to array of elements */ const uint8_t *pp = (*p); /* Local pointer for decoding */ size_t num_elem = 0; /* Number of elements in selection */ @@ -906,7 +934,7 @@ H5S_point_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ unsigned i, j; /* local counting variables */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -928,7 +956,7 @@ H5S_point_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t H5_ UINT32DECODE(pp, *tcoord); /* Select points */ - if(H5S_select_elements(space, op, num_elem, (const hsize_t *)coord) < 0) + if(H5S_select_elements(space, H5S_SELECT_SET, num_elem, (const hsize_t *)coord) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") /* Update decoding pointer */ @@ -940,17 +968,17 @@ done: H5MM_xfree(coord); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_deserialize() */ +} /* end H5S__point_deserialize() */ /*-------------------------------------------------------------------------- NAME - H5S_get_select_elem_pointlist + H5S__get_select_elem_pointlist PURPOSE Get the list of element points currently selected USAGE - herr_t H5S_get_select_elem_pointlist(space, hsize_t *buf) - H5S_t *space; IN: Dataspace pointer of selection to query + herr_t H5S__get_select_elem_pointlist(space, hsize_t *buf) + const H5S_t *space; IN: Dataspace pointer of selection to query hsize_t startpoint; IN: Element point to start with hsize_t numpoints; IN: Number of element points to get hsize_t *buf; OUT: List of element points selected @@ -973,12 +1001,13 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoints, hsize_t *buf) +H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, + hsize_t numpoints, hsize_t *buf) { H5S_pnt_node_t *node; /* Point node */ unsigned rank; /* Dataspace rank */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); HDassert(buf); @@ -1004,7 +1033,7 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint } /* end while */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_get_select_elem_pointlist() */ +} /* end H5S__get_select_elem_pointlist() */ /*-------------------------------------------------------------------------- @@ -1054,20 +1083,20 @@ H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a point selection") - ret_value = H5S_get_select_elem_pointlist(space, startpoint, numpoints, buf); + ret_value = H5S__get_select_elem_pointlist(space, startpoint, numpoints, buf); done: FUNC_LEAVE_API(ret_value) -} /* H5Sget_select_elem_pointlist() */ +} /* end H5Sget_select_elem_pointlist() */ /*-------------------------------------------------------------------------- NAME - H5S_point_bounds + H5S__point_bounds PURPOSE Gets the bounding box containing the selection. USAGE - herr_t H5S_point_bounds(space, start, end) + herr_t H5S__point_bounds(space, start, end) H5S_t *space; IN: Dataspace pointer of selection to query hsize_t *start; OUT: Starting coordinate of bounding box hsize_t *end; OUT: Opposite coordinate of bounding box @@ -1088,14 +1117,14 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) +H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) { H5S_pnt_node_t *node; /* Point node */ unsigned rank; /* Dataspace rank */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity check */ HDassert(space); @@ -1129,16 +1158,16 @@ H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_bounds() */ +} /* end H5S__point_bounds() */ /*-------------------------------------------------------------------------- NAME - H5S_point_offset + H5S__point_offset PURPOSE Gets the linear offset of the first element for the selection. USAGE - herr_t H5S_point_offset(space, offset) + herr_t H5S__point_offset(space, offset) const H5S_t *space; IN: Dataspace pointer of selection to query hsize_t *offset; OUT: Linear offset of first element in selection RETURNS @@ -1153,7 +1182,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_offset(const H5S_t *space, hsize_t *offset) +H5S__point_offset(const H5S_t *space, hsize_t *offset) { const hsize_t *pnt; /* Pointer to a selected point's coordinates */ const hssize_t *sel_offset; /* Pointer to the selection's offset */ @@ -1162,7 +1191,7 @@ H5S_point_offset(const H5S_t *space, hsize_t *offset) int i; /* index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC HDassert(space); HDassert(offset); @@ -1193,7 +1222,7 @@ H5S_point_offset(const H5S_t *space, hsize_t *offset) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_offset() */ +} /* end H5S__point_offset() */ /*-------------------------------------------------------------------------- @@ -1227,11 +1256,11 @@ H5S__point_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) /*-------------------------------------------------------------------------- NAME - H5S_point_is_contiguous + H5S__point_is_contiguous PURPOSE Check if a point selection is contiguous within the dataspace extent. USAGE - htri_t H5S_point_is_contiguous(space) + htri_t H5S__point_is_contiguous(space) H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -1247,31 +1276,31 @@ H5S__point_unlim_dim(const H5S_t H5_ATTR_UNUSED *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_point_is_contiguous(const H5S_t *space) +H5S__point_is_contiguous(const H5S_t *space) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); /* One point is definitely contiguous */ - if(space->select.num_elem==1) - ret_value=TRUE; + if(space->select.num_elem == 1) + ret_value = TRUE; else /* More than one point might be contiguous, but it's complex to check and we don't need it right now */ - ret_value=FALSE; + ret_value = FALSE; FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_is_contiguous() */ +} /* end H5S__point_is_contiguous() */ /*-------------------------------------------------------------------------- NAME - H5S_point_is_single + H5S__point_is_single PURPOSE Check if a point selection is single within the dataspace extent. USAGE - htri_t H5S_point_is_single(space) + htri_t H5S__point_is_single(space) H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -1284,31 +1313,31 @@ H5S_point_is_contiguous(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_point_is_single(const H5S_t *space) +H5S__point_is_single(const H5S_t *space) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); /* One point is definitely 'single' :-) */ - if(space->select.num_elem==1) - ret_value=TRUE; + if(space->select.num_elem == 1) + ret_value = TRUE; else - ret_value=FALSE; + ret_value = FALSE; FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_is_single() */ +} /* end H5S__point_is_single() */ /*-------------------------------------------------------------------------- NAME - H5S_point_is_regular + H5S__point_is_regular PURPOSE Check if a point selection is "regular" USAGE - htri_t H5S_point_is_regular(space) + htri_t H5S__point_is_regular(space) const H5S_t *space; IN: Dataspace pointer to check RETURNS TRUE/FALSE/FAIL @@ -1324,32 +1353,32 @@ H5S_point_is_single(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S_point_is_regular(const H5S_t *space) +H5S__point_is_regular(const H5S_t *space) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); /* Only simple check for regular points for now... */ - if(space->select.num_elem==1) - ret_value=TRUE; + if(space->select.num_elem == 1) + ret_value = TRUE; else - ret_value=FALSE; + ret_value = FALSE; FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_is_regular() */ +} /* end H5S__point_is_regular() */ /*-------------------------------------------------------------------------- NAME - H5S_point_adjust_u + H5S__point_adjust_u PURPOSE Adjust a "point" selection by subtracting an offset USAGE - herr_t H5S_point_adjust_u(space, offset) + herr_t H5S__point_adjust_u(space, offset) H5S_t *space; IN/OUT: Pointer to dataspace to adjust const hsize_t *offset; IN: Offset to subtract RETURNS @@ -1362,12 +1391,12 @@ H5S_point_is_regular(const H5S_t *space) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_adjust_u(H5S_t *space, const hsize_t *offset) +H5S__point_adjust_u(H5S_t *space, const hsize_t *offset) { H5S_pnt_node_t *node; /* Point node */ unsigned rank; /* Dataspace rank */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(space); HDassert(offset); @@ -1392,16 +1421,16 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset) } /* end while */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_point_adjust_u() */ +} /* end H5S__point_adjust_u() */ /*------------------------------------------------------------------------- - * Function: H5S_point_project_scalar + * Function: H5S__point_project_scalar * * Purpose: Projects a single element point selection into a scalar * dataspace * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -1409,12 +1438,12 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset) *------------------------------------------------------------------------- */ static herr_t -H5S_point_project_scalar(const H5S_t *space, hsize_t *offset) +H5S__point_project_scalar(const H5S_t *space, hsize_t *offset) { const H5S_pnt_node_t *node; /* Point node */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space)); @@ -1428,20 +1457,20 @@ H5S_point_project_scalar(const H5S_t *space, hsize_t *offset) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "point selection of one element has more than one node!") /* Calculate offset of selection in projected buffer */ - *offset = H5VM_array_offset(space->extent.rank, space->extent.size, node->pnt); + *offset = H5VM_array_offset(space->extent.rank, space->extent.size, node->pnt); done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_project_scalar() */ +} /* end H5S__point_project_scalar() */ /*------------------------------------------------------------------------- - * Function: H5S_point_project_simple + * Function: H5S__point_project_simple * * Purpose: Projects a point selection onto/into a simple dataspace * of a different rank * - * Return: non-negative on success, negative on failure. + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol * Sunday, July 18, 2010 @@ -1449,7 +1478,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset) +H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset) { const H5S_pnt_node_t *base_node; /* Point node in base space */ H5S_pnt_node_t *new_node; /* Point node in new space */ @@ -1457,7 +1486,7 @@ H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off unsigned rank_diff; /* Difference in ranks between spaces */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(base_space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(base_space)); @@ -1482,7 +1511,7 @@ H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off /* Calculate offset of selection in projected buffer */ HDmemset(block, 0, sizeof(block)); HDmemcpy(block, base_space->select.sel_info.pnt_lst->head->pnt, sizeof(hsize_t) * rank_diff); - *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); + *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); /* Iterate through base space's point nodes, copying the point information */ base_node = base_space->select.sel_info.pnt_lst->head; @@ -1559,7 +1588,7 @@ H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_point_project_simple() */ +} /* end H5S__point_project_simple() */ /*-------------------------------------------------------------------------- @@ -1620,16 +1649,16 @@ H5Sselect_elements(hid_t spaceid, H5S_seloper_t op, size_t num_elem, done: FUNC_LEAVE_API(ret_value) -} /* H5Sselect_elements() */ +} /* end H5Sselect_elements() */ /*-------------------------------------------------------------------------- NAME - H5S_point_get_seq_list + H5S__point_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S_point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + herr_t H5S__point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) H5S_t *space; IN: Dataspace containing selection to use. unsigned flags; IN: Flags for extra information about operation H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last @@ -1655,14 +1684,14 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, +H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { size_t io_left; /* The number of bytes left in the selection */ size_t start_io_left; /* The initial number of bytes left in the selection */ H5S_pnt_node_t *node; /* Point node */ - hsize_t dims[H5O_LAYOUT_NDIMS]; /* Total size of memory buf */ + hsize_t dims[H5S_MAX_RANK]; /* Total size of memory buf */ int ndims; /* Dimensionality of space*/ hsize_t acc; /* Coordinate accumulator */ hsize_t loc; /* Coordinate offset */ @@ -1670,7 +1699,7 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, int i; /* Local index variable */ herr_t ret_value=SUCCEED; /* return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ HDassert(space); @@ -1758,5 +1787,5 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_point_get_seq_list() */ +} /* end H5S__point_get_seq_list() */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 32ac51a..24db889 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -17,9 +17,6 @@ #ifndef _H5Sprivate_H #define _H5Sprivate_H -/* Early typedefs to avoid circular dependencies */ -typedef struct H5S_t H5S_t; - /* Include package's public header */ #include "H5Spublic.h" @@ -30,7 +27,6 @@ typedef struct H5S_t H5S_t; #include "H5private.h" /* Generic Functions */ #include "H5Fprivate.h" /* Files */ #include "H5Gprivate.h" /* Groups */ -#include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ #include "H5Tprivate.h" /* Datatypes */ @@ -68,14 +64,14 @@ typedef struct { /* Hyperslab selection iteration container */ typedef struct { /* Common fields for all hyperslab selections */ - hsize_t off[H5S_MAX_RANK]; /* Offset in span node (used as position for regular hyperslabs) */ + hsize_t off[H5S_MAX_RANK]; /* Offset in span node (used as position for regular hyperslabs) */ unsigned iter_rank; /* Rank of iterator information */ /* (This should always be the same as the dataspace - * rank, except for regular hyperslab selections in - * which there are contiguous regions in the lower - * dimensions which have been "flattened" out + * rank, except for regular hyperslab selections in + * which there are contiguous regions in the lower + * dimensions that have been "flattened") */ - hbool_t diminfo_valid; /* Whether the dimension information is valid */ + hbool_t diminfo_valid; /* Whether the dimension information is valid */ /* "Flattened" regular hyperslab selection fields */ H5S_hyper_dim_t diminfo[H5S_MAX_RANK]; /* "Flattened" regular selection information */ @@ -196,6 +192,12 @@ typedef struct H5S_sel_iter_op_t { #define H5S_SELECT_RELEASE(S) (H5S_select_release(S)) #define H5S_SELECT_DESERIALIZE(S,BUF) (H5S_select_deserialize(S,BUF)) +/* Forward declaration of structs used below */ +struct H5O_t; +struct H5O_loc_t; + +/* Early typedef to avoid circular dependencies */ +typedef struct H5S_t H5S_t; /* Operations on dataspaces */ H5_DLL H5S_t *H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max); @@ -207,7 +209,7 @@ H5_DLL hbool_t H5S_has_extent(const H5S_t *ds); H5_DLL int H5S_get_simple_extent_ndims(const H5S_t *ds); H5_DLL int H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[]/*out*/, hsize_t max_dims[]/*out*/); -H5_DLL herr_t H5S_write(H5F_t *f, H5O_t *oh, unsigned update_flags, H5S_t *ds); +H5_DLL herr_t H5S_write(H5F_t *f, struct H5O_t *oh, unsigned update_flags, H5S_t *ds); H5_DLL herr_t H5S_append(H5F_t *f, struct H5O_t *oh, H5S_t *ds); H5_DLL H5S_t *H5S_read(const struct H5O_loc_t *loc); H5_DLL htri_t H5S_set_extent(H5S_t *space, const hsize_t *size); @@ -314,7 +316,7 @@ H5_DLL herr_t H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, /* out: */ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type, - hbool_t do_permute, + hbool_t do_permute, hsize_t **permute_map, hbool_t * is_permuted); #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Spublic.h b/src/H5Spublic.h index d7a5d29..b7129ca 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -79,23 +79,22 @@ typedef enum H5S_seloper_t { typedef enum { H5S_SEL_ERROR = -1, /* Error */ H5S_SEL_NONE = 0, /* Nothing selected */ - H5S_SEL_POINTS = 1, /* Sequence of points selected */ - H5S_SEL_HYPERSLABS = 2, /* "New-style" hyperslab selection defined */ + H5S_SEL_POINTS = 1, /* Points / elements selected */ + H5S_SEL_HYPERSLABS = 2, /* Hyperslab selected */ H5S_SEL_ALL = 3, /* Entire extent selected */ H5S_SEL_N /*THIS MUST BE LAST */ -}H5S_sel_type; +} H5S_sel_type; #ifdef __cplusplus extern "C" { #endif -/* Functions in H5S.c */ +/* Operations on dataspaces */ H5_DLL hid_t H5Screate(H5S_class_t type); H5_DLL hid_t H5Screate_simple(int rank, const hsize_t dims[], - const hsize_t maxdims[]); + const hsize_t maxdims[]); H5_DLL herr_t H5Sset_extent_simple(hid_t space_id, int rank, - const hsize_t dims[], - const hsize_t max[]); + const hsize_t dims[], const hsize_t max[]); H5_DLL hid_t H5Scopy(hid_t space_id); H5_DLL herr_t H5Sclose(hid_t space_id); H5_DLL herr_t H5Sencode(hid_t obj_id, void *buf, size_t *nalloc); @@ -103,51 +102,47 @@ H5_DLL hid_t H5Sdecode(const void *buf); H5_DLL hssize_t H5Sget_simple_extent_npoints(hid_t space_id); H5_DLL int H5Sget_simple_extent_ndims(hid_t space_id); H5_DLL int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[], - hsize_t maxdims[]); + hsize_t maxdims[]); H5_DLL htri_t H5Sis_simple(hid_t space_id); +H5_DLL H5S_class_t H5Sget_simple_extent_type(hid_t space_id); +H5_DLL herr_t H5Sset_extent_none(hid_t space_id); +H5_DLL herr_t H5Sextent_copy(hid_t dst_id,hid_t src_id); +H5_DLL htri_t H5Sextent_equal(hid_t sid1, hid_t sid2); + +/* Operations on dataspace selections */ +H5_DLL H5S_sel_type H5Sget_select_type(hid_t spaceid); H5_DLL hssize_t H5Sget_select_npoints(hid_t spaceid); +H5_DLL herr_t H5Sselect_copy(hid_t dst_id, hid_t src_id); +H5_DLL htri_t H5Sselect_valid(hid_t spaceid); +H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[], + hsize_t end[]); +H5_DLL herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset); +H5_DLL herr_t H5Sselect_all(hid_t spaceid); +H5_DLL herr_t H5Sselect_none(hid_t spaceid); +H5_DLL herr_t H5Sselect_elements(hid_t space_id, H5S_seloper_t op, + size_t num_elem, const hsize_t *coord); +H5_DLL hssize_t H5Sget_select_elem_npoints(hid_t spaceid); +H5_DLL herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, + hsize_t numpoints, hsize_t buf[/*numpoints*/]); H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, - const hsize_t start[], - const hsize_t _stride[], - const hsize_t count[], - const hsize_t _block[]); + const hsize_t start[], const hsize_t _stride[], const hsize_t count[], + const hsize_t _block[]); /* #define NEW_HYPERSLAB_API */ /* Note that these haven't been working for a while and were never * publicly released - QAK */ #ifdef NEW_HYPERSLAB_API H5_DLL hid_t H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, - const hsize_t start[], - const hsize_t _stride[], - const hsize_t count[], - const hsize_t _block[]); -H5_DLL herr_t H5Sselect_select(hid_t space1_id, H5S_seloper_t op, - hid_t space2_id); -H5_DLL hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op, - hid_t space2_id); + const hsize_t start[], const hsize_t _stride[], const hsize_t count[], + const hsize_t _block[]); +H5_DLL herr_t H5Sselect_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id); +H5_DLL hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id); #endif /* NEW_HYPERSLAB_API */ -H5_DLL herr_t H5Sselect_elements(hid_t space_id, H5S_seloper_t op, - size_t num_elem, const hsize_t *coord); -H5_DLL H5S_class_t H5Sget_simple_extent_type(hid_t space_id); -H5_DLL herr_t H5Sset_extent_none(hid_t space_id); -H5_DLL herr_t H5Sextent_copy(hid_t dst_id,hid_t src_id); -H5_DLL htri_t H5Sextent_equal(hid_t sid1, hid_t sid2); -H5_DLL herr_t H5Sselect_copy(hid_t dst_id, hid_t src_id); -H5_DLL herr_t H5Sselect_all(hid_t spaceid); -H5_DLL herr_t H5Sselect_none(hid_t spaceid); -H5_DLL herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset); -H5_DLL htri_t H5Sselect_valid(hid_t spaceid); H5_DLL htri_t H5Sis_regular_hyperslab(hid_t spaceid); H5_DLL htri_t H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[], hsize_t stride[], hsize_t count[], hsize_t block[]); H5_DLL hssize_t H5Sget_select_hyper_nblocks(hid_t spaceid); -H5_DLL hssize_t H5Sget_select_elem_npoints(hid_t spaceid); H5_DLL herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, hsize_t numblocks, hsize_t buf[/*numblocks*/]); -H5_DLL herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, - hsize_t numpoints, hsize_t buf[/*numpoints*/]); -H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[], - hsize_t end[]); -H5_DLL H5S_sel_type H5Sget_select_type(hid_t spaceid); #ifdef __cplusplus } diff --git a/src/H5Sselect.c b/src/H5Sselect.c index dd656b1..4d7fc4f 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -17,9 +17,16 @@ * Purpose: Dataspace selection functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ @@ -27,16 +34,40 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Spkg.h" /* Dataspaces */ -#include "H5VMprivate.h" /* Vector and array functions */ -#include "H5WBprivate.h" /* Wrapped Buffers */ +#include "H5VMprivate.h" /* Vector and array functions */ + + +/****************/ +/* Local Macros */ +/****************/ + + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ -/* Local functions */ #ifdef LATER static herr_t H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end); static htri_t H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter); static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter); #endif /* LATER */ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + /* Declare a free list to manage the H5S_sel_iter_t struct */ H5FL_DEFINE(H5S_sel_iter_t); @@ -47,6 +78,11 @@ H5FL_SEQ_EXTERN(size_t); H5FL_SEQ_EXTERN(hsize_t); +/*******************/ +/* Local Variables */ +/*******************/ + + /*-------------------------------------------------------------------------- NAME @@ -78,13 +114,56 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset) HDassert(offset); /* Copy the offset over */ - HDmemcpy(space->select.offset, offset, sizeof(hssize_t)*space->extent.rank); + HDmemcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank); /* Indicate that the offset was changed */ space->select.offset_changed = TRUE; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S_select_offset() */ +} /* end H5S_select_offset() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Soffset_simple + PURPOSE + Changes the offset of a selection within a simple dataspace extent + USAGE + herr_t H5Soffset_simple(space_id, offset) + hid_t space_id; IN: Dataspace object to reset + const hssize_t *offset; IN: Offset to position the selection at + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function creates an offset for the selection within an extent, allowing + the same shaped selection to be moved to different locations within a + dataspace without requiring it to be re-defined. +--------------------------------------------------------------------------*/ +herr_t +H5Soffset_simple(hid_t space_id, const hssize_t *offset) +{ + H5S_t *space; /* Dataspace to query */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Hs", space_id, offset); + + /* Check args */ + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace") + if(space->extent.rank == 0 || (H5S_GET_EXTENT_TYPE(space) == H5S_SCALAR + || H5S_GET_EXTENT_TYPE(space) == H5S_NULL)) + HGOTO_ERROR(H5E_ATOM, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace") + if(offset == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no offset specified") + + /* Set the selection offset */ + if(H5S_select_offset(space, offset) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Soffset_simple() */ /*-------------------------------------------------------------------------- @@ -139,9 +218,10 @@ done: PURPOSE Copy a selection from one dataspace to another USAGE - herr_t H5S_select_copy(dst, src) + herr_t H5S_select_copy(dst, src, share_selection) H5S_t *dst; OUT: Pointer to the destination dataspace H5S_t *src; IN: Pointer to the source dataspace + hbool_t; IN: Whether to share the selection between the dataspaces RETURNS Non-negative on success/Negative on failure DESCRIPTION @@ -177,7 +257,7 @@ H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_copy() */ +} /* end H5S_select_copy() */ /*------------------------------------------------------------------------- @@ -211,7 +291,7 @@ H5S_select_release(H5S_t *ds) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_release() */ +} /* end H5S_select_release() */ /*------------------------------------------------------------------------- @@ -278,10 +358,10 @@ H5S_select_serial_size(const H5S_t *space) HDassert(space); /* Call the selection type's serial_size function */ - ret_value=(*space->select.type->serial_size)(space); + ret_value = (*space->select.type->serial_size)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_serial_size() */ +} /* end H5S_select_serial_size() */ /*-------------------------------------------------------------------------- @@ -311,7 +391,7 @@ H5S_select_serial_size(const H5S_t *space) herr_t H5S_select_serialize(const H5S_t *space, uint8_t **p) { - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -319,10 +399,10 @@ H5S_select_serialize(const H5S_t *space, uint8_t **p) HDassert(p); /* Call the selection type's serialize function */ - ret_value=(*space->select.type->serialize)(space,p); + ret_value = (*space->select.type->serialize)(space, p); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_serialize() */ +} /* end H5S_select_serialize() */ /*-------------------------------------------------------------------------- @@ -359,7 +439,7 @@ H5Sget_select_npoints(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sget_select_npoints() */ +} /* H5Sget_select_npoints() */ /*-------------------------------------------------------------------------- @@ -382,7 +462,7 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -hssize_t +H5_ATTR_PURE hssize_t H5S_get_select_npoints(const H5S_t *space) { FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -391,7 +471,7 @@ H5S_get_select_npoints(const H5S_t *space) HDassert(space); FUNC_LEAVE_NOAPI((hssize_t)space->select.num_elem) -} /* H5S_get_select_npoints() */ +} /* end H5S_get_select_npoints() */ /*-------------------------------------------------------------------------- @@ -413,8 +493,6 @@ H5S_get_select_npoints(const H5S_t *space) COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG - Christian Chilan 01/17/2007 - Changed the error return value from 0 to FAIL. --------------------------------------------------------------------------*/ htri_t H5Sselect_valid(hid_t spaceid) @@ -433,7 +511,7 @@ H5Sselect_valid(hid_t spaceid) done: FUNC_LEAVE_API(ret_value) -} /* H5Sselect_valid() */ +} /* end H5Sselect_valid() */ /*-------------------------------------------------------------------------- @@ -471,7 +549,7 @@ H5S_select_valid(const H5S_t *space) ret_value = (*space->select.type->is_valid)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_valid() */ +} /* end H5S_select_valid() */ /*-------------------------------------------------------------------------- @@ -584,7 +662,7 @@ H5S_select_deserialize(H5S_t **space, const uint8_t **p) default: break; - } + } /* end switch */ if(ret_value < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection") @@ -599,7 +677,7 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace") FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_deserialize() */ +} /* end H5S_select_deserialize() */ /*-------------------------------------------------------------------------- @@ -651,7 +729,7 @@ H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[]) done: FUNC_LEAVE_API(ret_value) -} /* H5Sget_select_bounds() */ +} /* end H5Sget_select_bounds() */ /*-------------------------------------------------------------------------- @@ -693,10 +771,10 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) HDassert(start); HDassert(end); - ret_value = (*space->select.type->bounds)(space,start,end); + ret_value = (*space->select.type->bounds)(space, start, end); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_get_select_bounds() */ +} /* end H5S_get_select_bounds() */ /*-------------------------------------------------------------------------- @@ -736,7 +814,7 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *offset) ret_value = (*space->select.type->offset)(space, offset); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_get_select_offset() */ +} /* end H5S_get_select_offset() */ /*-------------------------------------------------------------------------- @@ -774,7 +852,7 @@ H5S_get_select_unlim_dim(const H5S_t *space) ret_value = (*space->select.type->unlim_dim)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_get_select_unlim_dim() */ +} /* end H5S_get_select_unlim_dim() */ /*-------------------------------------------------------------------------- @@ -819,7 +897,7 @@ H5S_get_select_num_elem_non_unlim(const H5S_t *space, done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_get_select_unlim_dim() */ +} /* end H5S_get_select_unlim_dim() */ /*-------------------------------------------------------------------------- @@ -856,7 +934,7 @@ H5S_select_is_contiguous(const H5S_t *space) ret_value = (*space->select.type->is_contiguous)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_is_contiguous() */ +} /* end H5S_select_is_contiguous() */ /*-------------------------------------------------------------------------- @@ -893,7 +971,7 @@ H5S_select_is_single(const H5S_t *space) ret_value = (*space->select.type->is_single)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_is_single() */ +} /* end H5S_select_is_single() */ /*-------------------------------------------------------------------------- @@ -930,7 +1008,7 @@ H5S_select_is_regular(const H5S_t *space) ret_value = (*space->select.type->is_regular)(space); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_is_regular() */ +} /* end H5S_select_is_regular() */ /*-------------------------------------------------------------------------- @@ -968,7 +1046,7 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset) ret_value = (*space->select.type->adjust_u)(space, offset); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_adjust_u() */ +} /* end H5S_select_adjust_u() */ /*-------------------------------------------------------------------------- @@ -1007,7 +1085,7 @@ H5S_select_project_scalar(const H5S_t *space, hsize_t *offset) ret_value = (*space->select.type->project_scalar)(space, offset); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_project_scalar() */ +} /* end H5S_select_project_scalar() */ /*-------------------------------------------------------------------------- @@ -1048,7 +1126,7 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset) ret_value = (*space->select.type->project_simple)(space, new_space, offset); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_project_simple() */ +} /* end H5S_select_project_simple() */ /*-------------------------------------------------------------------------- @@ -1098,7 +1176,7 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s HDassert(sel_iter->type); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_init() */ +} /* end H5S_select_iter_init() */ /*-------------------------------------------------------------------------- @@ -1135,10 +1213,10 @@ H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords) HDassert(coords); /* Call iter_coords routine for selection type */ - ret_value = (*sel_iter->type->iter_coords)(sel_iter,coords); + ret_value = (*sel_iter->type->iter_coords)(sel_iter, coords); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_coords() */ +} /* end H5S_select_iter_coords() */ #ifdef LATER @@ -1170,7 +1248,7 @@ H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) { herr_t ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR /* Check args */ HDassert(iter); @@ -1178,10 +1256,10 @@ H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) HDassert(end); /* Call iter_block routine for selection type */ - ret_value = (*iter->type->iter_block)(iter,start,end); + ret_value = (*iter->type->iter_block)(iter, start, end); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_block() */ +} /* end H5S_select_iter_block() */ #endif /* LATER */ @@ -1219,7 +1297,7 @@ H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter) ret_value = (*sel_iter->type->iter_nelmts)(sel_iter); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_nelmts() */ +} /* end H5S_select_iter_nelmts() */ #ifdef LATER @@ -1249,7 +1327,7 @@ H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter) { herr_t ret_value; /* return value */ - FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR /* Check args */ HDassert(iter); @@ -1258,7 +1336,7 @@ H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter) ret_value = (*iter->type->iter_has_next_block)(iter); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_has_next_block() */ +} /* end H5S_select_iter_has_next_block() */ #endif /* LATER */ @@ -1296,13 +1374,13 @@ H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem) HDassert(nelem>0); /* Call iter_next routine for selection type */ - ret_value = (*iter->type->iter_next)(iter,nelem); + ret_value = (*iter->type->iter_next)(iter, nelem); /* Decrement the number of elements left in selection */ iter->elmt_left-=nelem; FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_next() */ +} /* end H5S_select_iter_next() */ #ifdef LATER @@ -1343,7 +1421,7 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter) ret_value = (*iter->type->iter_next_block)(iter); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_next_block() */ +} /* end H5S_select_iter_next_block() */ #endif /* LATER */ @@ -1381,7 +1459,7 @@ H5S_select_iter_release(H5S_sel_iter_t *sel_iter) ret_value = (*sel_iter->type->iter_release)(sel_iter); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_iter_release() */ +} /* end H5S_select_iter_release() */ /*-------------------------------------------------------------------------- @@ -1421,7 +1499,7 @@ H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, hsize_t *off = NULL; /* Array to store sequence offsets */ size_t *len = NULL; /* Array to store sequence lengths */ hssize_t nelmts; /* Number of elements in selection */ - hsize_t space_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */ + hsize_t space_size[H5S_MAX_RANK]; /* Dataspace size */ size_t max_elem; /* Maximum number of elements allowed in sequences */ size_t elmt_size; /* Datatype size */ unsigned ndims; /* Number of dimensions in dataspace */ @@ -1495,7 +1573,7 @@ H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, /* Loop, while bytes left in sequence */ while(curr_len > 0 && user_ret == 0) { - hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */ + hsize_t coords[H5S_MAX_RANK]; /* Coordinates of element in dataspace */ hsize_t tmp_off; /* Temporary offset within sequence */ uint8_t *loc; /* Current element location in buffer */ int i; /* Local Index variable */ @@ -1558,7 +1636,7 @@ done: iter = H5FL_FREE(H5S_sel_iter_t, iter); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_iterate() */ +} /* end H5S_select_iterate() */ /*-------------------------------------------------------------------------- @@ -1594,7 +1672,7 @@ H5Sget_select_type(hid_t space_id) done: FUNC_LEAVE_API(ret_value) -} /* end H5Sget_select_type() */ +} /* end H5Sget_select_type() */ /*-------------------------------------------------------------------------- @@ -1616,7 +1694,7 @@ done: pattern, don't call it directly, use the appropriate macro defined in H5Sprivate.h. --------------------------------------------------------------------------*/ -H5S_sel_type +H5_ATTR_PURE H5S_sel_type H5S_get_select_type(const H5S_t *space) { H5S_sel_type ret_value = H5S_SEL_ERROR; /* Return value */ @@ -1627,10 +1705,10 @@ H5S_get_select_type(const H5S_t *space) HDassert(space); /* Set return value */ - ret_value=H5S_GET_SELECT_TYPE(space); + ret_value = H5S_GET_SELECT_TYPE(space); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_get_select_type() */ +} /* end H5S_get_select_type() */ /*-------------------------------------------------------------------------- @@ -1661,9 +1739,9 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) { H5S_sel_iter_t *iter_a = NULL; /* Selection a iteration info */ H5S_sel_iter_t *iter_b = NULL; /* Selection b iteration info */ - hbool_t iter_a_init = FALSE; /* Selection a iteration info has been initialized */ - hbool_t iter_b_init = FALSE; /* Selection b iteration info has been initialized */ - htri_t ret_value = TRUE; /* Return value */ + hbool_t iter_a_init = FALSE; /* Selection a iteration info has been initialized */ + hbool_t iter_b_init = FALSE; /* Selection b iteration info has been initialized */ + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1683,20 +1761,19 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) unsigned space_a_rank; /* Number of dimensions of dataspace A */ unsigned space_b_rank; /* Number of dimensions of dataspace B */ - /* need to be able to handle spaces of different rank: + /* Need to be able to handle spaces of different rank: * * To simplify logic, let space_a point to the element of the set - * {space1, space2} with the largest rank or space1 if the ranks + * {space1, space2} with the largest rank or space1 if the ranks * are identical. * * Similarly, let space_b point to the element of {space1, space2} * with the smallest rank, or space2 if they are identical. * - * Let: space_a_rank be the rank of space_a, + * Let: space_a_rank be the rank of space_a, * space_b_rank be the rank of space_b, - * delta_rank = space_a_rank - space_b_rank. * - * Set all this up below. + * Set all this up here. */ if(space1->extent.rank >= space2->extent.rank) { space_a = space1; @@ -1934,7 +2011,7 @@ done: iter_b = H5FL_FREE(H5S_sel_iter_t, iter_b); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_shape_same() */ +} /* end H5S_select_shape_same() */ /*-------------------------------------------------------------------------- @@ -1943,24 +2020,24 @@ done: PURPOSE Given a dataspace a of rank n with some selection, construct a new - dataspace b of rank m (m != n), with the selection in a being - topologically identical to that in b (as verified by + dataspace b of rank m (m != n), with the selection in a being + topologically identical to that in b (as verified by H5S_select_shape_same(). - This function exists, as some I/O code chokes on topologically - identical selections with different ranks. At least to begin + This function exists, as some I/O code chokes on topologically + identical selections with different ranks. At least to begin with, we will deal with the issue by constructing projections - of the memory dataspace with ranks equaling those of the file + of the memory dataspace with ranks equaling those of the file dataspace. - Note that if m > n, it is possible that the starting point in the - buffer associated with the memory dataspace will have to be + Note that if m > n, it is possible that the starting point in the + buffer associated with the memory dataspace will have to be adjusted to match the projected dataspace. If the buf parameter is not NULL, the function must return an adjusted buffer base address in *adj_buf_ptr. USAGE - htri_t H5S_select_construct_projection(base_space, + htri_t H5S_select_construct_projection(base_space, new_space_ptr, new_space_rank, buf, @@ -1969,30 +2046,30 @@ done: H5S_t ** new_space_ptr; OUT: Ptr to location in which to return the address of the projected space int new_space_rank; IN: Rank of the projected space. - const void * buf; IN: Base address of the buffer + const void * buf; IN: Base address of the buffer associated with the base space. May be NULL. void ** adj_buf_ptr; OUT: If buf != NULL, store the base - address of the section of buf + address of the section of buf that is described by *new_space_ptr in *adj_buf_ptr. - + RETURNS Non-negative on success/Negative on failure. DESCRIPTION - Construct a new dataspace and associated selection which is a - projection of the supplied dataspace and associated selection into + Construct a new dataspace and associated selection which is a + projection of the supplied dataspace and associated selection into the specified rank. Return it in *new_space_ptr. - If buf is supplied, computes the base address of the projected + If buf is supplied, computes the base address of the projected selection in buf, and stores the base address in *adj_buf_ptr. - + GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - The selection in the supplied base_space has thickness 1 in all + The selection in the supplied base_space has thickness 1 in all dimensions greater than new_space_rank. Note that here we count - dimensions from the fastest changing coordinate to the slowest + dimensions from the fastest changing coordinate to the slowest changing changing coordinate. EXAMPLES REVISION LOG @@ -2038,28 +2115,28 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, /* Create new scalar dataspace */ if(NULL == (new_space = H5S_create(H5S_SCALAR))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace") - + /* No need to register the dataspace(i.e. get an ID) as * we will just be discarding it shortly. */ - /* Selection for the new space will be either all or + /* Selection for the new space will be either all or * none, depending on whether the base space has 0 or * 1 elements selected. * - * Observe that the base space can't have more than + * Observe that the base space can't have more than * one selected element, since its selection has the - * same shape as the file dataspace, and that data + * same shape as the file dataspace, and that data * space is scalar. */ if(1 == npoints) { /* Assuming that the selection in the base dataspace is not - * empty, we must compute the offset of the selected item in + * empty, we must compute the offset of the selected item in * the buffer associated with the base dataspace. * - * Since the new space rank is zero, we know that the - * the base space must have rank at least 1 -- and - * hence it is a simple dataspace. However, the + * Since the new space rank is zero, we know that the + * the base space must have rank at least 1 -- and + * hence it is a simple dataspace. However, the * selection, may be either point, hyperspace, or all. * */ @@ -2077,25 +2154,25 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */ hsize_t new_space_maxdims[H5S_MAX_RANK];/* Maximum dimensions for new dataspace */ unsigned rank_diff; /* Difference in ranks */ - + /* Set up the dimensions of the new, projected dataspace. * - * How we do this depends on whether we are projecting up into - * increased dimensions, or down into a reduced number of + * How we do this depends on whether we are projecting up into + * increased dimensions, or down into a reduced number of * dimensions. * - * If we are projecting up (the first half of the following - * if statement), we copy the dimensions of the base data - * space into the fastest changing dimensions of the new + * If we are projecting up (the first half of the following + * if statement), we copy the dimensions of the base data + * space into the fastest changing dimensions of the new * projected dataspace, and set the remaining dimensions to * one. * * If we are projecting down (the second half of the following - * if statement), we just copy the dimensions with the most + * if statement), we just copy the dimensions with the most * quickly changing dimensions into the dims for the projected * data set. * - * This works, because H5S_select_shape_same() will return + * This works, because H5S_select_shape_same() will return * true on selections of different rank iff: * * 1) the selection in the lower rank dataspace matches that @@ -2103,13 +2180,13 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, * the larger rank dataspace, and * * 2) the selection has thickness 1 in all ranks that appear - * only in the higher rank dataspace (i.e. those with + * only in the higher rank dataspace (i.e. those with * more slowly changing indicies). - */ + */ if(new_space_rank > base_space_rank) { hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */ - /* we must copy the dimensions of the base space into + /* we must copy the dimensions of the base space into * the fastest changing dimensions of the new space, * and set the remaining dimensions to 1 */ @@ -2120,7 +2197,7 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank); } /* end if */ else { /* new_space_rank < base_space_rank */ - /* we must copy the fastest changing dimension of the + /* we must copy the fastest changing dimension of the * base space into the dimensions of the new space. */ rank_diff = base_space_rank - new_space_rank; @@ -2128,12 +2205,12 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank); } /* end else */ - /* now have the new space rank and dimensions set up -- + /* now have the new space rank and dimensions set up -- * so we can create the new simple dataspace. */ if(NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") - + /* No need to register the dataspace(i.e. get an ID) as * we will just be discarding it shortly. */ @@ -2144,13 +2221,13 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, */ if(H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection") - + /* If we get this far, we have created the new dataspace, and projected * the selection in the base dataspace into the new dataspace. * - * If the base dataspace is simple, check to see if the - * offset_changed flag on the base selection has been set -- if so, - * project the offset into the new dataspace and set the + * If the base dataspace is simple, check to see if the + * offset_changed flag on the base selection has been set -- if so, + * project the offset into the new dataspace and set the * offset_changed flag. */ if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) { @@ -2182,12 +2259,12 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, * Since we can't do pointer arithmetic on void pointers, we first * cast buf to a pointer to byte -- i.e. uint8_t. * - * We then multiply the projected space element offset we - * calculated earlier by the supplied element size, add this - * value to the type cast buf pointer, cast the result back + * We then multiply the projected space element offset we + * calculated earlier by the supplied element size, add this + * value to the type cast buf pointer, cast the result back * to a pointer to void, and assign the result to *adj_buf_ptr. */ - *adj_buf_ptr = (const void *)(((const uint8_t *)buf) + + *adj_buf_ptr = (const void *)(((const uint8_t *)buf) + ((size_t)(projected_space_element_offset * element_size))); } /* end if */ else @@ -2202,7 +2279,7 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_construct_projection() */ +} /* end H5S_select_construct_projection() */ /*-------------------------------------------------------------------------- @@ -2233,7 +2310,7 @@ herr_t H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf) { H5S_sel_iter_t *iter = NULL; /* Selection iteration info */ - hbool_t iter_init = 0; /* Selection iteration info has been initialized */ + hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ hsize_t *off = NULL; /* Array to store sequence offsets */ size_t *len = NULL; /* Array to store sequence lengths */ hssize_t nelmts; /* Number of elements in selection */ @@ -2255,7 +2332,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b /* Initialize iterator */ if(H5S_select_iter_init(iter, space, fill_size) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") - iter_init = 1; /* Selection iteration info has been initialized */ + iter_init = TRUE; /* Selection iteration info has been initialized */ /* Get the number of elements in selection */ if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0) @@ -2310,7 +2387,7 @@ done: iter = H5FL_FREE(H5S_sel_iter_t, iter); FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_fill() */ +} /* end H5S_select_fill() */ /*-------------------------------------------------------------------------- @@ -2337,7 +2414,7 @@ done: src_intersect_space within the selection of src_space as a selection within the selection of dst_space. The result is placed in the selection of new_space_ptr. - + GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -2361,7 +2438,7 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, /* Create new space, using dst extent. Start with "all" selection. */ if(NULL == (new_space = H5S_create(H5S_SIMPLE))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create output dataspace") - if(H5S_extent_copy_real(&new_space->extent, &dst_space->extent, TRUE) < 0) + if(H5S__extent_copy_real(&new_space->extent, &dst_space->extent, TRUE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy destination space extent") /* If the intersecting space is "all", the intersection must be equal to the @@ -2379,14 +2456,14 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, if(H5S_select_none(new_space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") } /* end if */ - /* If any of the spaces use point selection, fall back to general algorithm - */ + /* If any of the spaces use point selection, fall back to general algorithm */ else if((src_intersect_space->select.type->type == H5S_SEL_POINTS) || (src_space->select.type->type == H5S_SEL_POINTS) || (dst_space->select.type->type == H5S_SEL_POINTS)) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") else { HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS); + /* Intersecting space is hyperslab selection. Call the hyperslab * routine to project to another hyperslab selection. */ if(H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space) < 0) @@ -2403,7 +2480,7 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace") FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_project_intersection() */ +} /* end H5S_select_project_intersection() */ /*-------------------------------------------------------------------------- @@ -2425,7 +2502,7 @@ done: Removes any and all portions of space that are also present in subtract_space. In essence, performs an A_NOT_B operation with the two selections. - + GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -2493,5 +2570,5 @@ H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_subtract() */ +} /* end H5S_select_subtract() */ diff --git a/src/H5Stest.c b/src/H5Stest.c index a7bee2b..50f5fa9 100644 --- a/src/H5Stest.c +++ b/src/H5Stest.c @@ -17,23 +17,60 @@ * Purpose: Dataspace selection testing functions. */ +/****************/ +/* Module Setup */ +/****************/ + #include "H5Smodule.h" /* This source code file is part of the H5S module */ #define H5S_TESTING /*suppress warning about H5S testing funcs*/ +/***********/ +/* Headers */ +/***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5Spkg.h" /* Dataspaces */ +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + /*-------------------------------------------------------------------------- NAME - H5S_select_shape_same_test + H5S__select_shape_same_test PURPOSE Determine if two dataspace selections are the same shape USAGE - htri_t H5S_select_shape_same_test(sid1, sid2) + htri_t H5S__select_shape_same_test(sid1, sid2) hid_t sid1; IN: 1st dataspace to compare hid_t sid2; IN: 2nd dataspace to compare RETURNS @@ -48,13 +85,13 @@ REVISION LOG --------------------------------------------------------------------------*/ htri_t -H5S_select_shape_same_test(hid_t sid1, hid_t sid2) +H5S__select_shape_same_test(hid_t sid1, hid_t sid2) { H5S_t *space1; /* Pointer to 1st dataspace */ H5S_t *space2; /* Pointer to 2nd dataspace */ htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Get dataspace structures */ if(NULL == (space1 = (H5S_t *)H5I_object_verify(sid1, H5I_DATASPACE))) @@ -68,16 +105,16 @@ H5S_select_shape_same_test(hid_t sid1, hid_t sid2) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_select_shape_same_test() */ +} /* H5S__select_shape_same_test() */ /*-------------------------------------------------------------------------- NAME - H5S_get_rebuild_status_test + H5S__get_rebuild_status_test PURPOSE Determine the status of hyperslab rebuild USAGE - htri_t H5S_inquiry_rebuild_status(hid_t space_id) + htri_t H5S__get_rebuild_status_test(hid_t space_id) hid_t space_id; IN: dataspace id RETURNS Non-negative TRUE/FALSE on success, negative on failure @@ -90,12 +127,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ htri_t -H5S_get_rebuild_status_test(hid_t space_id) +H5S__get_rebuild_status_test(hid_t space_id) { H5S_t *space; /* Pointer to 1st dataspace */ htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Get dataspace structures */ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) @@ -105,5 +142,5 @@ H5S_get_rebuild_status_test(hid_t space_id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_get_rebuild_status_test() */ +} /* H5S__get_rebuild_status_test() */ diff --git a/test/objcopy.c b/test/objcopy.c index eb4927f..4055781 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -1167,7 +1167,7 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts, if((obj2_sid = H5Rget_region(parent2, H5R_DATASET_REGION, ref_buf2)) < 0) TEST_ERROR /* Check if dataspaces are the same shape */ - if(H5S_select_shape_same_test(obj1_sid, obj2_sid) < 0) TEST_ERROR + if(H5S__select_shape_same_test(obj1_sid, obj2_sid) < 0) TEST_ERROR /* Close dataspaces */ if(H5Sclose(obj1_sid) < 0) TEST_ERROR @@ -2136,9 +2136,7 @@ test_copy_dataset_versionbounds(hid_t fcpl_src, hid_t fapl_src) char src_fname[NAME_BUF_SIZE]; /* Name of source file */ char dst_fname[NAME_BUF_SIZE]; /* Name of destination file */ H5F_libver_t low, high; /* File format bounds */ - H5F_libver_t low_src, high_src; /* Source file format bounds */ unsigned srcdset_fillversion; /* Fill version of source dataset */ - hbool_t valid_high = FALSE; /* TRUE if high bound is valid */ int i, j; /* Local index variables */ H5D_t *dsetp = NULL; /* Pointer to internal dset structure */ herr_t ret; /* Generic return value */ diff --git a/test/tselect.c b/test/tselect.c index bcc2a5b..9150b11 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -1888,9 +1888,9 @@ test_select_hyper_contig_dr__run_test(int test_num, const uint16_t *cube_buf, /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(small_cube_sid, + check = H5S__select_shape_same_test(small_cube_sid, file_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Read selection from disk */ ret = H5Dread(large_cube_dataset, @@ -1965,9 +1965,9 @@ test_select_hyper_contig_dr__run_test(int test_num, const uint16_t *cube_buf, /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(small_cube_sid, + check = H5S__select_shape_same_test(small_cube_sid, mem_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Read selection from disk */ @@ -2082,9 +2082,9 @@ test_select_hyper_contig_dr__run_test(int test_num, const uint16_t *cube_buf, * memory slice through the cube selection and the * on disk full small cube selections as having the same shape. */ - check = H5S_select_shape_same_test(small_cube_sid, + check = H5S__select_shape_same_test(small_cube_sid, mem_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* write the slice from the in memory large cube to the on disk small cube */ @@ -2193,9 +2193,9 @@ test_select_hyper_contig_dr__run_test(int test_num, const uint16_t *cube_buf, * on disk slice through the large cube selection * as having the same shape. */ - check = H5S_select_shape_same_test(small_cube_sid, + check = H5S__select_shape_same_test(small_cube_sid, file_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* write the cube from memory to the target slice of the disk cube */ @@ -2998,9 +2998,9 @@ test_select_hyper_checker_board_dr__run_test(int test_num, const uint16_t *cube_ /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(mem_small_cube_sid, + check = H5S__select_shape_same_test(mem_small_cube_sid, file_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* zero the buffer that we will be using for reading */ HDmemset(small_cube_buf_1, 0, sizeof(*small_cube_buf_1) * small_cube_size); @@ -3105,9 +3105,9 @@ test_select_hyper_checker_board_dr__run_test(int test_num, const uint16_t *cube_ /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(file_small_cube_sid, + check = H5S__select_shape_same_test(file_small_cube_sid, mem_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* zero out the in memory large cube */ @@ -3258,9 +3258,9 @@ test_select_hyper_checker_board_dr__run_test(int test_num, const uint16_t *cube_ /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(file_small_cube_sid, + check = H5S__select_shape_same_test(file_small_cube_sid, mem_large_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* write the slice from the in memory large cube to the @@ -3390,9 +3390,9 @@ test_select_hyper_checker_board_dr__run_test(int test_num, const uint16_t *cube_ /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(file_large_cube_sid, + check = H5S__select_shape_same_test(file_large_cube_sid, mem_small_cube_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* write the checker board selection of the in memory @@ -3525,13 +3525,13 @@ test_select_hyper_checker_board_dr__run_test(int test_num, const uint16_t *cube_ /**************************************************************** ** -** test_select_hyper_checker_board_dr(): Test H5S (dataspace) -** selection code with checkerboard source and target having +** test_select_hyper_checker_board_dr(): Test H5S (dataspace) +** selection code with checkerboard source and target having ** different ranks but the same shape. We have already -** tested H5S_shape_same in isolation, so now we try to do +** tested H5S_shape_same in isolation, so now we try to do ** I/O. ** -** This is just an initial smoke check, so we will work +** This is just an initial smoke check, so we will work ** with a slice through a cube only. ** ****************************************************************/ @@ -5902,6 +5902,10 @@ test_select_hyper_union_random_5d(hid_t read_plist) /* Select hyperslab */ ret = H5Sselect_hyperslab(sid1, (i == 0 ? H5S_SELECT_SET : H5S_SELECT_OR), start, NULL, count, NULL); CHECK(ret, FAIL, "H5Sselect_hyperslab"); + if(ret < 0) { + TestErrPrintf("Random hyperslabs for seed %u failed!\n", seed); + break; + } /* end if */ } /* end for */ /* Get the number of elements selected */ @@ -5920,14 +5924,18 @@ test_select_hyper_union_random_5d(hid_t read_plist) /* Read selection from disk */ ret=H5Dread(dataset,H5T_NATIVE_INT,sid2,sid1,read_plist,rbuf); CHECK(ret, FAIL, "H5Dread"); + if(ret < 0) { + TestErrPrintf("Random hyperslabs for seed %u failed!\n", seed); + break; + } /* end if */ /* Compare data read with data written out */ tbuf=rbuf; ret = H5Diterate(wbuf,H5T_NATIVE_INT,sid1,test_select_hyper_iter2,&tbuf); - if(ret<0) { - TestErrPrintf("Random hyperslabs for seed %u failed!\n",seed); + if(ret < 0) { + TestErrPrintf("Random hyperslabs for seed %u failed!\n", seed); break; - } + } /* end if */ /* Set the read buffer back to all zeroes */ HDmemset(rbuf, 0, (size_t)SPACE6_DIM1); @@ -6585,7 +6593,7 @@ test_select_combine(void) hsize_t dims[SPACE7_RANK]={SPACE7_DIM1,SPACE7_DIM2}; /* Dimensions of dataspace */ H5S_sel_type sel_type; /* Selection type */ hssize_t nblocks; /* Number of hyperslab blocks */ - hsize_t blocks[128][2][SPACE7_RANK]; /* List of blocks */ + hsize_t blocks[16][2][SPACE7_RANK]; /* List of blocks */ herr_t error; /* Output message about test being performed */ @@ -8087,290 +8095,290 @@ test_shape_same(void) /* Compare "all" selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(all_sid,all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(all_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(all_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(all_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(all_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(all_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,single_hyper_all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,single_hyper_all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(all_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(all_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(all_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(all_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare "none" selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(none_sid,none_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,none_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(none_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(none_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(none_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(none_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(none_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(none_sid,none_hyper_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid,none_hyper_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(none_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(none_sid, scalar_none_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(none_sid, scalar_none_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare single point selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(single_pt_sid,single_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,single_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(single_pt_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(single_pt_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(single_pt_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(single_pt_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(single_pt_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,single_hyper_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,single_hyper_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(single_pt_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(single_pt_sid, scalar_all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid, scalar_all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(single_pt_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_pt_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare multiple point selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(mult_pt_sid,mult_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,mult_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(mult_pt_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(mult_pt_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(mult_pt_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(mult_pt_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(mult_pt_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(mult_pt_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(mult_pt_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(mult_pt_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(mult_pt_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare single "normal" hyperslab selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(single_hyper_sid,single_hyper_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,single_hyper_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(single_hyper_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(single_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(single_hyper_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(single_hyper_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(single_hyper_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(single_hyper_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); #ifdef NOT_YET /* In theory, these two selections are the same shape, but the @@ -8394,8 +8402,8 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); @@ -8421,70 +8429,70 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare single "all" hyperslab selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(single_hyper_all_sid,single_hyper_all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,single_hyper_all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(single_hyper_all_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(single_hyper_all_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); #ifdef NOT_YET /* In theory, these two selections are the same shape, but the @@ -8508,8 +8516,8 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); @@ -8535,129 +8543,129 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_all_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_all_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_all_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_all_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare single "point" hyperslab selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,single_hyper_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,single_hyper_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(single_hyper_pt_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(single_hyper_pt_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,single_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,single_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(single_hyper_pt_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_pt_sid, scalar_all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid, scalar_all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(single_hyper_pt_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(single_hyper_pt_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare regular, strided hyperslab selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(regular_hyper_sid,regular_hyper_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,regular_hyper_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(regular_hyper_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(regular_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Construct point selection which matches regular, strided hyperslab selection */ /* Create dataspace for point selection */ @@ -8674,8 +8682,8 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); @@ -8700,8 +8708,8 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); @@ -8720,70 +8728,70 @@ test_shape_same(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(regular_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(regular_hyper_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(regular_hyper_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(regular_hyper_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare irregular hyperslab selection to all the selections created */ /* Compare against itself */ - check=H5S_select_shape_same_test(irreg_hyper_sid,irreg_hyper_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,irreg_hyper_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid=H5Scopy(irreg_hyper_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check=H5S_select_shape_same_test(irreg_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Construct hyperslab selection which matches irregular hyperslab selection */ /* Create dataspace for hyperslab selection */ @@ -8808,141 +8816,141 @@ test_shape_same(void) } /* end for */ /* Compare against hyperslab selection */ - check=H5S_select_shape_same_test(irreg_hyper_sid,tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid,tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(irreg_hyper_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(irreg_hyper_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(irreg_hyper_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare scalar "all" dataspace with all selections created */ /* Compare against itself */ - check = H5S_select_shape_same_test(scalar_all_sid, scalar_all_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, scalar_all_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid = H5Scopy(scalar_all_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check = H5S_select_shape_same_test(scalar_all_sid, tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check = H5S_select_shape_same_test(scalar_all_sid, all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check = H5S_select_shape_same_test(scalar_all_sid, none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check = H5S_select_shape_same_test(scalar_all_sid, single_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, single_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check = H5S_select_shape_same_test(scalar_all_sid, mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, single_hyper_pt_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, single_hyper_pt_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, none_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, none_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against scalar "none" hyperslab selection */ - check = H5S_select_shape_same_test(scalar_all_sid, scalar_none_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_all_sid, scalar_none_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare scalar "none" dataspace with all selections created */ /* Compare against itself */ - check = H5S_select_shape_same_test(scalar_none_sid, scalar_none_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, scalar_none_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against copy of itself */ tmp_sid = H5Scopy(scalar_none_sid); CHECK(tmp_sid, FAIL, "H5Scopy"); - check = H5S_select_shape_same_test(scalar_none_sid, tmp_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, tmp_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); /* Compare against "all" selection */ - check = H5S_select_shape_same_test(scalar_none_sid, all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "none" selection */ - check = H5S_select_shape_same_test(scalar_none_sid, none_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, none_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against single point selection */ - check = H5S_select_shape_same_test(scalar_none_sid, single_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, single_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against multiple point selection */ - check = H5S_select_shape_same_test(scalar_none_sid, mult_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, mult_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "plain" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, single_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, single_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "all" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, single_hyper_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, single_hyper_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "single point" single hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, single_hyper_pt_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, single_hyper_pt_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against regular, strided hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, regular_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, regular_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against irregular hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, irreg_hyper_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, irreg_hyper_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "no" hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, none_hyper_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, none_hyper_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Compare against scalar "all" hyperslab selection */ - check = H5S_select_shape_same_test(scalar_none_sid, scalar_all_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(scalar_none_sid, scalar_all_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Close dataspaces */ @@ -8974,27 +8982,27 @@ test_shape_same(void) /**************************************************************** ** -** test_shape_same_dr__smoke_check_1(): +** test_shape_same_dr__smoke_check_1(): ** -** Create a square, 2 D data space (10 X 10), and select +** Create a square, 2 D data space (10 X 10), and select ** all of it. ** -** Similarly, create nine, 3 D data spaces (10 X 10 X 10), -** and select (10 X 10 X 1) hyper slabs in each, three with -** the slab parallel to the xy plane, three parallel to the +** Similarly, create nine, 3 D data spaces (10 X 10 X 10), +** and select (10 X 10 X 1) hyper slabs in each, three with +** the slab parallel to the xy plane, three parallel to the ** xz plane, and three parallel to the yz plane. ** -** Assuming that z is the fastest changing dimension, -** H5S_select_shape_same() should return TRUE when comparing -** the full 2 D space against any hyperslab parallel to the -** yz plane in the 3 D space, and FALSE when comparing the +** Assuming that z is the fastest changing dimension, +** H5S_select_shape_same() should return TRUE when comparing +** the full 2 D space against any hyperslab parallel to the +** yz plane in the 3 D space, and FALSE when comparing the ** full 2 D space against the other two hyper slabs. ** -** Also create two additional 3 D data spaces (10 X 10 X 10), -** and select a (10 X 10 X 2) hyper slab parallel to the yz -** axis in one of them, and two parallel (10 X 10 X 1) hyper -** slabs parallel to the yz axis in the other. -** H5S_select_shape_same() should return FALSE when comparing +** Also create two additional 3 D data spaces (10 X 10 X 10), +** and select a (10 X 10 X 2) hyper slab parallel to the yz +** axis in one of them, and two parallel (10 X 10 X 1) hyper +** slabs parallel to the yz axis in the other. +** H5S_select_shape_same() should return FALSE when comparing ** each to the 2 D selection. ** ****************************************************************/ @@ -9183,42 +9191,42 @@ test_shape_same_dr__smoke_check_1(void) /* setup is done -- run the tests: */ /* Compare against "xy" selection */ - check = H5S_select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "xz" selection */ - check = H5S_select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "yz" selection */ - check = H5S_select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_3_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_3_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_4_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_4_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Close dataspaces */ @@ -9265,9 +9273,9 @@ test_shape_same_dr__smoke_check_1(void) /**************************************************************** ** -** test_shape_same_dr__smoke_check_2(): +** test_shape_same_dr__smoke_check_2(): ** -** Create a square, 2 D data space (10 X 10), and select +** Create a square, 2 D data space (10 X 10), and select ** a "checker board" hyper slab as follows: ** ** * * - - * * - - * * @@ -9281,27 +9289,27 @@ test_shape_same_dr__smoke_check_1(void) ** * * - - * * - - * * ** * * - - * * - - * * ** -** where asterisks indicate selected elements, and dashes +** where asterisks indicate selected elements, and dashes ** indicate unselected elements. ** -** Similarly, create nine, 3 D data spaces (10 X 10 X 10), -** and select similar (10 X 10 X 1) checker board hyper -** slabs in each, three with the slab parallel to the xy -** plane, three parallel to the xz plane, and three parallel +** Similarly, create nine, 3 D data spaces (10 X 10 X 10), +** and select similar (10 X 10 X 1) checker board hyper +** slabs in each, three with the slab parallel to the xy +** plane, three parallel to the xz plane, and three parallel ** to the yz plane. ** -** Assuming that z is the fastest changing dimension, -** H5S_select_shape_same() should return TRUE when comparing -** the 2 D space checker board selection against a checker -** board hyperslab parallel to the yz plane in the 3 D -** space, and FALSE when comparing the 2 D checkerboard -** selection against two hyper slabs parallel to the xy +** Assuming that z is the fastest changing dimension, +** H5S_select_shape_same() should return TRUE when comparing +** the 2 D space checker board selection against a checker +** board hyperslab parallel to the yz plane in the 3 D +** space, and FALSE when comparing the 2 D checkerboard +** selection against two hyper slabs parallel to the xy ** or xz planes. ** -** Also create an additional 3 D data spaces (10 X 10 X 10), -** and select a checker board parallel with the yz axis, -** save with some squares being on different planes. -** H5S_select_shape_same() should return FALSE when +** Also create an additional 3 D data spaces (10 X 10 X 10), +** and select a checker board parallel with the yz axis, +** save with some squares being on different planes. +** H5S_select_shape_same() should return FALSE when ** comparing this selection to the 2 D selection. ** ****************************************************************/ @@ -9584,7 +9592,7 @@ test_shape_same_dr__smoke_check_2(void) start[0] = 4; /* This test gets the right answer, but it fails the shape same - * test in an unexpected point. Bring this up with Quincey, as + * test in an unexpected point. Bring this up with Quincey, as * the oddness looks like it is not related to my code. * -- JRM */ @@ -9596,39 +9604,39 @@ test_shape_same_dr__smoke_check_2(void) /* setup is done -- run the tests: */ /* Compare against "xy" selection */ - check = H5S_select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "xz" selection */ - check = H5S_select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "yz" selection */ - check = H5S_select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_3_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_3_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Close dataspaces */ @@ -9673,9 +9681,9 @@ test_shape_same_dr__smoke_check_2(void) /**************************************************************** ** -** test_shape_same_dr__smoke_check_3(): +** test_shape_same_dr__smoke_check_3(): ** -** Create a square, 2 D data space (10 X 10), and select an +** Create a square, 2 D data space (10 X 10), and select an ** irregular hyper slab as follows: ** ** y @@ -9691,22 +9699,22 @@ test_shape_same_dr__smoke_check_2(void) ** 0 - - - - - - - - - - ** 0 1 2 3 4 5 6 7 8 9 x ** -** where asterisks indicate selected elements, and dashes +** where asterisks indicate selected elements, and dashes ** indicate unselected elements. ** -** Similarly, create nine, 3 D data spaces (10 X 10 X 10), -** and select similar irregular hyper slabs in each, three -** with the slab parallel to the xy plane, three parallel -** to the xz plane, and three parallel to the yz plane. -** Further, translate the irregular slab in 2/3rds of the +** Similarly, create nine, 3 D data spaces (10 X 10 X 10), +** and select similar irregular hyper slabs in each, three +** with the slab parallel to the xy plane, three parallel +** to the xz plane, and three parallel to the yz plane. +** Further, translate the irregular slab in 2/3rds of the ** cases. ** -** Assuming that z is the fastest changing dimension, -** H5S_select_shape_same() should return TRUE when -** comparing the 2 D irregular hyperslab selection -** against the irregular hyperslab selections parallel -** to the yz plane in the 3 D space, and FALSE when -** comparing it against the irregular hyper slabs +** Assuming that z is the fastest changing dimension, +** H5S_select_shape_same() should return TRUE when +** comparing the 2 D irregular hyperslab selection +** against the irregular hyperslab selections parallel +** to the yz plane in the 3 D space, and FALSE when +** comparing it against the irregular hyper slabs ** selections parallel to the xy or xz planes. ** ****************************************************************/ @@ -10119,36 +10127,36 @@ test_shape_same_dr__smoke_check_3(void) /* setup is done -- run the tests: */ /* Compare against "xy" selection */ - check = H5S_select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xy_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "xz" selection */ - check = H5S_select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_0_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_1_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_xz_slice_2_sid, small_square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Compare against "yz" selection */ - check = H5S_select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_0_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_1_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(small_cube_yz_slice_2_sid, small_square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); /* Close dataspaces */ @@ -10190,9 +10198,9 @@ test_shape_same_dr__smoke_check_3(void) /**************************************************************** ** -** test_shape_same_dr__smoke_check_4(): +** test_shape_same_dr__smoke_check_4(): ** -** Create a square, 2 D data space (10 X 10), and select +** Create a square, 2 D data space (10 X 10), and select ** the entire space. ** ** Similarly, create 3 D and 4 D data spaces: @@ -10213,7 +10221,7 @@ test_shape_same_dr__smoke_check_3(void) ** And select these entire spaces as well. ** ** Compare the 2 D space against all the other spaces -** with H5S_select_shape_same(). The (1 X 10 X 10) & +** with H5S_select_shape_same(). The (1 X 10 X 10) & ** (1 X 1 X 10 X 10) should return TRUE. All others ** should return FALSE. ** @@ -10331,39 +10339,39 @@ test_shape_same_dr__smoke_check_4(void) /* setup is done -- run the tests: */ - check = H5S_select_shape_same_test(three_d_space_0_sid, square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(three_d_space_0_sid, square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(three_d_space_1_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(three_d_space_1_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(three_d_space_2_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(three_d_space_2_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(three_d_space_3_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(three_d_space_3_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_0_sid, square_sid); - VERIFY(check, TRUE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_0_sid, square_sid); + VERIFY(check, TRUE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_1_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_1_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_2_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_2_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_3_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_3_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_4_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_4_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_5_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_5_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); - check = H5S_select_shape_same_test(four_d_space_6_sid, square_sid); - VERIFY(check, FALSE, "H5S_select_shape_same_test"); + check = H5S__select_shape_same_test(four_d_space_6_sid, square_sid); + VERIFY(check, FALSE, "H5S__select_shape_same_test"); /* Close dataspaces */ @@ -10410,12 +10418,12 @@ test_shape_same_dr__smoke_check_4(void) /**************************************************************** ** ** test_shape_same_dr__full_space_vs_slice(): Tests selection -** of a full n-cube data space vs an n-dimensional slice of -** of an m-cube (m > n) in a call to H5S_select_shape_same(). -** Note that this test does not require the n-cube and the +** of a full n-cube data space vs an n-dimensional slice of +** of an m-cube (m > n) in a call to H5S_select_shape_same(). +** Note that this test does not require the n-cube and the ** n-dimensional slice to have the same rank (although -** H5S_select_shape_same() should always return FALSE if -** they don't). +** H5S_select_shape_same() should always return FALSE if +** they don't). ** ** Per Quincey's suggestion, only test up to 5 dimensional ** spaces. @@ -10452,16 +10460,16 @@ test_shape_same_dr__full_space_vs_slice(int test_num, HDassert( large_rank <= SS_DR_MAX_RANK ); HDassert( 0 <= offset ); HDassert( offset < large_rank ); - HDassert( edge_size > 0 ); - HDassert( edge_size <= 1000 ); + HDassert( edge_size > 0 ); + HDassert( edge_size <= 1000 ); - sprintf(test_desc_0, - "\tn-cube slice through m-cube (n <= m) test %d.\n", + sprintf(test_desc_0, + "\tn-cube slice through m-cube (n <= m) test %d.\n", test_num); MESSAGE(7, (test_desc_0)); /* This statement must be updated if SS_DR_MAX_RANK is changed */ - sprintf(test_desc_1, + sprintf(test_desc_1, "\t\tranks: %d/%d offset: %d dim_selected: %d/%d/%d/%d/%d.\n", small_rank, large_rank, offset, (int)dim_selected[0], @@ -10526,7 +10534,7 @@ test_shape_same_dr__full_space_vs_slice(int test_num, /* setup is done -- run the test: */ - check = H5S_select_shape_same_test(n_cube_0_sid, n_cube_1_sid); + check = H5S__select_shape_same_test(n_cube_0_sid, n_cube_1_sid); VERIFY(check, expected_result, "test_shape_same_dr__full_space_vs_slice"); @@ -10542,27 +10550,27 @@ test_shape_same_dr__full_space_vs_slice(int test_num, /**************************************************************** ** -** test_shape_same_dr__run_full_space_vs_slice_tests(): +** test_shape_same_dr__run_full_space_vs_slice_tests(): ** ** Run the est_shape_same_dr__full_space_vs_slice() test ** over a variety of ranks and offsets. ** -** At present, we test H5S_select_shape_same() with +** At present, we test H5S_select_shape_same() with ** fully selected 1, 2, 3, and 4 cubes as one parameter, and ** 1, 2, 3, and 4 dimensional slices through a n-cube of rank -** no more than 5 (and at least the rank of the slice). -** We stop at rank 5, as Quincey suggested that it would be +** no more than 5 (and at least the rank of the slice). +** We stop at rank 5, as Quincey suggested that it would be ** sufficient. ** -** All the n-cubes will have lengths of the same size, so +** All the n-cubes will have lengths of the same size, so ** H5S_select_shape_same() should return true iff: ** -** 1) the rank for the fully selected n cube equals the +** 1) the rank for the fully selected n cube equals the ** number of dimensions selected in the slice through the ** m-cube (m >= n). ** ** 2) The dimensions selected in the slice through the m-cube -** are the dimesnions with the most quickly changing +** are the dimesnions with the most quickly changing ** indices. ** ****************************************************************/ @@ -10668,7 +10676,7 @@ test_shape_same_dr__run_full_space_vs_slice_tests(void) dim_selected, expected_result ); - + z++; } while((z < 2) && (large_rank >= 1)); @@ -10691,15 +10699,15 @@ test_shape_same_dr__run_full_space_vs_slice_tests(void) /**************************************************************** ** -** test_shape_same_dr__checkerboard(): Tests selection of a -** "checker board" subset of a full n-cube data space vs +** test_shape_same_dr__checkerboard(): Tests selection of a +** "checker board" subset of a full n-cube data space vs ** a "checker board" n-dimensional slice of an m-cube (m > n). -** in a call to H5S_select_shape_same(). +** in a call to H5S_select_shape_same(). ** -** Note that this test does not require the n-cube and the +** Note that this test does not require the n-cube and the ** n-dimensional slice to have the same rank (although -** H5S_select_shape_same() should always return FALSE if -** they don't). +** H5S_select_shape_same() should always return FALSE if +** they don't). ** ** Per Quincey's suggestion, only test up to 5 dimensional ** spaces. @@ -10719,11 +10727,11 @@ test_shape_same_dr__checkerboard(int test_num, char test_desc_1[128]; int i; int dims_selected = 0; - hid_t n_cube_0_sid; /* the checker board selected - * hyper cube + hid_t n_cube_0_sid; /* the checker board selected + * hyper cube */ - hid_t n_cube_1_sid; /* the hyper cube in which a - * checkerboard slice is selected + hid_t n_cube_1_sid; /* the hyper cube in which a + * checkerboard slice is selected */ hsize_t dims[SS_DR_MAX_RANK]; hsize_t base_start[2]; @@ -10745,8 +10753,8 @@ test_shape_same_dr__checkerboard(int test_num, HDassert( small_rank <= large_rank ); HDassert( large_rank <= SS_DR_MAX_RANK ); HDassert( 0 < checker_size ); - HDassert( checker_size <= edge_size ); - HDassert( edge_size <= 1000 ); + HDassert( checker_size <= edge_size ); + HDassert( edge_size <= 1000 ); HDassert( 0 <= offset ); HDassert( offset < (int)edge_size ); @@ -10757,13 +10765,13 @@ test_shape_same_dr__checkerboard(int test_num, HDassert( dims_selected >= 0 ); HDassert( dims_selected <= large_rank ); - sprintf(test_desc_0, - "\tcheckerboard n-cube slice through m-cube (n <= m) test %d.\n", + sprintf(test_desc_0, + "\tcheckerboard n-cube slice through m-cube (n <= m) test %d.\n", test_num); MESSAGE(7, (test_desc_0)); /* This statement must be updated if SS_DR_MAX_RANK is changed */ - sprintf(test_desc_1, + sprintf(test_desc_1, "\tranks: %d/%d edge/chkr size: %d/%d offset: %d dim_selected: %d/%d/%d/%d/%d:%d.\n", small_rank, large_rank, (int)edge_size, (int)checker_size, @@ -10803,17 +10811,17 @@ test_shape_same_dr__checkerboard(int test_num, * * * - - * * - - * * * * * - - * * - - * * * - * In both cases, asterisks indicate selected elements, + * In both cases, asterisks indicate selected elements, * and dashes indicate unselected elements. * * 3-D and 4-D ascii art is somewhat painful, so I'll * leave those selections to your imagination. :-) * * Note, that since the edge_size and checker_size are - * parameters that are passed in, the selection need + * parameters that are passed in, the selection need * not look exactly like the selection shown above. - * At present, the function allows checker sizes that - * are not even divisors of the edge size -- thus + * At present, the function allows checker sizes that + * are not even divisors of the edge size -- thus * something like the following is also possible: * * * * * - - - * * * - @@ -10827,14 +10835,14 @@ test_shape_same_dr__checkerboard(int test_num, * * * * - - - * * * - * - - - * * * - - - * * - * As the above pattern can't be selected in one + * As the above pattern can't be selected in one * call to H5Sselect_hyperslab(), and since the * values in the start, stride, count, and block - * arrays will be repeated over all entries in + * arrays will be repeated over all entries in * the selected space case, and over all selected * dimensions in the selected hyperslab case, we - * compute these values first and store them in - * in the base_start, base_stride, base_count, + * compute these values first and store them in + * in the base_start, base_stride, base_count, * and base_block arrays. */ @@ -10844,9 +10852,9 @@ test_shape_same_dr__checkerboard(int test_num, base_stride[0] = 2 * checker_size; base_stride[1] = 2 * checker_size; - /* Note that the following computation depends on the C99 - * requirement that integer division discard any fraction - * (truncation towards zero) to function correctly. As we + /* Note that the following computation depends on the C99 + * requirement that integer division discard any fraction + * (truncation towards zero) to function correctly. As we * now require C99, this shouldn't be a problem, but noting * it may save us some pain if we are ever obliged to support * pre-C99 compilers again. @@ -10863,7 +10871,7 @@ test_shape_same_dr__checkerboard(int test_num, base_block[0] = checker_size; base_block[1] = checker_size; - /* now setup start, stride, count, and block arrays for + /* now setup start, stride, count, and block arrays for * the first call to H5Sselect_hyperslab(). */ for(i = 0; i < SS_DR_MAX_RANK; i++) { @@ -10877,10 +10885,10 @@ test_shape_same_dr__checkerboard(int test_num, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* if small_rank == 1, or if edge_size == checker_size, we + /* if small_rank == 1, or if edge_size == checker_size, we * are done, as either there is no added dimension in which * to place offset selected "checkers". - * + * * Otherwise, set up start, stride, count and block, and * make the additional selection. */ @@ -10900,7 +10908,7 @@ test_shape_same_dr__checkerboard(int test_num, /* Wierdness alert: * - * Some how, it seems that selections can extend beyond the + * Some how, it seems that selections can extend beyond the * boundaries of the target data space -- hence the following * code to manually clip the selection back to the data space * proper. @@ -10923,8 +10931,8 @@ test_shape_same_dr__checkerboard(int test_num, /* Now select the checkerboard selection in the (possibly larger) n-cube. - * - * Since we have already calculated the base start, stride, count, + * + * Since we have already calculated the base start, stride, count, * and block, re-use the values in setting up start, stride, count, * and block. */ @@ -10968,10 +10976,10 @@ test_shape_same_dr__checkerboard(int test_num, start_ptr, stride_ptr, count_ptr, block_ptr); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* As before, if the number of dimensions selected is less than or - * equal to 1, or if edge_size == checker_size, we are done, as - * either there is no added dimension in which to place offset selected - * "checkers", or the hyperslab is completely occupied by one + /* As before, if the number of dimensions selected is less than or + * equal to 1, or if edge_size == checker_size, we are done, as + * either there is no added dimension in which to place offset selected + * "checkers", or the hyperslab is completely occupied by one * "checker". * * Otherwise, set up start, stride, count and block, and @@ -11001,7 +11009,7 @@ test_shape_same_dr__checkerboard(int test_num, /* Wierdness alert: * - * Again, it seems that selections can extend beyond the + * Again, it seems that selections can extend beyond the * boundaries of the target data space -- hence the following * code to manually clip the selection back to the data space * proper. @@ -11018,7 +11026,7 @@ test_shape_same_dr__checkerboard(int test_num, CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* setup is done -- run the test: */ - check = H5S_select_shape_same_test(n_cube_0_sid, n_cube_1_sid); + check = H5S__select_shape_same_test(n_cube_0_sid, n_cube_1_sid); VERIFY(check, expected_result, "test_shape_same_dr__checkerboard"); @@ -11034,23 +11042,23 @@ test_shape_same_dr__checkerboard(int test_num, /**************************************************************** ** -** test_shape_same_dr__run_checkerboard_tests(): +** test_shape_same_dr__run_checkerboard_tests(): ** -** In this set of tests, we test H5S_select_shape_same() -** with a "checkerboard" selection of 1, 2, 3, and 4 cubes as -** one parameter, and 1, 2, 3, and 4 dimensional checkerboard -** slices through a n-cube of rank no more than 5 (and at -** least the rank of the slice). +** In this set of tests, we test H5S_select_shape_same() +** with a "checkerboard" selection of 1, 2, 3, and 4 cubes as +** one parameter, and 1, 2, 3, and 4 dimensional checkerboard +** slices through a n-cube of rank no more than 5 (and at +** least the rank of the slice). ** -** All the n-cubes will have lengths of the same size, so +** All the n-cubes will have lengths of the same size, so ** H5S_select_shape_same() should return true iff: ** -** 1) the rank of the n cube equals the number of dimensions -** selected in the checker board slice through the m-cube +** 1) the rank of the n cube equals the number of dimensions +** selected in the checker board slice through the m-cube ** (m >= n). ** -** 2) The dimensions selected in the checkerboard slice -** through the m-cube are the dimensions with the most +** 2) The dimensions selected in the checkerboard slice +** through the m-cube are the dimensions with the most ** quickly changing indices. ** ****************************************************************/ @@ -11101,7 +11109,7 @@ test_shape_same_dr__run_checkerboard_tests(void) dim_selected[4] = FALSE; else dim_selected[4] = TRUE; - + /* compute the expected result: */ i = 0; @@ -11305,17 +11313,17 @@ test_shape_same_dr__run_checkerboard_tests(void) /**************************************************************** ** -** test_shape_same_dr__irregular(): +** test_shape_same_dr__irregular(): ** -** Tests selection of an "irregular" subset of a full +** Tests selection of an "irregular" subset of a full ** n-cube data space vs an identical "irregular" subset ** of an n-dimensional slice of an m-cube (m > n). -** in a call to H5S_select_shape_same(). +** in a call to H5S_select_shape_same(). ** -** Note that this test does not require the n-cube and the +** Note that this test does not require the n-cube and the ** n-dimensional slice to have the same rank (although -** H5S_select_shape_same() should always return FALSE if -** they don't). +** H5S_select_shape_same() should always return FALSE if +** they don't). ** ****************************************************************/ static void @@ -11337,7 +11345,7 @@ test_shape_same_dr__irregular(int test_num, hid_t n_cube_0_sid; /* the hyper cube containing * an irregular selection */ - hid_t n_cube_1_sid; /* the hyper cube in which a + hid_t n_cube_1_sid; /* the hyper cube in which a * slice contains an irregular * selection. */ @@ -11373,7 +11381,7 @@ test_shape_same_dr__irregular(int test_num, hsize_t clip_block[SS_DR_MAX_RANK] = {10, 10, 10, 10, 10}; - hsize_t *(starts[SS_DR_MAX_RANK]) = + hsize_t *(starts[SS_DR_MAX_RANK]) = {start_0, start_1, start_2, start_3, start_4}; hsize_t *(strides[SS_DR_MAX_RANK]) = {stride_0, stride_1, stride_2, stride_3, stride_4}; @@ -11396,8 +11404,8 @@ test_shape_same_dr__irregular(int test_num, HDassert( 0 < small_rank ); HDassert( small_rank <= large_rank ); HDassert( large_rank <= SS_DR_MAX_RANK ); - HDassert( 9 <= edge_size ); - HDassert( edge_size <= 1000 ); + HDassert( 9 <= edge_size ); + HDassert( edge_size <= 1000 ); HDassert( 0 <= slice_offset ); HDassert( slice_offset < edge_size ); HDassert( -2 <= pattern_offset ); @@ -11410,16 +11418,16 @@ test_shape_same_dr__irregular(int test_num, HDassert( dims_selected >= 0 ); HDassert( dims_selected <= large_rank ); - sprintf(test_desc_0, - "\tirregular sub set of n-cube slice through m-cube (n <= m) test %d.\n", + sprintf(test_desc_0, + "\tirregular sub set of n-cube slice through m-cube (n <= m) test %d.\n", test_num); MESSAGE(7, (test_desc_0)); /* This statement must be updated if SS_DR_MAX_RANK is changed */ - sprintf(test_desc_1, + sprintf(test_desc_1, "\tranks: %d/%d edge: %d s/p offset: %d/%d dim_selected: %d/%d/%d/%d/%d:%d.\n", small_rank, large_rank, - edge_size, + edge_size, slice_offset, pattern_offset, (int)dim_selected[0], (int)dim_selected[1], @@ -11438,11 +11446,11 @@ test_shape_same_dr__irregular(int test_num, CHECK(n_cube_0_sid, FAIL, "H5Screate_simple"); /* Select an "irregular" pattern in the small n-cube. This - * pattern can be though of a set of four 3 x 2 x 2 X 2 - * four dimensional prisims, each parallel to one of the - * axies and none of them intersecting with the other. + * pattern can be though of a set of four 3 x 2 x 2 X 2 + * four dimensional prisims, each parallel to one of the + * axies and none of them intersecting with the other. * - * In the lesser dimensional cases, this 4D pattern is + * In the lesser dimensional cases, this 4D pattern is * projected onto the lower dimensional space. * * In the 1-D case, the projection of the pattern looks @@ -11467,12 +11475,12 @@ test_shape_same_dr__irregular(int test_num, * 0 - - - - - - - - - - * 0 1 2 3 4 5 6 7 8 9 x * - * In both cases, asterisks indicate selected elements, + * In both cases, asterisks indicate selected elements, * and dashes indicate unselected elements. * * Note that is this case, since the edge size is fixed, - * the pattern does not change. However, we do use the - * displacement parameter to allow it to be moved around + * the pattern does not change. However, we do use the + * displacement parameter to allow it to be moved around * within the n-cube or hyper slab. */ @@ -11487,7 +11495,7 @@ test_shape_same_dr__irregular(int test_num, CHECK(ret, FAIL, "H5Sselect_hyperslab"); } /* end for */ - /* finally, clip the selection to ensure that it lies fully + /* finally, clip the selection to ensure that it lies fully * within the n-cube. */ ret = H5Sselect_hyperslab(n_cube_0_sid, H5S_SELECT_AND, @@ -11526,8 +11534,8 @@ test_shape_same_dr__irregular(int test_num, /* Now select the irregular selection in the (possibly larger) n-cube. - * - * Basic idea is to project the pattern used in the smaller n-cube + * + * Basic idea is to project the pattern used in the smaller n-cube * onto the dimensions selected in the larger n-cube, with the displacement * specified. */ @@ -11564,7 +11572,7 @@ test_shape_same_dr__irregular(int test_num, /* setup is done -- run the test: */ - check = H5S_select_shape_same_test(n_cube_0_sid, n_cube_1_sid); + check = H5S__select_shape_same_test(n_cube_0_sid, n_cube_1_sid); VERIFY(check, expected_result, "test_shape_same_dr__checkerboard"); @@ -11580,25 +11588,25 @@ test_shape_same_dr__irregular(int test_num, /**************************************************************** ** -** test_shape_same_dr__run_irregular_tests(): +** test_shape_same_dr__run_irregular_tests(): ** -** In this set of tests, we test H5S_select_shape_same() -** with an "irregular" subselection of 1, 2, 3, and 4 cubes as -** one parameter, and irregular subselections of 1, 2, 3, -** and 4 dimensional slices through a n-cube of rank no more -** than 5 (and at least the rank of the slice) as the other. -** Note that the "irregular" selection may be offset between +** In this set of tests, we test H5S_select_shape_same() +** with an "irregular" subselection of 1, 2, 3, and 4 cubes as +** one parameter, and irregular subselections of 1, 2, 3, +** and 4 dimensional slices through a n-cube of rank no more +** than 5 (and at least the rank of the slice) as the other. +** Note that the "irregular" selection may be offset between ** the n-cube and the slice. ** ** All the irregular selections will be identical (modulo rank) ** so H5S_select_shape_same() should return true iff: ** -** 1) the rank of the n cube equals the number of dimensions -** selected in the irregular slice through the m-cube +** 1) the rank of the n cube equals the number of dimensions +** selected in the irregular slice through the m-cube ** (m >= n). ** -** 2) The dimensions selected in the irregular slice -** through the m-cube are the dimensions with the most +** 2) The dimensions selected in the irregular slice +** through the m-cube are the dimensions with the most ** quickly changing indices. ** ****************************************************************/ @@ -11649,7 +11657,7 @@ test_shape_same_dr__run_irregular_tests(void) dim_selected[4] = FALSE; else dim_selected[4] = TRUE; - + /* compute the expected result: */ i = 0; @@ -11795,8 +11803,8 @@ test_shape_same_dr__run_irregular_tests(void) /**************************************************************** ** -** test_shape_same_dr(): Tests selections on dataspace with -** different ranks, to verify that "shape same" routine +** test_shape_same_dr(): Tests selections on dataspace with +** different ranks, to verify that "shape same" routine ** is now handling this case correctly. ** ****************************************************************/ @@ -11913,7 +11921,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_reg1); + rebuild_stat = H5S__get_rebuild_status_test(sid_reg1); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be TRUE. */ if(!rebuild_stat){ @@ -11922,7 +11930,7 @@ test_space_rebuild(void) } else { /* In this case, rebuild_check should be TRUE. */ - rebuild_check = H5S_select_shape_same_test(sid_reg1,sid_reg_ori1); + rebuild_check = H5S__select_shape_same_test(sid_reg1,sid_reg_ori1); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); } @@ -11945,7 +11953,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_irreg1); + rebuild_stat = H5S__get_rebuild_status_test(sid_irreg1); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -11992,7 +12000,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_reg2); + rebuild_stat = H5S__get_rebuild_status_test(sid_reg2); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be TRUE. */ if(!rebuild_stat){ @@ -12001,7 +12009,7 @@ test_space_rebuild(void) } else { /* In this case, rebuild_check should be TRUE. */ - rebuild_check = H5S_select_shape_same_test(sid_reg2,sid_reg_ori2); + rebuild_check = H5S__select_shape_same_test(sid_reg2,sid_reg_ori2); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); } @@ -12029,7 +12037,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_irreg2); + rebuild_stat = H5S__get_rebuild_status_test(sid_irreg2); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -12081,7 +12089,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_reg3); + rebuild_stat = H5S__get_rebuild_status_test(sid_reg3); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be TRUE. */ @@ -12091,7 +12099,7 @@ test_space_rebuild(void) } else { /* In this case, rebuild_check should be TRUE. */ - rebuild_check = H5S_select_shape_same_test(sid_reg3,sid_reg_ori3); + rebuild_check = H5S__select_shape_same_test(sid_reg3,sid_reg_ori3); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); } @@ -12124,7 +12132,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_irreg3); + rebuild_stat = H5S__get_rebuild_status_test(sid_irreg3); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -12184,7 +12192,7 @@ test_space_rebuild(void) rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_reg4); + rebuild_stat = H5S__get_rebuild_status_test(sid_reg4); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be TRUE. */ if(!rebuild_stat){ @@ -12193,7 +12201,7 @@ test_space_rebuild(void) } else { /* In this case, rebuild_check should be TRUE. */ - rebuild_check = H5S_select_shape_same_test(sid_reg4,sid_reg_ori4); + rebuild_check = H5S__select_shape_same_test(sid_reg4,sid_reg_ori4); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); } @@ -12237,7 +12245,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_irreg4); + rebuild_stat = H5S__get_rebuild_status_test(sid_irreg4); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -12301,7 +12309,7 @@ test_space_rebuild(void) rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_reg5); + rebuild_stat = H5S__get_rebuild_status_test(sid_reg5); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be TRUE. */ if(!rebuild_stat){ @@ -12310,7 +12318,7 @@ test_space_rebuild(void) } else { /* In this case, rebuild_check should be TRUE. */ - rebuild_check = H5S_select_shape_same_test(sid_reg5,sid_reg_ori5); + rebuild_check = H5S__select_shape_same_test(sid_reg5,sid_reg_ori5); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); } @@ -12359,7 +12367,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_irreg5); + rebuild_stat = H5S__get_rebuild_status_test(sid_irreg5); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -12400,7 +12408,7 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_spec,H5S_SELECT_SET,start5,stride5,count5,block5); CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_spec); + rebuild_stat = H5S__get_rebuild_status_test(sid_spec); /* In this case, rebuild_stat should be TRUE. */ if(!rebuild_stat){ ret = FAIL; @@ -12422,7 +12430,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = TRUE; - rebuild_stat = H5S_get_rebuild_status_test(sid_spec); + rebuild_stat = H5S__get_rebuild_status_test(sid_spec); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(rebuild_stat){ @@ -12445,7 +12453,7 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); rebuild_stat = FALSE; - rebuild_stat = H5S_get_rebuild_status_test(sid_spec); + rebuild_stat = H5S__get_rebuild_status_test(sid_spec); assert(rebuild_stat!=FAIL); /* In this case, rebuild_stat should be FALSE. */ if(!rebuild_stat){ @@ -12861,9 +12869,9 @@ test_select_bounds(void) /* Get bounds for 'none' selection */ H5E_BEGIN_TRY { ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bo unds"); - + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bo unds"); + /* Set point selection */ coord[0][0] = 3; coord[0][1] = 3; coord[1][0] = 3; coord[1][1] = 96; @@ -13040,14 +13048,14 @@ test_hyper_regular(void) /* Query if 'all' selection is regular hyperslab (should fail) */ H5E_BEGIN_TRY { is_regular = H5Sis_regular_hyperslab(sid); - } H5E_END_TRY; - VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); /* Query regular hyperslab selection info (should fail) */ H5E_BEGIN_TRY { ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); /* Set 'none' selection */ ret = H5Sselect_none(sid); @@ -13056,14 +13064,14 @@ test_hyper_regular(void) /* Query if 'none' selection is regular hyperslab (should fail) */ H5E_BEGIN_TRY { is_regular = H5Sis_regular_hyperslab(sid); - } H5E_END_TRY; - VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); /* Query regular hyperslab selection info (should fail) */ H5E_BEGIN_TRY { ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); /* Set point selection */ coord[0][0] = 3; coord[0][1] = 3; coord[0][2] = 3; @@ -13076,14 +13084,14 @@ test_hyper_regular(void) /* Query if 'point' selection is regular hyperslab (should fail) */ H5E_BEGIN_TRY { is_regular = H5Sis_regular_hyperslab(sid); - } H5E_END_TRY; - VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); /* Query regular hyperslab selection info (should fail) */ H5E_BEGIN_TRY { ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); /* Set "regular" hyperslab selection */ start[0] = 2; start[1] = 2; start[2] = 2; @@ -13095,7 +13103,7 @@ test_hyper_regular(void) /* Query if 'hyperslab' selection is regular hyperslab (should be TRUE) */ is_regular = H5Sis_regular_hyperslab(sid); - VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); + VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); /* Retrieve the hyperslab parameters */ ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); @@ -13121,13 +13129,13 @@ test_hyper_regular(void) /* Query if 'hyperslab' selection is regular hyperslab (should be FALSE) */ is_regular = H5Sis_regular_hyperslab(sid); - VERIFY(is_regular, FALSE, "H5Sis_regular_hyperslab"); + VERIFY(is_regular, FALSE, "H5Sis_regular_hyperslab"); /* Query regular hyperslab selection info (should fail) */ H5E_BEGIN_TRY { ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); /* 'XOR' in the point again, to remove it, which should make it regular again */ t_start[0] = 0; t_start[1] = 0; t_start[2] = 0; @@ -13137,7 +13145,7 @@ test_hyper_regular(void) /* Query if 'hyperslab' selection is regular hyperslab (should be TRUE) */ is_regular = H5Sis_regular_hyperslab(sid); - VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); + VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); /* Retrieve the hyperslab parameters */ ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); diff --git a/testpar/t_shapesame.c b/testpar/t_shapesame.c index eddbada..f5282bd 100644 --- a/testpar/t_shapesame.c +++ b/testpar/t_shapesame.c @@ -948,9 +948,9 @@ contig_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t * tv_ptr) /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->small_ds_slice_sid, + check = H5S__select_shape_same_test(tv_ptr->small_ds_slice_sid, tv_ptr->file_large_ds_sid_0); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* Read selection from disk */ @@ -1216,9 +1216,9 @@ contig_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t * tv_ptr) /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0, + check = H5S__select_shape_same_test(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* Read selection from disk */ @@ -1531,9 +1531,9 @@ contig_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t * tv_ptr) * memory slice through the cube selection and the * on disk full square selections as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0, + check = H5S__select_shape_same_test(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed."); + VRFY((check == TRUE), "H5S__select_shape_same_test passed."); /* write the slice from the in memory large data set to the @@ -1864,9 +1864,9 @@ contig_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t * tv_ptr) * on disk slice through the large data set selection * as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->mem_small_ds_sid, + check = H5S__select_shape_same_test(tv_ptr->mem_small_ds_sid, tv_ptr->file_large_ds_sid_0); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* write the small data set slice from memory to the @@ -3149,9 +3149,9 @@ ckrbrd_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t * tv_ptr) /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->small_ds_slice_sid, + check = H5S__select_shape_same_test(tv_ptr->small_ds_slice_sid, tv_ptr->file_large_ds_sid_0); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* Read selection from disk */ @@ -3415,9 +3415,9 @@ ckrbrd_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t * tv_ptr) /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0, + check = H5S__select_shape_same_test(tv_ptr->file_small_ds_sid_0, tv_ptr->mem_large_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* Read selection from disk */ @@ -3800,9 +3800,9 @@ ckrbrd_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t * tv_ptr) * large dataset and the checkerboard selection of the process * slice of the small data set as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_1, + check = H5S__select_shape_same_test(tv_ptr->file_small_ds_sid_1, tv_ptr->mem_large_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed."); + VRFY((check == TRUE), "H5S__select_shape_same_test passed."); /* write the checker board selection of the slice from the in @@ -4155,9 +4155,9 @@ ckrbrd_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t * tv_ptr) * on disk slice through the large data set selection * as having the same shape. */ - check = H5S_select_shape_same_test(tv_ptr->mem_small_ds_sid, + check = H5S__select_shape_same_test(tv_ptr->mem_small_ds_sid, tv_ptr->file_large_ds_sid_1); - VRFY((check == TRUE), "H5S_select_shape_same_test passed"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed"); /* write the small data set slice from memory to the diff --git a/testpar/t_span_tree.c b/testpar/t_span_tree.c index 02d2cca..cc79af2 100644 --- a/testpar/t_span_tree.c +++ b/testpar/t_span_tree.c @@ -2334,9 +2334,9 @@ lower_dim_size_comp_test__run_test(const int chunk_edge_size, /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(mem_large_ds_sid, + check = H5S__select_shape_same_test(mem_large_ds_sid, file_small_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed (1)"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed (1)"); ret = H5Dread(small_dataset, @@ -2455,9 +2455,9 @@ lower_dim_size_comp_test__run_test(const int chunk_edge_size, /* verify that H5S_select_shape_same() reports the two * selections as having the same shape. */ - check = H5S_select_shape_same_test(mem_small_ds_sid, + check = H5S__select_shape_same_test(mem_small_ds_sid, file_large_ds_sid); - VRFY((check == TRUE), "H5S_select_shape_same_test passed (2)"); + VRFY((check == TRUE), "H5S__select_shape_same_test passed (2)"); ret = H5Dread(large_dataset, @@ -2622,31 +2622,27 @@ void lower_dim_size_comp_test(void) { /* const char *fcnName = "lower_dim_size_comp_test()"; */ - int chunk_edge_size = 0; - int use_collective_io = 1; - hid_t dset_type = H5T_NATIVE_UINT; + int chunk_edge_size = 0; + int use_collective_io; + #if 0 HDsleep(60); #endif - HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned)); - for ( use_collective_io = (hbool_t)0; - (int)use_collective_io <= 1; - (hbool_t)(use_collective_io++) ) { + HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned)); + for(use_collective_io = 0; use_collective_io <= 1; use_collective_io++) { chunk_edge_size = 0; lower_dim_size_comp_test__run_test(chunk_edge_size, (hbool_t)use_collective_io, - dset_type); - + H5T_NATIVE_UINT); chunk_edge_size = 5; lower_dim_size_comp_test__run_test(chunk_edge_size, (hbool_t)use_collective_io, - dset_type); - } + H5T_NATIVE_UINT); + } /* end for */ return; - } /* lower_dim_size_comp_test() */ -- cgit v0.12 From 3ed1ac0f1b760fe84ec009de19550d98f0b38071 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Wed, 13 Feb 2019 08:24:27 -0600 Subject: Add missing toolchain include for cross-compile --- config/cmake/scripts/HPC/sbatch-HDF5options.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/config/cmake/scripts/HPC/sbatch-HDF5options.cmake b/config/cmake/scripts/HPC/sbatch-HDF5options.cmake index dc97b3a..f70526e 100644 --- a/config/cmake/scripts/HPC/sbatch-HDF5options.cmake +++ b/config/cmake/scripts/HPC/sbatch-HDF5options.cmake @@ -34,6 +34,7 @@ if (DEFINED KNL) set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") set (LOCAL_BATCH_SCRIPT_NAME "knl_ctestS.sl") set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "knl_ctestP.sl") + set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCMAKE_TOOLCHAIN_FILE:STRING=config/toolchain/crayle.cmake") else () set (LOCAL_BATCH_SCRIPT_NAME "ctestS.sl") set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ctestP.sl") -- cgit v0.12 From b95f05638ce40ccd944248f5865a248f39ef0d10 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Wed, 13 Feb 2019 15:53:25 -0600 Subject: TRILAB-111 fixes for parallel testing --- CTestConfig.cmake | 4 +- config/cmake/hdf5-config.cmake.in | 3 + config/cmake/scripts/CTestScript.cmake | 8 +- config/cmake/scripts/HPC/bsub-HDF5options.cmake | 13 +- config/cmake/scripts/HPC/raybsub-HDF5options.cmake | 13 +- config/toolchain/crayle.cmake | 10 - src/CMakeLists.txt | 2 +- test/CMakeTests.cmake | 97 +++--- test/CMakeVFDTests.cmake | 100 +++++- test/CMakeVOLTests.cmake | 106 ++++++- test/testframe.c | 338 +++++++++++---------- testpar/CMakeLists.txt | 2 +- testpar/CMakeTests.cmake | 68 ++++- testpar/CMakeVFDTests.cmake | 20 +- 14 files changed, 499 insertions(+), 285 deletions(-) diff --git a/CTestConfig.cmake b/CTestConfig.cmake index 5b35688..d80f48f 100644 --- a/CTestConfig.cmake +++ b/CTestConfig.cmake @@ -45,9 +45,9 @@ set (VALGRIND_COMMAND_OPTIONS "-v --tool=memcheck --leak-check=full --track-fds= set (CTEST_MEMORYCHECK_COMMAND "/usr/bin/valgrind") set (CTEST_MEMORYCHECK_COMMAND_OPTIONS "-v --tool=memcheck --leak-check=full --track-fds=yes --num-callers=50 --show-reachable=yes --track-origins=yes --malloc-fill=0xff --free-fill=0xfe") -set (CTEST_TEST_TIMEOUT 600 CACHE STRING +set (CTEST_TEST_TIMEOUT 1200 CACHE STRING "Maximum time allowed before CTest will kill the test.") -set (DART_TESTING_TIMEOUT 600 CACHE STRING +set (DART_TESTING_TIMEOUT 1200 CACHE STRING "Maximum time allowed before CTest will kill the test." FORCE) SET(CTEST_SUBMIT_RETRY_DELAY 20 CACHE STRING diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index e687a58..3bd9e1d 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -38,6 +38,7 @@ set (${HDF5_PACKAGE_NAME}_BUILD_CPP_LIB @HDF5_BUILD_CPP_LIB@) set (${HDF5_PACKAGE_NAME}_BUILD_JAVA @HDF5_BUILD_JAVA@) set (${HDF5_PACKAGE_NAME}_BUILD_TOOLS @HDF5_BUILD_TOOLS@) set (${HDF5_PACKAGE_NAME}_BUILD_HL_LIB @HDF5_BUILD_HL_LIB@) +set (${HDF5_PACKAGE_NAME}_ENABLE_THREADSAFE @HDF5_ENABLE_THREADSAFE@) set (${HDF5_PACKAGE_NAME}_ENABLE_Z_LIB_SUPPORT @HDF5_ENABLE_Z_LIB_SUPPORT@) set (${HDF5_PACKAGE_NAME}_ENABLE_SZIP_SUPPORT @HDF5_ENABLE_SZIP_SUPPORT@) set (${HDF5_PACKAGE_NAME}_ENABLE_SZIP_ENCODING @HDF5_ENABLE_SZIP_ENCODING@) @@ -45,6 +46,8 @@ set (${HDF5_PACKAGE_NAME}_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@) set (${HDF5_PACKAGE_NAME}_PACKAGE_EXTLIBS @HDF5_PACKAGE_EXTLIBS@) set (${HDF5_PACKAGE_NAME}_EXPORT_LIBRARIES @HDF5_LIBRARIES_TO_EXPORT@) set (${HDF5_PACKAGE_NAME}_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") +set (${HDF5_PACKAGE_NAME}_DEFAULT_API_VERSION "@DEFAULT_API_VERSION@") +set (${HDF5_PACKAGE_NAME}_PARALLEL_FILTERED_WRITES "@PARALLEL_FILTERED_WRITES@") #----------------------------------------------------------------------------- # Dependencies diff --git a/config/cmake/scripts/CTestScript.cmake b/config/cmake/scripts/CTestScript.cmake index 0e2afc7..6958f31 100644 --- a/config/cmake/scripts/CTestScript.cmake +++ b/config/cmake/scripts/CTestScript.cmake @@ -257,7 +257,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") # On Cray XC40, configuring fails in the Fortran section when using the craype-mic-knl module. # When the configure phase is done with the craype-haswell module and the build phase is done # with the craype-mic-knl module, configure succeeds and tests pass on the knl compute nodes - # for Intel, Cray, GCC and Clang compilers. If the variables aren't set or if not + # for Intel, Cray, GCC and Clang compilers. If the variables aren't set or if not # cross compiling, the module switch will not occur. if (CMAKE_CROSSCOMPILING AND COMPILENODE_HWCOMPILE_MODULE AND COMPUTENODE_HWCOMPILE_MODULE) execute_process (COMMAND module switch ${COMPILENODE_HWCOMPILE_MODULE} ${COMPUTENODE_HWCOMPILE_MODULE}) @@ -277,11 +277,11 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND ${ctest_test_args} RETURN_VALUE res) else () file(STRINGS ${CTEST_BINARY_DIRECTORY}/Testing/TAG TAG_CONTENTS REGEX "^2([0-9]+)[-]([0-9]+)$") - if ("${LOCAL_BATCH_SCRIPT_COMMAND}" STREQUAL "raybsub") + if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) - endif () + endif () message(STATUS "Check for existence of ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/Test.xml") execute_process(COMMAND ls ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/Test.xml RESULT_VARIABLE result OUTPUT_QUIET ERROR_QUIET) while(result) @@ -296,7 +296,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/Test.xml ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/SerialTest.xml) file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}.log ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}_Serial.log) unset(result CACHE) - if ("${LOCAL_BATCH_SCRIPT_COMMAND}" STREQUAL "raybsub") + if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) diff --git a/config/cmake/scripts/HPC/bsub-HDF5options.cmake b/config/cmake/scripts/HPC/bsub-HDF5options.cmake index a862a6b..83c17aa 100644 --- a/config/cmake/scripts/HPC/bsub-HDF5options.cmake +++ b/config/cmake/scripts/HPC/bsub-HDF5options.cmake @@ -33,17 +33,8 @@ set (LOCAL_BATCH_TEST "TRUE") set (LOCAL_BATCH_SCRIPT_NAME "ctestS.lsf") set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ctestP.lsf") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_TEST:BOOL=ON") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=ctestS.lsf") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=ctestP.lsf") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=${LOCAL_BATCH_SCRIPT_NAME}") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_EXECUTABLE:STRING=srun") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_NUMPROC_FLAG:STRING=-n") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_MAX_NUMPROCS:STRING=6") - -############################################################################################# -### some additions and alternatives to cross compile on haswell for knl -#set (COMPILENODE_HWCOMPILE_MODULE "craype-haswell") -#set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") -#set (SITE_BUILDNAME_SUFFIX "knl-intel17-SHARED" -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=knl_ctestS.sl") -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=knl_ctestP.sl") -############################################################################################# diff --git a/config/cmake/scripts/HPC/raybsub-HDF5options.cmake b/config/cmake/scripts/HPC/raybsub-HDF5options.cmake index d3c8721..9775979 100644 --- a/config/cmake/scripts/HPC/raybsub-HDF5options.cmake +++ b/config/cmake/scripts/HPC/raybsub-HDF5options.cmake @@ -33,17 +33,8 @@ set (LOCAL_BATCH_TEST "TRUE") set (LOCAL_BATCH_SCRIPT_NAME "ray_ctestS.lsf") set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ray_ctestP.lsf") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_TEST:BOOL=ON") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=ray_ctestS.lsf") -set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=ray_ctestP.lsf") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=${LOCAL_BATCH_SCRIPT_NAME}") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_EXECUTABLE:STRING=mpirun") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_NUMPROC_FLAG:STRING=-np") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_MAX_NUMPROCS:STRING=6") - -############################################################################################# -### some additions and alternatives to cross compile on haswell for knl -#set (COMPILENODE_HWCOMPILE_MODULE "craype-haswell") -#set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") -#set (SITE_BUILDNAME_SUFFIX "knl-intel17-SHARED" -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=knl_ctestS.sl") -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=knl_ctestP.sl") -############################################################################################# diff --git a/config/toolchain/crayle.cmake b/config/toolchain/crayle.cmake index 159f43a..bf7cf69 100644 --- a/config/toolchain/crayle.cmake +++ b/config/toolchain/crayle.cmake @@ -8,13 +8,3 @@ set(CMAKE_Fortran_COMPILER ftn) # the following is used if cross-compiling set(CMAKE_CROSSCOMPILING_EMULATOR "") - -# option to use pre-generated H5Tinit.c file -set(HDF5_USE_PREGEN OFF) -# directory where H5Tinit.c file will be found -#set(HDF5_USE_PREGEN_DIR "/lscratch1/lknox/HDF5_1_10_4/CMake-hdf5-1.10.4") - -# option to generate H5Tinit.c by running H5detect on knl compute node during build -#set(HDF5_BATCH_H5DETECT ON) -#set(HDF5_BATCH_CMD "sbatch") -#set(HDF5_BATCH_H5DETECT_SCRIPT "knl_H5detect.sl") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b105a9..4d77a8b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -944,7 +944,7 @@ if (BUILD_SHARED_LIBS) endif () if (LOCAL_BATCH_TEST) - if ("${LOCAL_BATCH_SCRIPT_COMMAND}" STREQUAL "raybsub") + if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") configure_file ( ${HDF5_SOURCE_DIR}/bin/batch/${LOCAL_BATCH_SCRIPT_COMMAND} ${HDF5_BINARY_DIR}/${LOCAL_BATCH_SCRIPT_COMMAND} ESCAPE_QUOTES @ONLY diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index ba72e3a..b087172 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -231,47 +231,31 @@ add_test (NAME H5TEST-clear-testhdf5-objects ) set_tests_properties (H5TEST-clear-testhdf5-objects PROPERTIES FIXTURES_SETUP clear_testhdf5) -if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME H5TEST-testhdf5-base COMMAND $ -x heap -x file -x select) - set_tests_properties (H5TEST-testhdf5-base PROPERTIES - FIXTURES_REQUIRED clear_testhdf5 - ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" - WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - ) - add_test (NAME H5TEST-testhdf5-heap COMMAND $ -o heap) - set_tests_properties (H5TEST-testhdf5-heap PROPERTIES - FIXTURES_REQUIRED clear_testhdf5 - ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" - WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - ) - add_test (NAME H5TEST-testhdf5-file COMMAND $ -o file) - set_tests_properties (H5TEST-testhdf5-file PROPERTIES - FIXTURES_REQUIRED clear_testhdf5 - ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" - WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - ) - add_test (NAME H5TEST-testhdf5-select COMMAND $ -o select) - set_tests_properties (H5TEST-testhdf5-select PROPERTIES - FIXTURES_REQUIRED clear_testhdf5 - ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" - WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - ) -else () - add_test (NAME H5TEST-testhdf5 COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=testhdf5.txt" - #-D "TEST_REFERENCE=testhdf5.out" - -D "TEST_FOLDER=${HDF5_TEST_BINARY_DIR}/H5TEST" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" - ) - set_tests_properties (H5TEST-testhdf5 PROPERTIES - FIXTURES_REQUIRED clear_testhdf5 - ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" - WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - ) +add_test (NAME H5TEST-testhdf5-base COMMAND $ -x heap -x file -x select) +set_tests_properties (H5TEST-testhdf5-base PROPERTIES + FIXTURES_REQUIRED clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST +) +add_test (NAME H5TEST-testhdf5-heap COMMAND $ -o heap) +set_tests_properties (H5TEST-testhdf5-heap PROPERTIES + FIXTURES_REQUIRED clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST +) +add_test (NAME H5TEST-testhdf5-file COMMAND $ -o file) +set_tests_properties (H5TEST-testhdf5-file PROPERTIES + FIXTURES_REQUIRED clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST +) +add_test (NAME H5TEST-testhdf5-select COMMAND $ -o select) +set_tests_properties (H5TEST-testhdf5-select PROPERTIES + FIXTURES_REQUIRED clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST +) +if (NOT HDF5_ENABLE_USING_MEMCHECKER) if (BUILD_SHARED_LIBS) add_test (NAME H5TEST-shared-clear-testhdf5-objects COMMAND ${CMAKE_COMMAND} @@ -298,19 +282,28 @@ else () ${HDF5_TEST_BINARY_DIR}/H5TEST-shared ) set_tests_properties (H5TEST-shared-clear-testhdf5-objects PROPERTIES FIXTURES_SETUP shared_clear_testhdf5) - add_test (NAME H5TEST-shared-testhdf5 COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS:STRING=" - -D "TEST_EXPECT=0" - -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=testhdf5.txt" - #-D "TEST_REFERENCE=testhdf5.out" - -D "TEST_FOLDER=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + add_test (NAME H5TEST-shared-testhdf5-base COMMAND $ -x heap -x file -x select) + set_tests_properties (H5TEST-shared-testhdf5-base PROPERTIES + FIXTURES_REQUIRED shared_clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST-shared ) - set_tests_properties (H5TEST-shared-testhdf5 PROPERTIES + add_test (NAME H5TEST-shared-testhdf5-heap COMMAND $ -o heap) + set_tests_properties (H5TEST-shared-testhdf5-heap PROPERTIES FIXTURES_REQUIRED shared_clear_testhdf5 - ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST-shared + ) + add_test (NAME H5TEST-shared-testhdf5-file COMMAND $ -o file) + set_tests_properties (H5TEST-shared-testhdf5-file PROPERTIES + FIXTURES_REQUIRED shared_clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" + WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST-shared + ) + add_test (NAME H5TEST-shared-testhdf5-select COMMAND $ -o select) + set_tests_properties (H5TEST-shared-testhdf5-select PROPERTIES + FIXTURES_REQUIRED shared_clear_testhdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST-shared ) endif () diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index 9f03c40..0d51e25 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -111,32 +111,48 @@ endif () if ("${vfdtest}" STREQUAL "flush1" OR "${vfdtest}" STREQUAL "flush2") if ("${vfdname}" STREQUAL "multi" OR "${vfdname}" STREQUAL "split") if (NOT BUILD_SHARED_LIBS AND NOT ${HDF_CFG_NAME} MATCHES "Debug") + add_test ( + NAME VFD-${vfdname}-${vfdtest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}/${vfdname}-${vfdtest}.out + ${vfdname}/${vfdname}-${vfdtest}.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest} PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out.err + ) add_test (NAME VFD-${vfdname}-${test}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}-shared" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest}-shared PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname}-shared ) @@ -152,64 +168,96 @@ endif () endif () endif () else () + add_test ( + NAME VFD-${vfdname}-${vfdtest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}/${vfdname}-${vfdtest}.out + ${vfdname}/${vfdname}-${vfdtest}.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest} PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out.err + ) add_test (NAME VFD-${vfdname}-${test}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}-shared" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest}-shared PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname}-shared ) endif () endif () else () + add_test ( + NAME VFD-${vfdname}-${vfdtest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}/${vfdname}-${vfdtest}.out + ${vfdname}/${vfdname}-${vfdtest}.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest} PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) if (BUILD_SHARED_LIBS AND NOT "${vfdtest}" STREQUAL "cache") + add_test ( + NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}-shared" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest}-shared PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}-shared;HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname}-shared ) @@ -218,32 +266,48 @@ endif () endmacro () macro (DO_VFD_TEST vfdtest vfdname resultcode) + add_test ( + NAME VFD-${vfdname}-${vfdtest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}/${vfdname}-${vfdtest}.out + ${vfdname}/${vfdname}-${vfdtest}.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest} PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out + ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out.err + ) add_test (NAME VFD-${vfdname}-${vfdtest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared" + -D "TEST_OUTPUT=${vfdname}-${vfdtest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}-shared" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-${vfdtest}-shared PROPERTIES + DEPENDS VFD-${vfdname}-${vfdtest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname}-shared ) @@ -277,33 +341,49 @@ endif () endif () endif () if (HDF5_TEST_FHEAP_VFD) + add_test ( + NAME VFD-${vfdname}-fheap-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}/${vfdname}-fheap.out + ${vfdname}/${vfdname}-fheap.out.err + ) add_test (NAME VFD-${vfdname}-fheap COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-fheap" + -D "TEST_OUTPUT=${vfdname}-fheap.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-fheap PROPERTIES + DEPENDS VFD-${vfdname}-fheap-clear-objects TIMEOUT ${CTEST_VERY_LONG_TIMEOUT} ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VFD-${vfdname}-fheap-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-fheap-shared.out + ${vfdname}-shared/${vfdname}-fheap-shared.out.err + ) add_test (NAME VFD-${vfdname}-fheap-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-fheap-shared" + -D "TEST_OUTPUT=${vfdname}-fheap-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}-shared" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) set_tests_properties (VFD-${vfdname}-fheap-shared PROPERTIES + DEPENDS VFD-${vfdname}-fheap-shared-clear-objects TIMEOUT ${CTEST_VERY_LONG_TIMEOUT} ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname}-shared;HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname}-shared diff --git a/test/CMakeVOLTests.cmake b/test/CMakeVOLTests.cmake index fdd7ba0..d7da159 100644 --- a/test/CMakeVOLTests.cmake +++ b/test/CMakeVOLTests.cmake @@ -108,32 +108,48 @@ endif () if ("${voltest}" STREQUAL "flush1" OR "${voltest}" STREQUAL "flush2") if ("${volname}" STREQUAL "multi" OR "${volname}" STREQUAL "split") if (NOT BUILD_SHARED_LIBS AND NOT ${HDF_CFG_NAME} MATCHES "Debug") + add_test ( + NAME VOL-${volname}-${voltest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}/${volname}-${voltest}.out + ${volname}/${volname}-${voltest}.out.err + ) add_test (NAME VOL-${volname}-${voltest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}" + -D "TEST_OUTPUT=${volname}-${voltest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest} PROPERTIES + DEPENDS VOL-${volname}-${voltest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) if (BUILD_SHARED_LIBS) - add_test (NAME VOL-${volname}-${test}-shared + add_test ( + NAME VOL-${volname}-${voltest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}-shared/${volname}-${voltest}-shared.out + ${volname}-shared/${volname}-${voltest}-shared.out.err + ) + add_test (NAME VOL-${volname}-${voltest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}-shared" + -D "TEST_OUTPUT=${volname}-${voltest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}-shared" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest}-shared PROPERTIES + DEPENDS VOL-${volname}-${voltest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname}-shared ) @@ -143,70 +159,102 @@ endif () COMMAND ${CMAKE_COMMAND} -E echo "SKIP VOL-${volname}-${voltest}" ) if (BUILD_SHARED_LIBS) - add_test (NAME VOL-${volname}-${test}-shared + add_test (NAME VOL-${volname}-${voltest}-shared COMMAND ${CMAKE_COMMAND} -E echo "SKIP VOL-${volname}-${voltest}-shared" ) endif () endif () else () + add_test ( + NAME VOL-${volname}-${voltest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}/${volname}-${voltest}.out + ${volname}/${volname}-${voltest}.out.err + ) add_test (NAME VOL-${volname}-${voltest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}" + -D "TEST_OUTPUT=${volname}-${voltest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest} PROPERTIES + DEPENDS VOL-${volname}-${voltest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) if (BUILD_SHARED_LIBS) - add_test (NAME VOL-${volname}-${test}-shared + add_test ( + NAME VOL-${volname}-${voltest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}-shared/${volname}-${voltest}-shared.out + ${volname}-shared/${volname}-${voltest}-shared.out.err + ) + add_test (NAME VOL-${volname}-${voltest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}-shared" + -D "TEST_OUTPUT=${volname}-${voltest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}-shared" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest}-shared PROPERTIES + DEPENDS VOL-${volname}-${voltest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname}-shared ) endif () endif () else () + add_test ( + NAME VOL-${volname}-${voltest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}/${volname}-${voltest}.out + ${volname}/${volname}-${voltest}.out.err + ) add_test (NAME VOL-${volname}-${voltest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}" + -D "TEST_OUTPUT=${volname}-${voltest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest} PROPERTIES + DEPENDS VOL-${volname}-${voltest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) if (BUILD_SHARED_LIBS AND NOT "${voltest}" STREQUAL "cache") + add_test ( + NAME VOL-${volname}-${voltest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}-shared/${volname}-${voltest}-shared.out + ${volname}-shared/${volname}-${voltest}-shared.out.err + ) add_test (NAME VOL-${volname}-${voltest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}-shared" + -D "TEST_OUTPUT=${volname}-${voltest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}-shared" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest}-shared PROPERTIES + DEPENDS VOL-${volname}-${voltest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}-shared;HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname}-shared ) @@ -216,32 +264,48 @@ endif () macro (DO_VOL_TEST voltest volname volinfo resultcode) #message(STATUS "${voltest}-${volname} with ${volinfo}") + add_test ( + NAME VOL-${volname}-${voltest}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}/${volname}-${voltest}.out + ${volname}/${volname}-${voltest}.out.err + ) add_test (NAME VOL-${volname}-${voltest} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}" + -D "TEST_OUTPUT=${volname}-${voltest}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest} PROPERTIES + DEPENDS VOL-${volname}-${voltest}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VOL-${volname}-${voltest}-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}-shared/${volname}-${voltest}-shared.out + ${volname}-shared/${volname}-${voltest}-shared.out.err + ) add_test (NAME VOL-${volname}-${voltest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-${voltest}-shared" + -D "TEST_OUTPUT=${volname}-${voltest}-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}-shared" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-${voltest}-shared PROPERTIES + DEPENDS VOL-${volname}-${voltest}-shared-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname}-shared ) @@ -276,33 +340,49 @@ endif () endif () endif () if (HDF5_TEST_FHEAP_VOL) + add_test ( + NAME VOL-${volname}-fheap-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}/${volname}-fheap.out + ${volname}/${volname}-fheap.out.err + ) add_test (NAME VOL-${volname}-fheap COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-fheap" + -D "TEST_OUTPUT=${volname}-fheap.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-fheap PROPERTIES + DEPENDS VOL-${volname}-fheap-clear-objects TIMEOUT ${CTEST_VERY_LONG_TIMEOUT} ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) if (BUILD_SHARED_LIBS) + add_test ( + NAME VOL-${volname}-fheap-shared-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${volname}-shared/${volname}-fheap-shared.out + ${volname}-shared/${volname}-fheap-shared.out.err + ) add_test (NAME VOL-${volname}-fheap-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VOL:STRING=${volinfo}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${volname}-fheap-shared" + -D "TEST_OUTPUT=${volname}-fheap-shared.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${volname}-shared" -P "${HDF_RESOURCES_DIR}/volTest.cmake" ) set_tests_properties (VOL-${volname}-fheap-shared PROPERTIES + DEPENDS VOL-${volname}-fheap-shared-clear-objects TIMEOUT ${CTEST_VERY_LONG_TIMEOUT} ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname}-shared;HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname}-shared diff --git a/test/testframe.c b/test/testframe.c index 335118c..97b2d1f 100644 --- a/test/testframe.c +++ b/test/testframe.c @@ -15,7 +15,7 @@ * Programmer: Quincey Koziol * Tuesday, January 6, 2004 * - * Purpose: Provides support functions for the testing framework. + * Purpose: Provides support functions for the testing framework. * */ @@ -28,24 +28,25 @@ #define MAXTESTDESC 64 typedef struct TestStruct { - int NumErrors; - char Description[MAXTESTDESC]; - int SkipFlag; - char Name[MAXTESTNAME]; - void (*Call)(void); - void (*Cleanup)(void); - const void *Parameters; + int NumErrors; + char Description[MAXTESTDESC]; + int SkipFlag; + char Name[MAXTESTNAME]; + void (*Call)(void); + void (*Cleanup)(void); + const void *Parameters; } TestStruct; /* * Variables used by testing framework. */ +static int enable_error_stack = 0; /* enable error stack; disable=0 enable=1 */ static int num_errs = 0; /* Total number of errors during testing */ int TestVerbosity = VERBO_DEF; /* Default Verbosity is Low */ -static int Summary = 0; /* Show test summary. Default is no. */ -static int CleanUp = 1; /* Do cleanup or not. Default is yes. */ -static int TestExpress = -1; /* Do TestExpress or not. -1 means not set yet. */ +static int Summary = 0; /* Show test summary. Default is no. */ +static int CleanUp = 1; /* Do cleanup or not. Default is yes. */ +static int TestExpress = -1; /* Do TestExpress or not. -1 means not set yet. */ static TestStruct *Test = NULL; /* Array of tests */ static unsigned TestAlloc = 0; /* Size of the Test array */ static unsigned Index = 0; @@ -54,7 +55,7 @@ static const char *TestProgName = NULL; static void (*TestPrivateUsage)(void) = NULL; static int (*TestPrivateParser)(int ac, char *av[]) = NULL; - + /* * Setup a test function and add it to the list of tests. * It must have no parameters and returns void. @@ -74,12 +75,12 @@ AddTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), con /* Sanity checking */ if (HDstrlen(TheDescr) >= MAXTESTDESC) { printf("Test description ('%s') too long, increase MAXTESTDESC(%d).\n", - TheDescr, MAXTESTDESC); + TheDescr, MAXTESTDESC); exit(EXIT_FAILURE); } /* end if */ if (HDstrlen(TheName) >= MAXTESTNAME) { printf("Test name too long, increase MAXTESTNAME(%d).\n", - MAXTESTNAME); + MAXTESTNAME); exit(EXIT_FAILURE); } /* end if */ @@ -102,12 +103,12 @@ AddTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), con /* Set up test function */ HDstrcpy(Test[Index].Description, TheDescr); if(*TheName != '-') { - HDstrcpy(Test[Index].Name, TheName); - Test[Index].SkipFlag = 0; + HDstrcpy(Test[Index].Name, TheName); + Test[Index].SkipFlag = 0; } - else { /* skip test by default */ - HDstrcpy(Test[Index].Name, TheName+1); - Test[Index].SkipFlag = 1; + else { /* skip test by default */ + HDstrcpy(Test[Index].Name, TheName+1); + Test[Index].SkipFlag = 1; } Test[Index].Call = TheCall; Test[Index].Cleanup = Cleanup; @@ -118,7 +119,7 @@ AddTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), con Index++; } - + /* * Initialize testing framework * @@ -130,8 +131,8 @@ AddTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), con * private options. Default to NULL which means none is provided. * * Modifications: - * Albert Cheng 2004/08/17 - * Added the ProgName, private_usage and private_parser arguments. + * Albert Cheng 2004/08/17 + * Added the ProgName, private_usage and private_parser arguments. */ void TestInit(const char *ProgName, void (*private_usage)(void), int (*private_parser)(int ac, char *av[])) { @@ -140,7 +141,8 @@ void TestInit(const char *ProgName, void (*private_usage)(void), int (*private_p * half the functions this test calls are private, so automatic error * reporting wouldn't do much good since it's triggered at the API layer. */ - H5Eset_auto2(H5E_DEFAULT, NULL, NULL); + if (enable_error_stack == 0) + H5Eset_auto2(H5E_DEFAULT, NULL, NULL); /* * Record the program name and private routines if provided. @@ -152,50 +154,50 @@ void TestInit(const char *ProgName, void (*private_usage)(void), int (*private_p TestPrivateParser = private_parser; } - + /* * Print test usage. - * First print the common test options, then the extra options if provided. + * First print the common test options, then the extra options if provided. * * Modification: - * 2004/08/18 Albert Cheng. Add TestPrivateUsage feature. + * 2004/08/18 Albert Cheng. Add TestPrivateUsage feature. */ void TestUsage(void) { - unsigned i; - - print_func("Usage: %s [-v[erbose] (l[ow]|m[edium]|h[igh]|0-9)] %s\n", - TestProgName, (TestPrivateUsage ? "" : "")); - print_func(" [-[e]x[clude] name]+ \n"); - print_func(" [-o[nly] name]+ \n"); - print_func(" [-b[egin] name] \n"); - print_func(" [-s[ummary]] \n"); - print_func(" [-c[leanoff]] \n"); - print_func(" [-h[elp]] \n"); - print_func("\n\n"); - print_func("verbose controls the amount of information displayed\n"); - print_func("exclude to exclude tests by name\n"); - print_func("only to name tests which should be run\n"); - print_func("begin start at the name of the test givin\n"); - print_func("summary prints a summary of test results at the end\n"); - print_func("cleanoff does not delete *.hdf files after execution of tests\n"); - print_func("help print out this information\n"); - if (TestPrivateUsage){ - print_func("\nExtra options\n"); - TestPrivateUsage(); - } - print_func("\n\n"); - print_func("This program currently tests the following: \n\n"); - print_func("%16s %s\n", "Name", "Description"); - print_func("%16s %s\n", "----", "-----------"); - - for (i = 0; i < Index; i++) - print_func("%16s %s\n", Test[i].Name, Test[i].Description); - - print_func("\n\n"); + unsigned i; + + print_func("Usage: %s [-v[erbose] (l[ow]|m[edium]|h[igh]|0-9)] %s\n", + TestProgName, (TestPrivateUsage ? "" : "")); + print_func(" [-[e]x[clude] name]+ \n"); + print_func(" [-o[nly] name]+ \n"); + print_func(" [-b[egin] name] \n"); + print_func(" [-s[ummary]] \n"); + print_func(" [-c[leanoff]] \n"); + print_func(" [-h[elp]] \n"); + print_func("\n\n"); + print_func("verbose controls the amount of information displayed\n"); + print_func("exclude to exclude tests by name\n"); + print_func("only to name tests which should be run\n"); + print_func("begin start at the name of the test givin\n"); + print_func("summary prints a summary of test results at the end\n"); + print_func("cleanoff does not delete *.hdf files after execution of tests\n"); + print_func("help print out this information\n"); + if (TestPrivateUsage){ + print_func("\nExtra options\n"); + TestPrivateUsage(); + } + print_func("\n\n"); + print_func("This program currently tests the following: \n\n"); + print_func("%16s %s\n", "Name", "Description"); + print_func("%16s %s\n", "----", "-----------"); + + for (i = 0; i < Index; i++) + print_func("%16s %s\n", Test[i].Name, Test[i].Description); + + print_func("\n\n"); } - + /* * Print test info. */ @@ -209,7 +211,7 @@ void TestInfo(const char *ProgName) print_func("Linked with hdf5 version %u.%u release %u\n", major, minor, release); } - + /* * Parse command line information. * argc, argv: the usual command line argument count and strings @@ -218,7 +220,7 @@ void TestInfo(const char *ProgName) * exit EXIT_FAILURE if error is encountered. * * Modification: - * 2004/08/18 Albert Cheng. Add extra_parse feature. + * 2004/08/18 Albert Cheng. Add extra_parse feature. */ void TestParseCmdLine(int argc, char *argv[]) { @@ -226,80 +228,82 @@ void TestParseCmdLine(int argc, char *argv[]) int ret_code; while (argv++, --argc > 0){ - if ((HDstrcmp(*argv, "-verbose") == 0) || - (HDstrcmp(*argv, "-v") == 0)) { - if (argc > 0){ - --argc; ++argv; - ParseTestVerbosity(*argv); - }else{ - TestUsage(); - exit(EXIT_FAILURE); - } - } - else if (((HDstrcmp(*argv, "-exclude") == 0) || - (HDstrcmp(*argv, "-x") == 0))) { - if (argc > 0){ - --argc; ++argv; - SetTest(*argv, SKIPTEST); - }else{ - TestUsage(); - exit(EXIT_FAILURE); - } - } - else if (((HDstrcmp(*argv, "-begin") == 0) || - (HDstrcmp(*argv, "-b") == 0))) { - if (argc > 0){ - --argc; ++argv; - SetTest(*argv, BEGINTEST); - }else{ - TestUsage(); - exit(EXIT_FAILURE); - } - } - else if (((HDstrcmp(*argv, "-only") == 0) || - (HDstrcmp(*argv, "-o") == 0))) { - if(argc > 0) { - unsigned Loop; - - --argc; ++argv; - - /* Skip all tests, then activate only one. */ + if ((HDstrcmp(*argv, "-verbose") == 0) || + (HDstrcmp(*argv, "-v") == 0)) { + if (argc > 0){ + --argc; ++argv; + ParseTestVerbosity(*argv); + }else{ + TestUsage(); + exit(EXIT_FAILURE); + } + } + else if (((HDstrcmp(*argv, "-exclude") == 0) || + (HDstrcmp(*argv, "-x") == 0))) { + if (argc > 0){ + --argc; ++argv; + SetTest(*argv, SKIPTEST); + }else{ + TestUsage(); + exit(EXIT_FAILURE); + } + } + else if (((HDstrcmp(*argv, "-begin") == 0) || + (HDstrcmp(*argv, "-b") == 0))) { + if (argc > 0){ + --argc; ++argv; + SetTest(*argv, BEGINTEST); + }else{ + TestUsage(); + exit(EXIT_FAILURE); + } + } + else if (((HDstrcmp(*argv, "-only") == 0) || + (HDstrcmp(*argv, "-o") == 0))) { + if(argc > 0) { + unsigned Loop; + + --argc; ++argv; + + /* Skip all tests, then activate only one. */ if(!skipped_all) { for(Loop = 0; Loop < Index; Loop++) Test[Loop].SkipFlag = 1; skipped_all = TRUE; } /* end if */ - SetTest(*argv, ONLYTEST); - } /* end if */ + SetTest(*argv, ONLYTEST); + } /* end if */ else { - TestUsage(); - exit(EXIT_FAILURE); - } - } - else if ((HDstrcmp(*argv, "-summary") == 0) || (HDstrcmp(*argv, "-s") == 0)) - Summary = 1; - else if ((HDstrcmp(*argv, "-help") == 0) || (HDstrcmp(*argv, "-h") == 0)) { - TestUsage(); - exit(EXIT_SUCCESS); + TestUsage(); + exit(EXIT_FAILURE); } - else if ((HDstrcmp(*argv, "-cleanoff") == 0) || (HDstrcmp(*argv, "-c") == 0)) - SetTestNoCleanup(); - else { - /* non-standard option. Break out. */ - break; - } + } + else if ((HDstrcmp(*argv, "-summary") == 0) || (HDstrcmp(*argv, "-s") == 0)) + Summary = 1; + else if (HDstrcmp(*argv, "-enable-error-stack") == 0) + enable_error_stack = 1; + else if ((HDstrcmp(*argv, "-help") == 0) || (HDstrcmp(*argv, "-h") == 0)) { + TestUsage(); + exit(EXIT_SUCCESS); + } + else if ((HDstrcmp(*argv, "-cleanoff") == 0) || (HDstrcmp(*argv, "-c") == 0)) + SetTestNoCleanup(); + else { + /* non-standard option. Break out. */ + break; + } } /* Call extra parsing function if provided. */ if (NULL != TestPrivateParser){ - ret_code=TestPrivateParser(argc+1, argv-1); - if (ret_code != 0) - exit(EXIT_FAILURE); + ret_code=TestPrivateParser(argc+1, argv-1); + if (ret_code != 0) + exit(EXIT_FAILURE); } } - + /* * Perform Tests. */ @@ -314,10 +318,10 @@ void PerformTests(void) MESSAGE(2, ("Testing -- %s (%s) \n", Test[Loop].Description, Test[Loop].Name)); MESSAGE(5, ("===============================================\n")); Test[Loop].NumErrors = num_errs; - Test_parameters = Test[Loop].Parameters; - ALARM_ON; + Test_parameters = Test[Loop].Parameters; + ALARM_ON; Test[Loop].Call(); - ALARM_OFF; + ALARM_OFF; Test[Loop].NumErrors = num_errs - Test[Loop].NumErrors; MESSAGE(5, ("===============================================\n")); MESSAGE(5, ("There were %d errors detected.\n\n", (int)Test[Loop].NumErrors)); @@ -332,7 +336,7 @@ void PerformTests(void) print_func("All tests were successful. \n\n"); } - + /* * Display test summary. */ @@ -354,7 +358,7 @@ void TestSummary(void) print_func("\n\n"); } - + /* * Cleanup files from testing */ @@ -370,7 +374,7 @@ void TestCleanup(void) Test[Loop].Cleanup(); } - + /* * Shutdown the test infrastructure */ @@ -380,7 +384,7 @@ void TestShutdown(void) HDfree(Test); } - + /* * Retrieve the verbosity level for the testing framework */ @@ -504,16 +508,16 @@ int SetTestNoCleanup(void) void ParseTestVerbosity(char *argv) { if (*argv == 'l') - SetTestVerbosity(VERBO_LO); + SetTestVerbosity(VERBO_LO); else if (*argv == 'm') - SetTestVerbosity(VERBO_MED); + SetTestVerbosity(VERBO_MED); else if (*argv == 'h') - SetTestVerbosity(VERBO_HI); + SetTestVerbosity(VERBO_HI); else - SetTestVerbosity(atoi(argv)); + SetTestVerbosity(atoi(argv)); } - + /* * Retrieve the number of testing errors for the testing framework */ @@ -522,7 +526,7 @@ H5_ATTR_PURE int GetTestNumErrs(void) return(num_errs); } - + /* * Increment the number of testing errors */ @@ -531,7 +535,7 @@ void IncTestNumErrs(void) num_errs++; } - + /* * Retrieve the current Test Parameters pointer. */ @@ -540,7 +544,7 @@ H5_ATTR_PURE const void *GetTestParameters(void) return(Test_parameters); } - + /* * This routine is designed to provide equivalent functionality to 'printf' * and also increment the error count for the testing framework. @@ -563,7 +567,7 @@ TestErrPrintf(const char *format, ...) return ret_value; } - + /* * Set (control) which test will be tested. * SKIPTEST: skip this test @@ -576,41 +580,41 @@ void SetTest(const char *testname, int action) unsigned Loop; switch (action){ - case SKIPTEST: - for (Loop = 0; Loop < Index; Loop++) - if (HDstrcmp(testname, Test[Loop].Name) == 0){ - Test[Loop].SkipFlag = 1; - break; - } - break; - case BEGINTEST: - for (Loop = 0; Loop < Index; Loop++) { - if (HDstrcmp(testname, Test[Loop].Name) != 0) - Test[Loop].SkipFlag = 1; - else{ - /* Found it. Set it to run. Done. */ - Test[Loop].SkipFlag = 0; - break; - } - } - break; - case ONLYTEST: - for (Loop = 0; Loop < Index; Loop++) { - if (HDstrcmp(testname, Test[Loop].Name) == 0) { - /* Found it. Set it to run. Break to skip the rest. */ - Test[Loop].SkipFlag = 0; - break; - } - } - break; - default: - /* error */ - printf("*** ERROR: Unknown action (%d) for SetTest\n", action); - break; + case SKIPTEST: + for (Loop = 0; Loop < Index; Loop++) + if (HDstrcmp(testname, Test[Loop].Name) == 0){ + Test[Loop].SkipFlag = 1; + break; + } + break; + case BEGINTEST: + for (Loop = 0; Loop < Index; Loop++) { + if (HDstrcmp(testname, Test[Loop].Name) != 0) + Test[Loop].SkipFlag = 1; + else{ + /* Found it. Set it to run. Done. */ + Test[Loop].SkipFlag = 0; + break; + } + } + break; + case ONLYTEST: + for (Loop = 0; Loop < Index; Loop++) { + if (HDstrcmp(testname, Test[Loop].Name) == 0) { + /* Found it. Set it to run. Break to skip the rest. */ + Test[Loop].SkipFlag = 0; + break; + } + } + break; + default: + /* error */ + printf("*** ERROR: Unknown action (%d) for SetTest\n", action); + break; } } - + /* * Enable alarm on test execution, configurable by environment variable */ diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index 0b3cbe3..71459c7 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -47,7 +47,7 @@ set (H5P_TESTS t_mpi t_bigio t_cache - t_cache_image + #t_cache_image t_pflush1 t_pflush2 t_pread diff --git a/testpar/CMakeTests.cmake b/testpar/CMakeTests.cmake index b71e7bc..12ccc58 100644 --- a/testpar/CMakeTests.cmake +++ b/testpar/CMakeTests.cmake @@ -15,17 +15,83 @@ ### T E S T I N G ### ############################################################################## ############################################################################## +# Remove any output file left over from previous test run +add_test (NAME MPI_TEST-clear-testphdf5-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ParaTest.h5 + WORKING_DIRECTORY + ${HDF5_TEST_PAR_BINARY_DIR} +) +set_tests_properties (MPI_TEST-clear-testphdf5-objects PROPERTIES FIXTURES_SETUP par_clear_testphdf5) -add_test (NAME MPI_TEST_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +set (SKIP_testphdf5 "") +#if (${HDF5_OPENMPI_VERSION_SKIP}) +# set (SKIP_testphdf5 "${SKIP_testphdf5};-x;ecdsetw") +#endif () + +add_test (NAME MPI_TEST_testphdf5 COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${SKIP_testphdf5}) +set_tests_properties (MPI_TEST_testphdf5 PROPERTIES + FIXTURES_REQUIRED par_clear_testphdf5 + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" + WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} +) +if (NOT "${last_test}" STREQUAL "") + set_tests_properties (MPI_TEST_testphdf5 PROPERTIES DEPENDS ${last_test}) +endif () +set (last_test "MPI_TEST_testphdf5") + +#if (${HDF5_OPENMPI_VERSION_SKIP}) +# list (REMOVE_ITEM H5P_TESTS t_shapesame) +#endif () + +set (test_par_CLEANFILES + t_cache_image_00.h5 + t_cache_image_01.h5 + t_cache_image_02.h5 + flush.h5 + noflush.h5 + reloc_t_pread_data_file.h5 + reloc_t_pread_group_0_file.h5 + reloc_t_pread_group_1_file.h5 + shutdown.h5 + after_mpi_fin.h5 + #the following should have been removed by the programs + bigio_test.h5 + CacheTestDummy.h5 + t_filters_parallel.h5 + MPItest.h5 + ShapeSameTest.h5 +) + +# Remove any output file left over from previous test run +add_test (NAME MPI_TEST-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${test_par_CLEANFILES} + WORKING_DIRECTORY + ${HDF5_TEST_PAR_BINARY_DIR} +) +set_tests_properties (MPI_TEST-clear-objects PROPERTIES FIXTURES_SETUP par_clear_objects) foreach (testp ${H5P_TESTS}) add_test (NAME MPI_TEST_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + set_tests_properties (MPI_TEST_${testp} PROPERTIES + FIXTURES_REQUIRED par_clear_objects + ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" + WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} + ) + if (NOT "${last_test}" STREQUAL "") + set_tests_properties (MPI_TEST_${testp} PROPERTIES DEPENDS ${last_test}) + endif () + set (last_test "MPI_TEST_${testp}") endforeach () # The t_pflush1 test is hard-coded to fail. set_tests_properties (MPI_TEST_t_pflush1 PROPERTIES WILL_FAIL "true") #set_property (TEST MPI_TEST_t_pflush1 PROPERTY PASS_REGULAR_EXPRESSION "PASSED") set_tests_properties (MPI_TEST_t_pflush2 PROPERTIES DEPENDS MPI_TEST_t_pflush1) +set_tests_properties (MPI_TEST_t_prestart PROPERTIES DEPENDS MPI_TEST_t_pshutdown) ############################################################################## ############################################################################## diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index e2bf88a..de16a31 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -33,20 +33,36 @@ set (VFD_LIST ${VFD_LIST} direct) endif () +foreach (vfdtest ${VFD_LIST}) + file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${vfdtest}") +endforeach () + macro (ADD_VFD_TEST vfdname resultcode) if (NOT HDF5_ENABLE_USING_MEMCHECKER) foreach (test ${H5P_VFD_TESTS}) add_test ( + NAME MPI_TEST_VFD-${vfdname}-${test}-clear-objects + COMMAND ${CMAKE_COMMAND} + -E remove + ${vfdname}-shared/${vfdname}-${test}.out + ${vfdname}-shared/${vfdname}-${test}.out.err + ) + add_test ( NAME MPI_TEST_VFD-${vfdname}-${test} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${test}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_OUTPUT=${vfdname}-${test}.out" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) + set_tests_properties (MPI_TEST_VFD-${vfdname}-${test} PROPERTIES + DEPENDS MPI_TEST_VFD-${vfdname}-${test}-clear-objects + ENVIRONMENT "srcdir=${HDF5_TEST_PAR_BINARY_DIR}/${vfdname}" + WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR}/${vfdname} + ) endforeach () endif () endmacro () -- cgit v0.12 From 2268685c08a77d2b09613bef196d6138c6adb7a1 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Thu, 14 Feb 2019 11:20:17 -0600 Subject: CMake if statement correction --- config/cmake/scripts/CTestScript.cmake | 4 ++-- src/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/cmake/scripts/CTestScript.cmake b/config/cmake/scripts/CTestScript.cmake index 6958f31..2dfb5d9 100644 --- a/config/cmake/scripts/CTestScript.cmake +++ b/config/cmake/scripts/CTestScript.cmake @@ -277,7 +277,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND ${ctest_test_args} RETURN_VALUE res) else () file(STRINGS ${CTEST_BINARY_DIRECTORY}/Testing/TAG TAG_CONTENTS REGEX "^2([0-9]+)[-]([0-9]+)$") - if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) @@ -296,7 +296,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/Test.xml ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/SerialTest.xml) file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}.log ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}_Serial.log) unset(result CACHE) - if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d77a8b..c4048e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -944,7 +944,7 @@ if (BUILD_SHARED_LIBS) endif () if (LOCAL_BATCH_TEST) - if (${LOCAL_BATCH_SCRIPT_COMMAND} STREQUAL "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") configure_file ( ${HDF5_SOURCE_DIR}/bin/batch/${LOCAL_BATCH_SCRIPT_COMMAND} ${HDF5_BINARY_DIR}/${LOCAL_BATCH_SCRIPT_COMMAND} ESCAPE_QUOTES @ONLY -- cgit v0.12 From 35e9128c7e27a5dfd058ee2b88423ba7bfd80401 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Thu, 14 Feb 2019 12:52:01 -0600 Subject: Skip testing of cache_image test --- test/CMakeTests.cmake | 2 ++ test/CMakeVFDTests.cmake | 1 + test/CMakeVOLTests.cmake | 1 + 3 files changed, 4 insertions(+) diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index b087172..959e537 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -660,6 +660,7 @@ if (NOT CYGWIN) set_tests_properties (H5TEST-cache PROPERTIES TIMEOUT ${CTEST_VERY_LONG_TIMEOUT}) endif () +if (TEST_CACHE_IMAGE) #-- Adding test for cache_image add_test ( NAME H5TEST-clear-cache_image-objects @@ -676,6 +677,7 @@ set_tests_properties (H5TEST-cache_image PROPERTIES ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST;HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST ) +endif () if (BUILD_SHARED_LIBS) #-- Adding test for cache diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index 0d51e25..569f215 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -92,6 +92,7 @@ endif () set (H5_VFD_SKIP_TESTS cache + cache_image accum fheap big diff --git a/test/CMakeVOLTests.cmake b/test/CMakeVOLTests.cmake index d7da159..334520c 100644 --- a/test/CMakeVOLTests.cmake +++ b/test/CMakeVOLTests.cmake @@ -89,6 +89,7 @@ endif () set (H5_VOL_SKIP_TESTS cache + cache_image accum fheap big -- cgit v0.12 From d676456b54c24890c3daa4efe0b4b51337f05455 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Thu, 14 Feb 2019 15:03:05 -0600 Subject: Add command to build options and check defines --- config/cmake/scripts/CTestScript.cmake | 4 ++-- config/cmake/scripts/HDF5config.cmake | 19 +++++++++++-------- config/cmake/scripts/HPC/raybsub-HDF5options.cmake | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/config/cmake/scripts/CTestScript.cmake b/config/cmake/scripts/CTestScript.cmake index 2dfb5d9..e234057 100644 --- a/config/cmake/scripts/CTestScript.cmake +++ b/config/cmake/scripts/CTestScript.cmake @@ -277,7 +277,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND ${ctest_test_args} RETURN_VALUE res) else () file(STRINGS ${CTEST_BINARY_DIRECTORY}/Testing/TAG TAG_CONTENTS REGEX "^2([0-9]+)[-]([0-9]+)$") - if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND STREQUAL "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_NAME}) @@ -296,7 +296,7 @@ message (STATUS "Dashboard script configuration:\n${vars}\n") file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/Test.xml ${CTEST_BINARY_DIRECTORY}/Testing/${TAG_CONTENTS}/SerialTest.xml) file (RENAME ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}.log ${CTEST_BINARY_DIRECTORY}/Testing/Temporary/LastTest_${TAG_CONTENTS}_Serial.log) unset(result CACHE) - if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND STREQUAL "raybsub") execute_process (COMMAND ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) else () execute_process (COMMAND ${LOCAL_BATCH_SCRIPT_COMMAND} ${LOCAL_BATCH_SCRIPT_ARGS} ${CTEST_BINARY_DIRECTORY}/${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}) diff --git a/config/cmake/scripts/HDF5config.cmake b/config/cmake/scripts/HDF5config.cmake index bcd33df..83909b2 100644 --- a/config/cmake/scripts/HDF5config.cmake +++ b/config/cmake/scripts/HDF5config.cmake @@ -101,45 +101,48 @@ endif () ################################################################### ######### Following describes compiler ############ if (NOT DEFINED HPC) + if (NOT DEFINED BUILD_GENERATOR) + message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + endif () if (WIN32) set (SITE_OS_NAME "Windows") set (SITE_OS_VERSION "WIN7") - if (${BUILD_GENERATOR} STREQUAL "VS201764") + if (BUILD_GENERATOR STREQUAL "VS201764") set (CTEST_CMAKE_GENERATOR "Visual Studio 15 2017 Win64") set (SITE_OS_BITS "64") set (SITE_COMPILER_NAME "vs2017") set (SITE_COMPILER_VERSION "15") - elseif (${BUILD_GENERATOR} STREQUAL "VS2017") + elseif (BUILD_GENERATOR STREQUAL "VS2017") set (CTEST_CMAKE_GENERATOR "Visual Studio 15 2017") set (SITE_OS_BITS "32") set (SITE_COMPILER_NAME "vs2017") set (SITE_COMPILER_VERSION "15") - elseif (${BUILD_GENERATOR} STREQUAL "VS201564") + elseif (BUILD_GENERATOR STREQUAL "VS201564") set (CTEST_CMAKE_GENERATOR "Visual Studio 14 2015 Win64") set (SITE_OS_BITS "64") set (SITE_COMPILER_NAME "vs2015") set (SITE_COMPILER_VERSION "14") - elseif (${BUILD_GENERATOR} STREQUAL "VS2015") + elseif (BUILD_GENERATOR STREQUAL "VS2015") set (CTEST_CMAKE_GENERATOR "Visual Studio 14 2015") set (SITE_OS_BITS "32") set (SITE_COMPILER_NAME "vs2015") set (SITE_COMPILER_VERSION "14") - elseif (${BUILD_GENERATOR} STREQUAL "VS201364") + elseif (BUILD_GENERATOR STREQUAL "VS201364") set (CTEST_CMAKE_GENERATOR "Visual Studio 12 2013 Win64") set (SITE_OS_BITS "64") set (SITE_COMPILER_NAME "vs2013") set (SITE_COMPILER_VERSION "12") - elseif (${BUILD_GENERATOR} STREQUAL "VS2013") + elseif (BUILD_GENERATOR STREQUAL "VS2013") set (CTEST_CMAKE_GENERATOR "Visual Studio 12 2013") set (SITE_OS_BITS "32") set (SITE_COMPILER_NAME "vs2013") set (SITE_COMPILER_VERSION "12") - elseif (${BUILD_GENERATOR} STREQUAL "VS201264") + elseif (BUILD_GENERATOR STREQUAL "VS201264") set (CTEST_CMAKE_GENERATOR "Visual Studio 11 2012 Win64") set (SITE_OS_BITS "64") set (SITE_COMPILER_NAME "vs2012") set (SITE_COMPILER_VERSION "11") - elseif (${BUILD_GENERATOR} STREQUAL "VS2012") + elseif (BUILD_GENERATOR STREQUAL "VS2012") set (CTEST_CMAKE_GENERATOR "Visual Studio 11 2012") set (SITE_OS_BITS "32") set (SITE_COMPILER_NAME "vs2012") diff --git a/config/cmake/scripts/HPC/raybsub-HDF5options.cmake b/config/cmake/scripts/HPC/raybsub-HDF5options.cmake index 9775979..4aad887 100644 --- a/config/cmake/scripts/HPC/raybsub-HDF5options.cmake +++ b/config/cmake/scripts/HPC/raybsub-HDF5options.cmake @@ -33,6 +33,7 @@ set (LOCAL_BATCH_TEST "TRUE") set (LOCAL_BATCH_SCRIPT_NAME "ray_ctestS.lsf") set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "ray_ctestP.lsf") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_TEST:BOOL=ON") +set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_COMMAND:STRING=${LOCAL_BATCH_SCRIPT_COMMAND}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_NAME:STRING=${LOCAL_BATCH_SCRIPT_NAME}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=${LOCAL_BATCH_SCRIPT_PARALLEL_NAME}") set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DMPIEXEC_EXECUTABLE:STRING=mpirun") -- cgit v0.12 From b5a4f470cdf7113c0691cca6fb201672c4e1d86d Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Thu, 14 Feb 2019 15:28:02 -0600 Subject: Use STREQUAL --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4048e1..698c143 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -944,7 +944,7 @@ if (BUILD_SHARED_LIBS) endif () if (LOCAL_BATCH_TEST) - if (LOCAL_BATCH_SCRIPT_COMMAND MATCHES "raybsub") + if (LOCAL_BATCH_SCRIPT_COMMAND STREQUAL "raybsub") configure_file ( ${HDF5_SOURCE_DIR}/bin/batch/${LOCAL_BATCH_SCRIPT_COMMAND} ${HDF5_BINARY_DIR}/${LOCAL_BATCH_SCRIPT_COMMAND} ESCAPE_QUOTES @ONLY -- cgit v0.12 From 4a4ec03dfdbc98835d601f1ce0005e68a8a076e4 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Thu, 14 Feb 2019 15:35:04 -0600 Subject: Adding a C++ wrapper Description: - Added a wrapper for H5Ovisit2 to class H5Object // Recursively visit elements reachable from this object. void visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields); - Fixed various typos in documentation Platforms tested: Linux/64 (jelly) Linux/64 (platypus) Darwin (osx1011test) --- c++/src/H5LaccProp.h | 11 ++-- c++/src/H5LcreatProp.h | 11 ++-- c++/src/H5Object.cpp | 69 ++++++++++++++++++++-- c++/src/H5Object.h | 26 +++++++-- c++/test/tlinks.cpp | 156 +++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 238 insertions(+), 35 deletions(-) diff --git a/c++/src/H5LaccProp.h b/c++/src/H5LaccProp.h index 70890b3..ec5e54f 100644 --- a/c++/src/H5LaccProp.h +++ b/c++/src/H5LaccProp.h @@ -12,9 +12,6 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// Class LinkAccPropList represents the HDF5 file access property list and -// inherits from DataType. - #ifndef __H5LinkAccPropList_H #define __H5LinkAccPropList_H @@ -22,15 +19,15 @@ namespace H5 { /*! \class LinkAccPropList \brief Class LinkAccPropList inherits from PropList and provides - wrappers for the HDF5 file access property list. + wrappers for the HDF5 link access property list. */ // Inheritance: PropList -> IdComponent class H5_DLLCPP LinkAccPropList : public PropList { public: - ///\brief Default file access property list. + ///\brief Default link access property list. static const LinkAccPropList& DEFAULT; - // Creates a file access property list. + // Creates a link access property list. LinkAccPropList(); ///\brief Returns this class name. @@ -39,7 +36,7 @@ class H5_DLLCPP LinkAccPropList : public PropList { // Copy constructor: same as the original LinkAccPropList. LinkAccPropList(const LinkAccPropList& original); - // Creates a copy of an existing file access property list + // Creates a copy of an existing link access property list // using the property list id. LinkAccPropList (const hid_t plist_id); diff --git a/c++/src/H5LcreatProp.h b/c++/src/H5LcreatProp.h index 12cb479..f6e10bf 100644 --- a/c++/src/H5LcreatProp.h +++ b/c++/src/H5LcreatProp.h @@ -12,9 +12,6 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// Class LinkCreatPropList represents the HDF5 file access property list and -// inherits from DataType. - #ifndef __H5LinkCreatPropList_H #define __H5LinkCreatPropList_H @@ -22,15 +19,15 @@ namespace H5 { /*! \class LinkCreatPropList \brief Class LinkCreatPropList inherits from PropList and provides - wrappers for the HDF5 file access property list. + wrappers for the HDF5 link creation property list. */ // Inheritance: PropList -> IdComponent class H5_DLLCPP LinkCreatPropList : public PropList { public: - ///\brief Default file access property list. + ///\brief Default link creation property list. static const LinkCreatPropList& DEFAULT; - // Creates a file access property list. + // Creates a link creation property list. LinkCreatPropList(); ///\brief Returns this class name. @@ -39,7 +36,7 @@ class H5_DLLCPP LinkCreatPropList : public PropList { // Copy constructor: same as the original LinkCreatPropList. LinkCreatPropList(const LinkCreatPropList& original); - // Creates a copy of an existing file access property list + // Creates a copy of an existing link creation property list // using the property list id. LinkCreatPropList (const hid_t plist_id); diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 1c22efe..03558e9 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -12,6 +12,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include +#include +using namespace std; #include "H5private.h" // for HDmemset #include "H5Include.h" @@ -40,9 +42,8 @@ namespace H5 { #ifndef DOXYGEN_SHOULD_SKIP_THIS -// userAttrOpWrpr simply interfaces between the user's function and the -// C library function H5Aiterate2; used to resolve the different prototype -// problem. May be moved to Iterator later. +// userAttrOpWrpr interfaces between the user's function and the +// C library function H5Aiterate2 extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, const H5A_info_t *ainfo, void *op_data) { @@ -52,6 +53,17 @@ extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, return 0; } +// userVisitOpWrpr interfaces between the user's function and the +// C library function H5Ovisit2 +extern "C" herr_t userVisitOpWrpr(hid_t obj_id, const char *attr_name, + const H5O_info_t *obj_info, void *op_data) +{ + H5std_string s_attr_name = H5std_string(attr_name); + UserData4Visit* myData = reinterpret_cast (op_data); + int status = myData->op(*myData->obj, s_attr_name, obj_info, myData->opData); + return status; +} + //-------------------------------------------------------------------------- // Function: H5Object default constructor (protected) // Programmer Binh-Minh Ribler - 2000 @@ -197,8 +209,6 @@ Attribute H5Object::openAttribute(const unsigned int idx) const ///\par Description /// The signature of user_op is /// void (*)(H5::H5Location&, H5std_string, void*). -/// For information, please refer to the H5Aiterate2 API in -/// the HDF5 C Reference Manual. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_data) @@ -228,6 +238,55 @@ int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_dat } //-------------------------------------------------------------------------- +// Function: H5Object::visit +///\brief Recursively visits all HDF5 objects accessible from this object. +///\param idx_type - IN: Type of index; valid values include: +/// \li \c H5_INDEX_NAME +/// \li \c H5_INDEX_CRT_ORDER +///\param order - IN: Order in which index is traversed; valid values include: +/// \li \c H5_ITER_DEC +/// \li \c H5_ITER_INC +/// \li \c H5_ITER_NATIVE +///\param user_op - IN: Callback function passing data regarding the +/// object to the calling application +///\param *op_data - IN: User-defined pointer to data required by the +/// application for its processing of the object +///\param fields - IN: Flags specifying the fields to be retrieved +/// to the callback op +///\return +/// \li On success: +/// \li the return value of the first operator that returns a positive value +/// \li zero if all members were processed with no operator returning non-zero +/// \li On failure: +/// \li an exception Exception will be thrown if something went +/// wrong within the library or the operator failed +///\exception H5::Exception +///\par Description +/// For information, please refer to the H5Ovisit2 API in the HDF5 +/// C Reference Manual. +// Programmer Binh-Minh Ribler - Feb, 2019 +//-------------------------------------------------------------------------- +void H5Object::visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields) +{ + // Store the user's function and data + UserData4Visit* userData = new UserData4Visit; + userData->opData = op_data; + userData->op = user_op; + userData->obj = this; + + // Call the C API passing in op wrapper and info + herr_t ret_value = H5Ovisit2(getId(), idx_type, order, userVisitOpWrpr, static_cast(userData), fields); + + // Release memory + delete userData; + + // Throw exception if H5Ovisit2 failed, which could be a failure in + // the library or in the call back operator + if (ret_value < 0) + throw Exception(inMemFunc("visit"), "H5Ovisit2 failed"); +} + +//-------------------------------------------------------------------------- // Function: H5Object::objVersion ///\brief Returns the header version of this HDF5 object. ///\return Object version, which can have the following values: diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h index 10b3865..4a4e909 100644 --- a/c++/src/H5Object.h +++ b/c++/src/H5Object.h @@ -40,16 +40,30 @@ namespace H5 { // Inheritance: H5Location -> IdComponent // Define the operator function pointer for H5Aiterate(). -typedef void (*attr_operator_t)(H5Object& loc/*in*/, - const H5std_string attr_name/*in*/, - void *operator_data/*in,out*/); +typedef void (*attr_operator_t)(H5Object& loc, + const H5std_string attr_name, + void *operator_data); + +// Define the operator function pointer for H5Ovisit2(). +typedef int (*visit_operator_t)(H5Object& obj, + const H5std_string attr_name, + const H5O_info_t *oinfo, + void *operator_data); // User data for attribute iteration class UserData4Aiterate { public: attr_operator_t op; void* opData; - H5Object* location; + H5Object* location; // Consider changing to H5Location +}; + +// User data for visit iteration +class UserData4Visit { + public: + visit_operator_t op; + void* opData; + H5Object* obj; }; class H5_DLLCPP H5Object : public H5Location { @@ -71,6 +85,9 @@ class H5_DLLCPP H5Object : public H5Location { // Iterate user's function over the attributes of this object. int iterateAttrs(attr_operator_t user_op, unsigned* idx = NULL, void* op_data = NULL); + // Recursively visit elements reachable from this object. + void visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields); + // Returns the object header version of an object unsigned objVersion() const; @@ -98,6 +115,7 @@ class H5_DLLCPP H5Object : public H5Location { ssize_t getObjName(H5std_string& obj_name, size_t len = 0) const; H5std_string getObjName() const; + #ifndef DOXYGEN_SHOULD_SKIP_THIS protected: diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index 6e990c9..c8bf8e6 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -33,17 +33,6 @@ using namespace H5; // A lot of the definition inherited from C test links.c is left here until // the H5L API is implemented and tests are completed - BMR 10/19/2009 -/* - * This file needs to access private information from the H5G package. - * This file also needs to access the group testing code. - */ -//#define H5G_FRIEND -//#define H5G_TESTING - -//#include "h5test.h" -//#include "H5Gpkg.h" /* Groups */ -//#include "H5Iprivate.h" /* IDs */ -//#include "H5Lprivate.h" /* Links */ /* File for external link test. Created with gen_udlinks.c */ #define LINKED_FILE "be_extlink2.h5" @@ -95,6 +84,7 @@ const char *FILENAME[] = { "extlinks19A", /* 42: */ "extlinks19B", /* 43: */ "extlinks20", /* 44: */ + "visit", /* 45: */ NULL }; @@ -230,12 +220,15 @@ typedef struct { const link_visit_t *info; /* Pointer to the link visit structure to use */ } lvisit_ud_t; +#endif /* Object visit structs */ typedef struct { const char *path; /* Path to object */ H5O_type_t type; /* Type of object */ } obj_visit_t; + +#if 0 static const obj_visit_t ovisit0_old[] = { {".", H5O_TYPE_GROUP}, {"Dataset_zero", H5O_TYPE_DATASET}, @@ -302,17 +295,18 @@ static const obj_visit_t ovisit2_new[] = { {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE} }; +#endif typedef struct { unsigned idx; /* Index in object visit structure */ const obj_visit_t *info; /* Pointer to the object visit structure to use */ } ovisit_ud_t; -#endif static const char *FILENAME[] = { "link0", "link1.h5", "link2.h5", + "visit", NULL }; @@ -842,6 +836,138 @@ static void test_num_links(hid_t fapl_id, hbool_t new_format) } // test_num_links +static const obj_visit_t file_visit[] = { + {".", H5O_TYPE_GROUP}, + {"Data", H5O_TYPE_GROUP}, + {"Data/Compressed_Data", H5O_TYPE_DATASET}, + {"Data/Float_Data", H5O_TYPE_DATASET}, +}; + +static const obj_visit_t group_visit[] = { + {".", H5O_TYPE_GROUP}, + {"Compressed_Data", H5O_TYPE_DATASET}, + {"Float_Data", H5O_TYPE_DATASET}, +}; + +const H5std_string FILE_NAME("tvisit.h5"); +const H5std_string GROUP_NAME("/Data"); +const H5std_string DSET1_NAME("/Data/Compressed_Data"); +const H5std_string DSET2_NAME("/Data/Float_Data"); +const int RANK = 2; +const int DIM1 = 2; + +// Operator function +static int visit_obj_cb(H5Object& obj, const H5std_string name, const H5O_info_t *oinfo, void *_op_data) +{ + ovisit_ud_t *op_data = static_cast (_op_data); + + // Check for correct object information + if(strcmp(op_data->info[op_data->idx].path, name.c_str())) return(H5_ITER_ERROR); + if(op_data->info[op_data->idx].type != oinfo->type) return(H5_ITER_ERROR); + + // Advance to next location + op_data->idx++; + + return(H5_ITER_CONT); +} + +/*------------------------------------------------------------------------- + * Function: test_visit + * + * Purpose Test H5Object::visit + * + * Return Success: 0 + * Failure: -1 + * + * February 8, 2019 + *------------------------------------------------------------------------- + */ +static void test_visit(hid_t fapl_id, hbool_t new_format) +{ + hsize_t dims[2]; + hsize_t cdims[2]; + char filename[NAME_BUF_SIZE]; + + if(new_format) + SUBTEST("H5Object::visit (w/new group format)") + else + SUBTEST("H5Object::visit") + + try + { + // Use the file access template id to create a file access prop. list + FileAccPropList fapl(fapl_id); + + // Build the hdf5 file name and create the file + h5_fixname(FILENAME[3], fapl_id, filename, sizeof filename); + H5File *file = new H5File(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + + // Create a group + Group* group = new Group(file->createGroup(GROUP_NAME)); + + // Create a chunked/compressed dataset within this group specified by path + dims[0] = 20; + dims[1] = 2; + cdims[0] = 2; + cdims[1] = 2; + DataSpace *dataspace = new DataSpace(RANK, dims); // create new dspace + DSetCreatPropList ds_creatplist; // create dataset creation prop list + ds_creatplist.setChunk(2, cdims); // then modify it for compression + ds_creatplist.setDeflate(6); + + DataSet* dataset = new DataSet(file->createDataSet(DSET1_NAME, + PredType::NATIVE_INT, *dataspace, ds_creatplist)); + + delete dataset; + delete dataspace; + + // Create another dataset + dims[0] = 5; + dims[1] = 2; + dataspace = new DataSpace(RANK, dims); // create second dspace + dataset = new DataSet(file->createDataSet(DSET2_NAME, + PredType::NATIVE_FLOAT, *dataspace)); + + // Close everything + delete dataset; + delete dataspace; + delete group; + delete file; + + // Reopen the file and group in the file. + file = new H5File(filename, H5F_ACC_RDWR); + group = new Group(file->openGroup("Data")); + + // Open the group + dataset = new DataSet(group->openDataSet(DSET2_NAME)); + delete dataset; + + // Visit objects in the file + ovisit_ud_t udata; /* User-data for visiting */ + udata.idx = 0; + udata.info = file_visit; + + file->visit(H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC); + + // Visit objects in the group + udata.idx = 0; + udata.info = group_visit; + + group->visit(H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, &udata, H5O_INFO_BASIC); + + // Close the group and file. + delete group; + delete file; + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_visit()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_visit + + /*------------------------------------------------------------------------- * Function: test_links * @@ -857,6 +983,11 @@ void test_links() { hid_t fapl_id, fapl2_id; /* File access property lists */ unsigned new_format; /* Whether to use the new format or not */ + const char *envval; + + envval = HDgetenv("HDF5_DRIVER"); + if(envval == NULL) + envval = "nomatch"; fapl_id = h5_fileaccess(); @@ -891,6 +1022,7 @@ void test_links() test_move(my_fapl_id, new_format); test_copy(my_fapl_id, new_format); test_lcpl(my_fapl_id, new_format); + test_visit(my_fapl_id, new_format); } /* end for */ /* Close 2nd FAPL */ -- cgit v0.12 From 6ea0dafa41415c0888889214c82f75a02ec4a545 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Thu, 14 Feb 2019 15:47:02 -0600 Subject: Use correct variable name --- config/cmake/HDF5UseFortran.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cmake/HDF5UseFortran.cmake b/config/cmake/HDF5UseFortran.cmake index 6b77ca4..03597f2 100644 --- a/config/cmake/HDF5UseFortran.cmake +++ b/config/cmake/HDF5UseFortran.cmake @@ -234,7 +234,7 @@ foreach (KIND ${VAR} ) set (pack_real_sizeof "${pack_real_sizeof} ${PROG_OUTPUT1},") endforeach () -if (pack_int_sizeof STREQUAL "") +if (pack_real_sizeof STREQUAL "") message (FATAL_ERROR "Failed to find available REAL KINDs for Fortran") endif () -- cgit v0.12 From 268128e5202366dbea1f9a00ebcbed30a62ea674 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Thu, 14 Feb 2019 15:47:24 -0600 Subject: Added C++ wrapper for H5Ovisit2 --- release_docs/RELEASE.txt | 48 ++++-------------------------------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 316798d..8423981 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -167,52 +167,12 @@ New Features C++ Library: ------------ - - New wrappers + - Added a wrapper for H5Ovisit2 - Added the following items: - - + Class DSetAccPropList for the dataset access property list. - - + Wrapper for H5Dget_access_plist to class DataSet - // Gets the access property list of this dataset. - DSetAccPropList getAccessPlist() const; - - + Wrappers for H5Pset_chunk_cache and H5Pget_chunk_cache to class DSetAccPropList - // Sets the raw data chunk cache parameters. - void setChunkCache(size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0) - - // Retrieves the raw data chunk cache parameters. - void getChunkCache(size_t &rdcc_nslots, size_t &rdcc_nbytes, double &rdcc_w0) - - + New operator!= to class DataType (HDFFV-10472) - // Determines whether two datatypes are not the same. - bool operator!=(const DataType& compared_type) - - + Wrappers for H5Oget_info2, H5Oget_info_by_name2, and H5Oget_info_by_idx2 - (HDFFV-10458) - - // Retrieves information about an HDF5 object. - void getObjinfo(H5O_info_t& objinfo, unsigned fields = H5O_INFO_BASIC) const; - - // Retrieves information about an HDF5 object, given its name. - void getObjinfo(const char* name, H5O_info_t& objinfo, - unsigned fields = H5O_INFO_BASIC, - const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; - void getObjinfo(const H5std_string& name, H5O_info_t& objinfo, - unsigned fields = H5O_INFO_BASIC, - const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; - - // Retrieves information about an HDF5 object, given its index. - void getObjinfo(const char* grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, - unsigned fields = H5O_INFO_BASIC, - const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; - void getObjinfo(const H5std_string& grp_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, - unsigned fields = H5O_INFO_BASIC, - const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + // Recursively visit elements reachable from this object. + void visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields); - (BMR - 2018/07/22, HDFFV-10150, HDFFV-10458, HDFFV-1047) + (BMR - 2019/02/14, HDFFV-10532) Java Library: -- cgit v0.12 From 320eaf91b9adb36bb0fed9264d460e4a808200b7 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 14 Feb 2019 16:20:32 -0600 Subject: More changes to align with incoming selection improvements. --- fortran/src/H5Sf.c | 161 - fortran/src/H5Sff.F90 | 304 -- fortran/src/H5f90proto.h | 3 - src/H5Dmpio.c | 4 +- src/H5Sall.c | 148 +- src/H5Shyper.c | 12028 ++++++++++++++++++++------------------------- src/H5Smpio.c | 7 +- src/H5Snone.c | 116 +- src/H5Spkg.h | 4 +- src/H5Spoint.c | 279 +- src/H5Sprivate.h | 8 +- src/H5Spublic.h | 10 - src/H5Sselect.c | 87 +- test/tselect.c | 366 -- 14 files changed, 5774 insertions(+), 7751 deletions(-) diff --git a/fortran/src/H5Sf.c b/fortran/src/H5Sf.c index 2eae0d9..96540f7 100644 --- a/fortran/src/H5Sf.c +++ b/fortran/src/H5Sf.c @@ -995,167 +995,6 @@ done: } -#ifdef NEW_HYPERSLAB_API -/****if* H5Sf/h5scombine_hyperslab_c - * NAME - * h5scombine_hyperslab_c - * PURPOSE - * Call H5Scombine_hyperslab - * INPUTS - * space_id - identifier of the dataspace - * operator - defines how the new selection is combined - * start - offset of start of hyperslab - * count - number of blocks included in the hyperslab - * stride - hyperslab stride (interval between blocks) - * block - size of block in the hyperslab - * OUTPUTS - * hyper_id - identifier for the new dataspace - * RETURNS - * 0 on success, -1 on failure - * AUTHOR - * Elena Pourmal - * Monday, October 7, 2002 - * HISTORY - * - * SOURCE -*/ - -int_f -h5scombine_hyperslab_c ( hid_t_f *space_id , int_f *op, hsize_t_f *start, hsize_t_f *count, hsize_t_f *stride, hsize_t_f *block, hid_t_f *hyper_id) -/******/ -{ - int ret_value = -1; - hid_t c_space_id; - hid_t c_hyper_id; - hsize_t *c_start = NULL; - hsize_t *c_count = NULL; - hsize_t *c_stride = NULL; - hsize_t *c_block = NULL; - - H5S_seloper_t c_op; - herr_t status; - int rank; - int i; - - rank = H5Sget_simple_extent_ndims(*space_id); - if (rank < 0 ) return ret_value; - c_start = (hsize_t *)HDmalloc(sizeof(hsize_t)*rank); - if (c_start == NULL) goto DONE; - - c_count = (hsize_t *)HDmalloc(sizeof(hsize_t)*rank); - if (c_count == NULL) goto DONE; - - c_stride = (hsize_t *)HDmalloc(sizeof(hsize_t)*rank); - if (c_stride == NULL) goto DONE; - - c_block = (hsize_t *)HDmalloc(sizeof(hsize_t)*rank); - if (c_block == NULL) goto DONE; - - - /* - * Reverse dimensions due to C-FORTRAN storage order. - */ - - for (i=0; i < rank; i++) { - int t= (rank - i) - 1; - c_start[i] = (hsize_t)start[t]; - c_count[i] = (hsize_t)count[t]; - c_stride[i] = (hsize_t)stride[t]; - c_block[i] = (hsize_t)block[t]; - } - - c_op = (H5S_seloper_t)*op; - - c_space_id = (hid_t)*space_id; - c_hyper_id = H5Scombine_hyperslab(c_space_id, c_op, c_start, c_stride, c_count, c_block); - if ( c_hyper_id < 0 ) goto DONE; - *hyper_id = (hid_t_f)c_hyper_id; - ret_value = 0; -DONE: - if(c_start != NULL) HDfree(c_start); - if(c_count != NULL) HDfree(c_count); - if(c_stride!= NULL) HDfree(c_stride); - if(c_block != NULL) HDfree(c_block); - return ret_value; -} -/****if* H5Sf/h5scombine_select_c - * NAME - * h5scombine_select_c - * PURPOSE - * Call H5Scombine_ select - * INPUTS - * space1_id - identifier of the first dataspace - * operator - defines how the new selection is combined - * space2_id - identifier of the second dataspace - * OUTPUTS - * ds_id - identifier for the new dataspace - * RETURNS - * 0 on success, -1 on failure - * AUTHOR - * Elena Pourmal - * Monday, October 7, 2002 - * HISTORY - * - * SOURCE -*/ - -int_f -h5scombine_select_c ( hid_t_f *space1_id , int_f *op, hid_t_f *space2_id, hid_t_f *ds_id) -/******/ -{ - int ret_value = -1; - hid_t c_space1_id; - hid_t c_space2_id; - hid_t c_ds_id; - H5S_seloper_t c_op; - - c_op = (H5S_seloper_t)*op; - - c_space1_id = (hid_t)*space1_id; - c_space2_id = (hid_t)*space2_id; - c_ds_id = H5Scombine_select(c_space1_id, c_op, c_space2_id); - if ( c_ds_id < 0 ) return ret_value; - *ds_id = (hid_t_f)c_ds_id; - ret_value = 0; - return ret_value; -} -/****if* H5Sf/h5sselect_select_c - * NAME - * h5sselect_select_c - * PURPOSE - * Call H5Sselect_ select - * INPUTS - * space1_id - identifier of the first dataspace to modify - * operator - defines how the new selection is combined - * space2_id - identifier of the second dataspace - * RETURNS - * 0 on success, -1 on failure - * AUTHOR - * Elena Pourmal - * Monday, October 7, 2002 - * HISTORY - * - * SOURCE -*/ - -int_f -h5sselect_select_c ( hid_t_f *space1_id , int_f *op, hid_t_f *space2_id) -/******/ -{ - int ret_value = -1; - hid_t c_space1_id; - hid_t c_space2_id; - H5S_seloper_t c_op; - - c_op = (H5S_seloper_t)*op; - - c_space1_id = (hid_t)*space1_id; - c_space2_id = (hid_t)*space2_id; - if( H5Sselect_select(c_space1_id, c_op, c_space2_id)< 0) return ret_value; - ret_value = 0; - return ret_value; -} -#endif /*NEW_HYPERSLAB_API*/ /****if* H5Sf/h5sget_select_type_c * NAME * h5sget_select_type_c diff --git a/fortran/src/H5Sff.F90 b/fortran/src/H5Sff.F90 index 3434fba..3af7755 100644 --- a/fortran/src/H5Sff.F90 +++ b/fortran/src/H5Sff.F90 @@ -1275,310 +1275,6 @@ CONTAINS DEALLOCATE(def_stride) END SUBROUTINE h5sselect_hyperslab_f -! !$! -! !$!****s* H5S/h5scombine_hyperslab_f -! !$! -! !$! NAME -! !$! h5scombine_hyperslab_f -! !$! -! !$! PURPOSE -! !$! Combine a hyperslab selection with the current -! !$! selection for a dataspace -! !$! -! !$! INPUTS -! !$! space_id - dataspace of selection to use -! !$! operator - flag, valid values are: -! !$! H5S_SELECT_NOOP_F -! !$! H5S_SELECT_SET_F -! !$! H5S_SELECT_OR_F -! !$! H5S_SELECT_AND_F -! !$! H5S_SELECT_XOR_F -! !$! H5S_SELECT_NOTB_F -! !$! H5S_SELECT_NOTA_F -! !$! H5S_SELECT_APPEND_F -! !$! H5S_SELECT_PREPEND_F -! !$! start - array with hyperslab offsets -! !$! count - number of blocks included in the -! !$! hyperslab -! !$! OUTPUTS -! !$! hyper_id - identifier for the new hyperslab -! !$! hdferr: - error code -! !$! Success: 0 -! !$! Failure: -1 -! !$! OPTIONAL PARAMETERS -! !$! stride - array with hyperslab strides -! !$! block - array with hyperslab block sizes -! !$! -! !$! AUTHOR -! !$! Elena Pourmal -! !$! October 7, 2002 -! !$! -! !$! HISTORY -! !$! -! !$! -! !$! NOTES -! !$! Commented out until 1.6 ? 10/08/2002 -! !$! -! !$! SOURCE -! SUBROUTINE h5scombine_hyperslab_f(space_id, operator, start, count, & -! hyper_id, hdferr, stride, block) -! IMPLICIT NONE -! INTEGER(HID_T), INTENT(IN) :: space_id ! Dataspace identifier -! INTEGER, INTENT(IN) :: operator ! Flag, valid values are: - ! H5S_SELECT_NOOP_F - ! H5S_SELECT_SET_F - ! H5S_SELECT_OR_F - ! H5S_SELECT_AND_F - ! H5S_SELECT_XOR_F - ! H5S_SELECT_NOTB_F - ! H5S_SELECT_NOTA_F - ! H5S_SELECT_APPEND_F - ! H5S_SELECT_PREPEND_F - ! -! INTEGER(HSIZE_T), DIMENSION(*), INTENT(IN) :: start - ! Starting coordinates of the hyperslab -! INTEGER(HSIZE_T), DIMENSION(*), INTENT(IN) :: count - ! Number of blocks to select - ! from dataspace -! INTEGER(HID_T), INTENT(OUT) :: hyper_id ! New hyperslab identifier -! INTEGER, INTENT(OUT) :: hdferr ! Error code -! INTEGER(HSIZE_T), DIMENSION(:), OPTIONAL, INTENT(IN) :: stride - ! Array of how many elements to move - ! in each direction -! INTEGER(HSIZE_T), DIMENSION(:), OPTIONAL, INTENT(IN) :: block - ! Sizes of element block -! INTEGER(HSIZE_T), DIMENSION(:), ALLOCATABLE :: def_block -! INTEGER(HSIZE_T), DIMENSION(:), ALLOCATABLE :: def_stride -! INTEGER :: rank -! INTEGER :: error1, error2 - -! INTERFACE -! INTEGER FUNCTION h5scombine_hyperslab_c(space_id, operator, & -! start, count, stride, block, hyper_id) -! USE H5GLOBAL -! !DEC$IF DEFINED(HDF5F90_WINDOWS) -! !DEC$ATTRIBUTES C,reference,decorate,alias:'H5SCOMBINE_HYPERSLAB_C'::h5scombine_hyperslab_c -! !DEC$ENDIF -! INTEGER(HID_T), INTENT(IN) :: space_id -! INTEGER, INTENT(IN) :: operator -! INTEGER(HSIZE_T), DIMENSION(*), INTENT(IN) :: start -! INTEGER(HSIZE_T), DIMENSION(*), INTENT(IN) :: count -! INTEGER(HSIZE_T), DIMENSION(*), OPTIONAL, INTENT(IN) :: stride -! INTEGER(HSIZE_T), DIMENSION(*), OPTIONAL, INTENT(IN) :: block -! INTEGER(HID_T), INTENT(OUT) :: hyper_id -! END FUNCTION h5scombine_hyperslab_c -! END INTERFACE - -! if (present(stride).and. present(block)) then -! hdferr = h5scombine_hyperslab_c(space_id, operator, start, count, & -! stride, block, hyper_id) -! return -! endif - ! Case of optional parameters. - ! - ! Find the rank of the dataspace to allocate memory for - ! default stride and block arrays. - ! -! CALL h5sget_simple_extent_ndims_f(space_id, rank, hdferr) -! if( hdferr .EQ. -1) return - ! -! if (present(stride).and. .not.present(block)) then -! allocate(def_block(rank), stat=error1) -! if (error1.NE.0) then -! hdferr = -1 -! return -! endif -! def_block = 1 -! hdferr = h5scombine_hyperslab_c(space_id, operator, start, count, & -! stride, def_block, hyper_id) -! deallocate(def_block) -! return -! endif - -! if (.not.present(stride).and. present(block)) then -! allocate(def_stride(rank), stat=error2) -! if (error2.NE.0) then -! hdferr = -1 -! return -! endif -! def_stride = 1 -! hdferr = h5scombine_hyperslab_c(space_id, operator, start, count, & -! def_stride, block, hyper_id) -! deallocate(def_stride) -! return -! endif -! allocate(def_block(rank), stat=error1) -! allocate(def_stride(rank), stat=error2) -! if ((error1.NE.0) .OR. (error2.NE.0)) then -! hdferr = -1 -! return -! endif -! def_block = 1 -! def_stride = 1 -! hdferr = h5scombine_hyperslab_c(space_id, operator, start, count, & -! def_stride, def_block, hyper_id) -! deallocate(def_block) -! deallocate(def_stride) - -! END SUBROUTINE h5scombine_hyperslab_f - -! !$! -! !$!****s* H5S/ -! !$! -! !$! NAME -! !$! h5scombine_select_f -! !$! -! !$! PURPOSE -! !$! Combine two hyperslab selections with an operation -! !$! and return a dataspace with resulting selection. -! !$! -! !$! INPUTS -! !$! space1_id - dataspace of selection to use -! !$! operator - flag, valid values are: -! !$! H5S_SELECT_NOOP_F -! !$! H5S_SELECT_SET_F -! !$! H5S_SELECT_OR_F -! !$! H5S_SELECT_AND_F -! !$! H5S_SELECT_XOR_F -! !$! H5S_SELECT_NOTB_F -! !$! H5S_SELECT_NOTA_F -! !$! H5S_SELECT_APPEND_F -! !$! H5S_SELECT_PREPEND_F -! !$! space2_id - dataspace of selection to use -! !$! OUTPUTS -! !$! ds_id - idataspace identifier with the new selection -! !$! hdferr: - error code -! !$! Success: 0 -! !$! Failure: -1 -! !$! OPTIONAL PARAMETERS - NONE -! !$! -! !$! AUTHOR -! !$! Elena Pourmal -! !$! October 7, 2002 -! !$! -! !$! HISTORY -! !$! -! !$! -! !$! NOTES commented out until 1.6 release(?) 10/08/2002 -! !$! - -! ! SOURCE -! !$ SUBROUTINE h5scombine_select_f(space1_id, operator, space2_id, & -! ds_id, hdferr) -! IMPLICIT NONE -! INTEGER(HID_T), INTENT(IN) :: space1_id ! First dataspace identifier -! INTEGER(HID_T), INTENT(IN) :: space2_id ! Second dataspace identifier -! INTEGER, INTENT(IN) :: operator ! Flag, valid values are: - ! H5S_SELECT_NOOP_F - ! H5S_SELECT_SET_F - ! H5S_SELECT_OR_F - ! H5S_SELECT_AND_F - ! H5S_SELECT_XOR_F - ! H5S_SELECT_NOTB_F - ! H5S_SELECT_NOTA_F - ! H5S_SELECT_APPEND_F - ! H5S_SELECT_PREPEND_F - ! -! INTEGER(HID_T), INTENT(OUT) :: ds_id ! New dataspace identifier -! INTEGER, INTENT(OUT) :: hdferr ! Error code -! -! INTERFACE -! INTEGER FUNCTION h5scombine_select_c(space1_id, operator, & -! space2_id, ds_id) -! USE H5GLOBAL -! !DEC$IF DEFINED(HDF5F90_WINDOWS) -! !DEC$ATTRIBUTES C,reference,decorate,alias:'H5SCOMBINE_SELECT_C'::h5scombine_select_c -! !DEC$ENDIF -! INTEGER(HID_T), INTENT(IN) :: space1_id -! INTEGER(HID_T), INTENT(IN) :: space2_id -! INTEGER, INTENT(IN) :: operator -! INTEGER(HID_T), INTENT(OUT) :: ds_id -! END FUNCTION h5scombine_select_c -! END INTERFACE - -! hdferr = h5scombine_select_c(space1_id, operator, space2_id, & -! ds_id) -! return - -! END SUBROUTINE h5scombine_select_f - -! !$! -! !$!****s* H5S/ -! !$! -! !$! NAME -! !$! h5sselect_select_f -! !$! -! !$! PURPOSE -! !$! Refine a hyperslab selection with an operation -! !$! using second hyperslab -! !$! -! !$! INPUTS -! !$! space1_id - dataspace of selection to modify -! !$! operator - flag, valid values are: -! !$! H5S_SELECT_NOOP_F -! !$! H5S_SELECT_SET_F -! !$! H5S_SELECT_OR_F -! !$! H5S_SELECT_AND_F -! !$! H5S_SELECT_XOR_F -! !$! H5S_SELECT_NOTB_F -! !$! H5S_SELECT_NOTA_F -! !$! H5S_SELECT_APPEND_F -! !$! H5S_SELECT_PREPEND_F -! !$! space2_id - dataspace of selection to use -! !$! -! !$! OUTPUTS -! !$! hdferr: - error code -! !$! Success: 0 -! !$! Failure: -1 -! !$! OPTIONAL PARAMETERS - NONE -! !$! -! !$! AUTHOR -! !$! Elena Pourmal -! !$! October 7, 2002 -! !$! -! !$! HISTORY -! !$! -! !$! -! !$! NOTESCommented out until 1.6 release(?) 10/08/2002 EIP -! !$! - -! ! SOURCE -! SUBROUTINE h5sselect_select_f(space1_id, operator, space2_id, & -! hdferr) -! IMPLICIT NONE -! INTEGER(HID_T), INTENT(INOUT) :: space1_id ! Dataspace identifier to - ! modify -! INTEGER(HID_T), INTENT(IN) :: space2_id ! Second dataspace identifier -! INTEGER, INTENT(IN) :: operator ! Flag, valid values are: - ! H5S_SELECT_NOOP_F - ! H5S_SELECT_SET_F - ! H5S_SELECT_OR_F - ! H5S_SELECT_AND_F - ! H5S_SELECT_XOR_F - ! H5S_SELECT_NOTB_F - ! H5S_SELECT_NOTA_F - ! H5S_SELECT_APPEND_F - ! H5S_SELECT_PREPEND_F - ! -! INTEGER, INTENT(OUT) :: hdferr ! Error code - -! INTERFACE -! INTEGER FUNCTION h5sselect_select_c(space1_id, operator, & -! space2_id) -! USE H5GLOBAL -! !DEC$IF DEFINED(HDF5F90_WINDOWS) -! !DEC$ATTRIBUTES C,reference,decorate,alias:'H5SSELECT_SELECT_C'::h5sselect_select_c -! !DEC$ENDIF -! INTEGER(HID_T), INTENT(INOUT) :: space1_id -! INTEGER(HID_T), INTENT(IN) :: space2_id -! INTEGER, INTENT(IN) :: operator -! END FUNCTION h5sselect_select_c -! END INTERFACE - -! hdferr = h5sselect_select_c(space1_id, operator, space2_id) -! return - -! END SUBROUTINE h5sselect_select_f ! !****s* H5S/h5sget_select_type_f diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 56b7f22..fada004 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -120,9 +120,6 @@ H5_FCDLL int_f h5sset_extent_none_c( hid_t_f *space_id ); H5_FCDLL int_f h5sselect_hyperslab_c( hid_t_f *space_id , int_f *op, hsize_t_f *start, hsize_t_f *count, hsize_t_f *stride, hsize_t_f *block); H5_FCDLL int_f h5sget_select_type_c( hid_t_f *space_id , int_f *op); H5_FCDLL int_f h5sselect_elements_c( hid_t_f *space_id , int_f *op, size_t_f *nelements, hsize_t_f *coord); -H5_FCDLL int_f h5scombine_hyperslab_c( hid_t_f *space_id , int_f *op, hsize_t_f *start, hsize_t_f *count, hsize_t_f *stride, hsize_t_f *block, hid_t_f *hyper_id); -H5_FCDLL int_f h5scombine_select_c( hid_t_f *space1_id , int_f *op, hid_t_f *space2_id, hid_t_f *ds_id); -H5_FCDLL int_f h5sselect_select_c( hid_t_f *space1_id , int_f *op, hid_t_f *space2_id); H5_FCDLL int_f h5sdecode_c( _fcd buf, hid_t_f *obj_id ); H5_FCDLL int_f h5sencode_c(_fcd buf, hid_t_f *obj_id, size_t_f *nalloc ); H5_FCDLL int_f h5sextent_equal_c( hid_t_f * space1_id, hid_t_f *space2_id, hid_t_f *c_equal); diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 01cf932..2a6c05f 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -2869,7 +2869,7 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty mem_iter_init = TRUE; /* Collect the modification data into the buffer */ - if(!H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t)iter_nelmts, mod_data_p)) + if(0 == H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t)iter_nelmts, mod_data_p)) HGOTO_ERROR(H5E_IO, H5E_CANTGATHER, FAIL, "couldn't gather from write buffer") /* Send modification data to new owner */ @@ -3214,7 +3214,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer") /* Gather modification data from the application write buffer into a temporary buffer */ - if(!H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, tmp_gath_buf)) + if(0 == H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, tmp_gath_buf)) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't gather from write buffer") if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) diff --git a/src/H5Sall.c b/src/H5Sall.c index 76181d1..0aa2f05 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -362,6 +362,80 @@ H5S__all_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) /*-------------------------------------------------------------------------- NAME + H5S__all_get_seq_list + PURPOSE + Create a list of offsets & lengths for a selection + USAGE + herr_t H5S__all_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__all_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, + size_t H5_ATTR_UNUSED maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) +{ + size_t elem_used; /* The number of elements used */ + + FUNC_ENTER_STATIC_NOERR + + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); + + /* Determine the actual number of elements to use */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + elem_used = MIN(maxelem, (size_t)iter->elmt_left); + HDassert(elem_used > 0); + + /* Compute the offset in the dataset */ + off[0] = iter->u.all.byte_offset; + len[0] = elem_used * iter->elmt_size; + + /* Should only need one sequence for 'all' selections */ + *nseq = 1; + + /* Set the number of elements used */ + *nelem = elem_used; + + /* Update the iterator */ + iter->elmt_left -= elem_used; + iter->u.all.elmt_offset += elem_used; + iter->u.all.byte_offset += len[0]; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__all_get_seq_list() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__all_iter_release PURPOSE Release "all" selection iterator information for a dataspace @@ -993,77 +1067,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Sselect_all() */ - -/*-------------------------------------------------------------------------- - NAME - H5S__all_get_seq_list - PURPOSE - Create a list of offsets & lengths for a selection - USAGE - herr_t H5S__all_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__all_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, - size_t H5_ATTR_UNUSED maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) -{ - size_t elem_used; /* The number of elements used */ - - FUNC_ENTER_STATIC_NOERR - - /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); - - /* Determine the actual number of elements to use */ - H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - elem_used = MIN(maxelem, (size_t)iter->elmt_left); - HDassert(elem_used > 0); - - /* Compute the offset in the dataset */ - off[0] = iter->u.all.byte_offset; - len[0] = elem_used * iter->elmt_size; - - /* Should only need one sequence for 'all' selections */ - *nseq = 1; - - /* Set the number of elements used */ - *nelem = elem_used; - - /* Update the iterator */ - iter->elmt_left -= elem_used; - iter->u.all.elmt_offset += elem_used; - iter->u.all.byte_offset += len[0]; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__all_get_seq_list() */ - diff --git a/src/H5Shyper.c b/src/H5Shyper.c index e9354ca..c9fab38 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -80,9 +80,6 @@ static herr_t H5S__hyper_generate_spans(H5S_t *space); static herr_t H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]); -#ifdef NEW_HYPERSLAB_API -static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); -#endif /*NEW_HYPERSLAB_API*/ static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, hsize_t *block, hsize_t clip_size); static hsize_t H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, @@ -1082,8161 +1079,7036 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) /*-------------------------------------------------------------------------- NAME - H5S__hyper_iter_release + H5S__hyper_get_seq_list_gen PURPOSE - Release hyperslab selection iterator information for a dataspace + Create a list of offsets & lengths for a selection USAGE - herr_t H5S__hyper_iter_release(iter) - H5S_sel_iter_t *iter; IN: Pointer to selection iterator + herr_t H5S_select_hyper_get_file_list_gen(space,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths RETURNS - Non-negative on success/Negative on failure + Non-negative on success/Negative on failure. DESCRIPTION - Releases all information for a dataspace hyperslab selection iterator + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_iter_release(H5S_sel_iter_t *iter) +H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) { + H5S_hyper_span_t *curr_span; /* Current hyperslab span node */ + H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */ + hsize_t slab[H5S_MAX_RANK]; /* Cumulative size of each dimension in bytes */ + hsize_t acc; /* Accumulator for computing cumulative sizes */ + hsize_t loc_off; /* Element offset in the dataspace */ + hsize_t last_span_end = 0; /* The offset of the end of the last span */ + hsize_t *abs_arr; /* Absolute hyperslab span position */ + const hssize_t *off_arr; /* Offset within the dataspace extent */ + size_t span_size = 0; /* Number of bytes in current span to actually process */ + size_t io_left; /* Number of elements left to process */ + size_t io_bytes_left; /* Number of bytes left to process */ + size_t io_used; /* Number of elements processed */ + size_t curr_seq = 0; /* Number of sequence/offsets stored in the arrays */ + size_t elem_size; /* Size of each element iterating over */ + unsigned ndims; /* Number of dimensions of dataset */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + int curr_dim; /* Current dimension being operated on */ + unsigned u; /* Index variable */ + int i; /* Index variable */ + FUNC_ENTER_STATIC_NOERR /* Check args */ + HDassert(space); HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); -/* Release the information needed for non-regular hyperslab I/O */ - /* Free the copy of the selections span tree */ - if(iter->u.hyp.spans != NULL) - H5S__hyper_free_span_info(iter->u.hyp.spans); + /* Set the rank of the fastest changing dimension */ + ndims = space->extent.rank; + fast_dim = (ndims - 1); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_iter_release() */ + /* Get the pointers to the current span info and span nodes */ + curr_span = iter->u.hyp.span[fast_dim]; + abs_arr = iter->u.hyp.off; + off_arr = space->select.offset; + ispan = iter->u.hyp.span; + elem_size = iter->elmt_size; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_new_span - PURPOSE - Make a new hyperslab span node - USAGE - H5S_hyper_span_t *H5S__hyper_new_span(low, high, down, next) - hsize_t low, high; IN: Low and high bounds for new span node - H5S_hyper_span_info_t *down; IN: Down span tree for new node - H5S_hyper_span_t *next; IN: Next span for new node - RETURNS - Pointer to next span node on success, NULL on failure - DESCRIPTION - Allocate and initialize a new hyperslab span node, filling in the low & - high bounds, the down span and next span pointers also. Increment the - reference count of the 'down span' if applicable. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5S_hyper_span_t * -H5S__hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next) -{ - H5S_hyper_span_t *ret_value = NULL; /* Return value */ + /* Set the amount of elements to perform I/O on, etc. */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + io_left = MIN(maxelem, (size_t)iter->elmt_left); + io_bytes_left = io_left * elem_size; - FUNC_ENTER_STATIC + /* Compute the cumulative size of dataspace dimensions */ + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= space->extent.size[i]; + } /* end for */ - /* Allocate a new span node */ - if(NULL == (ret_value = H5FL_MALLOC(H5S_hyper_span_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + /* Set the offset of the first element iterated on */ + for(u = 0, loc_off = 0; u < ndims; u++) + /* Compute the sequential element offset */ + loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; - /* Copy the span's basic information */ - ret_value->low = low; - ret_value->high = high; - ret_value->nelem = (high - low) + 1; - ret_value->pstride = 0; - ret_value->down = down; - ret_value->next = next; + /* Range check against number of elements left in selection */ + HDassert(io_bytes_left <= (iter->elmt_left * elem_size)); - /* Increment the reference count of the 'down span' if there is one */ - if(ret_value->down) - ret_value->down->count++; + /* Take care of any partial spans leftover from previous I/Os */ + if(abs_arr[fast_dim] != curr_span->low) { + /* Finish the span in the fastest changing dimension */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_new_span() */ + /* Compute the number of bytes to attempt in this span */ + H5_CHECKED_ASSIGN(span_size, size_t, ((curr_span->high - abs_arr[fast_dim])+1)*elem_size, hsize_t); - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_span_precompute_helper - PURPOSE - Helper routine to precompute the nelem and pstrides in bytes. - USAGE - void H5S__hyper_span_precompute_helper(span_info, elmt_size) - H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on - size_t elmt_size; IN: element size to work with - RETURNS - None - DESCRIPTION - Change the nelem and pstride values in the span tree from elements to - bytes using the elmt_size parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static void -H5S__hyper_span_precompute_helper(H5S_hyper_span_info_t *spans, size_t elmt_size) -{ - FUNC_ENTER_STATIC_NOERR + /* Check number of bytes against upper bounds allowed */ + if(span_size > io_bytes_left) + span_size = io_bytes_left; - /* Sanity checks */ - HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); + /* Add the partial span to the list of sequences */ + off[curr_seq] = loc_off; + len[curr_seq] = span_size; - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { - H5S_hyper_span_t *span; /* Hyperslab span */ + /* Increment sequence count */ + curr_seq++; - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); + /* Set the location of the last span's end */ + last_span_end = loc_off + span_size; - /* Set the scratch pointers in all the nodes */ - span = spans->head; + /* Decrement I/O left to perform */ + io_bytes_left -= span_size; - /* Loop over all the spans for this down span tree */ - while(span != NULL) { - /* If there are down spans, precompute their values also */ - if(span->down != NULL) - H5S__hyper_span_precompute_helper(span->down, elmt_size); + /* Check if we are done */ + if(io_bytes_left > 0) { + /* Move to next span in fastest changing dimension */ + curr_span = curr_span->next; - /* Change the nelem & pstride values into bytes */ - span->nelem *= elmt_size; - span->pstride *= elmt_size; + if(NULL != curr_span) { + /* Move location offset of destination */ + loc_off += (curr_span->low - abs_arr[fast_dim]) * elem_size; - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end if */ + /* Move iterator for fastest changing dimension */ + abs_arr[fast_dim] = curr_span->low; + } /* end if */ + } /* end if */ + else { + /* Advance the hyperslab iterator */ + abs_arr[fast_dim] += span_size / elem_size; - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_span_precompute_helper() */ + /* Check if we are still within the span */ + if(abs_arr[fast_dim] <= curr_span->high) { + iter->u.hyp.span[fast_dim] = curr_span; + } /* end if */ + /* If we walked off that span, advance to the next span */ + else { + /* Advance span in this dimension */ + curr_span = curr_span->next; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_span_precompute - PURPOSE - Precompute the nelem and pstrides in bytes. - USAGE - herr_t H5S__hyper_span_precompute(span_info, elmt_size) - H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on - size_t elmt_size; IN: element size to work with - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Change the nelem and pstride values in the span tree from elements to - bytes using the elmt_size parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size) -{ - FUNC_ENTER_STATIC_NOERR + /* Check if we have a valid span in this dimension still */ + if(NULL != curr_span) { + /* Reset absolute position */ + abs_arr[fast_dim] = curr_span->low; + iter->u.hyp.span[fast_dim] = curr_span; + } /* end if */ + } /* end else */ + } /* end else */ - HDassert(spans); + /* Adjust iterator pointers */ - /* Call the helper routine to actually do the work */ - H5S__hyper_span_precompute_helper(spans, elmt_size); + if(NULL == curr_span) { +/* Same as code in main loop */ + /* Start at the next fastest dim */ + curr_dim = (int)(fast_dim - 1); - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(spans); + /* Work back up through the dimensions */ + while(curr_dim >= 0) { + /* Reset the current span */ + curr_span = iter->u.hyp.span[curr_dim]; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_span_precompute() */ + /* Increment absolute position */ + abs_arr[curr_dim]++; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_span_scratch - PURPOSE - Reset the scratch pointers on hyperslab span trees - USAGE - void H5S__hyper_span_scratch(span_info) - H5S_hyper_span_info_t *span_info; IN: Span tree to reset - RETURNS - - DESCRIPTION - Reset the scratch pointers on a hyperslab span tree to NULL. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static void -H5S__hyper_span_scratch(H5S_hyper_span_info_t *spans) -{ - FUNC_ENTER_STATIC_NOERR - - HDassert(spans); + /* Check if we are still within the span */ + if(abs_arr[curr_dim] <= curr_span->high) { + break; + } /* end if */ + /* If we walked off that span, advance to the next span */ + else { + /* Advance span in this dimension */ + curr_span = curr_span->next; - /* Check if we've already set this down span tree */ - if(spans->scratch != NULL) { - H5S_hyper_span_t *span; /* Hyperslab span */ + /* Check if we have a valid span in this dimension still */ + if(NULL != curr_span) { + /* Reset the span in the current dimension */ + ispan[curr_dim] = curr_span; - /* Reset the tree's scratch pointer */ - spans->scratch = NULL; + /* Reset absolute position */ + abs_arr[curr_dim] = curr_span->low; - /* Set the scratch pointers in all the nodes */ - span = spans->head; - while(span != NULL) { - /* If there are down spans, set their scratch value also */ - if(span->down != NULL) - H5S__hyper_span_scratch(span->down); + break; + } /* end if */ + else + /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ + curr_dim--; + } /* end else */ + } /* end while */ - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end if */ + /* Check if we have more spans in the tree */ + if(curr_dim >= 0) { + /* Walk back down the iterator positions, resetting them */ + while((unsigned)curr_dim < fast_dim) { + HDassert(curr_span); + HDassert(curr_span->down); + HDassert(curr_span->down->head); - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_span_scratch() */ + /* Increment current dimension */ + curr_dim++; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_copy_span_helper - PURPOSE - Helper routine to copy a hyperslab span tree - USAGE - H5S_hyper_span_info_t * H5S__hyper_copy_span_helper(spans) - H5S_hyper_span_info_t *spans; IN: Span tree to copy - RETURNS - Pointer to the copied span tree on success, NULL on failure - DESCRIPTION - Copy a hyperslab span tree, using reference counting as appropriate. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5S_hyper_span_info_t * -H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans) -{ - H5S_hyper_span_t *span; /* Hyperslab span */ - H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ - H5S_hyper_span_t *prev_span; /* Previous hyperslab span */ - H5S_hyper_span_info_t *new_down; /* New down span tree */ - H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ + /* Set the new span_info & span for this dimension */ + iter->u.hyp.span[curr_dim] = curr_span->down->head; - FUNC_ENTER_STATIC + /* Advance span down the tree */ + curr_span = curr_span->down->head; - /* Sanity checks */ - HDassert(spans); - HDassert(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)); + /* Reset the absolute offset for the dim */ + abs_arr[curr_dim] = curr_span->low; + } /* end while */ - /* Check if the span tree was already copied */ - if(spans->scratch != NULL) { - /* Just return the value of the already copied span tree */ - ret_value = spans->scratch; + /* Verify that the curr_span points to the fastest dim */ + HDassert(curr_span == iter->u.hyp.span[fast_dim]); - /* Increment the reference count of the span tree */ - ret_value->count++; + /* Reset the buffer offset */ + for(u = 0, loc_off = 0; u < ndims; u++) + loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + } /* end else */ + else + /* We had better be done with I/O or bad things are going to happen... */ + HDassert(io_bytes_left == 0); + } /* end if */ } /* end if */ - else { - /* Allocate a new span_info node */ - if(NULL == (ret_value = H5FL_CALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info") - /* Copy the span_info information */ - ret_value->count = 1; + /* Perform the I/O on the elements, based on the position of the iterator */ + while(io_bytes_left > 0 && curr_seq < maxseq) { + /* Sanity check */ + HDassert(curr_span); - /* Set the scratch pointer in the node being copied to the newly allocated node */ - spans->scratch = ret_value; + /* Adjust location offset of destination to compensate for initial increment below */ + loc_off -= curr_span->pstride; - /* Copy over the nodes in the span list */ - span = spans->head; - prev_span = NULL; - while(span != NULL) { - /* Allocate a new node */ - if(NULL == (new_span = H5S__hyper_new_span(span->low, span->high, NULL, NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + /* Loop over all the spans in the fastest changing dimension */ + while(curr_span != NULL) { + /* Move location offset of destination */ + loc_off += curr_span->pstride; - /* Append to list of spans */ - if(NULL == prev_span) - ret_value->head = new_span; - else - prev_span->next = new_span; + /* Compute the number of elements to attempt in this span */ + H5_CHECKED_ASSIGN(span_size, size_t, curr_span->nelem, hsize_t); - /* Copy the pstride */ - new_span->pstride = span->pstride; + /* Check number of elements against upper bounds allowed */ + if(span_size >= io_bytes_left) { + /* Trim the number of bytes to output */ + span_size = io_bytes_left; + io_bytes_left = 0; - /* Recurse to copy the 'down' spans, if there are any */ - if(span->down != NULL) { - if(NULL == (new_down = H5S__hyper_copy_span_helper(span->down))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab spans") - new_span->down = new_down; - } /* end if */ +/* COMMON */ + /* Store the I/O information for the span */ - /* Update the previous (new) span */ - prev_span = new_span; + /* Check if this is appending onto previous sequence */ + if(curr_seq > 0 && last_span_end == loc_off) + len[curr_seq - 1] += span_size; + else { + off[curr_seq] = loc_off; + len[curr_seq] = span_size; - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end else */ + /* Increment the number of sequences in arrays */ + curr_seq++; + } /* end else */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_copy_span_helper() */ + /* Set the location of the last span's end */ + last_span_end = loc_off + span_size; +/* end COMMON */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_copy_span - PURPOSE - Copy a hyperslab span tree - USAGE - H5S_hyper_span_info_t * H5S__hyper_copy_span(span_info) - H5S_hyper_span_info_t *span_info; IN: Span tree to copy - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Copy a hyperslab span tree, using reference counting as appropriate. - (Which means that just the nodes in the top span tree are duplicated and - the reference counts of their 'down spans' are just incremented) - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5S_hyper_span_info_t * -H5S__hyper_copy_span(H5S_hyper_span_info_t *spans) -{ - H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ + /* Break out now, we are finished with I/O */ + break; + } /* end if */ + else { + /* Decrement I/O left to perform */ + io_bytes_left -= span_size; - FUNC_ENTER_STATIC +/* COMMON */ + /* Store the I/O information for the span */ - /* Sanity check */ - HDassert(spans); + /* Check if this is appending onto previous sequence */ + if(curr_seq > 0 && last_span_end == loc_off) + len[curr_seq - 1] += span_size; + else { + off[curr_seq] = loc_off; + len[curr_seq] = span_size; - /* Copy the hyperslab span tree */ - if(NULL == (ret_value = H5S__hyper_copy_span_helper(spans))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") + /* Increment the number of sequences in arrays */ + curr_seq++; + } /* end else */ - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(spans); + /* Set the location of the last span's end */ + last_span_end = loc_off + span_size; +/* end COMMON */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_copy_span() */ + /* If the sequence & offset arrays are full, do what? */ + if(curr_seq >= maxseq) + /* Break out now, we are finished with sequences */ + break; + } /* end else */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_cmp_spans - PURPOSE - Check if two hyperslab span trees are the same - USAGE - hbool_t H5S__hyper_cmp_spans(span1, span2) - H5S_hyper_span_info_t *span_info1; IN: First span tree to compare - H5S_hyper_span_info_t *span_info2; IN: Second span tree to compare - RETURNS - TRUE (1) or FALSE (0) on success, can't fail - DESCRIPTION - Compare two hyperslab span trees to determine if they refer to the same - selection. If span1 & span2 are both NULL, that counts as equal. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5_ATTR_PURE hbool_t -H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, - const H5S_hyper_span_info_t *span_info2) -{ - hbool_t ret_value = FALSE; /* Return value */ + /* Move to next span in fastest changing dimension */ + curr_span = curr_span->next; + } /* end while */ - FUNC_ENTER_STATIC_NOERR + /* Check if we are done */ + if(io_bytes_left == 0 || curr_seq >= maxseq) { + HDassert(curr_span); + abs_arr[fast_dim] = curr_span->low + (span_size / elem_size); - /* Check for redundant comparison (or both spans being NULL) */ - if(span_info1 == span_info2) - ret_value = TRUE; - else { - /* Check for one span being NULL */ - if(span_info1 == NULL || span_info2 == NULL) - ret_value = FALSE; - else { - const H5S_hyper_span_t *span1; - const H5S_hyper_span_t *span2; + /* Check if we are still within the span */ + if(abs_arr[fast_dim] <= curr_span->high) { + iter->u.hyp.span[fast_dim]=curr_span; + break; + } /* end if */ + /* If we walked off that span, advance to the next span */ + else { + /* Advance span in this dimension */ + curr_span = curr_span->next; - /* Get the pointers to the actual lists of spans */ - span1 = span_info1->head; - span2 = span_info2->head; + /* Check if we have a valid span in this dimension still */ + if(curr_span != NULL) { + /* Reset absolute position */ + abs_arr[fast_dim] = curr_span->low; + iter->u.hyp.span[fast_dim] = curr_span; + break; + } /* end if */ + } /* end else */ + } /* end if */ - /* Sanity checking */ - HDassert(span1); - HDassert(span2); + /* Adjust iterator pointers */ + + /* Start at the next fastest dim */ + curr_dim = (int)(fast_dim - 1); + + /* Work back up through the dimensions */ + while(curr_dim >= 0) { + /* Reset the current span */ + curr_span=iter->u.hyp.span[curr_dim]; + + /* Increment absolute position */ + abs_arr[curr_dim]++; + + /* Check if we are still within the span */ + if(abs_arr[curr_dim]<=curr_span->high) { + break; + } /* end if */ + /* If we walked off that span, advance to the next span */ + else { + /* Advance span in this dimension */ + curr_span = curr_span->next; + + /* Check if we have a valid span in this dimension still */ + if(curr_span != NULL) { + /* Reset the span in the current dimension */ + ispan[curr_dim] = curr_span; + + /* Reset absolute position */ + abs_arr[curr_dim] = curr_span->low; - /* infinite loop which must be broken out of */ - while(1) { - /* Check for both spans being NULL */ - if(span1 == NULL && span2 == NULL) { - ret_value = TRUE; break; } /* end if */ - else { - /* Check for one span being NULL */ - if(span1 == NULL || span2 == NULL) { - ret_value = FALSE; - break; - } /* end if */ - else { - /* Check if the actual low & high span information is the same */ - if(span1->low != span2->low || span1->high != span2->high) { - ret_value = FALSE; - break; - } /* end if */ - else { - if(span1->down != NULL || span2 != NULL) { - if(!H5S__hyper_cmp_spans(span1->down, span2->down)) { - ret_value = FALSE; - break; - } /* end if */ - else { - /* Keep going... */ - } /* end else */ - } /* end if */ - else { - /* Keep going... */ - } /* end else */ - } /* end else */ - } /* end else */ - } /* end else */ + else + /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ + curr_dim--; + } /* end else */ + } /* end while */ - /* Advance to the next nodes in the span list */ - span1 = span1->next; - span2 = span2->next; - } /* end while */ - } /* end else */ - } /* end else */ + /* Check if we are finished with the spans in the tree */ + if(curr_dim < 0) { + /* We had better be done with I/O or bad things are going to happen... */ + HDassert(io_bytes_left == 0); + break; + } /* end if */ + else { + /* Walk back down the iterator positions, resetting them */ + while((unsigned)curr_dim < fast_dim) { + HDassert(curr_span); + HDassert(curr_span->down); + HDassert(curr_span->down->head); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_cmp_spans() */ + /* Increment current dimension to the next dimension down */ + curr_dim++; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_free_span_info - PURPOSE - Free a hyperslab span info node - USAGE - herr_t H5S__hyper_free_span_info(span_info) - H5S_hyper_span_info_t *span_info; IN: Span info node to free - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Free a hyperslab span info node, along with all the span nodes and the - 'down spans' from the nodes, if reducing their reference count to zero - indicates it is appropriate to do so. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) -{ - H5S_hyper_span_t *span, *next_span; - herr_t ret_value = SUCCEED; /* Return value */ + /* Set the new span for the next dimension down */ + iter->u.hyp.span[curr_dim] = curr_span->down->head; - FUNC_ENTER_STATIC + /* Advance span down the tree */ + curr_span = curr_span->down->head; - HDassert(span_info); + /* Reset the absolute offset for the dim */ + abs_arr[curr_dim] = curr_span->low; + } /* end while */ - /* Decrement the span tree's reference count */ - span_info->count--; + /* Verify that the curr_span points to the fastest dim */ + HDassert(curr_span == iter->u.hyp.span[fast_dim]); + } /* end else */ - /* Free the span tree if the reference count drops to zero */ - if(span_info->count == 0) { + /* Reset the buffer offset */ + for(u = 0, loc_off = 0; u < ndims; u++) + loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + } /* end while */ - /* Work through the list of spans pointed to by this 'info' node */ - span = span_info->head; - while(span != NULL) { - next_span = span->next; - if(H5S__hyper_free_span(span) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span") - span = next_span; - } /* end while */ + /* Decrement number of elements left in iterator */ + io_used = (io_left - (io_bytes_left / elem_size)); + iter->elmt_left -= io_used; - /* Free this span info */ - span_info = H5FL_FREE(H5S_hyper_span_info_t, span_info); - } /* end if */ + /* Set the number of sequences generated */ + *nseq = curr_seq; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_free_span_info() */ + /* Set the number of elements used */ + *nelem = io_used; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_get_seq_list_gen() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_free_span + H5S__hyper_get_seq_list_opt PURPOSE - Free a hyperslab span node + Create a list of offsets & lengths for a selection USAGE - herr_t H5S__hyper_free_span(span) - H5S_hyper_span_t *span; IN: Span node to free + herr_t H5S_select_hyper_get_file_list_opt(space,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure. DESCRIPTION - Free a hyperslab span node, along with the 'down spans' from the node, - if reducing their reference count to zero indicates it is appropriate to - do so. + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_free_span(H5S_hyper_span_t *span) +H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) { - herr_t ret_value = SUCCEED; - - FUNC_ENTER_STATIC - - HDassert(span); - - /* Decrement the reference count of the 'down spans', freeing them if appropriate */ - if(span->down != NULL) - if(H5S__hyper_free_span_info(span->down) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span tree") - - /* Free this span */ - span = H5FL_FREE(H5S_hyper_span_t, span); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_free_span() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_copy - PURPOSE - Copy a selection from one dataspace to another - USAGE - herr_t H5S__hyper_copy(dst, src, share_selection) - H5S_t *dst; OUT: Pointer to the destination dataspace - H5S_t *src; IN: Pointer to the source dataspace - hbool_t; IN: Whether to share the selection between the dataspaces - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Copies all the hyperslab selection information from the source - dataspace to the destination dataspace. - - If the SHARE_SELECTION flag is set, then the selection can be shared - between the source and destination dataspaces. (This should only occur in - situations where the destination dataspace will immediately change to a new - selection) - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) -{ - H5S_hyper_sel_t *dst_hslab; /* Pointer to destination hyperslab info */ - const H5S_hyper_sel_t *src_hslab; /* Pointer to source hyperslab info */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC + hsize_t *mem_size; /* Size of the source buffer */ + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + const hssize_t *sel_off; /* Selection offset in dataspace */ + hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary block count */ + hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block offset */ + hsize_t wrap[H5S_MAX_RANK]; /* Bytes to wrap around at the end of a row */ + hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + hsize_t fast_dim_start, /* Local copies of fastest changing dimension info */ + fast_dim_stride, + fast_dim_block, + fast_dim_offset; + size_t fast_dim_buf_off; /* Local copy of amount to move fastest dimension buffer offset */ + size_t fast_dim_count; /* Number of blocks left in fastest changing dimension */ + size_t tot_blk_count; /* Total number of blocks left to output */ + size_t act_blk_count; /* Actual number of blocks to output */ + size_t total_rows; /* Total number of entire rows to output */ + size_t curr_rows; /* Current number of entire rows to output */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + unsigned ndims; /* Number of dimensions of dataset */ + int temp_dim; /* Temporary rank holder */ + hsize_t acc; /* Accumulator */ + hsize_t loc; /* Coordinate offset */ + size_t curr_seq = 0; /* Current sequence being operated on */ + size_t actual_elem; /* The actual number of elements to count */ + size_t actual_bytes;/* The actual number of bytes to copy */ + size_t io_left; /* The number of elements left in I/O operation */ + size_t start_io_left; /* The initial number of elements left in I/O operation */ + size_t elem_size; /* Size of each element iterating over */ + unsigned u; /* Local index variable */ + int i; /* Local index variable */ - /* Sanity check */ - HDassert(src); - HDassert(dst); + FUNC_ENTER_STATIC_NOERR - /* Allocate space for the hyperslab selection information */ - if(NULL == (dst->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); - /* Set temporary pointers */ - dst_hslab = dst->select.sel_info.hslab; - src_hslab = src->select.sel_info.hslab; + /* Set the local copy of the diminfo pointer */ + tdiminfo = iter->u.hyp.diminfo; - /* Copy the hyperslab information */ - dst_hslab->diminfo_valid = src_hslab->diminfo_valid; - if(src_hslab->diminfo_valid) { - size_t u; /* Local index variable */ + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + /* Set the aliases for a few important dimension ranks */ + ndims = iter->u.hyp.iter_rank; + fast_dim = ndims - 1; - for(u=0; uextent.rank; u++) { - dst_hslab->opt_diminfo[u]=src_hslab->opt_diminfo[u]; - dst_hslab->app_diminfo[u]=src_hslab->app_diminfo[u]; - } /* end for */ - } /* end if */ - dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst; + /* Set the local copy of the selection offset */ + sel_off = iter->u.hyp.sel_off; - /* Check if there is hyperslab span information to copy */ - /* (Regular hyperslab information is copied with the selection structure) */ - if(src->select.sel_info.hslab->span_lst != NULL) { - if(share_selection) { - /* Share the source's span tree by incrementing the reference count on it */ - dst->select.sel_info.hslab->span_lst = src->select.sel_info.hslab->span_lst; - dst->select.sel_info.hslab->span_lst->count++; - } /* end if */ - else - /* Copy the hyperslab span information */ - dst->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(src->select.sel_info.hslab->span_lst); + /* Set up the pointer to the size of the memory space */ + mem_size = iter->u.hyp.size; } /* end if */ - else - dst->select.sel_info.hslab->span_lst = NULL; + else { + /* Set the aliases for a few important dimension ranks */ + ndims = space->extent.rank; + fast_dim = ndims - 1; - /* Copy the unlimited dimension info */ - dst_hslab->unlim_dim = src_hslab->unlim_dim; - dst_hslab->num_elem_non_unlim = src_hslab->num_elem_non_unlim; + /* Set the local copy of the selection offset */ + sel_off = space->select.offset; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_copy() */ + /* Set up the pointer to the size of the memory space */ + mem_size = space->extent.size; + } /* end else */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_is_valid_helper - PURPOSE - Check whether the selection fits within the extent, with the current - offset defined. - USAGE - hbool_t H5S__hyper_is_valid_helper(spans, offset, rank); - const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree - const hssize_t *offset; IN: Pointer to offset array - const hsize_t *size; IN: Pointer to size array - hsize_t rank; IN: Current rank looking at - RETURNS - TRUE if the selection fits within the extent, FALSE if it does not - DESCRIPTION - Determines if the current selection at the current offset fits within the - extent for the dataspace. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_is_valid_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, - const hsize_t *size) -{ - H5S_hyper_span_t *curr; /* Hyperslab information nodes */ - hbool_t ret_value = TRUE; /* Return value */ + /* initialize row sizes for each dimension */ + elem_size = iter->elmt_size; + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= mem_size[i]; + } /* end for */ - FUNC_ENTER_STATIC_NOERR + /* Calculate the number of elements to sequence through */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + io_left = MIN((size_t)iter->elmt_left, maxelem); - HDassert(spans); - HDassert(offset); - HDassert(size); + /* Sanity check that there aren't any "remainder" sequences in process */ + HDassert(!((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || + ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1))); - /* Check each point to determine whether selection + offset is within extent */ - curr = spans->head; - while(curr != NULL) { - /* Check if an offset has been defined */ - /* Bounds check the selected point + offset against the extent */ - if((((hssize_t)curr->low + *offset) >= (hssize_t)*size) - || (((hssize_t)curr->low + *offset) < 0) - || (((hssize_t)curr->high + *offset) >= (hssize_t)*size) - || (((hssize_t)curr->high + *offset) < 0)) - HGOTO_DONE(FALSE) + /* We've cleared the "remainder" of the previous fastest dimension + * sequence before calling this routine, so we must be at the beginning of + * a sequence. Use the fancy algorithm to compute the offsets and run + * through as many as possible, until the buffer fills up. + */ - /* Recurse if this node has down spans */ - if(curr->down != NULL) - if(!H5S__hyper_is_valid_helper(curr->down, offset + 1, size + 1)) - HGOTO_DONE(FALSE) + /* Keep the number of elements we started with */ + start_io_left = io_left; - /* Advance to next node */ - curr = curr->next; - } /* end while */ + /* Compute the arrays to perform I/O on */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_valid_helper() */ + /* Copy the location of the point to get */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_is_valid - PURPOSE - Check whether the selection fits within the extent, with the current - offset defined. - USAGE - htri_t H5S__hyper_is_valid(space); - H5S_t *space; IN: Dataspace pointer to query - RETURNS - TRUE if the selection fits within the extent, FALSE if it does not and - Negative on an error. - DESCRIPTION - Determines if the current selection at the current offset fits within the - extent for the dataspace. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static htri_t -H5S__hyper_is_valid(const H5S_t *space) -{ - htri_t ret_value = TRUE; /* return value */ + /* Compute the current "counts" for this location */ + for(u = 0; u < ndims; u++) { + if(tdiminfo[u].count == 1) { + tmp_count[u] = 0; + tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; + } /* end if */ + else { + tmp_count[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) / tdiminfo[u].stride; + tmp_block[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) % tdiminfo[u].stride; + } /* end else */ + } /* end for */ - FUNC_ENTER_STATIC_NOERR + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += offset[u] * slab[u]; - HDassert(space); + /* Set the number of elements to write each time */ + H5_CHECKED_ASSIGN(actual_elem, size_t, tdiminfo[fast_dim].block, hsize_t); - /* Check for unlimited selection */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_DONE(FALSE) + /* Set the number of actual bytes */ + actual_bytes = actual_elem * elem_size; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ - hssize_t end; /* The high bound of a region in a dimension */ - unsigned u; /* Counter */ + /* Set local copies of information for the fastest changing dimension */ + fast_dim_start = tdiminfo[fast_dim].start; + fast_dim_stride = tdiminfo[fast_dim].stride; + fast_dim_block = tdiminfo[fast_dim].block; + H5_CHECKED_ASSIGN(fast_dim_buf_off, size_t, slab[fast_dim] * fast_dim_stride, hsize_t); + fast_dim_offset = (hsize_t)((hssize_t)fast_dim_start + sel_off[fast_dim]); - /* Check each dimension */ - for(u = 0; u < space->extent.rank; u++) { - /* if block or count is zero, then can skip the test since */ - /* no data point is chosen */ - if(diminfo[u].count && diminfo[u].block) { - /* Bounds check the start point in this dimension */ - if(((hssize_t)diminfo[u].start + space->select.offset[u]) < 0 || - ((hssize_t)diminfo[u].start + space->select.offset[u]) >= (hssize_t)space->extent.size[u]) - HGOTO_DONE(FALSE) + /* Compute the number of blocks which would fit into the buffer */ + H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); + tot_blk_count = (size_t)(io_left / fast_dim_block); - /* Compute the largest location in this dimension */ - end = (hssize_t)(diminfo[u].start + diminfo[u].stride * (diminfo[u].count - 1) + (diminfo[u].block - 1)) + space->select.offset[u]; + /* Don't go over the maximum number of sequences allowed */ + tot_blk_count = MIN(tot_blk_count, (maxseq - curr_seq)); - /* Bounds check the end point in this dimension */ - if(end < 0 || end >= (hssize_t)space->extent.size[u]) - HGOTO_DONE(FALSE) - } /* end if */ - } /* end for */ - } /* end if */ - else - /* Call the recursive routine to validate the span tree */ - ret_value = H5S__hyper_is_valid_helper(space->select.sel_info.hslab->span_lst, space->select.offset, space->extent.size); + /* Compute the amount to wrap at the end of each row */ + for(u = 0; u < ndims; u++) + wrap[u] = (mem_size[u] - (tdiminfo[u].stride * tdiminfo[u].count)) * slab[u]; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_valid() */ + /* Compute the amount to skip between blocks */ + for(u = 0; u < ndims; u++) + skip[u] = (tdiminfo[u].stride - tdiminfo[u].block) * slab[u]; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_span_nblocks - PURPOSE - Count the number of blocks in a span tree - USAGE - hsize_t H5S__hyper_span_nblocks(spans) - const H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count elements of - RETURNS - Number of blocks in span tree on success; negative on failure - DESCRIPTION - Counts the number of blocks described by the spans in a span tree. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static hsize_t -H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans) -{ - hsize_t ret_value = 0; /* Return value */ + /* Check if there is a partial row left (with full blocks) */ + if(tmp_count[fast_dim] > 0) { + /* Get number of blocks in fastest dimension */ + H5_CHECKED_ASSIGN(fast_dim_count, size_t, tdiminfo[fast_dim].count - tmp_count[fast_dim], hsize_t); - FUNC_ENTER_STATIC_NOERR + /* Make certain this entire row will fit into buffer */ + fast_dim_count = MIN(fast_dim_count, tot_blk_count); - /* Count the number of elements in the span tree */ - if(spans != NULL) { - H5S_hyper_span_t *span; /* Hyperslab span */ + /* Number of blocks to sequence over */ + act_blk_count = fast_dim_count; - span = spans->head; - while(span != NULL) { - /* If there are down spans, add the total down span blocks */ - if(span->down != NULL) - ret_value += H5S__hyper_span_nblocks(span->down); - /* If there are no down spans, just count the block in this span */ - else - ret_value++; + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; - /* Advance to next span */ - span = span->next; + /* Increment sequence count */ + curr_seq++; + + /* Increment information to reflect block just processed */ + loc += fast_dim_buf_off; + + /* Decrement number of blocks */ + fast_dim_count--; } /* end while */ - } /* end else */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_span_nblocks() */ + /* Decrement number of elements left */ + io_left -= actual_elem * act_blk_count; - -/*-------------------------------------------------------------------------- - NAME - H5S__get_select_hyper_nblocks - PURPOSE - Get the number of hyperslab blocks in current hyperslab selection - USAGE - hsize_t H5S__get_select_hyper_nblocks(space) - H5S_t *space; IN: Dataspace ptr of selection to query - RETURNS - The number of hyperslab blocks in selection on success, negative on failure - DESCRIPTION - Returns the number of hyperslab blocks in current selection for dataspace. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static hsize_t -H5S__get_select_hyper_nblocks(const H5S_t *space) -{ - hsize_t ret_value = 0; /* Return value */ + /* Decrement number of blocks left */ + tot_blk_count -= act_blk_count; - FUNC_ENTER_STATIC_NOERR + /* Increment information to reflect block just processed */ + tmp_count[fast_dim] += act_blk_count; - HDassert(space); - HDassert(space->select.sel_info.hslab->unlim_dim < 0); + /* Check if we finished the entire row of blocks */ + if(tmp_count[fast_dim] >= tdiminfo[fast_dim].count) { + /* Increment offset in destination buffer */ + loc += wrap[fast_dim]; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - unsigned u; /* Local index variable */ + /* Increment information to reflect block just processed */ + offset[fast_dim] = fast_dim_offset; /* reset the offset in the fastest dimension */ + tmp_count[fast_dim] = 0; - /* Check each dimension */ - for(ret_value = 1, u = 0; u < space->extent.rank; u++) - ret_value *= space->select.sel_info.hslab->app_diminfo[u].count; + /* Increment the offset and count for the other dimensions */ + temp_dim = (int)fast_dim - 1; + while(temp_dim >= 0) { + /* Move to the next row in the curent dimension */ + offset[temp_dim]++; + tmp_block[temp_dim]++; + + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + break; + else { + /* Move to the next block in the current dimension */ + offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); + loc += skip[temp_dim]; + tmp_block[temp_dim] = 0; + tmp_count[temp_dim]++; + + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_count[temp_dim] < tdiminfo[temp_dim].count) + break; + else { + offset[temp_dim] = (hsize_t)((hssize_t)tdiminfo[temp_dim].start + sel_off[temp_dim]); + loc += wrap[temp_dim]; + tmp_count[temp_dim] = 0; /* reset back to the beginning of the line */ + tmp_block[temp_dim] = 0; + } /* end else */ + } /* end else */ + + /* Decrement dimension count */ + temp_dim--; + } /* end while */ + } /* end if */ + else { + /* Update the offset in the fastest dimension */ + offset[fast_dim] += (fast_dim_stride * act_blk_count); + } /* end else */ } /* end if */ - else - ret_value = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__get_select_hyper_nblocks() */ + /* Compute the number of entire rows to read in */ + H5_CHECK_OVERFLOW(tot_blk_count / tdiminfo[fast_dim].count, hsize_t, size_t); + curr_rows = total_rows = (size_t)(tot_blk_count / tdiminfo[fast_dim].count); - -/*-------------------------------------------------------------------------- - NAME - H5Sget_select_hyper_nblocks - PURPOSE - Get the number of hyperslab blocks in current hyperslab selection - USAGE - hssize_t H5Sget_select_hyper_nblocks(dsid) - hid_t dsid; IN: Dataspace ID of selection to query - RETURNS - The number of hyperslab blocks in selection on success, negative on failure - DESCRIPTION - Returns the number of hyperslab blocks in current selection for dataspace. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hssize_t -H5Sget_select_hyper_nblocks(hid_t spaceid) -{ - H5S_t *space; /* Dataspace to modify selection of */ - hssize_t ret_value; /* return value */ + /* Reset copy of number of blocks in fastest dimension */ + H5_CHECKED_ASSIGN(fast_dim_count, size_t, tdiminfo[fast_dim].count, hsize_t); - FUNC_ENTER_API(FAIL) - H5TRACE1("Hs", "i", spaceid); + /* Read in data until an entire sequence can't be written out any longer */ + while(curr_rows > 0) { - /* Check args */ - if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get number of blocks for unlimited selection") +#define DUFF_GUTS \ +/* Store the sequence information */ \ +off[curr_seq] = loc; \ +len[curr_seq] = actual_bytes; \ + \ +/* Increment sequence count */ \ +curr_seq++; \ + \ +/* Increment information to reflect block just processed */ \ +loc += fast_dim_buf_off; - ret_value = (hssize_t)H5S__get_select_hyper_nblocks(space); +#ifdef NO_DUFFS_DEVICE + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + DUFF_GUTS -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sget_select_hyper_nblocks() */ + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ +#else /* NO_DUFFS_DEVICE */ + { + size_t duffs_index; /* Counting index for Duff's device */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_serial_size - PURPOSE - Determine the number of bytes needed to store the serialized hyperslab - selection information. - USAGE - hssize_t H5S__hyper_serial_size(space) - H5S_t *space; IN: Dataspace pointer to query - RETURNS - The number of bytes required on success, negative on an error. - DESCRIPTION - Determines the number of bytes required to serialize the current hyperslab - selection information for storage on disk. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static hssize_t -H5S__hyper_serial_size(const H5S_t *space) -{ - hsize_t block_count; /* block counter for regular hyperslabs */ - unsigned u; /* Counter */ - hssize_t ret_value = -1; /* return value */ + duffs_index = (fast_dim_count + 7) / 8; + switch (fast_dim_count % 8) { + default: + HDassert(0 && "This Should never be executed!"); + break; + case 0: + do + { + DUFF_GUTS + case 7: + DUFF_GUTS + case 6: + DUFF_GUTS + case 5: + DUFF_GUTS + case 4: + DUFF_GUTS + case 3: + DUFF_GUTS + case 2: + DUFF_GUTS + case 1: + DUFF_GUTS + } while (--duffs_index > 0); + } /* end switch */ + } +#endif /* NO_DUFFS_DEVICE */ +#undef DUFF_GUTS - FUNC_ENTER_STATIC_NOERR + /* Increment offset in destination buffer */ + loc += wrap[fast_dim]; - HDassert(space); + /* Increment the offset and count for the other dimensions */ + temp_dim = (int)fast_dim - 1; + while(temp_dim >= 0) { + /* Move to the next row in the curent dimension */ + offset[temp_dim]++; + tmp_block[temp_dim]++; - /* Check for version (right now, an unlimited dimension is the only thing - * that would bump the version) */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - /* Version 2 */ - /* Size required is always: - * + + + - * + + - * (4 (start/stride/count/block) * * ) = - * 17 + (4 * rank * 8) bytes - */ - ret_value = (hssize_t)17 + ((hssize_t)4 * (hssize_t)space->extent.rank - * (hssize_t)8); - else { - /* Version 1 */ - /* Basic number of bytes required to serialize hyperslab selection: - * + + + - * + + <# of blocks (4 bytes)> - * = 24 bytes - */ - ret_value = 24; + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + break; + else { + /* Move to the next block in the current dimension */ + offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); + loc += skip[temp_dim]; + tmp_block[temp_dim] = 0; + tmp_count[temp_dim]++; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - /* Check each dimension */ - for(block_count = 1, u = 0; u < space->extent.rank; u++) - block_count *= space->select.sel_info.hslab->opt_diminfo[u].count; - } /* end if */ - else - /* Spin through hyperslab spans, adding 8 * rank bytes for each block */ - block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_count[temp_dim] < tdiminfo[temp_dim].count) + break; + else { + offset[temp_dim] = (hsize_t)((hssize_t)tdiminfo[temp_dim].start + sel_off[temp_dim]); + loc += wrap[temp_dim]; + tmp_count[temp_dim] = 0; /* reset back to the beginning of the line */ + tmp_block[temp_dim] = 0; + } /* end else */ + } /* end else */ - H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t); - ret_value += (hssize_t)(8 * block_count * space->extent.rank); - } /* end else */ + /* Decrement dimension count */ + temp_dim--; + } /* end while */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_serial_size() */ + /* Decrement the number of rows left */ + curr_rows--; + } /* end while */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_serialize_helper - PURPOSE - Serialize the current selection into a user-provided buffer. - USAGE - void H5S__hyper_serialize_helper(spans, start, end, rank, buf) - H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to serialize - hssize_t start[]; IN/OUT: Accumulated start points - hssize_t end[]; IN/OUT: Accumulated end points - hsize_t rank; IN: Current rank looking at - uint8 *buf; OUT: Buffer to put serialized selection into - RETURNS - None - DESCRIPTION - Serializes the current element selection into a buffer. (Primarily for - storing on disk). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static void -H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, - hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p) -{ - H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ - uint8_t *pp = (*p); /* Local pointer for decoding */ + /* Adjust the number of blocks & elements left to transfer */ - FUNC_ENTER_STATIC_NOERR + /* Decrement number of elements left */ + H5_CHECK_OVERFLOW(actual_elem * (total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); + io_left -= (size_t)(actual_elem * (total_rows * tdiminfo[fast_dim].count)); - /* Sanity checks */ - HDassert(spans); - HDassert(start); - HDassert(end); - HDassert(rank < H5S_MAX_RANK); - HDassert(p && pp); + /* Decrement number of blocks left */ + H5_CHECK_OVERFLOW((total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); + tot_blk_count -= (size_t)(total_rows * tdiminfo[fast_dim].count); - /* Walk through the list of spans, recursing or outputting them */ - curr = spans->head; - while(curr != NULL) { - /* Recurse if this node has down spans */ - if(curr->down != NULL) { - /* Add the starting and ending points for this span to the list */ - start[rank] = curr->low; - end[rank] = curr->high; + /* Read in partial row of blocks */ + if(io_left > 0 && curr_seq < maxseq) { + /* Get remaining number of blocks left to output */ + fast_dim_count = tot_blk_count; - /* Recurse down to the next dimension */ - H5S__hyper_serialize_helper(curr->down, start, end, rank + 1, &pp); - } /* end if */ - else { - hsize_t u; /* Index variable */ + /* Loop over all the blocks in the fastest changing dimension */ + while(fast_dim_count > 0) { + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; - /* Encode all the previous dimensions starting & ending points */ + /* Increment sequence count */ + curr_seq++; - /* Encode previous starting points */ - for(u = 0; u < rank; u++) - UINT32ENCODE(pp, (uint32_t)start[u]); + /* Increment information to reflect block just processed */ + loc += fast_dim_buf_off; - /* Encode starting point for this span */ - UINT32ENCODE(pp, (uint32_t)curr->low); + /* Decrement number of blocks */ + fast_dim_count--; + } /* end while */ - /* Encode previous ending points */ - for(u = 0; u < rank; u++) - UINT32ENCODE(pp, (uint32_t)end[u]); + /* Decrement number of elements left */ + io_left -= actual_elem * tot_blk_count; - /* Encode starting point for this span */ - UINT32ENCODE(pp, (uint32_t)curr->high); - } /* end else */ + /* Increment information to reflect block just processed */ + offset[fast_dim] += (fast_dim_stride * tot_blk_count); /* move the offset in the fastest dimension */ - /* Advance to next node */ - curr = curr->next; - } /* end while */ + /* Handle any leftover, partial blocks in this row */ + if(io_left > 0 && curr_seq < maxseq) { + actual_elem = io_left; + actual_bytes = actual_elem * elem_size; - /* Update encoding pointer */ - *p = pp; + /* Store the sequence information */ + off[curr_seq] = loc; + len[curr_seq] = actual_bytes; - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_serialize_helper() */ + /* Increment sequence count */ + curr_seq++; + + /* Decrement the number of elements left */ + io_left -= actual_elem; + + /* Increment buffer correctly */ + offset[fast_dim] += actual_elem; + } /* end if */ + + /* don't bother checking slower dimensions */ + HDassert(io_left == 0 || curr_seq == maxseq); + } /* end if */ + + /* Update the iterator */ + + /* Update the iterator with the location we stopped */ + /* (Subtract out the selection offset) */ + for(u = 0; u < ndims; u++) + iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); + + /* Decrement the number of elements left in selection */ + iter->elmt_left -= (start_io_left - io_left); + + /* Increment the number of sequences generated */ + *nseq += curr_seq; + + /* Increment the number of elements used */ + *nelem += start_io_left - io_left; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_get_seq_list_opt() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_serialize + H5S__hyper_get_seq_list_single PURPOSE - Serialize the current selection into a user-provided buffer. + Create a list of offsets & lengths for a selection USAGE - herr_t H5S_hyper_serialize(space, p) - const H5S_t *space; IN: Dataspace with selection to serialize - uint8_t **p; OUT: Pointer to buffer to put serialized - selection. Will be advanced to end of - serialized selection. + herr_t H5S__hyper_get_seq_list_single(space, flags, iter, maxseq, maxelem, nseq, nelem, off, len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths RETURNS - Non-negative on success/Negative on failure + Non-negative on success/Negative on failure. DESCRIPTION - Serializes the current element selection into a buffer. (Primarily for - storing on disk). + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_serialize(const H5S_t *space, uint8_t **p) +H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) { - uint8_t *pp; /* Local pointer for decoding */ - uint8_t *lenp; /* Pointer to length location for later storage */ - uint32_t len = 0; /* Number of bytes used */ - uint32_t version; /* Version number */ - uint8_t flags = 0; /* Flags for message */ - hsize_t block_count; /* Block counter for regular hyperslabs */ + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const hssize_t *sel_off; /* Selection offset in dataspace */ + hsize_t *mem_size; /* Size of the source buffer */ + hsize_t base_offset[H5S_MAX_RANK]; /* Base coordinate offset in dataspace */ + hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + hsize_t fast_dim_block; /* Local copies of fastest changing dimension info */ + hsize_t acc; /* Accumulator */ + hsize_t loc; /* Coordinate offset */ + size_t tot_blk_count; /* Total number of blocks left to output */ + size_t elem_size; /* Size of each element iterating over */ + size_t io_left; /* The number of elements left in I/O operation */ + size_t actual_elem; /* The actual number of elements to count */ + unsigned ndims; /* Number of dimensions of dataset */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + unsigned skip_dim; /* Rank of the dimension to skip along */ + unsigned u; /* Local index variable */ + int i; /* Local index variable */ FUNC_ENTER_STATIC_NOERR - /* Sanity checks */ + /* Check args */ HDassert(space); - HDassert(p); - pp = (*p); - HDassert(pp); - - /* Calculate version */ - if(space->select.sel_info.hslab->unlim_dim >= 0) { - version = 2; - flags |= H5S_SELECT_FLAG_UNLIM; - } /* end if */ - else - version = 1; - - /* Store the preamble information */ - UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ - UINT32ENCODE(pp, version); /* Store the version number */ - if(version >= 2) - *(pp)++ = flags; /* Store the flags */ - else - UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */ - lenp = pp; /* keep the pointer to the length location for later */ - pp += 4; /* skip over space for length */ + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); - /* Encode number of dimensions */ - UINT32ENCODE(pp, (uint32_t)space->extent.rank); - len += 4; + /* Set a local copy of the diminfo pointer */ + tdiminfo = iter->u.hyp.diminfo; - /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ - if(flags & H5S_SELECT_FLAG_UNLIM) { - unsigned i; + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + /* Set the aliases for a few important dimension ranks */ + ndims = iter->u.hyp.iter_rank; - HDassert(H5S_UNLIMITED == HSIZE_UNDEF); + /* Set the local copy of the selection offset */ + sel_off = iter->u.hyp.sel_off; - /* Iterate over dimensions */ - for(i = 0; i < space->extent.rank; i++) { - /* Encode start/stride/block/count */ - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].start); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].stride); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].count); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].block); - } /* end for */ + /* Set up the pointer to the size of the memory space */ + mem_size = iter->u.hyp.size; } /* end if */ - /* Check for a "regular" hyperslab selection */ - else if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ - hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ - hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - unsigned ndims; /* Rank of the dataspace */ - unsigned u; /* Local counting variable */ - hbool_t done; /* Whether we are done with the iteration */ - - /* Set some convenience values */ + else { + /* Set the aliases for a few important dimension ranks */ ndims = space->extent.rank; - fast_dim = ndims - 1; - diminfo = space->select.sel_info.hslab->opt_diminfo; - /* Check each dimension */ - for(block_count = 1, u = 0; u < ndims; u++) - block_count *= diminfo[u].count; + /* Set the local copy of the selection offset */ + sel_off = space->select.offset; - /* Encode number of hyperslabs */ - H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(pp, (uint32_t)block_count); - len += 4; + /* Set up the pointer to the size of the memory space */ + mem_size = space->extent.size; + } /* end else */ + fast_dim = ndims - 1; - /* Now serialize the information for the regular hyperslab */ + /* initialize row sizes for each dimension */ + elem_size = iter->elmt_size; + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= mem_size[i]; + } /* end for */ - /* Build the tables of count sizes as well as the initial offset */ - for(u = 0; u < ndims; u++) { - tmp_count[u] = diminfo[u].count; - offset[u] = diminfo[u].start; - } /* end for */ + /* Copy the base location of the block */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + base_offset[u] = (hsize_t)((hssize_t)tdiminfo[u].start + sel_off[u]); - /* We're not done with the iteration */ - done = FALSE; + /* Copy the location of the point to get */ + /* (Add in the selection offset) */ + for(u = 0; u < ndims; u++) + offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); - /* Go iterate over the hyperslabs */ - while(done == FALSE) { - /* Iterate over the blocks in the fastest dimension */ - while(tmp_count[fast_dim] > 0) { - /* Add 8 bytes times the rank for each hyperslab selected */ - len += 8 * ndims; + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += offset[u] * slab[u]; - /* Encode hyperslab starting location */ - for(u = 0; u < ndims; u++) - UINT32ENCODE(pp, (uint32_t)offset[u]); + /* Set local copies of information for the fastest changing dimension */ + fast_dim_block = tdiminfo[fast_dim].block; - /* Encode hyperslab ending location */ - for(u = 0; u < ndims; u++) - UINT32ENCODE(pp, (uint32_t)(offset[u] + (diminfo[u].block - 1))); + /* Calculate the number of elements to sequence through */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + io_left = MIN((size_t)iter->elmt_left, maxelem); - /* Move the offset to the next sequence to start */ - offset[fast_dim]+=diminfo[fast_dim].stride; + /* Compute the number of blocks which would fit into the buffer */ + H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); + tot_blk_count = (size_t)(io_left / fast_dim_block); - /* Decrement the block count */ - tmp_count[fast_dim]--; - } /* end while */ + /* Don't go over the maximum number of sequences allowed */ + tot_blk_count = MIN(tot_blk_count, maxseq); - /* Work on other dimensions if necessary */ - if(fast_dim > 0) { - int temp_dim; /* Temporary rank holder */ + /* Set the number of elements to write each time */ + H5_CHECKED_ASSIGN(actual_elem, size_t, fast_dim_block, hsize_t); - /* Reset the block counts */ - tmp_count[fast_dim] = diminfo[fast_dim].count; + /* Check for blocks to operate on */ + if(tot_blk_count > 0) { + size_t actual_bytes; /* The actual number of bytes to copy */ - /* Bubble up the decrement to the slower changing dimensions */ - temp_dim = (int)fast_dim - 1; - while(temp_dim >= 0 && done == FALSE) { - /* Decrement the block count */ - tmp_count[temp_dim]--; + /* Set the number of actual bytes */ + actual_bytes = actual_elem * elem_size; - /* Check if we have more blocks left */ - if(tmp_count[temp_dim] > 0) - break; + /* Check for 1-dim selection */ + if(0 == fast_dim) { + /* Sanity checks */ + HDassert(1 == tot_blk_count); + HDassert(io_left == actual_elem); - /* Check for getting out of iterator */ - if(temp_dim == 0) - done = TRUE; + /* Store the sequence information */ + *off++ = loc; + *len++ = actual_bytes; + } /* end if */ + else { + hsize_t skip_slab; /* Temporary copy of slab[fast_dim - 1] */ + size_t blk_count; /* Total number of blocks left to output */ - /* Reset the block count in this dimension */ - tmp_count[temp_dim] = diminfo[temp_dim].count; + /* Find first dimension w/block >1 */ + skip_dim = fast_dim; + for(i = (int)(fast_dim - 1); i >= 0; i--) + if(tdiminfo[i].block > 1) { + skip_dim = (unsigned)i; + break; + } /* end if */ + skip_slab = slab[skip_dim]; - /* Wrapped a dimension, go up to next dimension */ - temp_dim--; + /* Check for being able to use fast algorithm for 1-D */ + if(0 == skip_dim) { + /* Create sequences until an entire row can't be used */ + blk_count = tot_blk_count; + while(blk_count > 0) { + /* Store the sequence information */ + *off++ = loc; + *len++ = actual_bytes; + + /* Increment offset in destination buffer */ + loc += skip_slab; + + /* Decrement block count */ + blk_count--; } /* end while */ + + /* Move to the next location */ + offset[skip_dim] += tot_blk_count; } /* end if */ - else - break; /* Break out now, for 1-D selections */ + else { + hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block offset */ + hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ + int temp_dim; /* Temporary rank holder */ - /* Re-compute offset array */ - for(u = 0; u < ndims; u++) - offset[u] = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); - } /* end while */ - } /* end if */ - else { - hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ - hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ - - /* Encode number of hyperslabs */ - block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); - H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); - UINT32ENCODE(pp, (uint32_t)block_count); - len += 4; + /* Set the starting block location */ + for(u = 0; u < ndims; u++) + tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; - /* Add 8 bytes times the rank for each hyperslab selected */ - H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t); - len += (uint32_t)(8 * space->extent.rank * block_count); + /* Compute the amount to skip between sequences */ + for(u = 0; u < ndims; u++) + skip[u] = (mem_size[u] - tdiminfo[u].block) * slab[u]; - /* Encode each hyperslab in selection */ - H5S__hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &pp); - } /* end else */ + /* Create sequences until an entire row can't be used */ + blk_count = tot_blk_count; + while(blk_count > 0) { + /* Store the sequence information */ + *off++ = loc; + *len++ = actual_bytes; - /* Encode length */ - UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */ + /* Set temporary dimension for advancing offsets */ + temp_dim = (int)skip_dim; - /* Update encoding pointer */ - *p = pp; + /* Increment offset in destination buffer */ + loc += skip_slab; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_serialize() */ + /* Increment the offset and count for the other dimensions */ + while(temp_dim >= 0) { + /* Move to the next row in the curent dimension */ + offset[temp_dim]++; + tmp_block[temp_dim]++; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_deserialize - PURPOSE - Deserialize the current selection from a user-provided buffer. - USAGE - herr_t H5S__hyper_deserialize(space, p) - H5S_t *space; IN/OUT: Dataspace pointer to place - selection into - uint32_t version IN: Selection version - uint8_t flags IN: Selection flags - uint8 **p; OUT: Pointer to buffer holding serialized - selection. Will be advanced to end of - serialized selection. - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Deserializes the current selection into a buffer. (Primarily for retrieving - from disk). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t flags, - const uint8_t **p) -{ - unsigned rank; /* Rank of points */ - const uint8_t *pp; /* Local pointer for decoding */ - hsize_t start[H5S_MAX_RANK]; /* Hyperslab start information */ - hsize_t block[H5S_MAX_RANK]; /* Hyperslab block information */ - unsigned u; /* Local counting variable */ - herr_t ret_value = FAIL; /* Return value */ + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + break; + else { + offset[temp_dim] = base_offset[temp_dim]; + loc += skip[temp_dim]; + tmp_block[temp_dim] = 0; + } /* end else */ - FUNC_ENTER_STATIC + /* Decrement dimension count */ + temp_dim--; + } /* end while */ - /* Check args */ - HDassert(space); - HDassert(p); - pp = (*p); - HDassert(pp); + /* Decrement block count */ + blk_count--; + } /* end while */ + } /* end else */ + } /* end else */ - /* Deserialize slabs to select */ - /* (The header and rank have already beed decoded) */ - rank = space->extent.rank; /* Retrieve rank from space */ + /* Update the iterator, if there were any blocks used */ - /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ - if(flags & H5S_SELECT_FLAG_UNLIM) { - hsize_t stride[H5S_MAX_RANK]; /* Hyperslab stride information */ - hsize_t count[H5S_MAX_RANK]; /* Hyperslab count information */ + /* Decrement the number of elements left in selection */ + iter->elmt_left -= tot_blk_count * actual_elem; - /* Sanity checks */ - HDassert(H5S_UNLIMITED == HSIZE_UNDEF); - HDassert(version >= 2); + /* Check if there are elements left in iterator */ + if(iter->elmt_left > 0) { + /* Update the iterator with the location we stopped */ + /* (Subtract out the selection offset) */ + for(u = 0; u < ndims; u++) + iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); + } /* end if */ - /* Iterate over dimensions */ - for(u = 0; u < rank; u++) { - /* Decode start/stride/block/count */ - UINT64DECODE(pp, start[u]); - UINT64DECODE(pp, stride[u]); - UINT64DECODE(pp, count[u]); - UINT64DECODE(pp, block[u]); - } /* end for */ + /* Increment the number of sequences generated */ + *nseq += tot_blk_count; - /* Select the hyperslab to the current selection */ - if((ret_value = H5S_select_hyperslab(space, H5S_SELECT_SET, start, stride, count, block)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't change selection") + /* Increment the number of elements used */ + *nelem += tot_blk_count * actual_elem; } /* end if */ - else { - const hsize_t *stride; /* Hyperslab stride information */ - const hsize_t *count; /* Hyperslab count information */ - hsize_t end[H5S_MAX_RANK]; /* Hyperslab end information */ - hsize_t *tstart; /* Temporary hyperslab pointers */ - hsize_t *tend; /* Temporary hyperslab pointers */ - hsize_t *tblock; /* Temporary hyperslab pointers */ - size_t block_count; /* Number of blocks in selection */ - unsigned v; /* Local counting variable */ - /* Decode the number of blocks */ - UINT32DECODE(pp, block_count); + /* Check for partial block, with room for another sequence */ + if(io_left > (tot_blk_count * actual_elem) && tot_blk_count < maxseq) { + size_t elmt_remainder; /* Elements remaining */ - /* Set the count & stride for all blocks */ - stride = count = H5S_hyper_ones_g; + /* Compute elements left */ + elmt_remainder = io_left - (tot_blk_count * actual_elem); + HDassert(elmt_remainder < fast_dim_block); + HDassert(elmt_remainder > 0); - /* Retrieve the coordinates from the buffer */ - for(u = 0; u < block_count; u++) { - /* Decode the starting points */ - for(tstart = start, v = 0; v < rank; v++, tstart++) - UINT32DECODE(pp, *tstart); + /* Store the sequence information */ + *off++ = loc; + *len++ = elmt_remainder * elem_size; - /* Decode the ending points */ - for(tend = end, v = 0; v < rank; v++, tend++) - UINT32DECODE(pp, *tend); + /* Update the iterator with the location we stopped */ + iter->u.hyp.off[fast_dim] += (hsize_t)elmt_remainder; - /* Change the ending points into blocks */ - for(tblock = block, tstart = start, tend = end, v = 0; v < rank; v++, tstart++, tend++, tblock++) - *tblock = (*tend - *tstart) + 1; + /* Decrement the number of elements left in selection */ + iter->elmt_left -= elmt_remainder; - /* Select or add the hyperslab to the current selection */ - if((ret_value = H5S_select_hyperslab(space, (u == 0 ? H5S_SELECT_SET : H5S_SELECT_OR), start, stride, count, block)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't change selection") - } /* end for */ - } /* end else */ + /* Increment the number of sequences generated */ + (*nseq)++; - /* Update decoding pointer */ - *p = pp; + /* Increment the number of elements used */ + *nelem += elmt_remainder; + } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_deserialize() */ + /* Sanity check */ + HDassert(*nseq > 0); + HDassert(*nelem > 0); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_get_seq_list_single() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_span_blocklist + H5S__hyper_get_seq_list PURPOSE - Get a list of hyperslab blocks currently selected + Create a list of offsets & lengths for a selection USAGE - herr_t H5S__hyper_span_blocklist(spans, start, end, rank, startblock, numblocks, buf) - H5S_hyper_span_info_t *spans; IN: Dataspace pointer of selection to query - hsize_t start[]; IN/OUT: Accumulated start points - hsize_t end[]; IN/OUT: Accumulated end points - hsize_t rank; IN: Rank of dataspace - hsize_t *startblock; IN/OUT: Hyperslab block to start with - hsize_t *numblocks; IN/OUT: Number of hyperslab blocks to get - hsize_t **buf; OUT: List of hyperslab blocks selected + herr_t H5S__hyper_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets (in bytes) + size_t *len; OUT: Array of lengths (in bytes) RETURNS - Non-negative on success/Negative on failure + Non-negative on success/Negative on failure. DESCRIPTION - Puts a list of the hyperslab blocks into the user's buffer. The blocks - start with the '*startblock'th block in the list of blocks and put - '*numblocks' number of blocks into the user's buffer (or until the end of - the list of blocks, whichever happens first) - The block coordinates have the same dimensionality (rank) as the - dataspace they are located within. The list of blocks is formatted as - follows: <"start" coordinate> immediately followed by <"opposite" corner - coordinate>, followed by the next "start" and "opposite" coordinate, etc. - until all the block information requested has been put into the user's - buffer. - No guarantee of any order of the blocks is implied. + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], - hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, - hsize_t **buf) +H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) { - const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ - hsize_t u; /* Index variable */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_STATIC + herr_t ret_value = FAIL; /* return value */ - /* Sanity checks */ - HDassert(spans); - HDassert(rank < H5S_MAX_RANK); - HDassert(start); - HDassert(end); - HDassert(startblock); - HDassert(numblocks && *numblocks > 0); - HDassert(buf && *buf); + FUNC_ENTER_STATIC_NOERR - /* Walk through the list of spans, recursing or outputting them */ - curr = spans->head; - while(curr != NULL && *numblocks > 0) { - /* Recurse if this node has down spans */ - if(curr->down != NULL) { - /* Add the starting and ending points for this span to the list */ - start[rank] = curr->low; - end[rank] = curr->high; + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(iter->elmt_left > 0); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); - /* Recurse down to the next dimension */ - if(H5S__hyper_span_blocklist(curr->down, start, end, (rank + 1), startblock, numblocks, buf) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + /* Check for the special case of just one H5Sselect_hyperslab call made */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const hssize_t *sel_off; /* Selection offset in dataspace */ + hsize_t *mem_size; /* Size of the source buffer */ + unsigned ndims; /* Number of dimensions of dataset */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + hbool_t single_block; /* Whether the selection is a single block */ + unsigned u; /* Local index variable */ + + /* Set a local copy of the diminfo pointer */ + tdiminfo = iter->u.hyp.diminfo; + + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + /* Set the aliases for a few important dimension ranks */ + ndims = iter->u.hyp.iter_rank; + + /* Set the local copy of the selection offset */ + sel_off = iter->u.hyp.sel_off; + + /* Set up the pointer to the size of the memory space */ + mem_size = iter->u.hyp.size; } /* end if */ else { - /* Skip this block if we haven't skipped all the startblocks yet */ - if(*startblock > 0) { - /* Decrement the starting block */ - (*startblock)--; + /* Set the aliases for a few important dimension ranks */ + ndims = space->extent.rank; + + /* Set the local copy of the selection offset */ + sel_off = space->select.offset; + + /* Set up the pointer to the size of the memory space */ + mem_size = space->extent.size; + } /* end else */ + fast_dim = ndims - 1; + + /* Check if we stopped in the middle of a sequence of elements */ + if((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || + ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1)) { + hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + hsize_t loc; /* Coordinate offset */ + hsize_t acc; /* Accumulator */ + size_t leftover; /* The number of elements left over from the last sequence */ + size_t actual_elem; /* The actual number of elements to count */ + size_t elem_size; /* Size of each element iterating over */ + int i; /* Local index variable */ + + + /* Calculate the number of elements left in the sequence */ + if(tdiminfo[fast_dim].count == 1) { + H5_CHECKED_ASSIGN(leftover, size_t, tdiminfo[fast_dim].block - (iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start), hsize_t); } /* end if */ - /* Process this block */ else { - /* Encode all the previous dimensions starting & ending points */ + H5_CHECKED_ASSIGN(leftover, size_t, tdiminfo[fast_dim].block - ((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride), hsize_t); + } /* end else */ - /* Copy previous starting points */ - for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &start[u], sizeof(hsize_t)); + /* Make certain that we don't write too many */ + actual_elem = MIN3(leftover, (size_t)iter->elmt_left, maxelem); - /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->low, sizeof(hsize_t)); - (*buf)++; + /* Initialize row sizes for each dimension */ + elem_size = iter->elmt_size; + for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { + slab[i] = acc; + acc *= mem_size[i]; + } /* end for */ - /* Copy previous ending points */ - for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &end[u], sizeof(hsize_t)); + /* Compute the initial buffer offset */ + for(u = 0, loc = 0; u < ndims; u++) + loc += ((hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u])) * slab[u]; - /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->high, sizeof(hsize_t)); - (*buf)++; + /* Add a new sequence */ + off[0] = loc; + H5_CHECKED_ASSIGN(len[0], size_t, actual_elem * elem_size, hsize_t); - /* Decrement the number of blocks processed */ - (*numblocks)--; - } /* end else */ + /* Increment sequence array locations */ + off++; + len++; + + /* Advance the hyperslab iterator */ + H5S__hyper_iter_next(iter, actual_elem); + + /* Decrement the number of elements left in selection */ + iter->elmt_left -= actual_elem; + + /* Decrement element/sequence limits */ + maxelem -= actual_elem; + maxseq--; + + /* Set the number of sequences generated and elements used */ + *nseq = 1; + *nelem = actual_elem; + + /* Check for using up all the sequences/elements */ + if(0 == iter->elmt_left || 0 == maxelem || 0 == maxseq) + return(SUCCEED); + } /* end if */ + else { + /* Reset the number of sequences generated and elements used */ + *nseq = 0; + *nelem = 0; } /* end else */ - /* Advance to next node */ - curr = curr->next; - } /* end while */ + /* Check for a single block selected */ + single_block = TRUE; + for(u = 0; u < ndims; u++) + if(1 != tdiminfo[u].count) { + single_block = FALSE; + break; + } /* end if */ + + /* Check for single block selection */ + if(single_block) + /* Use single-block optimized call to generate sequence list */ + ret_value = H5S__hyper_get_seq_list_single(space, iter, maxseq, maxelem, nseq, nelem, off, len); + else + /* Use optimized call to generate sequence list */ + ret_value = H5S__hyper_get_seq_list_opt(space, iter, maxseq, maxelem, nseq, nelem, off, len); + } /* end if */ + else + /* Call the general sequence generator routine */ + ret_value = H5S__hyper_get_seq_list_gen(space, iter, maxseq, maxelem, nseq, nelem, off, len); -done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_span_blocklist() */ +} /* end H5S__hyper_get_seq_list() */ /*-------------------------------------------------------------------------- NAME - H5S__get_select_hyper_blocklist + H5S__hyper_iter_release PURPOSE - Get the list of hyperslab blocks currently selected + Release hyperslab selection iterator information for a dataspace USAGE - herr_t H5S__get_select_hyper_blocklist(space, startblock, numblocks, buf) - H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t startblock; IN: Hyperslab block to start with - hsize_t numblocks; IN: Number of hyperslab blocks to get - hsize_t *buf; OUT: List of hyperslab blocks selected + herr_t H5S__hyper_iter_release(iter) + H5S_sel_iter_t *iter; IN: Pointer to selection iterator RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION - Puts a list of the hyperslab blocks into the user's buffer. The blocks - start with the 'startblock'th block in the list of blocks and put - 'numblocks' number of blocks into the user's buffer (or until the end of - the list of blocks, whichever happens first) - The block coordinates have the same dimensionality (rank) as the - dataspace they are located within. The list of blocks is formatted as - follows: <"start" coordinate> immediately followed by <"opposite" corner - coordinate>, followed by the next "start" and "opposite" coordinate, etc. - until all the block information requested has been put into the user's - buffer. - No guarantee of any order of the blocks is implied. + Releases all information for a dataspace hyperslab selection iterator GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblock, hsize_t numblocks, hsize_t *buf) +H5S__hyper_iter_release(H5S_sel_iter_t *iter) { - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR - HDassert(space); - HDassert(buf); - HDassert(space->select.sel_info.hslab->unlim_dim < 0); + /* Check args */ + HDassert(iter); - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ - hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ - hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - unsigned ndims; /* Rank of the dataspace */ - hbool_t done; /* Whether we are done with the iteration */ - unsigned u; /* Counter */ + /* Free the copy of the hyperslab selection span tree */ + if(iter->u.hyp.spans != NULL) + H5S__hyper_free_span_info(iter->u.hyp.spans); - /* Set some convienence values */ - ndims = space->extent.rank; - fast_dim = ndims - 1; + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_iter_release() */ - /* Check which set of dimension information to use */ - if(internal) - /* - * Use the "optimized dimension information" to pass back information - * on the blocks set, not the "application information". - */ - diminfo = space->select.sel_info.hslab->opt_diminfo; - else - if(space->select.sel_info.hslab->unlim_dim >= 0) - /* - * There is an unlimited dimension so we must use opt_diminfo as - * it has been "clipped" to the current extent. - */ - diminfo = space->select.sel_info.hslab->opt_diminfo; - else - /* - * Use the "application dimension information" to pass back to - * the user the blocks they set, not the optimized, internal - * information. - */ - diminfo = space->select.sel_info.hslab->app_diminfo; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_new_span + PURPOSE + Make a new hyperslab span node + USAGE + H5S_hyper_span_t *H5S__hyper_new_span(low, high, down, next) + hsize_t low, high; IN: Low and high bounds for new span node + H5S_hyper_span_info_t *down; IN: Down span tree for new node + H5S_hyper_span_t *next; IN: Next span for new node + RETURNS + Pointer to new span node on success, NULL on failure + DESCRIPTION + Allocate and initialize a new hyperslab span node, filling in the low & + high bounds, the down span and next span pointers also. Increment the + reference count of the 'down span' if applicable. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5S_hyper_span_t * +H5S__hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, + H5S_hyper_span_t *next) +{ + H5S_hyper_span_t *ret_value = NULL; /* Return value */ - /* Build the tables of count sizes as well as the initial offset */ - for(u = 0; u < ndims; u++) { - tmp_count[u] = diminfo[u].count; - offset[u] = diminfo[u].start; - } /* end for */ + FUNC_ENTER_STATIC - /* We're not done with the iteration */ - done = FALSE; - - /* Go iterate over the hyperslabs */ - while(!done && numblocks > 0) { - hsize_t temp_off; /* Offset in a given dimension */ - - /* Iterate over the blocks in the fastest dimension */ - while(tmp_count[fast_dim] > 0 && numblocks > 0) { - - /* Check if we should copy this block information */ - if(startblock == 0) { - /* Copy the starting location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); - buf += ndims; - - /* Compute the ending location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); - for(u = 0; u < ndims; u++) - buf[u] += (diminfo[u].block - 1); - buf += ndims; + /* Allocate a new span node */ + if(NULL == (ret_value = H5FL_MALLOC(H5S_hyper_span_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Decrement the number of blocks to retrieve */ - numblocks--; - } /* end if */ - else - startblock--; + /* Copy the span's basic information */ + ret_value->low = low; + ret_value->high = high; + ret_value->nelem = (high - low) + 1; + ret_value->pstride = 0; + ret_value->down = down; + ret_value->next = next; - /* Move the offset to the next sequence to start */ - offset[fast_dim] += diminfo[fast_dim].stride; + /* Increment the reference count of the 'down span' if there is one */ + if(ret_value->down) + ret_value->down->count++; - /* Decrement the block count */ - tmp_count[fast_dim]--; - } /* end while */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_new_span() */ - /* Work on other dimensions if necessary */ - if(fast_dim > 0 && numblocks > 0) { - int temp_dim; /* Temporary rank holder */ + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_span_precompute_helper + PURPOSE + Helper routine to precompute the nelem and pstrides in bytes. + USAGE + void H5S__hyper_span_precompute_helper(span_info, elmt_size) + H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on + size_t elmt_size; IN: element size to work with + RETURNS + None + DESCRIPTION + Change the nelem and pstride values in the span tree from elements to + bytes using the elmt_size parameter. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5S__hyper_span_precompute_helper(H5S_hyper_span_info_t *spans, size_t elmt_size) +{ + FUNC_ENTER_STATIC_NOERR - /* Reset the block counts */ - tmp_count[fast_dim] = diminfo[fast_dim].count; + /* Sanity checks */ + HDassert(spans); + HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || + spans->scratch == NULL); - /* Bubble up the decrement to the slower changing dimensions */ - temp_dim = (int)(fast_dim - 1); - while(temp_dim >= 0 && !done) { - /* Decrement the block count */ - tmp_count[temp_dim]--; + /* Check if we've already set this down span tree */ + if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { + H5S_hyper_span_t *span; /* Hyperslab span */ - /* Check if we have more blocks left */ - if(tmp_count[temp_dim] > 0) - break; + /* Set the tree's scratch pointer */ + spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); - /* Check for getting out of iterator */ - if(temp_dim == 0) - done = TRUE; + /* Set the scratch pointers in all the nodes */ + span = spans->head; - /* Reset the block count in this dimension */ - tmp_count[temp_dim] = diminfo[temp_dim].count; + /* Loop over all the spans for this down span tree */ + while(span != NULL) { + /* If there are down spans, precompute their values also */ + if(span->down != NULL) + H5S__hyper_span_precompute_helper(span->down, elmt_size); - /* Wrapped a dimension, go up to next dimension */ - temp_dim--; - } /* end while */ - } /* end if */ + /* Change the nelem & pstride values into bytes */ + span->nelem *= elmt_size; + span->pstride *= elmt_size; - /* Re-compute offset array */ - for(u = 0; u < ndims; u++) { - temp_off = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); - offset[u] = temp_off; - } /* end for */ + /* Advance to next span */ + span = span->next; } /* end while */ } /* end if */ - else { - hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ - hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ - - ret_value = H5S__hyper_span_blocklist(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &startblock, &numblocks, &buf); - } /* end else */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__get_select_hyper_blocklist() */ + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_span_precompute_helper() */ /*-------------------------------------------------------------------------- NAME - H5Sget_select_hyper_blocklist + H5S__hyper_span_precompute PURPOSE - Get the list of hyperslab blocks currently selected + Precompute the nelem and pstrides in bytes. USAGE - herr_t H5Sget_select_hyper_blocklist(dsid, startblock, numblocks, buf) - hid_t dsid; IN: Dataspace ID of selection to query - hsize_t startblock; IN: Hyperslab block to start with - hsize_t numblocks; IN: Number of hyperslab blocks to get - hsize_t buf[]; OUT: List of hyperslab blocks selected + herr_t H5S__hyper_span_precompute(span_info, elmt_size) + H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on + size_t elmt_size; IN: element size to work with RETURNS Non-negative on success, negative on failure DESCRIPTION - Puts a list of the hyperslab blocks into the user's buffer. The blocks - start with the 'startblock'th block in the list of blocks and put - 'numblocks' number of blocks into the user's buffer (or until the end of - the list of blocks, whichever happen first) - The block coordinates have the same dimensionality (rank) as the - dataspace they are located within. The list of blocks is formatted as - follows: <"start" coordinate> immediately followed by <"opposite" corner - coordinate>, followed by the next "start" and "opposite" coordinate, etc. - until all the block information requested has been put into the user's - buffer. - No guarantee of any order of the blocks is implied. + Change the nelem and pstride values in the span tree from elements to + bytes using the elmt_size parameter. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, - hsize_t numblocks, hsize_t buf[/*numblocks*/]) +static herr_t +H5S__hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size) { - H5S_t *space; /* Dataspace to modify selection of */ - herr_t ret_value; /* return value */ + FUNC_ENTER_STATIC_NOERR - FUNC_ENTER_API(FAIL) - H5TRACE4("e", "ihh*[a2]h", spaceid, startblock, numblocks, buf); + HDassert(spans); - /* Check args */ - if(buf == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer") - if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get blocklist for unlimited selection") + /* Call the helper routine to actually do the work */ + H5S__hyper_span_precompute_helper(spans, elmt_size); - /* Go get the correct number of blocks */ - if(numblocks > 0) - ret_value = H5S__get_select_hyper_blocklist(space, 0, startblock, numblocks, buf); - else - ret_value = SUCCEED; /* Successfully got 0 blocks... */ + /* Reset the scratch pointers for the next routine which needs them */ + H5S__hyper_span_scratch(spans); -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sget_select_hyper_blocklist() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_span_precompute() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_bounds_helper + H5S__hyper_span_scratch PURPOSE - Gets the bounding box containing the selection. + Reset the scratch pointers on hyperslab span trees USAGE - htri_t H5S_hyper_bounds_helper(spans, offset, rank); - const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree - const hssize_t *offset; IN: Pointer to offset array - hsize_t rank; IN: Current rank looking at - hsize_t *start; OUT: Start array bounds - hsize_t *end; OUT: End array bounds + void H5S__hyper_span_scratch(span_info) + H5S_hyper_span_info_t *span_info; IN: Span tree to reset RETURNS - Non-negative on success, negative on failure + DESCRIPTION - Retrieves the bounding box containing the current selection and places - it into the user's buffers. The start and end buffers must be large - enough to hold the dataspace rank number of coordinates. The bounding box - exactly contains the selection, ie. if a 2-D element selection is currently - defined with the following points: (4,5), (6,8) (10,7), the bounding box - with be (4, 5), (10, 8). - The bounding box calculations _does_ include the current offset of the - selection within the dataspace extent. + Reset the scratch pointers on a hyperslab span tree to NULL. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end) +static void +H5S__hyper_span_scratch(H5S_hyper_span_info_t *spans) { - H5S_hyper_span_t *curr; /* Hyperslab information nodes */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR HDassert(spans); - HDassert(offset); - HDassert(rank < H5S_MAX_RANK); - HDassert(start); - HDassert(end); - /* Check each point to determine whether selection+offset is within extent */ - curr=spans->head; - while(curr!=NULL) { - /* Check for offset moving selection negative */ - if(((hssize_t)curr->low + offset[rank]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - - /* Check if the current span extends the bounding box */ - if((curr->low + (hsize_t)offset[rank]) < start[rank]) - start[rank] = curr->low + (hsize_t)offset[rank]; - if((curr->high + (hsize_t)offset[rank]) > end[rank]) - end[rank] = curr->high + (hsize_t)offset[rank]; + /* Check if we've already set this down span tree */ + if(spans->scratch != NULL) { + H5S_hyper_span_t *span; /* Hyperslab span */ - /* Recurse if this node has down spans */ - if(curr->down != NULL) { - if(H5S_hyper_bounds_helper(curr->down, offset, (rank + 1), start, end) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "failure in lower dimension") - } /* end if */ + /* Reset the tree's scratch pointer */ + spans->scratch = NULL; - /* Advance to next node */ - curr = curr->next; - } /* end while */ + /* Set the scratch pointers in all the nodes */ + span = spans->head; + while(span != NULL) { + /* If there are down spans, set their scratch value also */ + if(span->down != NULL) + H5S__hyper_span_scratch(span->down); -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_bounds_helper() */ + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end if */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_span_scratch() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_bounds + H5S__hyper_copy_span_helper PURPOSE - Gets the bounding box containing the selection. + Helper routine to copy a hyperslab span tree USAGE - herr_t H5S__hyper_bounds(space, hsize_t *start, hsize_t *end) - H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *start; OUT: Starting coordinate of bounding box - hsize_t *end; OUT: Opposite coordinate of bounding box + H5S_hyper_span_info_t * H5S__hyper_copy_span_helper(spans) + H5S_hyper_span_info_t *spans; IN: Span tree to copy RETURNS - Non-negative on success, negative on failure + Pointer to the copied span tree on success, NULL on failure DESCRIPTION - Retrieves the bounding box containing the current selection and places - it into the user's buffers. The start and end buffers must be large - enough to hold the dataspace rank number of coordinates. The bounding box - exactly contains the selection, ie. if a 2-D element selection is currently - defined with the following points: (4,5), (6,8) (10,7), the bounding box - with be (4, 5), (10, 8). - The bounding box calculations _does_ include the current offset of the - selection within the dataspace extent. + Copy a hyperslab span tree, using reference counting as appropriate. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) +static H5S_hyper_span_info_t * +H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans) { - unsigned rank; /* Dataspace rank */ - unsigned i; /* index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5S_hyper_span_t *span; /* Hyperslab span */ + H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ + H5S_hyper_span_t *prev_span; /* Previous hyperslab span */ + H5S_hyper_span_info_t *new_down; /* New down span tree */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC - /* Sanity check */ - HDassert(space); - HDassert(start); - HDassert(end); + /* Sanity checks */ + HDassert(spans); + HDassert(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)); - /* Set the start and end arrays up */ - rank = space->extent.rank; - for(i = 0; i < rank; i++) { - start[i] = HSIZET_MAX; - end[i] = 0; - } /* end for */ + /* Check if the span tree was already copied */ + if(spans->scratch != NULL) { + /* Just return the value of the already copied span tree */ + ret_value = spans->scratch; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ + /* Increment the reference count of the span tree */ + ret_value->count++; + } /* end if */ + else { + /* Allocate a new span_info node */ + if(NULL == (ret_value = H5FL_CALLOC(H5S_hyper_span_info_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info") - /* Check each dimension */ - for(i = 0; i < rank; i++) { - /* Check for offset moving selection negative */ - if((space->select.offset[i] + (hssize_t)diminfo[i].start) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + /* Copy the span_info information */ + ret_value->count = 1; - /* Compute the smallest location in this dimension */ - start[i] = diminfo[i].start + (hsize_t)space->select.offset[i]; + /* Set the scratch pointer in the node being copied to the newly allocated node */ + spans->scratch = ret_value; - /* Compute the largest location in this dimension */ - if((int)i == space->select.sel_info.hslab->unlim_dim) - end[i] = H5S_UNLIMITED; + /* Copy over the nodes in the span list */ + span = spans->head; + prev_span = NULL; + while(span != NULL) { + /* Allocate a new node */ + if(NULL == (new_span = H5S__hyper_new_span(span->low, span->high, NULL, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + + /* Append to list of spans */ + if(NULL == prev_span) + ret_value->head = new_span; else - end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i]; - } /* end for */ - } /* end if */ - else { - /* Call the recursive routine to get the bounds for the span tree */ - ret_value = H5S_hyper_bounds_helper(space->select.sel_info.hslab->span_lst, space->select.offset, (hsize_t)0, start, end); - } /* end if */ + prev_span->next = new_span; + + /* Copy the pstride */ + new_span->pstride = span->pstride; + + /* Recurse to copy the 'down' spans, if there are any */ + if(span->down != NULL) { + if(NULL == (new_down = H5S__hyper_copy_span_helper(span->down))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab spans") + new_span->down = new_down; + } /* end if */ + + /* Update the previous (new) span */ + prev_span = new_span; + + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_bounds() */ +} /* end H5S__hyper_copy_span_helper() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_offset + H5S__hyper_copy_span PURPOSE - Gets the linear offset of the first element for the selection. + Copy a hyperslab span tree USAGE - herr_t H5S__hyper_offset(space, offset) - const H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *offset; OUT: Linear offset of first element in selection + H5S_hyper_span_info_t * H5S__hyper_copy_span(span_info) + H5S_hyper_span_info_t *span_info; IN: Span tree to copy RETURNS Non-negative on success, negative on failure DESCRIPTION - Retrieves the linear offset (in "units" of elements) of the first element - selected within the dataspace. + Copy a hyperslab span tree, using reference counting as appropriate. + (Which means that just the nodes in the top span tree are duplicated and + the reference counts of their 'down spans' are just incremented) GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Calling this function on a "none" selection returns fail. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_offset(const H5S_t *space, hsize_t *offset) +static H5S_hyper_span_info_t * +H5S__hyper_copy_span(H5S_hyper_span_info_t *spans) { - const hssize_t *sel_offset; /* Pointer to the selection's offset */ - const hsize_t *dim_size; /* Pointer to a dataspace's extent */ - hsize_t accum; /* Accumulator for dimension sizes */ - unsigned rank; /* Dataspace rank */ - int i; /* index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC - HDassert(space && space->extent.rank>0); - HDassert(offset); - - /* Start at linear offset 0 */ - *offset = 0; - - /* Set up pointers to arrays of values */ - rank = space->extent.rank; - sel_offset = space->select.offset; - dim_size = space->extent.size; - - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */ - - /* Loop through starting coordinates, calculating the linear offset */ - accum = 1; - for(i = (int)(rank - 1); i >= 0; i--) { - hssize_t hyp_offset = (hssize_t)diminfo[i].start + sel_offset[i]; /* Hyperslab's offset in this dimension */ - - /* Check for offset moving selection out of the dataspace */ - if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - - /* Add the hyperslab's offset in this dimension to the total linear offset */ - *offset += (hsize_t)(hyp_offset * (hssize_t)accum); - - /* Increase the accumulator */ - accum *= dim_size[i]; - } /* end for */ - } /* end if */ - else { - const H5S_hyper_span_t *span; /* Hyperslab span node */ - hsize_t dim_accum[H5S_MAX_RANK]; /* Accumulators, for each dimension */ - - /* Calculate the accumulator for each dimension */ - accum = 1; - for(i = (int)(rank - 1); i >= 0; i--) { - /* Set the accumulator for this dimension */ - dim_accum[i] = accum; - - /* Increase the accumulator */ - accum *= dim_size[i]; - } /* end for */ - - /* Get information for the first span, in the slowest changing dimension */ - span = space->select.sel_info.hslab->span_lst->head; - - /* Work down the spans, computing the linear offset */ - i = 0; - while(span) { - hssize_t hyp_offset = (hssize_t)span->low + sel_offset[i]; /* Hyperslab's offset in this dimension */ - - /* Check for offset moving selection out of the dataspace */ - if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + /* Sanity check */ + HDassert(spans); - /* Add the hyperslab's offset in this dimension to the total linear offset */ - *offset += (hsize_t)(hyp_offset * (hssize_t)dim_accum[i]); + /* Copy the hyperslab span tree */ + if(NULL == (ret_value = H5S__hyper_copy_span_helper(spans))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") - /* Advance to first span in "down" dimension */ - if(span->down) { - HDassert(span->down->head); - span = span->down->head; - } /* end if */ - else - span = NULL; - i++; - } /* end while */ - } /* end else */ + /* Reset the scratch pointers for the next routine which needs them */ + H5S__hyper_span_scratch(spans); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_offset() */ +} /* end H5S__hyper_copy_span() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_unlim_dim + H5S__hyper_cmp_spans PURPOSE - Return unlimited dimension of selection, or -1 if none + Check if two hyperslab span trees are the same USAGE - int H5S__hyper_unlim_dim(space) - H5S_t *space; IN: Dataspace pointer to check + hbool_t H5S__hyper_cmp_spans(span1, span2) + H5S_hyper_span_info_t *span_info1; IN: First span tree to compare + H5S_hyper_span_info_t *span_info2; IN: Second span tree to compare RETURNS - Unlimited dimension of selection, or -1 if none (never fails). + TRUE (1) or FALSE (0) on success, can't fail DESCRIPTION - Returns the index of the unlimited dimension of the selection, or -1 - if the selection has no unlimited dimension. + Compare two hyperslab span trees to determine if they refer to the same + selection. If span1 & span2 are both NULL, that counts as equal. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static int -H5S__hyper_unlim_dim(const H5S_t *space) +static H5_ATTR_PURE hbool_t +H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, + const H5S_hyper_span_info_t *span_info2) { - FUNC_ENTER_STATIC_NOERR + hbool_t ret_value = FALSE; /* Return value */ - FUNC_LEAVE_NOAPI(space->select.sel_info.hslab->unlim_dim); -} /* end H5S__hyper_unlim_dim() */ + FUNC_ENTER_STATIC_NOERR - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_num_elem_non_unlim - PURPOSE - Return number of elements in the non-unlimited dimensions + /* Check for redundant comparison (or both spans being NULL) */ + if(span_info1 == span_info2) + ret_value = TRUE; + else { + /* Check for one span being NULL */ + if(span_info1 == NULL || span_info2 == NULL) + ret_value = FALSE; + else { + const H5S_hyper_span_t *span1; + const H5S_hyper_span_t *span2; + + /* Get the pointers to the actual lists of spans */ + span1 = span_info1->head; + span2 = span_info2->head; + + /* Sanity checking */ + HDassert(span1); + HDassert(span2); + + /* infinite loop which must be broken out of */ + while(1) { + /* Check for both spans being NULL */ + if(span1 == NULL && span2 == NULL) { + ret_value = TRUE; + break; + } /* end if */ + else { + /* Check for one span being NULL */ + if(span1 == NULL || span2 == NULL) { + ret_value = FALSE; + break; + } /* end if */ + else { + /* Check if the actual low & high span information is the same */ + if(span1->low != span2->low || span1->high != span2->high) { + ret_value = FALSE; + break; + } /* end if */ + else { + if(span1->down != NULL || span2 != NULL) { + if(!H5S__hyper_cmp_spans(span1->down, span2->down)) { + ret_value = FALSE; + break; + } /* end if */ + else { + /* Keep going... */ + } /* end else */ + } /* end if */ + else { + /* Keep going... */ + } /* end else */ + } /* end else */ + } /* end else */ + } /* end else */ + + /* Advance to the next nodes in the span list */ + span1 = span1->next; + span2 = span2->next; + } /* end while */ + } /* end else */ + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_cmp_spans() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_free_span_info + PURPOSE + Free a hyperslab span info node USAGE - herr_t H5S__hyper_num_elem_non_unlim(space,num_elem_non_unlim) - H5S_t *space; IN: Dataspace pointer to check - hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions + herr_t H5S__hyper_free_span_info(span_info) + H5S_hyper_span_info_t *span_info; IN: Span info node to free RETURNS - Non-negative on success/Negative on failure + Non-negative on success, negative on failure DESCRIPTION - Returns the number of elements in a slice through the non-unlimited - dimensions of the selection. Fails if the selection has no unlimited - dimension. + Free a hyperslab span info node, along with all the span nodes and the + 'down spans' from the nodes, if reducing their reference count to zero + indicates it is appropriate to do so. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim) +H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) { - herr_t ret_value = SUCCEED; + H5S_hyper_span_t *span, *next_span; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - /* Sanity check */ - HDassert(space); - HDassert(num_elem_non_unlim); + HDassert(span_info); - /* Get number of elements in the non-unlimited dimensions */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - *num_elem_non_unlim = space->select.sel_info.hslab->num_elem_non_unlim; - else - HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection has no unlimited dimension") + /* Decrement the span tree's reference count */ + span_info->count--; + + /* Free the span tree if the reference count drops to zero */ + if(span_info->count == 0) { + + /* Work through the list of spans pointed to by this 'info' node */ + span = span_info->head; + while(span != NULL) { + next_span = span->next; + if(H5S__hyper_free_span(span) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span") + span = next_span; + } /* end while */ + + /* Free this span info */ + span_info = H5FL_FREE(H5S_hyper_span_info_t, span_info); + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_num_elem_non_unlim() */ +} /* end H5S__hyper_free_span_info() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_is_contiguous + H5S__hyper_free_span PURPOSE - Check if a hyperslab selection is contiguous within the dataspace extent. + Free a hyperslab span node USAGE - htri_t H5S__hyper_is_contiguous(space) - H5S_t *space; IN: Dataspace pointer to check + herr_t H5S__hyper_free_span(span) + H5S_hyper_span_t *span; IN: Span node to free RETURNS - TRUE/FALSE/FAIL + Non-negative on success, negative on failure DESCRIPTION - Checks to see if the current selection in the dataspace is contiguous. - This is primarily used for reading the entire selection in one swoop. + Free a hyperslab span node, along with the 'down spans' from the node, + if reducing their reference count to zero indicates it is appropriate to + do so. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5_ATTR_PURE htri_t -H5S__hyper_is_contiguous(const H5S_t *space) +static herr_t +H5S__hyper_free_span(H5S_hyper_span_t *span) { - hbool_t small_contiguous, /* Flag for small contiguous block */ - large_contiguous; /* Flag for large contiguous block */ - unsigned u; /* index variable */ - htri_t ret_value = FALSE; /* Return value */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC - HDassert(space); + HDassert(span); - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ + /* Decrement the reference count of the 'down spans', freeing them if appropriate */ + if(span->down != NULL) + if(H5S__hyper_free_span_info(span->down) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span tree") - /* - * For a regular hyperslab to be contiguous, it must have only one - * block (i.e. count==1 in all dimensions) and the block size must be - * the same as the dataspace extent's in all but the slowest changing - * dimension. (dubbed "large contiguous" block) - * - * OR - * - * The selection must have only one block (i.e. count==1) in all - * dimensions and the block size must be 1 in all but the fastest - * changing dimension. (dubbed "small contiguous" block) - */ + /* Free this span */ + span = H5FL_FREE(H5S_hyper_span_t, span); - /* Initialize flags */ - large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */ - small_contiguous = FALSE; /* assume false initially */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_free_span() */ - /* Check for a "large contigous" block */ - for(u = 0; u < space->extent.rank; u++) { - if(diminfo[u].count > 1) { - large_contiguous = FALSE; - break; - } /* end if */ - if(u > 0 && diminfo[u].block != space->extent.size[u]) { - large_contiguous = FALSE; - break; - } /* end if */ - } /* end for */ + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_copy + PURPOSE + Copy a selection from one dataspace to another + USAGE + herr_t H5S__hyper_copy(dst, src, share_selection) + H5S_t *dst; OUT: Pointer to the destination dataspace + H5S_t *src; IN: Pointer to the source dataspace + hbool_t; IN: Whether to share the selection between the dataspaces + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Copies all the hyperslab selection information from the source + dataspace to the destination dataspace. - /* If we didn't find a large contiguous block, check for a small one */ - if(!large_contiguous) { - small_contiguous = TRUE; - for(u = 0; u < space->extent.rank; u++) { - if(diminfo[u].count > 1) { - small_contiguous = FALSE; - break; - } /* end if */ - if(u < (space->extent.rank - 1) && diminfo[u].block != 1) { - small_contiguous = FALSE; - break; - } /* end if */ - } /* end for */ - } /* end if */ + If the SHARE_SELECTION flag is set, then the selection can be shared + between the source and destination dataspaces. (This should only occur in + situations where the destination dataspace will immediately change to a new + selection) + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) +{ + H5S_hyper_sel_t *dst_hslab; /* Pointer to destination hyperslab info */ + const H5S_hyper_sel_t *src_hslab; /* Pointer to source hyperslab info */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Indicate true if it's either a large or small contiguous block */ - if(large_contiguous || small_contiguous) - ret_value = TRUE; - } /* end if */ - else { - H5S_hyper_span_info_t *spans; /* Hyperslab span info node */ - H5S_hyper_span_t *span; /* Hyperslab span node */ + FUNC_ENTER_STATIC - /* - * For a hyperslab to be contiguous, it must have only one block and - * either it's size must be the same as the dataspace extent's in all - * but the slowest changing dimension - * OR - * block size must be 1 in all but the fastest changing dimension. - */ - /* Initialize flags */ - large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */ - small_contiguous = FALSE; /* assume false initially */ + /* Sanity check */ + HDassert(src); + HDassert(dst); - /* Get information for slowest changing information */ - spans = space->select.sel_info.hslab->span_lst; - span = spans->head; + /* Allocate space for the hyperslab selection information */ + if(NULL == (dst->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") - /* If there are multiple spans in the slowest changing dimension, the selection isn't contiguous */ - if(span->next != NULL) - large_contiguous = FALSE; - else { - /* Now check the rest of the dimensions */ - if(span->down != NULL) { - u = 1; /* Current dimension working on */ - - /* Get the span information for the next fastest dimension */ - spans = span->down; - - /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ - while(spans != NULL) { - span = spans->head; - - /* Check that this is the only span and it spans the entire dimension */ - if(span->next != NULL) { - large_contiguous = FALSE; - break; - } /* end if */ - else { - /* If this span doesn't cover the entire dimension, then this selection isn't contiguous */ - if(((span->high - span->low) + 1) != space->extent.size[u]) { - large_contiguous = FALSE; - break; - } /* end if */ - else { - /* Walk down to the next span */ - spans = span->down; - - /* Increment dimension */ - u++; - } /* end else */ - } /* end else */ - } /* end while */ - } /* end if */ - } /* end else */ - - /* If we didn't find a large contiguous block, check for a small one */ - if(!large_contiguous) { - small_contiguous = TRUE; - - /* Get information for slowest changing information */ - spans = space->select.sel_info.hslab->span_lst; - span = spans->head; - - /* Current dimension working on */ - u = 0; + /* Set temporary pointers */ + dst_hslab = dst->select.sel_info.hslab; + src_hslab = src->select.sel_info.hslab; - /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ - while(spans != NULL) { - span = spans->head; + /* Copy the hyperslab information */ + dst_hslab->diminfo_valid = src_hslab->diminfo_valid; + if(src_hslab->diminfo_valid) { + size_t u; /* Local index variable */ - /* Check that this is the only span and it spans the entire dimension */ - if(span->next != NULL) { - small_contiguous = FALSE; - break; - } /* end if */ - else { - /* If this span doesn't cover the entire dimension, then this selection isn't contiguous */ - if(u < (space->extent.rank - 1) && ((span->high-span->low) + 1) != 1) { - small_contiguous = FALSE; - break; - } /* end if */ - else { - /* Walk down to the next span */ - spans = span->down; + for(u=0; uextent.rank; u++) { + dst_hslab->opt_diminfo[u]=src_hslab->opt_diminfo[u]; + dst_hslab->app_diminfo[u]=src_hslab->app_diminfo[u]; + } /* end for */ + } /* end if */ + dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst; - /* Increment dimension */ - u++; - } /* end else */ - } /* end else */ - } /* end while */ + /* Check if there is hyperslab span information to copy */ + /* (Regular hyperslab information is copied with the selection structure) */ + if(src->select.sel_info.hslab->span_lst != NULL) { + if(share_selection) { + /* Share the source's span tree by incrementing the reference count on it */ + dst->select.sel_info.hslab->span_lst = src->select.sel_info.hslab->span_lst; + dst->select.sel_info.hslab->span_lst->count++; } /* end if */ + else + /* Copy the hyperslab span information */ + dst->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(src->select.sel_info.hslab->span_lst); + } /* end if */ + else + dst->select.sel_info.hslab->span_lst = NULL; - /* Indicate true if it's either a large or small contiguous block */ - if(large_contiguous || small_contiguous) - ret_value = TRUE; - } /* end else */ + /* Copy the unlimited dimension info */ + dst_hslab->unlim_dim = src_hslab->unlim_dim; + dst_hslab->num_elem_non_unlim = src_hslab->num_elem_non_unlim; +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_contiguous() */ +} /* end H5S__hyper_copy() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_is_single + H5S__hyper_is_valid_helper PURPOSE - Check if a hyperslab selection is a single block within the dataspace extent. + Check whether the selection fits within the extent, with the current + offset defined. USAGE - htri_t H5S__hyper_is_single(space) - H5S_t *space; IN: Dataspace pointer to check + hbool_t H5S__hyper_is_valid_helper(spans, offset, rank); + const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree + const hssize_t *offset; IN: Pointer to offset array + const hsize_t *size; IN: Pointer to size array + hsize_t rank; IN: Current rank looking at RETURNS - TRUE/FALSE/FAIL + TRUE if the selection fits within the extent, FALSE if it does not DESCRIPTION - Checks to see if the current selection in the dataspace is a single block. - This is primarily used for reading the entire selection in one swoop. + Determines if the current selection at the current offset fits within the + extent for the dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5_ATTR_PURE htri_t -H5S__hyper_is_single(const H5S_t *space) +static hbool_t +H5S__hyper_is_valid_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, + const hsize_t *size) { - htri_t ret_value = TRUE; /* return value */ + H5S_hyper_span_t *curr; /* Hyperslab information nodes */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC_NOERR - HDassert(space); - - /* Check for a "single" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - unsigned u; /* index variable */ + HDassert(spans); + HDassert(offset); + HDassert(size); - /* - * For a regular hyperslab to be single, it must have only one - * block (i.e. count==1 in all dimensions) - */ + /* Check each point to determine whether selection + offset is within extent */ + curr = spans->head; + while(curr != NULL) { + /* Check if an offset has been defined */ + /* Bounds check the selected point + offset against the extent */ + if((((hssize_t)curr->low + *offset) >= (hssize_t)*size) + || (((hssize_t)curr->low + *offset) < 0) + || (((hssize_t)curr->high + *offset) >= (hssize_t)*size) + || (((hssize_t)curr->high + *offset) < 0)) + HGOTO_DONE(FALSE) - /* Check for a single block */ - for(u = 0; u < space->extent.rank; u++) - if(space->select.sel_info.hslab->opt_diminfo[u].count > 1) + /* Recurse if this node has down spans */ + if(curr->down != NULL) + if(!H5S__hyper_is_valid_helper(curr->down, offset + 1, size + 1)) HGOTO_DONE(FALSE) - } /* end if */ - else { - H5S_hyper_span_info_t *spans; /* Hyperslab span info node */ - - /* - * For a region to be single, it must have only one block - */ - /* Get information for slowest changing information */ - spans = space->select.sel_info.hslab->span_lst; - - /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ - while(spans != NULL) { - H5S_hyper_span_t *span; /* Hyperslab span node */ - - span = spans->head; - /* Check that this is the only span and it spans the entire dimension */ - if(span->next != NULL) - HGOTO_DONE(FALSE) - else - /* Walk down to the next span */ - spans = span->down; - } /* end while */ - } /* end else */ + /* Advance to next node */ + curr = curr->next; + } /* end while */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_single() */ +} /* end H5S__hyper_is_valid_helper() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_is_regular + H5S__hyper_is_valid PURPOSE - Check if a hyperslab selection is "regular" + Check whether the selection fits within the extent, with the current + offset defined. USAGE - htri_t H5S__hyper_is_regular(space) - const H5S_t *space; IN: Dataspace pointer to check + htri_t H5S__hyper_is_valid(space); + H5S_t *space; IN: Dataspace pointer to query RETURNS - TRUE/FALSE/FAIL + TRUE if the selection fits within the extent, FALSE if it does not and + Negative on an error. DESCRIPTION - Checks to see if the current selection in a dataspace is the a regular - pattern. - This is primarily used for reading the entire selection in one swoop. + Determines if the current selection at the current offset fits within the + extent for the dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Doesn't check for "regular" hyperslab selections composed of spans EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static htri_t -H5S__hyper_is_regular(const H5S_t *space) +H5S__hyper_is_valid(const H5S_t *space) { - htri_t ret_value = FAIL; /* return value */ + htri_t ret_value = TRUE; /* return value */ FUNC_ENTER_STATIC_NOERR - /* Check args */ HDassert(space); - /* Only simple check for regular hyperslabs for now... */ - if(space->select.sel_info.hslab->diminfo_valid) - ret_value = TRUE; + /* Check for unlimited selection */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_DONE(FALSE) + + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ + hssize_t end; /* The high bound of a region in a dimension */ + unsigned u; /* Counter */ + + /* Check each dimension */ + for(u = 0; u < space->extent.rank; u++) { + /* if block or count is zero, then can skip the test since */ + /* no data point is chosen */ + if(diminfo[u].count && diminfo[u].block) { + /* Bounds check the start point in this dimension */ + if(((hssize_t)diminfo[u].start + space->select.offset[u]) < 0 || + ((hssize_t)diminfo[u].start + space->select.offset[u]) >= (hssize_t)space->extent.size[u]) + HGOTO_DONE(FALSE) + + /* Compute the largest location in this dimension */ + end = (hssize_t)(diminfo[u].start + diminfo[u].stride * (diminfo[u].count - 1) + (diminfo[u].block - 1)) + space->select.offset[u]; + + /* Bounds check the end point in this dimension */ + if(end < 0 || end >= (hssize_t)space->extent.size[u]) + HGOTO_DONE(FALSE) + } /* end if */ + } /* end for */ + } /* end if */ else - ret_value = FALSE; + /* Call the recursive routine to validate the span tree */ + ret_value = H5S__hyper_is_valid_helper(space->select.sel_info.hslab->span_lst, space->select.offset, space->extent.size); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_regular() */ +} /* end H5S__hyper_is_valid() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_release + H5S__hyper_span_nblocks PURPOSE - Release hyperslab selection information for a dataspace + Count the number of blocks in a span tree USAGE - herr_t H5S__hyper_release(space) - H5S_t *space; IN: Pointer to dataspace - RETURNS - Non-negative on success/Negative on failure + hsize_t H5S__hyper_span_nblocks(spans) + const H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count elements of + RETURNS + Number of blocks in span tree on success; negative on failure DESCRIPTION - Releases all hyperslab selection information for a dataspace + Counts the number of blocks described by the spans in a span tree. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG - * Robb Matzke, 1998-08-25 - * The fields which are freed are set to NULL to prevent them from being - * freed again later. This fixes some allocation problems where - * changing the hyperslab selection of one dataspace causes a core dump - * when closing some other dataspace. --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_release(H5S_t *space) +static hsize_t +H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans) { - herr_t ret_value = SUCCEED; - - FUNC_ENTER_STATIC + hsize_t ret_value = 0; /* Return value */ - /* Check args */ - HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); + FUNC_ENTER_STATIC_NOERR - /* Reset the number of points selected */ - space->select.num_elem = 0; + /* Count the number of elements in the span tree */ + if(spans != NULL) { + H5S_hyper_span_t *span; /* Hyperslab span */ - /* Release irregular hyperslab information */ - if(space->select.sel_info.hslab) { - if(space->select.sel_info.hslab->span_lst != NULL) - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + span = spans->head; + while(span != NULL) { + /* If there are down spans, add the total down span blocks */ + if(span->down != NULL) + ret_value += H5S__hyper_span_nblocks(span->down); + /* If there are no down spans, just count the block in this span */ + else + ret_value++; - /* Release space for the hyperslab selection information */ - space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); - } /* end if */ + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end else */ -done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_release() */ +} /* end H5S__hyper_span_nblocks() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_recover_span + H5S__get_select_hyper_nblocks PURPOSE - Recover a generated span, if appropriate + Get the number of hyperslab blocks in current hyperslab selection USAGE - herr_t H5S__hyper_recover_span(recover, curr_span, next_span) - unsigned *recover; IN/OUT: Pointer recover flag - H5S_hyper_span_t **curr_span; IN/OUT: Pointer to current span in list - H5S_hyper_span_t *next_span; IN: Pointer to next span + hsize_t H5S__get_select_hyper_nblocks(space) + H5S_t *space; IN: Dataspace ptr of selection to query RETURNS - Non-negative on success, negative on failure + The number of hyperslab blocks in selection on success, negative on failure DESCRIPTION - Check if the current span needs to be recovered and free it if so. - Set the current span to the next span in any case. + Returns the number of hyperslab blocks in current selection for dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_recover_span(hbool_t *recover, H5S_hyper_span_t **curr_span, H5S_hyper_span_t *next_span) +static hsize_t +H5S__get_select_hyper_nblocks(const H5S_t *space) { + hsize_t ret_value = 0; /* Return value */ + FUNC_ENTER_STATIC_NOERR - HDassert(recover); - HDassert(curr_span); + HDassert(space); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); - /* Check if the span should be recovered */ - if(*recover) { - H5S__hyper_free_span(*curr_span); - *recover = FALSE; - } /* end if */ + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + unsigned u; /* Local index variable */ - /* Set the current span to next span */ - *curr_span = next_span; + /* Check each dimension */ + for(ret_value = 1, u = 0; u < space->extent.rank; u++) + ret_value *= space->select.sel_info.hslab->app_diminfo[u].count; + } /* end if */ + else + ret_value = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__hyper_recover_span() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__get_select_hyper_nblocks() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_coord_to_span + H5Sget_select_hyper_nblocks PURPOSE - Create a span tree for a single element + Get the number of hyperslab blocks in current hyperslab selection USAGE - H5S_hyper_span_t *H5S__hyper_coord_to_span(rank, coords) - unsigned rank; IN: Number of dimensions of coordinate - hsize_t *coords; IN: Location of element + hssize_t H5Sget_select_hyper_nblocks(dsid) + hid_t dsid; IN: Dataspace ID of selection to query RETURNS - Non-negative on success, negative on failure + The number of hyperslab blocks in selection on success, negative on failure DESCRIPTION - Create a span tree for a single element + Returns the number of hyperslab blocks in current selection for dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5S_hyper_span_t * -H5S__hyper_coord_to_span(unsigned rank, const hsize_t *coords) +hssize_t +H5Sget_select_hyper_nblocks(hid_t spaceid) { - H5S_hyper_span_t *new_span; /* Pointer to new span tree for coordinate */ - H5S_hyper_span_info_t *down = NULL; /* Pointer to new span tree for next level down */ - H5S_hyper_span_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_STATIC - - HDassert(rank > 0); - HDassert(coords); - - /* Search for location to insert new element in tree */ - if(rank > 1) { - /* Allocate a span info node */ - if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - + H5S_t *space; /* Dataspace to modify selection of */ + hssize_t ret_value; /* return value */ - /* Build span tree for coordinates below this one */ - if(NULL == (down->head = H5S__hyper_coord_to_span(rank - 1, &coords[1]))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - } /* end if */ + FUNC_ENTER_API(FAIL) + H5TRACE1("Hs", "i", spaceid); - /* Build span for this coordinate */ - if(NULL == (new_span = H5S__hyper_new_span(coords[0], coords[0], down, NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + /* Check args */ + if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get number of blocks for unlimited selection") - /* Set return value */ - ret_value = new_span; + ret_value = (hssize_t)H5S__get_select_hyper_nblocks(space); done: - if(ret_value == NULL && down != NULL) - H5S__hyper_free_span_info(down); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_coord_to_span() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Sget_select_hyper_nblocks() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_add_span_element_helper + H5S__hyper_serial_size PURPOSE - Add a single element to a span tree + Determine the number of bytes needed to store the serialized hyperslab + selection information. USAGE - herr_t H5S_hyper_add_span_element_helper(prev_span, span_tree, rank, coords) - H5S_hyper_span_info_t *span_tree; IN/OUT: Pointer to span tree to append to - unsigned rank; IN: Number of dimensions of coordinates - hsize_t *coords; IN: Location of element to add to span tree + hssize_t H5S__hyper_serial_size(space) + H5S_t *space; IN: Dataspace pointer to query RETURNS - Non-negative on success, negative on failure + The number of bytes required on success, negative on an error. DESCRIPTION - Add a single element to an existing span tree. + Determines the number of bytes required to serialize the current hyperslab + selection information for storage on disk. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Assumes that the element is not already covered by the span tree EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, - unsigned rank, const hsize_t *coords) +static hssize_t +H5S__hyper_serial_size(const H5S_t *space) { - H5S_hyper_span_info_t *tspan_info; /* Temporary pointer to span info */ - H5S_hyper_span_info_t *prev_span_info; /* Pointer to span info for level above current position */ - H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */ - H5S_hyper_span_t *tmp2_span; /* Another temporary pointer to a span */ - H5S_hyper_span_t *new_span; /* New span created for element */ - herr_t ret_value = SUCCEED; /* Return value */ + hsize_t block_count; /* block counter for regular hyperslabs */ + unsigned u; /* Counter */ + hssize_t ret_value = -1; /* return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR - /* Sanity check */ - HDassert(span_tree); - HDassert(rank > 0); - HDassert(coords); + HDassert(space); - /* Get pointer to last span in span tree */ - tspan_info=span_tree; - if(span_tree->scratch) - tmp_span=(H5S_hyper_span_t *)span_tree->scratch; + /* Check for version (right now, an unlimited dimension is the only thing + * that would bump the version) */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + /* Version 2 */ + /* Size required is always: + * + + + + * + + + * (4 (start/stride/count/block) * * ) = + * 17 + (4 * rank * 8) bytes + */ + ret_value = (hssize_t)17 + ((hssize_t)4 * (hssize_t)space->extent.rank + * (hssize_t)8); else { - tmp_span=span_tree->head; - HDassert(tmp_span); - span_tree->scratch=(H5S_hyper_span_info_t *)tmp_span; - } /* end else */ + /* Version 1 */ + /* Basic number of bytes required to serialize hyperslab selection: + * + + + + * + + <# of blocks (4 bytes)> + * = 24 bytes + */ + ret_value = 24; - /* Find last span tree which includes a portion of the coordinate */ - prev_span_info=NULL; - while(coords[0]>=tmp_span->low && coords[0]<=tmp_span->high) { - /* Move rank & coordinate offset down a dimension */ - rank--; - coords++; + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + /* Check each dimension */ + for(block_count = 1, u = 0; u < space->extent.rank; u++) + block_count *= space->select.sel_info.hslab->opt_diminfo[u].count; + } /* end if */ + else + /* Spin through hyperslab spans, adding 8 * rank bytes for each block */ + block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); - /* Remember the span tree we are descending into */ - prev_span_info=tspan_info; - tspan_info=tmp_span->down; + H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, hssize_t); + ret_value += (hssize_t)(8 * block_count * space->extent.rank); + } /* end else */ - /* Get the last span in this span's 'down' tree */ - if(tspan_info->scratch) - tmp_span=(H5S_hyper_span_t *)tspan_info->scratch; - else { - tmp_span=tspan_info->head; - HDassert(tmp_span); - tspan_info->scratch=(H5S_hyper_span_info_t *)tmp_span; - } /* end else */ - } /* end while */ - - /* Check if we made it all the way to the bottom span in the tree */ - if(rank>1) { - /* Before we create another span at this level in the tree, check if - * the last span's "down tree" was equal to any other spans in this - * list of spans in the span tree. - * - * If so, release last span information and make last span merge into - * previous span (if possible), or at least share their "down tree" - * information. - */ - tmp2_span=tspan_info->head; - while(tmp2_span!=tmp_span) { - if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { - /* Check for merging into previous span */ - if(tmp2_span->high+1==tmp_span->low) { - /* Release last span created */ - H5S__hyper_free_span(tmp_span); - - /* Increase size of previous span */ - tmp2_span->high++; - tmp2_span->nelem++; - - /* Reset the 'tmp_span' for the rest of this block's algorithm */ - tmp_span=tmp2_span; - } /* end if */ - /* Span is disjoint, but has the same "down tree" selection */ - else { - /* Release "down tree" information */ - H5S__hyper_free_span_info(tmp_span->down); - - /* Point at earlier span's "down tree" */ - tmp_span->down=tmp2_span->down; - - /* Increment reference count on shared "down tree" */ - tmp_span->down->count++; - } /* end else */ - - /* Found span to merge into, break out now */ - break; - } /* end if */ - - /* Advance to next span to check */ - tmp2_span=tmp2_span->next; - } /* end while */ - - /* Make span tree for current coordinates */ - if(NULL == (new_span = H5S__hyper_coord_to_span(rank, coords))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - - /* Add new span tree as span */ - HDassert(tmp_span); - tmp_span->next=new_span; - - /* Make scratch pointer point to last span in list */ - HDassert(tspan_info); - tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; - - /* Set the proper 'pstride' for new span */ - new_span->pstride=new_span->low-tmp_span->low; - } /* end if */ - else { - /* Does new node adjoin existing node? */ - if(tmp_span->high+1==coords[0]) { - tmp_span->high++; - tmp_span->nelem++; - - /* Check if this span tree should now be merged with a level higher in the tree */ - if(prev_span_info!=NULL) { - /* Before we create another span at this level in the tree, check if - * the last span's "down tree" was equal to any other spans in this - * list of spans in the span tree. - * - * If so, release last span information and make last span merge into - * previous span (if possible), or at least share their "down tree" - * information. - */ - tmp2_span=prev_span_info->head; - tmp_span=(H5S_hyper_span_t *)prev_span_info->scratch; - while(tmp2_span!=tmp_span) { - if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { - /* Check for merging into previous span */ - if(tmp2_span->high+1==tmp_span->low) { - /* Release last span created */ - H5S__hyper_free_span(tmp_span); - - /* Increase size of previous span */ - tmp2_span->high++; - tmp2_span->nelem++; - - /* Update pointers */ - tmp2_span->next=NULL; - prev_span_info->scratch=(H5S_hyper_span_info_t *)tmp2_span; - } /* end if */ - /* Span is disjoint, but has the same "down tree" selection */ - else { - /* Release "down tree" information */ - H5S__hyper_free_span_info(tmp_span->down); - - /* Point at earlier span's "down tree" */ - tmp_span->down=tmp2_span->down; - - /* Increment reference count on shared "down tree" */ - tmp_span->down->count++; - } /* end else */ - - /* Found span to merge into, break out now */ - break; - } /* end if */ - - /* Advance to next span to check */ - tmp2_span=tmp2_span->next; - } /* end while */ - } /* end if */ - } /* end if */ - else { - if(NULL == (new_span = H5S__hyper_new_span(coords[0], coords[0], NULL, NULL))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - - /* Add new span tree as span */ - HDassert(tmp_span); - tmp_span->next=new_span; - - /* Make scratch pointer point to last span in list */ - tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; - - /* Set the proper 'pstride' for new span */ - new_span->pstride = new_span->low - tmp_span->low; - } /* end else */ - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_add_span_element_helper() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_serial_size() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_add_span_element + H5S__hyper_serialize_helper PURPOSE - Add a single element to a span tree + Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_hyper_add_span_element(space, span_tree, rank, coords) - H5S_t *space; IN/OUT: Pointer to dataspace to add coordinate to - unsigned rank; IN: Number of dimensions of coordinates - hsize_t *coords; IN: Location of element to add to span tree + void H5S__hyper_serialize_helper(spans, start, end, rank, buf) + H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to serialize + hssize_t start[]; IN/OUT: Accumulated start points + hssize_t end[]; IN/OUT: Accumulated end points + hsize_t rank; IN: Current rank looking at + uint8 *buf; OUT: Buffer to put serialized selection into RETURNS - Non-negative on success, negative on failure + None DESCRIPTION - Add a single element to an existing span tree. + Serializes the current element selection into a buffer. (Primarily for + storing on disk). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Assumes that the element is not already in the dataspace's selection EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) +static void +H5S__hyper_serialize_helper(const H5S_hyper_span_info_t *spans, + hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p) { - H5S_hyper_span_info_t *head = NULL; /* Pointer to new head of span tree */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(space); - HDassert(rank > 0); - HDassert(coords); - HDassert(space->extent.rank == rank); + H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ + uint8_t *pp = (*p); /* Local pointer for decoding */ - /* Check if this is the first element in the selection */ - if(NULL == space->select.sel_info.hslab) { - /* Allocate a span info node */ - if(NULL == (head = H5FL_CALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") + FUNC_ENTER_STATIC_NOERR - /* Set the reference count */ - head->count = 1; + /* Sanity checks */ + HDassert(spans); + HDassert(start); + HDassert(end); + HDassert(rank < H5S_MAX_RANK); + HDassert(p && pp); - /* Build span tree for this coordinate */ - if(NULL == (head->head = H5S__hyper_coord_to_span(rank, coords))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab spans for coordinate") + /* Walk through the list of spans, recursing or outputting them */ + curr = spans->head; + while(curr != NULL) { + /* Recurse if this node has down spans */ + if(curr->down != NULL) { + /* Add the starting and ending points for this span to the list */ + start[rank] = curr->low; + end[rank] = curr->high; - /* Allocate selection info */ - if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab selection") + /* Recurse down to the next dimension */ + H5S__hyper_serialize_helper(curr->down, start, end, rank + 1, &pp); + } /* end if */ + else { + hsize_t u; /* Index variable */ - /* Set the selection to the new span tree */ - space->select.sel_info.hslab->span_lst = head; + /* Encode all the previous dimensions starting & ending points */ - /* Set selection type */ - space->select.type = H5S_sel_hyper; + /* Encode previous starting points */ + for(u = 0; u < rank; u++) + UINT32ENCODE(pp, (uint32_t)start[u]); - /* Reset "regular" hyperslab flag */ - space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Encode starting point for this span */ + UINT32ENCODE(pp, (uint32_t)curr->low); - /* Set unlim_dim */ - space->select.sel_info.hslab->unlim_dim = -1; + /* Encode previous ending points */ + for(u = 0; u < rank; u++) + UINT32ENCODE(pp, (uint32_t)end[u]); - /* Set # of elements in selection */ - space->select.num_elem = 1; - } /* end if */ - else { - if(H5S__hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst, rank, coords) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert coordinate into span tree") + /* Encode starting point for this span */ + UINT32ENCODE(pp, (uint32_t)curr->high); + } /* end else */ - /* Increment # of elements in selection */ - space->select.num_elem++; - } /* end else */ + /* Advance to next node */ + curr = curr->next; + } /* end while */ -done: - if(ret_value < 0) - if(head) - H5S__hyper_free_span_info(head); + /* Update encoding pointer */ + *p = pp; - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_add_span_element() */ + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_serialize_helper() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_reset_scratch + H5S__hyper_serialize PURPOSE - Reset the scratch information for span tree + Serialize the current selection into a user-provided buffer. USAGE - herr_t H5S_hyper_reset_scratch(space) - H5S_t *space; IN/OUT: Pointer to dataspace to reset scratch pointers + herr_t H5S_hyper_serialize(space, p) + const H5S_t *space; IN: Dataspace with selection to serialize + uint8_t **p; OUT: Pointer to buffer to put serialized + selection. Will be advanced to end of + serialized selection. RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION - Resets the "scratch" pointers used for various tasks in computing hyperslab - spans. + Serializes the current element selection into a buffer. (Primarily for + storing on disk). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5S_hyper_reset_scratch(H5S_t *space) +static herr_t +H5S__hyper_serialize(const H5S_t *space, uint8_t **p) { - herr_t ret_value = SUCCEED; /* Return value */ + uint8_t *pp; /* Local pointer for decoding */ + uint8_t *lenp; /* Pointer to length location for later storage */ + uint32_t len = 0; /* Number of bytes used */ + uint32_t version; /* Version number */ + uint8_t flags = 0; /* Flags for message */ + hsize_t block_count; /* Block counter for regular hyperslabs */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC_NOERR + /* Sanity checks */ HDassert(space); + HDassert(p); + pp = (*p); + HDassert(pp); - /* Check if there are spans in the span tree */ - if(space->select.sel_info.hslab->span_lst != NULL) - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + /* Calculate version */ + if(space->select.sel_info.hslab->unlim_dim >= 0) { + version = 2; + flags |= H5S_SELECT_FLAG_UNLIM; + } /* end if */ + else + version = 1; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_reset_scratch() */ + /* Store the preamble information */ + UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */ + UINT32ENCODE(pp, version); /* Store the version number */ + if(version >= 2) + *(pp)++ = flags; /* Store the flags */ + else + UINT32ENCODE(pp, (uint32_t)0); /* Store the un-used padding */ + lenp = pp; /* keep the pointer to the length location for later */ + pp += 4; /* skip over space for length */ - -/*-------------------------------------------------------------------------- - NAME - H5S_hyper_convert - PURPOSE - Convert a compatible selection to span tree form - USAGE - herr_t H5S_hyper_convert(space) - H5S_t *space; IN/OUT: Pointer to dataspace to convert - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Converts a compatible selection (currently only "all" selections) to the - span-tree form of a hyperslab selection. (Point and "none" selection aren't - currently supported and hyperslab selection always have the span-tree form - available). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5S_hyper_convert(H5S_t *space) -{ - herr_t ret_value = SUCCEED; /* Return value */ + /* Encode number of dimensions */ + UINT32ENCODE(pp, (uint32_t)space->extent.rank); + len += 4; - FUNC_ENTER_NOAPI(FAIL) + /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ + if(flags & H5S_SELECT_FLAG_UNLIM) { + unsigned i; - HDassert(space); + HDassert(H5S_UNLIMITED == HSIZE_UNDEF); - /* Check the type of selection */ - switch(H5S_GET_SELECT_TYPE(space)) { - case H5S_SEL_ALL: /* All elements selected in dataspace */ - /* Convert current "all" selection to "real" hyperslab selection */ - { - const hsize_t *tmp_start; /* Temporary start information */ - const hsize_t *tmp_stride; /* Temporary stride information */ - const hsize_t *tmp_count; /* Temporary count information */ - const hsize_t *tmp_block; /* Temporary block information */ + /* Iterate over dimensions */ + for(i = 0; i < space->extent.rank; i++) { + /* Encode start/stride/block/count */ + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].start); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].stride); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].count); + UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].block); + } /* end for */ + } /* end if */ + /* Check for a "regular" hyperslab selection */ + else if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ + hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + unsigned ndims; /* Rank of the dataspace */ + unsigned u; /* Local counting variable */ + hbool_t done; /* Whether we are done with the iteration */ - /* Set up temporary information for the dimensions */ - tmp_start = H5S_hyper_zeros_g; - tmp_stride = tmp_count = H5S_hyper_ones_g; - tmp_block = space->extent.size; + /* Set some convenience values */ + ndims = space->extent.rank; + fast_dim = ndims - 1; + diminfo = space->select.sel_info.hslab->opt_diminfo; - /* Convert to hyperslab selection */ - if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't convert selection") - } /* end case */ - break; + /* Check each dimension */ + for(block_count = 1, u = 0; u < ndims; u++) + block_count *= diminfo[u].count; - case H5S_SEL_HYPERSLABS: /* Hyperslab selection */ - break; + /* Encode number of hyperslabs */ + H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); + UINT32ENCODE(pp, (uint32_t)block_count); + len += 4; - case H5S_SEL_NONE: /* No elements selected in dataspace */ - case H5S_SEL_POINTS: /* Point selection */ - case H5S_SEL_ERROR: /* Selection error */ - case H5S_SEL_N: /* Selection count */ - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "can't convert to span tree selection") - } /* end switch */ + /* Now serialize the information for the regular hyperslab */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_convert() */ + /* Build the tables of count sizes as well as the initial offset */ + for(u = 0; u < ndims; u++) { + tmp_count[u] = diminfo[u].count; + offset[u] = diminfo[u].start; + } /* end for */ -#ifdef LATER - -/*-------------------------------------------------------------------------- - NAME - H5S_hyper_intersect_helper - PURPOSE - Helper routine to detect intersections in span trees - USAGE - htri_t H5S_hyper_intersect_helper(spans1, spans2) - H5S_hyper_span_info_t *spans1; IN: First span tree to operate with - H5S_hyper_span_info_t *spans2; IN: Second span tree to operate with - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Quickly detect intersections between two span trees - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static htri_t -H5S_hyper_intersect_helper (H5S_hyper_span_info_t *spans1, H5S_hyper_span_info_t *spans2) -{ - H5S_hyper_span_t *curr1; /* Pointer to current span in 1st span tree */ - H5S_hyper_span_t *curr2; /* Pointer to current span in 2nd span tree */ - htri_t status; /* Status from recursive call */ - htri_t ret_value=FALSE; /* Return value */ + /* We're not done with the iteration */ + done = FALSE; - FUNC_ENTER_NOAPI_NOINIT + /* Go iterate over the hyperslabs */ + while(done == FALSE) { + /* Iterate over the blocks in the fastest dimension */ + while(tmp_count[fast_dim] > 0) { + /* Add 8 bytes times the rank for each hyperslab selected */ + len += 8 * ndims; - /* Sanity check */ - HDassert((spans1 && spans2) || (spans1 == NULL && spans2 == NULL)); + /* Encode hyperslab starting location */ + for(u = 0; u < ndims; u++) + UINT32ENCODE(pp, (uint32_t)offset[u]); - /* "NULL" span trees compare as overlapping */ - if(spans1==NULL && spans2==NULL) - HGOTO_DONE(TRUE); + /* Encode hyperslab ending location */ + for(u = 0; u < ndims; u++) + UINT32ENCODE(pp, (uint32_t)(offset[u] + (diminfo[u].block - 1))); - /* Get the span lists for each span in this tree */ - curr1=spans1->head; - curr2=spans2->head; - - /* Iterate over the spans in each tree */ - while(curr1!=NULL && curr2!=NULL) { - /* Check for 1st span entirely before 2nd span */ - if(curr1->highlow) - curr1=curr1->next; - /* Check for 2nd span entirely before 1st span */ - else if(curr2->highlow) - curr2=curr2->next; - /* Spans must overlap */ - else { - /* Recursively check spans in next dimension down */ - if((status=H5S_hyper_intersect_helper(curr1->down,curr2->down))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check") + /* Move the offset to the next sequence to start */ + offset[fast_dim]+=diminfo[fast_dim].stride; - /* If there is a span intersection in the down dimensions, the span trees overlap */ - if(status==TRUE) - HGOTO_DONE(TRUE); + /* Decrement the block count */ + tmp_count[fast_dim]--; + } /* end while */ - /* No intersection in down dimensions, advance to next span */ - if(curr1->highhigh) - curr1=curr1->next; - else - curr2=curr2->next; - } /* end else */ - } /* end while */ + /* Work on other dimensions if necessary */ + if(fast_dim > 0) { + int temp_dim; /* Temporary rank holder */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_hyper_intersect_helper() */ + /* Reset the block counts */ + tmp_count[fast_dim] = diminfo[fast_dim].count; - -/*-------------------------------------------------------------------------- - NAME - H5S_hyper_intersect - PURPOSE - Detect intersections in span trees - USAGE - htri_t H5S_hyper_intersect(space1, space2) - H5S_t *space1; IN: First dataspace to operate on span tree - H5S_t *space2; IN: Second dataspace to operate on span tree - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Quickly detect intersections between two span trees - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5S_hyper_intersect (H5S_t *space1, H5S_t *space2) -{ - htri_t ret_value=FAIL; /* Return value */ + /* Bubble up the decrement to the slower changing dimensions */ + temp_dim = (int)fast_dim - 1; + while(temp_dim >= 0 && done == FALSE) { + /* Decrement the block count */ + tmp_count[temp_dim]--; - FUNC_ENTER_NOAPI_NOINIT + /* Check if we have more blocks left */ + if(tmp_count[temp_dim] > 0) + break; - /* Sanity check */ - HDassert(space1); - HDassert(space2); + /* Check for getting out of iterator */ + if(temp_dim == 0) + done = TRUE; - /* Check that the space selections both have span trees */ - if(space1->select.sel_info.hslab->span_lst==NULL || - space2->select.sel_info.hslab->span_lst==NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Reset the block count in this dimension */ + tmp_count[temp_dim] = diminfo[temp_dim].count; - /* Check that the dataspaces are both the same rank */ - if(space1->extent.rank!=space2->extent.rank) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "dataspace ranks don't match") + /* Wrapped a dimension, go up to next dimension */ + temp_dim--; + } /* end while */ + } /* end if */ + else + break; /* Break out now, for 1-D selections */ - /* Perform the span-by-span intersection check */ - if((ret_value=H5S_hyper_intersect_helper(space1->select.sel_info.hslab->span_lst,space2->select.sel_info.hslab->span_lst))<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check") + /* Re-compute offset array */ + for(u = 0; u < ndims; u++) + offset[u] = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); + } /* end while */ + } /* end if */ + else { + hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ + hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5S_hyper_intersect() */ -#endif /* LATER */ + /* Encode number of hyperslabs */ + block_count = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); + H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t); + UINT32ENCODE(pp, (uint32_t)block_count); + len += 4; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_intersect_block_helper - PURPOSE - Helper routine to detect intersections in span trees - USAGE - hbool_t H5S__hyper_intersect_block_helper(spans, start, end) - H5S_hyper_span_info_t *spans; IN: First span tree to operate with - hsize_t *start; IN: Starting coordinate for block - hsize_t *end; IN: Ending coordinate for block - RETURN - Non-negative (TRUE/FALSE) on success, can't fail - DESCRIPTION - Quickly detect intersections between span tree and block - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans, - const hsize_t *start, const hsize_t *end) -{ - H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */ - hbool_t ret_value = FALSE; /* Return value */ - - FUNC_ENTER_STATIC_NOERR - - /* Sanity check */ - HDassert(spans); - HDassert(start); - HDassert(end); - - /* Get the span list for spans in this tree */ - curr = spans->head; - - /* Iterate over the spans in the tree */ - while(curr != NULL) { - /* Check for span entirely before block */ - if(curr->high < *start) - /* Advance to next span in this dimension */ - curr = curr->next; - /* If this span is past the end of the block, then we're done in this dimension */ - else if(curr->low > *end) - HGOTO_DONE(FALSE) - /* block & span overlap */ - else { - if(curr->down == NULL) - HGOTO_DONE(TRUE) - else { - hbool_t status; /* Status from recursive call */ - - /* Recursively check spans in next dimension down */ - status = H5S__hyper_intersect_block_helper(curr->down, start + 1, end + 1); + /* Add 8 bytes times the rank for each hyperslab selected */ + H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t); + len += (uint32_t)(8 * space->extent.rank * block_count); - /* If there is a span intersection in the down dimensions, the span trees overlap */ - if(status == TRUE) - HGOTO_DONE(TRUE); + /* Encode each hyperslab in selection */ + H5S__hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &pp); + } /* end else */ - /* No intersection in down dimensions, advance to next span */ - curr = curr->next; - } /* end else */ - } /* end else */ - } /* end while */ + /* Encode length */ + UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */ - /* Fall through with 'FALSE' return value */ + /* Update encoding pointer */ + *p = pp; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_intersect_block_helper() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_serialize() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_intersect_block + H5S__hyper_deserialize PURPOSE - Detect intersections in span trees + Deserialize the current selection from a user-provided buffer. USAGE - htri_t H5S_hyper_intersect_block(space, start, end) - H5S_t *space; IN: First dataspace to operate on span tree - hssize_t *start; IN: Starting coordinate for block - hssize_t *end; IN: Ending coordinate for block + herr_t H5S__hyper_deserialize(space, p) + H5S_t *space; IN/OUT: Dataspace pointer to place + selection into + uint32_t version IN: Selection version + uint8_t flags IN: Selection flags + uint8 **p; OUT: Pointer to buffer holding serialized + selection. Will be advanced to end of + serialized selection. RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION - Quickly detect intersections between span tree and block + Deserializes the current selection into a buffer. (Primarily for retrieving + from disk). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -htri_t -H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end) +static herr_t +H5S__hyper_deserialize(H5S_t *space, uint32_t H5_ATTR_UNUSED version, uint8_t flags, + const uint8_t **p) { - htri_t ret_value = FAIL; /* Return value */ + unsigned rank; /* Rank of points */ + const uint8_t *pp; /* Local pointer for decoding */ + hsize_t start[H5S_MAX_RANK]; /* Hyperslab start information */ + hsize_t block[H5S_MAX_RANK]; /* Hyperslab block information */ + unsigned u; /* Local counting variable */ + herr_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC - /* Sanity check */ + /* Check args */ HDassert(space); - HDassert(start); - HDassert(end); + HDassert(p); + pp = (*p); + HDassert(pp); - /* Check for 'all' selection, instead of a hyperslab selection */ - /* (Technically, this shouldn't be in the "hyperslab" routines...) */ - if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL) - HGOTO_DONE(TRUE); + /* Deserialize slabs to select */ + /* (The header and rank have already beed decoded) */ + rank = space->extent.rank; /* Retrieve rank from space */ - /* Check that the space selection has a span tree */ - if(NULL == space->select.sel_info.hslab->span_lst) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ + if(flags & H5S_SELECT_FLAG_UNLIM) { + hsize_t stride[H5S_MAX_RANK]; /* Hyperslab stride information */ + hsize_t count[H5S_MAX_RANK]; /* Hyperslab count information */ - /* Perform the span-by-span intersection check */ - ret_value = H5S__hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst, start, end); + /* Sanity checks */ + HDassert(H5S_UNLIMITED == HSIZE_UNDEF); + HDassert(version >= 2); + + /* Iterate over dimensions */ + for(u = 0; u < rank; u++) { + /* Decode start/stride/block/count */ + UINT64DECODE(pp, start[u]); + UINT64DECODE(pp, stride[u]); + UINT64DECODE(pp, count[u]); + UINT64DECODE(pp, block[u]); + } /* end for */ + + /* Select the hyperslab to the current selection */ + if((ret_value = H5S_select_hyperslab(space, H5S_SELECT_SET, start, stride, count, block)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't change selection") + } /* end if */ + else { + const hsize_t *stride; /* Hyperslab stride information */ + const hsize_t *count; /* Hyperslab count information */ + hsize_t end[H5S_MAX_RANK]; /* Hyperslab end information */ + hsize_t *tstart; /* Temporary hyperslab pointers */ + hsize_t *tend; /* Temporary hyperslab pointers */ + hsize_t *tblock; /* Temporary hyperslab pointers */ + size_t block_count; /* Number of blocks in selection */ + unsigned v; /* Local counting variable */ + + /* Decode the number of blocks */ + UINT32DECODE(pp, block_count); + + /* Set the count & stride for all blocks */ + stride = count = H5S_hyper_ones_g; + + /* Retrieve the coordinates from the buffer */ + for(u = 0; u < block_count; u++) { + /* Decode the starting points */ + for(tstart = start, v = 0; v < rank; v++, tstart++) + UINT32DECODE(pp, *tstart); + + /* Decode the ending points */ + for(tend = end, v = 0; v < rank; v++, tend++) + UINT32DECODE(pp, *tend); + + /* Change the ending points into blocks */ + for(tblock = block, tstart = start, tend = end, v = 0; v < rank; v++, tstart++, tend++, tblock++) + *tblock = (*tend - *tstart) + 1; + + /* Select or add the hyperslab to the current selection */ + if((ret_value = H5S_select_hyperslab(space, (u == 0 ? H5S_SELECT_SET : H5S_SELECT_OR), start, stride, count, block)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't change selection") + } /* end for */ + } /* end else */ + + /* Update decoding pointer */ + *p = pp; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_intersect_block() */ +} /* end H5S__hyper_deserialize() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_adjust_u_helper + H5S__hyper_span_blocklist PURPOSE - Helper routine to adjust offsets in span trees + Get a list of hyperslab blocks currently selected USAGE - void H5S__hyper_adjust_u_helper(spans, offset) - H5S_hyper_span_info_t *spans; IN: Span tree to operate with - const hsize_t *offset; IN: Offset to subtract + herr_t H5S__hyper_span_blocklist(spans, start, end, rank, startblock, numblocks, buf) + H5S_hyper_span_info_t *spans; IN: Dataspace pointer of selection to query + hsize_t start[]; IN/OUT: Accumulated start points + hsize_t end[]; IN/OUT: Accumulated end points + hsize_t rank; IN: Rank of dataspace + hsize_t *startblock; IN/OUT: Hyperslab block to start with + hsize_t *numblocks; IN/OUT: Number of hyperslab blocks to get + hsize_t **buf; OUT: List of hyperslab blocks selected RETURNS - None + Non-negative on success/Negative on failure DESCRIPTION - Adjust the location of the spans in a span tree by subtracting an offset + Puts a list of the hyperslab blocks into the user's buffer. The blocks + start with the '*startblock'th block in the list of blocks and put + '*numblocks' number of blocks into the user's buffer (or until the end of + the list of blocks, whichever happens first) + The block coordinates have the same dimensionality (rank) as the + dataspace they are located within. The list of blocks is formatted as + follows: <"start" coordinate> immediately followed by <"opposite" corner + coordinate>, followed by the next "start" and "opposite" coordinate, etc. + until all the block information requested has been put into the user's + buffer. + No guarantee of any order of the blocks is implied. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void -H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, - const hsize_t *offset) +static herr_t +H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], + hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, + hsize_t **buf) { - FUNC_ENTER_STATIC_NOERR + const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ + hsize_t u; /* Index variable */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_STATIC /* Sanity checks */ HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); - HDassert(offset); - - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { - H5S_hyper_span_t *span; /* Pointer to current span in span tree */ + HDassert(rank < H5S_MAX_RANK); + HDassert(start); + HDassert(end); + HDassert(startblock); + HDassert(numblocks && *numblocks > 0); + HDassert(buf && *buf); - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); + /* Walk through the list of spans, recursing or outputting them */ + curr = spans->head; + while(curr != NULL && *numblocks > 0) { + /* Recurse if this node has down spans */ + if(curr->down != NULL) { + /* Add the starting and ending points for this span to the list */ + start[rank] = curr->low; + end[rank] = curr->high; - /* Iterate over the spans in tree */ - span = spans->head; - while(span != NULL) { - /* Adjust span offset */ - HDassert(span->low >= *offset); - span->low -= *offset; - span->high -= *offset; + /* Recurse down to the next dimension */ + if(H5S__hyper_span_blocklist(curr->down, start, end, (rank + 1), startblock, numblocks, buf) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + } /* end if */ + else { + /* Skip this block if we haven't skipped all the startblocks yet */ + if(*startblock > 0) { + /* Decrement the starting block */ + (*startblock)--; + } /* end if */ + /* Process this block */ + else { + /* Encode all the previous dimensions starting & ending points */ - /* Recursively adjust spans in next dimension down */ - if(span->down != NULL) - H5S__hyper_adjust_u_helper(span->down, offset + 1); + /* Copy previous starting points */ + for(u = 0; u < rank; u++, (*buf)++) + HDmemcpy(*buf, &start[u], sizeof(hsize_t)); - /* Advance to next span in this dimension */ - span = span->next; - } /* end while */ - } /* end if */ + /* Copy starting point for this span */ + HDmemcpy(*buf, &curr->low, sizeof(hsize_t)); + (*buf)++; - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_adjust_u_helper() */ + /* Copy previous ending points */ + for(u = 0; u < rank; u++, (*buf)++) + HDmemcpy(*buf, &end[u], sizeof(hsize_t)); + + /* Copy starting point for this span */ + HDmemcpy(*buf, &curr->high, sizeof(hsize_t)); + (*buf)++; + + /* Decrement the number of blocks processed */ + (*numblocks)--; + } /* end else */ + } /* end else */ + + /* Advance to next node */ + curr = curr->next; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_span_blocklist() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_adjust_u + H5S__get_select_hyper_blocklist PURPOSE - Adjust a hyperslab selection by subtracting an offset + Get the list of hyperslab blocks currently selected USAGE - void H5S__hyper_adjust_u(space,offset) - H5S_t *space; IN/OUT: Pointer to dataspace to adjust - const hsize_t *offset; IN: Offset to subtract + herr_t H5S__get_select_hyper_blocklist(space, startblock, numblocks, buf) + H5S_t *space; IN: Dataspace pointer of selection to query + hsize_t startblock; IN: Hyperslab block to start with + hsize_t numblocks; IN: Number of hyperslab blocks to get + hsize_t *buf; OUT: List of hyperslab blocks selected RETURNS Non-negative on success, negative on failure DESCRIPTION - Moves a hyperslab selection by subtracting an offset from it. + Puts a list of the hyperslab blocks into the user's buffer. The blocks + start with the 'startblock'th block in the list of blocks and put + 'numblocks' number of blocks into the user's buffer (or until the end of + the list of blocks, whichever happens first) + The block coordinates have the same dimensionality (rank) as the + dataspace they are located within. The list of blocks is formatted as + follows: <"start" coordinate> immediately followed by <"opposite" corner + coordinate>, followed by the next "start" and "opposite" coordinate, etc. + until all the block information requested has been put into the user's + buffer. + No guarantee of any order of the blocks is implied. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset) +H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblock, hsize_t numblocks, hsize_t *buf) { + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_STATIC_NOERR - /* Sanity check */ HDassert(space); - HDassert(offset); + HDassert(buf); + HDassert(space->select.sel_info.hslab->unlim_dim < 0); - /* Subtract the offset from the "regular" coordinates, if they exist */ + /* Check for a "regular" hyperslab selection */ if(space->select.sel_info.hslab->diminfo_valid) { - unsigned u; /* Local index variable */ + const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ + hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ + unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + unsigned ndims; /* Rank of the dataspace */ + hbool_t done; /* Whether we are done with the iteration */ + unsigned u; /* Counter */ - for(u = 0; u < space->extent.rank; u++) { - HDassert(space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); - space->select.sel_info.hslab->opt_diminfo[u].start -= offset[u]; - } /* end for */ - } /* end if */ + /* Set some convienence values */ + ndims = space->extent.rank; + fast_dim = ndims - 1; - /* Subtract the offset from the span tree coordinates, if they exist */ - if(space->select.sel_info.hslab->span_lst) { - H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, offset); + /* Check which set of dimension information to use */ + if(internal) + /* + * Use the "optimized dimension information" to pass back information + * on the blocks set, not the "application information". + */ + diminfo = space->select.sel_info.hslab->opt_diminfo; + else + if(space->select.sel_info.hslab->unlim_dim >= 0) + /* + * There is an unlimited dimension so we must use opt_diminfo as + * it has been "clipped" to the current extent. + */ + diminfo = space->select.sel_info.hslab->opt_diminfo; + else + /* + * Use the "application dimension information" to pass back to + * the user the blocks they set, not the optimized, internal + * information. + */ + diminfo = space->select.sel_info.hslab->app_diminfo; - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); - } /* end if */ + /* Build the tables of count sizes as well as the initial offset */ + for(u = 0; u < ndims; u++) { + tmp_count[u] = diminfo[u].count; + offset[u] = diminfo[u].start; + } /* end for */ - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_adjust_u() */ + /* We're not done with the iteration */ + done = FALSE; - -/*------------------------------------------------------------------------- - * Function: H5S__hyper_project_scalar - * - * Purpose: Projects a single element hyperslab selection into a scalar - * dataspace - * - * Return: Non-negative on success, negative on failure. - * - * Programmer: Quincey Koziol - * Sunday, July 18, 2010 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset) -{ - hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ + /* Go iterate over the hyperslabs */ + while(!done && numblocks > 0) { + hsize_t temp_off; /* Offset in a given dimension */ - FUNC_ENTER_STATIC_NOERR + /* Iterate over the blocks in the fastest dimension */ + while(tmp_count[fast_dim] > 0 && numblocks > 0) { - /* Check args */ - HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); - HDassert(offset); + /* Check if we should copy this block information */ + if(startblock == 0) { + /* Copy the starting location */ + HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); + buf += ndims; - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ - unsigned u; /* Counter */ + /* Compute the ending location */ + HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); + for(u = 0; u < ndims; u++) + buf[u] += (diminfo[u].block - 1); + buf += ndims; - /* Build the table of the initial offset */ - for(u = 0; u < space->extent.rank; u++) { - /* Keep the offset for later */ - block[u] = diminfo[u].start; - } /* end for */ - } /* end if */ - else { - const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ - unsigned curr_dim; /* Current dimension being operated on */ + /* Decrement the number of blocks to retrieve */ + numblocks--; + } /* end if */ + else + startblock--; - /* Advance down selected spans */ - curr = space->select.sel_info.hslab->span_lst->head; - curr_dim = 0; - while(curr) { - /* Sanity check for more than one span */ - HDassert(NULL == curr->next); - HDassert(curr->low == curr->high); + /* Move the offset to the next sequence to start */ + offset[fast_dim] += diminfo[fast_dim].stride; - /* Save the location of the selection in current dimension */ - block[curr_dim] = curr->low; + /* Decrement the block count */ + tmp_count[fast_dim]--; + } /* end while */ - /* Advance down to next dimension */ - curr = curr->down->head; - curr_dim++; - } /* end while */ - } /* end else */ + /* Work on other dimensions if necessary */ + if(fast_dim > 0 && numblocks > 0) { + int temp_dim; /* Temporary rank holder */ - /* Calculate offset of selection in projected buffer */ - *offset = H5VM_array_offset(space->extent.rank, space->extent.size, block); + /* Reset the block counts */ + tmp_count[fast_dim] = diminfo[fast_dim].count; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_project_scalar() */ + /* Bubble up the decrement to the slower changing dimensions */ + temp_dim = (int)(fast_dim - 1); + while(temp_dim >= 0 && !done) { + /* Decrement the block count */ + tmp_count[temp_dim]--; - -/*------------------------------------------------------------------------- - * Function: H5S__hyper_project_simple_lower - * - * Purpose: Projects a hyperslab selection onto/into a simple dataspace - * of a lower rank - * - * Return: Non-negative on success, negative on failure. - * - * Programmer: Quincey Koziol - * Sunday, July 18, 2010 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space) -{ - H5S_hyper_span_info_t *down; /* Pointer to list of spans */ - unsigned curr_dim; /* Current dimension being operated on */ + /* Check if we have more blocks left */ + if(tmp_count[temp_dim] > 0) + break; - FUNC_ENTER_STATIC_NOERR + /* Check for getting out of iterator */ + if(temp_dim == 0) + done = TRUE; - /* Check args */ - HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); - HDassert(new_space); - HDassert(new_space->extent.rank < base_space->extent.rank); + /* Reset the block count in this dimension */ + tmp_count[temp_dim] = diminfo[temp_dim].count; - /* Walk down the span tree until we reach the selection to project */ - down = base_space->select.sel_info.hslab->span_lst; - curr_dim = 0; - while(down && curr_dim < (base_space->extent.rank - new_space->extent.rank)) { - /* Sanity check */ - HDassert(NULL == down->head->next); + /* Wrapped a dimension, go up to next dimension */ + temp_dim--; + } /* end while */ + } /* end if */ - /* Advance down to next dimension */ - down = down->head->down; - curr_dim++; - } /* end while */ - HDassert(down); + /* Re-compute offset array */ + for(u = 0; u < ndims; u++) { + temp_off = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); + offset[u] = temp_off; + } /* end for */ + } /* end while */ + } /* end if */ + else { + hsize_t start[H5S_MAX_RANK]; /* Location of start of hyperslab */ + hsize_t end[H5S_MAX_RANK]; /* Location of end of hyperslab */ - /* Share the underlying hyperslab span information */ - new_space->select.sel_info.hslab->span_lst = down; - new_space->select.sel_info.hslab->span_lst->count++; + ret_value = H5S__hyper_span_blocklist(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &startblock, &numblocks, &buf); + } /* end else */ - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_project_simple_lower() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__get_select_hyper_blocklist() */ -/*------------------------------------------------------------------------- - * Function: H5S__hyper_project_simple_higher - * - * Purpose: Projects a hyperslab selection onto/into a simple dataspace - * of a higher rank - * - * Return: Non-negative on success, negative on failure. - * - * Programmer: Quincey Koziol - * Sunday, July 18, 2010 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) +/*-------------------------------------------------------------------------- + NAME + H5Sget_select_hyper_blocklist + PURPOSE + Get the list of hyperslab blocks currently selected + USAGE + herr_t H5Sget_select_hyper_blocklist(dsid, startblock, numblocks, buf) + hid_t dsid; IN: Dataspace ID of selection to query + hsize_t startblock; IN: Hyperslab block to start with + hsize_t numblocks; IN: Number of hyperslab blocks to get + hsize_t buf[]; OUT: List of hyperslab blocks selected + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Puts a list of the hyperslab blocks into the user's buffer. The blocks + start with the 'startblock'th block in the list of blocks and put + 'numblocks' number of blocks into the user's buffer (or until the end of + the list of blocks, whichever happen first) + The block coordinates have the same dimensionality (rank) as the + dataspace they are located within. The list of blocks is formatted as + follows: <"start" coordinate> immediately followed by <"opposite" corner + coordinate>, followed by the next "start" and "opposite" coordinate, etc. + until all the block information requested has been put into the user's + buffer. + No guarantee of any order of the blocks is implied. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, + hsize_t numblocks, hsize_t buf[/*numblocks*/]) { - H5S_hyper_span_t *prev_span = NULL; /* Pointer to previous list of spans */ - unsigned delta_rank; /* Difference in dataspace ranks */ - unsigned curr_dim; /* Current dimension being operated on */ - herr_t ret_value = SUCCEED; /* Return value */ + H5S_t *space; /* Dataspace to modify selection of */ + herr_t ret_value; /* return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "ihh*[a2]h", spaceid, startblock, numblocks, buf); /* Check args */ - HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); - HDassert(new_space); - HDassert(new_space->extent.rank > base_space->extent.rank); - - /* Create nodes until reaching the correct # of dimensions */ - new_space->select.sel_info.hslab->span_lst = NULL; - curr_dim = 0; - delta_rank = (new_space->extent.rank - base_space->extent.rank); - while(curr_dim < delta_rank) { - H5S_hyper_span_info_t *new_span_info; /* Pointer to list of spans */ - H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ - - /* Allocate a new span_info node */ - if(NULL == (new_span_info = H5FL_CALLOC(H5S_hyper_span_info_t))) { - if(prev_span) - if(H5S__hyper_free_span(prev_span) < 0) - HERROR(H5E_DATASPACE, H5E_CANTFREE, "can't free hyperslab span"); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") - } /* end if */ - - /* Check for linking into higher span */ - if(prev_span) - prev_span->down = new_span_info; - - /* Allocate a new node */ - if(NULL == (new_span = H5S__hyper_new_span((hsize_t)0, (hsize_t)0, NULL, NULL))) { - HDassert(new_span_info); - if(!prev_span) - (void)H5FL_FREE(H5S_hyper_span_info_t, new_span_info); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - } /* end if */ - - /* Set the span_info information */ - new_span_info->count = 1; - new_span_info->head = new_span; - - /* Attach to new space, if top span info */ - if(NULL == new_space->select.sel_info.hslab->span_lst) - new_space->select.sel_info.hslab->span_lst = new_span_info; - - /* Remember previous span info */ - prev_span = new_span; - - /* Advance to next dimension */ - curr_dim++; - } /* end while */ - HDassert(new_space->select.sel_info.hslab->span_lst); - HDassert(prev_span); + if(buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer") + if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection") + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot get blocklist for unlimited selection") - /* Share the underlying hyperslab span information */ - prev_span->down = base_space->select.sel_info.hslab->span_lst; - prev_span->down->count++; + /* Go get the correct number of blocks */ + if(numblocks > 0) + ret_value = H5S__get_select_hyper_blocklist(space, 0, startblock, numblocks, buf); + else + ret_value = SUCCEED; /* Successfully got 0 blocks... */ done: - if(ret_value < 0 && new_space->select.sel_info.hslab->span_lst) { - if(new_space->select.sel_info.hslab->span_lst->head) - if(H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free hyperslab span") - - new_space->select.sel_info.hslab->span_lst = H5FL_FREE(H5S_hyper_span_info_t, new_space->select.sel_info.hslab->span_lst); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_project_simple_higher() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Sget_select_hyper_blocklist() */ -/*------------------------------------------------------------------------- - * Function: H5S__hyper_project_simple - * - * Purpose: Projects a hyperslab selection onto/into a simple dataspace - * of a different rank - * - * Return: Non-negative on success, negative on failure. - * - * Programmer: Quincey Koziol - * Sunday, July 18, 2010 - * - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_bounds_helper + PURPOSE + Gets the bounding box containing the selection. + USAGE + htri_t H5S_hyper_bounds_helper(spans, offset, rank); + const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree + const hssize_t *offset; IN: Pointer to offset array + hsize_t rank; IN: Current rank looking at + hsize_t *start; OUT: Start array bounds + hsize_t *end; OUT: End array bounds + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Retrieves the bounding box containing the current selection and places + it into the user's buffers. The start and end buffers must be large + enough to hold the dataspace rank number of coordinates. The bounding box + exactly contains the selection, ie. if a 2-D element selection is currently + defined with the following points: (4,5), (6,8) (10,7), the bounding box + with be (4, 5), (10, 8). + The bounding box calculations _does_ include the current offset of the + selection within the dataspace extent. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ static herr_t -H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, - hsize_t *offset) +H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end) { - herr_t ret_value = SUCCEED; /* Return value */ + H5S_hyper_span_t *curr; /* Hyperslab information nodes */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI_NOINIT - /* Check args */ - HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); - HDassert(new_space); + HDassert(spans); HDassert(offset); + HDassert(rank < H5S_MAX_RANK); + HDassert(start); + HDassert(end); - /* We are setting a new selection, remove any current selection in new dataspace */ - if(H5S_SELECT_RELEASE(new_space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + /* Check each point to determine whether selection+offset is within extent */ + curr=spans->head; + while(curr!=NULL) { + /* Check for offset moving selection negative */ + if(((hssize_t)curr->low + offset[rank]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - /* Allocate space for the hyperslab selection information */ - if(NULL == (new_space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") + /* Check if the current span extends the bounding box */ + if((curr->low + (hsize_t)offset[rank]) < start[rank]) + start[rank] = curr->low + (hsize_t)offset[rank]; + if((curr->high + (hsize_t)offset[rank]) > end[rank]) + end[rank] = curr->high + (hsize_t)offset[rank]; - /* Set unlim_dim */ - new_space->select.sel_info.hslab->unlim_dim = -1; + /* Recurse if this node has down spans */ + if(curr->down != NULL) { + if(H5S_hyper_bounds_helper(curr->down, offset, (rank + 1), start, end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "failure in lower dimension") + } /* end if */ - /* Check for a "regular" hyperslab selection */ - if(base_space->select.sel_info.hslab->diminfo_valid) { - unsigned base_space_dim; /* Current dimension in the base dataspace */ - unsigned new_space_dim; /* Current dimension in the new dataspace */ - - /* Check if the new space's rank is < or > base space's rank */ - if(new_space->extent.rank < base_space->extent.rank) { - const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ - hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ - unsigned u; /* Local index variable */ - - /* Compute the offset for the down-projection */ - HDmemset(block, 0, sizeof(block)); - for(u = 0; u < (base_space->extent.rank - new_space->extent.rank); u++) - block[u] = opt_diminfo[u].start; - *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); - - /* Set the correct dimensions for the base & new spaces */ - base_space_dim = base_space->extent.rank - new_space->extent.rank; - new_space_dim = 0; - } /* end if */ - else { - HDassert(new_space->extent.rank > base_space->extent.rank); - - /* The offset is zero when projected into higher dimensions */ - *offset = 0; - - /* Set the diminfo information for the higher dimensions */ - for(new_space_dim = 0; new_space_dim < (new_space->extent.rank - base_space->extent.rank); new_space_dim++) { - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = 0; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = 1; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = 1; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = 1; - - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = 0; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = 1; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = 1; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = 1; - } /* end for */ - - /* Start at beginning of base space's dimension info */ - base_space_dim = 0; - } /* end else */ - - /* Copy the diminfo */ - while(base_space_dim < base_space->extent.rank) { - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].start; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].stride; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].count; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].block; - - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].start; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].stride; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].count; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].block; - - /* Advance to next dimensions */ - base_space_dim++; - new_space_dim++; - } /* end for */ - - /* Indicate that the dimension information is valid */ - new_space->select.sel_info.hslab->diminfo_valid = TRUE; - - /* Indicate that there's no slab information */ - new_space->select.sel_info.hslab->span_lst = NULL; - } /* end if */ - else { - /* Check if the new space's rank is < or > base space's rank */ - if(new_space->extent.rank < base_space->extent.rank) { - const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ - hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ - unsigned curr_dim; /* Current dimension being operated on */ - - /* Clear the block buffer */ - HDmemset(block, 0, sizeof(block)); - - /* Advance down selected spans */ - curr = base_space->select.sel_info.hslab->span_lst->head; - curr_dim = 0; - while(curr && curr_dim < (base_space->extent.rank - new_space->extent.rank)) { - /* Save the location of the selection in current dimension */ - block[curr_dim] = curr->low; - - /* Advance down to next dimension */ - curr = curr->down->head; - curr_dim++; - } /* end while */ - - /* Compute the offset for the down-projection */ - *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); - - /* Project the base space's selection down in less dimensions */ - if(H5S__hyper_project_simple_lower(base_space, new_space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions") - } /* end if */ - else { - HDassert(new_space->extent.rank > base_space->extent.rank); - - /* The offset is zero when projected into higher dimensions */ - *offset = 0; - - /* Project the base space's selection down in more dimensions */ - if(H5S__hyper_project_simple_higher(base_space, new_space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions") - } /* end else */ - - /* Indicate that the dimension information is not valid */ - new_space->select.sel_info.hslab->diminfo_valid = FALSE; - } /* end else */ - - /* Number of elements selected will be the same */ - new_space->select.num_elem = base_space->select.num_elem; - - /* Set selection type */ - new_space->select.type = H5S_sel_hyper; + /* Advance to next node */ + curr = curr->next; + } /* end while */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_project_simple() */ +} /* end H5S_hyper_bounds_helper() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_adjust_s_helper + H5S__hyper_bounds PURPOSE - Helper routine to adjust offsets in span trees + Gets the bounding box containing the selection. USAGE - void H5S__hyper_adjust_s_helper(spans, offset) - H5S_hyper_span_info_t *spans; IN: Span tree to operate with - const hssize_t *offset; IN: Offset to subtract + herr_t H5S__hyper_bounds(space, hsize_t *start, hsize_t *end) + H5S_t *space; IN: Dataspace pointer of selection to query + hsize_t *start; OUT: Starting coordinate of bounding box + hsize_t *end; OUT: Opposite coordinate of bounding box RETURNS - None + Non-negative on success, negative on failure DESCRIPTION - Adjust the location of the spans in a span tree by subtracting an offset + Retrieves the bounding box containing the current selection and places + it into the user's buffers. The start and end buffers must be large + enough to hold the dataspace rank number of coordinates. The bounding box + exactly contains the selection, ie. if a 2-D element selection is currently + defined with the following points: (4,5), (6,8) (10,7), the bounding box + with be (4, 5), (10, 8). + The bounding box calculations _does_ include the current offset of the + selection within the dataspace extent. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void -H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, - const hssize_t *offset) +static herr_t +H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) { - FUNC_ENTER_STATIC_NOERR + unsigned rank; /* Dataspace rank */ + unsigned i; /* index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Sanity checks */ - HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); - HDassert(offset); + FUNC_ENTER_STATIC - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { - H5S_hyper_span_t *span; /* Pointer to current span in span tree */ + /* Sanity check */ + HDassert(space); + HDassert(start); + HDassert(end); - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); + /* Set the start and end arrays up */ + rank = space->extent.rank; + for(i = 0; i < rank; i++) { + start[i] = HSIZET_MAX; + end[i] = 0; + } /* end for */ - /* Iterate over the spans in tree */ - span = spans->head; - while(span != NULL) { - /* Adjust span offset */ - HDassert((hssize_t)span->low >= *offset); - span->low = (hsize_t)((hssize_t)span->low - *offset); - span->high = (hsize_t)((hssize_t)span->high - *offset); + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ - /* Recursively adjust spans in next dimension down */ - if(span->down != NULL) - H5S__hyper_adjust_s_helper(span->down, offset + 1); + /* Check each dimension */ + for(i = 0; i < rank; i++) { + /* Check for offset moving selection negative */ + if((space->select.offset[i] + (hssize_t)diminfo[i].start) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - /* Advance to next span in this dimension */ - span = span->next; - } /* end while */ + /* Compute the smallest location in this dimension */ + start[i] = diminfo[i].start + (hsize_t)space->select.offset[i]; + + /* Compute the largest location in this dimension */ + if((int)i == space->select.sel_info.hslab->unlim_dim) + end[i] = H5S_UNLIMITED; + else + end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i]; + } /* end for */ + } /* end if */ + else { + /* Call the recursive routine to get the bounds for the span tree */ + ret_value = H5S_hyper_bounds_helper(space->select.sel_info.hslab->span_lst, space->select.offset, (hsize_t)0, start, end); } /* end if */ - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_adjust_s_helper() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_bounds() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_adjust_s + H5S__hyper_offset PURPOSE - Adjust a hyperslab selection by subtracting an offset + Gets the linear offset of the first element for the selection. USAGE - herr_t H5S_hyper_adjust_s(space,offset) - H5S_t *space; IN/OUT: Pointer to dataspace to adjust - const hssize_t *offset; IN: Offset to subtract + herr_t H5S__hyper_offset(space, offset) + const H5S_t *space; IN: Dataspace pointer of selection to query + hsize_t *offset; OUT: Linear offset of first element in selection RETURNS Non-negative on success, negative on failure DESCRIPTION - Moves a hyperslab selection by subtracting an offset from it. + Retrieves the linear offset (in "units" of elements) of the first element + selected within the dataspace. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Calling this function on a "none" selection returns fail. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset) +static herr_t +H5S__hyper_offset(const H5S_t *space, hsize_t *offset) { - herr_t ret_value = SUCCEED; /* Return value */ + const hssize_t *sel_offset; /* Pointer to the selection's offset */ + const hsize_t *dim_size; /* Pointer to a dataspace's extent */ + hsize_t accum; /* Accumulator for dimension sizes */ + unsigned rank; /* Dataspace rank */ + int i; /* index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC - /* Sanity checks */ - HDassert(space); + HDassert(space && space->extent.rank>0); HDassert(offset); - /* Subtract the offset from the "regular" coordinates, if they exist */ - if(space->select.sel_info.hslab->diminfo_valid) { - unsigned u; /* Local index variable */ + /* Start at linear offset 0 */ + *offset = 0; - for(u = 0; u < space->extent.rank; u++) { - HDassert((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); - space->select.sel_info.hslab->opt_diminfo[u].start = (hsize_t)((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start - offset[u]); - } /* end for */ - } /* end if */ + /* Set up pointers to arrays of values */ + rank = space->extent.rank; + sel_offset = space->select.offset; + dim_size = space->extent.size; - /* Subtract the offset from the span tree coordinates, if they exist */ - if(space->select.sel_info.hslab->span_lst) { - H5S__hyper_adjust_s_helper(space->select.sel_info.hslab->span_lst, offset); + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */ - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + /* Loop through starting coordinates, calculating the linear offset */ + accum = 1; + for(i = (int)(rank - 1); i >= 0; i--) { + hssize_t hyp_offset = (hssize_t)diminfo[i].start + sel_offset[i]; /* Hyperslab's offset in this dimension */ + + /* Check for offset moving selection out of the dataspace */ + if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + + /* Add the hyperslab's offset in this dimension to the total linear offset */ + *offset += (hsize_t)(hyp_offset * (hssize_t)accum); + + /* Increase the accumulator */ + accum *= dim_size[i]; + } /* end for */ } /* end if */ + else { + const H5S_hyper_span_t *span; /* Hyperslab span node */ + hsize_t dim_accum[H5S_MAX_RANK]; /* Accumulators, for each dimension */ + + /* Calculate the accumulator for each dimension */ + accum = 1; + for(i = (int)(rank - 1); i >= 0; i--) { + /* Set the accumulator for this dimension */ + dim_accum[i] = accum; + + /* Increase the accumulator */ + accum *= dim_size[i]; + } /* end for */ + + /* Get information for the first span, in the slowest changing dimension */ + span = space->select.sel_info.hslab->span_lst->head; + + /* Work down the spans, computing the linear offset */ + i = 0; + while(span) { + hssize_t hyp_offset = (hssize_t)span->low + sel_offset[i]; /* Hyperslab's offset in this dimension */ + + /* Check for offset moving selection out of the dataspace */ + if(hyp_offset < 0 || (hsize_t)hyp_offset >= dim_size[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + + /* Add the hyperslab's offset in this dimension to the total linear offset */ + *offset += (hsize_t)(hyp_offset * (hssize_t)dim_accum[i]); + + /* Advance to first span in "down" dimension */ + if(span->down) { + HDassert(span->down->head); + span = span->down->head; + } /* end if */ + else + span = NULL; + i++; + } /* end while */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_adjust_s() */ +} /* end H5S__hyper_offset() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_normalize_offset + H5S__hyper_unlim_dim PURPOSE - "Normalize" a hyperslab selection by adjusting it's coordinates by the - amount of the selection offset. + Return unlimited dimension of selection, or -1 if none USAGE - htri_t H5S_hyper_normalize_offset(space, old_offset) - H5S_t *space; IN/OUT: Pointer to dataspace to move - hssize_t *old_offset; OUT: Pointer to space to store old offset + int H5S__hyper_unlim_dim(space) + H5S_t *space; IN: Dataspace pointer to check RETURNS - TRUE/FALSE for hyperslab selection, FAIL on error + Unlimited dimension of selection, or -1 if none (never fails). DESCRIPTION - Copies the current selection offset into the array provided, then - inverts the selection offset, subtracts the offset from the hyperslab - selection and resets the offset to zero. + Returns the index of the unlimited dimension of the selection, or -1 + if the selection has no unlimited dimension. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -htri_t -H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset) +static int +H5S__hyper_unlim_dim(const H5S_t *space) { - htri_t ret_value = FALSE; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(space); - HDassert(old_offset); - - /* Check for hyperslab selection & offset changed */ - if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS && space->select.offset_changed) { - unsigned u; /* Local index variable */ - - /* Copy & invert the selection offset */ - for(u = 0; u < space->extent.rank; u++) { - old_offset[u] = space->select.offset[u]; - space->select.offset[u] = -space->select.offset[u]; - } /* end for */ - - /* Call the 'adjust' routine */ - if(H5S_hyper_adjust_s(space, space->select.offset) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection") - - /* Zero out the selection offset */ - HDmemset(space->select.offset, 0, sizeof(hssize_t) * space->extent.rank); - - /* Indicate that the offset was normalized */ - ret_value = TRUE; - } /* end if */ + FUNC_ENTER_STATIC_NOERR -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_normalize_offset() */ + FUNC_LEAVE_NOAPI(space->select.sel_info.hslab->unlim_dim); +} /* end H5S__hyper_unlim_dim() */ /*-------------------------------------------------------------------------- NAME - H5S_hyper_denormalize_offset + H5S__hyper_num_elem_non_unlim PURPOSE - "Denormalize" a hyperslab selection by reverse adjusting it's coordinates - by the amount of the former selection offset. + Return number of elements in the non-unlimited dimensions USAGE - herr_t H5S_hyper_denormalize_offset(space, old_offset) - H5S_t *space; IN/OUT: Pointer to dataspace to move - hssize_t *old_offset; IN: Pointer to old offset array + herr_t H5S__hyper_num_elem_non_unlim(space,num_elem_non_unlim) + H5S_t *space; IN: Dataspace pointer to check + hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION - Subtracts the old offset from the current selection (canceling out the - effect of the "normalize" routine), then restores the old offset into - the dataspace. + Returns the number of elements in a slice through the non-unlimited + dimensions of the selection. Fails if the selection has no unlimited + dimension. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset) +static herr_t +H5S__hyper_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC - /* Sanity checks */ + /* Sanity check */ HDassert(space); - HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - - /* Call the 'adjust' routine */ - if(H5S_hyper_adjust_s(space, old_offset) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection") + HDassert(num_elem_non_unlim); - /* Copy the selection offset over */ - HDmemcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); + /* Get number of elements in the non-unlimited dimensions */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + *num_elem_non_unlim = space->select.sel_info.hslab->num_elem_non_unlim; + else + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection has no unlimited dimension") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_denormalize_offset() */ +} /* end H5S__hyper_num_elem_non_unlim() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_append_span + H5S__hyper_is_contiguous PURPOSE - Create a new span and append to span list + Check if a hyperslab selection is contiguous within the dataspace extent. USAGE - herr_t H5S__hyper_append_span(prev_span, span_tree, low, high, down, next) - H5S_hyper_span_t **prev_span; IN/OUT: Pointer to previous span in list - H5S_hyper_span_info_t **span_tree; IN/OUT: Pointer to span tree to append to - hsize_t low, high; IN: Low and high bounds for new span node - H5S_hyper_span_info_t *down; IN: Down span tree for new node - H5S_hyper_span_t *next; IN: Next span for new node + htri_t H5S__hyper_is_contiguous(space) + H5S_t *space; IN: Dataspace pointer to check RETURNS - Non-negative on success, negative on failure + TRUE/FALSE/FAIL DESCRIPTION - Create a new span node and append to a span list. Update the previous - span in the list also. + Checks to see if the current selection in the dataspace is contiguous. + This is primarily used for reading the entire selection in one swoop. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_append_span(H5S_hyper_span_t **prev_span, - H5S_hyper_span_info_t **span_tree, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next) +static H5_ATTR_PURE htri_t +H5S__hyper_is_contiguous(const H5S_t *space) { - H5S_hyper_span_t *new_span = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t small_contiguous, /* Flag for small contiguous block */ + large_contiguous; /* Flag for large contiguous block */ + unsigned u; /* index variable */ + htri_t ret_value = FALSE; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR - HDassert(prev_span); - HDassert(span_tree); + HDassert(space); - /* Check for adding first node to merged spans */ - if(*prev_span == NULL) { - /* Allocate new span node to append to list */ - if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ - /* Make first node in span list */ + /* + * For a regular hyperslab to be contiguous, it must have only one + * block (i.e. count==1 in all dimensions) and the block size must be + * the same as the dataspace extent's in all but the slowest changing + * dimension. (dubbed "large contiguous" block) + * + * OR + * + * The selection must have only one block (i.e. count==1) in all + * dimensions and the block size must be 1 in all but the fastest + * changing dimension. (dubbed "small contiguous" block) + */ - /* Check that we haven't already allocated a span tree */ - HDassert(*span_tree == NULL); + /* Initialize flags */ + large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */ + small_contiguous = FALSE; /* assume false initially */ - /* Allocate a new span_info node */ - if(NULL == (*span_tree = H5FL_CALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") + /* Check for a "large contigous" block */ + for(u = 0; u < space->extent.rank; u++) { + if(diminfo[u].count > 1) { + large_contiguous = FALSE; + break; + } /* end if */ + if(u > 0 && diminfo[u].block != space->extent.size[u]) { + large_contiguous = FALSE; + break; + } /* end if */ + } /* end for */ - /* Set the span tree's basic information */ - (*span_tree)->count = 1; - (*span_tree)->head = new_span; + /* If we didn't find a large contiguous block, check for a small one */ + if(!large_contiguous) { + small_contiguous = TRUE; + for(u = 0; u < space->extent.rank; u++) { + if(diminfo[u].count > 1) { + small_contiguous = FALSE; + break; + } /* end if */ + if(u < (space->extent.rank - 1) && diminfo[u].block != 1) { + small_contiguous = FALSE; + break; + } /* end if */ + } /* end for */ + } /* end if */ - /* Update previous merged span */ - *prev_span = new_span; - } /* end if */ - /* Merge or append to existing merged spans list */ - else { - /* Check if span can just extend the previous merged span */ - if((((*prev_span)->high + 1) == low) && - H5S__hyper_cmp_spans(down, (*prev_span)->down)==TRUE) { - /* Extend previous merged span to include new high bound */ - (*prev_span)->high = high; - (*prev_span)->nelem += (high - low) + 1; - } /* end if */ - else { - /* Allocate new span node to append to list */ - if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - - /* Check if there is actually a down span */ - if(new_span->down) { - /* Check if the down spans for the new span node are the same as the previous span node */ - if(H5S__hyper_cmp_spans(new_span->down, (*prev_span)->down)) { - /* Release the down span for the new node */ - H5S__hyper_free_span_info(new_span->down); - - /* Point the new node's down span at the previous node's down span */ - new_span->down = (*prev_span)->down; - - /* Increment the reference count to the shared down span */ - new_span->down->count++; - } /* end if */ - } /* end if */ - - /* Indicate elements from previous span */ - new_span->pstride = low - (*prev_span)->low; - - /* Append to end of merged spans list */ - (*prev_span)->next = new_span; - *prev_span = new_span; - } /* end else */ - } /* end else */ - -done: - if(ret_value < 0) - if(new_span && H5S__hyper_free_span(new_span) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_append_span() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_clip_spans - PURPOSE - Clip a new span tree against the current spans in the hyperslab selection - USAGE - herr_t H5S__hyper_clip_spans(span_a, span_b, a_not_b, a_and_b, b_not_a) - H5S_hyper_span_t *a_spans; IN: Span tree 'a' to clip with. - H5S_hyper_span_t *b_spans; IN: Span tree 'b' to clip with. - H5S_hyper_span_t **a_not_b; OUT: Span tree of 'a' hyperslab spans which - doesn't overlap with 'b' hyperslab - spans. - H5S_hyper_span_t **a_and_b; OUT: Span tree of 'a' hyperslab spans which - overlaps with 'b' hyperslab spans. - H5S_hyper_span_t **b_not_a; OUT: Span tree of 'b' hyperslab spans which - doesn't overlap with 'a' hyperslab - spans. - RETURNS - non-negative on success, negative on failure - DESCRIPTION - Clip one span tree ('a') against another span tree ('b'). Creates span - trees for the area defined by the 'a' span tree which does not overlap the - 'b' span tree ("a not b"), the area defined by the overlap of the 'a' - hyperslab span tree and the 'b' span tree ("a and b"), and the area defined - by the 'b' hyperslab span tree which does not overlap the 'a' span - tree ("b not a"). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans, - H5S_hyper_span_info_t **a_not_b, H5S_hyper_span_info_t **a_and_b, - H5S_hyper_span_info_t **b_not_a) -{ - H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */ - H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */ - H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */ - H5S_hyper_span_t *last_a_not_b; /* Pointer to previous node in span tree 'a_not_b' */ - H5S_hyper_span_t *last_a_and_b; /* Pointer to previous node in span tree 'a_and_b' */ - H5S_hyper_span_t *last_b_not_a; /* Pointer to previous node in span tree 'b_not_a' */ - H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */ - H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */ - H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */ - hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Check args */ - HDassert(a_spans); - HDassert(b_spans); - HDassert(a_not_b); - HDassert(a_and_b); - HDassert(b_not_a); - - /* Check if both span trees are not defined */ - if(a_spans == NULL && b_spans == NULL) { - *a_not_b = NULL; - *a_and_b = NULL; - *b_not_a = NULL; - } /* end if */ - /* If span 'a' is not defined, but 'b' is, copy 'b' and set the other return span trees to empty */ - else if(a_spans == NULL) { - *a_not_b = NULL; - *a_and_b = NULL; - if(NULL == (*b_not_a = H5S__hyper_copy_span(b_spans))) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") - } /* end if */ - /* If span 'b' is not defined, but 'a' is, copy 'a' and set the other return span trees to empty */ - else if(b_spans == NULL) { - if(NULL == (*a_not_b = H5S__hyper_copy_span(a_spans)) ) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") - *a_and_b = NULL; - *b_not_a = NULL; + /* Indicate true if it's either a large or small contiguous block */ + if(large_contiguous || small_contiguous) + ret_value = TRUE; } /* end if */ - /* If span 'a' and 'b' are both defined, calculate the proper span trees */ else { - /* Check if both span trees completely overlap */ - if(H5S__hyper_cmp_spans(a_spans, b_spans)) { - *a_not_b = NULL; - if(NULL == (*a_and_b = H5S__hyper_copy_span(a_spans))) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") - *b_not_a = NULL; - } /* end if */ - else { - /* Get the pointers to the new and old span lists */ - span_a = a_spans->head; - span_b = b_spans->head; - - /* Reset the pointers to the previous spans */ - last_a_not_b = last_a_and_b = last_b_not_a = NULL; - - /* No spans to recover yet */ - recover_a = recover_b = FALSE; - - /* Work through the list of spans in the new list */ - while(span_a != NULL && span_b != NULL) { - /* Check if span 'a' is completely before span 'b' */ - /* AAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - if(span_a->high < span_b->low) { - /* Copy span 'a' and add to a_not_b list */ + H5S_hyper_span_info_t *spans; /* Hyperslab span info node */ + H5S_hyper_span_t *span; /* Hyperslab span node */ - /* Merge/add span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, span_a->down, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + /* + * For a hyperslab to be contiguous, it must have only one block and + * either it's size must be the same as the dataspace extent's in all + * but the slowest changing dimension + * OR + * block size must be 1 in all but the fastest changing dimension. + */ + /* Initialize flags */ + large_contiguous = TRUE; /* assume true and reset if the dimensions don't match */ + small_contiguous = FALSE; /* assume false initially */ - /* Advance span 'a', leave span 'b' */ - H5S__hyper_recover_span(&recover_a, &span_a, span_a->next); - } /* end if */ - /* Check if span 'a' overlaps only the lower bound */ - /* of span 'b' , up to the upper bound of span 'b' */ - /* AAAAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) { - /* Split span 'a' into two parts at the low bound of span 'b' */ + /* Get information for slowest changing information */ + spans = space->select.sel_info.hslab->span_lst; + span = spans->head; - /* Merge/add lower part of span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->low - 1, span_a->down, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + /* If there are multiple spans in the slowest changing dimension, the selection isn't contiguous */ + if(span->next != NULL) + large_contiguous = FALSE; + else { + /* Now check the rest of the dimensions */ + if(span->down != NULL) { + u = 1; /* Current dimension working on */ - /* Check for overlaps between upper part of span 'a' and lower part of span 'b' */ + /* Get the span information for the next fastest dimension */ + spans = span->down; - /* Make certain both spans either have a down span or both don't have one */ - HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); + /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ + while(spans != NULL) { + span = spans->head; - /* If there are no down spans, just add the overlapping area to the a_and_b list */ - if(span_a->down == NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_a->high, NULL, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + /* Check that this is the only span and it spans the entire dimension */ + if(span->next != NULL) { + large_contiguous = FALSE; + break; } /* end if */ - /* If there are down spans, check for the overlap in them and add to each appropriate list */ else { - /* NULL out the temporary pointers to clipped areas in down spans */ - down_a_not_b = NULL; - down_a_and_b = NULL; - down_b_not_a = NULL; - - /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - /* Check for additions to the a_not_b list */ - if(down_a_not_b) { - /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_a->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ - - /* Check for additions to the a_and_b list */ - if(down_a_and_b) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_a->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ - - /* Check for additions to the b_not_a list */ - if(down_b_not_a) { - /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); + /* If this span doesn't cover the entire dimension, then this selection isn't contiguous */ + if(((span->high - span->low) + 1) != space->extent.size[u]) { + large_contiguous = FALSE; + break; } /* end if */ - } /* end else */ - - /* Split off upper part of span 'b' at upper span of span 'a' */ + else { + /* Walk down to the next span */ + spans = span->down; - /* Check if there is actually an upper part of span 'b' to split off */ - if(span_a->high < span_b->high) { - /* Allocate new span node for upper part of span 'b' */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - - /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - - /* Make upper part of span 'b' into new span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); - recover_b = TRUE; - } /* end if */ - /* No upper part of span 'b' to split */ - else { - /* Advance both 'a' and 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end if */ - /* Check if span 'a' overlaps the lower & upper bound */ - /* of span 'b' */ - /* AAAAAAAAAAAAAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low < span_b->low && span_a->high > span_b->high) { - /* Split off lower part of span 'a' at lower span of span 'b' */ - - /* Merge/add lower part of span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Check for overlaps between middle part of span 'a' and span 'b' */ - - /* Make certain both spans either have a down span or both don't have one */ - HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - - /* If there are no down spans, just add the overlapping area to the a_and_b list */ - if(span_a->down == NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ - /* If there are down spans, check for the overlap in them and add to each appropriate list */ - else { - /* NULL out the temporary pointers to clipped areas in down spans */ - down_a_not_b = NULL; - down_a_and_b = NULL; - down_b_not_a = NULL; - - /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - /* Check for additions to the a_not_b list */ - if(down_a_not_b) { - /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_b->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ - - /* Check for additions to the a_and_b list */ - if(down_a_and_b) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ - - /* Check for additions to the b_not_a list */ - if(down_b_not_a) { - /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ - - /* Split off upper part of span 'a' at upper span of span 'b' */ - - /* Allocate new span node for upper part of span 'a' */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - - /* Make upper part of span 'a' the new span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); - recover_a = TRUE; - - /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end if */ - /* Check if span 'a' is entirely within span 'b' */ - /* AAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low >= span_b->low && span_a->high <= span_b->high) { - /* Split off lower part of span 'b' at lower span of span 'a' */ - - /* Check if there is actually a lower part of span 'b' to split off */ - if(span_a->low > span_b->low) { - /* Merge/add lower part of span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ - else { - /* Keep going, nothing to split off */ - } /* end else */ - - /* Check for overlaps between span 'a' and midle of span 'b' */ - - /* Make certain both spans either have a down span or both don't have one */ - HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - - /* If there are no down spans, just add the overlapping area to the a_and_b list */ - if(span_a->down == NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ - /* If there are down spans, check for the overlap in them and add to each appropriate list */ - else { - /* NULL out the temporary pointers to clipped areas in down spans */ - down_a_not_b = NULL; - down_a_and_b = NULL; - down_b_not_a = NULL; - - /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - /* Check for additions to the a_not_b list */ - if(down_a_not_b) { - /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ - - /* Check for additions to the a_and_b list */ - if(down_a_and_b!=NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ - - /* Check for additions to the b_not_a list */ - if(down_b_not_a!=NULL) { - /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_a->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ - - /* Check if there is actually an upper part of span 'b' to split off */ - if(span_a->high < span_b->high) { - /* Split off upper part of span 'b' at upper span of span 'a' */ - - /* Allocate new span node for upper part of spans 'a' */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - - /* And advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - - /* Make upper part of span 'b' the new span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); - recover_b=1; - } /* end if */ - else { - /* Advance both span 'a' & span 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end if */ - /* Check if span 'a' overlaps only the upper bound */ - /* of span 'b' */ - /* AAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) { - /* Check if there is actually a lower part of span 'b' to split off */ - if(span_a->low > span_b->low) { - /* Split off lower part of span 'b' at lower span of span 'a' */ - - /* Merge/add lower part of span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ - else { - /* Keep going, nothing to split off */ - } /* end else */ - - /* Check for overlaps between lower part of span 'a' and upper part of span 'b' */ - - /* Make certain both spans either have a down span or both don't have one */ - HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - - /* If there are no down spans, just add the overlapping area to the a_and_b list */ - if(span_a->down == NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - } /* end if */ - /* If there are down spans, check for the overlap in them and add to each appropriate list */ - else { - /* NULL out the temporary pointers to clipped areas in down spans */ - down_a_not_b = NULL; - down_a_and_b = NULL; - down_b_not_a = NULL; - - /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - /* Check for additions to the a_not_b list */ - if(down_a_not_b) { - /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_not_b); - } /* end if */ - - /* Check for additions to the a_and_b list */ - if(down_a_and_b!=NULL) { - /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_a_and_b); - } /* end if */ - - /* Check for additions to the b_not_a list */ - if(down_b_not_a) { - /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_b->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Release the down span tree generated */ - H5S__hyper_free_span_info(down_b_not_a); - } /* end if */ - } /* end else */ - - /* Split off upper part of span 'a' at upper span of span 'b' */ - - /* Allocate new span node for upper part of span 'a' */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - - /* Make upper part of span 'a' into new span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); - recover_a=1; - - /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end if */ - /* span 'a' must be entirely above span 'b' */ - /* AAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else { - /* Copy span 'b' and add to b_not_a list */ - - /* Merge/add span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Advance span 'b', leave span 'a' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end while */ - - /* Clean up 'a' spans which haven't been covered yet */ - if(span_a != NULL && span_b == NULL) { - while(span_a != NULL) { - /* Copy span 'a' and add to a_not_b list */ - - /* Merge/add span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Advance to the next 'a' span */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - } /* end while */ - } /* end if */ - /* Clean up 'b' spans which haven't been covered yet */ - else if(span_a == NULL && span_b != NULL) { - while(span_b != NULL) { - /* Copy span 'b' and add to b_not_a list */ - - /* Merge/add span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - - /* Advance to the next 'b' span */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end while */ - } /* end if */ - } /* end else */ - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_clip_spans() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_merge_spans_helper - PURPOSE - Merge two hyperslab span tree together - USAGE - H5S_hyper_span_info_t *H5S__hyper_merge_spans_helper(a_spans, b_spans) - H5S_hyper_span_info_t *a_spans; IN: First hyperslab spans to merge - together - H5S_hyper_span_info_t *b_spans; IN: Second hyperslab spans to merge - together - RETURNS - Pointer to span tree containing the merged spans on success, NULL on failure - DESCRIPTION - Merge two sets of hyperslab spans together and return the span tree from - the merged set. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5S_hyper_span_info_t * -H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans) -{ - H5S_hyper_span_info_t *merged_spans = NULL; /* Pointer to the merged span tree */ - H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_STATIC - - /* Make certain both 'a' & 'b' spans have down span trees or neither does */ - HDassert((a_spans != NULL && b_spans != NULL) || (a_spans == NULL && b_spans == NULL)); - - /* Check if the span trees for the 'a' span and the 'b' span are the same */ - if(H5S__hyper_cmp_spans(a_spans, b_spans)) { - if(a_spans == NULL) - merged_spans = NULL; - else { - /* Copy one of the span trees to return */ - if(NULL == (merged_spans = H5S__hyper_copy_span(a_spans))) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") - } /* end else */ - } /* end if */ - else { - H5S_hyper_span_t *span_a; /* Pointer to current span 'a' working on */ - H5S_hyper_span_t *span_b; /* Pointer to current span 'b' working on */ - H5S_hyper_span_t *prev_span_merge; /* Pointer to previous merged span */ - hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ - - /* Get the pointers to the 'a' and 'b' span lists */ - span_a = a_spans->head; - span_b = b_spans->head; - - /* Set the pointer to the previous spans */ - prev_span_merge = NULL; - - /* No spans to recover yet */ - recover_a = recover_b = FALSE; - - /* Work through the list of spans in the new list */ - while(span_a != NULL && span_b != NULL) { - H5S_hyper_span_info_t *tmp_spans; /* Pointer to temporary new span tree */ - H5S_hyper_span_t *tmp_span; /* Pointer to temporary new span */ - - /* Check if the 'a' span is completely before 'b' span */ - /* AAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - if(span_a->high < span_b->low) { - /* Merge/add span 'a' with/to the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - } /* end if */ - /* Check if span 'a' overlaps only the lower bound */ - /* of span 'b', up to the upper bound of span 'b' */ - /* AAAAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) { - /* Check if span 'a' and span 'b' down spans are equal */ - if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { - /* Merge/add copy of span 'a' with/to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ - else { - /* Merge/add lower part of span 'a' with/to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - - /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ - - /* Check if there is an upper part of span 'b' */ - if(span_a->high < span_b->high) { - /* Copy upper part of span 'b' as new span 'b' */ - - /* Allocate new span node to append to list */ - if((tmp_span = H5S__hyper_new_span(span_a->high+1,span_b->high,span_b->down,span_b->next))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span") - - /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - - /* Set new span 'b' to tmp_span */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); - recover_b = TRUE; - } /* end if */ - else { - /* Advance both span 'a' & 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end if */ - /* Check if span 'a' overlaps the lower & upper bound */ - /* of span 'b' */ - /* AAAAAAAAAAAAAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low < span_b->low && span_a->high > span_b->high) { - /* Check if span 'a' and span 'b' down spans are equal */ - if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { - /* Merge/add copy of lower & middle parts of span 'a' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ - else { - /* Merge/add lower part of span 'a' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - - /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ - - /* Copy upper part of span 'a' as new span 'a' (remember to free) */ - - /* Allocate new span node to append to list */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - - /* Set new span 'a' to tmp_span */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); - recover_a = TRUE; - - /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end if */ - /* Check if span 'a' is entirely within span 'b' */ - /* AAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if(span_a->low >= span_b->low && span_a->high <= span_b->high) { - /* Check if span 'a' and span 'b' down spans are equal */ - if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { - /* Merge/add copy of lower & middle parts of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ - else { - /* Check if there is a lower part of span 'b' */ - if(span_a->low > span_b->low) { - /* Merge/add lower part of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - } /* end if */ - else { - /* No lower part of span 'b' , keep going... */ - } /* end else */ - - /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - - /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - - /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ - - /* Check if there is an upper part of span 'b' */ - if(span_a->high < span_b->high) { - /* Copy upper part of span 'b' as new span 'b' (remember to free) */ - - /* Allocate new span node to append to list */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - - /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - - /* Set new span 'b' to tmp_span */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); - recover_b = TRUE; - } /* end if */ - else { - /* Advance both spans */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end if */ - /* Check if span 'a' overlaps only the upper bound */ - /* of span 'b' */ - /* AAAAAAAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) { - /* Check if span 'a' and span 'b' down spans are equal */ - if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { - /* Merge/add copy of span 'b' to merged spans if so */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + /* Increment dimension */ + u++; + } /* end else */ + } /* end else */ + } /* end while */ + } /* end if */ + } /* end else */ + + /* If we didn't find a large contiguous block, check for a small one */ + if(!large_contiguous) { + small_contiguous = TRUE; + + /* Get information for slowest changing information */ + spans = space->select.sel_info.hslab->span_lst; + span = spans->head; + + /* Current dimension working on */ + u = 0; + + /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ + while(spans != NULL) { + span = spans->head; + + /* Check that this is the only span and it spans the entire dimension */ + if(span->next != NULL) { + small_contiguous = FALSE; + break; } /* end if */ else { - /* Check if there is a lower part of span 'b' */ - if(span_a->low > span_b->low) { - /* Merge/add lower part of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + /* If this span doesn't cover the entire dimension, then this selection isn't contiguous */ + if(u < (space->extent.rank - 1) && ((span->high-span->low) + 1) != 1) { + small_contiguous = FALSE; + break; } /* end if */ else { - /* No lower part of span 'b' , keep going... */ + /* Walk down to the next span */ + spans = span->down; + + /* Increment dimension */ + u++; } /* end else */ + } /* end else */ + } /* end while */ + } /* end if */ - /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); + /* Indicate true if it's either a large or small contiguous block */ + if(large_contiguous || small_contiguous) + ret_value = TRUE; + } /* end else */ - /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_is_contiguous() */ - /* Release merged span tree for overlapped section */ - H5S__hyper_free_span_info(tmp_spans); - } /* end else */ + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_is_single + PURPOSE + Check if a hyperslab selection is a single block within the dataspace extent. + USAGE + htri_t H5S__hyper_is_single(space) + H5S_t *space; IN: Dataspace pointer to check + RETURNS + TRUE/FALSE/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace is a single block. + This is primarily used for reading the entire selection in one swoop. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5_ATTR_PURE htri_t +H5S__hyper_is_single(const H5S_t *space) +{ + htri_t ret_value = TRUE; /* return value */ - /* Copy upper part of span 'a' as new span 'a' */ + FUNC_ENTER_STATIC_NOERR - /* Allocate new span node to append to list */ - if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + HDassert(space); - /* Set new span 'a' to tmp_span */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); - recover_a = TRUE; + /* Check for a "single" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + unsigned u; /* index variable */ - /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end if */ - /* Span 'a' must be entirely above span 'b' */ - /* AAAAA */ - /* <-----------------------------------> */ - /* BBBBBBBBBB */ - else { - /* Merge/add span 'b' with the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + /* + * For a regular hyperslab to be single, it must have only one + * block (i.e. count==1 in all dimensions) + */ - /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end else */ - } /* end while */ + /* Check for a single block */ + for(u = 0; u < space->extent.rank; u++) + if(space->select.sel_info.hslab->opt_diminfo[u].count > 1) + HGOTO_DONE(FALSE) + } /* end if */ + else { + H5S_hyper_span_info_t *spans; /* Hyperslab span info node */ - /* Clean up 'a' spans which haven't been added to the list of merged spans */ - if(span_a != NULL && span_b == NULL) { - while(span_a != NULL) { - /* Merge/add all 'a' spans into the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + /* + * For a region to be single, it must have only one block + */ + /* Get information for slowest changing information */ + spans = space->select.sel_info.hslab->span_lst; - /* Advance to next 'a' span, until all processed */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - } /* end while */ - } /* end if */ + /* Cycle down the spans until we run out of down spans or find a non-contiguous span */ + while(spans != NULL) { + H5S_hyper_span_t *span; /* Hyperslab span node */ - /* Clean up 'b' spans which haven't been added to the list of merged spans */ - if(span_a == NULL && span_b != NULL) { - while(span_b != NULL) { - /* Merge/add all 'b' spans into the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + span = spans->head; - /* Advance to next 'b' span, until all processed */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end while */ - } /* end if */ + /* Check that this is the only span and it spans the entire dimension */ + if(span->next != NULL) + HGOTO_DONE(FALSE) + else + /* Walk down to the next span */ + spans = span->down; + } /* end while */ } /* end else */ - /* Set return value */ - ret_value = merged_spans; - done: - if(ret_value == NULL) - if(merged_spans && H5S__hyper_free_span_info(merged_spans) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_merge_spans_helper() */ +} /* end H5S__hyper_is_single() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_merge_spans + H5S__hyper_is_regular PURPOSE - Merge new hyperslab spans to existing hyperslab selection + Check if a hyperslab selection is "regular" USAGE - herr_t H5S__hyper_merge_spans(space, new_spans, can_own) - H5S_t *space; IN: Dataspace to add new spans to hyperslab - selection. - H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to - hyperslab selection - hbool_t can_own; IN: Flag to indicate that it is OK to point - directly to the new spans, instead of - copying them. + htri_t H5S__hyper_is_regular(space) + const H5S_t *space; IN: Dataspace pointer to check RETURNS - non-negative on success, negative on failure + TRUE/FALSE/FAIL DESCRIPTION - Add a set of hyperslab spans to an existing hyperslab selection. The - new spans are required to be non-overlapping with the existing spans in - the dataspace's current hyperslab selection. + Checks to see if the current selection in a dataspace is the a regular + pattern. + This is primarily used for reading the entire selection in one swoop. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Doesn't check for "regular" hyperslab selections composed of spans EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t can_own) +static htri_t +H5S__hyper_is_regular(const H5S_t *space) { + htri_t ret_value = FAIL; /* return value */ + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); - HDassert(new_spans); - /* If this is the first span tree in the hyperslab selection, just use it */ - if(space->select.sel_info.hslab->span_lst == NULL) { - if(can_own) - space->select.sel_info.hslab->span_lst = new_spans; - else - space->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(new_spans); - } /* end if */ - else { - H5S_hyper_span_info_t *merged_spans; + /* Only simple check for regular hyperslabs for now... */ + if(space->select.sel_info.hslab->diminfo_valid) + ret_value = TRUE; + else + ret_value = FALSE; - /* Get the merged spans */ - merged_spans = H5S__hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_is_regular() */ - /* Sanity checking since we started with some spans, we should still have some after the merge */ - HDassert(merged_spans); + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_release + PURPOSE + Release hyperslab selection information for a dataspace + USAGE + herr_t H5S__hyper_release(space) + H5S_t *space; IN: Pointer to dataspace + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Releases all hyperslab selection information for a dataspace + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG + * Robb Matzke, 1998-08-25 + * The fields which are freed are set to NULL to prevent them from being + * freed again later. This fixes some allocation problems where + * changing the hyperslab selection of one dataspace causes a core dump + * when closing some other dataspace. +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_release(H5S_t *space) +{ + herr_t ret_value = SUCCEED; - /* Free the previous spans */ - H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + FUNC_ENTER_STATIC - /* Point to the new merged spans */ - space->select.sel_info.hslab->span_lst = merged_spans; - } /* end else */ + /* Check args */ + HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); + + /* Reset the number of points selected */ + space->select.num_elem = 0; + + /* Release irregular hyperslab information */ + if(space->select.sel_info.hslab) { + if(space->select.sel_info.hslab->span_lst != NULL) + if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_merge_spans() */ + /* Release space for the hyperslab selection information */ + space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_release() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_spans_nelem + H5S__hyper_recover_span PURPOSE - Count the number of elements in a span tree + Recover a generated span, if appropriate USAGE - hsize_t H5S__hyper_spans_nelem(spans) - const H5S_hyper_span_info_t *spans; IN: Hyperslan span tree to count elements of + herr_t H5S__hyper_recover_span(recover, curr_span, next_span) + unsigned *recover; IN/OUT: Pointer recover flag + H5S_hyper_span_t **curr_span; IN/OUT: Pointer to current span in list + H5S_hyper_span_t *next_span; IN: Pointer to next span RETURNS - Number of elements in span tree on success; negative on failure + Non-negative on success, negative on failure DESCRIPTION - Counts the number of elements described by the spans in a span tree. + Check if the current span needs to be recovered and free it if so. + Set the current span to the next span in any case. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static hsize_t -H5S__hyper_spans_nelem(const H5S_hyper_span_info_t *spans) +static herr_t +H5S__hyper_recover_span(hbool_t *recover, H5S_hyper_span_t **curr_span, H5S_hyper_span_t *next_span) { - hsize_t ret_value = 0; /* Return value */ - FUNC_ENTER_STATIC_NOERR - /* Count the number of elements in the span tree */ - if(spans != NULL) { - const H5S_hyper_span_t *span; /* Hyperslab span */ + HDassert(recover); + HDassert(curr_span); - span = spans->head; - while(span != NULL) { - /* If there are down spans, multiply the size of this span by the total down span elements */ - if(span->down != NULL) - ret_value += span->nelem * H5S__hyper_spans_nelem(span->down); - /* If there are no down spans, just count the elements in this span */ - else - ret_value += span->nelem; + /* Check if the span should be recovered */ + if(*recover) { + H5S__hyper_free_span(*curr_span); + *recover = FALSE; + } /* end if */ - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end else */ + /* Set the current span to next span */ + *curr_span = next_span; - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_spans_nelem() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5S__hyper_recover_span() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_make_spans + H5S__hyper_coord_to_span PURPOSE - Create a span tree + Create a span tree for a single element USAGE - H5S_hyper_span_t *H5S__hyper_make_spans(rank, start, stride, count, block) - unsigned rank; IN: # of dimensions of the space - const hsize_t *start; IN: Starting location of the hyperslabs - const hsize_t *stride; IN: Stride from the beginning of one block to - the next - const hsize_t *count; IN: Number of blocks - const hsize_t *block; IN: Size of hyperslab block + H5S_hyper_span_t *H5S__hyper_coord_to_span(rank, coords) + unsigned rank; IN: Number of dimensions of coordinate + hsize_t *coords; IN: Location of element RETURNS - Pointer to new span tree on success, NULL on failure + Non-negative on success, negative on failure DESCRIPTION - Generates a new span tree for the hyperslab parameters specified. - Each span tree has a list of the elements spanned in each dimension, with - each span node containing a pointer to the list of spans in the next - dimension down. + Create a span tree for a single element GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5S_hyper_span_info_t * -H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride, - const hsize_t *count, const hsize_t *block) +static H5S_hyper_span_t * +H5S__hyper_coord_to_span(unsigned rank, const hsize_t *coords) { - H5S_hyper_span_info_t *down = NULL; /* Pointer to spans in next dimension down */ - H5S_hyper_span_t *last_span; /* Current position in hyperslab span list */ - H5S_hyper_span_t *head = NULL; /* Head of new hyperslab span list */ - hsize_t stride_iter; /* Iterator over the stride values */ - int i; /* Counters */ - unsigned u; /* Counters */ - H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ + H5S_hyper_span_t *new_span; /* Pointer to new span tree for coordinate */ + H5S_hyper_span_info_t *down = NULL; /* Pointer to new span tree for next level down */ + H5S_hyper_span_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC - /* Check args */ HDassert(rank > 0); - HDassert(start); - HDassert(stride); - HDassert(count); - HDassert(block); - - /* Start creating spans in fastest changing dimension */ - for(i = (int)(rank - 1); i >= 0; i--) { - - /* Sanity check */ - if(0 == count[i]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "count == 0 is invalid") - - /* Start a new list in this dimension */ - head = NULL; - last_span = NULL; - - /* Generate all the span segments for this dimension */ - for(u = 0, stride_iter = 0; u < count[i]; u++, stride_iter += stride[i]) - { - H5S_hyper_span_t *span; /* New hyperslab span */ - - /* Allocate a span node */ - if(NULL == (span = H5FL_MALLOC(H5S_hyper_span_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - - /* Set the span's basic information */ - span->low = start[i] + stride_iter; - span->high = span->low + (block[i] - 1); - span->nelem = block[i]; - span->pstride = stride[i]; - span->next = NULL; - - /* Append to the list of spans in this dimension */ - if(head == NULL) - head = span; - else - last_span->next = span; - - /* Move current pointer */ - last_span = span; - - /* Set the information for the next dimension down's spans, if appropriate */ - if(down != NULL) { - span->down = down; - down->count++; /* Increment reference count for shared span */ - } /* end if */ - else - span->down = NULL; - } /* end for */ + HDassert(coords); + /* Search for location to insert new element in tree */ + if(rank > 1) { /* Allocate a span info node */ if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Keep the pointer to the next dimension down's completed list */ - down->head = head; - } /* end for */ + /* Build span tree for coordinates below this one */ + if(NULL == (down->head = H5S__hyper_coord_to_span(rank - 1, &coords[1]))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + } /* end if */ - /* Indicate that there is a pointer to this tree */ - if(down) - down->count = 1; + /* Build span for this coordinate */ + if(NULL == (new_span = H5S__hyper_new_span(coords[0], coords[0], down, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Success! Return the head of the list in the slowest changing dimension */ - ret_value = down; + /* Set return value */ + ret_value = new_span; done: - /* cleanup if error (ret_value will be NULL) */ - if(!ret_value) { - if(head || down) { - if(head && down) - if(down->head != head) - down = NULL; - - do { - if(down) { - head = down->head; - down = H5FL_FREE(H5S_hyper_span_info_t, down); - } /* end if */ - down = head->down; - - while(head) { - last_span = head->next; - head = H5FL_FREE(H5S_hyper_span_t, head); - head = last_span; - } /* end while */ - } while(down); - } /* end if */ - } /* end if */ + if(ret_value == NULL && down != NULL) + H5S__hyper_free_span_info(down); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_make_spans() */ +} /* end H5S__hyper_coord_to_span() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_rebuild_helper + H5S__hyper_add_span_element_helper PURPOSE - Helper routine to rebuild optimized hyperslab information if possible. - (It can be recovered with regular selection) + Add a single element to a span tree USAGE - herr_t H5S__hyper_rebuild_helper(space) - const H5S_hyper_span_t *span; IN: Portion of span tree to check - H5S_hyper_dim_t span_slab[]; OUT: Rebuilt section of hyperslab description - unsigned rank; IN: Current dimension to work on + herr_t H5S_hyper_add_span_element_helper(prev_span, span_tree, rank, coords) + H5S_hyper_span_info_t *span_tree; IN/OUT: Pointer to span tree to append to + unsigned rank; IN: Number of dimensions of coordinates + hsize_t *coords; IN: Location of element to add to span tree RETURNS - TRUE/FALSE for hyperslab selection rebuilt + Non-negative on success, negative on failure DESCRIPTION - Examine the span tree for a hyperslab selection and rebuild - the start/stride/count/block information for the selection, if possible. + Add a single element to an existing span tree. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - To be able to recover the optimized information, the span tree must conform - to span tree able to be generated from a single H5S_SELECT_SET operation. + Assumes that the element is not already covered by the span tree EXAMPLES REVISION LOG - KY, 2005/9/22 --------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab_info[], - unsigned rank) +static herr_t +H5S__hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, + unsigned rank, const hsize_t *coords) { - hbool_t ret_value = TRUE; /* Return value */ + H5S_hyper_span_info_t *tspan_info; /* Temporary pointer to span info */ + H5S_hyper_span_info_t *prev_span_info; /* Pointer to span info for level above current position */ + H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */ + H5S_hyper_span_t *tmp2_span; /* Another temporary pointer to a span */ + H5S_hyper_span_t *new_span; /* New span created for element */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(span_tree); + HDassert(rank > 0); + HDassert(coords); + + /* Get pointer to last span in span tree */ + tspan_info=span_tree; + if(span_tree->scratch) + tmp_span=(H5S_hyper_span_t *)span_tree->scratch; + else { + tmp_span=span_tree->head; + HDassert(tmp_span); + span_tree->scratch=(H5S_hyper_span_info_t *)tmp_span; + } /* end else */ + + /* Find last span tree which includes a portion of the coordinate */ + prev_span_info=NULL; + while(coords[0]>=tmp_span->low && coords[0]<=tmp_span->high) { + /* Move rank & coordinate offset down a dimension */ + rank--; + coords++; + + /* Remember the span tree we are descending into */ + prev_span_info=tspan_info; + tspan_info=tmp_span->down; + + /* Get the last span in this span's 'down' tree */ + if(tspan_info->scratch) + tmp_span=(H5S_hyper_span_t *)tspan_info->scratch; + else { + tmp_span=tspan_info->head; + HDassert(tmp_span); + tspan_info->scratch=(H5S_hyper_span_info_t *)tmp_span; + } /* end else */ + } /* end while */ - FUNC_ENTER_STATIC_NOERR + /* Check if we made it all the way to the bottom span in the tree */ + if(rank>1) { + /* Before we create another span at this level in the tree, check if + * the last span's "down tree" was equal to any other spans in this + * list of spans in the span tree. + * + * If so, release last span information and make last span merge into + * previous span (if possible), or at least share their "down tree" + * information. + */ + tmp2_span=tspan_info->head; + while(tmp2_span!=tmp_span) { + if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { + /* Check for merging into previous span */ + if(tmp2_span->high+1==tmp_span->low) { + /* Release last span created */ + H5S__hyper_free_span(tmp_span); - if(span) { - const H5S_hyper_span_t *prev_span = NULL; /* Previous span in list */ - H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK]; - hsize_t curr_stride; - hsize_t curr_block; - hsize_t curr_start; - hsize_t curr_low; - size_t outcount; /* Number of spans encountered in this dimension */ + /* Increase size of previous span */ + tmp2_span->high++; + tmp2_span->nelem++; - /* Initialization */ - curr_stride = 1; - curr_low = 0; - outcount = 0; + /* Reset the 'tmp_span' for the rest of this block's algorithm */ + tmp_span=tmp2_span; + } /* end if */ + /* Span is disjoint, but has the same "down tree" selection */ + else { + /* Release "down tree" information */ + H5S__hyper_free_span_info(tmp_span->down); - /* Get "canonical" down span information */ - if(span->down) { - HDassert(span->down->head); + /* Point at earlier span's "down tree" */ + tmp_span->down=tmp2_span->down; - /* Go to the next down span and check whether the selection can be rebuilt */ - if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) - HGOTO_DONE(FALSE) + /* Increment reference count on shared "down tree" */ + tmp_span->down->count++; + } /* end else */ - HDmemcpy(canon_down_span_slab_info, span_slab_info, sizeof(H5S_hyper_dim_t) * rank); - } /* end if */ + /* Found span to merge into, break out now */ + break; + } /* end if */ - /* Assign the initial starting point & block size */ - curr_start = span->low; - curr_block = (span->high - span->low) + 1; + /* Advance to next span to check */ + tmp2_span=tmp2_span->next; + } /* end while */ - /* Loop the spans */ - while(span) { - if(outcount > 0) { - hsize_t next_stride; /* Stride from previous span */ - hsize_t next_block; /* Block size of current span */ + /* Make span tree for current coordinates */ + if(NULL == (new_span = H5S__hyper_coord_to_span(rank, coords))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - /* Check that down spans match current slab info */ - /* (Can skip check if previous span's down pointer is same as current one) */ - if(span->down && (NULL == prev_span || prev_span->down != span->down)) { - H5S_hyper_dim_t *curr_down_span_slab_info; - unsigned u; /* Local index variable */ + /* Add new span tree as span */ + HDassert(tmp_span); + tmp_span->next=new_span; - HDassert(span->down->head); + /* Make scratch pointer point to last span in list */ + HDassert(tspan_info); + tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; - /* Go to the next down span and check whether the selection can be rebuilt.*/ - if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) - HGOTO_DONE(FALSE) + /* Set the proper 'pstride' for new span */ + new_span->pstride=new_span->low-tmp_span->low; + } /* end if */ + else { + /* Does new node adjoin existing node? */ + if(tmp_span->high+1==coords[0]) { + tmp_span->high++; + tmp_span->nelem++; - /* Compare the slab information of the adjacent spans in the down span tree. - We have to compare all the sub-tree slab information with the canon_down_span_slab_info.*/ - for(u = 0; u < rank - 1; u++) { - curr_down_span_slab_info = &span_slab_info[u]; + /* Check if this span tree should now be merged with a level higher in the tree */ + if(prev_span_info!=NULL) { + /* Before we create another span at this level in the tree, check if + * the last span's "down tree" was equal to any other spans in this + * list of spans in the span tree. + * + * If so, release last span information and make last span merge into + * previous span (if possible), or at least share their "down tree" + * information. + */ + tmp2_span=prev_span_info->head; + tmp_span=(H5S_hyper_span_t *)prev_span_info->scratch; + while(tmp2_span!=tmp_span) { + if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { + /* Check for merging into previous span */ + if(tmp2_span->high+1==tmp_span->low) { + /* Release last span created */ + H5S__hyper_free_span(tmp_span); - if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[u].count > 0) { - if(curr_down_span_slab_info->start != canon_down_span_slab_info[u].start - || curr_down_span_slab_info->stride != canon_down_span_slab_info[u].stride - || curr_down_span_slab_info->block != canon_down_span_slab_info[u].block - || curr_down_span_slab_info->count != canon_down_span_slab_info[u].count) - HGOTO_DONE(FALSE) - } /* end if */ - else if(!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0))) - HGOTO_DONE(FALSE) - } /* end for */ - } /* end if */ + /* Increase size of previous span */ + tmp2_span->high++; + tmp2_span->nelem++; - /* Obtain values for stride and block */ - next_stride = span->low - curr_low; - next_block = (span->high - span->low) + 1; + /* Update pointers */ + tmp2_span->next=NULL; + prev_span_info->scratch=(H5S_hyper_span_info_t *)tmp2_span; + } /* end if */ + /* Span is disjoint, but has the same "down tree" selection */ + else { + /* Release "down tree" information */ + H5S__hyper_free_span_info(tmp_span->down); - /* Compare stride and block in this span, to compare stride, - * three spans are needed. Account for the first two spans. - */ - if(next_block != curr_block) - HGOTO_DONE(FALSE) - if(outcount > 1 && curr_stride != next_stride) - HGOTO_DONE(FALSE) + /* Point at earlier span's "down tree" */ + tmp_span->down=tmp2_span->down; - /* Keep the isolated stride to be 1 */ - curr_stride = next_stride; + /* Increment reference count on shared "down tree" */ + tmp_span->down->count++; + } /* end else */ + + /* Found span to merge into, break out now */ + break; + } /* end if */ + + /* Advance to next span to check */ + tmp2_span=tmp2_span->next; + } /* end while */ } /* end if */ + } /* end if */ + else { + if(NULL == (new_span = H5S__hyper_new_span(coords[0], coords[0], NULL, NULL))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - /* Keep current starting point */ - curr_low = span->low; + /* Add new span tree as span */ + HDassert(tmp_span); + tmp_span->next=new_span; - /* Advance to next span */ - prev_span = span; - span = span->next; - outcount++; - } /* end while */ + /* Make scratch pointer point to last span in list */ + tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; - /* Save the span information. */ - span_slab_info[rank - 1].start = curr_start; - span_slab_info[rank - 1].count = outcount; - span_slab_info[rank - 1].block = curr_block; - span_slab_info[rank - 1].stride = curr_stride; - } /* end if */ + /* Set the proper 'pstride' for new span */ + new_span->pstride = new_span->low - tmp_span->low; + } /* end else */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_rebuild_helper() */ +} /* end H5S__hyper_add_span_element_helper() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_rebuild + H5S_hyper_add_span_element PURPOSE - Rebuild optimized hyperslab information if possible. - (It can be recovered with regular selection) + Add a single element to a span tree USAGE - hbool_t H5S__hyper_rebuild(space) - const H5S_t *space; IN: Dataspace to check + herr_t H5S_hyper_add_span_element(space, span_tree, rank, coords) + H5S_t *space; IN/OUT: Pointer to dataspace to add coordinate to + unsigned rank; IN: Number of dimensions of coordinates + hsize_t *coords; IN: Location of element to add to span tree RETURNS - TRUE/FALSE for hyperslab selection rebuilt + Non-negative on success, negative on failure DESCRIPTION - Examine the span tree for a hyperslab selection and rebuild - the start/stride/count/block information for the selection, if possible. + Add a single element to an existing span tree. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - To be able to recover the optimized information, the span tree must conform - to span tree able to be generated from a single H5S_SELECT_SET operation. + Assumes that the element is not already in the dataspace's selection EXAMPLES REVISION LOG - This routine is the optimization of the old version. The previous version - can only detect a singluar selection. This version is general enough to - detect any regular selection. - KY, 2005/9/22 --------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_rebuild(H5S_t *space) +herr_t +H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) { - H5S_hyper_dim_t top_span_slab_info[H5S_MAX_RANK]; - unsigned rank, curr_dim; - hbool_t ret_value = TRUE; /* Return value */ + H5S_hyper_span_info_t *head = NULL; /* Pointer to new head of span tree */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(space); + HDassert(rank > 0); + HDassert(coords); + HDassert(space->extent.rank == rank); + + /* Check if this is the first element in the selection */ + if(NULL == space->select.sel_info.hslab) { + /* Allocate a span info node */ + if(NULL == (head = H5FL_CALLOC(H5S_hyper_span_info_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") + + /* Set the reference count */ + head->count = 1; + + /* Build span tree for this coordinate */ + if(NULL == (head->head = H5S__hyper_coord_to_span(rank, coords))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab spans for coordinate") + + /* Allocate selection info */ + if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab selection") + + /* Set the selection to the new span tree */ + space->select.sel_info.hslab->span_lst = head; - FUNC_ENTER_STATIC_NOERR + /* Set selection type */ + space->select.type = H5S_sel_hyper; - /* Check args */ - HDassert(space); - HDassert(space->select.sel_info.hslab->span_lst); + /* Reset "regular" hyperslab flag */ + space->select.sel_info.hslab->diminfo_valid = FALSE; - /* Check the rank of space */ - rank = space->extent.rank; + /* Set unlim_dim */ + space->select.sel_info.hslab->unlim_dim = -1; - /* Check whether the slab can be rebuilt. Only regular selection can be rebuilt. If yes, fill in correct values.*/ - if(!H5S__hyper_rebuild_helper(space->select.sel_info.hslab->span_lst->head, top_span_slab_info, rank)) { - HGOTO_DONE(FALSE) + /* Set # of elements in selection */ + space->select.num_elem = 1; } /* end if */ else { - H5S_hyper_dim_t *diminfo; - H5S_hyper_dim_t *app_diminfo; - - diminfo = space->select.sel_info.hslab->opt_diminfo; - app_diminfo = space->select.sel_info.hslab->app_diminfo; - - for(curr_dim = 0; curr_dim < rank; curr_dim++) { - - app_diminfo[(rank - curr_dim) - 1].start = diminfo[(rank - curr_dim) - 1].start = top_span_slab_info[curr_dim].start; - app_diminfo[(rank - curr_dim) - 1].stride = diminfo[(rank - curr_dim) - 1].stride = top_span_slab_info[curr_dim].stride; - app_diminfo[(rank - curr_dim) - 1].count = diminfo[(rank - curr_dim) - 1].count = top_span_slab_info[curr_dim].count; - app_diminfo[(rank - curr_dim) - 1].block = diminfo[(rank - curr_dim) - 1].block = top_span_slab_info[curr_dim].block; - - } /* end for */ + if(H5S__hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst, rank, coords) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert coordinate into span tree") - space->select.sel_info.hslab->diminfo_valid = TRUE; + /* Increment # of elements in selection */ + space->select.num_elem++; } /* end else */ done: + if(ret_value < 0) + if(head) + H5S__hyper_free_span_info(head); + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_rebuild() */ +} /* end H5S_hyper_add_span_element() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_generate_spans + H5S_hyper_reset_scratch PURPOSE - Create span tree for a regular hyperslab selection + Reset the scratch information for span tree USAGE - herr_t H5S__hyper_generate_spans(space) - H5S_t *space; IN/OUT: Pointer to dataspace + herr_t H5S_hyper_reset_scratch(space) + H5S_t *space; IN/OUT: Pointer to dataspace to reset scratch pointers RETURNS Non-negative on success, negative on failure DESCRIPTION - Create a span tree representation of a regular hyperslab selection and - add it to the information for the hyperslab selection. + Resets the "scratch" pointers used for various tasks in computing hyperslab + spans. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_generate_spans(H5S_t *space) +herr_t +H5S_hyper_reset_scratch(H5S_t *space) { - hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ - hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ - hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ - hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI(FAIL) HDassert(space); - HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - - /* Get the diminfo */ - for(u = 0; u < space->extent.rank; u++) { - /* Check for unlimited dimension and return error */ - /* These should be able to be converted to assertions once everything - * that calls this function checks for unlimited selections first - * (especially the new hyperslab API) -NAF */ - if(space->select.sel_info.hslab->opt_diminfo[u].count == H5S_UNLIMITED) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited count") - if(space->select.sel_info.hslab->opt_diminfo[u].block == H5S_UNLIMITED) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited block") - - tmp_start[u]=space->select.sel_info.hslab->opt_diminfo[u].start; - tmp_stride[u]=space->select.sel_info.hslab->opt_diminfo[u].stride; - tmp_count[u]=space->select.sel_info.hslab->opt_diminfo[u].count; - tmp_block[u]=space->select.sel_info.hslab->opt_diminfo[u].block; - } /* end for */ - /* Build the hyperslab information also */ - if(H5S__generate_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") + /* Check if there are spans in the span tree */ + if(space->select.sel_info.hslab->span_lst != NULL) + /* Reset the scratch pointers for the next routine which needs them */ + H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_generate_spans() */ +} /* end H5S_hyper_reset_scratch() */ -#ifndef NEW_HYPERSLAB_API -/*------------------------------------------------------------------------- - * Function: H5S__generate_hyperlab - * - * Purpose: Generate hyperslab information from H5S_select_hyperslab() - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, September 12, 2000 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], - const hsize_t stride[], const hsize_t count[], const hsize_t block[]) +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_convert + PURPOSE + Convert a compatible selection to span tree form + USAGE + herr_t H5S_hyper_convert(space) + H5S_t *space; IN/OUT: Pointer to dataspace to convert + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Converts a compatible selection (currently only "all" selections) to the + span-tree form of a hyperslab selection. (Point and "none" selection aren't + currently supported and hyperslab selection always have the span-tree form + available). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_convert(H5S_t *space) { - H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ - H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ - H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ - H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI(FAIL) - /* Check args */ HDassert(space); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); - HDassert(start); - HDassert(stride); - HDassert(count); - HDassert(block); - - /* Generate span tree for new hyperslab information */ - if(NULL == (new_spans = H5S__hyper_make_spans(space->extent.rank, start, stride, count, block))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information") - - /* Generate list of blocks to add/remove based on selection operation */ - if(op==H5S_SELECT_SET) { - /* Add new spans to current selection */ - if(H5S__hyper_merge_spans(space,new_spans,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - - /* Set the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(new_spans); - - /* Indicate that the new_spans are owned */ - new_spans = NULL; - } /* end if */ - else { - hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */ - - /* Generate lists of spans which overlap and don't overlap */ - if(H5S__hyper_clip_spans(space->select.sel_info.hslab->span_lst,new_spans,&a_not_b,&a_and_b,&b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - switch(op) { - case H5S_SELECT_OR: - /* Add any new spans from b_not_a to current selection */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - - /* Update the number of elements in current selection */ - space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Check the type of selection */ + switch(H5S_GET_SELECT_TYPE(space)) { + case H5S_SEL_ALL: /* All elements selected in dataspace */ + /* Convert current "all" selection to "real" hyperslab selection */ + { + const hsize_t *tmp_start; /* Temporary start information */ + const hsize_t *tmp_stride; /* Temporary stride information */ + const hsize_t *tmp_count; /* Temporary count information */ + const hsize_t *tmp_block; /* Temporary block information */ - case H5S_SELECT_AND: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Set up temporary information for the dimensions */ + tmp_start = H5S_hyper_zeros_g; + tmp_stride = tmp_count = H5S_hyper_ones_g; + tmp_block = space->extent.size; - /* Reset the number of items in selection */ - space->select.num_elem=0; + /* Convert to hyperslab selection */ + if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't convert selection") + } /* end case */ + break; - /* Check if there are any overlapped selections */ - if(a_and_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_and_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + case H5S_SEL_HYPERSLABS: /* Hyperslab selection */ + break; - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_and_b); + case H5S_SEL_NONE: /* No elements selected in dataspace */ + case H5S_SEL_POINTS: /* Point selection */ + case H5S_SEL_ERROR: /* Selection error */ + case H5S_SEL_N: /* Selection count */ + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "can't convert to span tree selection") + } /* end switch */ - /* Indicate that the a_and_b spans are owned */ - a_and_b=NULL; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_convert() */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_intersect_block_helper + PURPOSE + Helper routine to detect intersections in span trees + USAGE + hbool_t H5S__hyper_intersect_block_helper(spans, start, end) + H5S_hyper_span_info_t *spans; IN: First span tree to operate with + hsize_t *start; IN: Starting coordinate for block + hsize_t *end; IN: Ending coordinate for block + RETURN + Non-negative (TRUE/FALSE) on success, can't fail + DESCRIPTION + Quickly detect intersections between span tree and block + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static hbool_t +H5S__hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans, + const hsize_t *start, const hsize_t *end) +{ + H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */ + hbool_t ret_value = FALSE; /* Return value */ - case H5S_SELECT_XOR: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + FUNC_ENTER_STATIC_NOERR - /* Reset the number of items in selection */ - space->select.num_elem=0; + /* Sanity check */ + HDassert(spans); + HDassert(start); + HDassert(end); - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_not_b,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Get the span list for spans in this tree */ + curr = spans->head; - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + /* Iterate over the spans in the tree */ + while(curr != NULL) { + /* Check for span entirely before block */ + if(curr->high < *start) + /* Advance to next span in this dimension */ + curr = curr->next; + /* If this span is past the end of the block, then we're done in this dimension */ + else if(curr->low > *end) + HGOTO_DONE(FALSE) + /* block & span overlap */ + else { + if(curr->down == NULL) + HGOTO_DONE(TRUE) + else { + hbool_t status; /* Status from recursive call */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Recursively check spans in next dimension down */ + status = H5S__hyper_intersect_block_helper(curr->down, start + 1, end + 1); - /* Update the number of elements in current selection */ - space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + /* If there is a span intersection in the down dimensions, the span trees overlap */ + if(status == TRUE) + HGOTO_DONE(TRUE); - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* No intersection in down dimensions, advance to next span */ + curr = curr->next; + } /* end else */ + } /* end else */ + } /* end while */ - case H5S_SELECT_NOTB: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Fall through with 'FALSE' return value */ - /* Reset the number of items in selection */ - space->select.num_elem=0; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_intersect_block_helper() */ - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_not_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_intersect_block + PURPOSE + Detect intersections in span trees + USAGE + htri_t H5S_hyper_intersect_block(space, start, end) + H5S_t *space; IN: First dataspace to operate on span tree + hssize_t *start; IN: Starting coordinate for block + hssize_t *end; IN: Ending coordinate for block + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Quickly detect intersections between span tree and block + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end) +{ + htri_t ret_value = FAIL; /* Return value */ - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + FUNC_ENTER_NOAPI(FAIL) - /* Indicate that the a_not_b are owned */ - a_not_b=NULL; + /* Sanity check */ + HDassert(space); + HDassert(start); + HDassert(end); - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Check for 'all' selection, instead of a hyperslab selection */ + /* (Technically, this shouldn't be in the "hyperslab" routines...) */ + if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL) + HGOTO_DONE(TRUE); - case H5S_SELECT_NOTA: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Check that the space selection has a span tree */ + if(NULL == space->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - /* Reset the number of items in selection */ - space->select.num_elem=0; + /* Perform the span-by-span intersection check */ + ret_value = H5S__hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst, start, end); - /* Check if there are any non-overlapped selections */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_intersect_block() */ - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(b_not_a); + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_adjust_u_helper + PURPOSE + Helper routine to adjust offsets in span trees + USAGE + void H5S__hyper_adjust_u_helper(spans, offset) + H5S_hyper_span_info_t *spans; IN: Span tree to operate with + const hsize_t *offset; IN: Offset to subtract + RETURNS + None + DESCRIPTION + Adjust the location of the spans in a span tree by subtracting an offset + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, + const hsize_t *offset) +{ + FUNC_ENTER_STATIC_NOERR - /* Indicate that the b_not_a are owned */ - b_not_a=NULL; + /* Sanity checks */ + HDassert(spans); + HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || + spans->scratch == NULL); + HDassert(offset); - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Check if we've already set this down span tree */ + if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { + H5S_hyper_span_t *span; /* Pointer to current span in span tree */ - case H5S_SELECT_NOOP: - case H5S_SELECT_SET: - case H5S_SELECT_APPEND: - case H5S_SELECT_PREPEND: - case H5S_SELECT_INVALID: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ + /* Set the tree's scratch pointer */ + spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); - /* Check if the resulting hyperslab span tree is empty */ - if(space->select.sel_info.hslab->span_lst==NULL) { - H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + /* Iterate over the spans in tree */ + span = spans->head; + while(span != NULL) { + /* Adjust span offset */ + HDassert(span->low >= *offset); + span->low -= *offset; + span->high -= *offset; - /* Sanity check */ - HDassert(space->select.num_elem == 0); + /* Recursively adjust spans in next dimension down */ + if(span->down != NULL) + H5S__hyper_adjust_u_helper(span->down, offset + 1); - /* Allocate a span info node */ - if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") + /* Advance to next span in this dimension */ + span = span->next; + } /* end while */ + } /* end if */ - /* Set the reference count */ - spans->count=1; + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_adjust_u_helper() */ - /* Reset the scratch pad space */ - spans->scratch=0; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_adjust_u + PURPOSE + Adjust a hyperslab selection by subtracting an offset + USAGE + void H5S__hyper_adjust_u(space,offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hsize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves a hyperslab selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset) +{ + FUNC_ENTER_STATIC_NOERR - /* Set to empty tree */ - spans->head=NULL; + /* Sanity check */ + HDassert(space); + HDassert(offset); - /* Set pointer to empty span tree */ - space->select.sel_info.hslab->span_lst=spans; - } /* end if */ - else { - /* Check if we updated the spans */ - if(updated_spans) { - /* Attempt to rebuild "optimized" start/stride/count/block information. - * from resulting hyperslab span tree - */ - H5S__hyper_rebuild(space); - } /* end if */ - } /* end else */ - } /* end else */ + /* Subtract the offset from the "regular" coordinates, if they exist */ + if(space->select.sel_info.hslab->diminfo_valid) { + unsigned u; /* Local index variable */ -done: - /* Free resources */ - if(a_not_b) - if(H5S__hyper_free_span_info(a_not_b) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(a_and_b) - if(H5S__hyper_free_span_info(a_and_b) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(b_not_a) - if(H5S__hyper_free_span_info(b_not_a) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(new_spans) - if(H5S__hyper_free_span_info(new_spans) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") + for(u = 0; u < space->extent.rank; u++) { + HDassert(space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); + space->select.sel_info.hslab->opt_diminfo[u].start -= offset[u]; + } /* end for */ + } /* end if */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__generate_hyperslab() */ + /* Subtract the offset from the span tree coordinates, if they exist */ + if(space->select.sel_info.hslab->span_lst) { + H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, offset); + + /* Reset the scratch pointers for the next routine which needs them */ + H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_adjust_u() */ /*------------------------------------------------------------------------- - * Function: H5S_select_hyperslab + * Function: H5S__hyper_project_scalar * - * Purpose: Internal version of H5Sselect_hyperslab(). + * Purpose: Projects a single element hyperslab selection into a scalar + * dataspace * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol - * Wednesday, January 10, 2001 + * Sunday, July 18, 2010 * *------------------------------------------------------------------------- */ -herr_t -H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], - const hsize_t *stride, const hsize_t count[], const hsize_t *block) +static herr_t +H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset) { - hsize_t int_stride[H5S_MAX_RANK]; /* Internal storage for stride information */ - hsize_t int_count[H5S_MAX_RANK]; /* Internal storage for count information */ - hsize_t int_block[H5S_MAX_RANK]; /* Internal storage for block information */ - const hsize_t *opt_stride; /* Optimized stride information */ - const hsize_t *opt_count; /* Optimized count information */ - const hsize_t *opt_block; /* Optimized block information */ - int unlim_dim = -1; /* Unlimited dimension in selection, of -1 if none */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); - HDassert(start); - HDassert(count); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); - - /* Point to the correct stride values */ - if(stride == NULL) - stride = H5S_hyper_ones_g; - - /* Point to the correct block values */ - if(block == NULL) - block = H5S_hyper_ones_g; - - /* Check new selection */ - for(u = 0; u < space->extent.rank; u++) { - /* Check for overlapping hyperslab blocks in new selection. */ - if(count[u] > 1 && stride[u] < block[u]) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap") - - /* Detect zero-sized hyperslabs in new selection */ - if(count[u] == 0 || block[u] == 0) { - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - /* Convert to "none" selection */ - if(H5S_select_none(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") - HGOTO_DONE(SUCCEED); - - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays same */ - - case H5S_SELECT_NOOP: - case H5S_SELECT_APPEND: - case H5S_SELECT_PREPEND: - case H5S_SELECT_INVALID: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - } /* end if */ + HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); + HDassert(offset); - /* Check for unlimited dimension */ - if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { - if(unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") - else { - if(count[u] == block[u]) /* Both are H5S_UNLIMITED */ - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") - unlim_dim = (int)u; - } /* end else */ - } /* end if */ - } /* end for */ + /* Check for a "regular" hyperslab selection */ + if(space->select.sel_info.hslab->diminfo_valid) { + const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ + unsigned u; /* Counter */ - /* Optimize hyperslab parameters to merge contiguous blocks, etc. */ - if(stride == H5S_hyper_ones_g && block == H5S_hyper_ones_g) { - /* Point to existing arrays */ - opt_stride = H5S_hyper_ones_g; - opt_count = H5S_hyper_ones_g; - opt_block = count; - } /* end if */ - else { - /* Point to local arrays */ - opt_stride = int_stride; - opt_count = int_count; - opt_block = int_block; + /* Build the table of the initial offset */ for(u = 0; u < space->extent.rank; u++) { - /* contiguous hyperslabs have the block size equal to the stride */ - if((stride[u] == block[u]) && (count[u] != H5S_UNLIMITED)) { - int_count[u] = 1; - int_stride[u] = 1; - if(block[u] == 1) - int_block[u] = count[u]; - else - int_block[u] = block[u] * count[u]; - } /* end if */ - else { - if(count[u] == 1) - int_stride[u] = 1; - else { - HDassert((stride[u] > block[u]) || - ((stride[u] == block[u]) && (count[u] == H5S_UNLIMITED))); - int_stride[u] = stride[u]; - } /* end else */ - int_count[u] = count[u]; - int_block[u] = block[u]; - } /* end else */ + /* Keep the offset for later */ + block[u] = diminfo[u].start; } /* end for */ - } /* end else */ - - /* Check for operating on unlimited selection */ - if((H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS) - && (space->select.sel_info.hslab->unlim_dim >= 0) - && (op != H5S_SELECT_SET)) { - /* Check for invalid operation */ - if(unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") - if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") - HDassert(space->select.sel_info.hslab->diminfo_valid); - - /* Clip unlimited selection to include new selection */ - if(H5S_hyper_clip_unlim(space, - start[space->select.sel_info.hslab->unlim_dim] - + ((opt_count[space->select.sel_info.hslab->unlim_dim] - (hsize_t)1) - * opt_stride[space->select.sel_info.hslab->unlim_dim]) - + opt_block[space->select.sel_info.hslab->unlim_dim]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") - - /* If an empty space was returned it must be "none" */ - HDassert((space->select.num_elem > (hsize_t)0) || (space->select.type->type == H5S_SEL_NONE)); } /* end if */ + else { + const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ + unsigned curr_dim; /* Current dimension being operated on */ - /* Fixup operation for non-hyperslab selections */ - switch(H5S_GET_SELECT_TYPE(space)) { - case H5S_SEL_NONE: /* No elements selected in dataspace */ - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - /* Change "none" selection to hyperslab selection */ - break; - - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - op = H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ - break; - - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays "none" */ - - case H5S_SELECT_NOOP: - case H5S_SELECT_APPEND: - case H5S_SELECT_PREPEND: - case H5S_SELECT_INVALID: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - break; - - case H5S_SEL_ALL: /* All elements selected in dataspace */ - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - /* Change "all" selection to hyperslab selection */ - break; - - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays "all" */ - - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - op = H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ - break; - - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - /* Convert current "all" selection to "real" hyperslab selection */ - /* Then allow operation to proceed */ - { - const hsize_t *tmp_start; /* Temporary start information */ - const hsize_t *tmp_stride; /* Temporary stride information */ - const hsize_t *tmp_count; /* Temporary count information */ - const hsize_t *tmp_block; /* Temporary block information */ - - /* Set up temporary information for the dimensions */ - tmp_start = H5S_hyper_zeros_g; - tmp_stride = tmp_count = H5S_hyper_ones_g; - tmp_block = space->extent.size; - - /* Convert to hyperslab selection */ - if(H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") - } /* end case */ - break; - - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - /* Convert to "none" selection */ - if(H5S_select_none(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") - HGOTO_DONE(SUCCEED); - - case H5S_SELECT_NOOP: - case H5S_SELECT_APPEND: - case H5S_SELECT_PREPEND: - case H5S_SELECT_INVALID: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - break; - - case H5S_SEL_HYPERSLABS: - /* Hyperslab operation on hyperslab selection, OK */ - break; - - case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */ - if(op == H5S_SELECT_SET) /* Allow only "set" operation to proceed */ - break; - /* Else fall through to error */ + /* Advance down selected spans */ + curr = space->select.sel_info.hslab->span_lst->head; + curr_dim = 0; + while(curr) { + /* Sanity check for more than one span */ + HDassert(NULL == curr->next); + HDassert(curr->low == curr->high); - case H5S_SEL_ERROR: - case H5S_SEL_N: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ + /* Save the location of the selection in current dimension */ + block[curr_dim] = curr->low; - if(op == H5S_SELECT_SET) { - /* If we are setting a new selection, remove current selection first */ - if(H5S_SELECT_RELEASE(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + /* Advance down to next dimension */ + curr = curr->down->head; + curr_dim++; + } /* end while */ + } /* end else */ - /* Allocate space for the hyperslab selection information */ - if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Calculate offset of selection in projected buffer */ + *offset = H5VM_array_offset(space->extent.rank, space->extent.size, block); - /* Save the diminfo */ - space->select.num_elem = 1; - for(u = 0; u < space->extent.rank; u++) { - space->select.sel_info.hslab->app_diminfo[u].start = start[u]; - space->select.sel_info.hslab->app_diminfo[u].stride = stride[u]; - space->select.sel_info.hslab->app_diminfo[u].count = count[u]; - space->select.sel_info.hslab->app_diminfo[u].block = block[u]; + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_project_scalar() */ - space->select.sel_info.hslab->opt_diminfo[u].start = start[u]; - space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u]; - space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u]; - space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u]; + +/*------------------------------------------------------------------------- + * Function: H5S__hyper_project_simple_lower + * + * Purpose: Projects a hyperslab selection onto/into a simple dataspace + * of a lower rank + * + * Return: Non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol + * Sunday, July 18, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space) +{ + H5S_hyper_span_info_t *down; /* Pointer to list of spans */ + unsigned curr_dim; /* Current dimension being operated on */ - space->select.num_elem *= (opt_count[u] * opt_block[u]); - } /* end for */ + FUNC_ENTER_STATIC_NOERR - /* Save unlim_dim */ - space->select.sel_info.hslab->unlim_dim = unlim_dim; + /* Check args */ + HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); + HDassert(new_space); + HDassert(new_space->extent.rank < base_space->extent.rank); - /* Indicate that the dimension information is valid */ - space->select.sel_info.hslab->diminfo_valid = TRUE; + /* Walk down the span tree until we reach the selection to project */ + down = base_space->select.sel_info.hslab->span_lst; + curr_dim = 0; + while(down && curr_dim < (base_space->extent.rank - new_space->extent.rank)) { + /* Sanity check */ + HDassert(NULL == down->head->next); - /* Indicate that there's no slab information */ - space->select.sel_info.hslab->span_lst = NULL; + /* Advance down to next dimension */ + down = down->head->down; + curr_dim++; + } /* end while */ + HDassert(down); - /* Handle unlimited selections */ - if(unlim_dim >= 0) { - /* Calculate num_elem_non_unlim */ - space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; - for(u = 0; u < space->extent.rank; u++) - if((int)u != unlim_dim) - space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); + /* Share the underlying hyperslab span information */ + new_space->select.sel_info.hslab->span_lst = down; + new_space->select.sel_info.hslab->span_lst->count++; - /* Set num_elem */ - if(space->select.num_elem != (hsize_t)0) - space->select.num_elem = H5S_UNLIMITED; - } /* end if */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_project_simple_lower() */ - /* Set selection type */ - space->select.type = H5S_sel_hyper; - } /* end if */ - else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) { - /* Sanity check */ - HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); + +/*------------------------------------------------------------------------- + * Function: H5S__hyper_project_simple_higher + * + * Purpose: Projects a hyperslab selection onto/into a simple dataspace + * of a higher rank + * + * Return: Non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol + * Sunday, July 18, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) +{ + H5S_hyper_span_t *prev_span = NULL; /* Pointer to previous list of spans */ + unsigned delta_rank; /* Difference in dataspace ranks */ + unsigned curr_dim; /* Current dimension being operated on */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Handle unlimited selections */ - if(unlim_dim >= 0) { - hsize_t bounds_start[H5S_MAX_RANK]; - hsize_t bounds_end[H5S_MAX_RANK]; - hsize_t tmp_count = opt_count[unlim_dim]; - hsize_t tmp_block = opt_block[unlim_dim]; + FUNC_ENTER_STATIC - /* Check for invalid operation */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") - if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + /* Check args */ + HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); + HDassert(new_space); + HDassert(new_space->extent.rank > base_space->extent.rank); - /* Get bounds of existing selection */ - if(H5S__hyper_bounds(space, bounds_start, bounds_end) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + /* Create nodes until reaching the correct # of dimensions */ + new_space->select.sel_info.hslab->span_lst = NULL; + curr_dim = 0; + delta_rank = (new_space->extent.rank - base_space->extent.rank); + while(curr_dim < delta_rank) { + H5S_hyper_span_info_t *new_span_info; /* Pointer to list of spans */ + H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ - /* Patch count and block to remove unlimited and include the - * existing selection. - */ - H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); - HDassert((tmp_count == 1) || (opt_count != H5S_hyper_ones_g)); - HDassert((tmp_block == 1) || (opt_block != H5S_hyper_ones_g)); - if(opt_count != H5S_hyper_ones_g) { - HDassert(opt_count == int_count); - int_count[unlim_dim] = tmp_count; - } /* end if */ - if(opt_block != H5S_hyper_ones_g) { - HDassert(opt_block == int_block); - int_block[unlim_dim] = tmp_block; - } /* end if */ + /* Allocate a new span_info node */ + if(NULL == (new_span_info = H5FL_CALLOC(H5S_hyper_span_info_t))) { + if(prev_span) + if(H5S__hyper_free_span(prev_span) < 0) + HERROR(H5E_DATASPACE, H5E_CANTFREE, "can't free hyperslab span"); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") } /* end if */ - /* Check if there's no hyperslab span information currently */ - if(NULL == space->select.sel_info.hslab->span_lst) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Check for linking into higher span */ + if(prev_span) + prev_span->down = new_span_info; - /* Indicate that the regular dimensions are no longer valid */ - space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Allocate a new node */ + if(NULL == (new_span = H5S__hyper_new_span((hsize_t)0, (hsize_t)0, NULL, NULL))) { + HDassert(new_span_info); + if(!prev_span) + (void)H5FL_FREE(H5S_hyper_span_info_t, new_span_info); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") + } /* end if */ - /* Set selection type */ - /* (Could be overridden by resetting selection to 'none', below) */ - space->select.type = H5S_sel_hyper; + /* Set the span_info information */ + new_span_info->count = 1; + new_span_info->head = new_span; - /* Add in the new hyperslab information */ - if(H5S__generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + /* Attach to new space, if top span info */ + if(NULL == new_space->select.sel_info.hslab->span_lst) + new_space->select.sel_info.hslab->span_lst = new_span_info; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_hyperslab() */ + /* Remember previous span info */ + prev_span = new_span; - -/*-------------------------------------------------------------------------- - NAME - H5Sselect_hyperslab - PURPOSE - Specify a hyperslab to combine with the current hyperslab selection - USAGE - herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block) - hid_t dsid; IN: Dataspace ID of selection to modify - H5S_seloper_t op; IN: Operation to perform on current selection - const hsize_t *start; IN: Offset of start of hyperslab - const hsize_t *stride; IN: Hyperslab stride - const hsize_t *count; IN: Number of blocks included in hyperslab - const hsize_t *block; IN: Size of block in hyperslab - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Combines a hyperslab selection with the current selection for a dataspace. - If the current selection is not a hyperslab, it is freed and the hyperslab - parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a - selection composing the entire current extent). If STRIDE or BLOCK is - NULL, they are assumed to be set to all '1'. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[], - const hsize_t stride[], const hsize_t count[], const hsize_t block[]) -{ - H5S_t *space; /* Dataspace to modify selection of */ - herr_t ret_value = SUCCEED; /* Return value */ + /* Advance to next dimension */ + curr_dim++; + } /* end while */ + HDassert(new_space->select.sel_info.hslab->span_lst); + HDassert(prev_span); - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iSs*h*h*h*h", space_id, op, start, stride, count, block); + /* Share the underlying hyperslab span information */ + prev_span->down = base_space->select.sel_info.hslab->span_lst; + prev_span->down->count++; - /* Check args */ - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space") - if(H5S_NULL == H5S_GET_EXTENT_TYPE(space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space") - if(start == NULL || count == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified") - if(!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID)) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - if(stride != NULL) { - unsigned u; /* Local index variable */ +done: + if(ret_value < 0 && new_space->select.sel_info.hslab->span_lst) { + if(new_space->select.sel_info.hslab->span_lst->head) + if(H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free hyperslab span") - /* Check for 0-sized strides */ - for(u = 0; u < space->extent.rank; u++) - if(stride[u] == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stride==0 value") + new_space->select.sel_info.hslab->span_lst = H5FL_FREE(H5S_hyper_span_info_t, new_space->select.sel_info.hslab->span_lst); } /* end if */ - if(H5S_select_hyperslab(space, op, start, stride, count, block) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_project_simple_higher() */ -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sselect_hyperslab() */ -#else /* NEW_HYPERSLAB_API */ /* Works */ /*------------------------------------------------------------------------- - * Function: H5S_operate_hyperslab + * Function: H5S__hyper_project_simple * - * Purpose: Combines two hyperslabs with an operation, putting the - * result into a third hyperslab selection + * Purpose: Projects a hyperslab selection onto/into a simple dataspace + * of a different rank * - * Return: non-negative on success/NULL on failure + * Return: Non-negative on success, negative on failure. * * Programmer: Quincey Koziol - * Tuesday, October 30, 2001 - * - * Modifications: + * Sunday, July 18, 2010 * *------------------------------------------------------------------------- */ static herr_t -H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper_t op, H5S_hyper_span_info_t *spans2, - hbool_t can_own_span2, hbool_t *span2_owned) +H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, + hsize_t *offset) { - H5S_hyper_span_info_t *a_not_b=NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ - H5S_hyper_span_info_t *a_and_b=NULL; /* Span tree for hyperslab spans in both old and new span trees */ - H5S_hyper_span_info_t *b_not_a=NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check args */ - HDassert(result); - HDassert(spans2); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); + HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space)); + HDassert(new_space); + HDassert(offset); - /* Just copy the selection from spans2 if we are setting the selection */ - /* ('space1' to 'result' aliasing happens at the next layer up) */ - if(op==H5S_SELECT_SET) { - if(H5S__hyper_merge_spans(result,spans2,can_own_span2)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* We are setting a new selection, remove any current selection in new dataspace */ + if(H5S_SELECT_RELEASE(new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(spans2); + /* Allocate space for the hyperslab selection information */ + if(NULL == (new_space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") - /* Indicate that we took ownership of span2, if allowed */ - if(can_own_span2) - *span2_owned=TRUE; - } /* end if */ - else { - hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */ + /* Set unlim_dim */ + new_space->select.sel_info.hslab->unlim_dim = -1; - HDassert(spans1); + /* Check for a "regular" hyperslab selection */ + if(base_space->select.sel_info.hslab->diminfo_valid) { + unsigned base_space_dim; /* Current dimension in the base dataspace */ + unsigned new_space_dim; /* Current dimension in the new dataspace */ - /* Generate lists of spans which overlap and don't overlap */ - if(H5S__hyper_clip_spans(spans1,spans2,&a_not_b,&a_and_b,&b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") + /* Check if the new space's rank is < or > base space's rank */ + if(new_space->extent.rank < base_space->extent.rank) { + const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ + hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ + unsigned u; /* Local index variable */ - /* Switch on the operation */ - switch(op) { - case H5S_SELECT_OR: - /* Copy spans from spans1 to current selection */ - if(spans1!=NULL) { - if(H5S__hyper_merge_spans(result,spans1,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Compute the offset for the down-projection */ + HDmemset(block, 0, sizeof(block)); + for(u = 0; u < (base_space->extent.rank - new_space->extent.rank); u++) + block[u] = opt_diminfo[u].start; + *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(spans1); - } /* end if */ + /* Set the correct dimensions for the base & new spaces */ + base_space_dim = base_space->extent.rank - new_space->extent.rank; + new_space_dim = 0; + } /* end if */ + else { + HDassert(new_space->extent.rank > base_space->extent.rank); - /* Add any new spans from spans2 to current selection */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(result,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* The offset is zero when projected into higher dimensions */ + *offset = 0; - /* Update the number of elements in current selection */ - result->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + /* Set the diminfo information for the higher dimensions */ + for(new_space_dim = 0; new_space_dim < (new_space->extent.rank - base_space->extent.rank); new_space_dim++) { + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = 0; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = 1; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = 1; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = 1; - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = 0; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = 1; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = 1; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = 1; + } /* end for */ - case H5S_SELECT_AND: - /* Check if there are any overlapped selections */ - if(a_and_b!=NULL) { - if(H5S__hyper_merge_spans(result,a_and_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Start at beginning of base space's dimension info */ + base_space_dim = 0; + } /* end else */ - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(a_and_b); + /* Copy the diminfo */ + while(base_space_dim < base_space->extent.rank) { + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = + base_space->select.sel_info.hslab->app_diminfo[base_space_dim].start; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = + base_space->select.sel_info.hslab->app_diminfo[base_space_dim].stride; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = + base_space->select.sel_info.hslab->app_diminfo[base_space_dim].count; + new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = + base_space->select.sel_info.hslab->app_diminfo[base_space_dim].block; - /* Indicate that the result owns the a_and_b spans */ - a_and_b=NULL; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = + base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].start; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = + base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].stride; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = + base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].count; + new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = + base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].block; - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Advance to next dimensions */ + base_space_dim++; + new_space_dim++; + } /* end for */ - case H5S_SELECT_XOR: - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(result,a_not_b,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Indicate that the dimension information is valid */ + new_space->select.sel_info.hslab->diminfo_valid = TRUE; - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + /* Indicate that there's no slab information */ + new_space->select.sel_info.hslab->span_lst = NULL; + } /* end if */ + else { + /* Check if the new space's rank is < or > base space's rank */ + if(new_space->extent.rank < base_space->extent.rank) { + const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ + hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ + unsigned curr_dim; /* Current dimension being operated on */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(result,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Clear the block buffer */ + HDmemset(block, 0, sizeof(block)); - /* Update the number of elements in current selection */ - result->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + /* Advance down selected spans */ + curr = base_space->select.sel_info.hslab->span_lst->head; + curr_dim = 0; + while(curr && curr_dim < (base_space->extent.rank - new_space->extent.rank)) { + /* Save the location of the selection in current dimension */ + block[curr_dim] = curr->low; - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Advance down to next dimension */ + curr = curr->down->head; + curr_dim++; + } /* end while */ - case H5S_SELECT_NOTB: - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(result,a_not_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Compute the offset for the down-projection */ + *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + /* Project the base space's selection down in less dimensions */ + if(H5S__hyper_project_simple_lower(base_space, new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions") + } /* end if */ + else { + HDassert(new_space->extent.rank > base_space->extent.rank); - /* Indicate that the result owns the a_not_b spans */ - a_not_b=NULL; + /* The offset is zero when projected into higher dimensions */ + *offset = 0; - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Project the base space's selection down in more dimensions */ + if(H5S__hyper_project_simple_higher(base_space, new_space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions") + } /* end else */ - case H5S_SELECT_NOTA: - /* Check if there are any non-overlapped selections */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(result,b_not_a,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Indicate that the dimension information is not valid */ + new_space->select.sel_info.hslab->diminfo_valid = FALSE; + } /* end else */ + + /* Number of elements selected will be the same */ + new_space->select.num_elem = base_space->select.num_elem; + + /* Set selection type */ + new_space->select.type = H5S_sel_hyper; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_project_simple() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_adjust_s_helper + PURPOSE + Helper routine to adjust offsets in span trees + USAGE + void H5S__hyper_adjust_s_helper(spans, offset) + H5S_hyper_span_info_t *spans; IN: Span tree to operate with + const hssize_t *offset; IN: Offset to subtract + RETURNS + None + DESCRIPTION + Adjust the location of the spans in a span tree by subtracting an offset + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, + const hssize_t *offset) +{ + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(spans); + HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || + spans->scratch == NULL); + HDassert(offset); + + /* Check if we've already set this down span tree */ + if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { + H5S_hyper_span_t *span; /* Pointer to current span in span tree */ - /* Update the number of elements in current selection */ - result->select.num_elem = H5S__hyper_spans_nelem(b_not_a); + /* Set the tree's scratch pointer */ + spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); - /* Indicate that the result owns the b_not_a spans */ - b_not_a=NULL; + /* Iterate over the spans in tree */ + span = spans->head; + while(span != NULL) { + /* Adjust span offset */ + HDassert((hssize_t)span->low >= *offset); + span->low = (hsize_t)((hssize_t)span->low - *offset); + span->high = (hsize_t)((hssize_t)span->high - *offset); - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Recursively adjust spans in next dimension down */ + if(span->down != NULL) + H5S__hyper_adjust_s_helper(span->down, offset + 1); - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ + /* Advance to next span in this dimension */ + span = span->next; + } /* end while */ + } /* end if */ - /* Free the hyperslab trees generated from the clipping algorithm */ - if(a_not_b) - H5S__hyper_free_span_info(a_not_b); - if(a_and_b) - H5S__hyper_free_span_info(a_and_b); - if(b_not_a) - H5S__hyper_free_span_info(b_not_a); + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_adjust_s_helper() */ - /* Check if the resulting hyperslab span tree is empty */ - if(result->select.sel_info.hslab->span_lst==NULL) { - H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_adjust_s + PURPOSE + Adjust a hyperslab selection by subtracting an offset + USAGE + herr_t H5S_hyper_adjust_s(space,offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hssize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves a hyperslab selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset) +{ + herr_t ret_value = SUCCEED; /* Return value */ - /* Sanity check */ - HDassert(result->select.num_elem == 0); + FUNC_ENTER_NOAPI(FAIL) - /* Allocate a span info node */ - if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span") + /* Sanity checks */ + HDassert(space); + HDassert(offset); - /* Set the reference count */ - spans->count=1; + /* Subtract the offset from the "regular" coordinates, if they exist */ + if(space->select.sel_info.hslab->diminfo_valid) { + unsigned u; /* Local index variable */ - /* Reset the scratch pad space */ - spans->scratch=0; + for(u = 0; u < space->extent.rank; u++) { + HDassert((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); + space->select.sel_info.hslab->opt_diminfo[u].start = (hsize_t)((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start - offset[u]); + } /* end for */ + } /* end if */ - /* Set to empty tree */ - spans->head=NULL; + /* Subtract the offset from the span tree coordinates, if they exist */ + if(space->select.sel_info.hslab->span_lst) { + H5S__hyper_adjust_s_helper(space->select.sel_info.hslab->span_lst, offset); - /* Set pointer to empty span tree */ - result->select.sel_info.hslab->span_lst=spans; - } /* end if */ - else { - /* Check if we updated the spans */ - if(updated_spans) { - /* Attempt to rebuild "optimized" start/stride/count/block information. - * from resulting hyperslab span tree - */ - H5S__hyper_rebuild(result); - } /* end if */ - } /* end else */ - } /* end else */ + /* Reset the scratch pointers for the next routine which needs them */ + H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_operate_hyperslab() */ +} /* end H5S_hyper_adjust_s() */ -/*------------------------------------------------------------------------- - * Function: H5S_generate_hyperlab - * - * Purpose: Generate hyperslab information from H5S_select_hyperslab() - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol (split from HS_select_hyperslab()). - * Tuesday, September 12, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], - const hsize_t stride[], const hsize_t count[], const hsize_t block[]) +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_normalize_offset + PURPOSE + "Normalize" a hyperslab selection by adjusting it's coordinates by the + amount of the selection offset. + USAGE + htri_t H5S_hyper_normalize_offset(space, old_offset) + H5S_t *space; IN/OUT: Pointer to dataspace to move + hssize_t *old_offset; OUT: Pointer to space to store old offset + RETURNS + TRUE/FALSE for hyperslab selection, FAIL on error + DESCRIPTION + Copies the current selection offset into the array provided, then + inverts the selection offset, subtracts the offset from the hyperslab + selection and resets the offset to zero. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset) { - H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ - H5S_hyper_span_info_t *tmp_spans=NULL; /* Temporary copy of selection */ - hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */ - herr_t ret_value=SUCCEED; /* Return value */ + htri_t ret_value = FALSE; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_NOAPI(FAIL) - /* Check args */ + /* Sanity checks */ HDassert(space); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); - HDassert(start); - HDassert(stride); - HDassert(count); - HDassert(block); + HDassert(old_offset); - /* Generate span tree for new hyperslab information */ - if(NULL == (new_spans = H5S__hyper_make_spans(space->extent.rank, start, stride, count, block))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information") + /* Check for hyperslab selection & offset changed */ + if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS && space->select.offset_changed) { + unsigned u; /* Local index variable */ - /* Copy the original dataspace */ - if(space->select.sel_info.hslab->span_lst!=NULL) { - /* Take ownership of the dataspace's hyperslab spans */ - /* (These are freed later) */ - tmp_spans=space->select.sel_info.hslab->span_lst; - space->select.sel_info.hslab->span_lst=NULL; + /* Copy & invert the selection offset */ + for(u = 0; u < space->extent.rank; u++) { + old_offset[u] = space->select.offset[u]; + space->select.offset[u] = -space->select.offset[u]; + } /* end for */ - /* Reset the other dataspace selection information */ - if(H5S_SELECT_RELEASE(space)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + /* Call the 'adjust' routine */ + if(H5S_hyper_adjust_s(space, space->select.offset) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection") - /* Allocate space for the hyperslab selection information */ - if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Zero out the selection offset */ + HDmemset(space->select.offset, 0, sizeof(hssize_t) * space->extent.rank); - /* Set unlim_dim */ - space->select.sel_info.hslab->unlim_dim = -1; + /* Indicate that the offset was normalized */ + ret_value = TRUE; } /* end if */ - /* Combine tmp_space (really space) & new_space, with the result in space */ - if(H5S_operate_hyperslab(space,tmp_spans,op,new_spans,TRUE,&span2_owned)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - done: - /* Free temporary data structures */ - if(tmp_spans!=NULL) - if(H5S__hyper_free_span_info(tmp_spans)<0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(new_spans!=NULL && span2_owned==FALSE) - if(H5S__hyper_free_span_info(new_spans)<0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__generate_hyperslab() */ +} /* end H5S_hyper_normalize_offset() */ -/*------------------------------------------------------------------------- - * Function: H5S_select_hyperslab - * - * Purpose: Internal version of H5Sselect_hyperslab(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, January 10, 2001 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_denormalize_offset + PURPOSE + "Denormalize" a hyperslab selection by reverse adjusting it's coordinates + by the amount of the former selection offset. + USAGE + herr_t H5S_hyper_denormalize_offset(space, old_offset) + H5S_t *space; IN/OUT: Pointer to dataspace to move + hssize_t *old_offset; IN: Pointer to old offset array + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Subtracts the old offset from the current selection (canceling out the + effect of the "normalize" routine), then restores the old offset into + the dataspace. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ herr_t -H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, - const hsize_t start[], - const hsize_t *stride, - const hsize_t count[], - const hsize_t *block) +H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset) { - hsize_t int_stride[H5S_MAX_RANK]; /* Internal storage for stride information */ - hsize_t int_count[H5S_MAX_RANK]; /* Internal storage for count information */ - hsize_t int_block[H5S_MAX_RANK]; /* Internal storage for block information */ - const hsize_t *opt_stride; /* Optimized stride information */ - const hsize_t *opt_count; /* Optimized count information */ - const hsize_t *opt_block; /* Optimized block information */ - unsigned u; /* Counters */ - int unlim_dim = -1; /* Unlimited dimension in selection, of -1 if none */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Check args */ + /* Sanity checks */ HDassert(space); - HDassert(start); - HDassert(count); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); + HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); + + /* Call the 'adjust' routine */ + if(H5S_hyper_adjust_s(space, old_offset) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection") + + /* Copy the selection offset over */ + HDmemcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_denormalize_offset() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_append_span + PURPOSE + Create a new span and append to span list + USAGE + herr_t H5S__hyper_append_span(prev_span, span_tree, low, high, down, next) + H5S_hyper_span_t **prev_span; IN/OUT: Pointer to previous span in list + H5S_hyper_span_info_t **span_tree; IN/OUT: Pointer to span tree to append to + hsize_t low, high; IN: Low and high bounds for new span node + H5S_hyper_span_info_t *down; IN: Down span tree for new node + H5S_hyper_span_t *next; IN: Next span for new node + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Create a new span node and append to a span list. Update the previous + span in the list also. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_append_span(H5S_hyper_span_t **prev_span, + H5S_hyper_span_info_t **span_tree, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next) +{ + H5S_hyper_span_t *new_span = NULL; + herr_t ret_value = SUCCEED; /* Return value */ - /* Point to the correct stride values */ - if(stride == NULL) - stride = H5S_hyper_ones_g; + FUNC_ENTER_STATIC - /* Point to the correct block values */ - if(block == NULL) - block = H5S_hyper_ones_g; + HDassert(prev_span); + HDassert(span_tree); - /* Check for unlimited dimension */ - for(u = 0; uextent.rank; u++) - if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { - if(unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") - else { - if(count[u] == block[u] /* == H5S_UNLIMITED */) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") - unlim_dim = (int)u; - } /* end else */ - } /* end if */ + /* Check for adding first node to merged spans */ + if(*prev_span == NULL) { + /* Allocate new span node to append to list */ + if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - /* - * Check new selection. - */ - for(u=0; uextent.rank; u++) { - /* Check for overlapping hyperslab blocks in new selection. */ - if(count[u] > 1 && stride[u] < block[u]) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap") + /* Make first node in span list */ - /* Detect zero-sized hyperslabs in new selection */ - if(count[u] == 0 || block[u] == 0) { - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - /* Convert to "none" selection */ - if(H5S_select_none(space)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") - HGOTO_DONE(SUCCEED); + /* Check that we haven't already allocated a span tree */ + HDassert(*span_tree == NULL); - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays same */ + /* Allocate a new span_info node */ + if(NULL == (*span_tree = H5FL_CALLOC(H5S_hyper_span_info_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - } /* end if */ - } /* end for */ + /* Set the span tree's basic information */ + (*span_tree)->count = 1; + (*span_tree)->head = new_span; - /* Optimize hyperslab parameters to merge contiguous blocks, etc. */ - if(stride == H5S_hyper_ones_g && block == H5S_hyper_ones_g) { - /* Point to existing arrays */ - opt_stride = H5S_hyper_ones_g; - opt_count = H5S_hyper_ones_g; - opt_block = count; + /* Update previous merged span */ + *prev_span = new_span; } /* end if */ + /* Merge or append to existing merged spans list */ else { - /* Point to local arrays */ - opt_stride = int_stride; - opt_count = int_count; - opt_block = int_block; - for(u=0; uextent.rank; u++) { - /* contiguous hyperslabs have the block size equal to the stride */ - if((stride[u] == block[u]) && (count[u] != H5S_UNLIMITED)) { - int_count[u]=1; - int_stride[u]=1; - if(block[u]==1) - int_block[u]=count[u]; - else - int_block[u]=block[u]*count[u]; - } /* end if */ - else { - if(count[u]==1) - int_stride[u]=1; - else { - HDassert((stride[u] > block[u]) || ((stride[u] == block[u]) - && (count[u] == H5S_UNLIMITED))); - int_stride[u]=stride[u]; - } /* end else */ - int_count[u]=count[u]; - int_block[u]=block[u]; - } /* end else */ - } /* end for */ - } /* end else */ + /* Check if span can just extend the previous merged span */ + if((((*prev_span)->high + 1) == low) && + H5S__hyper_cmp_spans(down, (*prev_span)->down)==TRUE) { + /* Extend previous merged span to include new high bound */ + (*prev_span)->high = high; + (*prev_span)->nelem += (high - low) + 1; + } /* end if */ + else { + /* Allocate new span node to append to list */ + if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - /* Check for operating on unlimited selection */ - if((H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS) - && (space->select.sel_info.hslab->unlim_dim >= 0) - && (op != H5S_SELECT_SET)) - { - /* Check for invalid operation */ - if(unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") - if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") - HDassert(space->select.sel_info.hslab->diminfo_valid); + /* Check if there is actually a down span */ + if(new_span->down) { + /* Check if the down spans for the new span node are the same as the previous span node */ + if(H5S__hyper_cmp_spans(new_span->down, (*prev_span)->down)) { + /* Release the down span for the new node */ + H5S__hyper_free_span_info(new_span->down); - /* Clip unlimited selection to include new selection */ - if(H5S_hyper_clip_unlim(space, - start[space->select.sel_info.hslab->unlim_dim] - + ((opt_count[space->select.sel_info.hslab->unlim_dim] - - (hsize_t)1) - * opt_stride[space->select.sel_info.hslab->unlim_dim]) - + opt_block[space->select.sel_info.hslab->unlim_dim]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") + /* Point the new node's down span at the previous node's down span */ + new_span->down = (*prev_span)->down; - /* If an empty space was returned it must be "none" */ - HDassert((space->select.num_elem > (hsize_t)0) - || (space->select.type->type == H5S_SEL_NONE)); - } /* end if */ + /* Increment the reference count to the shared down span */ + new_span->down->count++; + } /* end if */ + } /* end if */ - /* Fixup operation for non-hyperslab selections */ - switch(H5S_GET_SELECT_TYPE(space)) { - case H5S_SEL_NONE: /* No elements selected in dataspace */ - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - /* Change "none" selection to hyperslab selection */ - break; + /* Indicate elements from previous span */ + new_span->pstride = low - (*prev_span)->low; - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - op=H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ - break; + /* Append to end of merged spans list */ + (*prev_span)->next = new_span; + *prev_span = new_span; + } /* end else */ + } /* end else */ - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays "none" */ +done: + if(ret_value < 0) + if(new_span && H5S__hyper_free_span(new_span) < 0) + HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span") - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - break; + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_append_span() */ - case H5S_SEL_ALL: /* All elements selected in dataspace */ - switch(op) { - case H5S_SELECT_SET: /* Select "set" operation */ - /* Change "all" selection to hyperslab selection */ - break; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_clip_spans + PURPOSE + Clip a new span tree against the current spans in the hyperslab selection + USAGE + herr_t H5S__hyper_clip_spans(span_a, span_b, a_not_b, a_and_b, b_not_a) + H5S_hyper_span_t *a_spans; IN: Span tree 'a' to clip with. + H5S_hyper_span_t *b_spans; IN: Span tree 'b' to clip with. + H5S_hyper_span_t **a_not_b; OUT: Span tree of 'a' hyperslab spans which + doesn't overlap with 'b' hyperslab + spans. + H5S_hyper_span_t **a_and_b; OUT: Span tree of 'a' hyperslab spans which + overlaps with 'b' hyperslab spans. + H5S_hyper_span_t **b_not_a; OUT: Span tree of 'b' hyperslab spans which + doesn't overlap with 'a' hyperslab + spans. + RETURNS + non-negative on success, negative on failure + DESCRIPTION + Clip one span tree ('a') against another span tree ('b'). Creates span + trees for the area defined by the 'a' span tree which does not overlap the + 'b' span tree ("a not b"), the area defined by the overlap of the 'a' + hyperslab span tree and the 'b' span tree ("a and b"), and the area defined + by the 'b' hyperslab span tree which does not overlap the 'a' span + tree ("b not a"). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans, + H5S_hyper_span_info_t **a_not_b, H5S_hyper_span_info_t **a_and_b, + H5S_hyper_span_info_t **b_not_a) +{ + H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */ + H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */ + H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */ + H5S_hyper_span_t *last_a_not_b; /* Pointer to previous node in span tree 'a_not_b' */ + H5S_hyper_span_t *last_a_and_b; /* Pointer to previous node in span tree 'a_and_b' */ + H5S_hyper_span_t *last_b_not_a; /* Pointer to previous node in span tree 'b_not_a' */ + H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */ + H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */ + H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */ + hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ + herr_t ret_value = SUCCEED; /* Return value */ - case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ - HGOTO_DONE(SUCCEED); /* Selection stays "all" */ + FUNC_ENTER_STATIC - case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ - op=H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ - break; + /* Check args */ + HDassert(a_spans); + HDassert(b_spans); + HDassert(a_not_b); + HDassert(a_and_b); + HDassert(b_not_a); - case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ - case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ - /* Convert current "all" selection to "real" hyperslab selection */ - /* Then allow operation to proceed */ - { - hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ - hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ - hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ - hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ - - /* Fill in temporary information for the dimensions */ - for(u=0; uextent.rank; u++) { - tmp_start[u]=0; - tmp_stride[u]=1; - tmp_count[u]=1; - tmp_block[u]=space->extent.size[u]; - } /* end for */ + /* Check if both span trees are not defined */ + if(a_spans == NULL && b_spans == NULL) { + *a_not_b = NULL; + *a_and_b = NULL; + *b_not_a = NULL; + } /* end if */ + /* If span 'a' is not defined, but 'b' is, copy 'b' and set the other return span trees to empty */ + else if(a_spans == NULL) { + *a_not_b = NULL; + *a_and_b = NULL; + if(NULL == (*b_not_a = H5S__hyper_copy_span(b_spans))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + } /* end if */ + /* If span 'b' is not defined, but 'a' is, copy 'a' and set the other return span trees to empty */ + else if(b_spans == NULL) { + if(NULL == (*a_not_b = H5S__hyper_copy_span(a_spans)) ) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + *a_and_b = NULL; + *b_not_a = NULL; + } /* end if */ + /* If span 'a' and 'b' are both defined, calculate the proper span trees */ + else { + /* Check if both span trees completely overlap */ + if(H5S__hyper_cmp_spans(a_spans, b_spans)) { + *a_not_b = NULL; + if(NULL == (*a_and_b = H5S__hyper_copy_span(a_spans))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + *b_not_a = NULL; + } /* end if */ + else { + /* Get the pointers to the new and old span lists */ + span_a = a_spans->head; + span_b = b_spans->head; - /* Convert to hyperslab selection */ - if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") - } /* end case */ - break; + /* Reset the pointers to the previous spans */ + last_a_not_b = last_a_and_b = last_b_not_a = NULL; + + /* No spans to recover yet */ + recover_a = recover_b = FALSE; - case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ - /* Convert to "none" selection */ - if(H5S_select_none(space)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") - HGOTO_DONE(SUCCEED); + /* Work through the list of spans in the new list */ + while(span_a != NULL && span_b != NULL) { + /* Check if span 'a' is completely before span 'b' */ + /* AAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + if(span_a->high < span_b->low) { + /* Copy span 'a' and add to a_not_b list */ - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - break; + /* Merge/add span 'a' with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, span_a->down, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - case H5S_SEL_HYPERSLABS: - /* Hyperslab operation on hyperslab selection, OK */ - break; + /* Advance span 'a', leave span 'b' */ + H5S__hyper_recover_span(&recover_a, &span_a, span_a->next); + } /* end if */ + /* Check if span 'a' overlaps only the lower bound */ + /* of span 'b' , up to the upper bound of span 'b' */ + /* AAAAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) { + /* Split span 'a' into two parts at the low bound of span 'b' */ - case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */ - if(op==H5S_SELECT_SET) /* Allow only "set" operation to proceed */ - break; - /* Else fall through to error */ + /* Merge/add lower part of span 'a' with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->low - 1, span_a->down, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ + /* Check for overlaps between upper part of span 'a' and lower part of span 'b' */ + /* Make certain both spans either have a down span or both don't have one */ + HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - if(op==H5S_SELECT_SET) { - /* If we are setting a new selection, remove current selection first */ - if(H5S_SELECT_RELEASE(space)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab") + /* If there are no down spans, just add the overlapping area to the a_and_b list */ + if(span_a->down == NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_a->high, NULL, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + /* If there are down spans, check for the overlap in them and add to each appropriate list */ + else { + /* NULL out the temporary pointers to clipped areas in down spans */ + down_a_not_b = NULL; + down_a_and_b = NULL; + down_b_not_a = NULL; - /* Allocate space for the hyperslab selection information */ - if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ + if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - /* Save the diminfo */ - space->select.num_elem=1; - for(u=0; uextent.rank; u++) { - space->select.sel_info.hslab->app_diminfo[u].start = start[u]; - space->select.sel_info.hslab->app_diminfo[u].stride = stride[u]; - space->select.sel_info.hslab->app_diminfo[u].count = count[u]; - space->select.sel_info.hslab->app_diminfo[u].block = block[u]; + /* Check for additions to the a_not_b list */ + if(down_a_not_b) { + /* Merge/add overlapped part with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_a->high,down_a_not_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - space->select.sel_info.hslab->opt_diminfo[u].start = start[u]; - space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u]; - space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u]; - space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u]; + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_not_b); + } /* end if */ - space->select.num_elem*=(opt_count[u]*opt_block[u]); - } /* end for */ + /* Check for additions to the a_and_b list */ + if(down_a_and_b) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_a->high,down_a_and_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Save unlim_dim */ - space->select.sel_info.hslab->unlim_dim = unlim_dim; + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_and_b); + } /* end if */ - /* Indicate that the dimension information is valid */ - space->select.sel_info.hslab->diminfo_valid = TRUE; + /* Check for additions to the b_not_a list */ + if(down_b_not_a) { + /* Merge/add overlapped part with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->high,down_b_not_a,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Indicate that there's no slab information */ - space->select.sel_info.hslab->span_lst = NULL; + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_b_not_a); + } /* end if */ + } /* end else */ - /* Handle unlimited selections */ - if(unlim_dim >= 0) { - /* Calculate num_elem_non_unlim */ - space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; - for(u = 0; u < space->extent.rank; u++) - if((int)u != unlim_dim) - space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); + /* Split off upper part of span 'b' at upper span of span 'a' */ - /* Set num_elem */ - if(space->select.num_elem != (hsize_t)0) - space->select.num_elem = H5S_UNLIMITED; - } /* end if */ - } /* end if */ - else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) { - /* Sanity check */ - HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); + /* Check if there is actually an upper part of span 'b' to split off */ + if(span_a->high < span_b->high) { + /* Allocate new span node for upper part of span 'b' */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - /* Handle unlimited selections */ - if(unlim_dim >= 0) { - hsize_t bounds_start[H5S_MAX_RANK]; - hsize_t bounds_end[H5S_MAX_RANK]; - hsize_t tmp_count = opt_count[unlim_dim]; - hsize_t tmp_block = opt_block[unlim_dim]; + /* Advance span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - /* Check for invalid operation */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") - if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + /* Make upper part of span 'b' into new span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + recover_b = TRUE; + } /* end if */ + /* No upper part of span 'b' to split */ + else { + /* Advance both 'a' and 'b' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end else */ + } /* end if */ + /* Check if span 'a' overlaps the lower & upper bound */ + /* of span 'b' */ + /* AAAAAAAAAAAAAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low < span_b->low && span_a->high > span_b->high) { + /* Split off lower part of span 'a' at lower span of span 'b' */ - /* Get bounds of existing selection */ - if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + /* Merge/add lower part of span 'a' with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Patch count and block to remove unlimited and include the - * existing selection */ - H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); - HDassert((tmp_count == 1) || (opt_count != H5S_hyper_ones_g)); - HDassert((tmp_block == 1) || (opt_block != H5S_hyper_ones_g)); - if(opt_count != H5S_hyper_ones_g) { - HDassert(opt_count == int_count); - int_count[unlim_dim] = tmp_count; - } /* end if */ - if(opt_block != H5S_hyper_ones_g) { - HDassert(opt_block == int_block); - int_block[unlim_dim] = tmp_block; - } /* end if */ - } /* end if */ + /* Check for overlaps between middle part of span 'a' and span 'b' */ - /* Check if there's no hyperslab span information currently */ - if(NULL == space->select.sel_info.hslab->span_lst) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Make certain both spans either have a down span or both don't have one */ + HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - /* Indicate that the regular dimensions are no longer valid */ - space->select.sel_info.hslab->diminfo_valid = FALSE; + /* If there are no down spans, just add the overlapping area to the a_and_b list */ + if(span_a->down == NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,NULL,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + /* If there are down spans, check for the overlap in them and add to each appropriate list */ + else { + /* NULL out the temporary pointers to clipped areas in down spans */ + down_a_not_b = NULL; + down_a_and_b = NULL; + down_b_not_a = NULL; - /* Add in the new hyperslab information */ - if(H5S__generate_hyperslab (space, op, start, opt_stride, opt_count, opt_block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ + if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - /* Set selection type */ - space->select.type = H5S_sel_hyper; + /* Check for additions to the a_not_b list */ + if(down_a_not_b) { + /* Merge/add overlapped part with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_b->high,down_a_not_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_hyperslab() */ + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_not_b); + } /* end if */ - -/*-------------------------------------------------------------------------- - NAME - H5Sselect_hyperslab - PURPOSE - Specify a hyperslab to combine with the current hyperslab selection - USAGE - herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block) - hid_t dsid; IN: Dataspace ID of selection to modify - H5S_seloper_t op; IN: Operation to perform on current selection - const hsize_t *start; IN: Offset of start of hyperslab - const hsize_t *stride; IN: Hyperslab stride - const hsize_t *count; IN: Number of blocks included in hyperslab - const hsize_t *block; IN: Size of block in hyperslab - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - Combines a hyperslab selection with the current selection for a dataspace. - If the current selection is not a hyperslab, it is freed and the hyperslab - parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a - selection composing the entire current extent). If STRIDE or BLOCK is - NULL, they are assumed to be set to all '1'. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[], - const hsize_t stride[], const hsize_t count[], const hsize_t block[]) -{ - H5S_t *space = NULL; /* Dataspace to modify selection of */ - herr_t ret_value=SUCCEED; /* Return value */ + /* Check for additions to the a_and_b list */ + if(down_a_and_b) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,down_a_and_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iSs*h*h*h*h", space_id, op, start, stride, count, block); + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_and_b); + } /* end if */ + + /* Check for additions to the b_not_a list */ + if(down_b_not_a) { + /* Merge/add overlapped part with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,down_b_not_a,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Check args */ - if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if (H5S_SCALAR==H5S_GET_EXTENT_TYPE(space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space") - if (H5S_NULL==H5S_GET_EXTENT_TYPE(space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space") - if(start==NULL || count==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified") - if(!(op>H5S_SELECT_NOOP && opextent.rank; u++) { - if(stride[u]==0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stride==0 value") - } /* end for */ - } /* end if */ + /* Split off upper part of span 'a' at upper span of span 'b' */ - if (H5S_select_hyperslab(space, op, start, stride, count, block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + /* Allocate new span node for upper part of span 'a' */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sselect_hyperslab() */ + /* Make upper part of span 'a' the new span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + recover_a = TRUE; - -/*-------------------------------------------------------------------------- - NAME - H5Scombine_hyperslab - PURPOSE - Specify a hyperslab to combine with the current hyperslab selection and - return a new dataspace with the combined selection as the selection in the - new dataspace. - USAGE - hid_t H5Srefine_hyperslab(dsid, op, start, stride, count, block) - hid_t dsid; IN: Dataspace ID of selection to use - H5S_seloper_t op; IN: Operation to perform on current selection - const hsize_t *start; IN: Offset of start of hyperslab - const hsize_t *stride; IN: Hyperslab stride - const hsize_t *count; IN: Number of blocks included in hyperslab - const hsize_t *block; IN: Size of block in hyperslab - RETURNS - Dataspace ID on success/Negative on failure - DESCRIPTION - Combines a hyperslab selection with the current selection for a dataspace, - creating a new dataspace to return the generated selection. - If the current selection is not a hyperslab, it is freed and the hyperslab - parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a - selection composing the entire current extent). If STRIDE or BLOCK is - NULL, they are assumed to be set to all '1'. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hid_t -H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[], - const hsize_t stride[], const hsize_t count[], const hsize_t block[]) -{ - H5S_t *space; /* Dataspace to modify selection of */ - H5S_t *new_space = NULL; /* New dataspace created */ - hid_t ret_value; /* Return value */ + /* Advance span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end if */ + /* Check if span 'a' is entirely within span 'b' */ + /* AAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low >= span_b->low && span_a->high <= span_b->high) { + /* Split off lower part of span 'b' at lower span of span 'a' */ - FUNC_ENTER_API(FAIL) - H5TRACE6("i", "iSs*h*h*h*h", space_id, op, start, stride, count, block); + /* Check if there is actually a lower part of span 'b' to split off */ + if(span_a->low > span_b->low) { + /* Merge/add lower part of span 'b' with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Keep going, nothing to split off */ + } /* end else */ - /* Check args */ - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(start == NULL || count == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified") - if(!(op >= H5S_SELECT_SET && op <= H5S_SELECT_NOTA)) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + /* Check for overlaps between span 'a' and midle of span 'b' */ - /* Copy the first dataspace */ - if (NULL == (new_space = H5S_copy (space, TRUE, TRUE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy dataspace") + /* Make certain both spans either have a down span or both don't have one */ + HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - /* Go modify the selection in the new dataspace */ - if (H5S_select_hyperslab(new_space, op, start, stride, count, block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + /* If there are no down spans, just add the overlapping area to the a_and_b list */ + if(span_a->down == NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,NULL,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + /* If there are down spans, check for the overlap in them and add to each appropriate list */ + else { + /* NULL out the temporary pointers to clipped areas in down spans */ + down_a_not_b = NULL; + down_a_and_b = NULL; + down_b_not_a = NULL; - /* Atomize */ - if((ret_value = H5I_register(H5I_DATASPACE, new_space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ + if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") -done: - if(ret_value < 0 && new_space) - H5S_close(new_space); + /* Check for additions to the a_not_b list */ + if(down_a_not_b) { + /* Merge/add overlapped part with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,down_a_not_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - FUNC_LEAVE_API(ret_value) -} /* end H5Scombine_hyperslab() */ + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_not_b); + } /* end if */ - -/*------------------------------------------------------------------------- - * Function: H5S__combine_select - * - * Purpose: Internal version of H5Scombine_select(). - * - * Return: New dataspace on success/NULL on failure - * - * Programmer: Quincey Koziol - * Tuesday, October 30, 2001 - * - *------------------------------------------------------------------------- - */ -static H5S_t * -H5S__combine_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2) -{ - H5S_t *new_space = NULL; /* New dataspace generated */ - hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */ - H5S_t *ret_value; /* return value */ + /* Check for additions to the a_and_b list */ + if(down_a_and_b!=NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,down_a_and_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - FUNC_ENTER_STATIC + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_and_b); + } /* end if */ - /* Check args */ - HDassert(space1); - HDassert(space2); - HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA); + /* Check for additions to the b_not_a list */ + if(down_b_not_a!=NULL) { + /* Merge/add overlapped part with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_a->high,down_b_not_a,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Check that the space selections both have span trees */ - if(space1->select.sel_info.hslab->span_lst==NULL) - if(H5S__hyper_generate_spans(space1)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, NULL, "dataspace does not have span tree") - if(space2->select.sel_info.hslab->span_lst==NULL) - if(H5S__hyper_generate_spans(space2)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, NULL, "dataspace does not have span tree") + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_b_not_a); + } /* end if */ + } /* end else */ - /* Copy the first dataspace */ - if (NULL == (new_space = H5S_copy (space1, TRUE, TRUE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy dataspace") + /* Check if there is actually an upper part of span 'b' to split off */ + if(span_a->high < span_b->high) { + /* Split off upper part of span 'b' at upper span of span 'a' */ - /* Free the current selection for the new dataspace */ - if(H5S_SELECT_RELEASE(new_space)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, NULL, "can't release selection") + /* Allocate new span node for upper part of spans 'a' */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - /* Allocate space for the hyperslab selection information */ - if((new_space->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab info") + /* And advance span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - /* Set unlim_dim */ - new_space->select.sel_info.hslab->unlim_dim = -1; + /* Make upper part of span 'b' the new span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + recover_b=1; + } /* end if */ + else { + /* Advance both span 'a' & span 'b' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end else */ + } /* end if */ + /* Check if span 'a' overlaps only the upper bound */ + /* of span 'b' */ + /* AAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) { + /* Check if there is actually a lower part of span 'b' to split off */ + if(span_a->low > span_b->low) { + /* Split off lower part of span 'b' at lower span of span 'a' */ - /* Combine space1 & space2, with the result in new_space */ - if(H5S_operate_hyperslab(new_space,space1->select.sel_info.hslab->span_lst,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, NULL, "can't clip hyperslab information") + /* Merge/add lower part of span 'b' with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Keep going, nothing to split off */ + } /* end else */ - /* Set return value */ - ret_value = new_space; + /* Check for overlaps between lower part of span 'a' and upper part of span 'b' */ -done: - if(ret_value == NULL && new_space) - H5S_close(new_space); + /* Make certain both spans either have a down span or both don't have one */ + HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL)); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__combine_select() */ + /* If there are no down spans, just add the overlapping area to the a_and_b list */ + if(span_a->down == NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,NULL,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + } /* end if */ + /* If there are down spans, check for the overlap in them and add to each appropriate list */ + else { + /* NULL out the temporary pointers to clipped areas in down spans */ + down_a_not_b = NULL; + down_a_and_b = NULL; + down_b_not_a = NULL; - -/*-------------------------------------------------------------------------- - NAME - H5Scombine_select - PURPOSE - Combine two hyperslab selections with an operation, returning a dataspace - with the resulting selection. - USAGE - hid_t H5Scombine_select(space1, op, space2) - hid_t space1; IN: First Dataspace ID - H5S_seloper_t op; IN: Selection operation - hid_t space2; IN: Second Dataspace ID - RETURNS - Dataspace ID on success/Negative on failure - DESCRIPTION - Combine two existing hyperslab selections with an operation, returning - a new dataspace with the resulting selection. The dataspace extent from - space1 is copied for the dataspace extent of the newly created dataspace. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -hid_t -H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id) -{ - H5S_t *space1; /* First Dataspace */ - H5S_t *space2; /* Second Dataspace */ - H5S_t *new_space = NULL; /* New Dataspace */ - hid_t ret_value; /* Return value */ + /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ + if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - FUNC_ENTER_API(FAIL) - H5TRACE3("i", "iSsi", space1_id, op, space2_id); + /* Check for additions to the a_not_b list */ + if(down_a_not_b) { + /* Merge/add overlapped part with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->high,down_a_not_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Check args */ - if(NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(!(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA)) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_not_b); + } /* end if */ - /* Check that both dataspaces have the same rank */ - if(space1->extent.rank != space2->extent.rank) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same rank") + /* Check for additions to the a_and_b list */ + if(down_a_and_b!=NULL) { + /* Merge/add overlapped part with/to a_and_b list */ + if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,down_a_and_b,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Check that both dataspaces have hyperslab selections */ - if(H5S_GET_SELECT_TYPE(space1) != H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2) != H5S_SEL_HYPERSLABS) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces don't have hyperslab selections") + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_a_and_b); + } /* end if */ - /* Go combine the dataspaces */ - if(NULL == (new_space = H5S__combine_select(space1, op, space2))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to create hyperslab selection") + /* Check for additions to the b_not_a list */ + if(down_b_not_a) { + /* Merge/add overlapped part with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_b->high,down_b_not_a,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Atomize */ - if((ret_value = H5I_register(H5I_DATASPACE, new_space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + /* Release the down span tree generated */ + H5S__hyper_free_span_info(down_b_not_a); + } /* end if */ + } /* end else */ -done: - if(ret_value < 0 && new_space) - H5S_close(new_space); + /* Split off upper part of span 'a' at upper span of span 'b' */ - FUNC_LEAVE_API(ret_value) -} /* end H5Scombine_select() */ + /* Allocate new span node for upper part of span 'a' */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - -/*------------------------------------------------------------------------- - * Function: H5S_select_select - * - * Purpose: Internal version of H5Sselect_select(). - * - * Return: New dataspace on success/NULL on failure - * - * Programmer: Quincey Koziol - * Tuesday, October 30, 2001 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) -{ - H5S_hyper_span_info_t *tmp_spans=NULL; /* Temporary copy of selection */ - hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */ - herr_t ret_value=SUCCEED; /* Return value */ + /* Make upper part of span 'a' into new span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + recover_a=1; - FUNC_ENTER_NOAPI_NOINIT + /* Advance span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end if */ + /* span 'a' must be entirely above span 'b' */ + /* AAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else { + /* Copy span 'b' and add to b_not_a list */ - /* Check args */ - HDassert(space1); - HDassert(space2); - HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); + /* Merge/add span 'b' with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Check that the space selections both have span trees */ - if(space1->select.sel_info.hslab->span_lst==NULL) - if(H5S__hyper_generate_spans(space1)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - if(space2->select.sel_info.hslab->span_lst==NULL) - if(H5S__hyper_generate_spans(space2)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Advance span 'b', leave span 'a' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end else */ + } /* end while */ - /* Take ownership of the dataspace's hyperslab spans */ - /* (These are freed later) */ - tmp_spans=space1->select.sel_info.hslab->span_lst; - space1->select.sel_info.hslab->span_lst=NULL; + /* Clean up 'a' spans which haven't been covered yet */ + if(span_a != NULL && span_b == NULL) { + while(span_a != NULL) { + /* Copy span 'a' and add to a_not_b list */ - /* Reset the other dataspace selection information */ - if(H5S_SELECT_RELEASE(space1)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") + /* Merge/add span 'a' with/to a_not_b list */ + if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Allocate space for the hyperslab selection information */ - if((space1->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") + /* Advance to the next 'a' span */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + } /* end while */ + } /* end if */ + /* Clean up 'b' spans which haven't been covered yet */ + else if(span_a == NULL && span_b != NULL) { + while(span_b != NULL) { + /* Copy span 'b' and add to b_not_a list */ - /* Set unlim_dim */ - space1->select.sel_info.hslab->unlim_dim = -1; + /* Merge/add span 'b' with/to b_not_a list */ + if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Combine tmp_spans (from space1) & spans from space2, with the result in space1 */ - if(H5S_operate_hyperslab(space1,tmp_spans,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") + /* Advance to the next 'b' span */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end while */ + } /* end if */ + } /* end else */ + } /* end else */ done: - if(tmp_spans!=NULL) - H5S__hyper_free_span_info(tmp_spans); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_select() */ +} /* end H5S__hyper_clip_spans() */ /*-------------------------------------------------------------------------- NAME - H5Sselect_select + H5S__hyper_merge_spans_helper PURPOSE - Refine a hyperslab selection with an operation using a second hyperslab - to modify it. + Merge two hyperslab span tree together USAGE - herr_t H5Sselect_select(space1, op, space2) - hid_t space1; IN/OUT: First Dataspace ID - H5S_seloper_t op; IN: Selection operation - hid_t space2; IN: Second Dataspace ID + H5S_hyper_span_info_t *H5S__hyper_merge_spans_helper(a_spans, b_spans) + H5S_hyper_span_info_t *a_spans; IN: First hyperslab spans to merge + together + H5S_hyper_span_info_t *b_spans; IN: Second hyperslab spans to merge + together RETURNS - Non-negative on success/Negative on failure + Pointer to span tree containing the merged spans on success, NULL on failure DESCRIPTION - Refine an existing hyperslab selection with an operation, using a second - hyperslab. The first selection is modified to contain the result of - space1 operated on by space2. + Merge two sets of hyperslab spans together and return the span tree from + the merged set. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5Sselect_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id) +static H5S_hyper_span_info_t * +H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans) { - H5S_t *space1; /* First Dataspace */ - H5S_t *space2; /* Second Dataspace */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE3("e", "iSsi", space1_id, op, space2_id); - - /* Check args */ - if(NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(!(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA)) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - - /* Check that both dataspaces have the same rank */ - if(space1->extent.rank != space2->extent.rank) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same rank") + H5S_hyper_span_info_t *merged_spans = NULL; /* Pointer to the merged span tree */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ - /* Check that both dataspaces have hyperslab selections */ - if(H5S_GET_SELECT_TYPE(space1) != H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2) != H5S_SEL_HYPERSLABS) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces don't have hyperslab selections") + FUNC_ENTER_STATIC - /* Go refine the first selection */ - if(H5S_select_select(space1, op, space2) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to modify hyperslab selection") + /* Make certain both 'a' & 'b' spans have down span trees or neither does */ + HDassert((a_spans != NULL && b_spans != NULL) || (a_spans == NULL && b_spans == NULL)); -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Sselect_select() */ -#endif /* NEW_HYPERSLAB_API */ /* Works */ + /* Check if the span trees for the 'a' span and the 'b' span are the same */ + if(H5S__hyper_cmp_spans(a_spans, b_spans)) { + if(a_spans == NULL) + merged_spans = NULL; + else { + /* Copy one of the span trees to return */ + if(NULL == (merged_spans = H5S__hyper_copy_span(a_spans))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") + } /* end else */ + } /* end if */ + else { + H5S_hyper_span_t *span_a; /* Pointer to current span 'a' working on */ + H5S_hyper_span_t *span_b; /* Pointer to current span 'b' working on */ + H5S_hyper_span_t *prev_span_merge; /* Pointer to previous merged span */ + hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_get_seq_list_gen - PURPOSE - Create a list of offsets & lengths for a selection - USAGE - herr_t H5S_select_hyper_get_file_list_gen(space,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) -{ - H5S_hyper_span_t *curr_span; /* Current hyperslab span node */ - H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */ - hsize_t slab[H5S_MAX_RANK]; /* Cumulative size of each dimension in bytes */ - hsize_t acc; /* Accumulator for computing cumulative sizes */ - hsize_t loc_off; /* Element offset in the dataspace */ - hsize_t last_span_end = 0; /* The offset of the end of the last span */ - hsize_t *abs_arr; /* Absolute hyperslab span position */ - const hssize_t *off_arr; /* Offset within the dataspace extent */ - size_t span_size = 0; /* Number of bytes in current span to actually process */ - size_t io_left; /* Number of elements left to process */ - size_t io_bytes_left; /* Number of bytes left to process */ - size_t io_used; /* Number of elements processed */ - size_t curr_seq = 0; /* Number of sequence/offsets stored in the arrays */ - size_t elem_size; /* Size of each element iterating over */ - unsigned ndims; /* Number of dimensions of dataset */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - int curr_dim; /* Current dimension being operated on */ - unsigned u; /* Index variable */ - int i; /* Index variable */ + /* Get the pointers to the 'a' and 'b' span lists */ + span_a = a_spans->head; + span_b = b_spans->head; - FUNC_ENTER_STATIC_NOERR + /* Set the pointer to the previous spans */ + prev_span_merge = NULL; - /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); + /* No spans to recover yet */ + recover_a = recover_b = FALSE; - /* Set the rank of the fastest changing dimension */ - ndims = space->extent.rank; - fast_dim = (ndims - 1); + /* Work through the list of spans in the new list */ + while(span_a != NULL && span_b != NULL) { + H5S_hyper_span_info_t *tmp_spans; /* Pointer to temporary new span tree */ + H5S_hyper_span_t *tmp_span; /* Pointer to temporary new span */ - /* Get the pointers to the current span info and span nodes */ - curr_span = iter->u.hyp.span[fast_dim]; - abs_arr = iter->u.hyp.off; - off_arr = space->select.offset; - ispan = iter->u.hyp.span; - elem_size = iter->elmt_size; + /* Check if the 'a' span is completely before 'b' span */ + /* AAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + if(span_a->high < span_b->low) { + /* Merge/add span 'a' with/to the merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Set the amount of elements to perform I/O on, etc. */ - H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - io_left = MIN(maxelem, (size_t)iter->elmt_left); - io_bytes_left = io_left * elem_size; + /* Advance span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + } /* end if */ + /* Check if span 'a' overlaps only the lower bound */ + /* of span 'b', up to the upper bound of span 'b' */ + /* AAAAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) { + /* Check if span 'a' and span 'b' down spans are equal */ + if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { + /* Merge/add copy of span 'a' with/to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Merge/add lower part of span 'a' with/to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Compute the cumulative size of dataspace dimensions */ - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= space->extent.size[i]; - } /* end for */ + /* Get merged span tree for overlapped section */ + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - /* Set the offset of the first element iterated on */ - for(u = 0, loc_off = 0; u < ndims; u++) - /* Compute the sequential element offset */ - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + /* Merge/add overlapped section to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,tmp_spans,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Range check against number of elements left in selection */ - HDassert(io_bytes_left <= (iter->elmt_left * elem_size)); + /* Release merged span tree for overlapped section */ + H5S__hyper_free_span_info(tmp_spans); + } /* end else */ - /* Take care of any partial spans leftover from previous I/Os */ - if(abs_arr[fast_dim]!=curr_span->low) { + /* Check if there is an upper part of span 'b' */ + if(span_a->high < span_b->high) { + /* Copy upper part of span 'b' as new span 'b' */ - /* Finish the span in the fastest changing dimension */ + /* Allocate new span node to append to list */ + if((tmp_span = H5S__hyper_new_span(span_a->high+1,span_b->high,span_b->down,span_b->next))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span") - /* Compute the number of bytes to attempt in this span */ - H5_CHECKED_ASSIGN(span_size, size_t, ((curr_span->high-abs_arr[fast_dim])+1)*elem_size, hsize_t); + /* Advance span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - /* Check number of bytes against upper bounds allowed */ - if(span_size>io_bytes_left) - span_size=io_bytes_left; + /* Set new span 'b' to tmp_span */ + H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + recover_b = TRUE; + } /* end if */ + else { + /* Advance both span 'a' & 'b' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end else */ + } /* end if */ + /* Check if span 'a' overlaps the lower & upper bound */ + /* of span 'b' */ + /* AAAAAAAAAAAAAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low < span_b->low && span_a->high > span_b->high) { + /* Check if span 'a' and span 'b' down spans are equal */ + if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { + /* Merge/add copy of lower & middle parts of span 'a' to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Merge/add lower part of span 'a' to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Add the partial span to the list of sequences */ - off[curr_seq]=loc_off; - len[curr_seq]=span_size; + /* Get merged span tree for overlapped section */ + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - /* Increment sequence count */ - curr_seq++; + /* Merge/add overlapped section to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,tmp_spans,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Set the location of the last span's end */ - last_span_end=loc_off+span_size; + /* Release merged span tree for overlapped section */ + H5S__hyper_free_span_info(tmp_spans); + } /* end else */ - /* Decrement I/O left to perform */ - io_bytes_left-=span_size; + /* Copy upper part of span 'a' as new span 'a' (remember to free) */ - /* Advance the hyperslab iterator */ - /* Check if we are done */ - if(io_bytes_left > 0) { - /* Move to next span in fastest changing dimension */ - curr_span = curr_span->next; + /* Allocate new span node to append to list */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - if(NULL != curr_span) { - /* Move location offset of destination */ - loc_off += (curr_span->low - abs_arr[fast_dim]) * elem_size; + /* Set new span 'a' to tmp_span */ + H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + recover_a = TRUE; - /* Move iterator for fastest changing dimension */ - abs_arr[fast_dim] = curr_span->low; + /* Advance span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); } /* end if */ - } /* end if */ - else { - abs_arr[fast_dim] += span_size / elem_size; + /* Check if span 'a' is entirely within span 'b' */ + /* AAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if(span_a->low >= span_b->low && span_a->high <= span_b->high) { + /* Check if span 'a' and span 'b' down spans are equal */ + if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { + /* Merge/add copy of lower & middle parts of span 'b' to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Check if there is a lower part of span 'b' */ + if(span_a->low > span_b->low) { + /* Merge/add lower part of span 'b' to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + } /* end if */ + else { + /* No lower part of span 'b' , keep going... */ + } /* end else */ - /* Check if we are still within the span */ - if(abs_arr[fast_dim] <= curr_span->high) { - iter->u.hyp.span[fast_dim] = curr_span; - } /* end if */ - /* If we walked off that span, advance to the next span */ - else { - /* Advance span in this dimension */ - curr_span = curr_span->next; + /* Get merged span tree for overlapped section */ + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - /* Check if we have a valid span in this dimension still */ - if(NULL != curr_span) { - /* Reset absolute position */ - abs_arr[fast_dim] = curr_span->low; - iter->u.hyp.span[fast_dim] = curr_span; - } /* end if */ - } /* end else */ - } /* end else */ + /* Merge/add overlapped section to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,tmp_spans,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Adjust iterator pointers */ + /* Release merged span tree for overlapped section */ + H5S__hyper_free_span_info(tmp_spans); + } /* end else */ - if(NULL == curr_span) { -/* Same as code in main loop */ - /* Start at the next fastest dim */ - curr_dim = (int)(fast_dim - 1); + /* Check if there is an upper part of span 'b' */ + if(span_a->high < span_b->high) { + /* Copy upper part of span 'b' as new span 'b' (remember to free) */ - /* Work back up through the dimensions */ - while(curr_dim >= 0) { - /* Reset the current span */ - curr_span = iter->u.hyp.span[curr_dim]; + /* Allocate new span node to append to list */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Increment absolute position */ - abs_arr[curr_dim]++; + /* Advance span 'a' */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - /* Check if we are still within the span */ - if(abs_arr[curr_dim] <= curr_span->high) { - break; + /* Set new span 'b' to tmp_span */ + H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + recover_b = TRUE; } /* end if */ - /* If we walked off that span, advance to the next span */ else { - /* Advance span in this dimension */ - curr_span = curr_span->next; - - /* Check if we have a valid span in this dimension still */ - if(NULL != curr_span) { - /* Reset the span in the current dimension */ - ispan[curr_dim] = curr_span; - - /* Reset absolute position */ - abs_arr[curr_dim] = curr_span->low; - - break; + /* Advance both spans */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end else */ + } /* end if */ + /* Check if span 'a' overlaps only the upper bound */ + /* of span 'b' */ + /* AAAAAAAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) { + /* Check if span 'a' and span 'b' down spans are equal */ + if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { + /* Merge/add copy of span 'b' to merged spans if so */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + } /* end if */ + else { + /* Check if there is a lower part of span 'b' */ + if(span_a->low > span_b->low) { + /* Merge/add lower part of span 'b' to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { - /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ - curr_dim--; + /* No lower part of span 'b' , keep going... */ } /* end else */ - } /* end else */ - } /* end while */ - /* Check if we have more spans in the tree */ - if(curr_dim >= 0) { - /* Walk back down the iterator positions, resetting them */ - while((unsigned)curr_dim < fast_dim) { - HDassert(curr_span); - HDassert(curr_span->down); - HDassert(curr_span->down->head); + /* Get merged span tree for overlapped section */ + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); - /* Increment current dimension */ - curr_dim++; + /* Merge/add overlapped section to merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,tmp_spans,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Set the new span_info & span for this dimension */ - iter->u.hyp.span[curr_dim] = curr_span->down->head; + /* Release merged span tree for overlapped section */ + H5S__hyper_free_span_info(tmp_spans); + } /* end else */ - /* Advance span down the tree */ - curr_span = curr_span->down->head; + /* Copy upper part of span 'a' as new span 'a' */ - /* Reset the absolute offset for the dim */ - abs_arr[curr_dim] = curr_span->low; - } /* end while */ + /* Allocate new span node to append to list */ + if(NULL == (tmp_span = H5S__hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Verify that the curr_span points to the fastest dim */ - HDassert(curr_span == iter->u.hyp.span[fast_dim]); + /* Set new span 'a' to tmp_span */ + H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + recover_a = TRUE; - /* Reset the buffer offset */ - for(u = 0, loc_off = 0; u < ndims; u++) - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + /* Advance span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end if */ + /* Span 'a' must be entirely above span 'b' */ + /* AAAAA */ + /* <-----------------------------------> */ + /* BBBBBBBBBB */ + else { + /* Merge/add span 'b' with the merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + + /* Advance span 'b' */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); } /* end else */ - else - /* We had better be done with I/O or bad things are going to happen... */ - HDassert(io_bytes_left == 0); + } /* end while */ + + /* Clean up 'a' spans which haven't been added to the list of merged spans */ + if(span_a != NULL && span_b == NULL) { + while(span_a != NULL) { + /* Merge/add all 'a' spans into the merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + + /* Advance to next 'a' span, until all processed */ + H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + } /* end while */ } /* end if */ - } /* end if */ - /* Perform the I/O on the elements, based on the position of the iterator */ - while(io_bytes_left > 0 && curr_seq < maxseq) { - /* Sanity check */ - HDassert(curr_span); + /* Clean up 'b' spans which haven't been added to the list of merged spans */ + if(span_a == NULL && span_b != NULL) { + while(span_b != NULL) { + /* Merge/add all 'b' spans into the merged spans */ + if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") - /* Adjust location offset of destination to compensate for initial increment below */ - loc_off -= curr_span->pstride; + /* Advance to next 'b' span, until all processed */ + H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + } /* end while */ + } /* end if */ + } /* end else */ - /* Loop over all the spans in the fastest changing dimension */ - while(curr_span != NULL) { - /* Move location offset of destination */ - loc_off += curr_span->pstride; + /* Set return value */ + ret_value = merged_spans; - /* Compute the number of elements to attempt in this span */ - H5_CHECKED_ASSIGN(span_size, size_t, curr_span->nelem, hsize_t); +done: + if(ret_value == NULL) + if(merged_spans && H5S__hyper_free_span_info(merged_spans) < 0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_merge_spans_helper() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_merge_spans + PURPOSE + Merge new hyperslab spans to existing hyperslab selection + USAGE + herr_t H5S__hyper_merge_spans(space, new_spans, can_own) + H5S_t *space; IN: Dataspace to add new spans to hyperslab + selection. + H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to + hyperslab selection + hbool_t can_own; IN: Flag to indicate that it is OK to point + directly to the new spans, instead of + copying them. + RETURNS + non-negative on success, negative on failure + DESCRIPTION + Add a set of hyperslab spans to an existing hyperslab selection. The + new spans are required to be non-overlapping with the existing spans in + the dataspace's current hyperslab selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t can_own) +{ + FUNC_ENTER_STATIC_NOERR - /* Check number of elements against upper bounds allowed */ - if(span_size >= io_bytes_left) { - /* Trim the number of bytes to output */ - span_size = io_bytes_left; - io_bytes_left = 0; + /* Check args */ + HDassert(space); + HDassert(new_spans); -/* COMMON */ - /* Store the I/O information for the span */ + /* If this is the first span tree in the hyperslab selection, just use it */ + if(space->select.sel_info.hslab->span_lst == NULL) { + if(can_own) + space->select.sel_info.hslab->span_lst = new_spans; + else + space->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(new_spans); + } /* end if */ + else { + H5S_hyper_span_info_t *merged_spans; - /* Check if this is appending onto previous sequence */ - if(curr_seq > 0 && last_span_end == loc_off) - len[curr_seq - 1] += span_size; - else { - off[curr_seq] = loc_off; - len[curr_seq] = span_size; + /* Get the merged spans */ + merged_spans = H5S__hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans); - /* Increment the number of sequences in arrays */ - curr_seq++; - } /* end else */ + /* Sanity checking since we started with some spans, we should still have some after the merge */ + HDassert(merged_spans); - /* Set the location of the last span's end */ - last_span_end = loc_off + span_size; -/* end COMMON */ + /* Free the previous spans */ + H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); - /* Break out now, we are finished with I/O */ - break; - } /* end if */ - else { - /* Decrement I/O left to perform */ - io_bytes_left -= span_size; + /* Point to the new merged spans */ + space->select.sel_info.hslab->span_lst = merged_spans; + } /* end else */ -/* COMMON */ - /* Store the I/O information for the span */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_merge_spans() */ - /* Check if this is appending onto previous sequence */ - if(curr_seq > 0 && last_span_end == loc_off) - len[curr_seq-1]+=span_size; - else { - off[curr_seq] = loc_off; - len[curr_seq] = span_size; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_spans_nelem + PURPOSE + Count the number of elements in a span tree + USAGE + hsize_t H5S__hyper_spans_nelem(spans) + const H5S_hyper_span_info_t *spans; IN: Hyperslan span tree to count elements of + RETURNS + Number of elements in span tree on success; negative on failure + DESCRIPTION + Counts the number of elements described by the spans in a span tree. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static hsize_t +H5S__hyper_spans_nelem(const H5S_hyper_span_info_t *spans) +{ + hsize_t ret_value = 0; /* Return value */ - /* Increment the number of sequences in arrays */ - curr_seq++; - } /* end else */ + FUNC_ENTER_STATIC_NOERR - /* Set the location of the last span's end */ - last_span_end = loc_off + span_size; -/* end COMMON */ + /* Count the number of elements in the span tree */ + if(spans != NULL) { + const H5S_hyper_span_t *span; /* Hyperslab span */ - /* If the sequence & offset arrays are full, do what? */ - if(curr_seq >= maxseq) { - /* Break out now, we are finished with sequences */ - break; - } /* end else */ - } /* end else */ + span = spans->head; + while(span != NULL) { + /* If there are down spans, multiply the size of this span by the total down span elements */ + if(span->down != NULL) + ret_value += span->nelem * H5S__hyper_spans_nelem(span->down); + /* If there are no down spans, just count the elements in this span */ + else + ret_value += span->nelem; - /* Move to next span in fastest changing dimension */ - curr_span=curr_span->next; + /* Advance to next span */ + span = span->next; } /* end while */ + } /* end else */ - /* Check if we are done */ - if(io_bytes_left==0 || curr_seq>=maxseq) { - HDassert(curr_span); - abs_arr[fast_dim]=curr_span->low+(span_size/elem_size); - - /* Check if we are still within the span */ - if(abs_arr[fast_dim]<=curr_span->high) { - iter->u.hyp.span[fast_dim]=curr_span; - break; - } /* end if */ - /* If we walked off that span, advance to the next span */ - else { - /* Advance span in this dimension */ - curr_span=curr_span->next; + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_spans_nelem() */ - /* Check if we have a valid span in this dimension still */ - if(curr_span!=NULL) { - /* Reset absolute position */ - abs_arr[fast_dim]=curr_span->low; - iter->u.hyp.span[fast_dim]=curr_span; - break; - } /* end if */ - } /* end else */ - } /* end if */ + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_make_spans + PURPOSE + Create a span tree + USAGE + H5S_hyper_span_t *H5S__hyper_make_spans(rank, start, stride, count, block) + unsigned rank; IN: # of dimensions of the space + const hsize_t *start; IN: Starting location of the hyperslabs + const hsize_t *stride; IN: Stride from the beginning of one block to + the next + const hsize_t *count; IN: Number of blocks + const hsize_t *block; IN: Size of hyperslab block + RETURNS + Pointer to new span tree on success, NULL on failure + DESCRIPTION + Generates a new span tree for the hyperslab parameters specified. + Each span tree has a list of the elements spanned in each dimension, with + each span node containing a pointer to the list of spans in the next + dimension down. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5S_hyper_span_info_t * +H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride, + const hsize_t *count, const hsize_t *block) +{ + H5S_hyper_span_info_t *down = NULL; /* Pointer to spans in next dimension down */ + H5S_hyper_span_t *last_span; /* Current position in hyperslab span list */ + H5S_hyper_span_t *head = NULL; /* Head of new hyperslab span list */ + hsize_t stride_iter; /* Iterator over the stride values */ + int i; /* Counters */ + unsigned u; /* Counters */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ - /* Adjust iterator pointers */ + FUNC_ENTER_STATIC - /* Start at the next fastest dim */ - curr_dim = (int)(fast_dim - 1); + /* Check args */ + HDassert(rank > 0); + HDassert(start); + HDassert(stride); + HDassert(count); + HDassert(block); - /* Work back up through the dimensions */ - while(curr_dim >= 0) { - /* Reset the current span */ - curr_span=iter->u.hyp.span[curr_dim]; + /* Start creating spans in fastest changing dimension */ + for(i = (int)(rank - 1); i >= 0; i--) { - /* Increment absolute position */ - abs_arr[curr_dim]++; + /* Sanity check */ + if(0 == count[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "count == 0 is invalid") - /* Check if we are still within the span */ - if(abs_arr[curr_dim]<=curr_span->high) { - break; - } /* end if */ - /* If we walked off that span, advance to the next span */ - else { - /* Advance span in this dimension */ - curr_span=curr_span->next; + /* Start a new list in this dimension */ + head = NULL; + last_span = NULL; - /* Check if we have a valid span in this dimension still */ - if(curr_span!=NULL) { - /* Reset the span in the current dimension */ - ispan[curr_dim]=curr_span; + /* Generate all the span segments for this dimension */ + for(u = 0, stride_iter = 0; u < count[i]; u++, stride_iter += stride[i]) + { + H5S_hyper_span_t *span; /* New hyperslab span */ - /* Reset absolute position */ - abs_arr[curr_dim]=curr_span->low; + /* Allocate a span node */ + if(NULL == (span = H5FL_MALLOC(H5S_hyper_span_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - break; - } /* end if */ - else { - /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ - curr_dim--; - } /* end else */ - } /* end else */ - } /* end while */ + /* Set the span's basic information */ + span->low = start[i] + stride_iter; + span->high = span->low + (block[i] - 1); + span->nelem = block[i]; + span->pstride = stride[i]; + span->next = NULL; - /* Check if we are finished with the spans in the tree */ - if(curr_dim < 0) { - /* We had better be done with I/O or bad things are going to happen... */ - HDassert(io_bytes_left == 0); - break; - } /* end if */ - else { - /* Walk back down the iterator positions, resetting them */ - while((unsigned)curr_dim < fast_dim) { - HDassert(curr_span); - HDassert(curr_span->down); - HDassert(curr_span->down->head); + /* Append to the list of spans in this dimension */ + if(head == NULL) + head = span; + else + last_span->next = span; - /* Increment current dimension to the next dimension down */ - curr_dim++; + /* Move current pointer */ + last_span = span; - /* Set the new span for the next dimension down */ - iter->u.hyp.span[curr_dim] = curr_span->down->head; + /* Set the information for the next dimension down's spans, if appropriate */ + if(down != NULL) { + span->down = down; + down->count++; /* Increment reference count for shared span */ + } /* end if */ + else + span->down = NULL; + } /* end for */ - /* Advance span down the tree */ - curr_span = curr_span->down->head; + /* Allocate a span info node */ + if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") - /* Reset the absolute offset for the dim */ - abs_arr[curr_dim] = curr_span->low; - } /* end while */ + /* Keep the pointer to the next dimension down's completed list */ + down->head = head; - /* Verify that the curr_span points to the fastest dim */ - HDassert(curr_span == iter->u.hyp.span[fast_dim]); - } /* end else */ + } /* end for */ - /* Reset the buffer offset */ - for(u = 0, loc_off = 0; u < ndims; u++) - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; - } /* end while */ + /* Indicate that there is a pointer to this tree */ + if(down) + down->count = 1; - /* Decrement number of elements left in iterator */ - io_used = (io_left - (io_bytes_left / elem_size)); - iter->elmt_left -= io_used; + /* Success! Return the head of the list in the slowest changing dimension */ + ret_value = down; - /* Set the number of sequences generated */ - *nseq = curr_seq; +done: + /* cleanup if error (ret_value will be NULL) */ + if(!ret_value) { + if(head || down) { + if(head && down) + if(down->head != head) + down = NULL; - /* Set the number of elements used */ - *nelem = io_used; + do { + if(down) { + head = down->head; + down = H5FL_FREE(H5S_hyper_span_info_t, down); + } /* end if */ + down = head->down; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_gen() */ + while(head) { + last_span = head->next; + head = H5FL_FREE(H5S_hyper_span_t, head); + head = last_span; + } /* end while */ + } while(down); + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_make_spans() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list_opt + H5S__hyper_rebuild_helper PURPOSE - Create a list of offsets & lengths for a selection + Helper routine to rebuild optimized hyperslab information if possible. + (It can be recovered with regular selection) USAGE - herr_t H5S_select_hyper_get_file_list_opt(space,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths + herr_t H5S__hyper_rebuild_helper(space) + const H5S_hyper_span_t *span; IN: Portion of span tree to check + H5S_hyper_dim_t span_slab[]; OUT: Rebuilt section of hyperslab description + unsigned rank; IN: Current dimension to work on RETURNS - Non-negative on success/Negative on failure. + TRUE/FALSE for hyperslab selection rebuilt DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. + Examine the span tree for a hyperslab selection and rebuild + the start/stride/count/block information for the selection, if possible. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + To be able to recover the optimized information, the span tree must conform + to span tree able to be generated from a single H5S_SELECT_SET operation. EXAMPLES REVISION LOG + KY, 2005/9/22 --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +static hbool_t +H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab_info[], + unsigned rank) { - hsize_t *mem_size; /* Size of the source buffer */ - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ - const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ - hsize_t tmp_count[H5S_MAX_RANK];/* Temporary block count */ - hsize_t tmp_block[H5S_MAX_RANK];/* Temporary block offset */ - hsize_t wrap[H5S_MAX_RANK]; /* Bytes to wrap around at the end of a row */ - hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ - const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ - hsize_t fast_dim_start, /* Local copies of fastest changing dimension info */ - fast_dim_stride, - fast_dim_block, - fast_dim_offset; - size_t fast_dim_buf_off; /* Local copy of amount to move fastest dimension buffer offset */ - size_t fast_dim_count; /* Number of blocks left in fastest changing dimension */ - size_t tot_blk_count; /* Total number of blocks left to output */ - size_t act_blk_count; /* Actual number of blocks to output */ - size_t total_rows; /* Total number of entire rows to output */ - size_t curr_rows; /* Current number of entire rows to output */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - unsigned ndims; /* Number of dimensions of dataset */ - int temp_dim; /* Temporary rank holder */ - hsize_t acc; /* Accumulator */ - hsize_t loc; /* Coordinate offset */ - size_t curr_seq = 0; /* Current sequence being operated on */ - size_t actual_elem; /* The actual number of elements to count */ - size_t actual_bytes;/* The actual number of bytes to copy */ - size_t io_left; /* The number of elements left in I/O operation */ - size_t start_io_left; /* The initial number of elements left in I/O operation */ - size_t elem_size; /* Size of each element iterating over */ - unsigned u; /* Local index variable */ - int i; /* Local index variable */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC_NOERR - /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); + if(span) { + const H5S_hyper_span_t *prev_span = NULL; /* Previous span in list */ + H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK]; + hsize_t curr_stride; + hsize_t curr_block; + hsize_t curr_start; + hsize_t curr_low; + size_t outcount; /* Number of spans encountered in this dimension */ - /* Set the local copy of the diminfo pointer */ - tdiminfo = iter->u.hyp.diminfo; + /* Initialization */ + curr_stride = 1; + curr_low = 0; + outcount = 0; - /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { - /* Set the aliases for a few important dimension ranks */ - ndims = iter->u.hyp.iter_rank; - fast_dim = ndims - 1; + /* Get "canonical" down span information */ + if(span->down) { + HDassert(span->down->head); - /* Set the local copy of the selection offset */ - sel_off = iter->u.hyp.sel_off; + /* Go to the next down span and check whether the selection can be rebuilt */ + if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) + HGOTO_DONE(FALSE) - /* Set up the pointer to the size of the memory space */ - mem_size = iter->u.hyp.size; - } /* end if */ - else { - /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; - fast_dim = ndims - 1; + HDmemcpy(canon_down_span_slab_info, span_slab_info, sizeof(H5S_hyper_dim_t) * rank); + } /* end if */ - /* Set the local copy of the selection offset */ - sel_off = space->select.offset; + /* Assign the initial starting point & block size */ + curr_start = span->low; + curr_block = (span->high - span->low) + 1; - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; - } /* end else */ + /* Loop the spans */ + while(span) { + if(outcount > 0) { + hsize_t next_stride; /* Stride from previous span */ + hsize_t next_block; /* Block size of current span */ - /* initialize row sizes for each dimension */ - elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; - } /* end for */ + /* Check that down spans match current slab info */ + /* (Can skip check if previous span's down pointer is same as current one) */ + if(span->down && (NULL == prev_span || prev_span->down != span->down)) { + H5S_hyper_dim_t *curr_down_span_slab_info; + unsigned u; /* Local index variable */ - /* Calculate the number of elements to sequence through */ - H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - io_left = MIN((size_t)iter->elmt_left, maxelem); + HDassert(span->down->head); - /* Sanity check that there aren't any "remainder" sequences in process */ - HDassert(!((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || - ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1))); + /* Go to the next down span and check whether the selection can be rebuilt.*/ + if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) + HGOTO_DONE(FALSE) - /* We've cleared the "remainder" of the previous fastest dimension - * sequence before calling this routine, so we must be at the beginning of - * a sequence. Use the fancy algorithm to compute the offsets and run - * through as many as possible, until the buffer fills up. - */ + /* Compare the slab information of the adjacent spans in the down span tree. + We have to compare all the sub-tree slab information with the canon_down_span_slab_info.*/ + for(u = 0; u < rank - 1; u++) { + curr_down_span_slab_info = &span_slab_info[u]; - /* Keep the number of elements we started with */ - start_io_left = io_left; + if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[u].count > 0) { + if(curr_down_span_slab_info->start != canon_down_span_slab_info[u].start + || curr_down_span_slab_info->stride != canon_down_span_slab_info[u].stride + || curr_down_span_slab_info->block != canon_down_span_slab_info[u].block + || curr_down_span_slab_info->count != canon_down_span_slab_info[u].count) + HGOTO_DONE(FALSE) + } /* end if */ + else if(!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0))) + HGOTO_DONE(FALSE) + } /* end for */ + } /* end if */ + + /* Obtain values for stride and block */ + next_stride = span->low - curr_low; + next_block = (span->high - span->low) + 1; + + /* Compare stride and block in this span, to compare stride, + * three spans are needed. Account for the first two spans. + */ + if(next_block != curr_block) + HGOTO_DONE(FALSE) + if(outcount > 1 && curr_stride != next_stride) + HGOTO_DONE(FALSE) + + /* Keep the isolated stride to be 1 */ + curr_stride = next_stride; + } /* end if */ + + /* Keep current starting point */ + curr_low = span->low; - /* Compute the arrays to perform I/O on */ + /* Advance to next span */ + prev_span = span; + span = span->next; + outcount++; + } /* end while */ - /* Copy the location of the point to get */ - /* (Add in the selection offset) */ - for(u = 0; u < ndims; u++) - offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); + /* Save the span information. */ + span_slab_info[rank - 1].start = curr_start; + span_slab_info[rank - 1].count = outcount; + span_slab_info[rank - 1].block = curr_block; + span_slab_info[rank - 1].stride = curr_stride; + } /* end if */ - /* Compute the current "counts" for this location */ - for(u = 0; u < ndims; u++) { - if(tdiminfo[u].count == 1) { - tmp_count[u] = 0; - tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; - } /* end if */ - else { - tmp_count[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) / tdiminfo[u].stride; - tmp_block[u] = (iter->u.hyp.off[u] - tdiminfo[u].start) % tdiminfo[u].stride; - } /* end else */ - } /* end for */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_rebuild_helper() */ - /* Compute the initial buffer offset */ - for(u = 0, loc = 0; u < ndims; u++) - loc += offset[u] * slab[u]; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_rebuild + PURPOSE + Rebuild optimized hyperslab information if possible. + (It can be recovered with regular selection) + USAGE + hbool_t H5S__hyper_rebuild(space) + const H5S_t *space; IN: Dataspace to check + RETURNS + TRUE/FALSE for hyperslab selection rebuilt + DESCRIPTION + Examine the span tree for a hyperslab selection and rebuild + the start/stride/count/block information for the selection, if possible. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + To be able to recover the optimized information, the span tree must conform + to span tree able to be generated from a single H5S_SELECT_SET operation. + EXAMPLES + REVISION LOG + This routine is the optimization of the old version. The previous version + can only detect a singluar selection. This version is general enough to + detect any regular selection. + KY, 2005/9/22 +--------------------------------------------------------------------------*/ +static hbool_t +H5S__hyper_rebuild(H5S_t *space) +{ + H5S_hyper_dim_t top_span_slab_info[H5S_MAX_RANK]; + unsigned rank, curr_dim; + hbool_t ret_value = TRUE; /* Return value */ - /* Set the number of elements to write each time */ - H5_CHECKED_ASSIGN(actual_elem, size_t, tdiminfo[fast_dim].block, hsize_t); + FUNC_ENTER_STATIC_NOERR - /* Set the number of actual bytes */ - actual_bytes = actual_elem * elem_size; + /* Check args */ + HDassert(space); + HDassert(space->select.sel_info.hslab->span_lst); - /* Set local copies of information for the fastest changing dimension */ - fast_dim_start = tdiminfo[fast_dim].start; - fast_dim_stride = tdiminfo[fast_dim].stride; - fast_dim_block = tdiminfo[fast_dim].block; - H5_CHECKED_ASSIGN(fast_dim_buf_off, size_t, slab[fast_dim] * fast_dim_stride, hsize_t); - fast_dim_offset = (hsize_t)((hssize_t)fast_dim_start + sel_off[fast_dim]); + /* Check the rank of space */ + rank = space->extent.rank; - /* Compute the number of blocks which would fit into the buffer */ - H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); - tot_blk_count = (size_t)(io_left / fast_dim_block); + /* Check whether the slab can be rebuilt. Only regular selection can be rebuilt. If yes, fill in correct values.*/ + if(!H5S__hyper_rebuild_helper(space->select.sel_info.hslab->span_lst->head, top_span_slab_info, rank)) { + HGOTO_DONE(FALSE) + } /* end if */ + else { + H5S_hyper_dim_t *diminfo; + H5S_hyper_dim_t *app_diminfo; - /* Don't go over the maximum number of sequences allowed */ - tot_blk_count = MIN(tot_blk_count, (maxseq - curr_seq)); + diminfo = space->select.sel_info.hslab->opt_diminfo; + app_diminfo = space->select.sel_info.hslab->app_diminfo; - /* Compute the amount to wrap at the end of each row */ - for(u = 0; u < ndims; u++) - wrap[u] = (mem_size[u] - (tdiminfo[u].stride * tdiminfo[u].count)) * slab[u]; + for(curr_dim = 0; curr_dim < rank; curr_dim++) { - /* Compute the amount to skip between blocks */ - for(u = 0; u < ndims; u++) - skip[u] = (tdiminfo[u].stride - tdiminfo[u].block) * slab[u]; + app_diminfo[(rank - curr_dim) - 1].start = diminfo[(rank - curr_dim) - 1].start = top_span_slab_info[curr_dim].start; + app_diminfo[(rank - curr_dim) - 1].stride = diminfo[(rank - curr_dim) - 1].stride = top_span_slab_info[curr_dim].stride; + app_diminfo[(rank - curr_dim) - 1].count = diminfo[(rank - curr_dim) - 1].count = top_span_slab_info[curr_dim].count; + app_diminfo[(rank - curr_dim) - 1].block = diminfo[(rank - curr_dim) - 1].block = top_span_slab_info[curr_dim].block; - /* Check if there is a partial row left (with full blocks) */ - if(tmp_count[fast_dim] > 0) { - /* Get number of blocks in fastest dimension */ - H5_CHECKED_ASSIGN(fast_dim_count, size_t, tdiminfo[fast_dim].count - tmp_count[fast_dim], hsize_t); + } /* end for */ - /* Make certain this entire row will fit into buffer */ - fast_dim_count = MIN(fast_dim_count, tot_blk_count); + space->select.sel_info.hslab->diminfo_valid = TRUE; + } /* end else */ - /* Number of blocks to sequence over */ - act_blk_count = fast_dim_count; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_rebuild() */ - /* Loop over all the blocks in the fastest changing dimension */ - while(fast_dim_count > 0) { - /* Store the sequence information */ - off[curr_seq] = loc; - len[curr_seq] = actual_bytes; + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_generate_spans + PURPOSE + Create span tree for a regular hyperslab selection + USAGE + herr_t H5S__hyper_generate_spans(space) + H5S_t *space; IN/OUT: Pointer to dataspace + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Create a span tree representation of a regular hyperslab selection and + add it to the information for the hyperslab selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_generate_spans(H5S_t *space) +{ + hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ + hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ + hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ + hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Increment sequence count */ - curr_seq++; + FUNC_ENTER_STATIC - /* Increment information to reflect block just processed */ - loc += fast_dim_buf_off; + HDassert(space); + HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ + /* Get the diminfo */ + for(u = 0; u < space->extent.rank; u++) { + /* Check for unlimited dimension and return error */ + /* These should be able to be converted to assertions once everything + * that calls this function checks for unlimited selections first + * (especially the new hyperslab API) -NAF */ + if(space->select.sel_info.hslab->opt_diminfo[u].count == H5S_UNLIMITED) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited count") + if(space->select.sel_info.hslab->opt_diminfo[u].block == H5S_UNLIMITED) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited block") - /* Decrement number of elements left */ - io_left -= actual_elem * act_blk_count; + tmp_start[u]=space->select.sel_info.hslab->opt_diminfo[u].start; + tmp_stride[u]=space->select.sel_info.hslab->opt_diminfo[u].stride; + tmp_count[u]=space->select.sel_info.hslab->opt_diminfo[u].count; + tmp_block[u]=space->select.sel_info.hslab->opt_diminfo[u].block; + } /* end for */ - /* Decrement number of blocks left */ - tot_blk_count -= act_blk_count; + /* Build the hyperslab information also */ + if(H5S__generate_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") - /* Increment information to reflect block just processed */ - tmp_count[fast_dim] += act_blk_count; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_generate_spans() */ - /* Check if we finished the entire row of blocks */ - if(tmp_count[fast_dim] >= tdiminfo[fast_dim].count) { - /* Increment offset in destination buffer */ - loc += wrap[fast_dim]; + +/*------------------------------------------------------------------------- + * Function: H5S__generate_hyperlab + * + * Purpose: Generate hyperslab information from H5S_select_hyperslab() + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, September 12, 2000 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], + const hsize_t stride[], const hsize_t count[], const hsize_t block[]) +{ + H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ + H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ + H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ + H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Increment information to reflect block just processed */ - offset[fast_dim] = fast_dim_offset; /* reset the offset in the fastest dimension */ - tmp_count[fast_dim] = 0; + FUNC_ENTER_STATIC - /* Increment the offset and count for the other dimensions */ - temp_dim = (int)fast_dim - 1; - while(temp_dim >= 0) { - /* Move to the next row in the curent dimension */ - offset[temp_dim]++; - tmp_block[temp_dim]++; + /* Check args */ + HDassert(space); + HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); + HDassert(start); + HDassert(stride); + HDassert(count); + HDassert(block); - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) - break; - else { - /* Move to the next block in the current dimension */ - offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); - loc += skip[temp_dim]; - tmp_block[temp_dim] = 0; - tmp_count[temp_dim]++; + /* Generate span tree for new hyperslab information */ + if(NULL == (new_spans = H5S__hyper_make_spans(space->extent.rank, start, stride, count, block))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information") - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[temp_dim] < tdiminfo[temp_dim].count) - break; - else { - offset[temp_dim] = (hsize_t)((hssize_t)tdiminfo[temp_dim].start + sel_off[temp_dim]); - loc += wrap[temp_dim]; - tmp_count[temp_dim] = 0; /* reset back to the beginning of the line */ - tmp_block[temp_dim] = 0; - } /* end else */ - } /* end else */ + /* Generate list of blocks to add/remove based on selection operation */ + if(op==H5S_SELECT_SET) { + /* Add new spans to current selection */ + if(H5S__hyper_merge_spans(space,new_spans,TRUE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Decrement dimension count */ - temp_dim--; - } /* end while */ - } /* end if */ - else { - /* Update the offset in the fastest dimension */ - offset[fast_dim] += (fast_dim_stride * act_blk_count); - } /* end else */ + /* Set the number of elements in current selection */ + space->select.num_elem = H5S__hyper_spans_nelem(new_spans); + + /* Indicate that the new_spans are owned */ + new_spans = NULL; } /* end if */ + else { + hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */ - /* Compute the number of entire rows to read in */ - H5_CHECK_OVERFLOW(tot_blk_count / tdiminfo[fast_dim].count, hsize_t, size_t); - curr_rows = total_rows = (size_t)(tot_blk_count / tdiminfo[fast_dim].count); + /* Generate lists of spans which overlap and don't overlap */ + if(H5S__hyper_clip_spans(space->select.sel_info.hslab->span_lst,new_spans,&a_not_b,&a_and_b,&b_not_a)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - /* Reset copy of number of blocks in fastest dimension */ - H5_CHECKED_ASSIGN(fast_dim_count, size_t, tdiminfo[fast_dim].count, hsize_t); + switch(op) { + case H5S_SELECT_OR: + /* Add any new spans from b_not_a to current selection */ + if(b_not_a!=NULL) { + if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Read in data until an entire sequence can't be written out any longer */ - while(curr_rows > 0) { + /* Update the number of elements in current selection */ + space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); -#define DUFF_GUTS \ -/* Store the sequence information */ \ -off[curr_seq] = loc; \ -len[curr_seq] = actual_bytes; \ - \ -/* Increment sequence count */ \ -curr_seq++; \ - \ -/* Increment information to reflect block just processed */ \ -loc += fast_dim_buf_off; + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ + break; -#ifdef NO_DUFFS_DEVICE - /* Loop over all the blocks in the fastest changing dimension */ - while(fast_dim_count > 0) { - DUFF_GUTS + case H5S_SELECT_AND: + /* Free the current selection */ + if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + space->select.sel_info.hslab->span_lst=NULL; - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ -#else /* NO_DUFFS_DEVICE */ - { - size_t duffs_index; /* Counting index for Duff's device */ + /* Reset the number of items in selection */ + space->select.num_elem=0; - duffs_index = (fast_dim_count + 7) / 8; - switch (fast_dim_count % 8) { - default: - HDassert(0 && "This Should never be executed!"); - break; - case 0: - do - { - DUFF_GUTS - case 7: - DUFF_GUTS - case 6: - DUFF_GUTS - case 5: - DUFF_GUTS - case 4: - DUFF_GUTS - case 3: - DUFF_GUTS - case 2: - DUFF_GUTS - case 1: - DUFF_GUTS - } while (--duffs_index > 0); - } /* end switch */ - } -#endif /* NO_DUFFS_DEVICE */ -#undef DUFF_GUTS + /* Check if there are any overlapped selections */ + if(a_and_b!=NULL) { + if(H5S__hyper_merge_spans(space,a_and_b,TRUE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Increment offset in destination buffer */ - loc += wrap[fast_dim]; + /* Update the number of elements in current selection */ + space->select.num_elem = H5S__hyper_spans_nelem(a_and_b); - /* Increment the offset and count for the other dimensions */ - temp_dim = (int)fast_dim - 1; - while(temp_dim >= 0) { - /* Move to the next row in the curent dimension */ - offset[temp_dim]++; - tmp_block[temp_dim]++; + /* Indicate that the a_and_b spans are owned */ + a_and_b=NULL; - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ break; - else { - /* Move to the next block in the current dimension */ - offset[temp_dim] += (tdiminfo[temp_dim].stride - tdiminfo[temp_dim].block); - loc += skip[temp_dim]; - tmp_block[temp_dim] = 0; - tmp_count[temp_dim]++; - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_count[temp_dim] < tdiminfo[temp_dim].count) - break; - else { - offset[temp_dim] = (hsize_t)((hssize_t)tdiminfo[temp_dim].start + sel_off[temp_dim]); - loc += wrap[temp_dim]; - tmp_count[temp_dim] = 0; /* reset back to the beginning of the line */ - tmp_block[temp_dim] = 0; - } /* end else */ - } /* end else */ + case H5S_SELECT_XOR: + /* Free the current selection */ + if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + space->select.sel_info.hslab->span_lst=NULL; - /* Decrement dimension count */ - temp_dim--; - } /* end while */ + /* Reset the number of items in selection */ + space->select.num_elem=0; - /* Decrement the number of rows left */ - curr_rows--; - } /* end while */ + /* Check if there are any non-overlapped selections */ + if(a_not_b!=NULL) { + if(H5S__hyper_merge_spans(space,a_not_b,FALSE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Adjust the number of blocks & elements left to transfer */ + /* Update the number of elements in current selection */ + space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); - /* Decrement number of elements left */ - H5_CHECK_OVERFLOW(actual_elem * (total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); - io_left -= (size_t)(actual_elem * (total_rows * tdiminfo[fast_dim].count)); + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ + if(b_not_a!=NULL) { + if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Decrement number of blocks left */ - H5_CHECK_OVERFLOW((total_rows * tdiminfo[fast_dim].count), hsize_t, size_t); - tot_blk_count -= (size_t)(total_rows * tdiminfo[fast_dim].count); + /* Update the number of elements in current selection */ + space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); - /* Read in partial row of blocks */ - if(io_left > 0 && curr_seq < maxseq) { - /* Get remaining number of blocks left to output */ - fast_dim_count = tot_blk_count; + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ + break; - /* Loop over all the blocks in the fastest changing dimension */ - while(fast_dim_count > 0) { - /* Store the sequence information */ - off[curr_seq] = loc; - len[curr_seq] = actual_bytes; + case H5S_SELECT_NOTB: + /* Free the current selection */ + if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + space->select.sel_info.hslab->span_lst=NULL; - /* Increment sequence count */ - curr_seq++; + /* Reset the number of items in selection */ + space->select.num_elem=0; - /* Increment information to reflect block just processed */ - loc += fast_dim_buf_off; + /* Check if there are any non-overlapped selections */ + if(a_not_b!=NULL) { + if(H5S__hyper_merge_spans(space,a_not_b,TRUE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Decrement number of blocks */ - fast_dim_count--; - } /* end while */ + /* Update the number of elements in current selection */ + space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); - /* Decrement number of elements left */ - io_left -= actual_elem * tot_blk_count; + /* Indicate that the a_not_b are owned */ + a_not_b=NULL; - /* Increment information to reflect block just processed */ - offset[fast_dim] += (fast_dim_stride * tot_blk_count); /* move the offset in the fastest dimension */ + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ + break; - /* Handle any leftover, partial blocks in this row */ - if(io_left > 0 && curr_seq < maxseq) { - actual_elem = io_left; - actual_bytes = actual_elem * elem_size; + case H5S_SELECT_NOTA: + /* Free the current selection */ + if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + space->select.sel_info.hslab->span_lst=NULL; - /* Store the sequence information */ - off[curr_seq] = loc; - len[curr_seq] = actual_bytes; + /* Reset the number of items in selection */ + space->select.num_elem=0; - /* Increment sequence count */ - curr_seq++; + /* Check if there are any non-overlapped selections */ + if(b_not_a!=NULL) { + if(H5S__hyper_merge_spans(space,b_not_a,TRUE)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") - /* Decrement the number of elements left */ - io_left -= actual_elem; + /* Update the number of elements in current selection */ + space->select.num_elem = H5S__hyper_spans_nelem(b_not_a); - /* Increment buffer correctly */ - offset[fast_dim] += actual_elem; - } /* end if */ + /* Indicate that the b_not_a are owned */ + b_not_a=NULL; + + /* Indicate that the spans were updated */ + updated_spans = TRUE; + } /* end if */ + break; + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + + /* Check if the resulting hyperslab span tree is empty */ + if(space->select.sel_info.hslab->span_lst==NULL) { + H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + + /* Sanity check */ + HDassert(space->select.num_elem == 0); - /* don't bother checking slower dimensions */ - HDassert(io_left == 0 || curr_seq == maxseq); - } /* end if */ + /* Allocate a span info node */ + if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") - /* Update the iterator */ + /* Set the reference count */ + spans->count=1; - /* Update the iterator with the location we stopped */ - /* (Subtract out the selection offset) */ - for(u = 0; u < ndims; u++) - iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); + /* Reset the scratch pad space */ + spans->scratch=0; - /* Decrement the number of elements left in selection */ - iter->elmt_left -= (start_io_left - io_left); + /* Set to empty tree */ + spans->head=NULL; - /* Increment the number of sequences generated */ - *nseq += curr_seq; + /* Set pointer to empty span tree */ + space->select.sel_info.hslab->span_lst=spans; + } /* end if */ + else { + /* Check if we updated the spans */ + if(updated_spans) { + /* Attempt to rebuild "optimized" start/stride/count/block information. + * from resulting hyperslab span tree + */ + H5S__hyper_rebuild(space); + } /* end if */ + } /* end else */ + } /* end else */ - /* Increment the number of elements used */ - *nelem += start_io_left - io_left; +done: + /* Free resources */ + if(a_not_b) + if(H5S__hyper_free_span_info(a_not_b) < 0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") + if(a_and_b) + if(H5S__hyper_free_span_info(a_and_b) < 0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") + if(b_not_a) + if(H5S__hyper_free_span_info(b_not_a) < 0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") + if(new_spans) + if(H5S__hyper_free_span_info(new_spans) < 0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_opt() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__generate_hyperslab() */ -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_get_seq_list_single - PURPOSE - Create a list of offsets & lengths for a selection - USAGE - herr_t H5S__hyper_get_seq_list_single(space, flags, iter, maxseq, maxelem, nseq, nelem, off, len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +/*------------------------------------------------------------------------- + * Function: H5S_select_hyperslab + * + * Purpose: Internal version of H5Sselect_hyperslab(). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, January 10, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], + const hsize_t *stride, const hsize_t count[], const hsize_t *block) { - const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ - const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t *mem_size; /* Size of the source buffer */ - hsize_t base_offset[H5S_MAX_RANK]; /* Base coordinate offset in dataspace */ - hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ - hsize_t fast_dim_block; /* Local copies of fastest changing dimension info */ - hsize_t acc; /* Accumulator */ - hsize_t loc; /* Coordinate offset */ - size_t tot_blk_count; /* Total number of blocks left to output */ - size_t elem_size; /* Size of each element iterating over */ - size_t io_left; /* The number of elements left in I/O operation */ - size_t actual_elem; /* The actual number of elements to count */ - unsigned ndims; /* Number of dimensions of dataset */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - unsigned skip_dim; /* Rank of the dimension to skip along */ - unsigned u; /* Local index variable */ - int i; /* Local index variable */ + hsize_t int_stride[H5S_MAX_RANK]; /* Internal storage for stride information */ + hsize_t int_count[H5S_MAX_RANK]; /* Internal storage for count information */ + hsize_t int_block[H5S_MAX_RANK]; /* Internal storage for block information */ + const hsize_t *opt_stride; /* Optimized stride information */ + const hsize_t *opt_count; /* Optimized count information */ + const hsize_t *opt_block; /* Optimized block information */ + int unlim_dim = -1; /* Unlimited dimension in selection, of -1 if none */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Check args */ HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); + HDassert(start); + HDassert(count); + HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID); - /* Set a local copy of the diminfo pointer */ - tdiminfo = iter->u.hyp.diminfo; + /* Point to the correct stride values */ + if(stride == NULL) + stride = H5S_hyper_ones_g; - /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { - /* Set the aliases for a few important dimension ranks */ - ndims = iter->u.hyp.iter_rank; + /* Point to the correct block values */ + if(block == NULL) + block = H5S_hyper_ones_g; - /* Set the local copy of the selection offset */ - sel_off = iter->u.hyp.sel_off; + /* Check new selection */ + for(u = 0; u < space->extent.rank; u++) { + /* Check for overlapping hyperslab blocks in new selection. */ + if(count[u] > 1 && stride[u] < block[u]) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap") - /* Set up the pointer to the size of the memory space */ - mem_size = iter->u.hyp.size; - } /* end if */ - else { - /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; + /* Detect zero-sized hyperslabs in new selection */ + if(count[u] == 0 || block[u] == 0) { + switch(op) { + case H5S_SELECT_SET: /* Select "set" operation */ + case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ + case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ + /* Convert to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + HGOTO_DONE(SUCCEED); - /* Set the local copy of the selection offset */ - sel_off = space->select.offset; + case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ + case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ + case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ + HGOTO_DONE(SUCCEED); /* Selection stays same */ - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; - } /* end else */ - fast_dim = ndims - 1; + case H5S_SELECT_NOOP: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + } /* end if */ - /* initialize row sizes for each dimension */ - elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; + /* Check for unlimited dimension */ + if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") + else { + if(count[u] == block[u]) /* Both are H5S_UNLIMITED */ + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") + unlim_dim = (int)u; + } /* end else */ + } /* end if */ } /* end for */ - /* Copy the base location of the block */ - /* (Add in the selection offset) */ - for(u = 0; u < ndims; u++) - base_offset[u] = (hsize_t)((hssize_t)tdiminfo[u].start + sel_off[u]); + /* Optimize hyperslab parameters to merge contiguous blocks, etc. */ + if(stride == H5S_hyper_ones_g && block == H5S_hyper_ones_g) { + /* Point to existing arrays */ + opt_stride = H5S_hyper_ones_g; + opt_count = H5S_hyper_ones_g; + opt_block = count; + } /* end if */ + else { + /* Point to local arrays */ + opt_stride = int_stride; + opt_count = int_count; + opt_block = int_block; + for(u = 0; u < space->extent.rank; u++) { + /* contiguous hyperslabs have the block size equal to the stride */ + if((stride[u] == block[u]) && (count[u] != H5S_UNLIMITED)) { + int_count[u] = 1; + int_stride[u] = 1; + if(block[u] == 1) + int_block[u] = count[u]; + else + int_block[u] = block[u] * count[u]; + } /* end if */ + else { + if(count[u] == 1) + int_stride[u] = 1; + else { + HDassert((stride[u] > block[u]) || + ((stride[u] == block[u]) && (count[u] == H5S_UNLIMITED))); + int_stride[u] = stride[u]; + } /* end else */ + int_count[u] = count[u]; + int_block[u] = block[u]; + } /* end else */ + } /* end for */ + } /* end else */ + + /* Check for operating on unlimited selection */ + if((H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS) + && (space->select.sel_info.hslab->unlim_dim >= 0) + && (op != H5S_SELECT_SET)) { + /* Check for invalid operation */ + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") + HDassert(space->select.sel_info.hslab->diminfo_valid); - /* Copy the location of the point to get */ - /* (Add in the selection offset) */ - for(u = 0; u < ndims; u++) - offset[u] = (hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u]); + /* Clip unlimited selection to include new selection */ + if(H5S_hyper_clip_unlim(space, + start[space->select.sel_info.hslab->unlim_dim] + + ((opt_count[space->select.sel_info.hslab->unlim_dim] - (hsize_t)1) + * opt_stride[space->select.sel_info.hslab->unlim_dim]) + + opt_block[space->select.sel_info.hslab->unlim_dim]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") - /* Compute the initial buffer offset */ - for(u = 0, loc = 0; u < ndims; u++) - loc += offset[u] * slab[u]; + /* If an empty space was returned it must be "none" */ + HDassert((space->select.num_elem > (hsize_t)0) || (space->select.type->type == H5S_SEL_NONE)); + } /* end if */ - /* Set local copies of information for the fastest changing dimension */ - fast_dim_block = tdiminfo[fast_dim].block; + /* Fixup operation for non-hyperslab selections */ + switch(H5S_GET_SELECT_TYPE(space)) { + case H5S_SEL_NONE: /* No elements selected in dataspace */ + switch(op) { + case H5S_SELECT_SET: /* Select "set" operation */ + /* Change "none" selection to hyperslab selection */ + break; - /* Calculate the number of elements to sequence through */ - H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - io_left = MIN((size_t)iter->elmt_left, maxelem); + case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ + case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ + case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ + op = H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ + break; - /* Compute the number of blocks which would fit into the buffer */ - H5_CHECK_OVERFLOW(io_left / fast_dim_block, hsize_t, size_t); - tot_blk_count = (size_t)(io_left / fast_dim_block); + case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ + case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ + HGOTO_DONE(SUCCEED); /* Selection stays "none" */ - /* Don't go over the maximum number of sequences allowed */ - tot_blk_count = MIN(tot_blk_count, maxseq); + case H5S_SELECT_NOOP: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + break; - /* Set the number of elements to write each time */ - H5_CHECKED_ASSIGN(actual_elem, size_t, fast_dim_block, hsize_t); + case H5S_SEL_ALL: /* All elements selected in dataspace */ + switch(op) { + case H5S_SELECT_SET: /* Select "set" operation */ + /* Change "all" selection to hyperslab selection */ + break; - /* Check for blocks to operate on */ - if(tot_blk_count > 0) { - size_t actual_bytes; /* The actual number of bytes to copy */ + case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ + HGOTO_DONE(SUCCEED); /* Selection stays "all" */ - /* Set the number of actual bytes */ - actual_bytes = actual_elem * elem_size; + case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ + op = H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */ + break; - /* Check for 1-dim selection */ - if(0 == fast_dim) { - /* Sanity checks */ - HDassert(1 == tot_blk_count); - HDassert(io_left == actual_elem); + case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ + case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ + /* Convert current "all" selection to "real" hyperslab selection */ + /* Then allow operation to proceed */ + { + const hsize_t *tmp_start; /* Temporary start information */ + const hsize_t *tmp_stride; /* Temporary stride information */ + const hsize_t *tmp_count; /* Temporary count information */ + const hsize_t *tmp_block; /* Temporary block information */ - /* Store the sequence information */ - *off++ = loc; - *len++ = actual_bytes; - } /* end if */ - else { - hsize_t skip_slab; /* Temporary copy of slab[fast_dim - 1] */ - size_t blk_count; /* Total number of blocks left to output */ + /* Set up temporary information for the dimensions */ + tmp_start = H5S_hyper_zeros_g; + tmp_stride = tmp_count = H5S_hyper_ones_g; + tmp_block = space->extent.size; - /* Find first dimension w/block >1 */ - skip_dim = fast_dim; - for(i = (int)(fast_dim - 1); i >= 0; i--) - if(tdiminfo[i].block > 1) { - skip_dim = (unsigned)i; + /* Convert to hyperslab selection */ + if(H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection") + } /* end case */ break; - } /* end if */ - skip_slab = slab[skip_dim]; - - /* Check for being able to use fast algorithm for 1-D */ - if(0 == skip_dim) { - /* Create sequences until an entire row can't be used */ - blk_count = tot_blk_count; - while(blk_count > 0) { - /* Store the sequence information */ - *off++ = loc; - *len++ = actual_bytes; - /* Increment offset in destination buffer */ - loc += skip_slab; + case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ + /* Convert to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + HGOTO_DONE(SUCCEED); - /* Decrement block count */ - blk_count--; - } /* end while */ + case H5S_SELECT_NOOP: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + break; - /* Move to the next location */ - offset[skip_dim] += tot_blk_count; - } /* end if */ - else { - hsize_t tmp_block[H5S_MAX_RANK];/* Temporary block offset */ - hsize_t skip[H5S_MAX_RANK]; /* Bytes to skip between blocks */ - int temp_dim; /* Temporary rank holder */ + case H5S_SEL_HYPERSLABS: + /* Hyperslab operation on hyperslab selection, OK */ + break; - /* Set the starting block location */ - for(u = 0; u < ndims; u++) - tmp_block[u] = iter->u.hyp.off[u] - tdiminfo[u].start; + case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */ + if(op == H5S_SELECT_SET) /* Allow only "set" operation to proceed */ + break; + /* Else fall through to error */ - /* Compute the amount to skip between sequences */ - for(u = 0; u < ndims; u++) - skip[u] = (mem_size[u] - tdiminfo[u].block) * slab[u]; + case H5S_SEL_ERROR: + case H5S_SEL_N: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ - /* Create sequences until an entire row can't be used */ - blk_count = tot_blk_count; - while(blk_count > 0) { - /* Store the sequence information */ - *off++ = loc; - *len++ = actual_bytes; + if(op == H5S_SELECT_SET) { + /* If we are setting a new selection, remove current selection first */ + if(H5S_SELECT_RELEASE(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") - /* Set temporary dimension for advancing offsets */ - temp_dim = (int)skip_dim; + /* Allocate space for the hyperslab selection information */ + if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") - /* Increment offset in destination buffer */ - loc += skip_slab; + /* Save the diminfo */ + space->select.num_elem = 1; + for(u = 0; u < space->extent.rank; u++) { + space->select.sel_info.hslab->app_diminfo[u].start = start[u]; + space->select.sel_info.hslab->app_diminfo[u].stride = stride[u]; + space->select.sel_info.hslab->app_diminfo[u].count = count[u]; + space->select.sel_info.hslab->app_diminfo[u].block = block[u]; - /* Increment the offset and count for the other dimensions */ - while(temp_dim >= 0) { - /* Move to the next row in the curent dimension */ - offset[temp_dim]++; - tmp_block[temp_dim]++; + space->select.sel_info.hslab->opt_diminfo[u].start = start[u]; + space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u]; + space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u]; + space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u]; - /* If this block is still in the range of blocks to output for the dimension, break out of loop */ - if(tmp_block[temp_dim] < tdiminfo[temp_dim].block) - break; - else { - offset[temp_dim] = base_offset[temp_dim]; - loc += skip[temp_dim]; - tmp_block[temp_dim] = 0; - } /* end else */ + space->select.num_elem *= (opt_count[u] * opt_block[u]); + } /* end for */ - /* Decrement dimension count */ - temp_dim--; - } /* end while */ + /* Save unlim_dim */ + space->select.sel_info.hslab->unlim_dim = unlim_dim; - /* Decrement block count */ - blk_count--; - } /* end while */ - } /* end else */ - } /* end else */ + /* Indicate that the dimension information is valid */ + space->select.sel_info.hslab->diminfo_valid = TRUE; - /* Update the iterator, if there were any blocks used */ + /* Indicate that there's no slab information */ + space->select.sel_info.hslab->span_lst = NULL; - /* Decrement the number of elements left in selection */ - iter->elmt_left -= tot_blk_count * actual_elem; + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + /* Calculate num_elem_non_unlim */ + space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; + for(u = 0; u < space->extent.rank; u++) + if((int)u != unlim_dim) + space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); - /* Check if there are elements left in iterator */ - if(iter->elmt_left > 0) { - /* Update the iterator with the location we stopped */ - /* (Subtract out the selection offset) */ - for(u = 0; u < ndims; u++) - iter->u.hyp.off[u] = (hsize_t)((hssize_t)offset[u] - sel_off[u]); + /* Set num_elem */ + if(space->select.num_elem != (hsize_t)0) + space->select.num_elem = H5S_UNLIMITED; } /* end if */ - /* Increment the number of sequences generated */ - *nseq += tot_blk_count; - - /* Increment the number of elements used */ - *nelem += tot_blk_count * actual_elem; + /* Set selection type */ + space->select.type = H5S_sel_hyper; } /* end if */ + else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) { + /* Sanity check */ + HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - /* Check for partial block, with room for another sequence */ - if(io_left > (tot_blk_count * actual_elem) && tot_blk_count < maxseq) { - size_t elmt_remainder; /* Elements remaining */ + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + hsize_t tmp_count = opt_count[unlim_dim]; + hsize_t tmp_block = opt_block[unlim_dim]; + + /* Check for invalid operation */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") - /* Compute elements left */ - elmt_remainder = io_left - (tot_blk_count * actual_elem); - HDassert(elmt_remainder < fast_dim_block); - HDassert(elmt_remainder > 0); + /* Get bounds of existing selection */ + if(H5S__hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") - /* Store the sequence information */ - *off++ = loc; - *len++ = elmt_remainder * elem_size; + /* Patch count and block to remove unlimited and include the + * existing selection. + */ + H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, bounds_end[unlim_dim] + (hsize_t)1); + HDassert((tmp_count == 1) || (opt_count != H5S_hyper_ones_g)); + HDassert((tmp_block == 1) || (opt_block != H5S_hyper_ones_g)); + if(opt_count != H5S_hyper_ones_g) { + HDassert(opt_count == int_count); + int_count[unlim_dim] = tmp_count; + } /* end if */ + if(opt_block != H5S_hyper_ones_g) { + HDassert(opt_block == int_block); + int_block[unlim_dim] = tmp_block; + } /* end if */ + } /* end if */ - /* Update the iterator with the location we stopped */ - iter->u.hyp.off[fast_dim] += (hsize_t)elmt_remainder; + /* Check if there's no hyperslab span information currently */ + if(NULL == space->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - /* Decrement the number of elements left in selection */ - iter->elmt_left -= elmt_remainder; + /* Indicate that the regular dimensions are no longer valid */ + space->select.sel_info.hslab->diminfo_valid = FALSE; - /* Increment the number of sequences generated */ - (*nseq)++; + /* Set selection type */ + /* (Could be overridden by resetting selection to 'none', below) */ + space->select.type = H5S_sel_hyper; - /* Increment the number of elements used */ - *nelem += elmt_remainder; + /* Add in the new hyperslab information */ + if(H5S__generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - /* Sanity check */ - HDassert(*nseq > 0); - HDassert(*nelem > 0); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_single() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_select_hyperslab() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list + H5Sselect_hyperslab PURPOSE - Create a list of offsets & lengths for a selection + Specify a hyperslab to combine with the current hyperslab selection USAGE - herr_t H5S__hyper_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths + herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block) + hid_t dsid; IN: Dataspace ID of selection to modify + H5S_seloper_t op; IN: Operation to perform on current selection + const hsize_t *start; IN: Offset of start of hyperslab + const hsize_t *stride; IN: Hyperslab stride + const hsize_t *count; IN: Number of blocks included in hyperslab + const hsize_t *block; IN: Size of block in hyperslab RETURNS - Non-negative on success/Negative on failure. + Non-negative on success/Negative on failure DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. + Combines a hyperslab selection with the current selection for a dataspace. + If the current selection is not a hyperslab, it is freed and the hyperslab + parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a + selection composing the entire current extent). If STRIDE or BLOCK is + NULL, they are assumed to be set to all '1'. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +herr_t +H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[], + const hsize_t stride[], const hsize_t count[], const hsize_t block[]) { - herr_t ret_value = FAIL; /* return value */ + H5S_t *space; /* Dataspace to modify selection of */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iSs*h*h*h*h", space_id, op, start, stride, count, block); /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(iter->elmt_left > 0); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); - HDassert(space->select.sel_info.hslab->unlim_dim < 0); - - /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ - const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t *mem_size; /* Size of the source buffer */ - unsigned ndims; /* Number of dimensions of dataset */ - unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ - hbool_t single_block; /* Whether the selection is a single block */ + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space") + if(H5S_NULL == H5S_GET_EXTENT_TYPE(space)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space") + if(start == NULL || count == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified") + if(!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID)) + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + if(stride != NULL) { unsigned u; /* Local index variable */ - /* Set a local copy of the diminfo pointer */ - tdiminfo = iter->u.hyp.diminfo; - - /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { - /* Set the aliases for a few important dimension ranks */ - ndims = iter->u.hyp.iter_rank; - - /* Set the local copy of the selection offset */ - sel_off = iter->u.hyp.sel_off; - - /* Set up the pointer to the size of the memory space */ - mem_size = iter->u.hyp.size; - } /* end if */ - else { - /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; - - /* Set the local copy of the selection offset */ - sel_off = space->select.offset; - - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; - } /* end else */ - fast_dim = ndims - 1; - - /* Check if we stopped in the middle of a sequence of elements */ - if((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || - ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1)) { - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ - hsize_t loc; /* Coordinate offset */ - hsize_t acc; /* Accumulator */ - size_t leftover; /* The number of elements left over from the last sequence */ - size_t actual_elem; /* The actual number of elements to count */ - size_t elem_size; /* Size of each element iterating over */ - int i; /* Local index variable */ - - - /* Calculate the number of elements left in the sequence */ - if(tdiminfo[fast_dim].count == 1) { - H5_CHECKED_ASSIGN(leftover, size_t, tdiminfo[fast_dim].block - (iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start), hsize_t); - } /* end if */ - else { - H5_CHECKED_ASSIGN(leftover, size_t, tdiminfo[fast_dim].block - ((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride), hsize_t); - } /* end else */ - - /* Make certain that we don't write too many */ - actual_elem = MIN3(leftover, (size_t)iter->elmt_left, maxelem); - - /* Initialize row sizes for each dimension */ - elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; - } /* end for */ - - /* Compute the initial buffer offset */ - for(u = 0, loc = 0; u < ndims; u++) - loc += ((hsize_t)((hssize_t)iter->u.hyp.off[u] + sel_off[u])) * slab[u]; - - /* Add a new sequence */ - off[0] = loc; - H5_CHECKED_ASSIGN(len[0], size_t, actual_elem * elem_size, hsize_t); - - /* Increment sequence array locations */ - off++; - len++; - - /* Advance the hyperslab iterator */ - H5S__hyper_iter_next(iter, actual_elem); - - /* Decrement the number of elements left in selection */ - iter->elmt_left -= actual_elem; - - /* Decrement element/sequence limits */ - maxelem -= actual_elem; - maxseq--; - - /* Set the number of sequences generated and elements used */ - *nseq = 1; - *nelem = actual_elem; - - /* Check for using up all the sequences/elements */ - if(0 == iter->elmt_left || 0 == maxelem || 0 == maxseq) - return(SUCCEED); - } /* end if */ - else { - /* Reset the number of sequences generated and elements used */ - *nseq = 0; - *nelem = 0; - } /* end else */ - - /* Check for a single block selected */ - single_block = TRUE; - for(u = 0; u < ndims; u++) - if(1 != tdiminfo[u].count) { - single_block = FALSE; - break; - } /* end if */ - - /* Check for single block selection */ - if(single_block) - /* Use single-block optimized call to generate sequence list */ - ret_value = H5S__hyper_get_seq_list_single(space, iter, maxseq, maxelem, nseq, nelem, off, len); - else - /* Use optimized call to generate sequence list */ - ret_value = H5S__hyper_get_seq_list_opt(space, iter, maxseq, maxelem, nseq, nelem, off, len); + /* Check for 0-sized strides */ + for(u = 0; u < space->extent.rank; u++) + if(stride[u] == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stride==0 value") } /* end if */ - else - /* Call the general sequence generator routine */ - ret_value = H5S__hyper_get_seq_list_gen(space, iter, maxseq, maxelem, nseq, nelem, off, len); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_get_seq_list() */ + if(H5S_select_hyperslab(space, op, start, stride, count, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Sselect_hyperslab() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 2ebe987..01ec3e1 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -31,12 +31,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5Pprivate.h" /* Property lists */ #include "H5Spkg.h" /* Dataspaces */ #include "H5VMprivate.h" /* Vector and array functions */ @@ -97,6 +92,8 @@ static herr_t H5S__mpio_create_large_type(hsize_t, MPI_Aint, MPI_Datatype , MPI_ static hsize_t bigio_count = H5S_MAX_MPI_COUNT; + + /*------------------------------------------------------------------------- * Function: H5S_mpio_set_bigio_count * diff --git a/src/H5Snone.c b/src/H5Snone.c index c867e67..86994dd 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -334,6 +334,64 @@ H5S__none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) /*-------------------------------------------------------------------------- NAME + H5S__none_get_seq_list + PURPOSE + Create a list of offsets & lengths for a selection + USAGE + herr_t H5S__none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets + size_t *len; OUT: Array of lengths + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t H5_ATTR_UNUSED *iter, + size_t H5_ATTR_UNUSED maxseq, size_t H5_ATTR_UNUSED maxelem, size_t *nseq, size_t *nelem, + hsize_t H5_ATTR_UNUSED *off, size_t H5_ATTR_UNUSED *len) +{ + FUNC_ENTER_STATIC_NOERR + + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); + + /* "none" selections don't generate sequences of bytes */ + *nseq = 0; + + /* They don't use any elements, either */ + *nelem = 0; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__none_get_seq_list() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__none_iter_release PURPOSE Release "none" selection iterator information for a dataspace @@ -941,61 +999,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Sselect_none() */ - -/*-------------------------------------------------------------------------- - NAME - H5S__none_get_seq_list - PURPOSE - Create a list of offsets & lengths for a selection - USAGE - herr_t H5S__none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t H5_ATTR_UNUSED *iter, - size_t H5_ATTR_UNUSED maxseq, size_t H5_ATTR_UNUSED maxelem, size_t *nseq, size_t *nelem, - hsize_t H5_ATTR_UNUSED *off, size_t H5_ATTR_UNUSED *len) -{ - FUNC_ENTER_STATIC_NOERR - - /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); - - /* "none" selections don't generate sequences of bytes */ - *nseq = 0; - - /* They don't use any elements, either */ - *nelem = 0; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__none_get_seq_list() */ - diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 1fbfa35..0575f03 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -116,7 +116,7 @@ struct H5S_hyper_span_info_t { struct H5S_hyper_span_t *head; /* Pointer to list of spans in next dimension down */ }; -/* Information about new-style hyperslab selection */ +/* Information about 'diminfo' form of hyperslab selection */ typedef struct { hbool_t diminfo_valid; /* Whether the dataset has valid diminfo */ H5S_hyper_dim_t opt_diminfo[H5S_MAX_RANK]; /* per-dim selection info */ @@ -280,7 +280,7 @@ H5_DLL herr_t H5S__extent_release(H5S_extent_t *extent); H5_DLL herr_t H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max); -/* Operations on selections */ +/* Operations on hyperslab selections */ H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, const H5S_t *src_intersect_space, H5S_t *proj_space); H5_DLL herr_t H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space); diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 11cf448..6411b94 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -371,6 +371,144 @@ H5S__point_iter_next_block(H5S_sel_iter_t *iter) /*-------------------------------------------------------------------------- NAME + H5S__point_get_seq_list + PURPOSE + Create a list of offsets & lengths for a selection + USAGE + herr_t H5S__point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + H5S_t *space; IN: Dataspace containing selection to use. + unsigned flags; IN: Flags for extra information about operation + H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last + position of interest in selection. + size_t maxseq; IN: Maximum number of sequences to generate + size_t maxelem; IN: Maximum number of elements to include in the + generated sequences + size_t *nseq; OUT: Actual number of sequences generated + size_t *nelem; OUT: Actual number of elements in sequences generated + hsize_t *off; OUT: Array of offsets (in bytes) + size_t *len; OUT: Array of lengths (in bytes) + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + Use the selection in the dataspace to generate a list of byte offsets and + lengths for the region(s) selected. Start/Restart from the position in the + ITER parameter. The number of sequences generated is limited by the MAXSEQ + parameter and the number of sequences actually generated is stored in the + NSEQ parameter. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, + size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, + hsize_t *off, size_t *len) +{ + size_t io_left; /* The number of bytes left in the selection */ + size_t start_io_left; /* The initial number of bytes left in the selection */ + H5S_pnt_node_t *node; /* Point node */ + hsize_t dims[H5S_MAX_RANK]; /* Total size of memory buf */ + int ndims; /* Dimensionality of space*/ + hsize_t acc; /* Coordinate accumulator */ + hsize_t loc; /* Coordinate offset */ + size_t curr_seq; /* Current sequence being operated on */ + int i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + HDassert(space); + HDassert(iter); + HDassert(maxseq > 0); + HDassert(maxelem > 0); + HDassert(nseq); + HDassert(nelem); + HDassert(off); + HDassert(len); + + /* Choose the minimum number of bytes to sequence through */ + H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); + start_io_left = io_left = (size_t)MIN(iter->elmt_left, maxelem); + + /* Get the dataspace dimensions */ + if((ndims = H5S_get_simple_extent_dims (space, dims, NULL)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve dataspace dimensions") + + /* Walk through the points in the selection, starting at the current */ + /* location in the iterator */ + node = iter->u.pnt.curr; + curr_seq = 0; + while(NULL != node) { + /* Compute the offset of each selected point in the buffer */ + for(i = ndims - 1, acc = iter->elmt_size, loc = 0; i >= 0; i--) { + loc += (hsize_t)((hssize_t)node->pnt[i] + space->select.offset[i]) * acc; + acc *= dims[i]; + } /* end for */ + + /* Check if this is a later point in the selection */ + if(curr_seq > 0) { + /* If a sorted sequence is requested, make certain we don't go backwards in the offset */ + if((flags&H5S_GET_SEQ_LIST_SORTED) && locelmt_size; + } /* end if */ + else { + /* Add a new sequence */ + off[curr_seq] = loc; + len[curr_seq] = iter->elmt_size; + + /* Increment sequence count */ + curr_seq++; + } /* end else */ + } /* end if */ + else { + /* Add a new sequence */ + off[curr_seq] = loc; + len[curr_seq] = iter->elmt_size; + + /* Increment sequence count */ + curr_seq++; + } /* end else */ + + /* Decrement number of elements left to process */ + io_left--; + + /* Move the iterator */ + iter->u.pnt.curr = node->next; + iter->elmt_left--; + + /* Check if we're finished with all sequences */ + if(curr_seq == maxseq) + break; + + /* Check if we're finished with all the elements available */ + if(io_left == 0) + break; + + /* Advance to the next point */ + node = node->next; + } /* end while */ + + /* Set the number of sequences generated */ + *nseq = curr_seq; + + /* Set the number of elements used */ + *nelem = start_io_left - io_left; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__point_get_seq_list() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__point_iter_release PURPOSE Release point selection iterator information for a dataspace @@ -525,7 +663,7 @@ H5S__point_release(H5S_t *space) { H5S_pnt_node_t *curr, *next; /* Point selection nodes */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); @@ -640,6 +778,7 @@ H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selec FUNC_ENTER_STATIC + /* Sanity checks */ HDassert(src); HDassert(dst); @@ -1651,141 +1790,3 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Sselect_elements() */ - -/*-------------------------------------------------------------------------- - NAME - H5S__point_get_seq_list - PURPOSE - Create a list of offsets & lengths for a selection - USAGE - herr_t H5S__point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation - H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last - position of interest in selection. - size_t maxseq; IN: Maximum number of sequences to generate - size_t maxelem; IN: Maximum number of elements to include in the - generated sequences - size_t *nseq; OUT: Actual number of sequences generated - size_t *nelem; OUT: Actual number of elements in sequences generated - hsize_t *off; OUT: Array of offsets - size_t *len; OUT: Array of lengths - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Use the selection in the dataspace to generate a list of byte offsets and - lengths for the region(s) selected. Start/Restart from the position in the - ITER parameter. The number of sequences generated is limited by the MAXSEQ - parameter and the number of sequences actually generated is stored in the - NSEQ parameter. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) -{ - size_t io_left; /* The number of bytes left in the selection */ - size_t start_io_left; /* The initial number of bytes left in the selection */ - H5S_pnt_node_t *node; /* Point node */ - hsize_t dims[H5S_MAX_RANK]; /* Total size of memory buf */ - int ndims; /* Dimensionality of space*/ - hsize_t acc; /* Coordinate accumulator */ - hsize_t loc; /* Coordinate offset */ - size_t curr_seq; /* Current sequence being operated on */ - int i; /* Local index variable */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_STATIC - - /* Check args */ - HDassert(space); - HDassert(iter); - HDassert(maxseq > 0); - HDassert(maxelem > 0); - HDassert(nseq); - HDassert(nelem); - HDassert(off); - HDassert(len); - - /* Choose the minimum number of bytes to sequence through */ - H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - start_io_left = io_left = (size_t)MIN(iter->elmt_left, maxelem); - - /* Get the dataspace dimensions */ - if((ndims = H5S_get_simple_extent_dims (space, dims, NULL)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve dataspace dimensions") - - /* Walk through the points in the selection, starting at the current */ - /* location in the iterator */ - node = iter->u.pnt.curr; - curr_seq = 0; - while(NULL != node) { - /* Compute the offset of each selected point in the buffer */ - for(i = ndims - 1, acc = iter->elmt_size, loc = 0; i >= 0; i--) { - loc += (hsize_t)((hssize_t)node->pnt[i] + space->select.offset[i]) * acc; - acc *= dims[i]; - } /* end for */ - - /* Check if this is a later point in the selection */ - if(curr_seq>0) { - /* If a sorted sequence is requested, make certain we don't go backwards in the offset */ - if((flags&H5S_GET_SEQ_LIST_SORTED) && locelmt_size; - } /* end if */ - else { - /* Add a new sequence */ - off[curr_seq]=loc; - len[curr_seq]=iter->elmt_size; - - /* Increment sequence count */ - curr_seq++; - } /* end else */ - } /* end if */ - else { - /* Add a new sequence */ - off[curr_seq]=loc; - len[curr_seq]=iter->elmt_size; - - /* Increment sequence count */ - curr_seq++; - } /* end else */ - - /* Decrement number of elements left to process */ - io_left--; - - /* Move the iterator */ - iter->u.pnt.curr=node->next; - iter->elmt_left--; - - /* Check if we're finished with all sequences */ - if(curr_seq==maxseq) - break; - - /* Check if we're finished with all the elements available */ - if(io_left==0) - break; - - /* Advance to the next point */ - node=node->next; - } /* end while */ - - /* Set the number of sequences generated */ - *nseq=curr_seq; - - /* Set the number of elements used */ - *nelem=start_io_left-io_left; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__point_get_seq_list() */ - diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 24db889..f4e0006 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -58,7 +58,7 @@ typedef struct H5S_hyper_dim_t { /* Point selection iteration container */ typedef struct { - H5S_pnt_node_t *curr; /* Pointer to next node to output */ + H5S_pnt_node_t *curr; /* Pointer to next node to output */ } H5S_point_iter_t; /* Hyperslab selection iteration container */ @@ -286,9 +286,6 @@ H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords); H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space); H5_DLL herr_t H5S_hyper_convert(H5S_t *space); -#ifdef LATER -H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2); -#endif /* LATER */ H5_DLL htri_t H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end); H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset); H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); @@ -304,7 +301,8 @@ H5_DLL hsize_t H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hbool_t *partial); /* Operations on selection iterators */ -H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); +H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, + size_t elmt_size); H5_DLL herr_t H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords); H5_DLL hsize_t H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter); H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index b7129ca..561875a 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -127,16 +127,6 @@ H5_DLL herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint, H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[], const hsize_t _stride[], const hsize_t count[], const hsize_t _block[]); -/* #define NEW_HYPERSLAB_API */ -/* Note that these haven't been working for a while and were never - * publicly released - QAK */ -#ifdef NEW_HYPERSLAB_API -H5_DLL hid_t H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, - const hsize_t start[], const hsize_t _stride[], const hsize_t count[], - const hsize_t _block[]); -H5_DLL herr_t H5Sselect_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id); -H5_DLL hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id); -#endif /* NEW_HYPERSLAB_API */ H5_DLL htri_t H5Sis_regular_hyperslab(hid_t spaceid); H5_DLL htri_t H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[], hsize_t stride[], hsize_t count[], hsize_t block[]); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 4d7fc4f..24586de 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -295,43 +295,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5S_select_get_seq_list - * - * Purpose: Retrieves the next sequence of offset/length pairs for an - * iterator on a dataspace - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, May 18, 2004 - * - * Note: This routine participates in the "Inlining C function pointers" - * pattern, don't call it directly, use the appropriate macro - * defined in H5Sprivate.h. - * - *------------------------------------------------------------------------- - */ -herr_t -H5S_select_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len) -{ - herr_t ret_value = FAIL; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(space); - - /* Call the selection type's get_seq_list function */ - if((ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_get_seq_list() */ - - -/*------------------------------------------------------------------------- * Function: H5S_select_serial_size * * Purpose: Determines the number of bytes required to store the current @@ -1425,6 +1388,44 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter) #endif /* LATER */ +/*------------------------------------------------------------------------- + * Function: H5S_select_get_seq_list + * + * Purpose: Retrieves the next sequence of offset/length pairs for an + * iterator on a dataspace + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, May 18, 2004 + * + * Note: This routine participates in the "Inlining C function pointers" + * pattern, don't call it directly, use the appropriate macro + * defined in H5Sprivate.h. + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_select_get_seq_list(const H5S_t *space, unsigned flags, + H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, + size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len) +{ + herr_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(space); + + /* Call the selection type's get_seq_list function */ + if((ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_select_get_seq_list() */ + + /*-------------------------------------------------------------------------- NAME H5S_select_iter_release @@ -1731,8 +1732,6 @@ H5S_get_select_type(const H5S_t *space) Assumes that there is only a single "block" for hyperslab selections. EXAMPLES REVISION LOG - Modified function to view identical shapes with different dimensions - as being the same under some circumstances. --------------------------------------------------------------------------*/ htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) @@ -1912,11 +1911,11 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) space_a_dim = (int)space_a_rank - 1; space_b_dim = (int)space_b_rank - 1; - /* The first block only compares the sizes and sets the - * relative offsets for later blocks + /* The first block only compares the sizes and sets the + * relative offsets for later blocks */ if(first_block) { - /* If the block sizes in the common dimensions from + /* If the block sizes in the common dimensions from * each selection don't match, get out */ while(space_b_dim >= 0) { @@ -1932,7 +1931,7 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) space_b_dim--; } /* end while */ - /* similarly, if the block size in any dimension that appears only + /* Similarly, if the block size in any dimension that appears only * in space_a is not equal to 1, get out. */ while(space_a_dim >= 0) { @@ -1950,7 +1949,7 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) } /* end if */ /* Check over the blocks for each selection */ else { - /* for dimensions that space_a and space_b have in common: */ + /* For dimensions that space_a and space_b have in common: */ while(space_b_dim >= 0) { /* Check if the blocks are in the same relative location */ if((start_a[space_a_dim] - off_a[space_a_dim]) != diff --git a/test/tselect.c b/test/tselect.c index 9150b11..011be7c 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -4910,365 +4910,6 @@ test_select_hyper_union(void) HDfree(rbuf); } /* test_select_hyper_union() */ -#ifdef NEW_HYPERSLAB_API -/**************************************************************** -** -** test_select_hyper_union_stagger(): Test basic H5S (dataspace) selection code. -** Tests unions of staggered hyperslabs. (Uses H5Scombine_hyperslab -** and H5Sselect_select instead of H5Sselect_hyperslab) -** -****************************************************************/ -static void -test_select_hyper_union_stagger(void) -{ - hid_t file_id; /* File ID */ - hid_t dset_id; /* Dataset ID */ - hid_t dataspace; /* File dataspace ID */ - hid_t memspace; /* Memory dataspace ID */ - hid_t tmp_space; /* Temporary dataspace ID */ - hid_t tmp2_space; /* Another emporary dataspace ID */ - hsize_t dimsm[2]={7,7}; /* Memory array dimensions */ - hsize_t dimsf[2]={6,5}; /* File array dimensions */ - hsize_t count[2]={3,1}; /* 1st Hyperslab size */ - hsize_t count2[2]={3,1}; /* 2nd Hyperslab size */ - hsize_t count3[2]={2,1}; /* 3rd Hyperslab size */ - hssize_t offset[2]={0,0}; /* 1st Hyperslab offset */ - hssize_t offset2[2]={2,1}; /* 2nd Hyperslab offset */ - hssize_t offset3[2]={4,2}; /* 3rd Hyperslab offset */ - hsize_t count_out[2]={4,2}; /* Hyperslab size in memory */ - hssize_t offset_out[2]={0,3}; /* Hyperslab offset in memory */ - int data[6][5]; /* Data to write */ - int data_out[7][7]; /* Data read in */ - int input_loc[8][2]={{0,0}, - {1,0}, - {2,0}, - {2,1}, - {3,1}, - {4,1}, - {4,2}, - {5,2}}; - int output_loc[8][2]={{0,3}, - {0,4}, - {1,3}, - {1,4}, - {2,3}, - {2,4}, - {3,3}, - {3,4}}; - int dsetrank=2; /* File Dataset rank */ - int memrank=2; /* Memory Dataset rank */ - int i,j; /* Local counting variables */ - herr_t error; - hsize_t stride[2]={1,1}; - hsize_t block[2]={1,1}; - - /* Initialize data to write */ - for(i=0; i<6; i++) - for(j=0; j<5; j++) - data[i][j] = j*10 + i; - - /* Create file */ - file_id=H5Fcreate(FILENAME,H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT); - CHECK(file_id, FAIL, "H5Fcreate"); - - /* Create File Dataspace */ - dataspace=H5Screate_simple(dsetrank,dimsf,NULL); - CHECK(dataspace, FAIL, "H5Screate_simple"); - - /* Create File Dataset */ - dset_id=H5Dcreate2(file_id,"IntArray",H5T_NATIVE_INT,dataspace,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset_id, FAIL, "H5Dcreate2"); - - /* Write File Dataset */ - error=H5Dwrite(dset_id,H5T_NATIVE_INT,dataspace,dataspace,H5P_DEFAULT,data); - CHECK(error, FAIL, "H5Dwrite"); - - /* Close things */ - error=H5Sclose(dataspace); - CHECK(error, FAIL, "H5Sclose"); - error = H5Dclose(dset_id); - CHECK(error, FAIL, "H5Dclose"); - error = H5Fclose(file_id); - CHECK(error, FAIL, "H5Fclose"); - - /* Initialize intput buffer */ - memset(data_out, 0, 7 * 7 * sizeof(int)); - - /* Open file */ - file_id = H5Fopen(FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(file_id, FAIL, "H5Fopen"); - - /* Open dataset */ - dset_id = H5Dopen2(file_id, "IntArray", H5P_DEFAULT); - CHECK(dset_id, FAIL, "H5Dopen2"); - - /* Get the dataspace */ - dataspace = H5Dget_space(dset_id); - CHECK(dataspace, FAIL, "H5Dget_space"); - - /* Select the hyperslabs */ - error = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, stride, count, block); - CHECK(error, FAIL, "H5Sselect_hyperslab"); - tmp_space = H5Scombine_hyperslab(dataspace, H5S_SELECT_OR, offset2, stride, count2, block); - CHECK(tmp_space, FAIL, "H5Scombine_hyperslab"); - - /* Copy the file dataspace and select hyperslab */ - tmp2_space = H5Scopy(dataspace); - CHECK(tmp2_space, FAIL, "H5Scopy"); - error=H5Sselect_hyperslab(tmp2_space,H5S_SELECT_SET,offset3,stride,count3,block); - CHECK(error, FAIL, "H5Sselect_hyperslab"); - - /* Combine the copied dataspace with the temporary dataspace */ - error=H5Sselect_select(tmp_space,H5S_SELECT_OR,tmp2_space); - CHECK(error, FAIL, "H5Sselect_select"); - - /* Create Memory Dataspace */ - memspace=H5Screate_simple(memrank,dimsm,NULL); - CHECK(memspace, FAIL, "H5Screate_simple"); - - /* Select hyperslab in memory */ - error=H5Sselect_hyperslab(memspace,H5S_SELECT_SET,offset_out,stride,count_out,block); - CHECK(error, FAIL, "H5Sselect_hyperslab"); - - /* Read File Dataset */ - error=H5Dread(dset_id,H5T_NATIVE_INT,memspace,tmp_space,H5P_DEFAULT,data_out); - CHECK(error, FAIL, "H5Dread"); - - /* Verify input data */ - for(i=0; i<8; i++) { - if(data[input_loc[i][0]][input_loc[i][1]]!=data_out[output_loc[i][0]][output_loc[i][1]]) { - printf("input data #%d is wrong!\n",i); - printf("input_loc=[%d][%d]\n",input_loc[i][0],input_loc[i][1]); - printf("output_loc=[%d][%d]\n",output_loc[i][0],output_loc[i][1]); - printf("data=%d\n",data[input_loc[i][0]][input_loc[i][1]]); - TestErrPrintf("data_out=%d\n",data_out[output_loc[i][0]][output_loc[i][1]]); - } /* end if */ - } /* end for */ - - /* Close things */ - error=H5Sclose(tmp2_space); - CHECK(error, FAIL, "H5Sclose"); - error=H5Sclose(tmp_space); - CHECK(error, FAIL, "H5Sclose"); - error=H5Sclose(dataspace); - CHECK(error, FAIL, "H5Sclose"); - error=H5Sclose(memspace); - CHECK(error, FAIL, "H5Sclose"); - error=H5Dclose(dset_id); - CHECK(error, FAIL, "H5Dclose"); - error=H5Fclose(file_id); - CHECK(error, FAIL, "H5Fclose"); -} - -/**************************************************************** -** -** test_select_hyper_union_3d(): Test basic H5S (dataspace) selection code. -** Tests unions of hyperslabs in 3-D (Uses H5Scombine_hyperslab -** and H5Scombine_select instead of H5Sselect_hyperslab) -** -****************************************************************/ -static void -test_select_hyper_union_3d(void) -{ - hid_t fid1; /* HDF5 File IDs */ - hid_t dataset; /* Dataset ID */ - hid_t sid1,sid2; /* Dataspace ID */ - hid_t tmp_space; /* Temporary Dataspace ID */ - hid_t tmp2_space; /* Another temporary Dataspace ID */ - hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3}; - hsize_t dims2[] = {SPACE4_DIM1, SPACE4_DIM2, SPACE4_DIM3}; - hsize_t dims3[] = {SPACE3_DIM1, SPACE3_DIM2}; - hsize_t start[SPACE1_RANK]; /* Starting location of hyperslab */ - hsize_t stride[SPACE1_RANK]; /* Stride of hyperslab */ - hsize_t count[SPACE1_RANK]; /* Element count of hyperslab */ - hsize_t block[SPACE1_RANK]; /* Block size of hyperslab */ - struct row_list { - size_t z; - size_t y; - size_t x; - size_t l; - } rows[]= { /* Array of x,y,z coordinates & length for each row written from memory */ - {0,0,0,6}, /* 1st face of 3-D object */ - {0,1,0,6}, - {0,2,0,6}, - {0,3,0,6}, - {0,4,0,6}, - {1,0,0,6}, /* 2nd face of 3-D object */ - {1,1,0,6}, - {1,2,0,6}, - {1,3,0,6}, - {1,4,0,6}, - {2,0,0,6}, /* 3rd face of 3-D object */ - {2,1,0,10}, - {2,2,0,10}, - {2,3,0,10}, - {2,4,0,10}, - {2,5,2,8}, - {2,6,2,8}, - {3,0,0,6}, /* 4th face of 3-D object */ - {3,1,0,10}, - {3,2,0,10}, - {3,3,0,10}, - {3,4,0,10}, - {3,5,2,8}, - {3,6,2,8}, - {4,0,0,6}, /* 5th face of 3-D object */ - {4,1,0,10}, - {4,2,0,10}, - {4,3,0,10}, - {4,4,0,10}, - {4,5,2,8}, - {4,6,2,8}, - {5,1,2,8}, /* 6th face of 3-D object */ - {5,2,2,8}, - {5,3,2,8}, - {5,4,2,8}, - {5,5,2,8}, - {5,6,2,8}, - {6,1,2,8}, /* 7th face of 3-D object */ - {6,2,2,8}, - {6,3,2,8}, - {6,4,2,8}, - {6,5,2,8}, - {6,6,2,8}, - {7,1,2,8}, /* 8th face of 3-D object */ - {7,2,2,8}, - {7,3,2,8}, - {7,4,2,8}, - {7,5,2,8}, - {7,6,2,8}}; - uint8_t *wbuf, /* buffer to write to disk */ - *rbuf, /* buffer read from disk */ - *tbuf, /* temporary buffer pointer */ - *tbuf2; /* temporary buffer pointer */ - int i,j,k; /* Counters */ - herr_t ret; /* Generic return value */ - hsize_t npoints; /* Number of elements in selection */ - - /* Output message about test being performed */ - MESSAGE(5, ("Testing Hyperslab Selection Functions with unions of 3-D hyperslabs\n")); - - /* Allocate write & read buffers */ - wbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE4_DIM1 * SPACE4_DIM2 * SPACE4_DIM3); - CHECK(wbuf, NULL, "HDmalloc"); - rbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), SPACE3_DIM1 * SPACE3_DIM2); - CHECK(rbuf, NULL, "HDcalloc"); - - /* Initialize write buffer */ - for(i=0, tbuf=wbuf; i Date: Thu, 14 Feb 2019 19:27:02 -0600 Subject: Adding documentation Description Added detail about the argument "fields" of H5Object::visit. --- c++/src/H5Object.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 03558e9..e8cec97 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -252,7 +252,13 @@ int H5Object::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_dat ///\param *op_data - IN: User-defined pointer to data required by the /// application for its processing of the object ///\param fields - IN: Flags specifying the fields to be retrieved -/// to the callback op +/// to the callback op via the H5O_info_t argument. +/// \li \c H5O_INFO_BASIC fileno, addr, type, and rc fields +/// \li \c H5O_INFO_TIME atime, mtime, ctime, and btime fields +/// \li \c H5O_INFO_NUM_ATTRS num_attrs field +/// \li \c H5O_INFO_HDR hdr field +/// \li \c H5O_INFO_META_SIZE meta_size field +/// \li \c H5O_INFO_ALL H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE ///\return /// \li On success: /// \li the return value of the first operator that returns a positive value -- cgit v0.12 From f2f890fd8292fb8db1d42e3844f8bc65bccf6453 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Thu, 14 Feb 2019 19:40:10 -0600 Subject: Removed an extra "using" statement --- c++/src/H5Object.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index e8cec97..8d3334b 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -12,8 +12,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include -#include -using namespace std; #include "H5private.h" // for HDmemset #include "H5Include.h" -- cgit v0.12 From 122b63a5a27227f2349634f4e8f8e43d739255f5 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Fri, 15 Feb 2019 15:48:24 -0600 Subject: HDFFV-10703 Update CMake commands to latest standard --- CMakeInstallation.cmake | 7 +- CMakeLists.txt | 6 +- MANIFEST | 1 - c++/examples/CMakeTests.cmake | 8 +-- config/cmake/hdf5-config-version.cmake.in | 58 --------------- config/cmake/hdf5-config.cmake.in | 28 ++++---- config/cmake/jrunTest.cmake | 8 +-- config/cmake/userblockTest.cmake | 8 +-- config/cmake_ext_mod/ConfigureChecks.cmake | 8 +-- config/cmake_ext_mod/HDFUseCXX.cmake | 4 +- config/cmake_ext_mod/runTest.cmake | 8 +-- examples/CMakeTests.cmake | 12 ++-- fortran/examples/CMakeTests.cmake | 12 ++-- fortran/test/CMakeTests.cmake | 2 +- hl/examples/CMakeTests.cmake | 4 +- hl/fortran/test/CMakeLists.txt | 4 +- hl/fortran/test/CMakeTests.cmake | 4 +- hl/test/CMakeTests.cmake | 4 +- hl/tools/h5watch/CMakeTests.cmake | 2 +- java/examples/datasets/CMakeLists.txt | 6 +- java/examples/datatypes/CMakeLists.txt | 4 +- java/examples/groups/CMakeLists.txt | 10 +-- java/examples/intro/CMakeLists.txt | 4 +- java/src/hdf/hdf5lib/H5.java | 4 ++ test/CMakeLists.txt | 20 +++--- test/CMakeTests.cmake | 40 +++++------ test/CMakeVFDTests.cmake | 20 +++--- test/CMakeVOLTests.cmake | 14 ++-- test/flushrefreshTest.cmake | 102 +++++++++++++-------------- testpar/CMakeLists.txt | 4 +- testpar/CMakeTests.cmake | 18 ++--- testpar/CMakeVFDTests.cmake | 22 +++--- tools/test/h5copy/CMakeTests.cmake | 34 ++++----- tools/test/h5diff/CMakeTests.cmake | 16 ++--- tools/test/h5dump/CMakeTests.cmake | 22 +++--- tools/test/h5dump/CMakeTestsPBITS.cmake | 6 +- tools/test/h5dump/CMakeTestsVDS.cmake | 14 ++-- tools/test/h5dump/CMakeTestsXML.cmake | 6 +- tools/test/h5format_convert/CMakeTests.cmake | 76 ++++++++------------ tools/test/h5import/CMakeTests.cmake | 4 +- tools/test/h5jam/CMakeTests.cmake | 8 +-- tools/test/h5ls/CMakeTests.cmake | 10 +-- tools/test/h5ls/CMakeTestsVDS.cmake | 10 +-- tools/test/h5repack/CMakeTests.cmake | 36 +++++----- tools/test/h5repack/CMakeVFDTests.cmake | 2 +- tools/test/h5stat/CMakeTests.cmake | 14 ++-- tools/test/misc/CMakeTestsClear.cmake | 24 +++---- tools/test/misc/CMakeTestsMkgrp.cmake | 4 +- 48 files changed, 335 insertions(+), 407 deletions(-) delete mode 100644 config/cmake/hdf5-config-version.cmake.in diff --git a/CMakeInstallation.cmake b/CMakeInstallation.cmake index 7a0746a..6d05a58 100644 --- a/CMakeInstallation.cmake +++ b/CMakeInstallation.cmake @@ -104,9 +104,10 @@ endif () # Configure the hdf5-config-version .cmake file for the install directory #----------------------------------------------------------------------------- if (NOT HDF5_EXTERNALLY_CONFIGURED) - configure_file ( - ${HDF_RESOURCES_DIR}/hdf5-config-version.cmake.in - ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake @ONLY + write_basic_package_version_file ( + ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake + VERSION ${HDF5_PACKAGE_VERSION} + COMPATIBILITY SameMinorVersion ) install ( FILES ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index b9cdf4d..6446a7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ project (HDF5 C) # set CMAKE_INSTALL_PREFIX to the required install path. # Make install can be used to install all components for system-wide use. # -if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) MESSAGE(FATAL_ERROR "\nERROR! ${PROJECT_NAME} DOES NOT SUPPORT IN SOURCE BUILDS!\n" "CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" " == CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}\n" @@ -314,7 +314,7 @@ set (HDF5_PACKAGE_NAME "HDF5") set (HDF5_PACKAGE_VERSION "${H5_VERS_MAJOR}.${H5_VERS_MINOR}.${H5_VERS_RELEASE}") set (HDF5_PACKAGE_VERSION_MAJOR "${H5_VERS_MAJOR}.${H5_VERS_MINOR}") set (HDF5_PACKAGE_VERSION_MINOR "${H5_VERS_RELEASE}") -if (NOT "${H5_VERS_SUBRELEASE}" STREQUAL "") +if (H5_VERS_SUBRELEASE) set (HDF5_PACKAGE_VERSION_STRING "${HDF5_PACKAGE_VERSION}-${H5_VERS_SUBRELEASE}") else () set (HDF5_PACKAGE_VERSION_STRING "${HDF5_PACKAGE_VERSION}") @@ -845,7 +845,7 @@ if (EXISTS "${HDF5_SOURCE_DIR}/fortran" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/for message (STATUS "Fortran compiler ID is ${CMAKE_Fortran_COMPILER_ID}") # Building with PGI requires CMake 3.3 or greater because previous versions # of CMake add the wrong compiler flag for the PGI Fortran compiler. - if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "PGI" AND "${CMAKE_VERSION}" VERSION_LESS "3.3") + if (CMAKE_Fortran_COMPILER_ID MATCHES "PGI" AND CMAKE_VERSION VERSION_LESS "3.3") message (FATAL_ERROR " **** PGI FORTRAN REQUIRES CMAKE VERSION 3.3 OR GREATER **** ") endif () diff --git a/MANIFEST b/MANIFEST index 6c2018a..0b2026d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -3240,7 +3240,6 @@ ./config/cmake/H5cxx_config.h.in ./config/cmake/H5pubconf.h.in ./config/cmake/hdf5-config.cmake.in -./config/cmake/hdf5-config-version.cmake.in ./config/cmake/HDFCompilerFlags.cmake ./config/cmake/HDF5_Process_Flex_Files.cmake ./config/cmake/HDF5Macros.cmake diff --git a/c++/examples/CMakeTests.cmake b/c++/examples/CMakeTests.cmake index bd1f95b..58bdb68 100644 --- a/c++/examples/CMakeTests.cmake +++ b/c++/examples/CMakeTests.cmake @@ -26,7 +26,7 @@ SDSextendible.h5 Select.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex-clear-objects") @@ -46,7 +46,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_${example}") @@ -66,7 +66,7 @@ h5tutr_groups.h5 h5tutr_subset.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_tutr-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_tutr-clear-objects") @@ -86,7 +86,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (CPP_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "CPP_ex_${example}") diff --git a/config/cmake/hdf5-config-version.cmake.in b/config/cmake/hdf5-config-version.cmake.in deleted file mode 100644 index 8e16725..0000000 --- a/config/cmake/hdf5-config-version.cmake.in +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright by The HDF Group. -# All rights reserved. -# -# This file is part of HDF5. The full HDF5 copyright notice, including -# terms governing use, modification, and redistribution, is contained in -# the COPYING file, which can be found at the root of the source code -# distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. -# If you do not have access to either file, you may request a copy from -# help@hdfgroup.org. -# -#----------------------------------------------------------------------------- -# HDF5 Version file for install directory -#----------------------------------------------------------------------------- -# -# The created file sets PACKAGE_VERSION_EXACT if the current version string and -# the requested version string are exactly the same and it sets -# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, -# but only if the requested major.minor version is the same as the current one. -# The variable HDF5_VERSION_STRING must be set before calling configure_file(). - -set (PACKAGE_VERSION "@HDF5_VERSION_STRING@") - -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) - set(PACKAGE_VERSION_COMPATIBLE FALSE) -else () - if ("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "@H5_VERS_MAJOR@") - - # exact match for version @H5_VERS_MAJOR@.@H5_VERS_MINOR@ - if ("${PACKAGE_FIND_VERSION_MINOR}" STREQUAL "@H5_VERS_MINOR@") - - # compatible with any version @H5_VERS_MAJOR@.@H5_VERS_MINOR@.x - set (PACKAGE_VERSION_COMPATIBLE TRUE) - - if ("${PACKAGE_FIND_VERSION_PATCH}" STREQUAL "@H5_VERS_RELEASE@") - set (PACKAGE_VERSION_EXACT TRUE) - - if ("${PACKAGE_FIND_VERSION_TWEAK}" STREQUAL "@H5_VERS_SUBRELEASE@") - # not using this yet - endif () - endif () - else () - set (PACKAGE_VERSION_COMPATIBLE FALSE) - endif () - endif () -endif () - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") - return() -endif () - -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") - math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") - set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") - set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif () diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index 3bd9e1d..800de85 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -127,14 +127,14 @@ endif () # Handle requested components: list (REMOVE_DUPLICATES ${HDF5_PACKAGE_NAME}_FIND_COMPONENTS) foreach (comp IN LISTS ${HDF5_PACKAGE_NAME}_FIND_COMPONENTS) - if (${comp} STREQUAL "shared") + if (comp STREQUAL "shared") list (REMOVE_ITEM ${HDF5_PACKAGE_NAME}_FIND_COMPONENTS ${comp}) set (${HDF5_PACKAGE_NAME}_LIB_TYPE ${${HDF5_PACKAGE_NAME}_LIB_TYPE} ${comp}) if (${HDF5_PACKAGE_NAME}_BUILD_FORTRAN) set (${HDF5_PACKAGE_NAME}_INCLUDE_DIR_FORTRAN "@PACKAGE_INCLUDE_INSTALL_DIR@/shared") endif () - elseif (${comp} STREQUAL "static") + elseif (comp STREQUAL "static") list (REMOVE_ITEM ${HDF5_PACKAGE_NAME}_FIND_COMPONENTS ${comp}) set (${HDF5_PACKAGE_NAME}_LIB_TYPE ${${HDF5_PACKAGE_NAME}_LIB_TYPE} ${comp}) @@ -146,32 +146,32 @@ endforeach () foreach (libtype IN LISTS ${HDF5_PACKAGE_NAME}_LIB_TYPE) foreach (comp IN LISTS ${HDF5_PACKAGE_NAME}_FIND_COMPONENTS) set (hdf5_comp2) - if (${comp} STREQUAL "C") + if (comp STREQUAL "C") set (hdf5_comp "hdf5") - elseif (${comp} STREQUAL "CXX") + elseif (comp STREQUAL "CXX") set (hdf5_comp "hdf5_cpp") - elseif (${comp} STREQUAL "HL") + elseif (comp STREQUAL "HL") set (hdf5_comp "hdf5_hl") - elseif (${comp} STREQUAL "CXX_HL") + elseif (comp STREQUAL "CXX_HL") set (hdf5_comp "hdf5_hl_cpp") - elseif (${comp} STREQUAL "Java") + elseif (comp STREQUAL "Java") set (hdf5_comp "hdf5_java") - elseif (${comp} STREQUAL "Tools") + elseif (comp STREQUAL "Tools") set (hdf5_comp "hdf5_tools") - elseif (${comp} STREQUAL "Fortran") + elseif (comp STREQUAL "Fortran") set (hdf5_comp2 "hdf5_f90cstub") set (hdf5_comp "hdf5_fortran") - elseif (${comp} STREQUAL "Fortran_HL") + elseif (comp STREQUAL "Fortran_HL") set (hdf5_comp2 "hdf5_hl_f90cstub") set (hdf5_comp "hdf5_hl_fortran") endif () - if (${comp} STREQUAL "Java") + if (comp STREQUAL "Java") list (FIND ${HDF5_PACKAGE_NAME}_EXPORT_LIBRARIES "${hdf5_comp}" HAVE_COMP) else () list (FIND ${HDF5_PACKAGE_NAME}_EXPORT_LIBRARIES "${hdf5_comp}-${libtype}" HAVE_COMP) endif () if (${HAVE_COMP} LESS 0) - if (${comp} STREQUAL "Java") + if (comp STREQUAL "Java") set (${HDF5_PACKAGE_NAME}_${comp}_FOUND 0) else () set (${HDF5_PACKAGE_NAME}_${libtype}_${comp}_FOUND 0) @@ -184,9 +184,9 @@ foreach (libtype IN LISTS ${HDF5_PACKAGE_NAME}_LIB_TYPE) else () set (${HDF5_PACKAGE_NAME}_${libtype}_${comp}_FOUND 1) string(TOUPPER ${HDF5_PACKAGE_NAME}_${comp}_${libtype}_LIBRARY COMP_LIBRARY) - set (${COMP_LIBRARY} ${${COMP_LIBRARY}} @HDF5_PACKAGE@::${hdf5_comp2}-${libtype} @HDF5_PACKAGE@::${hdf5_comp}-${libtype}) + set (${COMP_LIBRARY} ${${COMP_LIBRARY}} @HDF5_PACKAGE@::${hdf5_comp2}-${libtype} @HDF5_PACKAGE@::${hdf5_comp}-${lcomp endif () - elseif (${comp} STREQUAL "Java") + elseif (comp STREQUAL "Java") set (${HDF5_PACKAGE_NAME}_${comp}_FOUND 1) string(TOUPPER ${HDF5_PACKAGE_NAME}_${comp}_LIBRARY COMP_LIBRARY) set (${COMP_LIBRARY} ${${COMP_LIBRARY}} hdf5::${hdf5_comp}) diff --git a/config/cmake/jrunTest.cmake b/config/cmake/jrunTest.cmake index 23f297c..d5cd903 100644 --- a/config/cmake/jrunTest.cmake +++ b/config/cmake/jrunTest.cmake @@ -142,8 +142,8 @@ if (NOT TEST_SKIP_COMPARE) foreach (line RANGE 0 ${_FP_LEN}) list (GET test_act ${line} str_act) list (GET test_ref ${line} str_ref) - if (NOT ${str_act} STREQUAL ${str_ref}) - if (NOT str_act STREQUAL "") + if (NOT str_act STREQUAL str_ref) + if (str_act) set (TEST_RESULT 1) message ("line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") endif () @@ -194,8 +194,8 @@ if (NOT TEST_SKIP_COMPARE) foreach (line RANGE 0 ${_FP_LEN}) list (GET test_act ${line} str_act) list (GET test_ref ${line} str_ref) - if (NOT ${str_act} STREQUAL ${str_ref}) - if (NOT ${str_act} STREQUAL "") + if (NOT str_act STREQUAL str_ref) + if (str_act) set (TEST_RESULT 1) message ("line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") endif () diff --git a/config/cmake/userblockTest.cmake b/config/cmake/userblockTest.cmake index 9af7e5b..4a580d0 100644 --- a/config/cmake/userblockTest.cmake +++ b/config/cmake/userblockTest.cmake @@ -62,7 +62,7 @@ if (TEST_CHECKUB STREQUAL "YES") OUTPUT_VARIABLE TEST_OUT ERROR_VARIABLE TEST_ERROR ) - if (NOT ${TEST_RESULT} STREQUAL "0") + if (TEST_RESULT) message (FATAL_ERROR "Failed: The output of ${TEST_PROGRAM} ${TEST_OFILE} is: ${TEST_ERROR}") endif () file (READ ${TEST_HFILE}.len.txt TEST_O_STRING_LEN) @@ -70,7 +70,7 @@ if (TEST_CHECKUB STREQUAL "YES") math( EXPR TEST_STRING_SIZE "${TEST_U_STRING_LEN} + ${TEST_O_STRING_LEN}" ) - if (NOT TEST_O_STRING_LEN STREQUAL "0") + if (TEST_O_STRING_LEN) #$JAM_BIN/getub -c $s2 $origfile > $cmpfile EXECUTE_PROCESS ( COMMAND ${TEST_GET_PROGRAM} -c ${TEST_O_STRING_LEN} ${TEST_OFILE} @@ -108,7 +108,7 @@ if (TEST_CHECKUB STREQUAL "YES") message (STATUS "COMPARE Result: ${TEST_RESULT}: ${TEST_STRING_SIZE}=${TEST_U_STRING_LEN}+${TEST_O_STRING_LEN}") # if the return value is !=${TEST_EXPECT} bail out - if (NOT ${TEST_RESULT} STREQUAL ${TEST_EXPECT}) + if (NOT TEST_RESULT EQUAL TEST_EXPECT) message (FATAL_ERROR "Failed: The output of ${TEST_HFILE}-ub did not match ${TEST_HFILE}.\n${TEST_ERROR}") endif () else () @@ -121,7 +121,7 @@ else () OUTPUT_VARIABLE TEST_OUT ERROR_VARIABLE TEST_ERROR ) - if (NOT TEST_H_STRING_LEN STREQUAL "0") + if (TEST_H_STRING_LEN) message (FATAL_ERROR "Failed: The output of ${TEST_HFILE} was NOT empty") endif () endif () diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 986280f..60dda17 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -445,7 +445,7 @@ if (NOT WINDOWS) # Check a bunch of time functions #----------------------------------------------------------------------------- CHECK_FUNCTION_EXISTS (gettimeofday ${HDF_PREFIX}_HAVE_GETTIMEOFDAY) - foreach (test + foreach (time_test HAVE_TM_GMTOFF HAVE___TM_GMTOFF # HAVE_TIMEZONE @@ -455,7 +455,7 @@ if (NOT WINDOWS) HAVE_TM_ZONE HAVE_STRUCT_TM_TM_ZONE ) - HDF_FUNCTION_TEST (${test}) + HDF_FUNCTION_TEST (${time_test}) endforeach () if (NOT CYGWIN AND NOT MINGW) HDF_FUNCTION_TEST (HAVE_TIMEZONE) @@ -559,7 +559,7 @@ endif () # Check a bunch of other functions #----------------------------------------------------------------------------- if (NOT WINDOWS) - foreach (test + foreach (other_test HAVE_ATTRIBUTE HAVE_C99_FUNC # STDC_HEADERS @@ -568,7 +568,7 @@ if (NOT WINDOWS) SYSTEM_SCOPE_THREADS HAVE_SOCKLEN_T ) - HDF_FUNCTION_TEST (${test}) + HDF_FUNCTION_TEST (${other_test}) endforeach () endif () diff --git a/config/cmake_ext_mod/HDFUseCXX.cmake b/config/cmake_ext_mod/HDFUseCXX.cmake index efaa556..8d98147 100644 --- a/config/cmake_ext_mod/HDFUseCXX.cmake +++ b/config/cmake_ext_mod/HDFUseCXX.cmake @@ -96,7 +96,7 @@ endmacro () # Check a bunch of cxx functions #----------------------------------------------------------------------------- if (CMAKE_CXX_COMPILER_LOADED) - foreach (test + foreach (cxx_test OLD_HEADER_FILENAME HDF_NO_NAMESPACE HDF_NO_STD @@ -104,6 +104,6 @@ if (CMAKE_CXX_COMPILER_LOADED) NO_STATIC_CAST CXX_HAVE_OFFSETOF ) - HDF_CXX_FUNCTION_TEST (${test}) + HDF_CXX_FUNCTION_TEST (${cxx_test}) endforeach () endif () diff --git a/config/cmake_ext_mod/runTest.cmake b/config/cmake_ext_mod/runTest.cmake index 48402a2..13e8a4d 100644 --- a/config/cmake_ext_mod/runTest.cmake +++ b/config/cmake_ext_mod/runTest.cmake @@ -218,8 +218,8 @@ if (NOT TEST_SKIP_COMPARE) foreach (line RANGE 0 ${_FP_LEN}) list (GET test_act ${line} str_act) list (GET test_ref ${line} str_ref) - if (NOT ${str_act} STREQUAL ${str_ref}) - if (NOT str_act STREQUAL "") + if (NOT str_act STREQUAL str_ref) + if (str_act) set (TEST_RESULT 1) message ("line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") endif () @@ -270,8 +270,8 @@ if (NOT TEST_SKIP_COMPARE) foreach (line RANGE 0 ${_FP_LEN}) list (GET test_act ${line} str_act) list (GET test_ref ${line} str_ref) - if (NOT ${str_act} STREQUAL ${str_ref}) - if (NOT ${str_act} STREQUAL "") + if (NOT str_act STREQUAL str_ref) + if (str_act) set (TEST_RESULT 1) message ("line = ${line}\n***ACTUAL: ${str_act}\n****REFER: ${str_ref}\n") endif () diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index cb47c78..1058566 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -71,7 +71,7 @@ vds-simpleIO.h5 vds-eiger.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (EXAMPLES-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "EXAMPLES-clear-objects") @@ -91,7 +91,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (EXAMPLES-${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "EXAMPLES-${example}") @@ -150,7 +150,7 @@ WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/H5EX-shared ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (EXAMPLES-shared-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "EXAMPLES-shared-clear-objects") @@ -171,7 +171,7 @@ ) endif () set_tests_properties (EXAMPLES-shared-${example} PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/H5EX-shared) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (EXAMPLES-shared-${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "EXAMPLES-shared-${example}") @@ -194,7 +194,7 @@ -P "${HDF_RESOURCES_EXT_DIR}/grepTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (MPI_TEST_EXAMPLES-ph5example PROPERTIES DEPENDS ${last_test}) endif () set (last_test "MPI_TEST_EXAMPLES-ph5example") @@ -214,7 +214,7 @@ ) endif () set_tests_properties (MPI_TEST_EXAMPLES-shared-ph5example PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/H5EX-shared) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (MPI_TEST_EXAMPLES-shared-ph5example PROPERTIES DEPENDS ${last_test}) endif () set (last_test "MPI_TEST_EXAMPLES-shared-ph5example") diff --git a/fortran/examples/CMakeTests.cmake b/fortran/examples/CMakeTests.cmake index face086..efbb209 100644 --- a/fortran/examples/CMakeTests.cmake +++ b/fortran/examples/CMakeTests.cmake @@ -37,7 +37,7 @@ SDScompound.h5 test.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f90_ex-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f90_ex-clear-objects") @@ -62,7 +62,7 @@ SDScompound.h5 test.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f90_ex-shared-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f90_ex-shared-clear-objects") @@ -83,7 +83,7 @@ foreach (example ${examples}) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f90_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f90_ex_${example}") @@ -102,7 +102,7 @@ foreach (example ${examples}) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f90_ex-shared_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f90_ex-shared_${example}") @@ -124,7 +124,7 @@ foreach (example ${F2003_examples}) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f03_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f03_ex_${example}") @@ -143,7 +143,7 @@ foreach (example ${F2003_examples}) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (f03_ex-shared_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "f03_ex-shared_${example}") diff --git a/fortran/test/CMakeTests.cmake b/fortran/test/CMakeTests.cmake index 2824ef7..5fa10f4 100644 --- a/fortran/test/CMakeTests.cmake +++ b/fortran/test/CMakeTests.cmake @@ -58,7 +58,7 @@ add_test ( vds.h5 visit.h5 ) -if (NOT "${last_test}" STREQUAL "") +if (last_test) set_tests_properties (FORTRAN_testhdf5-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "FORTRAN_testhdf5-clear-objects") diff --git a/hl/examples/CMakeTests.cmake b/hl/examples/CMakeTests.cmake index 166fa7c..c1fd6c2 100644 --- a/hl/examples/CMakeTests.cmake +++ b/hl/examples/CMakeTests.cmake @@ -51,7 +51,7 @@ add_custom_target(hl_ex_ex_ds1_files ALL COMMENT "Copying files needed by hl_ex_ ex_table_12.h5 ex_ds1.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (HL_ex-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "HL_ex-clear-objects") @@ -71,7 +71,7 @@ foreach (example ${examples}) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (HL_ex_${example} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "HL_ex_${example}") diff --git a/hl/fortran/test/CMakeLists.txt b/hl/fortran/test/CMakeLists.txt index 923989d..fca2852 100644 --- a/hl/fortran/test/CMakeLists.txt +++ b/hl/fortran/test/CMakeLists.txt @@ -70,8 +70,8 @@ macro (ADD_H5_FORTRAN_EXE file) endif () endmacro () -foreach (test ${H5_TESTS}) - ADD_H5_FORTRAN_EXE(${test}) +foreach (h5_test ${H5_TESTS}) + ADD_H5_FORTRAN_EXE(${h5_test}) endforeach () include (CMakeTests.cmake) diff --git a/hl/fortran/test/CMakeTests.cmake b/hl/fortran/test/CMakeTests.cmake index 04a49dc..54cc6ef 100644 --- a/hl/fortran/test/CMakeTests.cmake +++ b/hl/fortran/test/CMakeTests.cmake @@ -87,6 +87,6 @@ if (BUILD_SHARED_LIBS) ) endif () -foreach (test ${H5_TESTS}) - ADD_H5_FORTRAN_TEST(${test}) +foreach (h5_test ${H5_TESTS}) + ADD_H5_FORTRAN_TEST(${h5_test}) endforeach () diff --git a/hl/test/CMakeTests.cmake b/hl/test/CMakeTests.cmake index 4e945bc..477a165 100644 --- a/hl/test/CMakeTests.cmake +++ b/hl/test/CMakeTests.cmake @@ -61,7 +61,7 @@ macro (HL_ADD_TEST hl_name) -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (HL_${hl_name} PROPERTIES DEPENDS ${last_test} ENVIRONMENT "srcdir=${HDF5_HL_TEST_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_HL_TEST_BINARY_DIR} @@ -104,7 +104,7 @@ add_test ( testfl_packet_table_vlen.h5 test_table.h5 ) -if (NOT "${last_test}" STREQUAL "") +if (last_test) set_tests_properties (HL_test-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "HL_test-clear-objects") diff --git a/hl/tools/h5watch/CMakeTests.cmake b/hl/tools/h5watch/CMakeTests.cmake index 13d5e47..a4d3fa2 100644 --- a/hl/tools/h5watch/CMakeTests.cmake +++ b/hl/tools/h5watch/CMakeTests.cmake @@ -147,7 +147,7 @@ if (NOT SWMR_INCOMPAT) -E remove WATCH.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5WATCH-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5WATCH-clearall-objects") diff --git a/java/examples/datasets/CMakeLists.txt b/java/examples/datasets/CMakeLists.txt index 1375372..2338d0f 100644 --- a/java/examples/datasets/CMakeLists.txt +++ b/java/examples/datasets/CMakeLists.txt @@ -87,7 +87,7 @@ MACRO (ADD_H5_TEST resultfile resultcode) -D "TEST_REFERENCE=datasets/${resultfile}.txt" -P "${HDF_RESOURCES_DIR}/jrunTest.cmake" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_datasets-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_datasets-${resultfile}") @@ -96,7 +96,7 @@ ENDMACRO () if (BUILD_TESTING) foreach (example ${HDF_JAVA_EXAMPLES}) - if ("${example}" STREQUAL "H5Ex_D_External") + if (example STREQUAL "H5Ex_D_External") add_test ( NAME JAVA_datasets-${example}-clear-objects COMMAND ${CMAKE_COMMAND} @@ -112,7 +112,7 @@ if (BUILD_TESTING) ${HDFJAVA_EXAMPLES_BINARY_DIR}/${example}.h5 ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_datasets-${example}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( diff --git a/java/examples/datatypes/CMakeLists.txt b/java/examples/datatypes/CMakeLists.txt index 4a8b2a4..0fef370 100644 --- a/java/examples/datatypes/CMakeLists.txt +++ b/java/examples/datatypes/CMakeLists.txt @@ -72,7 +72,7 @@ MACRO (ADD_H5_TEST resultfile resultcode) -D "TEST_REFERENCE=datatypes/${resultfile}.txt" -P "${HDF_RESOURCES_DIR}/jrunTest.cmake" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_datatypes-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_datatypes-${resultfile}") @@ -86,7 +86,7 @@ if (BUILD_TESTING) -E remove ${HDFJAVA_EXAMPLES_BINARY_DIR}/${example}.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_datatypes-${example}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( diff --git a/java/examples/groups/CMakeLists.txt b/java/examples/groups/CMakeLists.txt index 2c5d33b..631eba7 100644 --- a/java/examples/groups/CMakeLists.txt +++ b/java/examples/groups/CMakeLists.txt @@ -71,7 +71,7 @@ MACRO (ADD_H5_TEST resultfile resultcode) -D "TEST_REFERENCE=groups/${resultfile}.txt" -P "${HDF_RESOURCES_DIR}/jrunTest.cmake" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_groups-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_groups-${resultfile}") @@ -79,8 +79,8 @@ ENDMACRO () if (BUILD_TESTING) foreach (example ${HDF_JAVA_EXAMPLES}) - if (NOT "${example}" STREQUAL "H5Ex_G_Iterate" AND NOT "${example}" STREQUAL "H5Ex_G_Visit") - if ("${example}" STREQUAL "H5Ex_G_Compact") + if (NOT example STREQUAL "H5Ex_G_Iterate" AND NOT example STREQUAL "H5Ex_G_Visit") + if (example STREQUAL "H5Ex_G_Compact") add_test ( NAME JAVA_groups-${example}-clear-h5s COMMAND ${CMAKE_COMMAND} @@ -96,7 +96,7 @@ if (BUILD_TESTING) ${HDFJAVA_EXAMPLES_BINARY_DIR}/${example}.h5 ) endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_groups-${example}-clear-h5s PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_groups-${example}-clear-h5s") @@ -108,7 +108,7 @@ if (BUILD_TESTING) ${HDFJAVA_EXAMPLES_SOURCE_DIR}/testfiles/examples.groups.${example}.txt ${HDFJAVA_EXAMPLES_GROUPS_BINARY_DIR}/${example}.txt ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_groups-${example}-copy-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_groups-${example}-copy-objects") diff --git a/java/examples/intro/CMakeLists.txt b/java/examples/intro/CMakeLists.txt index 8d56b86..8c94a09 100644 --- a/java/examples/intro/CMakeLists.txt +++ b/java/examples/intro/CMakeLists.txt @@ -73,7 +73,7 @@ MACRO (ADD_H5_TEST resultfile resultcode) -D "TEST_REFERENCE=intro/${resultfile}.txt" -P "${HDF_RESOURCES_DIR}/jrunTest.cmake" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_intro-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_intro-${resultfile}") @@ -88,7 +88,7 @@ if (BUILD_TESTING) -E remove ${HDFJAVA_EXAMPLES_BINARY_DIR}/${example}.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (JAVA_intro-${example}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( diff --git a/java/src/hdf/hdf5lib/H5.java b/java/src/hdf/hdf5lib/H5.java index 19ca83b..57157c2 100644 --- a/java/src/hdf/hdf5lib/H5.java +++ b/java/src/hdf/hdf5lib/H5.java @@ -3233,6 +3233,8 @@ public class H5 implements java.io.Serializable { * @param file_id * IN: Identifier of the target file. * + * @return true if the file-level is set to create minimized dataset object headers, false if not. + * * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ @@ -6998,6 +7000,8 @@ public class H5 implements java.io.Serializable { * @param dcpl_id * IN: Dataset creation property list * + * @return true if the given dcpl is set to create minimized dataset object headers, false if not. + * * @exception HDF5LibraryException * - Error from the HDF-5 Library. **/ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d67485..c442e9b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -293,9 +293,9 @@ set (H5_TESTS_MULTIPLE ttsafe ) # Only build single source tests here -foreach (test ${H5_TESTS}) - if (NOT ${test} IN_LIST H5_TESTS_MULTIPLE) - ADD_H5_EXE(${test}) +foreach (h5_test ${H5_TESTS}) + if (NOT h5_test IN_LIST H5_TESTS_MULTIPLE) + ADD_H5_EXE(${h5_test}) endif () endforeach () @@ -378,15 +378,15 @@ set (H5_CHECK_TESTS flushrefresh ) -foreach (test ${H5_CHECK_TESTS}) - ADD_H5_EXE(${test}) +foreach (h5_test ${H5_CHECK_TESTS}) + ADD_H5_EXE(${h5_test}) endforeach () #-- Adding test for libinfo set (GREP_RUNNER ${PROJECT_BINARY_DIR}/GrepRunner.cmake) file (WRITE ${GREP_RUNNER} "file (STRINGS \${TEST_PROGRAM} TEST_RESULT REGEX \"SUMMARY OF THE HDF5 CONFIGURATION\") -if (\${TEST_RESULT} STREQUAL \"0\") +if (NOT TEST_RESULT) message (FATAL_ERROR \"Failed: The output: \${TEST_RESULT} of \${TEST_PROGRAM} did not contain SUMMARY OF THE HDF5 CONFIGURATION\") else () message (STATUS \"COMMAND Result: \${TEST_RESULT}\") @@ -411,8 +411,8 @@ set (H5_SWMR_TESTS swmr_writer ) -foreach (test ${H5_SWMR_TESTS}) - ADD_H5_EXE(${test}) +foreach (h5_test ${H5_SWMR_TESTS}) + ADD_H5_EXE(${h5_test}) endforeach () set (H5_VDS_SWMR_TESTS @@ -421,8 +421,8 @@ set (H5_VDS_SWMR_TESTS vds_swmr_writer ) -foreach (test ${H5_VDS_SWMR_TESTS}) - ADD_H5_EXE(${test}) +foreach (h5_test ${H5_VDS_SWMR_TESTS}) + ADD_H5_EXE(${h5_test}) endforeach () #-- Adding test for accum_swmr_reader diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 959e537..26e5a78 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -545,33 +545,33 @@ set (H5TEST_SEPARATE_TESTS flush1 flush2 ) -foreach (test ${H5_TESTS}) - if (NOT ${test} IN_LIST H5TEST_SEPARATE_TESTS) +foreach (h5_test ${H5_TESTS}) + if (NOT h5_test IN_LIST H5TEST_SEPARATE_TESTS) if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME H5TEST-${test} COMMAND $) - set_tests_properties (H5TEST-${test} PROPERTIES + add_test (NAME H5TEST-${h5_test} COMMAND $) + set_tests_properties (H5TEST-${h5_test} PROPERTIES FIXTURES_REQUIRED clear_objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST ) else () - if ("${test}" STREQUAL "big" AND CYGWIN) - add_test (NAME H5TEST-${test} + if (h5_test STREQUAL "big" AND CYGWIN) + add_test (NAME H5TEST-${h5_test} COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${test}" ) else () - add_test (NAME H5TEST-${test} COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" + add_test (NAME H5TEST-${h5_test} COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=${test}.txt" + -D "TEST_OUTPUT=${h5_test}.txt" #-D "TEST_REFERENCE=${test}.out" -D "TEST_FOLDER=${HDF5_TEST_BINARY_DIR}/H5TEST" -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - set_tests_properties (H5TEST-${test} PROPERTIES + set_tests_properties (H5TEST-${h5_test} PROPERTIES FIXTURES_REQUIRED clear_objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST @@ -596,25 +596,25 @@ if (BUILD_SHARED_LIBS) ) set_tests_properties (H5TEST-shared-clear-objects PROPERTIES FIXTURES_SETUP shared_clear_objects) - foreach (test ${H5_TESTS}) - if (NOT ${test} IN_LIST H5TEST_SEPARATE_TESTS) - if ("${test}" STREQUAL "big" AND CYGWIN) - add_test (NAME H5TEST-shared-${test} + foreach (h5_test ${H5_TESTS}) + if (NOT h5_test IN_LIST H5TEST_SEPARATE_TESTS) + if (h5_test STREQUAL "big" AND CYGWIN) + add_test (NAME H5TEST-shared-${h5_test} COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${test}-shared" ) else () - add_test (NAME H5TEST-shared-${test} COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" + add_test (NAME H5TEST-shared-${h5_test} COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" -D "TEST_SKIP_COMPARE=TRUE" - -D "TEST_OUTPUT=${test}.txt" + -D "TEST_OUTPUT=${h5_test}.txt" #-D "TEST_REFERENCE=${test}.out" -D "TEST_FOLDER=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" ) endif () - set_tests_properties (H5TEST-shared-${test} PROPERTIES + set_tests_properties (H5TEST-shared-${h5_test} PROPERTIES FIXTURES_REQUIRED shared_clear_objects ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/H5TEST-shared" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST-shared @@ -1193,8 +1193,8 @@ if (HDF5_BUILD_GENERATORS) gen_plist ) - foreach (gen ${H5_GENERATORS}) - ADD_H5_GENERATOR (${gen}) + foreach (h5_gen ${H5_GENERATORS}) + ADD_H5_GENERATOR (${h5_gen}) endforeach () endif () diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index 569f215..ad3d1e9 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -109,9 +109,9 @@ endif () # Windows only macro macro (CHECK_VFD_TEST vfdtest vfdname resultcode) - if ("${vfdtest}" STREQUAL "flush1" OR "${vfdtest}" STREQUAL "flush2") - if ("${vfdname}" STREQUAL "multi" OR "${vfdname}" STREQUAL "split") - if (NOT BUILD_SHARED_LIBS AND NOT ${HDF_CFG_NAME} MATCHES "Debug") + if (vfdtest STREQUAL "flush1" OR vfdtest STREQUAL "flush2") + if (vfdname STREQUAL "multi" OR vfdname STREQUAL "split") + if (NOT BUILD_SHARED_LIBS AND NOT HDF_CFG_NAME MATCHES "Debug") add_test ( NAME VFD-${vfdname}-${vfdtest}-clear-objects COMMAND ${CMAKE_COMMAND} @@ -239,7 +239,7 @@ endif () ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) - if (BUILD_SHARED_LIBS AND NOT "${vfdtest}" STREQUAL "cache") + if (BUILD_SHARED_LIBS AND NOT vfdtest STREQUAL "cache") add_test ( NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects COMMAND ${CMAKE_COMMAND} @@ -316,12 +316,12 @@ endif () endmacro () macro (ADD_VFD_TEST vfdname resultcode) - foreach (test ${H5_TESTS}) - if (NOT ${test} IN_LIST H5_VFD_SKIP_TESTS) + foreach (h5_test ${H5_TESTS}) + if (NOT h5_test IN_LIST H5_VFD_SKIP_TESTS) if (WIN32) - CHECK_VFD_TEST (${test} ${vfdname} ${resultcode}) + CHECK_VFD_TEST (${h5_test} ${vfdname} ${resultcode}) else () - DO_VFD_TEST (${test} ${vfdname} ${resultcode}) + DO_VFD_TEST (${h5_test} ${vfdname} ${resultcode}) endif () endif () endforeach () @@ -394,6 +394,6 @@ endif () endmacro () # Run test with different Virtual File Driver - foreach (vfd ${VFD_LIST}) - ADD_VFD_TEST (${vfd} 0) + foreach (h5_vfd ${VFD_LIST}) + ADD_VFD_TEST (${h5_vfd} 0) endforeach () diff --git a/test/CMakeVOLTests.cmake b/test/CMakeVOLTests.cmake index 334520c..7c02e23 100644 --- a/test/CMakeVOLTests.cmake +++ b/test/CMakeVOLTests.cmake @@ -106,8 +106,8 @@ endif () # Windows only macro macro (CHECK_VOL_TEST voltest volname volinfo resultcode) - if ("${voltest}" STREQUAL "flush1" OR "${voltest}" STREQUAL "flush2") - if ("${volname}" STREQUAL "multi" OR "${volname}" STREQUAL "split") + if (voltest STREQUAL "flush1" OR voltest STREQUAL "flush2") + if (volname STREQUAL "multi" OR volname STREQUAL "split") if (NOT BUILD_SHARED_LIBS AND NOT ${HDF_CFG_NAME} MATCHES "Debug") add_test ( NAME VOL-${volname}-${voltest}-clear-objects @@ -236,7 +236,7 @@ endif () ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) - if (BUILD_SHARED_LIBS AND NOT "${voltest}" STREQUAL "cache") + if (BUILD_SHARED_LIBS AND NOT voltest STREQUAL "cache") add_test ( NAME VOL-${volname}-${voltest}-shared-clear-objects COMMAND ${CMAKE_COMMAND} @@ -315,12 +315,12 @@ endif () macro (ADD_VOL_TEST volname volinfo resultcode) #message(STATUS "volname=${volname} volinfo=${volinfo}") - foreach (test ${H5_TESTS}) - if (NOT ${test} IN_LIST H5_VOL_SKIP_TESTS) + foreach (h5_test ${H5_TESTS}) + if (NOT h5_test IN_LIST H5_VOL_SKIP_TESTS) if (WIN32) - CHECK_VOL_TEST (${test} ${volname} "${volinfo}" ${resultcode}) + CHECK_VOL_TEST (${h5_test} ${volname} "${volinfo}" ${resultcode}) else () - DO_VOL_TEST (${test} ${volname} "${volinfo}" ${resultcode}) + DO_VOL_TEST (${h5_test} ${volname} "${volinfo}" ${resultcode}) endif () endif () endforeach () diff --git a/test/flushrefreshTest.cmake b/test/flushrefreshTest.cmake index f66ee64..aa18c8a 100644 --- a/test/flushrefreshTest.cmake +++ b/test/flushrefreshTest.cmake @@ -53,7 +53,7 @@ if (TEST_ENV_VAR) #message (STATUS "ENV:${TEST_ENV_VAR}=$ENV{${TEST_ENV_VAR}}") endif () -message(STATUS "Background: ${PERL_EXECUTABLE} ${PERL_SCRIPT} ${TEST_PROGRAM}") +message (STATUS "Background: ${PERL_EXECUTABLE} ${PERL_SCRIPT} ${TEST_PROGRAM}") execute_process ( COMMAND ${PERL_EXECUTABLE} ${PERL_SCRIPT} ${TEST_PROGRAM} RESULT_VARIABLE SCRIPT_RESULT @@ -61,34 +61,34 @@ execute_process ( OUTPUT_VARIABLE SCRIPT_OUTPUT WORKING_DIRECTORY ${TEST_FOLDER} ) -message(STATUS "Background: ${SCRIPT_OUTPUT}") -if (NOT "${SCRIPT_RESULT}" STREQUAL "0") +message (STATUS "Background: ${SCRIPT_OUTPUT}") +if (SCRIPT_RESULT) message (FATAL_ERROR "Failed: The background script failed ${SCRIPT_RESULT}: ${SCRIPT_ERR}") endif () -set(verification_done "0") -while(verification_done LESS "1") - message(STATUS "checking first stage:${TEST_FOLDER}/${TEST_ARGS1}") - if(EXISTS ${TEST_FOLDER}/${TEST_ERR}) +set (verification_done "0") +while (verification_done LESS "1") + message (STATUS "checking first stage:${TEST_FOLDER}/${TEST_ARGS1}") + if (EXISTS ${TEST_FOLDER}/${TEST_ERR}) # Error exit script - set(verification_done "3") - elseif(EXISTS ${TEST_FOLDER}/${TEST_ARGS1}) + set (verification_done "3") + elseif (EXISTS ${TEST_FOLDER}/${TEST_ARGS1}) file (STRINGS ${TEST_FOLDER}/${TEST_ARGS1} v1) list (LENGTH v1 len_v1) - message(STATUS "v1:${v1} len_v1:${len_v1}") - if (NOT "${len_v1}" STREQUAL "0") + message (STATUS "v1:${v1} len_v1:${len_v1}") + if (len_v1) list (GET v1 0 param1) list (GET v1 -1 param2) endif () - file(REMOVE ${TEST_FOLDER}/${TEST_ARGS1}) - message(STATUS "PARAM1:${param1} PARAM2:${param2}") + file (REMOVE ${TEST_FOLDER}/${TEST_ARGS1}) + message (STATUS "PARAM1:${param1} PARAM2:${param2}") - if(${param1} MATCHES "VERIFICATION_DONE") - set(verification_done "1") - file(WRITE ${TEST_FOLDER}/${TEST_ARGS2} "all flush verification complete") - message(STATUS "write: ${TEST_FOLDER}/${TEST_ARGS2}") - else() - message(STATUS "execute: ${TEST_PROGRAM} ${param1} ${param2}") + if (param1 MATCHES "VERIFICATION_DONE") + set (verification_done "1") + file (WRITE ${TEST_FOLDER}/${TEST_ARGS2} "all flush verification complete") + message (STATUS "write: ${TEST_FOLDER}/${TEST_ARGS2}") + else () + message (STATUS "execute: ${TEST_PROGRAM} ${param1} ${param2}") execute_process ( COMMAND ${TEST_PROGRAM} ${param1} ${param2} RESULT_VARIABLE TEST_RESULT @@ -98,40 +98,40 @@ while(verification_done LESS "1") ERROR_VARIABLE TEST_ERROR WORKING_DIRECTORY ${TEST_FOLDER} ) - message(STATUS "flush verification: ${TEST_OUT}") - if (NOT "${TEST_RESULT}" STREQUAL "0") + message (STATUS "flush verification: ${TEST_OUT}") + if (TEST_RESULT) message (FATAL_ERROR "Failed: The flush verification failed ${TEST_RESULT}: ${TEST_ERROR}") endif () - file(WRITE ${TEST_FOLDER}/${TEST_ARGS2} "verification flush process done") - endif() - else() - message(STATUS "waiting: ${TEST_FOLDER}/${TEST_ARGS1}") + file (WRITE ${TEST_FOLDER}/${TEST_ARGS2} "verification flush process done") + endif () + else () + message (STATUS "waiting: ${TEST_FOLDER}/${TEST_ARGS1}") #execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 2) - endif() -endwhile() + endif () +endwhile () -while(verification_done LESS "2") - message(STATUS "checking second stage:${TEST_FOLDER}/${TEST_ARGS1}") - if(EXISTS ${TEST_FOLDER}/${TEST_ERR}) +while (verification_done LESS "2") + message (STATUS "checking second stage:${TEST_FOLDER}/${TEST_ARGS1}") + if (EXISTS ${TEST_FOLDER}/${TEST_ERR}) # Error exit script - set(verification_done "3") - elseif(EXISTS ${TEST_FOLDER}/${TEST_ARGS1}) + set (verification_done "3") + elseif (EXISTS ${TEST_FOLDER}/${TEST_ARGS1}) file (STRINGS ${TEST_FOLDER}/${TEST_ARGS1} v1) list (LENGTH v1 len_v1) - message(STATUS "v1:${v1} len_v1:${len_v1}") - if (NOT "${len_v1}" STREQUAL "0") + message (STATUS "v1:${v1} len_v1:${len_v1}") + if (len_v1) list (GET v1 0 param1) list (GET v1 -1 param2) endif () - file(REMOVE ${TEST_FOLDER}/${TEST_ARGS1}) - message(STATUS "PARAM1:${param1} PARAM2:${param2}") + file (REMOVE ${TEST_FOLDER}/${TEST_ARGS1}) + message (STATUS "PARAM1:${param1} PARAM2:${param2}") - if(${param1} MATCHES "VERIFICATION_DONE") - set(verification_done "2") - file(WRITE ${TEST_FOLDER}/${TEST_ARGS2} "all refresh verification complete") - message(STATUS "write: ${TEST_FOLDER}/${TEST_ARGS2}") - else() - message(STATUS "execute: ${TEST_PROGRAM} ${param1}") + if (param1 MATCHES "VERIFICATION_DONE") + set (verification_done "2") + file (WRITE ${TEST_FOLDER}/${TEST_ARGS2} "all refresh verification complete") + message (STATUS "write: ${TEST_FOLDER}/${TEST_ARGS2}") + else () + message (STATUS "execute: ${TEST_PROGRAM} ${param1}") execute_process ( COMMAND ${TEST_PROGRAM} ${param1} RESULT_VARIABLE TEST_RESULT @@ -141,22 +141,22 @@ while(verification_done LESS "2") ERROR_VARIABLE TEST_ERROR WORKING_DIRECTORY ${TEST_FOLDER} ) - message(STATUS "refresh verification: ${TEST_OUT}") - if (NOT "${TEST_RESULT}" STREQUAL "0") + message (STATUS "refresh verification: ${TEST_OUT}") + if (TEST_RESULT) message (FATAL_ERROR "Failed: The refresh verification failed ${TEST_RESULT}: ${TEST_ERROR}") endif () - file(WRITE ${TEST_FOLDER}/${TEST_ARGS2} "refresh verifiction process done") - endif() - else() - message(STATUS "waiting: ${TEST_FOLDER}/${TEST_ARGS1}") + file (WRITE ${TEST_FOLDER}/${TEST_ARGS2} "refresh verifiction process done") + endif () + else () + message (STATUS "waiting: ${TEST_FOLDER}/${TEST_ARGS1}") #execute_process (COMMAND ${CMAKE_COMMAND} -E sleep 2) - endif() -endwhile() + endif () +endwhile () message (STATUS "COMMAND Result: ${TEST_RESULT}") # if the return value is !=${TEST_EXPECT} bail out -if (NOT "${TEST_RESULT}" STREQUAL "${TEST_EXPECT}") +if (NOT TEST_RESULT EQUAL TEST_EXPECT) if (NOT TEST_NOERRDISPLAY) if (EXISTS ${TEST_FOLDER}/${TEST_OUTPUT}) file (READ ${TEST_FOLDER}/${TEST_OUTPUT} TEST_STREAM) diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index 71459c7..96ce0c0 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -58,8 +58,8 @@ set (H5P_TESTS t_filters_parallel ) -foreach (testp ${H5P_TESTS}) - ADD_H5P_EXE(${testp}) +foreach (h5_testp ${H5P_TESTS}) + ADD_H5P_EXE(${h5_testp}) endforeach () include (CMakeTests.cmake) diff --git a/testpar/CMakeTests.cmake b/testpar/CMakeTests.cmake index 12ccc58..214801b 100644 --- a/testpar/CMakeTests.cmake +++ b/testpar/CMakeTests.cmake @@ -26,7 +26,7 @@ add_test (NAME MPI_TEST-clear-testphdf5-objects set_tests_properties (MPI_TEST-clear-testphdf5-objects PROPERTIES FIXTURES_SETUP par_clear_testphdf5) set (SKIP_testphdf5 "") -#if (${HDF5_OPENMPI_VERSION_SKIP}) +#if (HDF5_OPENMPI_VERSION_SKIP) # set (SKIP_testphdf5 "${SKIP_testphdf5};-x;ecdsetw") #endif () @@ -36,12 +36,12 @@ set_tests_properties (MPI_TEST_testphdf5 PROPERTIES ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} ) -if (NOT "${last_test}" STREQUAL "") +if (last_test) set_tests_properties (MPI_TEST_testphdf5 PROPERTIES DEPENDS ${last_test}) endif () set (last_test "MPI_TEST_testphdf5") -#if (${HDF5_OPENMPI_VERSION_SKIP}) +#if (HDF5_OPENMPI_VERSION_SKIP) # list (REMOVE_ITEM H5P_TESTS t_shapesame) #endif () @@ -74,17 +74,17 @@ add_test (NAME MPI_TEST-clear-objects ) set_tests_properties (MPI_TEST-clear-objects PROPERTIES FIXTURES_SETUP par_clear_objects) -foreach (testp ${H5P_TESTS}) - add_test (NAME MPI_TEST_${testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) - set_tests_properties (MPI_TEST_${testp} PROPERTIES +foreach (h5_testp ${H5P_TESTS}) + add_test (NAME MPI_TEST_${h5_testp} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) + set_tests_properties (MPI_TEST_${h5_testp} PROPERTIES FIXTURES_REQUIRED par_clear_objects ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} ) - if (NOT "${last_test}" STREQUAL "") - set_tests_properties (MPI_TEST_${testp} PROPERTIES DEPENDS ${last_test}) + if (last_test) + set_tests_properties (MPI_TEST_${h5_testp} PROPERTIES DEPENDS ${last_test}) endif () - set (last_test "MPI_TEST_${testp}") + set (last_test "MPI_TEST_${h5_testp}") endforeach () # The t_pflush1 test is hard-coded to fail. diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index de16a31..c0b848b 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -39,27 +39,27 @@ endforeach () macro (ADD_VFD_TEST vfdname resultcode) if (NOT HDF5_ENABLE_USING_MEMCHECKER) - foreach (test ${H5P_VFD_TESTS}) + foreach (h5_test ${H5P_VFD_TESTS}) add_test ( - NAME MPI_TEST_VFD-${vfdname}-${test}-clear-objects + NAME MPI_TEST_VFD-${vfdname}-${h5_test}-clear-objects COMMAND ${CMAKE_COMMAND} -E remove - ${vfdname}-shared/${vfdname}-${test}.out - ${vfdname}-shared/${vfdname}-${test}.out.err + ${vfdname}-shared/${vfdname}-${h5_test}.out + ${vfdname}-shared/${vfdname}-${h5_test}.out.err ) add_test ( - NAME MPI_TEST_VFD-${vfdname}-${test} + NAME MPI_TEST_VFD-${vfdname}-${h5_test} COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" + -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -D "TEST_VFD:STRING=${vfdname}" -D "TEST_EXPECT=${resultcode}" - -D "TEST_OUTPUT=${vfdname}-${test}.out" + -D "TEST_OUTPUT=${vfdname}-${h5_test}.out" -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/${vfdname}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) - set_tests_properties (MPI_TEST_VFD-${vfdname}-${test} PROPERTIES - DEPENDS MPI_TEST_VFD-${vfdname}-${test}-clear-objects + set_tests_properties (MPI_TEST_VFD-${vfdname}-${h5_test} PROPERTIES + DEPENDS MPI_TEST_VFD-${vfdname}-${h5_test}-clear-objects ENVIRONMENT "srcdir=${HDF5_TEST_PAR_BINARY_DIR}/${vfdname}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR}/${vfdname} ) @@ -68,6 +68,6 @@ endforeach () endmacro () # Run test with different Virtual File Driver - foreach (vfd ${VFD_LIST}) - ADD_VFD_TEST (${vfd} 0) + foreach (h5_vfd ${VFD_LIST}) + ADD_VFD_TEST (${h5_vfd} 0) endforeach () diff --git a/tools/test/h5copy/CMakeTests.cmake b/tools/test/h5copy/CMakeTests.cmake index f31068b..85a8788 100644 --- a/tools/test/h5copy/CMakeTests.cmake +++ b/tools/test/h5copy/CMakeTests.cmake @@ -70,7 +70,7 @@ COMMAND $ -f ${fparam} -i ./testfiles/${infile} -o ./testfiles/${testname}.out.h5 ${vparam} ${sparam} ${srcname} ${dparam} ${dstname} ${ARGN} ) if (HDF5_ENABLE_USING_MEMCHECKER) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY_F-${testname} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -78,13 +78,13 @@ endif () # resultcode=2 will cause the test to skip the diff test - if (NOT "${resultcode}" STREQUAL "2") + if (NOT ${resultcode} EQUAL 2) add_test ( NAME H5COPY_F-${testname}-DIFF COMMAND $ -v ./testfiles/${infile} ./testfiles/${testname}.out.h5 ${srcname} ${dstname} ) set_tests_properties (H5COPY_F-${testname}-DIFF PROPERTIES DEPENDS H5COPY_F-${testname}) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5COPY_F-${testname}-DIFF PROPERTIES WILL_FAIL "true") endif () endif () @@ -106,7 +106,7 @@ COMMAND $ -i ./testfiles/${infile} -o ./testfiles/${testname}.out.h5 ${vparam} ${sparam} ${srcname} ${dparam} ${dstname} ${ARGN} ) if (HDF5_ENABLE_USING_MEMCHECKER) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY-${testname} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -114,13 +114,13 @@ endif () # resultcode=2 will cause the test to skip the diff test - if (NOT "${resultcode}" STREQUAL "2") + if (NOT ${resultcode} EQUAL 2) add_test ( NAME H5COPY-${testname}-DIFF COMMAND $ -v ./testfiles/${infile} ./testfiles/${testname}.out.h5 ${srcname} ${dstname} ) set_tests_properties (H5COPY-${testname}-DIFF PROPERTIES DEPENDS H5COPY-${testname}) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5COPY-${testname}-DIFF PROPERTIES WILL_FAIL "true") endif () endif () @@ -152,7 +152,7 @@ COMMAND $ -i ./testfiles/${infile} -o ./testfiles/${testname}.out.h5 -v -s ${psparam} -d ${pdparam} ) if (HDF5_ENABLE_USING_MEMCHECKER) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY-${testname}-prefill PROPERTIES DEPENDS ${last_test}) endif () else () @@ -165,13 +165,13 @@ ) set_tests_properties (H5COPY-${testname} PROPERTIES DEPENDS H5COPY-${testname}-prefill) # resultcode=2 will cause the test to skip the diff test - if (NOT "${resultcode}" STREQUAL "2") + if (NOT ${resultcode} EQUAL 2) add_test ( NAME H5COPY-${testname}-DIFF COMMAND $ -v ./testfiles/${infile} ./testfiles/${testname}.out.h5 ${srcname} ${dstname} ) set_tests_properties (H5COPY-${testname}-DIFF PROPERTIES DEPENDS H5COPY-${testname}) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5COPY-${testname}-DIFF PROPERTIES WILL_FAIL "true") endif () endif () @@ -193,7 +193,7 @@ COMMAND $ -i ./testfiles/${pfile} -o ./testfiles/${testname}.out.h5 -v -s ${psparam} -d ${pdparam} ) if (HDF5_ENABLE_USING_MEMCHECKER) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY_SAME-${testname}-prefill PROPERTIES DEPENDS ${last_test}) endif () else (HDF5_ENABLE_USING_MEMCHECKER) @@ -206,13 +206,13 @@ ) set_tests_properties (H5COPY_SAME-${testname} PROPERTIES DEPENDS H5COPY_SAME-${testname}-prefill) # resultcode=2 will cause the test to skip the diff test - if (NOT "${resultcode}" STREQUAL "2") + if (NOT ${resultcode} EQUAL 2) add_test ( NAME H5COPY_SAME-${testname}-DIFF COMMAND $ -v ./testfiles/${testname}.out.h5 ./testfiles/${testname}.out.h5 ${srcname} ${dstname} ) set_tests_properties (H5COPY_SAME-${testname}-DIFF PROPERTIES DEPENDS H5COPY_SAME-${testname}) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5COPY_SAME-${testname}-DIFF PROPERTIES WILL_FAIL "true") endif () endif () @@ -226,10 +226,10 @@ # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5COPY-CMP-${testname} COMMAND $ -i ./testfiles/${infile} -o ./testfiles/${testname}.out.h5 ${vparam} ${sparam} ${srcname} ${dparam} ${dstname} ${ARGN}) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5COPY-CMP-${testname} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY-CMP-${testname} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -272,7 +272,7 @@ testfiles/${testname}.out.h5.out testfiles/${testname}.out.h5.out.err ) - if ("${resultcode}" STREQUAL "2") + if (${resultcode} EQUAL 2) add_test ( NAME H5COPY_UD-${testname} COMMAND "${CMAKE_COMMAND}" @@ -335,7 +335,7 @@ testfiles/${testname}_ERR.out.h5.out testfiles/${testname}_ERR.out.h5.out.err ) - if ("${resultcode}" STREQUAL "2") + if (${resultcode} EQUAL 2) add_test ( NAME H5COPY_UD_ERR-${testname} COMMAND "${CMAKE_COMMAND}" @@ -443,7 +443,7 @@ h5copy_misc1.out.out.err ) set_tests_properties (H5COPY-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5COPY-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5COPY-clearall-objects") diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 1376e0d..6bce3f7 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -354,10 +354,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DIFF-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -369,7 +369,7 @@ testfiles/${resultfile}.out testfiles/${resultfile}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DIFF-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -396,10 +396,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME MPI_TEST_H5DIFF-${resultfile} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS} ${ARGN}) set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/PAR/testfiles") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (MPI_TEST_H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -411,7 +411,7 @@ PAR/testfiles/${resultfile}.out PAR/testfiles/${resultfile}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (MPI_TEST_H5DIFF-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -444,7 +444,7 @@ testfiles/${resultfile}.out testfiles/${resultfile}.out.err ) - if ("${resultcode}" STREQUAL "2") + if (${resultcode} EQUAL 2) add_test ( NAME H5DIFF_UD-${testname} COMMAND "${CMAKE_COMMAND}" @@ -925,7 +925,7 @@ h5diff_vlstr.out.err ) set_tests_properties (H5DIFF-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DIFF-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5DIFF-clearall-objects") diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 382e664..16dbc4d 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -406,7 +406,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${testname} COMMAND $ ${ARGN}) set_tests_properties (H5DUMP-${testname} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-${testname} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5DUMP-${testname}") @@ -419,7 +419,7 @@ testfiles/std/h5dump-${testname}.out testfiles/std/h5dump-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -456,10 +456,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -492,10 +492,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-N-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5DUMP-N-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-N-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-N-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -528,10 +528,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ ${ARGN} ${resultfile}.txt ${targetfile}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -571,10 +571,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ --ddl=${ddlfile}.txt ${ARGN} ${resultfile}.txt ${targetfile}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -1149,7 +1149,7 @@ zerodim.out.err ) set_tests_properties (H5DUMP-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/std") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5DUMP-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5DUMP-clearall-objects") diff --git a/tools/test/h5dump/CMakeTestsPBITS.cmake b/tools/test/h5dump/CMakeTestsPBITS.cmake index 4f3ee9f..a8ccb7d 100644 --- a/tools/test/h5dump/CMakeTestsPBITS.cmake +++ b/tools/test/h5dump/CMakeTestsPBITS.cmake @@ -124,10 +124,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/pbits") - if (NOT ${resultcode} STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_pbits_test}" STREQUAL "") + if (last_pbits_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_pbits_test}) endif () else () @@ -275,7 +275,7 @@ tpbitsUnsignedLongLong16.out.err ) set_tests_properties (H5DUMP_PACKED_BITS-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/pbits") - if (NOT "${last_pbits_test}" STREQUAL "") + if (last_pbits_test) set_tests_properties (H5DUMP_PACKED_BITS-clearall-objects PROPERTIES DEPENDS ${last_pbits_test}) endif () set (last_pbits_test "H5DUMP_PACKED_BITS-clearall-objects") diff --git a/tools/test/h5dump/CMakeTestsVDS.cmake b/tools/test/h5dump/CMakeTestsVDS.cmake index 922e79e..d7e3b88 100644 --- a/tools/test/h5dump/CMakeTestsVDS.cmake +++ b/tools/test/h5dump/CMakeTestsVDS.cmake @@ -120,10 +120,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_vds_test}" STREQUAL "") + if (last_vds_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_VDS_test}) endif () else () @@ -159,10 +159,10 @@ ENVIRONMENT "HDF5_VDS_PREFIX=${PROJECT_BINARY_DIR}/testfiles/vds/" WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds/prefix" ) - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP_PREFIX-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_vds_test}" STREQUAL "") + if (last_vds_test) set_tests_properties (H5DUMP_PREFIX-${resultfile} PROPERTIES DEPENDS ${last_VDS_test}) endif () else () @@ -197,10 +197,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP-${resultfile} COMMAND $ -p ${ARGN}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_vds_test}" STREQUAL "") + if (last_vds_test) set_tests_properties (H5DUMP-${resultfile} PROPERTIES DEPENDS ${last_VDS_test}) endif () else () @@ -276,7 +276,7 @@ vds_layout-maxmin.out.err ) set_tests_properties (H5DUMP_VDS-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") - if (NOT "${last_vds_test}" STREQUAL "") + if (last_vds_test) set_tests_properties (H5DUMP_VDS-clearall-objects PROPERTIES DEPENDS ${last_vds_test}) endif () set (last_VDS_test "H5DUMP_VDS-clearall-objects") diff --git a/tools/test/h5dump/CMakeTestsXML.cmake b/tools/test/h5dump/CMakeTestsXML.cmake index de87d2f..e48cec1 100644 --- a/tools/test/h5dump/CMakeTestsXML.cmake +++ b/tools/test/h5dump/CMakeTestsXML.cmake @@ -178,10 +178,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5DUMP_XML-${resultfile} COMMAND $ --xml ${ARGN}) set_tests_properties (H5DUMP_XML-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/xml") - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5DUMP_XML-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_xml_test}" STREQUAL "") + if (last_xml_test) set_tests_properties (H5DUMP_XML-${resultfile} PROPERTIES DEPENDS ${last_xml_test}) endif () else () @@ -357,7 +357,7 @@ tvlstr.h5.out.err ) set_tests_properties (H5DUMP-XML-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/xml") - if (NOT "${last_xml_test}" STREQUAL "") + if (last_xml_test) set_tests_properties (H5DUMP-XML-clearall-objects PROPERTIES DEPENDS ${last_xml_test}) endif () set (last_test "H5DUMP-XML-clearall-objects") diff --git a/tools/test/h5format_convert/CMakeTests.cmake b/tools/test/h5format_convert/CMakeTests.cmake index 5792d40..5599c1b 100644 --- a/tools/test/h5format_convert/CMakeTests.cmake +++ b/tools/test/h5format_convert/CMakeTests.cmake @@ -108,10 +108,10 @@ ./testfiles/${testname}.out ./testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () - if (NOT "${testfile}" STREQUAL "") + if (${testfile}) add_test ( NAME H5FC-${testname}-${testfile}-tmpfile COMMAND ${CMAKE_COMMAND} @@ -161,7 +161,7 @@ ./testfiles/${testname}.out ./testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -197,48 +197,30 @@ ./testfiles/${testname}.out ./testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () - if (NOT "${testfile}" STREQUAL "") - add_test ( - NAME H5FC-${testname}-${testfile}-tmpfile - COMMAND ${CMAKE_COMMAND} - -E copy_if_different ${HDF5_TOOLS_TEST_H5FC_SOURCE_DIR}/testfiles/${testfile} ./testfiles/outtmp.h5 - ) - set_tests_properties (H5FC-${testname}-${testfile}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") - add_test ( - NAME H5FC-${testname}-${testfile} - COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS=${ARGN};outtmp.h5" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" - -D "TEST_OUTPUT=${testname}.out" - -D "TEST_EXPECT=${resultcode}" - -D "TEST_REFERENCE=${resultfile}" - -D "TEST_ERRREF=${resultfile}.err" - -D "TEST_MASK_ERROR=true" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" - ) - set_tests_properties (H5FC-${testname}-${testfile} PROPERTIES DEPENDS "H5FC-${testname}-${testfile}-tmpfile") - set (last_test "H5FC-${testname}-${testfile}") - else () - add_test ( - NAME H5FC-${testname}-NA - COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=$" - -D "TEST_ARGS=${ARGN}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" - -D "TEST_OUTPUT=${testname}.out" - -D "TEST_EXPECT=${resultcode}" - -D "TEST_REFERENCE=${resultfile}" - -D "TEST_ERRREF=${resultfile}.err" - -D "TEST_MASK_ERROR=true" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" - ) - set_tests_properties (H5FC-${testname}-NA PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") - set (last_test "H5FC-${testname}-NA") - endif () + add_test ( + NAME H5FC-${testname}-${testfile}-tmpfile + COMMAND ${CMAKE_COMMAND} + -E copy_if_different ${HDF5_TOOLS_TEST_H5FC_SOURCE_DIR}/testfiles/${testfile} ./testfiles/outtmp.h5 + ) + set_tests_properties (H5FC-${testname}-${testfile}-tmpfile PROPERTIES DEPENDS "H5FC-${testname}-clear-objects") + add_test ( + NAME H5FC-${testname}-${testfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=$" + -D "TEST_ARGS=${ARGN};outtmp.h5" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${testname}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}" + -D "TEST_ERRREF=${resultfile}.err" + -D "TEST_MASK_ERROR=true" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + set_tests_properties (H5FC-${testname}-${testfile} PROPERTIES DEPENDS "H5FC-${testname}-${testfile}-tmpfile") + set (last_test "H5FC-${testname}-${testfile}") endif () endmacro () @@ -253,7 +235,7 @@ ./testfiles/${testname}.out ./testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -300,7 +282,7 @@ ./testfiles/${testname}.out ./testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -343,7 +325,7 @@ ./testfiles/${testname}_chk.out ./testfiles/${testname}_chk.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -449,7 +431,7 @@ chktmp.h5 dmptmp.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5FC-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5FC-clearall-objects") diff --git a/tools/test/h5import/CMakeTests.cmake b/tools/test/h5import/CMakeTests.cmake index 7d76fba..1090640 100644 --- a/tools/test/h5import/CMakeTests.cmake +++ b/tools/test/h5import/CMakeTests.cmake @@ -99,7 +99,7 @@ # If using memchecker skip macro based tests if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5IMPORT-${testname} COMMAND $ ${importfile} -c ${conffile} -o ${testfile}) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5IMPORT-${testname} PROPERTIES DEPENDS H5IMPORT-h5importtest) endif () else () @@ -499,7 +499,7 @@ binuin32.bin binuin32.conf ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5IMPORT-h5importtest-clear-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5IMPORT-clear-objects") diff --git a/tools/test/h5jam/CMakeTests.cmake b/tools/test/h5jam/CMakeTests.cmake index 2d00b86..677ba5c 100644 --- a/tools/test/h5jam/CMakeTests.cmake +++ b/tools/test/h5jam/CMakeTests.cmake @@ -55,7 +55,7 @@ # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5JAM-${expectfile} COMMAND $ ${ARGN}) - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5JAM-${expectfile} PROPERTIES WILL_FAIL "true") endif () else () @@ -91,7 +91,7 @@ # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5JAM-UNJAM-${expectfile} COMMAND $ ${ARGN}) - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5JAM-UNJAM-${expectfile} PROPERTIES WILL_FAIL "true") endif () else () @@ -205,7 +205,7 @@ set (compare_test "") endif () endif () - if (NOT "${compare_test}" STREQUAL "") + if (${compare_test}) add_test ( NAME H5JAM-${testname}-UNJAM-CHECK_UB_1-clear-objects COMMAND ${CMAKE_COMMAND} @@ -244,7 +244,7 @@ -D "TEST_OFILE=NULL" -P "${HDF_RESOURCES_DIR}/userblockTest.cmake" ) - if (NOT "${compare_test}" STREQUAL "") + if (${compare_test}) set_tests_properties (H5JAM-${testname}-UNJAM-CHECK_NOUB PROPERTIES DEPENDS H5JAM-${testname}-UNJAM-CHECK_UB_1) else () set_tests_properties (H5JAM-${testname}-UNJAM-CHECK_NOUB PROPERTIES DEPENDS H5JAM-${testname}-UNJAM) diff --git a/tools/test/h5ls/CMakeTests.cmake b/tools/test/h5ls/CMakeTests.cmake index 116d097..95af5ab 100644 --- a/tools/test/h5ls/CMakeTests.cmake +++ b/tools/test/h5ls/CMakeTests.cmake @@ -139,10 +139,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5LS-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5LS-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5LS-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -174,10 +174,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5LS-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5LS-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5LS-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -354,7 +354,7 @@ tvldtypes2be.out.err ) set_tests_properties (H5LS-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5LS-clearall-objects") diff --git a/tools/test/h5ls/CMakeTestsVDS.cmake b/tools/test/h5ls/CMakeTestsVDS.cmake index 2b6f61e..562a892 100644 --- a/tools/test/h5ls/CMakeTestsVDS.cmake +++ b/tools/test/h5ls/CMakeTestsVDS.cmake @@ -85,10 +85,10 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5LS-${resultfile} COMMAND $ ${ARGN}) set_tests_properties (H5LS-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5LS-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -123,10 +123,10 @@ ENVIRONMENT "HDF5_VDS_PREFIX=\${ORIGIN}" WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles" ) - if ("${resultcode}" STREQUAL "1") + if (${resultcode} EQUAL 1) set_tests_properties (H5LS_PREFIX-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS_PREFIX-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -193,7 +193,7 @@ tvds_layout-5.out.err ) set_tests_properties (H5LS_VDS-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles/vds") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5LS_VDS-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5LS_VDS-clearall-objects") diff --git a/tools/test/h5repack/CMakeTests.cmake b/tools/test/h5repack/CMakeTests.cmake index c2a2be7..2ad12ad 100644 --- a/tools/test/h5repack/CMakeTests.cmake +++ b/tools/test/h5repack/CMakeTests.cmake @@ -162,7 +162,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5REPACK-h5repack-${testname} COMMAND $ ${ARGN}) set_tests_properties (H5REPACK-h5repack-${testname} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK-h5repack-${testname} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5REPACK-h5repack-${testname}") @@ -174,7 +174,7 @@ testfiles/h5repack-${testname}.out testfiles/h5repack-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK-h5repack-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -208,7 +208,7 @@ -E remove testfiles/out-${testname}.${testfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_OLD-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -240,7 +240,7 @@ -E remove testfiles/out-${testname}.${testfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -272,7 +272,7 @@ NAME H5REPACK_CMP-${testname} COMMAND $ ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_CMP-${testname} PROPERTIES DEPENDS ${last_test}) endif () else () @@ -284,7 +284,7 @@ testfiles/${resultfile}-${testname}.out testfiles/${resultfile}-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_CMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -320,7 +320,7 @@ NAME H5REPACK_MASK-${testname} COMMAND $ ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_MASK-${testname} PROPERTIES DEPENDS ${last_test}) endif () else (HDF5_ENABLE_USING_MEMCHECKER) @@ -332,7 +332,7 @@ testfiles/${resultfile}-${testname}.out testfiles/${resultfile}-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_MASK-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -371,7 +371,7 @@ testfiles/${resultfile}-${testname}.out testfiles/${resultfile}-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_DMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -414,7 +414,7 @@ testfiles/${resultfile}-${testname}.out testfiles/${resultfile}-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_STAT-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -458,7 +458,7 @@ testfiles/${testfile}-${testname}-v.out testfiles/${testfile}-${testname}-v.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_VERIFY_LAYOUT-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -471,7 +471,7 @@ COMMAND $ ${PROJECT_BINARY_DIR}/testfiles/${testfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${testfile} ) set_tests_properties (H5REPACK_VERIFY_LAYOUT-${testname}_DFF PROPERTIES DEPENDS H5REPACK_VERIFY_LAYOUT-${testname}) - if ("${resultcode}" STREQUAL "0") + if (NOT ${resultcode}) add_test ( NAME H5REPACK_VERIFY_LAYOUT-${testname}_DMP COMMAND "${CMAKE_COMMAND}" @@ -533,7 +533,7 @@ testfiles/${testfile}-${testname}-v.out testfiles/${testfile}-${testname}-v.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_VERIFY_LAYOUT_VDS-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -570,7 +570,7 @@ testfiles/${testfile}-${testname}-v.out testfiles/${testfile}-${testname}-v.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_VERIFY_SUPERBLOCK-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -601,7 +601,7 @@ -E remove testfiles/out-${testname}.${testfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (ADD_H5_VERIFY_INVALIDBOUNDS-h5repack-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -624,7 +624,7 @@ testfiles/out-${testname}_N.${testname}.h5 testfiles/out-${testname}_M.${testname}.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_META-${testname}_N-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -656,7 +656,7 @@ testfiles/${resultfile}-${testname}.out testfiles/${resultfile}-${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK_UD-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -901,7 +901,7 @@ COMMAND ${CMAKE_COMMAND} -E remove ${LIST_TO_CLEAR} ) set_tests_properties (H5REPACK-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () endif () diff --git a/tools/test/h5repack/CMakeVFDTests.cmake b/tools/test/h5repack/CMakeVFDTests.cmake index 2042f31..e100e3c 100644 --- a/tools/test/h5repack/CMakeVFDTests.cmake +++ b/tools/test/h5repack/CMakeVFDTests.cmake @@ -47,7 +47,7 @@ -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" -P "${HDF_RESOURCES_DIR}/vfdTest.cmake" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5REPACK-VFD-${vfdname}-h5repacktest PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5REPACK-VFD-${vfdname}-h5repacktest") diff --git a/tools/test/h5stat/CMakeTests.cmake b/tools/test/h5stat/CMakeTests.cmake index ec8c9b1..737f4b5 100644 --- a/tools/test/h5stat/CMakeTests.cmake +++ b/tools/test/h5stat/CMakeTests.cmake @@ -97,10 +97,10 @@ # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5STAT-${resultfile} COMMAND $ ${ARGN}) - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5STAT-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5STAT-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else (HDF5_ENABLE_USING_MEMCHECKER) @@ -111,7 +111,7 @@ ${resultfile}.out ${resultfile}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5STAT-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -133,10 +133,10 @@ # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) add_test (NAME H5STAT-${resultfile} COMMAND $ ${ARGN}) - if (NOT "${resultcode}" STREQUAL "0") + if (${resultcode}) set_tests_properties (H5STAT-${resultfile} PROPERTIES WILL_FAIL "true") endif () - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5STAT-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else (HDF5_ENABLE_USING_MEMCHECKER) @@ -147,7 +147,7 @@ ${resultfile}.out ${resultfile}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5STAT-${resultfile}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -182,7 +182,7 @@ COMMAND ${CMAKE_COMMAND} -E remove ${CLEAR_LIST} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5STAT-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5STAT-clearall-objects") diff --git a/tools/test/misc/CMakeTestsClear.cmake b/tools/test/misc/CMakeTestsClear.cmake index c46ac59..24774fd 100644 --- a/tools/test/misc/CMakeTestsClear.cmake +++ b/tools/test/misc/CMakeTestsClear.cmake @@ -94,7 +94,7 @@ testfiles/${testname}.out testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_CMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -122,7 +122,7 @@ testfiles/${testname}.out testfiles/${testname}.out.err ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_CMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -152,7 +152,7 @@ testfiles/${testname}.out.err testfiles/${testfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_CMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -188,7 +188,7 @@ testfiles/${testname}.out.err testfiles/${testfile} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_CMP-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -223,7 +223,7 @@ ) set_tests_properties (H5CLEAR_RET-${testname} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") set_tests_properties (H5CLEAR_RET-${testname} PROPERTIES WILL_FAIL "${resultcode}") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_RET-${testname} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR_RET-${testname}") @@ -242,7 +242,7 @@ testfiles/${testname}_after_size.out.err testfiles/${testname}.h5 ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR_FILESIZE_TEST-${testname}-clear-objects PROPERTIES DEPENDS ${last_test}) endif () add_test ( @@ -302,7 +302,7 @@ -E copy_if_different "${PROJECT_SOURCE_DIR}/testfiles/${testfile}.h5" "${PROJECT_BINARY_DIR}/testfiles/${testfile}.h5" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-clr_open_chk-copy_${testname}.h5 PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR-clr_open_chk-copy_${testname}.h5") @@ -312,7 +312,7 @@ add_test (NAME H5CLEAR-clr_open_chk-${testname}_${resultcode} COMMAND $ ${testfile}.h5) set_tests_properties (H5CLEAR-clr_open_chk-${testname}_${resultcode} PROPERTIES WILL_FAIL "${resultcode}") set_tests_properties (H5CLEAR-clr_open_chk-${testname}_${resultcode} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-clr_open_chk-${testname}_${resultcode} PROPERTIES DEPENDS ${last_test}) endif () @@ -356,7 +356,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) mod_h5clear_mdc_image2.h5 ${HDF5_TEST_FILES} ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR-clearall-objects") @@ -368,7 +368,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) -E copy_if_different "${PROJECT_SOURCE_DIR}/testfiles/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/${h5_file}" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-copy_${h5_file} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR-copy_${h5_file}") @@ -381,7 +381,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) -E copy_if_different "${PROJECT_SOURCE_DIR}/testfiles/${h5_file}" "${PROJECT_BINARY_DIR}/testfiles/orig_${h5_file}" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-copy_orig_${h5_file} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR-copy_orig_${h5_file}") @@ -393,7 +393,7 @@ if (HDF5_ENABLE_USING_MEMCHECKER) -E copy_if_different "${PROJECT_SOURCE_DIR}/testfiles/mod_h5clear_mdc_image.h5" "${PROJECT_BINARY_DIR}/testfiles/mod_h5clear_mdc_image2.h5" ) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5CLEAR-copy_mod_h5clr_mdc_image2.h5 PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5CLEAR-copy_mod_h5clr_mdc_image2.h5") diff --git a/tools/test/misc/CMakeTestsMkgrp.cmake b/tools/test/misc/CMakeTestsMkgrp.cmake index e99983b..db3b7e4 100644 --- a/tools/test/misc/CMakeTestsMkgrp.cmake +++ b/tools/test/misc/CMakeTestsMkgrp.cmake @@ -73,7 +73,7 @@ ) set_tests_properties (H5MKGRP-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") if (HDF5_ENABLE_USING_MEMCHECKER) - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5MKGRP-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () else (HDF5_ENABLE_USING_MEMCHECKER) @@ -174,7 +174,7 @@ h5mkgrp_nested_mult_lp.out.err ) set_tests_properties (H5MKGRP-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (NOT "${last_test}" STREQUAL "") + if (last_test) set_tests_properties (H5MKGRP-clearall-objects PROPERTIES DEPENDS ${last_test}) endif () set (last_test "H5MKGRP-clearall-objects") -- cgit v0.12 From 58e6e3e102180e6ab454441869ec68b2ef506f20 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Fri, 15 Feb 2019 16:04:06 -0600 Subject: HDFFV-10703 macro vars need quotes --- java/examples/datasets/CMakeLists.txt | 5 ++--- java/examples/groups/CMakeLists.txt | 4 ++-- test/CMakeTests.cmake | 4 ++-- test/CMakeVFDTests.cmake | 6 +++--- test/CMakeVOLTests.cmake | 6 +++--- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/java/examples/datasets/CMakeLists.txt b/java/examples/datasets/CMakeLists.txt index 2338d0f..c327c86 100644 --- a/java/examples/datasets/CMakeLists.txt +++ b/java/examples/datasets/CMakeLists.txt @@ -71,7 +71,7 @@ foreach (HDFJAVA_JAR ${CMAKE_JAVA_INCLUDE_PATH}) set (CMAKE_JAVA_CLASSPATH "${CMAKE_JAVA_CLASSPATH}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${HDFJAVA_JAR}") endforeach () -MACRO (ADD_H5_TEST resultfile resultcode) +macro (ADD_H5_TEST resultfile resultcode) set (CMD_ARGS "-Dhdf.hdf5lib.H5.loadLibraryName=$:_DEBUG>>;") add_test ( NAME JAVA_datasets-${resultfile} @@ -91,10 +91,9 @@ MACRO (ADD_H5_TEST resultfile resultcode) set_tests_properties (JAVA_datasets-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_datasets-${resultfile}") -ENDMACRO () +endmacro () if (BUILD_TESTING) - foreach (example ${HDF_JAVA_EXAMPLES}) if (example STREQUAL "H5Ex_D_External") add_test ( diff --git a/java/examples/groups/CMakeLists.txt b/java/examples/groups/CMakeLists.txt index 631eba7..b31a186 100644 --- a/java/examples/groups/CMakeLists.txt +++ b/java/examples/groups/CMakeLists.txt @@ -55,7 +55,7 @@ foreach (h5_file ${HDF_JAVA_TEST_FILES}) endforeach () add_custom_target(H5Ex_G_Visit_files ALL COMMENT "Copying files needed by H5Ex_G_Visit tests" DEPENDS ${H5Ex_G_Visit_files_list}) -MACRO (ADD_H5_TEST resultfile resultcode) +macro (ADD_H5_TEST resultfile resultcode) set (CMD_ARGS "-Dhdf.hdf5lib.H5.loadLibraryName=$:_DEBUG>>;") add_test ( NAME JAVA_groups-${resultfile} @@ -75,7 +75,7 @@ MACRO (ADD_H5_TEST resultfile resultcode) set_tests_properties (JAVA_groups-${resultfile} PROPERTIES DEPENDS ${last_test}) endif () set (last_test "JAVA_groups-${resultfile}") -ENDMACRO () +endmacro () if (BUILD_TESTING) foreach (example ${HDF_JAVA_EXAMPLES}) diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 26e5a78..c606eb1 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -555,7 +555,7 @@ foreach (h5_test ${H5_TESTS}) WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST ) else () - if (h5_test STREQUAL "big" AND CYGWIN) + if ("${h5_test}" STREQUAL "big" AND CYGWIN) add_test (NAME H5TEST-${h5_test} COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${test}" ) @@ -598,7 +598,7 @@ if (BUILD_SHARED_LIBS) foreach (h5_test ${H5_TESTS}) if (NOT h5_test IN_LIST H5TEST_SEPARATE_TESTS) - if (h5_test STREQUAL "big" AND CYGWIN) + if ("${h5_test}" STREQUAL "big" AND CYGWIN) add_test (NAME H5TEST-shared-${h5_test} COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${test}-shared" ) diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index ad3d1e9..a4cf26d 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -109,8 +109,8 @@ endif () # Windows only macro macro (CHECK_VFD_TEST vfdtest vfdname resultcode) - if (vfdtest STREQUAL "flush1" OR vfdtest STREQUAL "flush2") - if (vfdname STREQUAL "multi" OR vfdname STREQUAL "split") + if ("${vfdtest}" STREQUAL "flush1" OR "${vfdtest}" STREQUAL "flush2") + if ("${vfdname}" STREQUAL "multi" OR "${vfdname}" STREQUAL "split") if (NOT BUILD_SHARED_LIBS AND NOT HDF_CFG_NAME MATCHES "Debug") add_test ( NAME VFD-${vfdname}-${vfdtest}-clear-objects @@ -239,7 +239,7 @@ endif () ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${vfdname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${vfdname} ) - if (BUILD_SHARED_LIBS AND NOT vfdtest STREQUAL "cache") + if (BUILD_SHARED_LIBS AND NOT "${vfdtest}" STREQUAL "cache") add_test ( NAME VFD-${vfdname}-${vfdtest}-shared-clear-objects COMMAND ${CMAKE_COMMAND} diff --git a/test/CMakeVOLTests.cmake b/test/CMakeVOLTests.cmake index 7c02e23..cf47291 100644 --- a/test/CMakeVOLTests.cmake +++ b/test/CMakeVOLTests.cmake @@ -106,8 +106,8 @@ endif () # Windows only macro macro (CHECK_VOL_TEST voltest volname volinfo resultcode) - if (voltest STREQUAL "flush1" OR voltest STREQUAL "flush2") - if (volname STREQUAL "multi" OR volname STREQUAL "split") + if ("${voltest}" STREQUAL "flush1" OR "${voltest}" STREQUAL "flush2") + if ("${volname}" STREQUAL "multi" OR "${volname}" STREQUAL "split") if (NOT BUILD_SHARED_LIBS AND NOT ${HDF_CFG_NAME} MATCHES "Debug") add_test ( NAME VOL-${volname}-${voltest}-clear-objects @@ -236,7 +236,7 @@ endif () ENVIRONMENT "srcdir=${HDF5_TEST_BINARY_DIR}/${volname};HDF5TestExpress=${HDF_TEST_EXPRESS}" WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/${volname} ) - if (BUILD_SHARED_LIBS AND NOT voltest STREQUAL "cache") + if (BUILD_SHARED_LIBS AND NOT "${voltest}" STREQUAL "cache") add_test ( NAME VOL-${volname}-${voltest}-shared-clear-objects COMMAND ${CMAKE_COMMAND} -- cgit v0.12 From 0116375ed2f1807c16908bfc63bab001a7c17df2 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Fri, 15 Feb 2019 16:22:31 -0600 Subject: HDFFV-10703 revert pre-3.11 option --- CMakeInstallation.cmake | 13 ++++--- MANIFEST | 1 + config/cmake/hdf5-config-version.cmake.in | 58 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 config/cmake/hdf5-config-version.cmake.in diff --git a/CMakeInstallation.cmake b/CMakeInstallation.cmake index 6d05a58..7cf3450 100644 --- a/CMakeInstallation.cmake +++ b/CMakeInstallation.cmake @@ -104,10 +104,15 @@ endif () # Configure the hdf5-config-version .cmake file for the install directory #----------------------------------------------------------------------------- if (NOT HDF5_EXTERNALLY_CONFIGURED) - write_basic_package_version_file ( - ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake - VERSION ${HDF5_PACKAGE_VERSION} - COMPATIBILITY SameMinorVersion + # 3.11 or greater + #write_basic_package_version_file ( + # ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake + # VERSION ${HDF5_PACKAGE_VERSION} + # COMPATIBILITY SameMinorVersion + #) + configure_file ( + ${HDF_RESOURCES_DIR}/hdf5-config-version.cmake.in + ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake @ONLY ) install ( FILES ${HDF5_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HDF5_PACKAGE}${HDF_PACKAGE_EXT}-config-version.cmake diff --git a/MANIFEST b/MANIFEST index 0b2026d..6c2018a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -3240,6 +3240,7 @@ ./config/cmake/H5cxx_config.h.in ./config/cmake/H5pubconf.h.in ./config/cmake/hdf5-config.cmake.in +./config/cmake/hdf5-config-version.cmake.in ./config/cmake/HDFCompilerFlags.cmake ./config/cmake/HDF5_Process_Flex_Files.cmake ./config/cmake/HDF5Macros.cmake diff --git a/config/cmake/hdf5-config-version.cmake.in b/config/cmake/hdf5-config-version.cmake.in new file mode 100644 index 0000000..8e16725 --- /dev/null +++ b/config/cmake/hdf5-config-version.cmake.in @@ -0,0 +1,58 @@ +# +# Copyright by The HDF Group. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the COPYING file, which can be found at the root of the source code +# distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +# +#----------------------------------------------------------------------------- +# HDF5 Version file for install directory +#----------------------------------------------------------------------------- +# +# The created file sets PACKAGE_VERSION_EXACT if the current version string and +# the requested version string are exactly the same and it sets +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major.minor version is the same as the current one. +# The variable HDF5_VERSION_STRING must be set before calling configure_file(). + +set (PACKAGE_VERSION "@HDF5_VERSION_STRING@") + +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else () + if ("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "@H5_VERS_MAJOR@") + + # exact match for version @H5_VERS_MAJOR@.@H5_VERS_MINOR@ + if ("${PACKAGE_FIND_VERSION_MINOR}" STREQUAL "@H5_VERS_MINOR@") + + # compatible with any version @H5_VERS_MAJOR@.@H5_VERS_MINOR@.x + set (PACKAGE_VERSION_COMPATIBLE TRUE) + + if ("${PACKAGE_FIND_VERSION_PATCH}" STREQUAL "@H5_VERS_RELEASE@") + set (PACKAGE_VERSION_EXACT TRUE) + + if ("${PACKAGE_FIND_VERSION_TWEAK}" STREQUAL "@H5_VERS_SUBRELEASE@") + # not using this yet + endif () + endif () + else () + set (PACKAGE_VERSION_COMPATIBLE FALSE) + endif () + endif () +endif () + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") + return() +endif () + +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") + math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") + set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif () -- cgit v0.12 From d16c4f59c266a6bad2b0faa90b413510d624f97e Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Fri, 15 Feb 2019 16:40:13 -0600 Subject: HDFFV-10703 Update version match logic --- config/cmake/hdf5-config-version.cmake.in | 50 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/config/cmake/hdf5-config-version.cmake.in b/config/cmake/hdf5-config-version.cmake.in index 8e16725..575c1ab 100644 --- a/config/cmake/hdf5-config-version.cmake.in +++ b/config/cmake/hdf5-config-version.cmake.in @@ -21,38 +21,38 @@ set (PACKAGE_VERSION "@HDF5_VERSION_STRING@") -if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) -else () - if ("${PACKAGE_FIND_VERSION_MAJOR}" STREQUAL "@H5_VERS_MAJOR@") +else() + if("@H5_VERS_MAJOR@.@H5_VERS_MINOR@" MATCHES "^([0-9]+)\\.([0-9]+)") + set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}") + else() + set(CVF_VERSION_MAJOR "@HDF5_VERSION_STRING@") + set(CVF_VERSION_MINOR "") + endif() + + if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND + (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR)) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() + + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() - # exact match for version @H5_VERS_MAJOR@.@H5_VERS_MINOR@ - if ("${PACKAGE_FIND_VERSION_MINOR}" STREQUAL "@H5_VERS_MINOR@") - - # compatible with any version @H5_VERS_MAJOR@.@H5_VERS_MINOR@.x - set (PACKAGE_VERSION_COMPATIBLE TRUE) - - if ("${PACKAGE_FIND_VERSION_PATCH}" STREQUAL "@H5_VERS_RELEASE@") - set (PACKAGE_VERSION_EXACT TRUE) - - if ("${PACKAGE_FIND_VERSION_TWEAK}" STREQUAL "@H5_VERS_SUBRELEASE@") - # not using this yet - endif () - endif () - else () - set (PACKAGE_VERSION_COMPATIBLE FALSE) - endif () - endif () -endif () # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: -if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") +if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") return() -endif () +endif() # check that the installed version has the same 32/64bit-ness as the one which is currently searching: -if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") +if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@") math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") set(PACKAGE_VERSION_UNSUITABLE TRUE) -endif () +endif() -- cgit v0.12 From 6c212353c45ef84b5c977c6019e4d72263534aea Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sat, 16 Feb 2019 00:47:47 -0600 Subject: Code improvement Description: Removed dead code and accidentally leftover code Platforms tested: Linux/64 (jelly) - very minor --- c++/test/tarray.cpp | 3 +- c++/test/tlinks.cpp | 286 ++--------------------------------------------- release_docs/RELEASE.txt | 6 +- 3 files changed, 13 insertions(+), 282 deletions(-) diff --git a/c++/test/tarray.cpp b/c++/test/tarray.cpp index 6bd4ca6..fccc556 100644 --- a/c++/test/tarray.cpp +++ b/c++/test/tarray.cpp @@ -286,7 +286,7 @@ H5::DataType getArr() *dims = 5; H5::ArrayType ret; ret = H5::ArrayType(H5::PredType::NATIVE_INT, 1, dims); - delete[] dims; + delete dims; return ret; } @@ -371,7 +371,6 @@ static void test_array_info() s1_t rdata[SPACE1_DIM1][ARRAY1_DIM1]; // Information read in hsize_t sdims1[] = {SPACE1_DIM1}; hsize_t tdims1[] = {ARRAY1_DIM1}; - int nmemb; // Number of compound members int ii; // counting variables hsize_t idxi, idxj, idxk; // dimension indicing variables H5T_class_t mclass; // Datatype class for field diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index c8bf8e6..491cd6a 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -31,272 +31,17 @@ using namespace H5; #include "h5test.h" #include "h5cpputil.h" // C++ utilility header file -// A lot of the definition inherited from C test links.c is left here until -// the H5L API is implemented and tests are completed - BMR 10/19/2009 - -/* File for external link test. Created with gen_udlinks.c */ -#define LINKED_FILE "be_extlink2.h5" - -#if 0 -const char *FILENAME[] = { - "links0", - "links1", - "links2", - "links3", - "links4a", /* 4 */ - "links4b", /* 5 */ - "links4c", /* 6 */ - "links4d", /* 7 */ - "links5", /* 8 */ - "links6", /* 9 */ - "links7", /* 10 */ - "links8", /* 11 */ - "extlinks0", /* 12: main files */ - "tmp/extlinks0", /* 13: */ - "extlinks1", /* 14: target files */ - "tmp/extlinks1", /* 15: */ - "extlinks2", /* 16: */ - "tmp/extlinks2", /* 17: */ - "extlinks3", /* 18: */ - "tmp/extlinks3", /* 19: */ - "extlinks4", /* 20: */ - "tmp/extlinks4", /* 21: */ - "extlinks5", /* 22: */ - "tmp/extlinks6", /* 23: */ - "extlinks7", /* 24: */ - "tmp/extlinks7", /* 25: */ - "tmp/extlinks8", /* 26: */ - "extlinks9", /* 27: */ - "tmp/extlinks9", /* 28: */ - "extlinks10", /* 29: */ /* TESTS for windows */ - "tmp/extlinks10", /* 30: */ - "tmp/extlinks11", /* 31: */ - "tmp/extlinks12", /* 32: */ - "extlinks13", /* 33: */ - "tmp/extlinks13", /* 34: */ - "tmp/extlinks14", /* 35: */ - "tmp/extlinks15", /* 36: */ - "extlinks16A", /* 37: */ /* TESTS for H5P_set_elink_fapl */ - "extlinks16B", /* 38: */ - "extlinks17", /* 39: */ - "extlinks18A", /* 40: */ - "extlinks18B", /* 41: */ - "extlinks19A", /* 42: */ - "extlinks19B", /* 43: */ - "extlinks20", /* 44: */ - "visit", /* 45: */ - NULL -}; - -#endif // 0 - -#define TMPDIR "tmp" - -#define FAMILY_SIZE 1024 -#define CORE_INCREMENT 1024 -#define NUM400 400 - -/* do not do check_all_closed() for "ext*" files and "tmp/ext*" */ -#define EXTSTOP 12 - -#define LINK_BUF_SIZE 1024 #define NAME_BUF_SIZE 1024 -#define MAX_NAME_LEN ((64*1024)+1024) - -/* Link type IDs */ -#define UD_HARD_TYPE 201 -#define UD_CB_TYPE H5L_TYPE_MAX -#define UD_PLIST_TYPE 128 -#define UD_CBFAIL_TYPE UD_PLIST_TYPE -#define UD_ERROR_TYPE 189 -#define UD_BAD_TYPE1 H5L_TYPE_HARD -#define UD_BAD_TYPE2 (H5L_TYPE_UD_MIN - 5) -#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1) - -#define DEST_PROP_NAME "destination_group" -#define REREG_TARGET_NAME "rereg_target" - -#define UD_CB_LINK_NAME "ud_callback_link" -#define NEW_UD_CB_LINK_NAME "ud_callback_link2" -#define UD_CB_TARGET "ud_target" -#define UD_CB_TARGET_LEN 10 - -#define LE_FILENAME "le_extlink1.h5" -#define BE_FILENAME "be_extlink1.h5" - -#define ELINK_CB_FAM_SIZE (hsize_t) 100 - #define H5L_DIM1 100 #define H5L_DIM2 100 -/* Creation order macros */ -#define CORDER_SOFT_GROUP_NAME "corder_soft_group" -#define CORDER_NLINKS 18 - -/* Timestamp macros */ -#define TIMESTAMP_GROUP_1 "timestamp1" -#define TIMESTAMP_GROUP_2 "timestamp2" - -/* Link iteration struct */ -typedef struct { - H5_iter_order_t order; /* Direction of iteration */ - unsigned ncalled; /* # of times callback is entered */ - unsigned nskipped; /* # of links skipped */ - int stop; /* # of iterations to stop after */ - int64_t curr; /* Current creation order value */ - size_t max_visit; /* Size of "visited link" flag array */ - hbool_t *visited; /* Pointer to array of "visited link" flags */ -} link_iter_info_t; - -#if 0 -/* Link visit structs */ -typedef struct { - const char *path; /* Path to link */ - H5L_type_t type; /* Type of link */ -} link_visit_t; -static const link_visit_t lvisit0[] = { - {"Dataset_zero", H5L_TYPE_HARD}, - {"Group1", H5L_TYPE_HARD}, - {"Group1/Dataset_one", H5L_TYPE_HARD}, - {"Group1/Group2", H5L_TYPE_HARD}, - {"Group1/Group2/Dataset_two", H5L_TYPE_HARD}, - {"Group1/Group2/Type_two", H5L_TYPE_HARD}, - {"Group1/Group2/hard_zero", H5L_TYPE_HARD}, - {"Group1/Type_one", H5L_TYPE_HARD}, - {"Group1/hard_one", H5L_TYPE_HARD}, - {"Type_zero", H5L_TYPE_HARD}, - {"ext_dangle", H5L_TYPE_EXTERNAL}, - {"ext_one", H5L_TYPE_EXTERNAL}, - {"hard_one", H5L_TYPE_HARD}, - {"hard_two", H5L_TYPE_HARD}, - {"hard_zero", H5L_TYPE_HARD}, - {"soft_dangle", H5L_TYPE_SOFT}, - {"soft_one", H5L_TYPE_SOFT}, - {"soft_two", H5L_TYPE_SOFT} -}; -static const link_visit_t lvisit1[] = { - {"Dataset_one", H5L_TYPE_HARD}, - {"Group2", H5L_TYPE_HARD}, - {"Group2/Dataset_two", H5L_TYPE_HARD}, - {"Group2/Type_two", H5L_TYPE_HARD}, - {"Group2/hard_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/Dataset_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/Group1", H5L_TYPE_HARD}, - {"Group2/hard_zero/Type_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/ext_dangle", H5L_TYPE_EXTERNAL}, - {"Group2/hard_zero/ext_one", H5L_TYPE_EXTERNAL}, - {"Group2/hard_zero/hard_one", H5L_TYPE_HARD}, - {"Group2/hard_zero/hard_two", H5L_TYPE_HARD}, - {"Group2/hard_zero/hard_zero", H5L_TYPE_HARD}, - {"Group2/hard_zero/soft_dangle", H5L_TYPE_SOFT}, - {"Group2/hard_zero/soft_one", H5L_TYPE_SOFT}, - {"Group2/hard_zero/soft_two", H5L_TYPE_SOFT}, - {"Type_one", H5L_TYPE_HARD}, - {"hard_one", H5L_TYPE_HARD} -}; -static const link_visit_t lvisit2[] = { - {"Dataset_two", H5L_TYPE_HARD}, - {"Type_two", H5L_TYPE_HARD}, - {"hard_zero", H5L_TYPE_HARD}, - {"hard_zero/Dataset_zero", H5L_TYPE_HARD}, - {"hard_zero/Group1", H5L_TYPE_HARD}, - {"hard_zero/Group1/Dataset_one", H5L_TYPE_HARD}, - {"hard_zero/Group1/Group2", H5L_TYPE_HARD}, - {"hard_zero/Group1/Type_one", H5L_TYPE_HARD}, - {"hard_zero/Group1/hard_one", H5L_TYPE_HARD}, - {"hard_zero/Type_zero", H5L_TYPE_HARD}, - {"hard_zero/ext_dangle", H5L_TYPE_EXTERNAL}, - {"hard_zero/ext_one", H5L_TYPE_EXTERNAL}, - {"hard_zero/hard_one", H5L_TYPE_HARD}, - {"hard_zero/hard_two", H5L_TYPE_HARD}, - {"hard_zero/hard_zero", H5L_TYPE_HARD}, - {"hard_zero/soft_dangle", H5L_TYPE_SOFT}, - {"hard_zero/soft_one", H5L_TYPE_SOFT}, - {"hard_zero/soft_two", H5L_TYPE_SOFT} -}; - -typedef struct { - unsigned idx; /* Index in link visit structure */ - const link_visit_t *info; /* Pointer to the link visit structure to use */ -} lvisit_ud_t; - -#endif - -/* Object visit structs */ +// Object visit structs typedef struct { const char *path; /* Path to object */ H5O_type_t type; /* Type of object */ } obj_visit_t; -#if 0 -static const obj_visit_t ovisit0_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_zero", H5O_TYPE_DATASET}, - {"Group1", H5O_TYPE_GROUP}, - {"Group1/Dataset_one", H5O_TYPE_DATASET}, - {"Group1/Group2", H5O_TYPE_GROUP}, - {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit0_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_zero", H5O_TYPE_DATASET}, - {"Group1", H5O_TYPE_GROUP}, - {"Group1/Dataset_one", H5O_TYPE_DATASET}, - {"Group1/Group2", H5O_TYPE_GROUP}, - {"Group1/Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group1/Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit1_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_one", H5O_TYPE_DATASET}, - {"Group2", H5O_TYPE_GROUP}, - {"Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group2/hard_zero", H5O_TYPE_GROUP}, - {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}, - {"Type_one", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit1_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_one", H5O_TYPE_DATASET}, - {"Group2", H5O_TYPE_GROUP}, - {"Group2/Dataset_two", H5O_TYPE_DATASET}, - {"Group2/Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"Group2/hard_zero", H5O_TYPE_GROUP}, - {"Group2/hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"Group2/hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE}, - {"Type_one", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit2_old[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_two", H5O_TYPE_DATASET}, - {"Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero", H5O_TYPE_GROUP}, - {"hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"hard_zero/Group1", H5O_TYPE_GROUP}, - {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET}, - {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -static const obj_visit_t ovisit2_new[] = { - {".", H5O_TYPE_GROUP}, - {"Dataset_two", H5O_TYPE_DATASET}, - {"Type_two", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero", H5O_TYPE_GROUP}, - {"hard_zero/Dataset_zero", H5O_TYPE_DATASET}, - {"hard_zero/Group1", H5O_TYPE_GROUP}, - {"hard_zero/Group1/Dataset_one", H5O_TYPE_DATASET}, - {"hard_zero/Group1/Type_one", H5O_TYPE_NAMED_DATATYPE}, - {"hard_zero/Type_zero", H5O_TYPE_NAMED_DATATYPE} -}; -#endif - +// User data for callback function typedef struct { unsigned idx; /* Index in object visit structure */ const obj_visit_t *info; /* Pointer to the object visit structure to use */ @@ -836,6 +581,7 @@ static void test_num_links(hid_t fapl_id, hbool_t new_format) } // test_num_links +// Data for visit on the file static const obj_visit_t file_visit[] = { {".", H5O_TYPE_GROUP}, {"Data", H5O_TYPE_GROUP}, @@ -843,6 +589,7 @@ static const obj_visit_t file_visit[] = { {"Data/Float_Data", H5O_TYPE_DATASET}, }; +// Data for visit on the group static const obj_visit_t group_visit[] = { {".", H5O_TYPE_GROUP}, {"Compressed_Data", H5O_TYPE_DATASET}, @@ -876,8 +623,7 @@ static int visit_obj_cb(H5Object& obj, const H5std_string name, const H5O_info_t * * Purpose Test H5Object::visit * - * Return Success: 0 - * Failure: -1 + * Return None * * February 8, 2019 *------------------------------------------------------------------------- @@ -963,9 +709,10 @@ static void test_visit(hid_t fapl_id, hbool_t new_format) } // end of try block catch (Exception& E) { + cerr << "in catch" << endl; issue_fail_msg("test_visit()", __LINE__, __FILE__, E.getCDetailMsg()); } -} // test_visit +} // test_visit() /*------------------------------------------------------------------------- @@ -983,13 +730,9 @@ void test_links() { hid_t fapl_id, fapl2_id; /* File access property lists */ unsigned new_format; /* Whether to use the new format or not */ - const char *envval; - - envval = HDgetenv("HDF5_DRIVER"); - if(envval == NULL) - envval = "nomatch"; - fapl_id = h5_fileaccess(); + if((fapl_id = h5_fileaccess()) < 0) + throw Exception("test_links", "Unable to get file access property list"); // Output message about test being performed MESSAGE(5, ("Testing Various Links\n")); @@ -1029,18 +772,11 @@ void test_links() H5Pclose(fapl2_id); h5_clean_files(FILENAME, fapl_id); - - /* Test that external links can be used after a library reset. MUST be - * called last so the reset doesn't interfere with the property lists. This - * routine will delete its own file. */ - /* nerrors += external_reset_register() < 0 ? 1 : 0; - */ } catch (Exception& E) { issue_fail_msg("test_links()", __LINE__, __FILE__, E.getCDetailMsg()); } - } @@ -1058,7 +794,3 @@ void cleanup_links() HDremove(FILENAME[0]); HDremove(FILENAME[1]); } - - - - diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8423981..879c3f3 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -167,10 +167,10 @@ New Features C++ Library: ------------ - - Added a wrapper for H5Ovisit2 + - Added new function to the C++ interface - // Recursively visit elements reachable from this object. - void visit(H5_index_t idx_type, H5_iter_order_t order, visit_operator_t user_op, void *op_data, unsigned int fields); + Added wrapper for H5Ovisit2: + H5Object::visit() (BMR - 2019/02/14, HDFFV-10532) -- cgit v0.12 From f69e11efa827521231813496a1ca1243dd0e1cba Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Sat, 16 Feb 2019 19:02:44 -0600 Subject: Remove ' ' (typo). --- bin/batch/cori_knl_ctestS.sl.in.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/batch/cori_knl_ctestS.sl.in.cmake b/bin/batch/cori_knl_ctestS.sl.in.cmake index bcb4881..c6d9e83 100644 --- a/bin/batch/cori_knl_ctestS.sl.in.cmake +++ b/bin/batch/cori_knl_ctestS.sl.in.cmake @@ -1,6 +1,6 @@ #!/bin/bash -#SBATCH -C knl,quad, cache +#SBATCH -C knl,quad,cache #SBATCH --nodes=1 #SBATCH -t 00:30:00 #SBATCH --mail-type=BEGIN,END,FAIL -- cgit v0.12 From a27d1b909d00748ec99bf06e2bf6ee84c6ad4aa1 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Sun, 17 Feb 2019 11:17:19 -0600 Subject: Fix typo --- config/cmake/hdf5-config.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index 800de85..b1ef0ac 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -184,7 +184,7 @@ foreach (libtype IN LISTS ${HDF5_PACKAGE_NAME}_LIB_TYPE) else () set (${HDF5_PACKAGE_NAME}_${libtype}_${comp}_FOUND 1) string(TOUPPER ${HDF5_PACKAGE_NAME}_${comp}_${libtype}_LIBRARY COMP_LIBRARY) - set (${COMP_LIBRARY} ${${COMP_LIBRARY}} @HDF5_PACKAGE@::${hdf5_comp2}-${libtype} @HDF5_PACKAGE@::${hdf5_comp}-${lcomp + set (${COMP_LIBRARY} ${${COMP_LIBRARY}} @HDF5_PACKAGE@::${hdf5_comp2}-${libtype} @HDF5_PACKAGE@::${hdf5_comp}-${libtype}) endif () elseif (comp STREQUAL "Java") set (${HDF5_PACKAGE_NAME}_${comp}_FOUND 1) -- cgit v0.12 From 6d07eb126e63b025199a5fe68f41a42269b5921b Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Sun, 17 Feb 2019 13:56:54 -0600 Subject: Update standard check --- config/cmake_ext_mod/ConfigureChecks.cmake | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 60dda17..cc9de79 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -229,7 +229,7 @@ macro (HDF_FUNCTION_TEST OTHER_TEST) endif () #message (STATUS "Performing ${OTHER_TEST}") - TRY_COMPILE (${OTHER_TEST} + try_compile (${OTHER_TEST} ${CMAKE_BINARY_DIR} ${HDF_RESOURCES_EXT_DIR}/HDFTests.c COMPILE_DEFINITIONS "${MACRO_CHECK_FUNCTION_DEFINITIONS}" @@ -274,12 +274,10 @@ if (NOT WINDOWS) # functionality so clock_gettime and CLOCK_MONOTONIC are defined # correctly. This was later updated to 200112L so that # posix_memalign() is visible for the direct VFD code on Linux - # systems. Even later, this was changed to 200809L to support - # pread/pwrite in VFDs. - # + # systems. # POSIX feature information can be found in the gcc manual at: # http://www.gnu.org/s/libc/manual/html_node/Feature-Test-Macros.html - set (HDF_EXTRA_C_FLAGS -D_POSIX_C_SOURCE=200809L) + set (HDF_EXTRA_C_FLAGS -D_POSIX_C_SOURCE=200112L) # Need to add this so that O_DIRECT is visible for the direct # VFD on Linux systems. @@ -288,7 +286,7 @@ if (NOT WINDOWS) option (HDF_ENABLE_LARGE_FILE "Enable support for large (64-bit) files on Linux." ON) if (HDF_ENABLE_LARGE_FILE AND NOT DEFINED TEST_LFS_WORKS_RUN) set (msg "Performing TEST_LFS_WORKS") - TRY_RUN (TEST_LFS_WORKS_RUN TEST_LFS_WORKS_COMPILE + try_run (TEST_LFS_WORKS_RUN TEST_LFS_WORKS_COMPILE ${CMAKE_BINARY_DIR} ${HDF_RESOURCES_EXT_DIR}/HDFTests.c COMPILE_DEFINITIONS "-DTEST_LFS_WORKS" -- cgit v0.12 From bcf5c400c06bf06820b25c37eceaa97245f15f1f Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Thu, 21 Feb 2019 16:39:37 -0600 Subject: Fix CMake H5_HAVE_THREADSAFE to set value in H5pubconf.h Add REQUIRED to find_package(Threads) Link against thread library if static and not WIN32 platform --- CMakeLists.txt | 12 +++++++----- config/cmake/H5pubconf.h.in | 7 ++++++- src/CMakeLists.txt | 5 +++++ test/CMakeLists.txt | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6446a7d..c2eb94d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -683,8 +683,10 @@ endif () option (HDF5_ENABLE_THREADSAFE "Enable thread-safety" OFF) if (HDF5_ENABLE_THREADSAFE) # check for unsupported options - message (STATUS " **** thread-safety option not supported with static library **** ") - message (STATUS " **** thread-safety option will not be used building static library **** ") + if (WIN32) + message (STATUS " **** thread-safety option not supported with static library **** ") + message (STATUS " **** thread-safety option will not be used building static library **** ") + endif () if (HDF5_ENABLE_PARALLEL) if (NOT ALLOW_UNSUPPORTED) message (FATAL_ERROR " **** parallel and thread-safety options are not supported **** ") @@ -722,9 +724,9 @@ if (HDF5_ENABLE_THREADSAFE) endif () endif () set(THREADS_PREFER_PTHREAD_FLAG ON) - find_package(Threads) - if (NOT Threads_FOUND) - message (STATUS " **** thread-safe package not found - threads still might work **** ") + find_package(Threads REQUIRED) + if (Threads_FOUND) + set (H5_HAVE_THREADSAFE 1) endif () endif () diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 273adb5..9e7b8b7 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -390,8 +390,13 @@ /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_SZLIB_H @H5_HAVE_SZLIB_H@ +#if defined(_WIN32) && !defined(H5_BUILT_AS_DYNAMIC_LIB) +/* Not supported on WIN32 platforms with static linking */ +/* #undef H5_HAVE_THREADSAFE */ +#else /* Define if we have thread safe support */ -#cmakedefine H5_HAVE_THREADSAFE @H5_HAVE_THREADSAFE@ +# cmakedefine H5_HAVE_THREADSAFE @H5_HAVE_THREADSAFE@ +#endif /* Define if timezone is a global variable */ #cmakedefine H5_HAVE_TIMEZONE @H5_HAVE_TIMEZONE@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 698c143..83240bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1118,6 +1118,11 @@ target_link_libraries (${HDF5_LIB_TARGET} PRIVATE ${LINK_LIBS} ${LINK_COMP_LIBS} "$<$:${MPI_C_LIBRARIES}>" PUBLIC $<$>:${CMAKE_DL_LIBS}> ) +if (NOT WIN32) + target_link_libraries (${HDF5_LIB_TARGET} + PUBLIC $<$:Threads::Threads> + ) +endif () set_global_variable (HDF5_LIBRARIES_TO_EXPORT ${HDF5_LIB_TARGET}) H5_SET_LIB_OPTIONS (${HDF5_LIB_TARGET} ${HDF5_LIB_NAME} STATIC 0) set_target_properties (${HDF5_LIB_TARGET} PROPERTIES FOLDER libraries) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c442e9b..276cf09 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -45,7 +45,7 @@ if (BUILD_SHARED_LIBS) INTERFACE "$/include>" ) target_compile_definitions(${HDF5_TEST_LIBSH_TARGET} - PUBLIC "H5_BUILT_AS_DYNAMIC_LIB" $<$:H5_HAVE_THREADSAFE> + PUBLIC "H5_BUILT_AS_DYNAMIC_LIB" ) TARGET_C_PROPERTIES (${HDF5_TEST_LIBSH_TARGET} SHARED) target_link_libraries (${HDF5_TEST_LIBSH_TARGET} -- cgit v0.12 From 8a4371f69ae07619fa9561431b9ee9df9d5b3e47 Mon Sep 17 00:00:00 2001 From: Jordan Henderson Date: Thu, 21 Feb 2019 22:28:17 -0600 Subject: Minor fix in h5str_sprintf for NULL region references --- java/src/jni/h5aImp.c | 2 +- java/src/jni/h5dImp.c | 2 +- java/src/jni/h5util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index e47515d..eaa356e 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -1389,7 +1389,7 @@ Java_hdf_hdf5lib_H5_H5Aread_1reg_1ref H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Aread_reg_ref: buf length < 0"); } - if (NULL == (ref_data = (hdset_reg_ref_t *) HDmalloc((size_t)n * sizeof(hdset_reg_ref_t)))) + if (NULL == (ref_data = (hdset_reg_ref_t *) HDcalloc(1, (size_t)n * sizeof(hdset_reg_ref_t)))) H5_JNI_FATAL_ERROR(ENVONLY, "H5Aread_reg_ref: failed to allocate read buffer"); if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, ref_data)) < 0) diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index 92a3723..d46773a 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -1633,7 +1633,7 @@ Java_hdf_hdf5lib_H5_H5Dread_1reg_1ref H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Dread_reg_ref: buf length < 0"); } - if (NULL == (ref_data = (hdset_reg_ref_t *) HDmalloc((size_t)n * sizeof(hdset_reg_ref_t)))) + if (NULL == (ref_data = (hdset_reg_ref_t *) HDcalloc(1, (size_t)n * sizeof(hdset_reg_ref_t)))) H5_JNI_FATAL_ERROR(ENVONLY, "H5Dread_reg_ref: failed to allocate read buffer"); if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, xfer_plist_id, ref_data)) < 0) diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index fce969e..10ca3f2 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -978,7 +978,7 @@ h5str_sprintf case H5T_REFERENCE: { - if (h5str_is_zero(cptr, 99)) { + if (h5str_is_zero(cptr, typeSize)) { if (!h5str_append(out_str, "NULL")) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); break; -- cgit v0.12 From d6663b95ac7e9e378b24bd721ea4403ca98d4adf Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 23 Feb 2019 17:02:29 -0600 Subject: Revise "management" VOL callbacks into 'info' and object 'wrap / retrieval' classes. --- src/H5Pfapl.c | 2 +- src/H5VL.c | 4 +- src/H5VLcallback.c | 44 +++++++++--------- src/H5VLint.c | 18 ++++---- src/H5VLnative.c | 24 ++++++---- src/H5VLpassthru.c | 132 ++++++++++++++++++++++++++++------------------------- src/H5VLpublic.h | 62 +++++++++++++++---------- test/vol.c | 24 ++++++---- 8 files changed, 170 insertions(+), 140 deletions(-) diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 452ea3f..bfb52ff 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -5231,7 +5231,7 @@ H5P__facc_vol_cmp(const void *_info1, const void *_info2, size_t H5_ATTR_UNUSED /* Use one of the classes (cls1) info comparison routines to compare the * info objects */ - HDassert(cls1->info_cmp == cls2->info_cmp); + HDassert(cls1->info_cls.cmp == cls2->info_cls.cmp); status = H5VL_cmp_connector_info(cls1, &cmp_value, info1->connector_info, info2->connector_info); HDassert(status >= 0); diff --git a/src/H5VL.c b/src/H5VL.c index 37ad187..aa276ec 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -156,9 +156,9 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector class name cannot be the NULL pointer") if (0 == HDstrlen(cls->name)) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector class name cannot be the empty string") - if (cls->info_copy && !cls->info_free) + if (cls->info_cls.copy && !cls->info_cls.free) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector must provide free callback for VOL info objects when a copy callback is provided") - if (cls->get_wrap_ctx && !cls->free_wrap_ctx) + if (cls->wrap_cls.get_wrap_ctx && !cls->wrap_cls.free_wrap_ctx) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector must provide free callback for object wrapping contexts when a get callback is provided") op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index e1030b2..5a5d9ee 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -348,14 +348,14 @@ H5VL_copy_connector_info(const H5VL_class_t *connector, void **dst_info, /* Check for actual source info */ if(src_info) { /* Allow the connector to copy or do it ourselves */ - if(connector->info_copy) { - if(NULL == (new_connector_info = (connector->info_copy)(src_info))) + if(connector->info_cls.copy) { + if(NULL == (new_connector_info = (connector->info_cls.copy)(src_info))) HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "connector info copy callback failed") } /* end if */ - else if(connector->info_size > 0) { - if(NULL == (new_connector_info = H5MM_malloc(connector->info_size))) + else if(connector->info_cls.size > 0) { + if(NULL == (new_connector_info = H5MM_malloc(connector->info_cls.size))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "connector info allocation failed") - HDmemcpy(new_connector_info, src_info, connector->info_size); + HDmemcpy(new_connector_info, src_info, connector->info_cls.size); } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "no way to copy connector info") @@ -444,13 +444,13 @@ H5VL_cmp_connector_info(const H5VL_class_t *connector, int *cmp_value, * if there is a a callback, otherwise just compare the info objects as * memory buffers */ - if(connector->info_cmp) { - if((connector->info_cmp)(cmp_value, info1, info2) < 0) + if(connector->info_cls.cmp) { + if((connector->info_cls.cmp)(cmp_value, info1, info2) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector info") } /* end if */ else { - HDassert(connector->info_size > 0); - *cmp_value = HDmemcmp(info1, info2, connector->info_size); + HDassert(connector->info_cls.size > 0); + *cmp_value = HDmemcmp(info1, info2, connector->info_cls.size); } /* end else */ done: @@ -518,8 +518,8 @@ H5VL_free_connector_info(const H5VL_class_t *connector, void *info) /* Only free info object, if it's non-NULL */ if(info) { /* Allow the connector to free info or do it ourselves */ - if(connector->info_free) { - if((connector->info_free)(info) < 0) + if(connector->info_cls.free) { + if((connector->info_cls.free)(info) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector info free request failed") } /* end if */ else @@ -590,8 +590,8 @@ H5VLconnector_info_to_str(const void *info, hid_t connector_id, char **str) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Allow the connector to serialize info */ - if(cls->info_to_str) { - if((cls->info_to_str)(info, str) < 0) + if(cls->info_cls.to_str) { + if((cls->info_cls.to_str)(info, str) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "can't serialize connector info") } /* end if */ else @@ -632,8 +632,8 @@ H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Allow the connector to deserialize info */ - if(cls->str_to_info) { - if((cls->str_to_info)(str, info) < 0) + if(cls->info_cls.from_str) { + if((cls->info_cls.from_str)(str, info) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize connector info") } /* end if */ else @@ -673,8 +673,8 @@ H5VLget_object(void *obj, hid_t connector_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID") /* Check for 'get_object' callback in connector */ - if(cls->get_object) - ret_value = (cls->get_object)(obj); + if(cls->wrap_cls.get_object) + ret_value = (cls->wrap_cls.get_object)(obj); else ret_value = obj; @@ -706,12 +706,12 @@ H5VL_get_wrap_ctx(const H5VL_class_t *connector, void *obj, void **wrap_ctx) HDassert(wrap_ctx); /* Allow the connector to copy or do it ourselves */ - if(connector->get_wrap_ctx) { + if(connector->wrap_cls.get_wrap_ctx) { /* Sanity check */ - HDassert(connector->free_wrap_ctx); + HDassert(connector->wrap_cls.free_wrap_ctx); /* Invoke connector's callback */ - if((connector->get_wrap_ctx)(obj, wrap_ctx) < 0) + if((connector->wrap_cls.get_wrap_ctx)(obj, wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "connector wrap context callback failed") } /* end if */ else @@ -777,7 +777,7 @@ H5VL_free_wrap_ctx(const H5VL_class_t *connector, void *wrap_ctx) /* Only free wrap context, if it's non-NULL */ if(wrap_ctx) { /* Free the connector's object wrapping context */ - if((connector->free_wrap_ctx)(wrap_ctx) < 0) + if((connector->wrap_cls.free_wrap_ctx)(wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector wrap context free request failed") } /* end if */ @@ -843,7 +843,7 @@ H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx, void *obj, /* Only wrap object if there's a wrap context */ if(wrap_ctx) { /* Ask the connector to wrap the object */ - if(NULL == (ret_value = (connector->wrap_object)(obj, obj_type, wrap_ctx))) + if(NULL == (ret_value = (connector->wrap_cls.wrap_object)(obj, obj_type, wrap_ctx))) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't wrap object") } /* end if */ else diff --git a/src/H5VLint.c b/src/H5VLint.c index f22fdb6..5aa25d2 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -740,8 +740,8 @@ H5VL_object_data(const H5VL_object_t *vol_obj) FUNC_ENTER_NOAPI_NOINIT_NOERR /* Check for 'get_object' callback in connector */ - if(vol_obj->connector->cls->get_object) - ret_value = (vol_obj->connector->cls->get_object)(vol_obj->data); + if(vol_obj->connector->cls->wrap_cls.get_object) + ret_value = (vol_obj->connector->cls->wrap_cls.get_object)(vol_obj->data); else ret_value = vol_obj->data; @@ -933,15 +933,15 @@ H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_clas HDassert(cls1->version == cls2->version); /* Compare connector info */ - if(cls1->info_size < cls2->info_size) { + if(cls1->info_cls.size < cls2->info_cls.size) { *cmp_value = -1; HGOTO_DONE(SUCCEED) } /* end if */ - if(cls1->info_size > cls2->info_size) { + if(cls1->info_cls.size > cls2->info_cls.size) { *cmp_value = 1; HGOTO_DONE(SUCCEED) } /* end if */ - HDassert(cls1->info_size == cls2->info_size); + HDassert(cls1->info_cls.size == cls2->info_cls.size); /* Set comparison value to 'equal' */ *cmp_value = 0; @@ -980,12 +980,12 @@ H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) /* Check for existing wrapping context */ if(NULL == vol_wrap_ctx) { /* Check if the connector can create a wrap context */ - if(connector->cls->get_wrap_ctx) { + if(connector->cls->wrap_cls.get_wrap_ctx) { /* Sanity check */ - HDassert(connector->cls->free_wrap_ctx); + HDassert(connector->cls->wrap_cls.free_wrap_ctx); /* Get the wrap context from the connector */ - if((connector->cls->get_wrap_ctx)(obj, &obj_wrap_ctx) < 0) + if((connector->cls->wrap_cls.get_wrap_ctx)(obj, &obj_wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve VOL connector's object wrap context") } /* end if */ @@ -1048,7 +1048,7 @@ H5VL_reset_vol_wrapper(void) /* If there is a VOL connector object wrapping context, release it */ if(vol_wrap_ctx->obj_wrap_ctx) { /* Release the VOL connector's object wrapping context */ - if((*vol_wrap_ctx->connector->cls->free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) + if((*vol_wrap_ctx->connector->cls->wrap_cls.free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release connector's object wrapping context") } /* end if */ diff --git a/src/H5VLnative.c b/src/H5VLnative.c index fe0fd4e..f4f3b5f 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -38,16 +38,20 @@ static H5VL_class_t H5VL_native_cls_g = { 0, /* capability flags */ NULL, /* initialize */ H5VL__native_term, /* terminate */ - (size_t)0, /* info size */ - NULL, /* info copy */ - NULL, /* info compare */ - NULL, /* info free */ - NULL, /* info to str */ - NULL, /* str to info */ - NULL, /* get_object */ - NULL, /* get_wrap_ctx */ - NULL, /* wrap_object */ - NULL, /* free_wrap_ctx */ + { /* info_cls */ + (size_t)0, /* info size */ + NULL, /* info copy */ + NULL, /* info compare */ + NULL, /* info free */ + NULL, /* info to str */ + NULL /* str to info */ + }, + { /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL /* free_wrap_ctx */ + }, { /* attribute_cls */ H5VL__native_attr_create, /* create */ H5VL__native_attr_open, /* open */ diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index f7f9058..fe72000 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -82,11 +82,15 @@ static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj); /* "Management" callbacks */ static herr_t H5VL_pass_through_init(hid_t vipl_id); static herr_t H5VL_pass_through_term(void); + +/* VOL info callbacks */ static void *H5VL_pass_through_info_copy(const void *info); static herr_t H5VL_pass_through_info_cmp(int *cmp_value, const void *info1, const void *info2); static herr_t H5VL_pass_through_info_free(void *info); static herr_t H5VL_pass_through_info_to_str(const void *info, char **str); static herr_t H5VL_pass_through_str_to_info(const char *str, void **info); + +/* VOL object wrap / retrieval callbacks */ static void *H5VL_pass_through_get_object(const void *obj); static herr_t H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx); static herr_t H5VL_pass_through_free_wrap_ctx(void *obj); @@ -173,82 +177,86 @@ static const H5VL_class_t H5VL_pass_through_g = { 0, /* capability flags */ H5VL_pass_through_init, /* initialize */ H5VL_pass_through_term, /* terminate */ - sizeof(H5VL_pass_through_info_t), /* info size */ - H5VL_pass_through_info_copy, /* info copy */ - H5VL_pass_through_info_cmp, /* info compare */ - H5VL_pass_through_info_free, /* info free */ - H5VL_pass_through_info_to_str, /* info to str */ - H5VL_pass_through_str_to_info, /* str to info */ - H5VL_pass_through_get_object, /* get_object */ - H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */ - H5VL_pass_through_wrap_object, /* wrap_object */ - H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */ + { /* info_cls */ + sizeof(H5VL_pass_through_info_t), /* size */ + H5VL_pass_through_info_copy, /* copy */ + H5VL_pass_through_info_cmp, /* compare */ + H5VL_pass_through_info_free, /* free */ + H5VL_pass_through_info_to_str, /* to_str */ + H5VL_pass_through_str_to_info, /* from_str */ + }, + { /* wrap_cls */ + H5VL_pass_through_get_object, /* get_object */ + H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */ + H5VL_pass_through_wrap_object, /* wrap_object */ + H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */ + }, { /* attribute_cls */ - H5VL_pass_through_attr_create, /* create */ - H5VL_pass_through_attr_open, /* open */ - H5VL_pass_through_attr_read, /* read */ - H5VL_pass_through_attr_write, /* write */ - H5VL_pass_through_attr_get, /* get */ - H5VL_pass_through_attr_specific, /* specific */ - H5VL_pass_through_attr_optional, /* optional */ - H5VL_pass_through_attr_close /* close */ + H5VL_pass_through_attr_create, /* create */ + H5VL_pass_through_attr_open, /* open */ + H5VL_pass_through_attr_read, /* read */ + H5VL_pass_through_attr_write, /* write */ + H5VL_pass_through_attr_get, /* get */ + H5VL_pass_through_attr_specific, /* specific */ + H5VL_pass_through_attr_optional, /* optional */ + H5VL_pass_through_attr_close /* close */ }, { /* dataset_cls */ - H5VL_pass_through_dataset_create, /* create */ - H5VL_pass_through_dataset_open, /* open */ - H5VL_pass_through_dataset_read, /* read */ - H5VL_pass_through_dataset_write, /* write */ - H5VL_pass_through_dataset_get, /* get */ - H5VL_pass_through_dataset_specific, /* specific */ - H5VL_pass_through_dataset_optional, /* optional */ - H5VL_pass_through_dataset_close /* close */ + H5VL_pass_through_dataset_create, /* create */ + H5VL_pass_through_dataset_open, /* open */ + H5VL_pass_through_dataset_read, /* read */ + H5VL_pass_through_dataset_write, /* write */ + H5VL_pass_through_dataset_get, /* get */ + H5VL_pass_through_dataset_specific, /* specific */ + H5VL_pass_through_dataset_optional, /* optional */ + H5VL_pass_through_dataset_close /* close */ }, - { /* datatype_cls */ - H5VL_pass_through_datatype_commit, /* commit */ - H5VL_pass_through_datatype_open, /* open */ - H5VL_pass_through_datatype_get, /* get_size */ - H5VL_pass_through_datatype_specific, /* specific */ - H5VL_pass_through_datatype_optional, /* optional */ - H5VL_pass_through_datatype_close /* close */ + { /* datatype_cls */ + H5VL_pass_through_datatype_commit, /* commit */ + H5VL_pass_through_datatype_open, /* open */ + H5VL_pass_through_datatype_get, /* get_size */ + H5VL_pass_through_datatype_specific, /* specific */ + H5VL_pass_through_datatype_optional, /* optional */ + H5VL_pass_through_datatype_close /* close */ }, { /* file_cls */ - H5VL_pass_through_file_create, /* create */ - H5VL_pass_through_file_open, /* open */ - H5VL_pass_through_file_get, /* get */ - H5VL_pass_through_file_specific, /* specific */ - H5VL_pass_through_file_optional, /* optional */ - H5VL_pass_through_file_close /* close */ + H5VL_pass_through_file_create, /* create */ + H5VL_pass_through_file_open, /* open */ + H5VL_pass_through_file_get, /* get */ + H5VL_pass_through_file_specific, /* specific */ + H5VL_pass_through_file_optional, /* optional */ + H5VL_pass_through_file_close /* close */ }, { /* group_cls */ - H5VL_pass_through_group_create, /* create */ - H5VL_pass_through_group_open, /* open */ - H5VL_pass_through_group_get, /* get */ - H5VL_pass_through_group_specific, /* specific */ - H5VL_pass_through_group_optional, /* optional */ - H5VL_pass_through_group_close /* close */ + H5VL_pass_through_group_create, /* create */ + H5VL_pass_through_group_open, /* open */ + H5VL_pass_through_group_get, /* get */ + H5VL_pass_through_group_specific, /* specific */ + H5VL_pass_through_group_optional, /* optional */ + H5VL_pass_through_group_close /* close */ }, { /* link_cls */ - H5VL_pass_through_link_create, /* create */ - H5VL_pass_through_link_copy, /* copy */ - H5VL_pass_through_link_move, /* move */ - H5VL_pass_through_link_get, /* get */ - H5VL_pass_through_link_specific, /* specific */ - H5VL_pass_through_link_optional, /* optional */ + H5VL_pass_through_link_create, /* create */ + H5VL_pass_through_link_copy, /* copy */ + H5VL_pass_through_link_move, /* move */ + H5VL_pass_through_link_get, /* get */ + H5VL_pass_through_link_specific, /* specific */ + H5VL_pass_through_link_optional, /* optional */ }, { /* object_cls */ - H5VL_pass_through_object_open, /* open */ - H5VL_pass_through_object_copy, /* copy */ - H5VL_pass_through_object_get, /* get */ - H5VL_pass_through_object_specific, /* specific */ - H5VL_pass_through_object_optional, /* optional */ + H5VL_pass_through_object_open, /* open */ + H5VL_pass_through_object_copy, /* copy */ + H5VL_pass_through_object_get, /* get */ + H5VL_pass_through_object_specific, /* specific */ + H5VL_pass_through_object_optional, /* optional */ }, { /* request_cls */ - H5VL_pass_through_request_wait, /* wait */ - H5VL_pass_through_request_notify, /* notify */ - H5VL_pass_through_request_cancel, /* cancel */ - H5VL_pass_through_request_specific, /* specific */ - H5VL_pass_through_request_optional, /* optional */ - H5VL_pass_through_request_free /* free */ + H5VL_pass_through_request_wait, /* wait */ + H5VL_pass_through_request_notify, /* notify */ + H5VL_pass_through_request_cancel, /* cancel */ + H5VL_pass_through_request_specific, /* specific */ + H5VL_pass_through_request_optional, /* optional */ + H5VL_pass_through_request_free /* free */ }, NULL /* optional */ }; diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 6ea9fc1..72e69b8 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -236,6 +236,25 @@ typedef struct H5VL_loc_params_t { } loc_data; } H5VL_loc_params_t; +/* VOL connector info fields & callbacks */ +typedef struct H5VL_info_class_t { + size_t size; /* Size of the VOL info */ + void * (*copy)(const void *info); /* Callback to create a copy of the VOL info */ + herr_t (*cmp)(int *cmp_value, const void *info1, const void *info2); /* Callback to compare VOL info */ + herr_t (*free)(void *info); /* Callback to release a VOL info */ + herr_t (*to_str)(const void *info, char **str); /* Callback to serialize connector's info into a string */ + herr_t (*from_str)(const char *str, void **info); /* Callback to deserialize a string into connector's info */ +} H5VL_info_class_t; + +/* VOL object wrap / retrieval callbacks */ +/* (These only need to be implemented by "pass through" VOL connectors) */ +typedef struct H5VL_wrap_class_t { + void * (*get_object)(const void *obj); /* Callback to retrieve underlying object */ + herr_t (*get_wrap_ctx)(const void *obj, void **wrap_ctx); /* Callback to retrieve the object wrapping context for the connector */ + void * (*wrap_object)(void *obj, H5I_type_t obj_type, void *wrap_ctx); /* Callback to wrap a library object */ + herr_t (*free_wrap_ctx)(void *wrap_ctx); /* Callback to release the object wrapping context for the connector */ +} H5VL_wrap_class_t; + /* H5A routines */ typedef struct H5VL_attr_class_t { void *(*create)(void *obj, const H5VL_loc_params_t *loc_params, const char *attr_name, @@ -370,34 +389,29 @@ typedef int H5VL_class_value_t; /* Class information for each VOL connector */ typedef struct H5VL_class_t { - unsigned int version; /* VOL connector class struct version # */ - H5VL_class_value_t value; /* Value to identify connector */ - const char *name; /* Connector name (MUST be unique!) */ - unsigned cap_flags; /* Capability flags for connector */ - herr_t (*initialize)(hid_t vipl_id); /* Connector initialization callback */ - herr_t (*terminate)(void); /* Connector termination callback */ - size_t info_size; /* Size of the VOL info */ - void * (*info_copy)(const void *info); /* Callback to create a copy of the VOL info */ - herr_t (*info_cmp)(int *cmp_value, const void *info1, const void *info2); /* Callback to compare VOL info */ - herr_t (*info_free)(void *info); /* Callback to release the VOL info copy */ - herr_t (*info_to_str)(const void *info, char **str); /* Callback to serialize connector's info into a string */ - herr_t (*str_to_info)(const char *str, void **info); /* Callback to deserialize a string into connector's info */ - void * (*get_object)(const void *obj); /* Callback to retrieve underlying object */ - herr_t (*get_wrap_ctx)(const void *obj, void **wrap_ctx); /* Callback to retrieve the object wrapping context for the connector */ - void* (*wrap_object)(void *obj, H5I_type_t obj_type, void *wrap_ctx); /* Callback to wrap a library object */ - herr_t (*free_wrap_ctx)(void *wrap_ctx); /* Callback to release the object wrapping context for the connector */ + /* Overall connector fields & callbacks */ + unsigned int version; /* VOL connector class struct version # */ + H5VL_class_value_t value; /* Value to identify connector */ + const char *name; /* Connector name (MUST be unique!) */ + unsigned cap_flags; /* Capability flags for connector */ + herr_t (*initialize)(hid_t vipl_id); /* Connector initialization callback */ + herr_t (*terminate)(void); /* Connector termination callback */ + + /* VOL framework */ + H5VL_info_class_t info_cls; /* VOL info fields & callbacks */ + H5VL_wrap_class_t wrap_cls; /* VOL object wrap / retrieval callbacks */ /* Data Model */ - H5VL_attr_class_t attr_cls; /* attribute class callbacks */ - H5VL_dataset_class_t dataset_cls; /* dataset class callbacks */ - H5VL_datatype_class_t datatype_cls; /* datatype class callbacks */ - H5VL_file_class_t file_cls; /* file class callbacks */ - H5VL_group_class_t group_cls; /* group class callbacks */ - H5VL_link_class_t link_cls; /* link class callbacks */ - H5VL_object_class_t object_cls; /* object class callbacks */ + H5VL_attr_class_t attr_cls; /* Attribute (H5A*) class callbacks */ + H5VL_dataset_class_t dataset_cls; /* Dataset (H5D*) class callbacks */ + H5VL_datatype_class_t datatype_cls; /* Datatype (H5T*) class callbacks */ + H5VL_file_class_t file_cls; /* File (H5F*) class callbacks */ + H5VL_group_class_t group_cls; /* Group (H5G*) class callbacks */ + H5VL_link_class_t link_cls; /* Link (H5L*) class callbacks */ + H5VL_object_class_t object_cls; /* Object (H5O*) class callbacks */ /* Services */ - H5VL_request_class_t request_cls; /* asynchronous request class callbacks */ + H5VL_request_class_t request_cls; /* Asynchronous request class callbacks */ /* Catch-all */ herr_t (*optional)(void *obj, hid_t dxpl_id, void **req, va_list arguments); /* Optional callback */ diff --git a/test/vol.c b/test/vol.c index c55874a..e267084 100644 --- a/test/vol.c +++ b/test/vol.c @@ -49,16 +49,20 @@ static const H5VL_class_t fake_vol_g = { 0, /* capability flags */ NULL, /* initialize */ NULL, /* terminate */ - (size_t)0, /* info size */ - NULL, /* info copy */ - NULL, /* info compare */ - NULL, /* info free */ - NULL, /* info to str */ - NULL, /* str to info */ - NULL, /* get_object */ - NULL, /* get_wrap_ctx */ - NULL, /* wrap_object */ - NULL, /* free_wrap_ctx */ + { /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* free_wrap_ctx */ + }, { /* attribute_cls */ NULL, /* create */ NULL, /* open */ -- cgit v0.12 From 6e77a5800e98886be6575eacdaacee7719bbf362 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Tue, 26 Feb 2019 10:40:20 -0600 Subject: Correct varname --- test/CMakeVFDTests.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index a4cf26d..791f75c 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -199,7 +199,7 @@ endif () ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out ${vfdname}-shared/${vfdname}-${vfdtest}-shared.out.err ) - add_test (NAME VFD-${vfdname}-${test}-shared + add_test (NAME VFD-${vfdname}-${vfdtest}-shared COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$" -D "TEST_ARGS:STRING=" -- cgit v0.12 From 64f21ec6397d00e45ff4d41e70c5131241be587e Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Wed, 27 Feb 2019 11:13:54 -0600 Subject: Correct CMake examples for a binary install --- config/cmake/HDF5_Examples.cmake.in | 2 - config/cmake/HDF5_Examples_options.cmake | 103 +++++++++++++++++++++++++++++++ release_docs/USING_CMake_Examples.txt | 22 +++++-- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/config/cmake/HDF5_Examples.cmake.in b/config/cmake/HDF5_Examples.cmake.in index bac174a..c4d9cd8 100644 --- a/config/cmake/HDF5_Examples.cmake.in +++ b/config/cmake/HDF5_Examples.cmake.in @@ -103,8 +103,6 @@ set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_PACKAGE_NAME:STRING=@HDF5_PAC if(WIN32) include(${CTEST_SCRIPT_DIRECTORY}\\HDF5_Examples_options.cmake) - include(${CTEST_SCRIPT_DIRECTORY}\\CTestScript.cmake) else() include(${CTEST_SCRIPT_DIRECTORY}/HDF5_Examples_options.cmake) - include(${CTEST_SCRIPT_DIRECTORY}/CTestScript.cmake) endif() diff --git a/config/cmake/HDF5_Examples_options.cmake b/config/cmake/HDF5_Examples_options.cmake index 386e99c..6e4b510 100644 --- a/config/cmake/HDF5_Examples_options.cmake +++ b/config/cmake/HDF5_Examples_options.cmake @@ -57,3 +57,106 @@ #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCOMPARE_TESTING:BOOL=ON") ############################################################################################# +# Do not edit below this line +############################################################################################# +#----------------------------------------------------------------------------- +# MAC machines need special option +#----------------------------------------------------------------------------- +if (APPLE) + # Compiler choice + execute_process (COMMAND xcrun --find cc OUTPUT_VARIABLE XCODE_CC OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND xcrun --find c++ OUTPUT_VARIABLE XCODE_CXX OUTPUT_STRIP_TRAILING_WHITESPACE) + set (ENV{CC} "${XCODE_CC}") + set (ENV{CXX} "${XCODE_CXX}") + if (NOT NO_MAC_FORTRAN) + # Shared fortran is not supported, build static + set (BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DBUILD_SHARED_LIBS:BOOL=OFF -DCMAKE_ANSI_CFLAGS:STRING=-fPIC") + else () + set (BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_BUILD_FORTRAN:BOOL=OFF") + endif () + set (BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCTEST_USE_LAUNCHERS:BOOL=ON -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=OFF") +else () + set (BUILD_OPTIONS "${ADD_BUILD_OPTIONS}") +endif () + +#----------------------------------------------------------------------------- +set (CTEST_CMAKE_COMMAND "\"${CMAKE_COMMAND}\"") +## -------------------------- +if (CTEST_USE_TAR_SOURCE) + ## Uncompress source if tar or zip file provided + ## -------------------------- + if (WIN32) + message (STATUS "extracting... [${CMAKE_EXECUTABLE_NAME} -E tar -xvf ${CTEST_USE_TAR_SOURCE}.zip]") + execute_process (COMMAND ${CMAKE_EXECUTABLE_NAME} -E tar -xvf ${CTEST_DASHBOARD_ROOT}\\${CTEST_USE_TAR_SOURCE}.zip RESULT_VARIABLE rv) + else () + message (STATUS "extracting... [${CMAKE_EXECUTABLE_NAME} -E tar -xvf ${CTEST_USE_TAR_SOURCE}.tar]") + execute_process (COMMAND ${CMAKE_EXECUTABLE_NAME} -E tar -xvf ${CTEST_DASHBOARD_ROOT}/${CTEST_USE_TAR_SOURCE}.tar RESULT_VARIABLE rv) + endif () + + if (NOT rv EQUAL 0) + message (STATUS "extracting... [error-(${rv}) clean up]") + file (REMOVE_RECURSE "${CTEST_SOURCE_DIRECTORY}") + message (FATAL_ERROR "error: extract of ${CTEST_SOURCE_NAME} failed") + endif () +endif() + +#----------------------------------------------------------------------------- +## Clear the build directory +## -------------------------- +set (CTEST_START_WITH_EMPTY_BINARY_DIRECTORY TRUE) +if (EXISTS "${CTEST_BINARY_DIRECTORY}" AND IS_DIRECTORY "${CTEST_BINARY_DIRECTORY}") + ctest_empty_binary_directory (${CTEST_BINARY_DIRECTORY}) +else () + file (MAKE_DIRECTORY "${CTEST_BINARY_DIRECTORY}") +endif () + +# Use multiple CPU cores to build +include (ProcessorCount) +ProcessorCount (N) +if (NOT N EQUAL 0) + if (NOT WIN32) + set (CTEST_BUILD_FLAGS -j${N}) + endif () + set (ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) +endif () +set (CTEST_CONFIGURE_COMMAND + "${CTEST_CMAKE_COMMAND} -C \"${CTEST_SOURCE_DIRECTORY}/config/cmake/cacheinit.cmake\" -DCMAKE_BUILD_TYPE:STRING=${CTEST_CONFIGURATION_TYPE} ${BUILD_OPTIONS} \"-G${CTEST_CMAKE_GENERATOR}\" \"${CTEST_SOURCE_DIRECTORY}\"" +) + +#----------------------------------------------------------------------------- +## -- set output to english +set ($ENV{LC_MESSAGES} "en_EN") + +#----------------------------------------------------------------------------- +configure_file (${CTEST_SOURCE_DIRECTORY}/config/cmake/CTestCustom.cmake ${CTEST_BINARY_DIRECTORY}/CTestCustom.cmake) +ctest_read_custom_files ("${CTEST_BINARY_DIRECTORY}") +## NORMAL process +## -------------------------- +ctest_start (Experimental) +ctest_configure (BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) +if (${res} LESS 0 OR ${res} GREATER 0) + file (APPEND ${CTEST_SCRIPT_DIRECTORY}/FailedCTest.txt "Failed Configure: ${res}\n") +endif () +if (LOCAL_SUBMIT) + ctest_submit (PARTS Configure Notes) +endif () +ctest_build (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND APPEND RETURN_VALUE res NUMBER_ERRORS errval) +if (${res} LESS 0 OR ${res} GREATER 0 OR ${errval} GREATER 0) + file(APPEND ${CTEST_SCRIPT_DIRECTORY}/FailedCTest.txt "Failed ${errval} Build: ${res}\n") +endif () +if (LOCAL_SUBMIT) + ctest_submit (PARTS Build) +endif () +ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND ${ctest_test_args} RETURN_VALUE res) +if (${res} LESS 0 OR ${res} GREATER 0) + file(APPEND ${CTEST_SCRIPT_DIRECTORY}/FailedCTest.txt "Failed Tests: ${res}\n") +endif () +if (LOCAL_SUBMIT) + ctest_submit (PARTS Test) +endif () +if (${res} LESS 0 OR ${res} GREATER 0) + message (FATAL_ERROR "tests FAILED") +endif () +#----------------------------------------------------------------------------- +############################################################################################################## +message (STATUS "DONE") diff --git a/release_docs/USING_CMake_Examples.txt b/release_docs/USING_CMake_Examples.txt index d5fae39..ea1ac05 100644 --- a/release_docs/USING_CMake_Examples.txt +++ b/release_docs/USING_CMake_Examples.txt @@ -22,7 +22,7 @@ I. Preconditions 1. We suggest you obtain the latest CMake for windows from the Kitware web site. The HDF5 1.10.x product requires a minimum CMake version - of 3.2.2. + of 3.10.2. 2. You have installed the HDF5 library built with CMake, by executing the HDF Install Utility (the *.msi file in the binary package for @@ -39,11 +39,13 @@ II. Building HDF5 Examples with CMake Files in the HDF5 install directory: HDF5Examples folder HDF5_Examples.cmake + HDF5_Examples_options.cmake Default installation process: Create a directory to run the examples, i.e. \test_hdf5. Copy HDF5Examples folder to this directory. Copy HDF5_Examples.cmake to this directory. + Copy HDF5_Examples_options.cmake to this directory. The default source folder is defined as "HDF5Examples". It can be changed with the CTEST_SOURCE_NAME script option. The default installation folder is defined for the platform. @@ -54,8 +56,9 @@ Default installation process: with the CTEST_CONFIGURATION_TYPE script option. Note that this must be the same as the value used with the -C command line option. The default build configuration is defined to build and use static libraries. - Shared libraries can be used with the STATIC_ONLY script option set to "NO". - Other options can be changed by editing the HDF5_Examples.cmake file. + + Shared libraries and other options can be changed by editing the + HDF5_Examples_options.cmake file. If the defaults are okay, execute from this directory: ctest -S HDF5_Examples.cmake -C Release -V -O test.log @@ -69,9 +72,16 @@ Default installation process: ======================================================================== -III. Other changes to the HDF5_Examples.cmake file +III. Defaults in the HDF5_Examples_options.cmake file ======================================================================== -Line 45-48: uncomment to use a source tarball or zipfile; - Add script option "TAR_SOURCE=MySource.tar". +#### DEFAULT: ### +#### BUILD_SHARED_LIBS:BOOL=OFF ### +#### HDF_BUILD_C:BOOL=ON ### +#### HDF_BUILD_CXX:BOOL=OFF ### +#### HDF_BUILD_FORTRAN:BOOL=OFF ### +#### HDF_BUILD_JAVA:BOOL=OFF ### +#### BUILD_TESTING:BOOL=OFF ### +#### HDF_ENABLE_PARALLEL:BOOL=OFF ### +#### HDF_ENABLE_THREADSAFE:BOOL=OFF ### -- cgit v0.12 From b23079de3af4bfb7aa0508fb81aacd67a76c2114 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Thu, 28 Feb 2019 14:36:38 -0600 Subject: HDFFV-10705: Fixed memory leak in scale offset filter. --- src/H5Zscaleoffset.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index cdf31a4..0026749 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -1174,6 +1174,8 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* special case: minbits equal to full precision */ if(minbits == p.size * 8) { HDmemcpy(outbuf, (unsigned char*)(*buf)+buf_offset, size_out); + /* free the original buffer */ + H5MM_xfree(*buf); /* convert to dataset datatype endianness order if needed */ if(need_convert) @@ -1272,6 +1274,9 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* special case: minbits equal to full precision */ if(minbits == p.size * 8) { HDmemcpy(outbuf + buf_offset, *buf, nbytes); + /* free the original buffer */ + H5MM_xfree(*buf); + *buf = outbuf; outbuf = NULL; *buf_size = size_out; -- cgit v0.12 From b8468e6fdb1fc6d7cfc47cc9324a4453d5c79358 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 5 Mar 2019 10:36:28 -0600 Subject: Move 'minimize dataset object header flag' into API context --- src/H5CX.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5CXprivate.h | 4 +++ src/H5Dint.c | 12 +++---- 3 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index d90fec1..cfcdfd4 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -186,6 +186,10 @@ typedef struct H5CX_t { hid_t lapl_id; /* LAPL ID for API operation */ H5P_genplist_t *lapl; /* Link Access Property List */ + /* DCPL */ + hid_t dcpl_id; /* DCPL ID for API operation */ + H5P_genplist_t *dcpl; /* Dataset Creation Property List */ + /* Internal: Object tagging info */ haddr_t tag; /* Current object's tag (ohdr chunk #0 address) */ @@ -271,6 +275,10 @@ typedef struct H5CX_t { size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */ hbool_t nlinks_valid; /* Whether number of soft / UD links to traverse is valid */ + /* Cached DCPL properties */ + hbool_t do_min_dset_ohdr; /* Whether to minimize dataset object header */ + hbool_t do_min_dset_ohdr_valid; /* Whether minimize dataset object header flag is valid */ + /* Cached VOL settings */ H5VL_connector_prop_t vol_connector_prop; /* Property for VOL connector ID & info */ hbool_t vol_connector_prop_valid; /* Whether property for VOL connector ID & info is valid */ @@ -325,6 +333,12 @@ typedef struct H5CX_lapl_cache_t { size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */ } H5CX_lapl_cache_t; +/* Typedef for cached default dataset creation property list information */ +/* (Same as the cached DXPL struct, above, except for the default DCPL) */ +typedef struct H5CX_dcpl_cache_t { + hbool_t do_min_dset_ohdr; /* Whether to minimize dataset object header */ +} H5CX_dcpl_cache_t; + /********************/ /* Local Prototypes */ @@ -358,6 +372,9 @@ static H5CX_dxpl_cache_t H5CX_def_dxpl_cache; /* Define a "default" link access property list cache structure to use for default LAPLs */ static H5CX_lapl_cache_t H5CX_def_lapl_cache; +/* Define a "default" dataset creation property list cache structure to use for default DCPLs */ +static H5CX_dcpl_cache_t H5CX_def_dcpl_cache; + /* Declare a static free list to manage H5CX_node_t structs */ H5FL_DEFINE_STATIC(H5CX_node_t); @@ -378,6 +395,7 @@ H5CX__init_package(void) { H5P_genplist_t *dx_plist; /* Data transfer property list */ H5P_genplist_t *la_plist; /* Link access property list */ + H5P_genplist_t *dc_plist; /* Dataset creation property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -477,6 +495,20 @@ H5CX__init_package(void) if(H5P_get(la_plist, H5L_ACS_NLINKS_NAME, &H5CX_def_lapl_cache.nlinks) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve number of soft / UD links to traverse") + + /* Reset the "default DCPL cache" information */ + HDmemset(&H5CX_def_dcpl_cache, 0, sizeof(H5CX_dcpl_cache_t)); + + /* Get the default DCPL cache information */ + + /* Get the default link access property list */ + if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_CREATE_DEFAULT))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list") + + /* Get flag to indicate whether to minimize dataset object header */ + if(H5P_get(dc_plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &H5CX_def_dcpl_cache.do_min_dset_ohdr) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX__init_package() */ @@ -732,6 +764,35 @@ H5CX_set_dxpl(hid_t dxpl_id) /*------------------------------------------------------------------------- + * Function: H5CX_set_dcpl + * + * Purpose: Sets the DCPL for the current API call context. + * + * Return: + * + * Programmer: Quincey Koziol + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +void +H5CX_set_dcpl(hid_t dcpl_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(*head); + + /* Set the API context's DCPL to a new value */ + (*head)->ctx.dcpl_id = dcpl_id; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5CX_set_dcpl() */ + + +/*------------------------------------------------------------------------- * Function: H5CX_set_lapl * * Purpose: Sets the LAPL for the current API call context. @@ -2001,6 +2062,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5CX_get_dset_min_ohdr_flag + * + * Purpose: Retrieves the flag that indicates whether the dataset object + * header should be minimized + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_dset_min_ohdr_flag(hbool_t *dset_min_ohdr_flag) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(dset_min_ohdr_flag); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); + + H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, do_min_dset_ohdr) + + /* Get the value */ + *dset_min_ohdr_flag = (*head)->ctx.do_min_dset_ohdr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_dset_min_ohdr_flag() */ + + +/*------------------------------------------------------------------------- * Function: H5CX_set_tag * * Purpose: Sets the object tag for the current API call context. diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index 46d25d0..51ee96b 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -60,6 +60,7 @@ H5_DLL hbool_t H5CX_is_def_dxpl(void); /* "Setter" routines for API context info */ H5_DLL void H5CX_set_dxpl(hid_t dxpl_id); H5_DLL void H5CX_set_lapl(hid_t lapl_id); +H5_DLL void H5CX_set_dcpl(hid_t dcpl_id); H5_DLL herr_t H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, hid_t loc_id, hbool_t is_collective); H5_DLL herr_t H5CX_set_loc(hid_t loc_id); @@ -105,6 +106,9 @@ H5_DLL herr_t H5CX_get_dt_conv_cb(H5T_conv_cb_t *cb_struct); /* "Getter" routines for LAPL properties cached in API context */ H5_DLL herr_t H5CX_get_nlinks(size_t *nlinks); +/* "Getter" routines for DCPL properties cached in API context */ +H5_DLL herr_t H5CX_get_dset_min_ohdr_flag(hbool_t *dset_min_ohdr_flag); + /* "Setter" routines for API context info */ H5_DLL void H5CX_set_tag(haddr_t tag); H5_DLL void H5CX_set_ring(H5AC_ring_t ring); diff --git a/src/H5Dint.c b/src/H5Dint.c index 7eb1aaf..384c66b 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -488,6 +488,9 @@ H5D__new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type) new_dset->dcpl_id = H5P_copy_plist(plist, FALSE); } /* end else */ + /* Set the DCPL for the API context */ + H5CX_set_dcpl(new_dset->dcpl_id); + /* Set return value */ ret_value = new_dset; @@ -678,7 +681,6 @@ done: static herr_t H5D__use_minimized_dset_headers(H5F_t *file, H5D_t *dset, hbool_t *minimize) { - H5P_genplist_t *plist = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT; @@ -687,11 +689,9 @@ H5D__use_minimized_dset_headers(H5F_t *file, H5D_t *dset, hbool_t *minimize) HDassert(dset); HDassert(minimize); - plist = H5P_object_verify(dset->shared->dcpl_id, H5P_DATASET_CREATE); - if(NULL == plist) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "problem getting dcpl") - if(H5P_get(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, minimize) == FAIL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get minimize value from dcpl") + /* Get the dataset object header minimize flag for this call */ + if(H5CX_get_dset_min_ohdr_flag(minimize) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset object header minimize flag from API context") if(FALSE == *minimize) *minimize = H5F_get_min_dset_ohdr(file); -- cgit v0.12 From 775e3740d64ca9a8a31ded673e93815d76387dad Mon Sep 17 00:00:00 2001 From: Larry Knox Date: Tue, 5 Mar 2019 17:23:56 -0600 Subject: Update documents following DHF5 1.10.5 release. --- release_docs/HISTORY-1_10.txt | 1035 ++++++++++++++++++++++++++++++++++++++++ release_docs/README_HDF5_CMake | 23 + release_docs/README_HPC | 285 ++++++++--- 3 files changed, 1264 insertions(+), 79 deletions(-) create mode 100644 release_docs/README_HDF5_CMake diff --git a/release_docs/HISTORY-1_10.txt b/release_docs/HISTORY-1_10.txt index 9887a54..ad8beb2 100644 --- a/release_docs/HISTORY-1_10.txt +++ b/release_docs/HISTORY-1_10.txt @@ -3,6 +3,8 @@ HDF5 History This file contains development history of the HDF5 1.10 branch +06. Release Information for hdf5-1.10.4 +05. Release Information for hdf5-1.10.3 04. Release Information for hdf5-1.10.2 03. Release Information for hdf5-1.10.1 02. Release Information for hdf5-1.10.0-patch1 @@ -10,6 +12,1039 @@ This file contains development history of the HDF5 1.10 branch [Search on the string '%%%%' for section breaks of each release.] +%%%%1.10.4%%%% + +HDF5 version 1.10.4 released on 2018-10-05 +================================================================================ + + +INTRODUCTION + +This document describes the differences between this release and the previous +HDF5 release. It contains information on the platforms tested and known +problems in this release. For more details check the HISTORY*.txt files in the +HDF5 source. + +Note that documentation in the links below will be updated at the time of each +final release. + +Links to HDF5 documentation can be found on The HDF5 web page: + + https://portal.hdfgroup.org/display/HDF5/HDF5 + +The official HDF5 releases can be obtained from: + + https://www.hdfgroup.org/downloads/hdf5/ + +Changes from Release to Release and New Features in the HDF5-1.10.x release series +can be found at: + + https://portal.hdfgroup.org/display/HDF5/HDF5+Application+Developer%27s+Guide + +If you have any questions or comments, please send them to the HDF Help Desk: + + help@hdfgroup.org + + +CONTENTS + +- Bug Fixes since HDF5-1.10.3 +- Supported Platforms +- Tested Configuration Features Summary +- More Tested Platforms +- Known Problems +- CMake vs. Autotools installations + + +New Features +============ + + Configuration: + ------------- + - Add toolchain and cross-compile support + + Added info on using a toolchain file to INSTALL_CMAKE.txt. A + toolchain file is also used in cross-compiling, which requires + CMAKE_CROSSCOMPILING_EMULATOR to be set. To help with cross-compiling + the fortran configure process, the HDF5UseFortran.cmake file macros + were improved. Fixed a Fortran configure file issue that incorrectly + used #cmakedefine instead of #define. + + (ADB - 2018/10/04, HDFFV-10594) + + - Add warning flags for Intel compilers + + Identified Intel compiler specific warnings flags that should be used + instead of GNU flags. + + (ADB - 2018/10/04, TRILABS-21) + + - Add default rpath to targets + + Default rpaths should be set in shared executables and + libraries to allow the use of loading dependent libraries + without requiring LD_LIBRARY_PATH to be set. The default + path should be relative using @rpath on osx and $ORIGIN + on linux. Windows is not affected. + + (ADB - 2018/09/26, HDFFV-10594) + + Library: + -------- + - Allow pre-generated H5Tinit.c and H5make_libsettings.c to be used. + + Rather than always running H5detect and generating H5Tinit.c and + H5make_libsettings.c, supply a location for those files. + + (ADB - 2018/09/18, HDFFV-10332) + + +Bug Fixes since HDF5-1.10.3 release +================================== + + Library + ------- + - Allow H5detect and H5make_libsettings to take a file as an argument. + + Rather than only writing to stdout, add a command argument to name + the file that H5detect and H5make_libsettings will use for output. + Without an argument, stdout is still used, so backwards compatibility + is maintained. + + (ADB - 2018/09/05, HDFFV-9059) + + - A bug was discovered in the parallel library where an application + would hang if a collective read/write of a chunked dataset occurred + when collective metadata reads were enabled and some of the ranks + had no selection in the dataset's dataspace. The ranks which had no + selection in the dataset's dataspace called H5D__chunk_addrmap() to + retrieve the lowest chunk address in the dataset. This is because we + require reads/writes to be performed in strictly non-decreasing order + of chunk address in the file. + + When the chunk index used was a version 1 or 2 B-tree, these + non-participating ranks would issue a collective MPI_Bcast() call + that the participating ranks would not issue, causing the hang. Since + the non-participating ranks are not actually reading/writing anything, + the H5D__chunk_addrmap() call can be safely removed and the address used + for the read/write can be set to an arbitrary number (0 was chosen). + + (JTH - 2018/08/25, HDFFV-10501) + + Java Library: + ---------------- + - JNI native library dependencies + + The build for the hdf5_java native library used the wrong + hdf5 target library for CMake builds. Correcting the hdf5_java + library to build with the shared hdf5 library required testing + paths to change also. + + (ADB - 2018/08/31, HDFFV-10568) + + - Java iterator callbacks + + Change global callback object to a small stack structure in order + to fix a runtime crash. This crash was discovered when iterating + through a file with nested group members. The global variable + visit_callback is overwritten when recursion starts. When recursion + completes, visit_callback will be pointing to the wrong callback method. + + (ADB - 2018/08/15, HDFFV-10536) + + - Java HDFLibraryException class + + Change parent class from Exception to RuntimeException. + + (ADB - 2018/07/30, HDFFV-10534) + + - JNI Read and Write + + Refactored variable-length functions, H5DreadVL and H5AreadVL, + to correct dataset and attribute reads. New write functions, + H5DwriteVL and H5AwriteVL, are under construction. + + (ADB - 2018/06/02, HDFFV-10519) + + +Supported Platforms +=================== + + Linux 2.6.32-696.16.1.el6.ppc64 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + #1 SMP ppc64 GNU/Linux g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + (ostrich) GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + IBM XL C/C++ V13.1 + IBM XL Fortran V15.1 + + Linux 3.10.0-327.10.1.el7 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + (kituo/moohan) Version 4.8.5 20150623 (Red Hat 4.8.5-4) + Version 4.9.3, Version 5.2.0 + Intel(R) C (icc), C++ (icpc), Fortran (icc) + compilers: + Version 17.0.0.098 Build 20160721 + MPICH 3.1.4 compiled with GCC 4.9.3 + + SunOS 5.11 32- and 64-bit Sun C 5.12 SunOS_sparc + (emu) Sun Fortran 95 8.6 SunOS_sparc + Sun C++ 5.12 SunOS_sparc + + Windows 7 Visual Studio 2015 w/ Intel Fortran 16 (cmake) + + Windows 7 x64 Visual Studio 2012 w/ Intel Fortran 15 (cmake) + Visual Studio 2013 w/ Intel Fortran 15 (cmake) + Visual Studio 2015 w/ Intel Fortran 16 (cmake) + Visual Studio 2015 w/ Intel C, Fortran 2017 (cmake) + Visual Studio 2015 w/ MSMPI 8 (cmake) + + Windows 10 Visual Studio 2015 w/ Intel Fortran 18 (cmake) + + Windows 10 x64 Visual Studio 2015 w/ Intel Fortran 18 (cmake) + Visual Studio 2017 w/ Intel Fortran 18 (cmake) + + Mac OS X Yosemite 10.10.5 Apple clang/clang++ version 6.1 from Xcode 7.0 + 64-bit gfortran GNU Fortran (GCC) 4.9.2 + (osx1010dev/osx1010test) Intel icc/icpc/ifort version 15.0.3 + + Mac OS X El Capitan 10.11.6 Apple clang/clang++ version 7.3.0 from Xcode 7.3 + 64-bit gfortran GNU Fortran (GCC) 5.2.0 + (osx1011dev/osx1011test) Intel icc/icpc/ifort version 16.0.2 + + Mac OS Sierra 10.12.6 Apple LLVM version 8.1.0 (clang/clang++-802.0.42) + 64-bit gfortran GNU Fortran (GCC) 7.1.0 + (kite) Intel icc/icpc/ifort version 17.0.2 + + +Tested Configuration Features Summary +===================================== + + In the tables below + y = tested + n = not tested in this release + C = Cluster + W = Workstation + x = not working in this release + dna = does not apply + ( ) = footnote appears below second table + = testing incomplete on this feature or platform + +Platform C F90/ F90 C++ zlib SZIP + parallel F2003 parallel +Solaris2.11 32-bit n y/y n y y y +Solaris2.11 64-bit n y/n n y y y +Windows 7 y y/y n y y y +Windows 7 x64 y y/y y y y y +Windows 7 Cygwin n y/n n y y y +Windows 7 x64 Cygwin n y/n n y y y +Windows 10 y y/y n y y y +Windows 10 x64 y y/y n y y y +Mac OS X Mavericks 10.9.5 64-bit n y/y n y y y +Mac OS X Yosemite 10.10.5 64-bit n y/y n y y y +Mac OS X El Capitan 10.11.6 64-bit n y/y n y y y +Mac OS Sierra 10.12.6 64-bit n y/y n y y y +CentOS 7.2 Linux 3.10.0 x86_64 PGI n y/y n y y y +CentOS 7.2 Linux 3.10.0 x86_64 GNU y y/y y y y y +CentOS 7.2 Linux 3.10.0 x86_64 Intel n y/y n y y y +Linux 2.6.32-573.18.1.el6.ppc64 n y/y n y y y + + +Platform Shared Shared Shared Thread- + C libs F90 libs C++ libs safe +Solaris2.11 32-bit y y y y +Solaris2.11 64-bit y y y y +Windows 7 y y y y +Windows 7 x64 y y y y +Windows 7 Cygwin n n n y +Windows 7 x64 Cygwin n n n y +Windows 10 y y y y +Windows 10 x64 y y y y +Mac OS X Mavericks 10.9.5 64-bit y n y y +Mac OS X Yosemite 10.10.5 64-bit y n y y +Mac OS X El Capitan 10.11.6 64-bit y n y y +Mac OS Sierra 10.12.6 64-bit y n y y +CentOS 7.2 Linux 3.10.0 x86_64 PGI y y y n +CentOS 7.2 Linux 3.10.0 x86_64 GNU y y y y +CentOS 7.2 Linux 3.10.0 x86_64 Intel y y y n +Linux 2.6.32-573.18.1.el6.ppc64 y y y n + +Compiler versions for each platform are listed in the preceding +"Supported Platforms" table. + + +More Tested Platforms +===================== +The following platforms are not supported but have been tested for this release. + + Linux 2.6.32-573.22.1.el6 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + (mayll/platypus) Version 4.4.7 20120313 + Version 4.9.3, 5.3.0, 6.2.0 + PGI C, Fortran, C++ for 64-bit target on + x86-64; + Version 17.10-0 + Intel(R) C (icc), C++ (icpc), Fortran (icc) + compilers: + Version 17.0.4.196 Build 20170411 + MPICH 3.1.4 compiled with GCC 4.9.3 + + Linux 3.10.0-327.18.2.el7 GNU C (gcc) and C++ (g++) compilers + #1 SMP x86_64 GNU/Linux Version 4.8.5 20150623 (Red Hat 4.8.5-4) + (jelly) with NAG Fortran Compiler Release 6.1(Tozai) + GCC Version 7.1.0 + OpenMPI 3.0.0-GCC-7.2.0-2.29, + 3.1.0-GCC-7.2.0-2.29 + Intel(R) C (icc) and C++ (icpc) compilers + Version 17.0.0.098 Build 20160721 + with NAG Fortran Compiler Release 6.1(Tozai) + + Linux 3.10.0-327.10.1.el7 MPICH 3.2 compiled with GCC 5.3.0 + #1 SMP x86_64 GNU/Linux + (moohan) + + Linux 2.6.32-573.18.1.el6.ppc64 MPICH mpich 3.1.4 compiled with + #1 SMP ppc64 GNU/Linux IBM XL C/C++ for Linux, V13.1 + (ostrich) and IBM XL Fortran for Linux, V15.1 + + Debian 8.4 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1 x86_64 GNU/Linux + gcc, g++ (Debian 4.9.2-10) 4.9.2 + GNU Fortran (Debian 4.9.2-10) 4.9.2 + (cmake and autotools) + + Fedora 24 4.7.2-201.fc24.x86_64 #1 SMP x86_64 x86_64 x86_64 GNU/Linux + gcc, g++ (GCC) 6.1.1 20160621 + (Red Hat 6.1.1-3) + GNU Fortran (GCC) 6.1.1 20160621 + (Red Hat 6.1.1-3) + (cmake and autotools) + + Ubuntu 16.04.1 4.4.0-38-generic #57-Ubuntu SMP x86_64 GNU/Linux + gcc, g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) + 5.4.0 20160609 + GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.2) + 5.4.0 20160609 + (cmake and autotools) + + +Known Problems +============== + + At present, metadata cache images may not be generated by parallel + applications. Parallel applications can read files with metadata cache + images, but since this is a collective operation, a deadlock is possible + if one or more processes do not participate. + + Three tests fail with OpenMPI 3.0.0/GCC-7.2.0-2.29: + testphdf5 (ecdsetw, selnone, cchunk1, cchunk3, cchunk4, and actualio) + t_shapesame (sscontig2) + t_pflush1/fails on exit + The first two tests fail attempting collective writes. + + Known problems in previous releases can be found in the HISTORY*.txt files + in the HDF5 source. Please report any new problems found to + help@hdfgroup.org. + + +CMake vs. Autotools installations +================================= +While both build systems produce similar results, there are differences. +Each system produces the same set of folders on linux (only CMake works +on standard Windows); bin, include, lib and share. Autotools places the +COPYING and RELEASE.txt file in the root folder, CMake places them in +the share folder. + +The bin folder contains the tools and the build scripts. Additionally, CMake +creates dynamic versions of the tools with the suffix "-shared". Autotools +installs one set of tools depending on the "--enable-shared" configuration +option. + build scripts + ------------- + Autotools: h5c++, h5cc, h5fc + CMake: h5c++, h5cc, h5hlc++, h5hlcc + +The include folder holds the header files and the fortran mod files. CMake +places the fortran mod files into separate shared and static subfolders, +while Autotools places one set of mod files into the include folder. Because +CMake produces a tools library, the header files for tools will appear in +the include folder. + +The lib folder contains the library files, and CMake adds the pkgconfig +subfolder with the hdf5*.pc files used by the bin/build scripts created by +the CMake build. CMake separates the C interface code from the fortran code by +creating C-stub libraries for each Fortran library. In addition, only CMake +installs the tools library. The names of the szip libraries are different +between the build systems. + +The share folder will have the most differences because CMake builds include +a number of CMake specific files for support of CMake's find_package and support +for the HDF5 Examples CMake project. + +%%%%1.10.3%%%% + +HDF5 version 1.10.3 released on 2018-08-21 +================================================================================ + + +INTRODUCTION + +This document describes the differences between this release and the previous +HDF5 release. It contains information on the platforms tested and known +problems in this release. For more details check the HISTORY*.txt files in the +HDF5 source. + +Note that documentation in the links below will be updated at the time of each +final release. + +Links to HDF5 documentation can be found on The HDF5 web page: + + https://portal.hdfgroup.org/display/HDF5/HDF5 + +The official HDF5 releases can be obtained from: + + https://www.hdfgroup.org/downloads/hdf5/ + +Changes from Release to Release and New Features in the HDF5-1.10.x release series +can be found at: + + https://portal.hdfgroup.org/display/HDF5/HDF5+Application+Developer%27s+Guide + +If you have any questions or comments, please send them to the HDF Help Desk: + + help@hdfgroup.org + + +CONTENTS + +- New Features +- Bug Fixes since HDF5-1.10.2 +- Supported Platforms +- Tested Configuration Features Summary +- More Tested Platforms +- Known Problems +- CMake vs. Autotools installations + + +New Features +============ + + Library + ------- + - Moved the H5DOread/write_chunk() API calls to H5Dread/write_chunk() + + The functionality of the direct chunk I/O calls in the high-level + library has been moved to the H5D package in the main library. This + will allow using those functions without building the high-level + library. The parameters and functionality of the H5D calls are + identical to the H5DO calls. + + The original H5DO high-level API calls have been retained, though + they are now just wrappers for the H5D calls. They are marked as + deprecated and are only available when the library is built with + deprecated functions. New code should use the H5D calls for this + reason. + + As a part of this work, the following symbols from H5Dpublic.h are no + longer used: + + H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME + H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME + H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME + H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME + H5D_XFER_DIRECT_CHUNK_READ_FLAG_NAME + H5D_XFER_DIRECT_CHUNK_READ_OFFSET_NAME + H5D_XFER_DIRECT_CHUNK_READ_FILTERS_NAME + + And properties with these names are no longer stored in the dataset + transfer property lists. The symbols are still defined in H5Dpublic.h, + but only when the library is built with deprecated symbols. + + (DER - 2018/05/04) + + Configuration: + ------------- + - Add missing USE_110_API_DEFAULT option. + + Option USE_110_API_DEFAULT sets the default version of + versioned APIs. The bin/makevers perl script did not set + the maxidx variable correctly when the 1.10 branch was + created. This caused the versioning process to always use + the latest version of any API. + + (ADB - 2018/08/17, HDFFV-10552) + + - Added configuration checks for the following MPI functions: + + MPI_Mprobe - Used for the Parallel Compression feature + MPI_Imrecv - Used for the Parallel Compression feature + + MPI_Get_elements_x - Used for the "big Parallel I/O" feature + MPI_Type_size_x - Used for the "big Parallel I/O" feature + + (JTH - 2018/08/02, HDFFV-10512) + + - Added section to the libhdf5.settings file to indicate + the status of the Parallel Compression and "big Parallel I/O" + features. + + (JTH - 2018/08/02, HDFFV-10512) + + - Add option to execute swmr shell scripts from CMake. + + Option TEST_SHELL_SCRIPTS redirects processing into a + separate ShellTests.cmake file for UNIX types. The tests + execute the shell scripts if a SH program is found. + + (ADB - 2018/07/16) + + + C++ Library: + ------------ + - New wrappers + + Added the following items: + + + Class DSetAccPropList for the dataset access property list. + + + Wrapper for H5Dget_access_plist to class DataSet + // Gets the access property list of this dataset. + DSetAccPropList getAccessPlist() const; + + + Wrappers for H5Pset_chunk_cache and H5Pget_chunk_cache to class DSetAccPropList + // Sets the raw data chunk cache parameters. + void setChunkCache(size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0) + + // Retrieves the raw data chunk cache parameters. + void getChunkCache(size_t &rdcc_nslots, size_t &rdcc_nbytes, double &rdcc_w0) + + + New operator!= to class DataType (HDFFV-10472) + // Determines whether two datatypes are not the same. + bool operator!=(const DataType& compared_type) + + + Wrappers for H5Oget_info2, H5Oget_info_by_name2, and H5Oget_info_by_idx2 + (HDFFV-10458) + + // Retrieves information about an HDF5 object. + void getObjinfo(H5O_info_t& objinfo, unsigned fields = H5O_INFO_BASIC) const; + + // Retrieves information about an HDF5 object, given its name. + void getObjinfo(const char* name, H5O_info_t& objinfo, + unsigned fields = H5O_INFO_BASIC, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + void getObjinfo(const H5std_string& name, H5O_info_t& objinfo, + unsigned fields = H5O_INFO_BASIC, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + + // Retrieves information about an HDF5 object, given its index. + void getObjinfo(const char* grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, + unsigned fields = H5O_INFO_BASIC, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + void getObjinfo(const H5std_string& grp_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t idx, H5O_info_t& objinfo, + unsigned fields = H5O_INFO_BASIC, + const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + + (BMR - 2018/07/22, HDFFV-10150, HDFFV-10458, HDFFV-1047) + + + Java Library: + ---------------- + - Java HDFLibraryException class + + Change parent class from Exception to RuntimeException. + + (ADB - 2018/07/30, HDFFV-10534) + + - JNI Read and Write + + Refactored variable-length functions, H5DreadVL and H5AreadVL, + to correct dataset and attribute reads. New write functions, + H5DwriteVL and H5AwriteVL, are under construction. + + (ADB - 2018/06/02, HDFFV-10519) + + +Bug Fixes since HDF5-1.10.2 release +================================== + + Library + ------- + - Performance issue with H5Oget_info + + H5Oget_info family of routines retrieves information for an object such + as object type, access time, number of attributes, and storage space etc. + Retrieving all such information regardless is an overkill and causes + performance issue when doing so for many objects. + + Add an additional parameter "fields" to the the H5Oget_info family of routines + indicating the type of information to be retrieved. The same is done to + the H5Ovisit family of routines which recursively visits an object + returning object information in a callback function. Both sets of routines + are versioned and the corresponding compatibility macros are added. + + The version 2 names of the two sets of routines are: + (1) H5Oget_info2, H5Oget_info_by_idx2, H5Oget_info_by_name2 + (2) H5Ovisit2, H5Ovisit_by_name2 + + (VC - 2018/08/15, HDFFV-10180) + + - Test failure due to metadata size in test/vds.c + + The size of metadata from test_api_get_ex_dcpl() in test/vds.c is not as expected + because the latest format should be used when encoding the layout for VDS. + + Set the latest format in a temporary fapl and pass the setting to the routines that + encode the dataset selection for VDS. + + (VC - 2018/08/14 HDFFV-10469) + + - Java HDF5LibraryException class + + The error minor and major values would be lost after the + constructor executed. + + Created two local class variables to hold the values obtained during + execution of the constructor. Refactored the class functions to retrieve + the class values rather then calling the native functions. + The native functions were renamed and called only during execution + of the constructor. + Added error checking to calling class constructors in JNI classes. + + (ADB - 2018/08/06, HDFFV-10544) + + - Added checks of the defined MPI_VERSION to guard against usage of + MPI-3 functions in the Parallel Compression and "big Parallel I/O" + features when HDF5 is built with MPI-2. Previously, the configure + step would pass but the build itself would fail when it could not + locate the MPI-3 functions used. + + As a result of these new checks, HDF5 can again be built with MPI-2, + but the Parallel Compression feature will be disabled as it relies + on the MPI-3 functions used. + + (JTH - 2018/08/02, HDFFV-10512) + + - User's patches: CVEs + + The following patches have been applied: + + CVE-2018-11202 - NULL pointer dereference was discovered in + H5S_hyper_make_spans in H5Shyper.c (HDFFV-10476) + https://security-tracker.debian.org/tracker/CVE-2018-11202 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2018-11202 + + CVE-2018-11203 - A division by zero was discovered in + H5D__btree_decode_key in H5Dbtree.c (HDFFV-10477) + https://security-tracker.debian.org/tracker/CVE-2018-11203 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2018-11203 + + CVE-2018-11204 - A NULL pointer dereference was discovered in + H5O__chunk_deserialize in H5Ocache.c (HDFFV-10478) + https://security-tracker.debian.org/tracker/CVE-2018-11204 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2018-11204 + + CVE-2018-11206 - An out of bound read was discovered in + H5O_fill_new_decode and H5O_fill_old_decode in H5Ofill.c + (HDFFV-10480) + https://security-tracker.debian.org/tracker/CVE-2018-11206 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2018-11206 + + CVE-2018-11207 - A division by zero was discovered in + H5D__chunk_init in H5Dchunk.c (HDFFV-10481) + https://security-tracker.debian.org/tracker/CVE-2018-11207 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=3DCVE-2018-11207 + + (BMR - 2018/7/22, PR#s: 1134 and 1139, + HDFFV-10476, HDFFV-10477, HDFFV-10478, HDFFV-10480, HDFFV-10481) + + - H5Adelete + + H5Adelete failed when deleting the last "large" attribute that + is stored densely via fractal heap/v2 b-tree. + + After removing the attribute, update the ainfo message. If the + number of attributes goes to zero, remove the message. + + (VC - 2018/07/20, HDFFV-9277) + + - A bug was discovered in the parallel library which caused partial + parallel reads of filtered datasets to return incorrect data. The + library used the incorrect dataspace for each chunk read, causing + the selection used in each chunk to be wrong. + + The bug was not caught during testing because all of the current + tests which do parallel reads of filtered data read all of the data + using an H5S_ALL selection. Several tests were added which exercise + partial parallel reads. + + (JTH - 2018/07/16, HDFFV-10467) + + - A bug was discovered in the parallel library which caused parallel + writes of filtered datasets to trigger an assertion failure in the + file free space manager. + + This occurred when the filter used caused chunks to repeatedly shrink + and grow over the course of several dataset writes. The previous chunk + information, such as the size of the chunk and the offset in the file, + was being cached and not updated after each write, causing the next write + to the chunk to retrieve the incorrect cached information and run into + issues when reallocating space in the file for the chunk. + + (JTH - 2018/07/16, HDFFV-10509) + + - A bug was discovered in the parallel library which caused the + H5D__mpio_array_gatherv() function to allocate too much memory. + + When the function is called with the 'allgather' parameter set + to a non-true value, the function will receive data from all MPI + ranks and gather it to the single rank specied by the 'root' + parameter. However, the bug in the function caused memory for + the received data to be allocated on all MPI ranks, not just the + singular rank specified as the receiver. In some circumstances, + this would cause an application to fail due to the large amounts + of memory being allocated. + + (JTH - 2018/07/16, HDFFV-10467) + + - Error checks in h5stat and when decoding messages + + h5stat exited with seg fault/core dumped when + errors are encountered in the internal library. + + Add error checks and --enable-error-stack option to h5stat. + Add range checks when decoding messages: old fill value, old + layout and refcount. + + (VC - 2018/07/11, HDFFV-10333) + + - If an HDF5 file contains a malformed compound datatype with a + suitably large offset, the type conversion code can run off + the end of the type conversion buffer, causing a segmentation + fault. + + This issue was reported to The HDF Group as issue #CVE-2017-17507. + + NOTE: The HDF5 C library cannot produce such a file. This condition + should only occur in a corrupt (or deliberately altered) file + or a file created by third-party software. + + THE HDF GROUP WILL NOT FIX THIS BUG AT THIS TIME + + Fixing this problem would involve updating the publicly visible + H5T_conv_t function pointer typedef and versioning the API calls + which use it. We normally only modify the public API during + major releases, so this bug will not be fixed at this time. + + (DER - 2018/02/26, HDFFV-10356) + + + Configuration + ------------- + - Applied patches to address Cywin build issues + + There were three issues for Cygwin builds: + - Shared libs were not built. + - The -std=c99 flag caused a SIG_SETMASK undeclared error. + - Undefined errors when buildbing test shared libraries. + + Patches to address these issues were received and incorporated in this version. + + (LRK - 2018/07/18, HDFFV-10475) + + - The --enable-debug/production configure flags are listed as 'deprecated' + when they should really be listed as 'removed'. + + In the autotools overhaul several years ago, we removed these flags and + implemented a new --enable-build-mode= flag. This was done because we + changed the semantics of the modes and didn't want users to silently + be exposed to them. The newer system is also more flexible and us to + add other modes (like 'clean'). + + The --enable-debug/production flags are now listed as removed. + + (DER - 2018/05/31, HDFFV-10505) + + - Moved the location of gcc attribute. + + The gcc attribute(no_sanitize), named as the macro HDF_NO_UBSAN, + was located after the function name. Builds with GCC 7 did not + indicate any problem, but GCC 8 issued errors. Moved the + attribute before the function name, as required. + + (ADB - 2018/05/22, HDFFV-10473) + + - Reworked java test suite into individual JUnit tests. + + Testing the whole suite of java unit tests in a single JUnit run + made it difficult to determine actual failures when tests would fail. + Running each file set of tests individually, allows individual failures + to be diagnosed easier. A side benefit is that tests for optional components + of the library can be disabled if not configured. + + (ADB - 2018/05/16, HDFFV-9739) + + - Converted CMake global commands ADD_DEFINITIONS and INCLUDE_DIRECTORIES + to use target_* type commands. This change modernizes the CMake usage + in the HDF5 library. + + In addition, there is the intention to convert to generator expressions, + where possible. The exception is Fortran FLAGS on Windows Visual Studio. + The HDF macros TARGET_C_PROPERTIES and TARGET_FORTRAN_PROPERTIES have + been removed with this change in usage. + + The additional language (C++ and Fortran) checks have also been localized + to only be checked when that language is enabled. + + (ADB - 2018/05/08) + + + Performance + ------------- + - Revamped internal use of DXPLs, improving performance + + (QAK - 2018/05/20) + + + Fortran + -------- + - Fixed issue with h5fget_obj_count_f and using a file id of H5F_OBJ_ALL_F not + returning the correct count. + + (MSB - 2018/5/15, HDFFV-10405) + + + C++ APIs + -------- + - Adding default arguments to existing functions + + Added the following items: + + Two more property list arguments are added to H5Location::createDataSet: + const DSetAccPropList& dapl = DSetAccPropList::DEFAULT + const LinkCreatPropList& lcpl = LinkCreatPropList::DEFAULT + + + One more property list argument is added to H5Location::openDataSet: + const DSetAccPropList& dapl = DSetAccPropList::DEFAULT + + (BMR - 2018/07/21, PR# 1146) + + - Improvement C++ documentation + + Replaced the table in main page of the C++ documentation from mht to htm format + for portability. + + (BMR - 2018/07/17, PR# 1141) + + +Supported Platforms +=================== + + Linux 2.6.32-696.16.1.el6.ppc64 gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + #1 SMP ppc64 GNU/Linux g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + (ostrich) GNU Fortran (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18) + IBM XL C/C++ V13.1 + IBM XL Fortran V15.1 + + Linux 3.10.0-327.10.1.el7 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + (kituo/moohan) Version 4.8.5 20150623 (Red Hat 4.8.5-4) + Version 4.9.3, Version 5.2.0 + Intel(R) C (icc), C++ (icpc), Fortran (icc) + compilers: + Version 17.0.0.098 Build 20160721 + MPICH 3.1.4 compiled with GCC 4.9.3 + + SunOS 5.11 32- and 64-bit Sun C 5.12 SunOS_sparc + (emu) Sun Fortran 95 8.6 SunOS_sparc + Sun C++ 5.12 SunOS_sparc + + Windows 7 Visual Studio 2015 w/ Intel Fortran 16 (cmake) + + Windows 7 x64 Visual Studio 2012 w/ Intel Fortran 15 (cmake) + Visual Studio 2013 w/ Intel Fortran 15 (cmake) + Visual Studio 2015 w/ Intel Fortran 16 (cmake) + Visual Studio 2015 w/ Intel C, Fortran 2017 (cmake) + Visual Studio 2015 w/ MSMPI 8 (cmake) + + Windows 10 Visual Studio 2015 w/ Intel Fortran 18 (cmake) + + Windows 10 x64 Visual Studio 2015 w/ Intel Fortran 18 (cmake) + Visual Studio 2017 w/ Intel Fortran 18 (cmake) + + Mac OS X Yosemite 10.10.5 Apple clang/clang++ version 6.1 from Xcode 7.0 + 64-bit gfortran GNU Fortran (GCC) 4.9.2 + (osx1010dev/osx1010test) Intel icc/icpc/ifort version 15.0.3 + + Mac OS X El Capitan 10.11.6 Apple clang/clang++ version 7.3.0 from Xcode 7.3 + 64-bit gfortran GNU Fortran (GCC) 5.2.0 + (osx1011dev/osx1011test) Intel icc/icpc/ifort version 16.0.2 + + Mac OS Sierra 10.12.6 Apple LLVM version 8.1.0 (clang/clang++-802.0.42) + 64-bit gfortran GNU Fortran (GCC) 7.1.0 + (swallow/kite) Intel icc/icpc/ifort version 17.0.2 + +Tested Configuration Features Summary +===================================== + + In the tables below + y = tested + n = not tested in this release + C = Cluster + W = Workstation + x = not working in this release + dna = does not apply + ( ) = footnote appears below second table + = testing incomplete on this feature or platform + +Platform C F90/ F90 C++ zlib SZIP + parallel F2003 parallel +Solaris2.11 32-bit n y/y n y y y +Solaris2.11 64-bit n y/n n y y y +Windows 7 y y/y n y y y +Windows 7 x64 y y/y y y y y +Windows 7 Cygwin n y/n n y y y +Windows 7 x64 Cygwin n y/n n y y y +Windows 10 y y/y n y y y +Windows 10 x64 y y/y n y y y +Mac OS X Mavericks 10.9.5 64-bit n y/y n y y y +Mac OS X Yosemite 10.10.5 64-bit n y/y n y y y +Mac OS X El Capitan 10.11.6 64-bit n y/y n y y y +Mac OS Sierra 10.12.6 64-bit n y/y n y y y +CentOS 7.2 Linux 2.6.32 x86_64 PGI n y/y n y y y +CentOS 7.2 Linux 2.6.32 x86_64 GNU y y/y y y y y +CentOS 7.2 Linux 2.6.32 x86_64 Intel n y/y n y y y +Linux 2.6.32-573.18.1.el6.ppc64 n y/y n y y y + + +Platform Shared Shared Shared Thread- + C libs F90 libs C++ libs safe +Solaris2.11 32-bit y y y y +Solaris2.11 64-bit y y y y +Windows 7 y y y y +Windows 7 x64 y y y y +Windows 7 Cygwin n n n y +Windows 7 x64 Cygwin n n n y +Windows 10 y y y y +Windows 10 x64 y y y y +Mac OS X Mavericks 10.9.5 64-bit y n y y +Mac OS X Yosemite 10.10.5 64-bit y n y y +Mac OS X El Capitan 10.11.6 64-bit y n y y +Mac OS Sierra 10.12.6 64-bit y n y y +CentOS 7.2 Linux 2.6.32 x86_64 PGI y y y n +CentOS 7.2 Linux 2.6.32 x86_64 GNU y y y y +CentOS 7.2 Linux 2.6.32 x86_64 Intel y y y n +Linux 2.6.32-573.18.1.el6.ppc64 y y y n + +Compiler versions for each platform are listed in the preceding +"Supported Platforms" table. + + +More Tested Platforms +===================== +The following platforms are not supported but have been tested for this release. + + Linux 2.6.32-573.22.1.el6 GNU C (gcc), Fortran (gfortran), C++ (g++) + #1 SMP x86_64 GNU/Linux compilers: + (mayll/platypus) Version 4.4.7 20120313 + Version 4.9.3, 5.3.0, 6.2.0 + PGI C, Fortran, C++ for 64-bit target on + x86-64; + Version 17.10-0 + Intel(R) C (icc), C++ (icpc), Fortran (icc) + compilers: + Version 17.0.4.196 Build 20170411 + MPICH 3.1.4 compiled with GCC 4.9.3 + + Linux 3.10.0-327.18.2.el7 GNU C (gcc) and C++ (g++) compilers + #1 SMP x86_64 GNU/Linux Version 4.8.5 20150623 (Red Hat 4.8.5-4) + (jelly) with NAG Fortran Compiler Release 6.1(Tozai) + GCC Version 7.1.0 + OpenMPI 3.0.0-GCC-7.2.0-2.29, + 3.1.0-GCC-7.2.0-2.29 + Intel(R) C (icc) and C++ (icpc) compilers + Version 17.0.0.098 Build 20160721 + with NAG Fortran Compiler Release 6.1(Tozai) + + Linux 3.10.0-327.10.1.el7 MPICH 3.2 compiled with GCC 5.3.0 + #1 SMP x86_64 GNU/Linux + (moohan) + + Linux 2.6.32-573.18.1.el6.ppc64 MPICH mpich 3.1.4 compiled with + #1 SMP ppc64 GNU/Linux IBM XL C/C++ for Linux, V13.1 + (ostrich) and IBM XL Fortran for Linux, V15.1 + + Debian 8.4 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1 x86_64 GNU/Linux + gcc, g++ (Debian 4.9.2-10) 4.9.2 + GNU Fortran (Debian 4.9.2-10) 4.9.2 + (cmake and autotools) + + Fedora 24 4.7.2-201.fc24.x86_64 #1 SMP x86_64 x86_64 x86_64 GNU/Linux + gcc, g++ (GCC) 6.1.1 20160621 + (Red Hat 6.1.1-3) + GNU Fortran (GCC) 6.1.1 20160621 + (Red Hat 6.1.1-3) + (cmake and autotools) + + Ubuntu 16.04.1 4.4.0-38-generic #57-Ubuntu SMP x86_64 GNU/Linux + gcc, g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) + 5.4.0 20160609 + GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.2) + 5.4.0 20160609 + (cmake and autotools) + + +Known Problems +============== + + At present, metadata cache images may not be generated by parallel + applications. Parallel applications can read files with metadata cache + images, but since this is a collective operation, a deadlock is possible + if one or more processes do not participate. + + Three tests fail with OpenMPI 3.0.0/GCC-7.2.0-2.29: + testphdf5 (ecdsetw, selnone, cchunk1, cchunk3, cchunk4, and actualio) + t_shapesame (sscontig2) + t_pflush1/fails on exit + The first two tests fail attempting collective writes. + + Known problems in previous releases can be found in the HISTORY*.txt files + in the HDF5 source. Please report any new problems found to + help@hdfgroup.org. + + +CMake vs. Autotools installations +================================= +While both build systems produce similar results, there are differences. +Each system produces the same set of folders on linux (only CMake works +on standard Windows); bin, include, lib and share. Autotools places the +COPYING and RELEASE.txt file in the root folder, CMake places them in +the share folder. + +The bin folder contains the tools and the build scripts. Additionally, CMake +creates dynamic versions of the tools with the suffix "-shared". Autotools +installs one set of tools depending on the "--enable-shared" configuration +option. + build scripts + ------------- + Autotools: h5c++, h5cc, h5fc + CMake: h5c++, h5cc, h5hlc++, h5hlcc + +The include folder holds the header files and the fortran mod files. CMake +places the fortran mod files into separate shared and static subfolders, +while Autotools places one set of mod files into the include folder. Because +CMake produces a tools library, the header files for tools will appear in +the include folder. + +The lib folder contains the library files, and CMake adds the pkgconfig +subfolder with the hdf5*.pc files used by the bin/build scripts created by +the CMake build. CMake separates the C interface code from the fortran code by +creating C-stub libraries for each Fortran library. In addition, only CMake +installs the tools library. The names of the szip libraries are different +between the build systems. + +The share folder will have the most differences because CMake builds include +a number of CMake specific files for support of CMake's find_package and support +for the HDF5 Examples CMake project. + + %%%%1.10.2%%%% HDF5 version 1.10.2 released on 2018-03-29 diff --git a/release_docs/README_HDF5_CMake b/release_docs/README_HDF5_CMake new file mode 100644 index 0000000..a2e7dce --- /dev/null +++ b/release_docs/README_HDF5_CMake @@ -0,0 +1,23 @@ +This tar file contains + + build-unix.sh script to build HDF5 with CMake on unix machines + build-unix-hpc.sh script to build HDF5 with CMake on unix machines and run + tests with batch scripts (sbatch). + CTestScript.cmake + HDF5config.cmake CMake scripts for building HDF5 + HDF5options.cmake + hdf5-1.11.4 HDF5 1.11.4 source + SZip.tar.gz source for building SZIP + ZLib.tar.gz source for building ZLIB + +For more information about building HDF5 with CMake, see USING_HDF5_CMake.txt in +hdf5-1.11.4/release_docs, or +https://portal.hdfgroup.org/display/support/Building+HDF5+with+CMake. + +For more information about building HDF5 with CMake on HPC machines, including +cross compiling on Cray XC40, see README_HPC in hdf5-1.11.4/release_docs. + + + + + diff --git a/release_docs/README_HPC b/release_docs/README_HPC index bdeab67..67a5d6c 100644 --- a/release_docs/README_HPC +++ b/release_docs/README_HPC @@ -1,79 +1,206 @@ -HDF5 version 1.11.4 currently under development - -HDF5 source tar files with the HPC prefix are intended for use on clusters where -configuration and build steps will be done on a login node and executable and -lib files that are built will be run on compute nodes. - -Note these differences from the regular CMake tar and zip files: - - Test programs produced by this tar file will be run using batch scripts. - - Serial and parallel HDF5options.cmake files, using parallel options by default. - -Note also that options are now available in HDF5 source to facilitate use of -toolchain files for using cross compilers available on login nodes to compile -HDF5 for compute nodes. - -Instructions to configure build and test HDF5 using CMake: - -1. The cmake version must be 3.10 or later (cmake --version). -2. Load or switch modules and set CC, FC, CXX for compilers desired. -3. run build-unix.sh to configure, build, test and package HDF5 with CMake. - -Contents: - -build-unix.sh Simple script for running CMake to configure, build, - test, and package HDF5. -CTestScript.cmake CMake script to configure, build, test and package - HDF5. -hdf5- HDF5 source for . -HDF5config.cmake CMake script to configure, build, test and package - HDF5. -HDF5Examples Source for HDF5 Examples. -HDF5options.cmake symlink to parallel or serial HDF5options.cmake files. - Default is parallel file, which builds and tests both - serial and parallel C and Fortran wrappers. - To build serial only, C Fortran and C++ wrappers, delete - The HDF5options.cmake link and run - 'ln -s ser-HDF5options.cmake HDF5options.cmake' to switch. -par-HDF5options.cmake Options file for HDF5 serial and parallel build and test. -ser-HDF5options.cmake Options file for HDF5 serial only build and test. -SZip.tar.gz Source for building SZip. -ZLib.tar.gz Source for buildng Zlib. - - -To cross compile with this HPC-CMake tar.gz HDF5 source file: -On Cray XC40 haswell login node for knl compute nodes using CMake and Cray modules: - 1. Uncomment line in HDF5options.txt to use a toolchain file - line 106 for - config/toolchain/crayle.cmake. - 2. Uncomment lines 110, 111, and 115 - 122 of HDF5options.cmake. - Line 110 allows configuring to complete on the haswell node. - Line 111 switches the compiler to build files for knl nodes. - Lines 115 - 122 set up test files to use sbatch to run build tests - in batch jobs on a knl compute node with 6 processes. - 3. Compiler module may be the default PrgEnv-intel/6.0.4 to use - intel/18.0.2 or other intel, PrgEnv-cray/6.0.4 to use cce/8.7.4, - or PrgEnv-gnu/6.0.4 for GCC compilers. PrgEnv-pgi/6.0.4 is also - available but has not been tested with this tar file. - 4. These CMake options are set in config/toolchain/crayle.cmake: - set(CMAKE_SYSTEM_NAME Linux) - set(CMAKE_COMPILER_VENDOR "CrayLinuxEnvironment") - set(CMAKE_C_COMPILER cc) - set(CMAKE_CXX_COMPILER c++) - set(CMAKE_Fortran_COMPILER ftn) - set(CMAKE_CROSSCOMPILING_EMULATOR "") - - 5. Settings for two other cross-compiling options are also in the - config/toolchain files which do not seem to be necessary with the - Cray PrgEnv-* modules - a. HDF5_USE_PREGEN. This option, along with the HDF5_USE_PREGEN_DIR - CMake variable would allow the use of an appropriate H5Tinit.c - file with type information generated on a compute node to be used - when cross compiling for those compute nodes. The use of the - variables in lines 110 and 111 of HDF5options.cmake file seem to - preclude needing this option with the available Cray modules and - CMake options. - b. HDF5_BATCH_H5DETECT and associated CMake variables. This option - when properly configured will run H5detect in a batch job on a - compute node at the beginning of the CMake build process. It - was also found to be unnecessary with the available Cray modules - and CMake options. -- +************************************************************************ +* Using CMake to build and test HDF5 source on HPC machines * +************************************************************************ + + Contents + +Section I: Prerequisites +Section II: Obtain HDF5 source +Section III: Using ctest command to build and test +Section IV: Cross compiling +Section V: Manual alternatives +Section VI: Other cross compiling options + +************************************************************************ + +======================================================================== +I. Prerequisites +======================================================================== + 1. Create a working directory that is accessible from the compute nodes for + running tests; the working directory should be in a scratch space or a + parallel file system space since testing will use this space. Building + from HDF5 source in a 'home' directory typically results in test + failures and should be avoided. + + 2. Load modules for desired compilers, module for cmake version 3.10 or greater, + and set any needed environment variables for compilers (i.e., CC, FC, CXX). + Unload any problematic modules (i.e., craype-hugepages2M). + +======================================================================== +II. Obtain HDF5 source +======================================================================== +Obtain HDF5 source code from the HDF5 repository using a git command or +from a release tar file in a working directory: + + git clone https://git@bitbucket.hdfgroup.org/scm/hdffv/hdf5.git + [-b branch] [source directory] + +If no branch is specified, then the 'develop' version will be checked out. +If no source directory is specified, then the source will be located in the +'hdf5' directory. The Cmake scripts expect the source to be in a directory +named hdf5-, where 'version string' uses the format '1.xx.xx'. +For example, for the current 'develop' version, the "hdf5" directory should +be renamed "hdf5-1.11.4", or for the first hdf5_1_10_5 pre-release version, +it should be renamed "hdf5-1.10.5-pre1". + +If the version number is not known a priori, the version string +can be obtained by running bin/h5vers in the top level directory of the source clone, and +the source directory renamed 'hdf5-'. + +Release or snapshot tar files may also be extracted and used. + +======================================================================== +III. Using ctest command to build and test +======================================================================== + +The ctest command [1]: + + ctest -S HDF5config.cmake,BUILD_GENERATOR=Unix -C Release -V -O hdf5.log + +will configure, build, test and package HDF5 from the downloaded source +after the setup steps outlined below are followed. + +CMake option variables are available to allow running test programs in batch +scripts on compute nodes and to cross-compile for compute node hardware using +a cross-compiling emulator. The setup steps will make default settings for +parallel or serial only builds available to the CMake command. + + 1. For the current 'develop' version the "hdf5" directory should be renamed + "hdf5-1.11.4". + + 2. Three cmake script files need to be copied to the working directory, or + have symbolic links to them, created in the working directory: + + hdf5-1.11.4/config/cmake/scripts/HDF5config.cmake + hdf5-1.11.4/config/cmake/scripts/CTestScript.cmake + hdf5-1.11.4/config/cmake/scripts/HDF5options.cmake + + should be copied to the working directory. + + 3. The resulting contents of the working directory are then: + + CTestScript.cmake + HDF5config.cmake + HDF5options.cmake + hdf5-1.11.4 + + Additionally, when the ctest command runs [1], it will add a build directory + in the working directory. + + 4. The following options (among others) can be added to the ctest + command [1], following '-S HDF5config.cmake,' and separated by ',': + + HPC=sbatch (or 'bsub' or 'raybsub') indicates which type of batch + files to use for running tests. If omitted, test + will run on the local machine or login node. + + KNL=true to cross-compile for KNL compute nodes on CrayXC40 + (see section IV) + + MPI=true enables parallel, disables c++, java, and threadsafe + + LOCAL_BATCH_SCRIPT_ARGS="--account=" to supply user account + information for batch jobs + + The HPC options will add BUILD_GENERATOR=Unix for the three HPC options. + An example ctest command for a parallel build on a system using sbatch is + + ctest -S HDF5config.cmake,HPC=sbatch,MPI=true -C Release -V -O hdf5.log + + Adding the option 'KNL=true' to the above list will compile for KNL nodes, + for example, on 'mutrino' and other CrayXC40 machines. + + Changing -V to -VV will produce more logging information in HDF5.log. + + More detailed CMake information can be found in the HDF5 source in + release_docs/INSTALL_CMake.txt. + +======================================================================== +IV. Cross-compiling +======================================================================== +For cross-compiling on Cray, set environment variables CC=cc, FC=ftn +and CXX=CC (for c++) after all compiler modules are loaded since switching +compiler modules may unset or reset these variables. + +CMake provides options for cross-compiling. To cross-compile for KNL hardware +on mutrino and other CrayXC40 machines, add HPC=sbatch,KNL=true to the +ctest command line. This will set the following options from the +config/cmake/scripts/HPC/sbatch-HDF5options.cmake file: + + set (COMPILENODE_HWCOMPILE_MODULE "craype-haswell") + set (COMPUTENODE_HWCOMPILE_MODULE "craype-mic-knl") + set (LOCAL_BATCH_SCRIPT_NAME "knl_ctestS.sl") + set (LOCAL_BATCH_SCRIPT_PARALLEL_NAME "knl_ctestP.sl") + set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DCMAKE_TOOLCHAIN_FILE:STRING=config/toolchain/crayle.cmake") + +On the Cray XC40 the craype-haswell module is needed for configuring, and the +craype-mic-knl module is needed for building to run on the KNL nodes. CMake +with the above options will swap modules after configuring is complete, +but before compiling programs for KNL. + +The sbatch script arguments for running jobs on KNL nodes may differ on CrayXC40 +machines other than mutrino. The batch scripts knl_ctestS.sl and knl_ctestP.sl +have the correct arguments for mutrino: "#SBATCH -p knl -C quad,cache". For +cori, another CrayXC40, that line is replaced by "#SBATCH -C knl,quad,cache". +For cori (and other machines), the values in LOCAL_BATCH_SCRIPT_NAME and +LOCAL_BATCH_SCRIPT_PARALLEL_NAME in the config/cmake/scripts/HPC/sbatch-HDF5options.cmake +file can be replaced by cori_knl_ctestS.sl and cori_knl_ctestS.sl, or the lines +can be edited in the batch files in hdf5-1.11.4/bin/batch. + +======================================================================== +V. Manual alternatives +======================================================================== +If using ctest is undesirable, one can create a build directory and run the cmake +configure command, for example + +"/projects/Mutrino/hpcsoft/cle6.0/common/cmake/3.10.2/bin/cmake" +-C "/hdf5-1.11.4/config/cmake/cacheinit.cmake" +-DCMAKE_BUILD_TYPE:STRING=Release -DHDF5_BUILD_FORTRAN:BOOL=ON +-DHDF5_BUILD_JAVA:BOOL=OFF +-DCMAKE_INSTALL_PREFIX:PATH=/HDF_Group/HDF5/1.11.4 +-DHDF5_ENABLE_Z_LIB_SUPPORT:BOOL=OFF -DHDF5_ENABLE_SZIP_SUPPORT:BOOL=OFF +-DHDF5_ENABLE_PARALLEL:BOOL=ON -DHDF5_BUILD_CPP_LIB:BOOL=OFF +-DHDF5_BUILD_JAVA:BOOL=OFF -DHDF5_ENABLE_THREADSAFE:BOOL=OFF +-DHDF5_PACKAGE_EXTLIBS:BOOL=ON -DLOCAL_BATCH_TEST:BOOL=ON +-DMPIEXEC_EXECUTABLE:STRING=srun -DMPIEXEC_NUMPROC_FLAG:STRING=-n +-DMPIEXEC_MAX_NUMPROCS:STRING=6 +-DCMAKE_TOOLCHAIN_FILE:STRING=config/toolchain/crayle.cmake +-DLOCAL_BATCH_SCRIPT_NAME:STRING=knl_ctestS.sl +-DLOCAL_BATCH_SCRIPT_PARALLEL_NAME:STRING=knl_ctestP.sl -DSITE:STRING=mutrino +-DBUILDNAME:STRING=par-knl_GCC493-SHARED-Linux-4.4.156-94.61.1.16335.0.PTF.1107299-default-x86_64 +"-GUnix Makefiles" "" "/hdf5-1.11.4" + +followed by make and batch jobs to run tests. + +To cross-compile on CrayXC40, run the configure command with the craype-haswell +module loaded, then switch to the craype-mic-knl module for the build process. + +Tests on machines using slurm can be run with + +"sbatch -p knl -C quad,cache ctestS.sl" + +or + +"sbatch -p knl -C quad,cache ctestP.sl" + +for parallel builds. + +Tests on machines using LSF will typically use "bsub ctestS.lsf", etc. + +======================================================================== +VI. Other cross compiling options +======================================================================== +Settings for two other cross-compiling options are also in the config/toolchain +files which do not seem to be necessary with the Cray PrgEnv-* modules + +1. HDF5_USE_PREGEN. This option, along with the HDF5_USE_PREGEN_DIR CMake + variable would allow the use of an appropriate H5Tinit.c file with type + information generated on a compute node to be used when cross compiling + for those compute nodes. The use of the variables in lines 110 and 111 + of HDF5options.cmake file seem to preclude needing this option with the + available Cray modules and CMake option. + +2. HDF5_BATCH_H5DETECT and associated CMake variables. This option when + properly configured will run H5detect in a batch job on a compute node + at the beginning of the CMake build process. It was also found to be + unnecessary with the available Cray modules and CMake options. -- cgit v0.12 From 33db9f56449c974fed6b4a8a19072546bcd31e15 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 5 Mar 2019 17:33:13 -0600 Subject: Fix typo. --- src/H5CX.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5CX.c b/src/H5CX.c index cfcdfd4..c97bdcd 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -501,7 +501,7 @@ H5CX__init_package(void) /* Get the default DCPL cache information */ - /* Get the default link access property list */ + /* Get the default dataset creation property list */ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_CREATE_DEFAULT))) HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list") -- cgit v0.12 From faec33960f48e070afd6a7d74630cda3029cb46f Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Wed, 6 Mar 2019 16:57:42 -0600 Subject: Fix issue with direct chunk write not updating the "last chunk" index cache. Fix issues involving datasets being "no allocated" when they contain cached raw data. --- release_docs/RELEASE.txt | 12 +++++ src/H5Dchunk.c | 40 ++++++++++++++-- src/H5Dcompact.c | 1 + src/H5Dcontig.c | 25 ++++++++++ src/H5Defl.c | 1 + src/H5Dint.c | 3 +- src/H5Dio.c | 4 +- src/H5Dpkg.h | 9 +++- src/H5Dvirtual.c | 50 ++++++++++++++++++++ src/H5Olayout.c | 6 ++- test/direct_chunk.c | 121 +++++++++++++++++++++++++++++++++++++++-------- 11 files changed, 243 insertions(+), 29 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 879c3f3..3ba00f0 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -224,6 +224,18 @@ Bug Fixes since HDF5-1.10.3 release Library ------- + - Fixed a bug that would cause an error or cause fill values to be + incorrectly read from a chunked dataset using the "single chunk" index if + the data was held in cache and there was no data on disk. + + (NAF - 2019/03/06) + + - Fixed a bug that could cause an error or cause fill values to be + incorrectly read from a dataset that was written to using H5Dwrite_chunk + if the dataset was not closed after writing. + + (NAF - 2019/03/06, HDFFV-10716) + - Fix hangs with collective metadata reads during chunked dataset I/O In the parallel library, it was discovered that when a particular diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index dcd3a8d..27a6125 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -313,6 +313,7 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{ H5D__chunk_construct, H5D__chunk_init, H5D__chunk_is_space_alloc, + H5D__chunk_is_data_cached, H5D__chunk_io_init, H5D__chunk_read, H5D__chunk_write, @@ -340,6 +341,7 @@ const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{ NULL, NULL, NULL, + NULL, #ifdef H5_HAVE_PARALLEL NULL, NULL, @@ -394,10 +396,13 @@ H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) + /* Sanity checks */ + HDassert(layout->type == H5D_CHUNKED); + io_info.dset = dset; /* Allocate dataspace and initialize it if it hasn't been. */ - if(!(*layout->ops->is_space_alloc)(&layout->storage)) + if(!H5D__chunk_is_space_alloc(&layout->storage)) /* Allocate storage */ if(H5D__alloc_storage(&io_info, H5D_ALLOC_WRITE, FALSE, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") @@ -435,13 +440,17 @@ H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, if(0 == idx_info.pline->nused && H5F_addr_defined(old_chunk.offset)) /* If there are no filters and we are overwriting the chunk we can just set values */ need_insert = FALSE; - else + else { /* Otherwise, create the chunk it if it doesn't exist, or reallocate the chunk * if its size has changed. */ if(H5D__chunk_file_alloc(&idx_info, &old_chunk, &udata.chunk_block, &need_insert, scaled) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk") + /* Cache the new chunk information */ + H5D__chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, &udata); + } /* end else */ + /* Make sure the address of the chunk is returned. */ if(!H5F_addr_defined(udata.chunk_block.offset)) HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk address isn't defined") @@ -506,7 +515,8 @@ H5D__chunk_direct_read(const H5D_t *dset, hsize_t *offset, uint32_t* filters, *filters = 0; /* Allocate dataspace and initialize it if it hasn't been. */ - if(!(*layout->ops->is_space_alloc)(&layout->storage)) + if(!H5D__chunk_is_space_alloc(&layout->storage) + && !H5D__chunk_is_data_cached(dset->shared)) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "storage is not initialized") /* Calculate the index of this chunk */ @@ -1019,6 +1029,30 @@ H5D__chunk_is_space_alloc(const H5O_storage_t *storage) /*------------------------------------------------------------------------- + * Function: H5D__chunk_is_data_cached + * + * Purpose: Query if raw data is cached for dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Wednessday, March 6, 2016 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(shared_dset); + + FUNC_LEAVE_NOAPI(shared_dset->cache.chunk.nused > 0) +} /* end H5D__chunk_is_data_cached() */ + + +/*------------------------------------------------------------------------- * Function: H5D__chunk_io_init * * Purpose: Performs initialization before any sort of I/O on the raw data diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index c0c2a80..651aaf4 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -80,6 +80,7 @@ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{ H5D__compact_construct, NULL, H5D__compact_is_space_alloc, + NULL, H5D__compact_io_init, H5D__contig_read, H5D__contig_write, diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index ad12ba0..c2e9bfc 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -118,6 +118,7 @@ const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{ H5D__contig_construct, H5D__contig_init, H5D__contig_is_space_alloc, + H5D__contig_is_data_cached, H5D__contig_io_init, H5D__contig_read, H5D__contig_write, @@ -538,6 +539,30 @@ H5D__contig_is_space_alloc(const H5O_storage_t *storage) /*------------------------------------------------------------------------- + * Function: H5D__contig_is_data_cached + * + * Purpose: Query if raw data is cached for dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Wednessday, March 6, 2016 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5D__contig_is_data_cached(const H5D_shared_t *shared_dset) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(shared_dset); + + FUNC_LEAVE_NOAPI(shared_dset->cache.contig.sieve_size > 0) +} /* end H5D__contig_is_data_cached() */ + + +/*------------------------------------------------------------------------- * Function: H5D__contig_io_init * * Purpose: Performs initialization before any sort of I/O on the raw data diff --git a/src/H5Defl.c b/src/H5Defl.c index b2f9b29..42b3947 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -91,6 +91,7 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{ H5D__efl_construct, NULL, H5D__efl_is_space_alloc, + NULL, H5D__efl_io_init, H5D__contig_read, H5D__contig_write, diff --git a/src/H5Dint.c b/src/H5Dint.c index 384c66b..874e845 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2898,7 +2898,8 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size) *------------------------------------------------------------------------- */ if(H5D_CHUNKED == dset->shared->layout.type) { - if(shrink && (*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) + if(shrink && ((*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage) + || (dset->shared->layout.ops->is_data_cached && (*dset->shared->layout.ops->is_data_cached)(dset->shared)))) /* Remove excess chunks */ if(H5D__chunk_prune_by_extent(dset, curr_dims) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to remove chunks") diff --git a/src/H5Dio.c b/src/H5Dio.c index 2f87e38..9343b80 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -518,7 +518,8 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, * has been overwritten. So just proceed in reading. */ if(nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 && - !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) { + !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) && + !(dataset->shared->layout.ops->is_data_cached && (*dataset->shared->layout.ops->is_data_cached)(dataset->shared))) { H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */ /* Retrieve dataset's fill-value properties */ @@ -550,6 +551,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, /* Sanity check that space is allocated, if there are elements */ if(nelmts > 0) HDassert((*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) + || (dataset->shared->layout.ops->is_data_cached && (*dataset->shared->layout.ops->is_data_cached)(dataset->shared)) || dataset->shared->dcpl_cache.efl.nused > 0 || dataset->shared->layout.type == H5D_COMPACT); diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 2767aa1..e7c623b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -113,12 +113,14 @@ typedef struct H5D_type_info_t { /* Forward declaration of structs used below */ struct H5D_io_info_t; struct H5D_chunk_map_t; +typedef struct H5D_shared_t H5D_shared_t; /* Function pointers for I/O on particular types of dataset layouts */ typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset); typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, const H5D_t *dset, hid_t dapl_id); typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage); +typedef hbool_t (*H5D_layout_is_data_cached_func_t)(const H5D_shared_t *shared_dset); typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, @@ -144,6 +146,7 @@ typedef struct H5D_layout_ops_t { H5D_layout_construct_func_t construct; /* Layout constructor for new datasets */ H5D_layout_init_func_t init; /* Layout initializer for dataset */ H5D_layout_is_space_alloc_func_t is_space_alloc; /* Query routine to determine if storage is allocated */ + H5D_layout_is_data_cached_func_t is_data_cached; /* Query routine to determine if any raw data is cached. If routine is not present then the layout type never caches raw data. */ H5D_layout_io_init_func_t io_init; /* I/O initialization routine */ H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */ H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */ @@ -429,7 +432,7 @@ typedef struct H5D_rdcdc_t { * created once for a given dataset. Thus, if a dataset is opened twice, * there will be two IDs and two H5D_t structs, both sharing one H5D_shared_t. */ -typedef struct H5D_shared_t { +struct H5D_shared_t { size_t fo_count; /* Reference count */ hbool_t closing; /* Flag to indicate dataset is closing */ hid_t type_id; /* ID for dataset's datatype */ @@ -459,7 +462,7 @@ typedef struct H5D_shared_t { H5D_append_flush_t append_flush; /* Append flush property information */ char *extfile_prefix; /* expanded external file prefix */ char *vds_prefix; /* expanded vds prefix */ -} H5D_shared_t; +}; struct H5D_t { H5O_loc_t oloc; /* Object header location */ @@ -618,6 +621,7 @@ H5_DLL herr_t H5D__layout_oh_write(const H5D_t *dataset, H5O_t *oh, unsigned upd /* Functions that operate on contiguous storage */ H5_DLL herr_t H5D__contig_alloc(H5F_t *f, H5O_storage_contig_t *storage); H5_DLL hbool_t H5D__contig_is_space_alloc(const H5O_storage_t *storage); +H5_DLL hbool_t H5D__contig_is_data_cached(const H5D_shared_t *shared_dset); H5_DLL herr_t H5D__contig_fill(const H5D_io_info_t *io_info); H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, @@ -636,6 +640,7 @@ H5_DLL htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, H5_DLL herr_t H5D__chunk_create(const H5D_t *dset /*in,out*/); H5_DLL herr_t H5D__chunk_set_info(const H5D_t *dset); H5_DLL hbool_t H5D__chunk_is_space_alloc(const H5O_storage_t *storage); +H5_DLL hbool_t H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset); H5_DLL herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata); H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes); diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index c0d49d8..a803cca 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -78,6 +78,7 @@ /********************/ /* Layout operation callbacks */ +static hbool_t H5D__virtual_is_data_cached(const H5D_shared_t *shared_dset); static herr_t H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *fm); @@ -121,6 +122,7 @@ const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{ NULL, H5D__virtual_init, H5D__virtual_is_space_alloc, + H5D__virtual_is_data_cached, NULL, H5D__virtual_read, H5D__virtual_write, @@ -2207,6 +2209,54 @@ H5D__virtual_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage) /*------------------------------------------------------------------------- + * Function: H5D__virtual_is_data_cached + * + * Purpose: Query if raw data is cached for dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Wednessday, March 6, 2016 + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5D__virtual_is_data_cached(const H5D_shared_t *shared_dset) +{ + const H5O_storage_virtual_t *storage; /* Convenience pointer */ + size_t i, j; /* Local index variables */ + hbool_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(shared_dset); + storage = &shared_dset->layout.storage.u.virt; + + /* Iterate over mappings */ + for(i = 0; i < storage->list_nused; i++) + /* Check for "printf" source dataset resolution */ + if(storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) { + /* Iterate over sub-source dsets */ + for(j = storage->list[i].sub_dset_io_start; j < storage->list[i].sub_dset_io_end; j++) + /* Check for cahced data in source dset */ + if(storage->list[i].sub_dset[j].dset + && storage->list[i].sub_dset[j].dset->shared->layout.ops->is_data_cached + && storage->list[i].sub_dset[j].dset->shared->layout.ops->is_data_cached(storage->list[i].sub_dset[j].dset->shared)) + HGOTO_DONE(TRUE); + } /* end if */ + else + if(storage->list[i].source_dset.dset + && storage->list[i].source_dset.dset->shared->layout.ops->is_data_cached + && storage->list[i].source_dset.dset->shared->layout.ops->is_data_cached(storage->list[i].source_dset.dset->shared)) + HGOTO_DONE(TRUE); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__virtual_is_data_cached() */ + + +/*------------------------------------------------------------------------- * Function: H5D__virtual_pre_io * * Purpose: Project all virtual mappings onto mem_space, with the diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 2b65e0c..86f4c46 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -1039,7 +1039,8 @@ H5O__layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, layout_dst->storage.u.contig.size = H5S_extent_nelem(udata->src_space_extent) * H5T_get_size(udata->src_dtype); - if(H5D__contig_is_space_alloc(&layout_src->storage)) { + if(H5D__contig_is_space_alloc(&layout_src->storage) + || (cpy_info->shared_fo && H5D__contig_is_data_cached((const H5D_shared_t *)cpy_info->shared_fo))) { /* copy contiguous raw data */ if(H5D__contig_copy(file_src, &layout_src->storage.u.contig, file_dst, &layout_dst->storage.u.contig, udata->src_dtype, cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy contiguous storage") @@ -1048,7 +1049,8 @@ H5O__layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, break; case H5D_CHUNKED: - if(H5D__chunk_is_space_alloc(&layout_src->storage)) { + if(H5D__chunk_is_space_alloc(&layout_src->storage) + || (cpy_info->shared_fo && H5D__chunk_is_data_cached((const H5D_shared_t *)cpy_info->shared_fo))) { /* Create chunked layout */ if(H5D__chunk_copy(file_src, &layout_src->storage.u.chunk, &layout_src->u.chunk, file_dst, &layout_dst->storage.u.chunk, udata->src_space_extent, udata->src_dtype, udata->common.src_pline, cpy_info) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy chunked storage") diff --git a/test/direct_chunk.c b/test/direct_chunk.c index 2edfe64..8de923e 100644 --- a/test/direct_chunk.c +++ b/test/direct_chunk.c @@ -58,6 +58,14 @@ #define OVERWRITE_CHUNK_NY 2 #define OVERWRITE_VALUE 42 +/* Test configurations */ +#define CONFIG_LATEST 0x01 +#define CONFIG_REOPEN_FILE 0x02 +#define CONFIG_REOPEN_DSET 0x04 +#define CONFIG_DIRECT_WRITE 0x08 +#define CONFIG_DIRECT_READ 0x10 +#define CONFIG_END 0x20 + /* Defines used in test_single_chunk_latest() */ #define FILE "single_latest.h5" #define DATASET "dataset" @@ -1973,7 +1981,7 @@ error: } /* test_read_unallocated_chunk() */ /*------------------------------------------------------------------------- - * Function: test_single_chunk_latest + * Function: test_single_chunk * * Purpose: This is to verify the fix for jira issue HDFFV-10425. * The problem was due to a bug in the internal ilbrary routine @@ -1989,13 +1997,16 @@ error: * index for the dataset. * Verify that the data read is the same as the written data. * + * Since expanded to test multiple combinations of cases + * involving a single chunk + * * Return: Success: 0 * Failure: 1 * *------------------------------------------------------------------------- */ static int -test_single_chunk_latest(void) +test_single_chunk(unsigned config) { hid_t fid; /* File ID */ hid_t fapl; /* File access property list ID */ @@ -2005,11 +2016,12 @@ test_single_chunk_latest(void) hsize_t dims[2] = {DIM0, DIM1}; /* Dimension sizes */ hsize_t chunk[2] = {CHUNK0, CHUNK1}; /* Chunk dimension sizes */ hsize_t offset[2] = {0,0}; /* Offset for writing */ + uint32_t filters; /* Filter mask out */ int wdata[DIM0][DIM1]; /* Write buffer */ int rdata[DIM0][DIM1]; /* Read buffer */ int i, j; /* Local index variable */ - TESTING("H5Dwrite_chunk with single chunk and latest format"); + TESTING("Single chunk I/O"); /* Initialize data */ for (i=0; i"); + if(config & CONFIG_LATEST) { + if(need_comma) + printf(", "); + printf("latest format"); + need_comma = TRUE; + } /* end if */ + if(config & CONFIG_REOPEN_FILE) { + if(need_comma) + printf(", "); + printf("reopen file"); + need_comma = TRUE; + } /* end if */ + else if(config & CONFIG_REOPEN_DSET) { + if(need_comma) + printf(", "); + printf("reopen dataset"); + need_comma = TRUE; + } /* end if */ + if(config & CONFIG_DIRECT_WRITE) { + if(need_comma) + printf(", "); + printf("direct write"); + need_comma = TRUE; + } /* end if */ + if(config & CONFIG_DIRECT_READ) { + if(need_comma) + printf(", "); + printf("direct read"); + need_comma = TRUE; + } /* end if */ + printf(":\n"); + fflush(stdout); + + nerrors += test_single_chunk(config); + } /* end for */ if(H5Fclose(file_id) < 0) goto error; @@ -2165,3 +2245,4 @@ error: HDputs("*** TESTS FAILED ***"); return EXIT_FAILURE; } + -- cgit v0.12 From fc3f606d5c30d614b7e6cddaf4d0dafd80987bec Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Thu, 7 Mar 2019 14:38:11 -0800 Subject: Fixed the MANIFEST --- MANIFEST | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST b/MANIFEST index 6c2018a..7cb2cfd 100644 --- a/MANIFEST +++ b/MANIFEST @@ -461,8 +461,9 @@ ./release_docs/INSTALL_parallel ./release_docs/INSTALL_Warnings.txt ./release_docs/INSTALL_Windows.txt -./release_docs/RELEASE.txt +./release_docs/README_HDF5_CMake ./release_docs/README_HPC +./release_docs/RELEASE.txt ./release_docs/USING_HDF5_CMake.txt ./release_docs/USING_HDF5_VS.txt -- cgit v0.12 From 5f22afff3a05a2c8fc694ddb0c7e1081a660b398 Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Fri, 8 Mar 2019 13:51:27 -0600 Subject: Added a note of bug fix for HDFFV-10705. --- release_docs/RELEASE.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 879c3f3..aed539b 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -224,6 +224,16 @@ Bug Fixes since HDF5-1.10.3 release Library ------- + - Fixed memory leak in scale offset filter + + In a special case where the MinBits is the same as the number of bits in + the datatype's precision, the filter's data buffer was not freed, causing + the memory usage to grow. In general the buffer was freed correctly. The + Minbits are the minimal number of bits to store the data values. Please + see the reference manual for H5Pset_scaleoffset for the detail. + + (RL - 2019/3/4, HDFFV-10705) + - Fix hangs with collective metadata reads during chunked dataset I/O In the parallel library, it was discovered that when a particular -- cgit v0.12 From deeb302747fe186d18bbf3e47d750ce6e47aef62 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 9 Mar 2019 21:41:38 -0600 Subject: Specify the default VOL connector to use with an environment variable. This implicitly adds support for changing the VOL connector for command-line tools or any application linked with the library. Also, add 'make check-vol' support for all directories, clearing up necessary issues in testing scripts, etc. --- Makefile.am | 3 +- c++/Makefile.am | 6 + fortran/Makefile.am | 6 + hl/Makefile.am | 6 + java/Makefile.am | 5 + src/H5.c | 6 +- src/H5Dcontig.c | 20 -- src/H5Fint.c | 13 +- src/H5Pfapl.c | 37 +++ src/H5Pint.c | 110 +++++++ src/H5Ppkg.h | 4 + src/H5Pprivate.h | 3 + src/H5VL.c | 200 ++---------- src/H5VLcallback.c | 45 +-- src/H5VLint.c | 629 ++++++++++++++++++++++++++++++++++--- src/H5VLpassthru.c | 36 ++- src/H5VLpkg.h | 15 + src/H5VLprivate.h | 8 +- test/cache_tagging.c | 52 +-- test/h5test.c | 118 ------- test/h5test.h | 4 +- test/objcopy.c | 2 +- test/testerror.sh.in | 4 +- test/titerate.c | 4 +- test/ttsafe_error.c | 65 ++-- testpar/Makefile.am | 5 + testpar/t_cache.c | 1 + tools/Makefile.am | 5 + tools/test/h5dump/testh5dump.sh.in | 6 +- tools/test/h5repack/h5repack.sh.in | 8 +- 30 files changed, 959 insertions(+), 467 deletions(-) diff --git a/Makefile.am b/Makefile.am index d58b1b4..b48bb30 100644 --- a/Makefile.am +++ b/Makefile.am @@ -187,9 +187,8 @@ check-vfd: done # Run tests with different Virtual Object Layer Connectors. -# Currently, only invoke check-vol in the test directory. check-vol: - for d in src test; do \ + for d in $(SUBDIRS); do \ if test $$d != .; then \ (cd $$d && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; \ fi; \ diff --git a/c++/Makefile.am b/c++/Makefile.am index 94fbefc..3713901 100644 --- a/c++/Makefile.am +++ b/c++/Makefile.am @@ -21,6 +21,12 @@ include $(top_srcdir)/config/commence.am ## Only recurse into subdirectories if C++ interface is enabled. if BUILD_CXX_CONDITIONAL SUBDIRS=src test + +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + endif DIST_SUBDIRS = src test examples diff --git a/fortran/Makefile.am b/fortran/Makefile.am index 38084b9..ca0733f 100644 --- a/fortran/Makefile.am +++ b/fortran/Makefile.am @@ -30,6 +30,12 @@ endif ## Only recurse into subdirectories if HDF5 is configured to use Fortran. if BUILD_FORTRAN_CONDITIONAL SUBDIRS=src test $(TESTPARALLEL_DIR) + +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + endif # All directories that have Makefiles diff --git a/hl/Makefile.am b/hl/Makefile.am index aee1f86..172d0e8 100644 --- a/hl/Makefile.am +++ b/hl/Makefile.am @@ -36,6 +36,12 @@ endif ## use the HL library if BUILD_HDF5_HL_CONDITIONAL SUBDIRS=src test tools $(CXX_DIR) $(FORTRAN_DIR) + +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + endif DIST_SUBDIRS=src test tools c++ fortran examples diff --git a/java/Makefile.am b/java/Makefile.am index 7d0e2f0..ed2414d 100644 --- a/java/Makefile.am +++ b/java/Makefile.am @@ -31,6 +31,11 @@ JAVA_API=yes SUBDIRS=src test examples +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + endif include $(top_srcdir)/config/conclude.am diff --git a/src/H5.c b/src/H5.c index bf4643c..104c9fd 100644 --- a/src/H5.c +++ b/src/H5.c @@ -214,7 +214,7 @@ H5_init_library(void) */ if(H5E_init() < 0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface") - if(H5VL_init() < 0) + if(H5VL_init_phase1() < 0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface") if(H5P_init() < 0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface") @@ -229,6 +229,10 @@ H5_init_library(void) if(H5FS_init() < 0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize FS interface") + /* Finish initializing interfaces that depend on the interfaces above */ + if(H5VL_init_phase2() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface") + /* Debugging? */ H5_debug_mask("-all"); H5_debug_mask(HDgetenv("HDF5_DEBUG")); diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index ad12ba0..8bd5e31 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -755,11 +755,6 @@ H5D__contig_readvv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, /* Reset sieve buffer dirty flag */ dset_contig->sieve_dirty = FALSE; - - /* Stash local copies of these value */ - sieve_start = dset_contig->sieve_loc; - sieve_size = dset_contig->sieve_size; - sieve_end = sieve_start+sieve_size; } /* end else */ } /* end if */ else { @@ -825,11 +820,6 @@ H5D__contig_readvv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, min = MIN3(rel_eoa - dset_contig->sieve_loc, max_data, dset_contig->sieve_buf_size); H5_CHECKED_ASSIGN(dset_contig->sieve_size, size_t, min, hsize_t); - /* Update local copies of sieve information */ - sieve_start = dset_contig->sieve_loc; - sieve_size = dset_contig->sieve_size; - sieve_end = sieve_start + sieve_size; - /* Read the new sieve buffer */ if(H5F_block_read(file, H5FD_MEM_DRAW, dset_contig->sieve_loc, dset_contig->sieve_size, dset_contig->sieve_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "block read failed") @@ -1110,11 +1100,6 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, /* Adjust sieve size */ dset_contig->sieve_size += len; - - /* Update local copies of sieve information */ - sieve_start = dset_contig->sieve_loc; - sieve_size = dset_contig->sieve_size; - sieve_end = sieve_start + sieve_size; } /* end if */ /* Can't add the new data onto the existing sieve buffer */ else { @@ -1146,11 +1131,6 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, min = MIN3(rel_eoa - dset_contig->sieve_loc, max_data, dset_contig->sieve_buf_size); H5_CHECKED_ASSIGN(dset_contig->sieve_size, size_t, min, hsize_t); - /* Update local copies of sieve information */ - sieve_start = dset_contig->sieve_loc; - sieve_size = dset_contig->sieve_size; - sieve_end = sieve_start + sieve_size; - /* Check if there is any point in reading the data from the file */ if(dset_contig->sieve_size > len) { /* Read the new sieve buffer */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 8a7019d..339c61b 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1362,19 +1362,10 @@ H5F__dest(H5F_t *f, hbool_t flush) HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list") /* Clean up the cached VOL connector ID & info */ - if(f->shared->vol_info) { - H5VL_class_t *connector; /* Pointer to connector */ - - /* Retrieve the connector for the ID */ - if(NULL == (connector = (H5VL_class_t *)H5I_object(f->shared->vol_id))) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a VOL connector ID") - - /* Free the connector info */ - if(H5VL_free_connector_info(connector, f->shared->vol_info) < 0) + if(f->shared->vol_info) + if(H5VL_free_connector_info(f->shared->vol_id, f->shared->vol_info) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to release VOL connector info object") - } /* end if */ if(f->shared->vol_id > 0) if(H5I_dec_ref(f->shared->vol_id) < 0) /* Push error, but keep going*/ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index bfb52ff..4b9bbdc 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -4907,6 +4907,43 @@ done: /*------------------------------------------------------------------------- + * Function: H5P_reset_vol_class + * + * Purpose: Change the VOL connector for a file access property class. + * + * Note: The VOL property will be copied into the property list and + * the reference count on the previous VOL will _NOT_ be decremented. + * The reference count on the new VOL will _NOT_ be incremented. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * March 8, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_reset_vol_class(const H5P_genclass_t *pclass, const H5VL_connector_prop_t *vol_prop) +{ + H5VL_connector_prop_t old_vol_prop; /* Previous VOL connector property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Get the connector ID & info property */ + if(H5P__class_get(pclass, H5F_ACS_VOL_CONN_NAME, &old_vol_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get VOL connector ID & info") + + /* Set the new connector ID & info property */ + if(H5P__class_set(pclass, H5F_ACS_VOL_CONN_NAME, vol_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VOL connector ID & info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_set_vol_class() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_vol * * Purpose: Set the file VOL connector (VOL_ID) for a file access diff --git a/src/H5Pint.c b/src/H5Pint.c index e2ae792..79b6cf5 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -3061,6 +3061,116 @@ done: /*-------------------------------------------------------------------------- NAME + H5P__class_get + PURPOSE + Internal routine to get a property's value from a property class. + USAGE + herr_t H5P__class_get(pclass, name, value) + const H5P_genclass_t *pclass; IN: Property class to find property in + const char *name; IN: Name of property to get + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Gets the current value for a property in a property class. The property + name must exist or this routine will fail. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'get' callback routine registered for this property will _NOT_ be + called, this routine is designed for internal library use only! + + This routine may not be called for zero-sized properties and will + return an error in that case. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P__class_get(const H5P_genclass_t *pclass, const char *name, void *value) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(pclass); + HDassert(name); + HDassert(value); + + /* Find property in list */ + if(NULL == (prop = (H5P_genprop_t *)H5SL_search(pclass->props, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Copy the property value */ + HDmemcpy(value, prop->value, prop->size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__class_get() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P__class_set + PURPOSE + Internal routine to set a property's value in a property class. + USAGE + herr_t H5P__class_set(pclass, name, value) + const H5P_genclass_t *pclass; IN: Property class to find property in + const char *name; IN: Name of property to set + const void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property class. The property name + must exist or this routine will fail. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The 'set' callback routine registered for this property will _NOT_ be + called, this routine is designed for internal library use only! + + This routine may not be called for zero-sized properties and will + return an error in that case. + + The previous value is overwritten, not released in any way. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P__class_set(const H5P_genclass_t *pclass, const char *name, const void *value) +{ + H5P_genprop_t *prop; /* Temporary property pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(pclass); + HDassert(name); + HDassert(value); + + /* Find property in list */ + if(NULL == (prop = (H5P_genprop_t *)H5SL_search(pclass->props, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Copy the property value */ + HDmemcpy(prop->value, value, prop->size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__class_set() */ + + +/*-------------------------------------------------------------------------- + NAME H5P_exist_plist PURPOSE Internal routine to query the existance of a property in a property list. diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 13f3b13..c8e5e98 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -151,6 +151,10 @@ H5_DLL herr_t H5P__register(H5P_genclass_t **pclass, const char *name, size_t si H5P_prp_close_func_t prp_close); H5_DLL herr_t H5P__add_prop(H5SL_t *props, H5P_genprop_t *prop); H5_DLL herr_t H5P__access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod); +H5_DLL herr_t H5P__class_get(const H5P_genclass_t *pclass, const char *name, + void *value); +H5_DLL herr_t H5P__class_set(const H5P_genclass_t *pclass, const char *name, + const void *value); H5_DLL htri_t H5P__exist_pclass(H5P_genclass_t *pclass, const char *name); H5_DLL herr_t H5P__get_size_plist(const H5P_genplist_t *plist, const char *name, size_t *size); diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 866f088..49f7a12 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -148,6 +148,7 @@ H5_DLLVAR const struct H5P_libclass_t H5P_CLS_OCPY[1]; /* Object copy */ /* Forward declaration of structs used below */ struct H5O_fill_t; struct H5T_t; +struct H5VL_connector_prop_t; /* Package initialization routine */ H5_DLL herr_t H5P_init(void); @@ -178,6 +179,8 @@ H5_DLL const void *H5P_peek_driver_info(H5P_genplist_t *plist); H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info); H5_DLL herr_t H5P_set_vol(H5P_genplist_t *plist, hid_t vol_id, const void *vol_info); +H5_DLL herr_t H5P_reset_vol_class(const H5P_genclass_t *pclass, + const struct H5VL_connector_prop_t *vol_prop); H5_DLL herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist, H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info); diff --git a/src/H5VL.c b/src/H5VL.c index aa276ec..6e21acb 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -29,11 +29,8 @@ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5PLprivate.h" /* Plugins */ #include "H5VLpkg.h" /* Virtual Object Layer */ @@ -46,29 +43,10 @@ /* Local Typedefs */ /******************/ -/* Information needed for iterating over the registered VOL connector hid_t IDs. - * The name or value of the new VOL connector that is being registered is - * stored in the name (or value) field and the found_id field is initialized to - * H5I_INVALID_HID (-1). If we find a VOL connector with the same name / value, - * we set the found_id field to the existing ID for return to the function. - */ -typedef struct { - /* IN */ - H5VL_get_connector_kind_t kind; /* Which kind of connector search to make */ - union { - const char *name; /* The name of the VOL connector to check */ - H5VL_class_value_t value; /* The value of the VOL connector to check */ - } u; - - /* OUT */ - hid_t found_id; /* The connector ID, if we found a match */ -} H5VL_get_connector_ud_t; - /********************/ /* Local Prototypes */ /********************/ -static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); /*********************/ @@ -88,45 +66,6 @@ static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); /*------------------------------------------------------------------------- - * Function: H5VL__get_connector_cb - * - * Purpose: Callback routine to search through registered VOLs - * - * Return: Success: H5_ITER_STOP if the class and op_data name - * members match. H5_ITER_CONT otherwise. - * - * Failure: Can't fail - * - *------------------------------------------------------------------------- - */ -static int -H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data) -{ - H5VL_get_connector_ud_t *op_data = (H5VL_get_connector_ud_t *)_op_data; /* User data for callback */ - H5VL_class_t *cls = (H5VL_class_t *)obj; - int ret_value = H5_ITER_CONT; /* Callback return value */ - - FUNC_ENTER_STATIC_NOERR - - if(H5VL_GET_CONNECTOR_BY_NAME == op_data->kind) { - if(0 == HDstrcmp(cls->name, op_data->u.name)) { - op_data->found_id = id; - ret_value = H5_ITER_STOP; - } /* end if */ - } /* end if */ - else { - HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->kind); - if(cls->value == op_data->u.value) { - op_data->found_id = id; - ret_value = H5_ITER_STOP; - } /* end if */ - } /* end else */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__get_connector_cb() */ - - -/*------------------------------------------------------------------------- * Function: H5VLregister_connector * * Purpose: Registers a new VOL connector as a member of the virtual object @@ -143,8 +82,7 @@ H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data) hid_t H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) { - H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "*xi", cls, vipl_id); @@ -161,25 +99,9 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) if (cls->wrap_cls.get_wrap_ctx && !cls->wrap_cls.free_wrap_ctx) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector must provide free callback for object wrapping contexts when a get callback is provided") - op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; - op_data.u.name = cls->name; - op_data.found_id = H5I_INVALID_HID; - - /* check if connector is already registered */ - if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL IDs") - - /* Increment the ref count on the existing VOL connector ID, if it's already registered */ - if(op_data.found_id != H5I_INVALID_HID) { - if (H5I_inc_ref(op_data.found_id, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") - ret_value = op_data.found_id; - } /* end if */ - else { - /* Create a new class ID */ - if ((ret_value = H5VL_register_connector(cls, TRUE, vipl_id)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") - } /* end else */ + /* Register connector */ + if((ret_value = H5VL__register_connector(cls, TRUE, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") done: FUNC_LEAVE_API(ret_value) @@ -203,8 +125,7 @@ done: hid_t H5VLregister_connector_by_name(const char *name, hid_t vipl_id) { - H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "*si", name, vipl_id); @@ -215,34 +136,9 @@ H5VLregister_connector_by_name(const char *name, hid_t vipl_id) if (0 == HDstrlen(name)) HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "zero-length VOL connector name is disallowed") - op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; - op_data.u.name = name; - op_data.found_id = H5I_INVALID_HID; - - /* Check if connector is already registered */ - if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids") - - /* If connector alread registered, increment ref count on ID and return ID */ - if(op_data.found_id != H5I_INVALID_HID) { - if(H5I_inc_ref(op_data.found_id, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") - ret_value = op_data.found_id; - } /* end if */ - else { - H5PL_key_t key; - const H5VL_class_t *cls; - - /* Try loading the connector */ - key.vol.kind = H5VL_GET_CONNECTOR_BY_NAME; - key.vol.u.name = name; - if(NULL == (cls = (const H5VL_class_t *)H5PL_load(H5PL_TYPE_VOL, &key))) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") - - /* Register the connector we loaded */ - if((ret_value = H5VL_register_connector(cls, TRUE, vipl_id)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") - } /* end else */ + /* Register connector */ + if((ret_value = H5VL__register_connector_by_name(name, TRUE, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") done: FUNC_LEAVE_API(ret_value) @@ -266,8 +162,7 @@ done: hid_t H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id) { - H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "VCi", value, vipl_id); @@ -276,34 +171,9 @@ H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id) if(value < 0) HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "negative VOL connector value is disallowed") - op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE; - op_data.u.value = value; - op_data.found_id = H5I_INVALID_HID; - - /* Check if connector is already registered */ - if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids") - - /* If connector alread registered, increment ref count on ID and return ID */ - if(op_data.found_id != H5I_INVALID_HID) { - if(H5I_inc_ref(op_data.found_id, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") - ret_value = op_data.found_id; - } /* end if */ - else { - H5PL_key_t key; - const H5VL_class_t *cls; - - /* Try loading the connector */ - key.vol.kind = H5VL_GET_CONNECTOR_BY_VALUE; - key.vol.u.value = value; - if(NULL == (cls = (const H5VL_class_t *)H5PL_load(H5PL_TYPE_VOL, &key))) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") - - /* Register the connector we loaded */ - if((ret_value = H5VL_register_connector(cls, TRUE, vipl_id)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") - } /* end else */ + /* Register connector */ + if((ret_value = H5VL__register_connector_by_value(value, TRUE, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") done: FUNC_LEAVE_API(ret_value) @@ -315,33 +185,26 @@ done: * * Purpose: Tests whether a VOL class has been registered or not * - * Return: Positive if the VOL class has been registered - * - * Zero if it is unregistered + * Return: >0 if the VOL class has been registered + * 0 if it is unregistered + * <0 on error (if the class is not a valid class ID) * - * Negative on error (if the class is not a valid class ID) + * Programmer: Dana Robinson + * June 17, 2017 * *------------------------------------------------------------------------- */ htri_t H5VLis_connector_registered(const char *name) { - H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ htri_t ret_value = FALSE; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("t", "*s", name); - op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; - op_data.u.name = name; - op_data.found_id = H5I_INVALID_HID; - - /* Check arguments */ - if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "can't iterate over VOL ids") - - if (op_data.found_id != H5I_INVALID_HID) - ret_value = TRUE; + /* Check if connector with this name is registered */ + if((ret_value = H5VL__is_connector_registered(name)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL") done: FUNC_LEAVE_API(ret_value) @@ -356,30 +219,22 @@ done: * Return: Positive if the VOL class has been registered * Negative on error (if the class is not a valid class or not registered) * + * Programmer: Dana Robinson + * June 17, 2017 + * *------------------------------------------------------------------------- */ hid_t H5VLget_connector_id(const char *name) { - H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "*s", name); - op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; - op_data.u.name = name; - op_data.found_id = H5I_INVALID_HID; - - /* Check arguments */ - if (H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL connector IDs") - - if (op_data.found_id != H5I_INVALID_HID) { - if (H5I_inc_ref(op_data.found_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") - ret_value = op_data.found_id; - } /* end if */ + /* Get connector ID with this name */ + if((ret_value = H5VL__get_connector_id(name, TRUE)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id") done: FUNC_LEAVE_API(ret_value) @@ -406,7 +261,8 @@ H5VLget_connector_name(hid_t obj_id, char *name/*out*/, size_t size) FUNC_ENTER_API(FAIL) H5TRACE3("Zs", "ixz", obj_id, name, size); - if ((ret_value = H5VL_get_connector_name(obj_id, name, size)) < 0) + /* Call internal routine */ + if((ret_value = H5VL__get_connector_name(obj_id, name, size)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "Can't get connector name") done: diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 5a5d9ee..d77c9f6 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -506,20 +506,25 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_free_connector_info(const H5VL_class_t *connector, void *info) +H5VL_free_connector_info(hid_t connector_id, void *info) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Sanity checks */ - HDassert(connector); + /* Sanity check */ + HDassert(connector_id > 0); + + /* Check args and get class pointer */ + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Only free info object, if it's non-NULL */ if(info) { /* Allow the connector to free info or do it ourselves */ - if(connector->info_cls.free) { - if((connector->info_cls.free)(info) < 0) + if(cls->info_cls.free) { + if((cls->info_cls.free)(info) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector info free request failed") } /* end if */ else @@ -544,18 +549,13 @@ done: herr_t H5VLfree_connector_info(hid_t connector_id, void *info) { - H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT H5TRACE2("e", "i*x", connector_id, info); - /* Check args and get class pointer */ - if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Free the VOL connector info object */ - if(H5VL_free_connector_info(cls, info) < 0) + if(H5VL_free_connector_info(connector_id, info) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL connector info object") done: @@ -623,24 +623,9 @@ H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info) FUNC_ENTER_API_NOINIT H5TRACE3("e", "*si**x", str, connector_id, info); - /* Only deserialize string, if it's non-NULL */ - if(str) { - H5VL_class_t *cls; /* VOL connector's class struct */ - - /* Check args and get class pointer */ - if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - - /* Allow the connector to deserialize info */ - if(cls->info_cls.from_str) { - if((cls->info_cls.from_str)(str, info) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize connector info") - } /* end if */ - else - *info = NULL; - } /* end if */ - else - *info = NULL; + /* Call internal routine */ + if(H5VL__connector_str_to_info(str, connector_id, info) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDECODE, FAIL, "can't deserialize connector info") done: FUNC_LEAVE_API_NOINIT(ret_value) diff --git a/src/H5VLint.c b/src/H5VLint.c index 5aa25d2..3d1be61 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -29,14 +29,19 @@ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Tprivate.h" /* Datatypes */ -#include "H5VLpkg.h" /* Virtual Object Layer */ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5PLprivate.h" /* Plugins */ +#include "H5Tprivate.h" /* Datatypes */ +#include "H5VLpkg.h" /* Virtual Object Layer */ + +/* VOL connectors */ +#include "H5VLnative.h" /* Native VOL connector */ +#include "H5VLpassthru.h" /* Pass-through VOL connector */ /****************/ @@ -55,6 +60,24 @@ typedef struct H5VL_wrap_ctx_t { void *obj_wrap_ctx; /* "wrap context" for outermost connector */ } H5VL_wrap_ctx_t; +/* Information needed for iterating over the registered VOL connector hid_t IDs. + * The name or value of the new VOL connector that is being registered is + * stored in the name (or value) field and the found_id field is initialized to + * H5I_INVALID_HID (-1). If we find a VOL connector with the same name / value, + * we set the found_id field to the existing ID for return to the function. + */ +typedef struct { + /* IN */ + H5VL_get_connector_kind_t kind; /* Which kind of connector search to make */ + union { + const char *name; /* The name of the VOL connector to check */ + H5VL_class_value_t value; /* The value of the VOL connector to check */ + } u; + + /* OUT */ + hid_t found_id; /* The connector ID, if we found a match */ +} H5VL_get_connector_ud_t; + /********************/ /* Package Typedefs */ @@ -65,6 +88,8 @@ typedef struct H5VL_wrap_ctx_t { /* Local Prototypes */ /********************/ static herr_t H5VL__free_cls(H5VL_class_t *cls); +static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); +static herr_t H5VL__set_def_conn(void); static void *H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); @@ -83,6 +108,7 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Library Private Variables */ /*****************************/ + /*******************/ /* Local Variables */ /*******************/ @@ -107,21 +133,27 @@ H5FL_DEFINE(H5VL_object_t); /* Declare a free list to manage the H5VL_wrap_ctx_t struct */ H5FL_DEFINE_STATIC(H5VL_wrap_ctx_t); +/* Default VOL connector */ +static H5VL_connector_prop_t H5VL_def_conn_s = {-1, NULL}; + /*------------------------------------------------------------------------- - * Function: H5VL_init + * Function: H5VL_init_phase1 * - * Purpose: Initialize the interface from some other package + * Purpose: Initialize the interface from some other package. This should + * be followed with a call to H5VL_init_phase2 after the H5P + * interface is completely set up, finish setting up the H5VL + * information. * - * Return: Success: Non-negative * + * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ herr_t -H5VL_init(void) +H5VL_init_phase1(void) { herr_t ret_value = SUCCEED; /* Return value */ @@ -131,7 +163,36 @@ H5VL_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_init() */ +} /* end H5VL_init_phase1() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_init_phase2 + * + * Purpose: Finish initializing the interface from some other package. + * + * Note: This is broken out as a separate routine to avoid a circular + * reference with the H5P package. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_init_phase2(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Set up the default VOL connector in the default FAPL */ + if(H5VL__set_def_conn() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "unable to set default VOL connector") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_init_phase2() */ /*------------------------------------------------------------------------- @@ -148,12 +209,12 @@ done: herr_t H5VL__init_package(void) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Initialize the atom group for the VL IDs */ - if (H5I_register_type(H5I_VOL_CLS) < 0) + if(H5I_register_type(H5I_VOL_CLS) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize H5VL interface") done: @@ -180,17 +241,27 @@ H5VL_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR if(H5_PKG_INIT_VAR) { - if (H5I_nmembers(H5I_VOL) > 0) { - (void)H5I_clear_type(H5I_VOL, FALSE, FALSE); + if(H5VL_def_conn_s.connector_id > 0) { + /* Release the default VOL connector */ + (void)H5VL_conn_free(&H5VL_def_conn_s); + H5VL_def_conn_s.connector_id = -1; + H5VL_def_conn_s.connector_info = NULL; n++; } /* end if */ else { - /* Destroy the VOL connector ID group */ - n += (H5I_dec_type_ref(H5I_VOL) > 0); - - /* Mark interface as closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; + if(H5I_nmembers(H5I_VOL) > 0) { + /* Unregister all VOL connectors */ + (void)H5I_clear_type(H5I_VOL, FALSE, FALSE); + n++; + } /* end if */ + else { + /* Destroy the VOL connector ID group */ + n += (H5I_dec_type_ref(H5I_VOL) > 0); + + /* Mark interface as closed */ + if(0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end else */ } /* end else */ } /* end if */ @@ -234,6 +305,182 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL__get_connector_cb + * + * Purpose: Callback routine to search through registered VOLs + * + * Return: Success: H5_ITER_STOP if the class and op_data name + * members match. H5_ITER_CONT otherwise. + * Failure: Can't fail + * + * Programmer: Dana Robinson + * June 22, 2017 + * + *------------------------------------------------------------------------- + */ +static int +H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data) +{ + H5VL_get_connector_ud_t *op_data = (H5VL_get_connector_ud_t *)_op_data; /* User data for callback */ + H5VL_class_t *cls = (H5VL_class_t *)obj; + int ret_value = H5_ITER_CONT; /* Callback return value */ + + FUNC_ENTER_STATIC_NOERR + + if(H5VL_GET_CONNECTOR_BY_NAME == op_data->kind) { + if(0 == HDstrcmp(cls->name, op_data->u.name)) { + op_data->found_id = id; + ret_value = H5_ITER_STOP; + } /* end if */ + } /* end if */ + else { + HDassert(H5VL_GET_CONNECTOR_BY_VALUE == op_data->kind); + if(cls->value == op_data->u.value) { + op_data->found_id = id; + ret_value = H5_ITER_STOP; + } /* end if */ + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__get_connector_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__set_def_conn + * + * Purpose: Parses a string that contains the default VOL connector for + * the library. + * + * Note: Usually from the environment variable "HDF5_VOL_CONNECTOR", + * but could be from elsewhere. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Jordan Henderson + * November 2018 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__set_def_conn(void) +{ + H5P_genplist_t *def_fapl; /* Default file access property list */ + H5P_genclass_t *def_fapclass; /* Default file access property class */ + const char *env_var; /* Environment variable for default VOL connector */ + char *buf = NULL; /* Buffer for tokenizing string */ + hid_t connector_id = -1; /* VOL conntector ID */ + void *vol_info = NULL; /* VOL connector info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(H5VL_def_conn_s.connector_id == (-1)); + HDassert(H5VL_def_conn_s.connector_info == NULL); + + /* Check for environment variable set */ + env_var = HDgetenv("HDF5_VOL_CONNECTOR"); + + /* Only parse the string if it's set */ + if(env_var && *env_var) { + char *lasts = NULL; /* Context pointer for strtok_r() call */ + const char *tok = NULL; /* Token from strtok_r call */ + htri_t connector_is_registered; /* Whether connector is already registered */ + + /* Duplicate the string to parse, as it is modified as we go */ + if(NULL == (buf = H5MM_strdup(env_var))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate memory for environment variable string") + + /* Get the first 'word' of the environment variable. + * If it's nothing (environment variable was whitespace) return error. + */ + if(NULL == (tok = HDstrtok_r(buf, " \t\n\r", &lasts))) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "VOL connector environment variable set empty?") + + /* First, check to see if the connector is already registered */ + if((connector_is_registered = H5VL__is_connector_registered(tok)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check if VOL connector already registered") + else if(connector_is_registered) { + /* Retrieve the ID of the already-registered VOL connector */ + if((connector_id = H5VL__get_connector_id(tok, FALSE)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get VOL connector ID") + } /* end else-if */ + else { + /* Check for VOL connectors that ship with the library */ + if(!HDstrcmp(tok, "native")) { + connector_id = H5VL_NATIVE; + if(H5I_inc_ref(connector_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, FAIL, "can't increment VOL connector refcount") + } /* end if */ + else if(!HDstrcmp(tok, "pass_through")) { + connector_id = H5VL_PASSTHRU; + if(H5I_inc_ref(connector_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, FAIL, "can't increment VOL connector refcount") + } /* end else-if */ + else { + /* Register the VOL connector */ + /* (NOTE: No provisions for vipl_id currently) */ + if((connector_id = H5VL__register_connector_by_name(tok, FALSE, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register connector") + } /* end else */ + } /* end else */ + + /* Was there any connector info specified in the environment variable? */ + if(NULL != (tok = HDstrtok_r(NULL, " \t\n\r", &lasts))) + if(H5VL__connector_str_to_info(tok, connector_id, &vol_info) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDECODE, FAIL, "can't deserialize connector info") + + /* Set the default VOL connector */ + H5VL_def_conn_s.connector_id = connector_id; + H5VL_def_conn_s.connector_info = vol_info; + } /* end if */ + else { + /* Set the default VOL connector */ + H5VL_def_conn_s.connector_id = H5_DEFAULT_VOL; + H5VL_def_conn_s.connector_info = NULL; + + /* Increment the ref count on the default connector */ + if(H5I_inc_ref(H5VL_def_conn_s.connector_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, FAIL, "can't increment VOL connector refcount") + } /* end else */ + + /* Get default file access pclass */ + if(NULL == (def_fapclass = (H5P_genclass_t *)H5I_object(H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_VOL, H5E_BADATOM, FAIL, "can't find object for default file access property class ID") + + /* Change the default VOL for the default file access pclass */ + if(H5P_reset_vol_class(def_fapclass, &H5VL_def_conn_s) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set default VOL connector for default file access property class") + + /* Get default file access plist */ + if(NULL == (def_fapl = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_VOL, H5E_BADATOM, FAIL, "can't find object for default fapl ID") + + /* Change the default VOL for the default FAPL */ + if(H5P_set_vol(def_fapl, H5VL_def_conn_s.connector_id, H5VL_def_conn_s.connector_info) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set default VOL connector for default FAPL") + +done: + /* Clean up on error */ + if(ret_value < 0) { + if(vol_info) + if(H5VL_free_connector_info(connector_id, vol_info) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free VOL connector info") + if(connector_id >= 0) + /* The H5VL_class_t struct will be freed by this function */ + if(H5I_dec_ref(connector_id) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister VOL connector") + } /* end if */ + + /* Clean up */ + H5MM_xfree(buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__set_def_conn() */ + + +/*------------------------------------------------------------------------- * Function: H5VL__wrap_obj * * Purpose: Wraps a library object with possible VOL connector wrappers, to @@ -393,29 +640,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_conn_free(const H5VL_connector_prop_t *info) +H5VL_conn_free(const H5VL_connector_prop_t *connector_prop) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - if(info) { + if(connector_prop) { /* Free the connector info (if it exists) and decrement the ID */ - if(info->connector_id > 0) { - if(info->connector_info) { - H5VL_class_t *connector; /* Pointer to connector */ - - /* Retrieve the connector for the ID */ - if(NULL == (connector = (H5VL_class_t *)H5I_object(info->connector_id))) - HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID") - + if(connector_prop->connector_id > 0) { + if(connector_prop->connector_info) /* Free the connector info */ - if(H5VL_free_connector_info(connector, (void *)info->connector_info) < 0) /* Casting away const OK - QAK */ + if(H5VL_free_connector_info(connector_prop->connector_id, (void *)connector_prop->connector_info) < 0) /* Casting away const OK - QAK */ HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL connector info object") - } /* end if */ /* Decrement reference count for connector ID */ - if(H5I_dec_ref(info->connector_id) < 0) + if(H5I_dec_ref(connector_prop->connector_id) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "can't decrement reference count for connector ID") } /* end if */ } /* end if */ @@ -595,6 +835,9 @@ done: * * Failure: H5I_INVALID_HID * + * Programmer: Dana Robinson + * June 22, 2017 + * *------------------------------------------------------------------------- */ hid_t @@ -610,7 +853,7 @@ H5VL_register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) HDassert(cls); /* Copy the class structure so the caller can reuse or free it */ - if (NULL == (saved = H5FL_CALLOC(H5VL_class_t))) + if(NULL == (saved = H5FL_MALLOC(H5VL_class_t))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "memory allocation failed for VOL connector class struct") HDmemcpy(saved, cls, sizeof(H5VL_class_t)); if(NULL == (saved->name = H5MM_strdup(cls->name))) @@ -621,23 +864,319 @@ H5VL_register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to init VOL connector") /* Create the new class ID */ - if ((ret_value = H5I_register(H5I_VOL, saved, app_ref)) < 0) + if((ret_value = H5I_register(H5I_VOL, saved, app_ref)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") done: - if (ret_value < 0 && saved) { - if (saved->name) + if(ret_value < 0 && saved) { + if(saved->name) H5MM_xfree((void *)(saved->name)); /* Casting away const OK -QAK */ H5FL_FREE(H5VL_class_t, saved); - } + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_register_connector() */ /*------------------------------------------------------------------------- - * Function: H5VL_get_connector_name + * Function: H5VL__register_connector + * + * Purpose: Registers a new VOL connector as a member of the virtual object + * layer class. + * + * Return: Success: A VOL connector ID which is good until the + * library is closed or the connector is + * unregistered. + * + * Failure: H5I_INVALID_HID + * + * Programmer: Dana Robinson + * June 22, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL__register_connector(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id) +{ + H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Set up op data for iteration */ + op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; + op_data.u.name = cls->name; + op_data.found_id = H5I_INVALID_HID; + + /* Check if connector is already registered */ + if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL IDs") + + /* Increment the ref count on the existing VOL connector ID, if it's already registered */ + if(op_data.found_id != H5I_INVALID_HID) { + if(H5I_inc_ref(op_data.found_id, app_ref) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + ret_value = op_data.found_id; + } /* end if */ + else { + /* Create a new class ID */ + if((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__register_connector() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__register_connector_by_name + * + * Purpose: Registers a new VOL connector as a member of the virtual object + * layer class. + * + * Return: Success: A VOL connector ID which is good until the + * library is closed or the connector is + * unregistered. + * + * Failure: H5I_INVALID_HID + * + * Programmer: Dana Robinson + * June 22, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_id) +{ + H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Set up op data for iteration */ + op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; + op_data.u.name = name; + op_data.found_id = H5I_INVALID_HID; + + /* Check if connector is already registered */ + if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids") + + /* If connector alread registered, increment ref count on ID and return ID */ + if(op_data.found_id != H5I_INVALID_HID) { + if(H5I_inc_ref(op_data.found_id, app_ref) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + ret_value = op_data.found_id; + } /* end if */ + else { + H5PL_key_t key; + const H5VL_class_t *cls; + + /* Try loading the connector */ + key.vol.kind = H5VL_GET_CONNECTOR_BY_NAME; + key.vol.u.name = name; + if(NULL == (cls = (const H5VL_class_t *)H5PL_load(H5PL_TYPE_VOL, &key))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") + + /* Register the connector we loaded */ + if((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__register_connector_by_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__register_connector_by_value + * + * Purpose: Registers a new VOL connector as a member of the virtual object + * layer class. + * + * Return: Success: A VOL connector ID which is good until the + * library is closed or the connector is + * unregistered. + * + * Failure: H5I_INVALID_HID + * + * Programmer: Dana Robinson + * June 22, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid_t vipl_id) +{ + H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Set up op data for iteration */ + op_data.kind = H5VL_GET_CONNECTOR_BY_VALUE; + op_data.u.value = value; + op_data.found_id = H5I_INVALID_HID; + + /* Check if connector is already registered */ + if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL ids") + + /* If connector alread registered, increment ref count on ID and return ID */ + if(op_data.found_id != H5I_INVALID_HID) { + if(H5I_inc_ref(op_data.found_id, app_ref) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + ret_value = op_data.found_id; + } /* end if */ + else { + H5PL_key_t key; + const H5VL_class_t *cls; + + /* Try loading the connector */ + key.vol.kind = H5VL_GET_CONNECTOR_BY_VALUE; + key.vol.u.value = value; + if(NULL == (cls = (const H5VL_class_t *)H5PL_load(H5PL_TYPE_VOL, &key))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") + + /* Register the connector we loaded */ + if((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__register_connector_by_value() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__is_connector_registered + * + * Purpose: Checks if a connector with a particular name is registered. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Dana Robinson + * June 17, 2017 + * + *------------------------------------------------------------------------- + */ +htri_t +H5VL__is_connector_registered(const char *name) +{ + H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Set up op data for iteration */ + op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; + op_data.u.name = name; + op_data.found_id = H5I_INVALID_HID; + + /* Find connector with name */ + if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "can't iterate over VOL connectors") + + /* Found a connector with that name */ + if(op_data.found_id != H5I_INVALID_HID) + ret_value = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__is_connector_registered() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__get_connector_id + * + * Purpose: Retrieves the ID for a registered VOL connector. + * + * Return: Positive if the VOL class has been registered + * Negative on error (if the class is not a valid class or not registered) + * + * Programmer: Dana Robinson + * June 17, 2017 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL__get_connector_id(const char *name, hbool_t is_api) +{ + H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Set up op data for iteration */ + op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; + op_data.u.name = name; + op_data.found_id = H5I_INVALID_HID; + + /* Find connector with name */ + if(H5I_iterate(H5I_VOL, H5VL__get_connector_cb, &op_data, TRUE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, H5I_INVALID_HID, "can't iterate over VOL connectors") + + /* Found a connector with that name */ + if(op_data.found_id != H5I_INVALID_HID) { + if(H5I_inc_ref(op_data.found_id, is_api) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + ret_value = op_data.found_id; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__get_connector_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__connector_str_to_info + * + * Purpose: Deserializes a string into a connector's info object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * March 2, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__connector_str_to_info(const char *str, hid_t connector_id, void **info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Only deserialize string, if it's non-NULL */ + if(str) { + H5VL_class_t *cls; /* VOL connector's class struct */ + + /* Check args and get class pointer */ + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Allow the connector to deserialize info */ + if(cls->info_cls.from_str) { + if((cls->info_cls.from_str)(str, info) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "can't deserialize connector info") + } /* end if */ + else + *info = NULL; + } /* end if */ + else + *info = NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__connector_str_to_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__get_connector_name * * Purpose: Private version of H5VLget_connector_name * @@ -647,14 +1186,14 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5VL_get_connector_name(hid_t id, char *name /*out*/, size_t size) +H5VL__get_connector_name(hid_t id, char *name /*out*/, size_t size) { H5VL_object_t *vol_obj; const H5VL_class_t *cls; size_t len; ssize_t ret_value = -1; - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* get the object pointer */ if (NULL == (vol_obj = H5VL_vol_object(id))) @@ -674,7 +1213,7 @@ H5VL_get_connector_name(hid_t id, char *name /*out*/, size_t size) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_get_connector_name() */ +} /* end H5VL__get_connector_name() */ /*------------------------------------------------------------------------- diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index fe72000..a4c85cc 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -20,6 +20,11 @@ * include _any_ private HDF5 header files. This connector should * therefore only make public HDF5 API calls and use standard C / * POSIX calls. + * + * Note that the HDF5 error stack must be preserved on code paths + * that could be invoked when the underlying VOL connector's + * callback can fail. + * */ @@ -297,6 +302,9 @@ H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id) * * Purpose: Release a pass through object * + * Note: Take care to preserve the current HDF5 error stack + * when calling HDF5 API calls. + * * Return: Success: 0 * Failure: -1 * @@ -308,7 +316,14 @@ H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id) static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj) { + hid_t err_id; + + err_id = H5Eget_current_stack(); + H5Idec_ref(obj->under_vol_id); + + H5Eset_current_stack(err_id); + free(obj); return 0; @@ -332,11 +347,8 @@ H5VL_pass_through_free_obj(H5VL_pass_through_t *obj) hid_t H5VL_pass_through_register(void) { - /* Clear the error stack */ - H5Eclear2(H5E_DEFAULT); - /* Singleton register the pass-through VOL connector ID */ - if(H5I_VOL != H5Iget_type(H5VL_PASSTHRU_g)) + if(H5VL_PASSTHRU_g < 0) H5VL_PASSTHRU_g = H5VLregister_connector(&H5VL_pass_through_g, H5P_DEFAULT); return H5VL_PASSTHRU_g; @@ -476,6 +488,9 @@ H5VL_pass_through_info_cmp(int *cmp_value, const void *_info1, const void *_info * * Purpose: Release an info object for the connector. * + * Note: Take care to preserve the current HDF5 error stack + * when calling HDF5 API calls. + * * Return: Success: 0 * Failure: -1 * @@ -485,16 +500,21 @@ static herr_t H5VL_pass_through_info_free(void *_info) { H5VL_pass_through_info_t *info = (H5VL_pass_through_info_t *)_info; + hid_t err_id; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL INFO Free\n"); #endif + err_id = H5Eget_current_stack(); + /* Release underlying VOL ID and info */ if(info->under_vol_info) H5VLfree_connector_info(info->under_vol_id, info->under_vol_info); H5Idec_ref(info->under_vol_id); + H5Eset_current_stack(err_id); + /* Free pass through info object itself */ free(info); @@ -695,6 +715,9 @@ H5VL_pass_through_wrap_object(void *obj, H5I_type_t obj_type, void *_wrap_ctx) * * Purpose: Release a "wrapper context" for an object * + * Note: Take care to preserve the current HDF5 error stack + * when calling HDF5 API calls. + * * Return: Success: 0 * Failure: -1 * @@ -704,16 +727,21 @@ static herr_t H5VL_pass_through_free_wrap_ctx(void *_wrap_ctx) { H5VL_pass_through_wrap_ctx_t *wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)_wrap_ctx; + hid_t err_id; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL WRAP CTX Free\n"); #endif + err_id = H5Eget_current_stack(); + /* Release underlying VOL ID and wrap context */ if(wrap_ctx->under_wrap_ctx) H5VLfree_wrap_ctx(wrap_ctx->under_wrap_ctx, wrap_ctx->under_vol_id); H5Idec_ref(wrap_ctx->under_vol_id); + H5Eset_current_stack(err_id); + /* Free pass through wrap context object itself */ free(wrap_ctx); diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h index bbdb0cc..69e51c2 100644 --- a/src/H5VLpkg.h +++ b/src/H5VLpkg.h @@ -28,21 +28,36 @@ /* Other private headers needed by this file */ + /**************************/ /* Package Private Macros */ /**************************/ + /****************************/ /* Package Private Typedefs */ /****************************/ + /*****************************/ /* Package Private Variables */ /*****************************/ + /******************************/ /* Package Private Prototypes */ /******************************/ +H5_DLL hid_t H5VL__register_connector(const H5VL_class_t *cls, hbool_t app_ref, + hid_t vipl_id); +H5_DLL hid_t H5VL__register_connector_by_name(const char *name, hbool_t app_ref, + hid_t vipl_id); +H5_DLL hid_t H5VL__register_connector_by_value(H5VL_class_value_t value, + hbool_t app_ref, hid_t vipl_id); +H5_DLL htri_t H5VL__is_connector_registered(const char *name); +H5_DLL hid_t H5VL__get_connector_id(const char *name, hbool_t is_api); +H5_DLL herr_t H5VL__connector_str_to_info(const char *str, hid_t connector_id, + void **info); +H5_DLL ssize_t H5VL__get_connector_name(hid_t id, char *name/*out*/, size_t size); #endif /* _H5VLpkg_H */ diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 283c77a..6b948f6 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -18,10 +18,12 @@ /* Private headers needed by this file */ + /**************************/ /* Library Private Macros */ /**************************/ + /****************************/ /* Library Private Typedefs */ /****************************/ @@ -62,14 +64,14 @@ typedef enum H5VL_get_connector_kind_t { /******************************/ /* Utility functions */ -H5_DLL herr_t H5VL_init(void); +H5_DLL herr_t H5VL_init_phase1(void); +H5_DLL herr_t H5VL_init_phase2(void); H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2); H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value); H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info); /* Functions that deal with VOL connectors */ H5_DLL hid_t H5VL_register_connector(const void *cls, hbool_t app_ref, hid_t vipl_id); -H5_DLL ssize_t H5VL_get_connector_name(hid_t id, char *name/*out*/, size_t size); /* NOTE: The object and ID functions below deal in VOL objects (i.e.; * H5VL_object_t). Similar non-VOL calls exist in H5Iprivate.h. Use @@ -112,7 +114,7 @@ H5_DLL int H5VL_copy_connector_info(const H5VL_class_t *connector, void **dst_in const void *src_info); H5_DLL herr_t H5VL_cmp_connector_info(const H5VL_class_t *connector, int *cmp_value, const void *info1, const void *info2); -H5_DLL herr_t H5VL_free_connector_info(const H5VL_class_t *connector, void *info); +H5_DLL herr_t H5VL_free_connector_info(hid_t connector_id, void *info); /* Attribute functions */ H5_DLL void *H5VL_attr_create(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req); diff --git a/test/cache_tagging.c b/test/cache_tagging.c index b91f013..e03defa 100644 --- a/test/cache_tagging.c +++ b/test/cache_tagging.c @@ -448,7 +448,7 @@ check_file_creation_tags(hid_t fcpl_id, int type) TESTING("tag application during file creation"); /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl_id, fapl)) < 0 ) TEST_ERROR; @@ -539,7 +539,7 @@ check_file_open_tags(hid_t fcpl, int type) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -652,7 +652,7 @@ check_group_creation_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -751,7 +751,7 @@ check_multi_group_creation_tags(void) TESTING("tag application during multiple group creation"); /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Set latest version of library */ if ( H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0 ) TEST_ERROR; @@ -881,7 +881,7 @@ check_link_iteration_tags(void) TESTING("tag application during iteration over links in a group"); /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* =========== */ /* Create File */ @@ -1000,7 +1000,7 @@ check_dense_attribute_tags(void) TESTING("tag application during dense attribute manipulation"); /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; if ( H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0 ) TEST_ERROR; /* Create Dcpl */ @@ -1184,7 +1184,7 @@ check_group_open_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -1295,7 +1295,7 @@ check_attribute_creation_tags(hid_t fcpl, int type) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -1429,7 +1429,7 @@ check_attribute_open_tags(hid_t fcpl, int type) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -1576,7 +1576,7 @@ check_attribute_rename_tags(hid_t fcpl, int type) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -1761,7 +1761,7 @@ check_attribute_delete_tags(hid_t fcpl, int type) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -1917,7 +1917,7 @@ check_dataset_creation_tags(hid_t fcpl, int type) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -2051,7 +2051,7 @@ check_dataset_creation_earlyalloc_tags(hid_t fcpl, int type) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -2187,7 +2187,7 @@ check_dataset_open_tags(void) /* ========= */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -2318,7 +2318,7 @@ check_dataset_write_tags(void) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -2457,7 +2457,7 @@ check_attribute_write_tags(hid_t fcpl, int type) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file with provided fcpl_t */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -2613,7 +2613,7 @@ check_dataset_read_tags(void) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -2751,7 +2751,7 @@ check_dataset_size_retrieval(void) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -2890,7 +2890,7 @@ check_dataset_extend_tags(void) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3017,7 +3017,7 @@ check_object_info_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3126,7 +3126,7 @@ check_object_copy_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3257,7 +3257,7 @@ check_link_removal_tags(hid_t fcpl, int type) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl)) < 0 ) TEST_ERROR; @@ -3416,7 +3416,7 @@ check_link_getname_tags(void) if ( (NULL == (data = (int *)HDcalloc(DIMS * DIMS, sizeof(int)))) ) TEST_ERROR; /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3553,7 +3553,7 @@ check_external_link_creation_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3660,7 +3660,7 @@ check_external_link_open_tags(void) /* ===== */ /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; @@ -3787,7 +3787,7 @@ check_invalid_tag_application(void) #if H5C_DO_TAGGING_SANITY_CHECKS /* Create Fapl */ - if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; + if ( (fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0 ) TEST_ERROR; /* Create a test file */ if ( (fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0 ) TEST_ERROR; diff --git a/test/h5test.c b/test/h5test.c index 0ba28f3..bc3f2fa 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -44,12 +44,6 @@ * is interpreted according to the driver. See * h5_get_vfd_fapl() for details. * - * HDF5_VOL_CONNECTOR: This string describes what VOL connector to - * use for HDF5 file access. The first word in the - * value is the name of the connector and subsequent data - * is interpreted according to the connector. See - * h5_get_vol_fapl() for details. - * * HDF5_LIBVER_BOUNDS: This string describes what library version bounds to * use for HDF5 file access. See h5_get_libver_fapl() for details. * @@ -785,10 +779,6 @@ h5_fileaccess(void) if(h5_get_vfd_fapl(fapl_id) < 0) goto error; - /* Next, try to set up a VOL connector */ - if(h5_get_vol_fapl(fapl_id) < 0) - goto error; - /* Finally, check for libver bounds */ if(h5_get_libver_fapl(fapl_id) < 0) goto error; @@ -829,10 +819,6 @@ h5_fileaccess_flags(unsigned flags) if((flags & H5_FILEACCESS_VFD) && h5_get_vfd_fapl(fapl_id) < 0) goto error; - /* Next, try to set up a VOL connector */ - if((flags & H5_FILEACCESS_VOL) && h5_get_vol_fapl(fapl_id) < 0) - goto error; - /* Finally, check for libver bounds */ if((flags & H5_FILEACCESS_LIBVER) && h5_get_libver_fapl(fapl_id) < 0) goto error; @@ -1046,110 +1032,6 @@ error: /*------------------------------------------------------------------------- - * Function: h5_get_vol_fapl - * - * Purpose: Returns a file access property list which is the default - * fapl but with a VOL connector set according to the constant - * or environment variable HDF5_VOL_CONNECTOR. - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Jordan Henderson - * November 2018 - * - *------------------------------------------------------------------------- - */ -herr_t -h5_get_vol_fapl(hid_t fapl) -{ - const char *env = NULL; - const char *tok = NULL; - char *lasts = NULL; /* Context pointer for strtok_r() call */ - htri_t connector_is_registered; - char buf[1024]; /* Buffer for tokenizing HDF5_VOL_CONNECTOR */ - void *vol_info = NULL; /* VOL connector info */ - hid_t connector_id = -1; - - /* Get the environment variable, if it exists */ - env = HDgetenv("HDF5_VOL_CONNECTOR"); -#ifdef HDF5_VOL_CONNECTOR - /* Use the environment variable, then the compile-time constant */ - if(!env) - env = HDF5_VOL_CONNECTOR; -#endif - - /* If the environment variable was not set, just return. */ - if(!env || !*env) - goto done; - - /* Get the first 'word' of the environment variable. - * If it's nothing (environment variable was whitespace) just return. - */ - HDstrncpy(buf, env, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - if(NULL == (tok = HDstrtok_r(buf, " \t\n\r", &lasts))) - goto done; - - /* First, check to see if the connector is already registered */ - if((connector_is_registered = H5VLis_connector_registered(tok)) < 0) - goto done; - else if(connector_is_registered) { - /* Retrieve the ID of the already-registered VOL connector */ - if((connector_id = H5VLget_connector_id(tok)) < 0) - goto error; - } /* end else-if */ - else { - /* Check for VOL connectors that ship with the library */ - if(!HDstrcmp(tok, "native")) { - connector_id = H5VL_NATIVE; - if(H5Iinc_ref(connector_id) < 0) - goto error; - } else if(!HDstrcmp(tok, "pass_through")) { - connector_id = H5VL_PASSTHRU; - if(H5Iinc_ref(connector_id) < 0) - goto error; - } else { - /* Register the VOL connector */ - /* (NOTE: No provisions for vipl_id currently) */ - if((connector_id = H5VLregister_connector_by_name(tok, H5P_DEFAULT)) < 0) - goto error; - } /* end else */ - } /* end else */ - - /* Was there any connector info specified in the environment variable? */ - if(NULL != (tok = HDstrtok_r(NULL, " \t\n\r", &lasts))) - if(H5VLconnector_str_to_info(tok, connector_id, &vol_info) < 0) - goto error; - - /* Set the VOL connector in the FAPL */ - if(H5Pset_vol(fapl, connector_id, vol_info) < 0) - goto error; - - /* Release VOL connector info, if there was any */ - if(vol_info) - if(H5VLfree_connector_info(connector_id, vol_info) < 0) - goto error; - - /* Close the connector ID */ - if(connector_id >= 0) - if(H5VLunregister_connector(connector_id) < 0) - goto error; - -done: - return 0; - -error: - if(vol_info) - H5VLfree_connector_info(connector_id, vol_info); - if(connector_id >= 0) - H5VLunregister_connector(connector_id); - - return -1; -} /* end h5_get_vol_fapl() */ - - -/*------------------------------------------------------------------------- * Function: h5_no_hwconv * * Purpose: Turn off hardware data type conversions. diff --git a/test/h5test.h b/test/h5test.h index 66a7863..8c3ce6b 100644 --- a/test/h5test.h +++ b/test/h5test.h @@ -123,8 +123,7 @@ H5TEST_DLLVAR MPI_Info h5_io_info_g; /* MPI INFO object for IO */ /* Flags for h5_fileaccess_flags() */ #define H5_FILEACCESS_VFD 0x01 -#define H5_FILEACCESS_VOL 0x02 -#define H5_FILEACCESS_LIBVER 0x04 +#define H5_FILEACCESS_LIBVER 0x02 #ifdef __cplusplus extern "C" { @@ -152,7 +151,6 @@ H5TEST_DLL H5VL_class_t *h5_get_dummy_vol_class(void); /* Functions that will replace components of a FAPL */ H5TEST_DLL herr_t h5_get_vfd_fapl(hid_t fapl_id); -H5TEST_DLL herr_t h5_get_vol_fapl(hid_t fapl_id); H5TEST_DLL herr_t h5_get_libver_fapl(hid_t fapl_id); /* h5_clean_files() replacements */ diff --git a/test/objcopy.c b/test/objcopy.c index 4055781..9c5ccc4 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -7869,7 +7869,7 @@ test_copy_old_layout(hid_t fcpl_dst, hid_t fapl, hbool_t test_open) addr_reset(); /* Setup */ - if((src_fapl = h5_fileaccess_flags(H5_FILEACCESS_VOL | H5_FILEACCESS_LIBVER)) < 0) TEST_ERROR + if((src_fapl = h5_fileaccess_flags(H5_FILEACCESS_LIBVER)) < 0) TEST_ERROR /* open source file (read-only) */ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0) TEST_ERROR diff --git a/test/testerror.sh.in b/test/testerror.sh.in index 734b051..ac2a109 100644 --- a/test/testerror.sh.in +++ b/test/testerror.sh.in @@ -22,7 +22,9 @@ CMP='cmp -s' DIFF='diff -c' # Skip plugin module to test missing filter -ENVCMD="env HDF5_PLUGIN_PRELOAD=::" +# Also reset the VOL connector to only use the native connector, because of the +# error stack checking. QAK - 2019/03/09 +ENVCMD="env HDF5_PLUGIN_PRELOAD=:: HDF5_VOL_CONNECTOR=native" nerrors=0 verbose=yes diff --git a/test/titerate.c b/test/titerate.c index 8c0ef24..54e9b5e 100644 --- a/test/titerate.c +++ b/test/titerate.c @@ -945,7 +945,7 @@ find_err_msg_cb(unsigned n, const H5E_error2_t *err_desc, void *_client_data) searched_err_t *searched_err = (searched_err_t *)_client_data; if (searched_err == NULL) - return -1; + return H5_ITER_ERROR; /* If the searched error message is found, stop the iteration */ if (err_desc->desc != NULL && strcmp(err_desc->desc, searched_err->message) == 0) @@ -953,6 +953,7 @@ find_err_msg_cb(unsigned n, const H5E_error2_t *err_desc, void *_client_data) searched_err->found = true; status = H5_ITER_STOP; } + return status; } /* end find_err_msg_cb() */ @@ -988,6 +989,7 @@ static void test_corrupted_attnamelen(void) /* Call H5Aiterate2 to trigger the failure in HDFFV-10588. Failure should occur in the decoding stage, so some arguments are not needed. */ err_status = H5Aiterate2(did, H5_INDEX_NAME, H5_ITER_INC, NULL, NULL, NULL); + VERIFY(err_status, FAIL, "H5Aiterate2"); /* Make sure the intended error was caught */ if(err_status == -1) diff --git a/test/ttsafe_error.c b/test/ttsafe_error.c index 56d87ee..5e26888 100644 --- a/test/ttsafe_error.c +++ b/test/ttsafe_error.c @@ -63,6 +63,8 @@ static void *tts_error_thread(void *); void tts_error(void) { + hid_t def_fapl = H5I_INVALID_HID; + hid_t vol_id = H5I_INVALID_HID; hid_t dataset = H5I_INVALID_HID; H5TS_thread_t threads[NUM_THREAD]; H5TS_attr_t attribute; @@ -111,39 +113,52 @@ tts_error(void) H5TS_attr_setscope(&attribute, H5TS_SCOPE_SYSTEM); #endif /* H5_HAVE_SYSTEM_SCOPE_THREADS */ - /* Create a hdf5 file using H5F_ACC_TRUNC access, default file - * creation plist and default file access plist - */ - error_file_g = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(error_file_g, H5I_INVALID_HID, "H5Fcreate"); + def_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(def_fapl, H5I_INVALID_HID, "H5Pcreate"); - for (i = 0; i < NUM_THREAD; i++) - threads[i] = H5TS_create_thread(tts_error_thread, &attribute, NULL); + status = H5Pget_vol_id(def_fapl, &vol_id); + CHECK(status, FAIL, "H5Pget_vol_id"); - for (i = 0; i < NUM_THREAD; i++) - H5TS_wait_for_thread(threads[i]); + if(vol_id == H5VL_NATIVE) { + /* Create a hdf5 file using H5F_ACC_TRUNC access, default file + * creation plist and default file access plist + */ + error_file_g = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, def_fapl); + CHECK(error_file_g, H5I_INVALID_HID, "H5Fcreate"); - if (error_flag_g) { - TestErrPrintf("At least one thread reported a value that was different from the expected value\n"); - HDprintf("(Update this test if the error stack changed!)\n"); - } + for (i = 0; i < NUM_THREAD; i++) + threads[i] = H5TS_create_thread(tts_error_thread, &attribute, NULL); + + for (i = 0; i < NUM_THREAD; i++) + H5TS_wait_for_thread(threads[i]); + + if (error_flag_g) { + TestErrPrintf("At least one thread reported a value that was different from the expected value\n"); + HDprintf("(Update this test if the error stack changed!)\n"); + } - if (error_count_g != NUM_THREAD - 1) - TestErrPrintf("Error: %d threads failed instead of %d\n", error_count_g, NUM_THREAD-1); + if (error_count_g != NUM_THREAD - 1) + TestErrPrintf("Error: %d threads failed instead of %d\n", error_count_g, NUM_THREAD-1); - dataset = H5Dopen2(error_file_g, DATASETNAME, H5P_DEFAULT); - CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); + dataset = H5Dopen2(error_file_g, DATASETNAME, H5P_DEFAULT); + CHECK(dataset, H5I_INVALID_HID, "H5Dopen2"); - status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value); - CHECK(status, FAIL, "H5Dread"); + status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value); + CHECK(status, FAIL, "H5Dread"); - if (value != WRITE_NUMBER) - TestErrPrintf("Error: Successful thread wrote value %d instead of %d\n", value, WRITE_NUMBER); + if (value != WRITE_NUMBER) + TestErrPrintf("Error: Successful thread wrote value %d instead of %d\n", value, WRITE_NUMBER); - status = H5Dclose(dataset); - CHECK(status, FAIL, "H5Dclose"); - status = H5Fclose(error_file_g); - CHECK(status, FAIL, "H5Fclose"); + status = H5Dclose(dataset); + CHECK(status, FAIL, "H5Dclose"); + status = H5Fclose(error_file_g); + CHECK(status, FAIL, "H5Fclose"); + } /* end if */ + else + HDprintf("Non-native VOL connector used, skipping test\n"); + + status = H5Idec_ref(vol_id); + CHECK(status, FAIL, "H5Idec_ref"); H5TS_attr_destroy(&attribute); } /* end tts_error() */ diff --git a/testpar/Makefile.am b/testpar/Makefile.am index a11099d..0e7898e 100644 --- a/testpar/Makefile.am +++ b/testpar/Makefile.am @@ -42,6 +42,11 @@ testphdf5_SOURCES=testphdf5.c t_dset.c t_file.c t_file_image.c t_mdset.c \ # The tests all depend on the hdf5 library and the test library LDADD = $(LIBH5TEST) $(LIBHDF5) +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + # Temporary files # MPItest.h5 is from t_mpi # Para*.h5 are from testphdf diff --git a/testpar/t_cache.c b/testpar/t_cache.c index 41c95e2..50e6d50 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -24,6 +24,7 @@ #include "H5ACpkg.h" #include "H5Cpkg.h" +#include "H5CXprivate.h" #include "H5Fpkg.h" #include "H5Iprivate.h" #include "H5MFprivate.h" diff --git a/tools/Makefile.am b/tools/Makefile.am index b0c33ed..c53ecd6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -24,4 +24,9 @@ CONFIG=ordered # All subdirectories SUBDIRS=lib src test +# Test with just the native connector, with a single pass-through connector +# and with a doubly-stacked pass-through. +VOL_LIST = native "pass_through under_vol=0;under_info={}" \ + "pass_through under_vol=505;under_info={under_vol=0;under_info={}}" + include $(top_srcdir)/config/conclude.am diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index af5d547..e1c02cf 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -40,7 +40,9 @@ LS='ls' AWK='awk' # Skip plugin module to test missing filter -ENVCMD="env HDF5_PLUGIN_PRELOAD=::" +# Also reset the VOL connector to only use the native connector, because of the +# error stack checking. QAK - 2019/03/09 +ENVCMD="env HDF5_PLUGIN_PRELOAD=:: HDF5_VOL_CONNECTOR=native" WORDS_BIGENDIAN="@WORDS_BIGENDIAN@" @@ -754,7 +756,7 @@ TOOLTEST4() { TESTING $DUMPER $@ ( cd $TESTDIR - $RUNSERIAL $DUMPER_BIN "$@" + $ENVCMD $RUNSERIAL $DUMPER_BIN "$@" ) >$actual 2>$actual_err # save actual and actual_err in case they are needed later. diff --git a/tools/test/h5repack/h5repack.sh.in b/tools/test/h5repack/h5repack.sh.in index a36eb08..282ba76 100644 --- a/tools/test/h5repack/h5repack.sh.in +++ b/tools/test/h5repack/h5repack.sh.in @@ -48,6 +48,10 @@ DIRNAME='dirname' LS='ls' AWK='awk' +# Reset the VOL connector to only use the native connector, because of the +# error stack checking. QAK - 2019/03/09 +ENVCMD="env HDF5_VOL_CONNECTOR=native" + H5DETECTSZIP=testh5repack_detect_szip H5DETECTSZIP_BIN=`pwd`/$H5DETECTSZIP @@ -284,7 +288,7 @@ TOOLTEST() TESTING $H5REPACK $@ ( cd $TESTDIR - $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + $ENVCMD $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile ) RET=$? if [ $RET != 0 ] ; then @@ -716,7 +720,7 @@ TOOLTESTM() { TESTING $H5REPACK $@ ( cd $TESTDIR - $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + $ENVCMD $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile ) >$actual 2>$actual_err # save actual and actual_err in case they are needed later. -- cgit v0.12 From 7c927a35902d50a03088c56efb9e0ad773500d02 Mon Sep 17 00:00:00 2001 From: "M. Scot Breitenfeld" Date: Mon, 11 Mar 2019 11:32:49 -0500 Subject: added more tests --- fortran/src/H5VLff.F90 | 42 +++++++++++++++++++++---------- fortran/src/H5_f.c | 63 +++++++++++++++++++++++----------------------- fortran/src/H5_ff.F90 | 65 ++++++++++++++++++++++++------------------------ fortran/src/HDF5.F90 | 1 + fortran/test/Makefile.am | 24 ++++++++++++++++++ 5 files changed, 117 insertions(+), 78 deletions(-) diff --git a/fortran/src/H5VLff.F90 b/fortran/src/H5VLff.F90 index 1e0dafb..5185c22 100644 --- a/fortran/src/H5VLff.F90 +++ b/fortran/src/H5VLff.F90 @@ -96,7 +96,7 @@ CONTAINS SUBROUTINE H5VLregister_connector_by_value_f(connector_value, vol_id, hdferr, vipl_id) IMPLICIT NONE - INTEGER :: connector_value + INTEGER, INTENT(IN) :: connector_value INTEGER(HID_T), INTENT(OUT) :: vol_id INTEGER, INTENT(OUT) :: hdferr INTEGER(HID_T), OPTIONAL, INTENT(IN) :: vipl_id @@ -108,7 +108,7 @@ CONTAINS BIND(C,NAME='H5VLregister_connector_by_value') IMPORT :: HID_T IMPORT :: C_INT - INTEGER(C_INT) :: connector_value + INTEGER(C_INT), VALUE :: connector_value INTEGER(HID_T), INTENT(IN), VALUE :: vipl_id END FUNCTION H5VLregister_connector_by_value END INTERFACE @@ -174,7 +174,7 @@ CONTAINS ! H5VLis_connector_registered_f ! ! PURPOSE -! Tests whether a VOL class has been registered or not. +! Retrieves the ID for a registered VOL connector. ! ! INPUTS ! cls - @@ -202,8 +202,10 @@ CONTAINS c_name = TRIM(name)//C_NULL_CHAR vol_id = H5VLget_connector_id(c_name) - hdferr = 0 - IF(vol_id.LT.0) hdferr = H5I_INVALID_HID_F + IF(vol_id.LT.0)THEN + hdferr = -1 + vol_id = H5I_INVALID_HID_F + ENDIF END SUBROUTINE H5VLget_connector_id_f @@ -215,29 +217,34 @@ CONTAINS INTEGER(SIZE_T), OPTIONAL :: name_len !***** CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(1:LEN(name)+1), TARGET :: c_name + INTEGER(SIZE_T) :: l TYPE(C_PTR) :: f_ptr INTERFACE INTEGER(SIZE_T) FUNCTION H5VLget_connector_name(obj_id, name, size) BIND(C,NAME='H5VLget_connector_name') - IMPORT :: HID_T, SIZE_T, C_PTR + IMPORT :: HID_T, SIZE_T, C_PTR, C_CHAR IMPLICIT NONE INTEGER(HID_T) , INTENT(IN), VALUE :: obj_id - TYPE(C_PTR), VALUE :: name + CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) :: name + ! TYPE(C_PTR), value :: name INTEGER(SIZE_T), INTENT(IN), VALUE :: size END FUNCTION H5VLget_connector_name END INTERFACE hdferr = 0 IF(PRESENT(name_len))THEN - name_len = INT(H5VLget_connector_name(obj_id, C_NULL_PTR, 0_SIZE_T), SIZE_T) + name_len = INT(H5VLget_connector_name(obj_id, c_name, 0_SIZE_T), SIZE_T) IF(name_len.LT.0) hdferr = H5I_INVALID_HID_F ELSE - f_ptr = C_LOC(c_name(1)(1:1)) - - IF(INT(H5VLget_connector_name(obj_id, f_ptr, INT(LEN(name)+1,SIZE_T)), SIZE_T).LT.0)THEN + ! f_ptr = C_LOC(c_name(1)(1:1)) + PRINT*,LEN(name)+1 + l = INT(LEN(name)+1,SIZE_T) + IF(INT(H5VLget_connector_name(obj_id, c_name, l), SIZE_T).LT.0)THEN hdferr = H5I_INVALID_HID_F ELSE + PRINT*,c_name CALL HD5c2fstring(name,c_name,LEN(name)) + PRINT*,"name", name ENDIF ENDIF @@ -310,8 +317,17 @@ CONTAINS END SUBROUTINE H5VLunregister_connector_f -! H5VLcmp_connector_cls - + !--------------------------------------------------------------------------- + ! Function: H5VLcmp_connector_cls_f + ! + ! Purpose: Compares two connector classes (based on their value field) + ! + ! Return: Success: Non-negative, *cmp set to a value like strcmp + ! + ! Failure: Negative, *cmp unset + ! + !--------------------------------------------------------------------------- + SUBROUTINE H5VLcmp_connector_cls_f(cmp, connector_id1, connector_id2, hdferr) IMPLICIT NONE INTEGER, INTENT(OUT), TARGET :: cmp diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index bd8998e..fdf4b9e 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -720,38 +720,37 @@ h5init_flags_c( int_f *h5d_flags, size_t_f *h5d_size_flags, h5vl_flags[32] = (int_f)H5VL_FILE_MOUNT; h5vl_flags[33] = (int_f)H5VL_FILE_UNMOUNT; h5vl_flags[34] = (int_f)H5VL_FILE_IS_ACCESSIBLE; - h5vl_flags[35] = (int_f)H5VL_FILE_CACHE_VOL_CONN; - h5vl_flags[36] = (int_f)H5VL_GROUP_GET_GCPL; - h5vl_flags[37] = (int_f)H5VL_GROUP_GET_INFO; - h5vl_flags[38] = (int_f)H5VL_GROUP_FLUSH; - h5vl_flags[39] = (int_f)H5VL_GROUP_REFRESH; - h5vl_flags[40] = (int_f)H5VL_LINK_CREATE_HARD; - h5vl_flags[41] = (int_f)H5VL_LINK_CREATE_SOFT; - h5vl_flags[42] = (int_f)H5VL_LINK_CREATE_UD; - h5vl_flags[43] = (int_f)H5VL_LINK_GET_INFO; - h5vl_flags[44] = (int_f)H5VL_LINK_GET_NAME; - h5vl_flags[45] = (int_f)H5VL_LINK_GET_VAL; - h5vl_flags[46] = (int_f)H5VL_LINK_DELETE; - h5vl_flags[47] = (int_f)H5VL_LINK_EXISTS; - h5vl_flags[48] = (int_f)H5VL_LINK_ITER; - h5vl_flags[49] = (int_f)H5VL_REF_GET_NAME; - h5vl_flags[50] = (int_f)H5VL_REF_GET_REGION; - h5vl_flags[51] = (int_f)H5VL_REF_GET_TYPE; - h5vl_flags[52] = (int_f)H5VL_ID_GET_NAME; - h5vl_flags[53] = (int_f)H5VL_OBJECT_CHANGE_REF_COUNT; - h5vl_flags[54] = (int_f)H5VL_OBJECT_EXISTS; - h5vl_flags[55] = (int_f)H5VL_OBJECT_VISIT; - h5vl_flags[56] = (int_f)H5VL_REF_CREATE; - h5vl_flags[57] = (int_f)H5VL_OBJECT_FLUSH; - h5vl_flags[58] = (int_f)H5VL_OBJECT_REFRESH; - h5vl_flags[59] = (int_f)H5VL_REQUEST_WAITANY; - h5vl_flags[60] = (int_f)H5VL_REQUEST_WAITSOME; - h5vl_flags[61] = (int_f)H5VL_REQUEST_WAITALL; - h5vl_flags[62] = (int_f)H5VL_OBJECT_BY_SELF; - h5vl_flags[63] = (int_f)H5VL_OBJECT_BY_NAME; - h5vl_flags[64] = (int_f)H5VL_OBJECT_BY_IDX; - h5vl_flags[65] = (int_f)H5VL_OBJECT_BY_ADDR; - h5vl_flags[66] = (int_f)H5VL_OBJECT_BY_REF; + h5vl_flags[35] = (int_f)H5VL_GROUP_GET_GCPL; + h5vl_flags[36] = (int_f)H5VL_GROUP_GET_INFO; + h5vl_flags[37] = (int_f)H5VL_GROUP_FLUSH; + h5vl_flags[38] = (int_f)H5VL_GROUP_REFRESH; + h5vl_flags[39] = (int_f)H5VL_LINK_CREATE_HARD; + h5vl_flags[40] = (int_f)H5VL_LINK_CREATE_SOFT; + h5vl_flags[41] = (int_f)H5VL_LINK_CREATE_UD; + h5vl_flags[42] = (int_f)H5VL_LINK_GET_INFO; + h5vl_flags[43] = (int_f)H5VL_LINK_GET_NAME; + h5vl_flags[44] = (int_f)H5VL_LINK_GET_VAL; + h5vl_flags[45] = (int_f)H5VL_LINK_DELETE; + h5vl_flags[46] = (int_f)H5VL_LINK_EXISTS; + h5vl_flags[47] = (int_f)H5VL_LINK_ITER; + h5vl_flags[48] = (int_f)H5VL_REF_GET_NAME; + h5vl_flags[49] = (int_f)H5VL_REF_GET_REGION; + h5vl_flags[50] = (int_f)H5VL_REF_GET_TYPE; + h5vl_flags[51] = (int_f)H5VL_ID_GET_NAME; + h5vl_flags[52] = (int_f)H5VL_OBJECT_CHANGE_REF_COUNT; + h5vl_flags[53] = (int_f)H5VL_OBJECT_EXISTS; + h5vl_flags[54] = (int_f)H5VL_OBJECT_VISIT; + h5vl_flags[55] = (int_f)H5VL_REF_CREATE; + h5vl_flags[56] = (int_f)H5VL_OBJECT_FLUSH; + h5vl_flags[57] = (int_f)H5VL_OBJECT_REFRESH; + h5vl_flags[58] = (int_f)H5VL_REQUEST_WAITANY; + h5vl_flags[59] = (int_f)H5VL_REQUEST_WAITSOME; + h5vl_flags[60] = (int_f)H5VL_REQUEST_WAITALL; + h5vl_flags[61] = (int_f)H5VL_OBJECT_BY_SELF; + h5vl_flags[62] = (int_f)H5VL_OBJECT_BY_NAME; + h5vl_flags[63] = (int_f)H5VL_OBJECT_BY_IDX; + h5vl_flags[64] = (int_f)H5VL_OBJECT_BY_ADDR; + h5vl_flags[65] = (int_f)H5VL_OBJECT_BY_REF; /* * H5Z flags */ diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90 index 2adc6aa..0d82f42 100644 --- a/fortran/src/H5_ff.F90 +++ b/fortran/src/H5_ff.F90 @@ -133,7 +133,7 @@ MODULE H5LIB ! H5VL flags declaration ! - INTEGER, PARAMETER :: H5VL_FLAGS_LEN = 67 + INTEGER, PARAMETER :: H5VL_FLAGS_LEN = 66 INTEGER, DIMENSION(1:H5VL_FLAGS_LEN) :: H5VL_flags ! @@ -647,38 +647,37 @@ CONTAINS H5VL_FILE_MOUNT_F = H5VL_flags(33) H5VL_FILE_UNMOUNT_F = H5VL_flags(34) H5VL_FILE_IS_ACCESSIBLE_F = H5VL_flags(35) - H5VL_FILE_CACHE_VOL_CONN_F = H5VL_flags(36) - H5VL_GROUP_GET_GCPL_F = H5VL_flags(37) - H5VL_GROUP_GET_INFO_F = H5VL_flags(38) - H5VL_GROUP_FLUSH_F = H5VL_flags(39) - H5VL_GROUP_REFRESH_F = H5VL_flags(40) - H5VL_LINK_CREATE_HARD_F = H5VL_flags(41) - H5VL_LINK_CREATE_SOFT_F = H5VL_flags(42) - H5VL_LINK_CREATE_UD_F = H5VL_flags(43) - H5VL_LINK_GET_INFO_F = H5VL_flags(44) - H5VL_LINK_GET_NAME_F = H5VL_flags(45) - H5VL_LINK_GET_VAL_F = H5VL_flags(46) - H5VL_LINK_DELETE_F = H5VL_flags(47) - H5VL_LINK_EXISTS_F = H5VL_flags(48) - H5VL_LINK_ITER_F = H5VL_flags(49) - H5VL_REF_GET_NAME_F = H5VL_flags(50) - H5VL_REF_GET_REGION_F = H5VL_flags(51) - H5VL_REF_GET_TYPE_F = H5VL_flags(52) - H5VL_ID_GET_NAME_F = H5VL_flags(53) - H5VL_OBJECT_CHANGE_REF_COUNT_F = H5VL_flags(54) - H5VL_OBJECT_EXISTS_F = H5VL_flags(55) - H5VL_OBJECT_VISIT_F = H5VL_flags(56) - H5VL_REF_CREATE_F = H5VL_flags(57) - H5VL_OBJECT_FLUSH_F = H5VL_flags(58) - H5VL_OBJECT_REFRESH_F = H5VL_flags(59) - H5VL_REQUEST_WAITANY_F = H5VL_flags(60) - H5VL_REQUEST_WAITSOME_F = H5VL_flags(61) - H5VL_REQUEST_WAITALL_F = H5VL_flags(62) - H5VL_OBJECT_BY_SELF_F = H5VL_flags(63) - H5VL_OBJECT_BY_NAME_F = H5VL_flags(64) - H5VL_OBJECT_BY_IDX_F = H5VL_flags(65) - H5VL_OBJECT_BY_ADDR_F = H5VL_flags(66) - H5VL_OBJECT_BY_REF_F = H5VL_flags(67) + H5VL_GROUP_GET_GCPL_F = H5VL_flags(36) + H5VL_GROUP_GET_INFO_F = H5VL_flags(37) + H5VL_GROUP_FLUSH_F = H5VL_flags(38) + H5VL_GROUP_REFRESH_F = H5VL_flags(39) + H5VL_LINK_CREATE_HARD_F = H5VL_flags(40) + H5VL_LINK_CREATE_SOFT_F = H5VL_flags(41) + H5VL_LINK_CREATE_UD_F = H5VL_flags(42) + H5VL_LINK_GET_INFO_F = H5VL_flags(43) + H5VL_LINK_GET_NAME_F = H5VL_flags(44) + H5VL_LINK_GET_VAL_F = H5VL_flags(45) + H5VL_LINK_DELETE_F = H5VL_flags(46) + H5VL_LINK_EXISTS_F = H5VL_flags(47) + H5VL_LINK_ITER_F = H5VL_flags(48) + H5VL_REF_GET_NAME_F = H5VL_flags(49) + H5VL_REF_GET_REGION_F = H5VL_flags(50) + H5VL_REF_GET_TYPE_F = H5VL_flags(51) + H5VL_ID_GET_NAME_F = H5VL_flags(52) + H5VL_OBJECT_CHANGE_REF_COUNT_F = H5VL_flags(53) + H5VL_OBJECT_EXISTS_F = H5VL_flags(54) + H5VL_OBJECT_VISIT_F = H5VL_flags(55) + H5VL_REF_CREATE_F = H5VL_flags(56) + H5VL_OBJECT_FLUSH_F = H5VL_flags(57) + H5VL_OBJECT_REFRESH_F = H5VL_flags(58) + H5VL_REQUEST_WAITANY_F = H5VL_flags(59) + H5VL_REQUEST_WAITSOME_F = H5VL_flags(60) + H5VL_REQUEST_WAITALL_F = H5VL_flags(61) + H5VL_OBJECT_BY_SELF_F = H5VL_flags(62) + H5VL_OBJECT_BY_NAME_F = H5VL_flags(63) + H5VL_OBJECT_BY_IDX_F = H5VL_flags(64) + H5VL_OBJECT_BY_ADDR_F = H5VL_flags(65) + H5VL_OBJECT_BY_REF_F = H5VL_flags(66) ! ! H5Z flags ! diff --git a/fortran/src/HDF5.F90 b/fortran/src/HDF5.F90 index 0370224..fe38b7d 100644 --- a/fortran/src/HDF5.F90 +++ b/fortran/src/HDF5.F90 @@ -38,6 +38,7 @@ MODULE HDF5 USE H5O USE H5P USE H5R + USE H5VL USE H5Z USE H5_gen USE H5LIB diff --git a/fortran/test/Makefile.am b/fortran/test/Makefile.am index 8613cf9..ef6cd7e 100644 --- a/fortran/test/Makefile.am +++ b/fortran/test/Makefile.am @@ -30,14 +30,35 @@ noinst_LTLIBRARIES=libh5test_fortran.la # want to build a shared C library and a static Fortran library. If so, # pass the -static flag to the library linker. if FORTRAN_SHARED_CONDITIONAL + TEST_SCRIPT = test_vol_connector.sh + SCRIPT_DEPEND = vol_connector$(EXEEXT) else AM_LDFLAGS+=-static endif +check_SCRIPTS = $(TEST_SCRIPT) + # Our main targets, the tests themselves TEST_PROG=fortranlib_test fflush1 fflush2 fortranlib_test_1_8 fortranlib_test_F03 check_PROGRAMS=$(TEST_PROG) +if FORTRAN_SHARED_CONDITIONAL + check_PROGRAMS+= vol_connector +endif + +if FORTRAN_SHARED_CONDITIONAL + # The libh5test library provides common support code for the tests. + # The filter_plugin* libraries are for use in filter_plugin.c. + # Build them as shared libraries if that option was enabled in configure. + noinst_LTLIBRARIES += libnull_vol_connector.la + + # VOL plugin test libraries + # + # null_vol_connector is used for testing basic VOL plugin functionality. + libnull_vol_connector_la_SOURCES=null_vol_connector.c + libnull_vol_connector_la_LDFLAGS=$(AM_LDFLAGS) -avoid-version -module -shared -export-dynamic -rpath /nowhere +endif + libh5test_fortran_la_SOURCES = tf_gen.F90 tf.F90 t.c @@ -50,6 +71,7 @@ fortranlib_test_1_8_SOURCES = tH5O.F90 tH5A_1_8.F90 tH5G_1_8.F90 tH5MISC_1_8.F90 fortranlib_test_F03_SOURCES = tH5E_F03.F90 tH5F_F03.F90 tH5L_F03.F90 \ tH5O_F03.F90 tH5P_F03.F90 tH5T_F03.F90 tHDF5_F03.F90 fortranlib_test_F03.F90 +vol_connector_SOURCES=vol_connector.F90 fflush1_SOURCES=fflush1.F90 fflush2_SOURCES=fflush2.F90 @@ -95,6 +117,8 @@ H5_test_buildiface_SOURCES = H5_test_buildiface.F90 H5_test_buildiface_LDADD = +DISTCLEANFILES=test_vol_connector.sh # TODO:CHECK IF WORKS MSB + # fflush2 depends on files created by fflush1 fflush2.chkexe_: fflush1.chkexe_ -- cgit v0.12 From 6682f51a1157dc9e88bd34528fff999aee50ca2a Mon Sep 17 00:00:00 2001 From: "M. Scot Breitenfeld" Date: Mon, 11 Mar 2019 11:34:10 -0500 Subject: add tests --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 30fe725..e40e3c6 100644 --- a/configure.ac +++ b/configure.ac @@ -3551,6 +3551,7 @@ AC_CONFIG_FILES([src/libhdf5.settings fortran/src/Makefile fortran/src/H5fort_type_defines.h fortran/test/Makefile + fortran/test/test_vol_connector.sh fortran/testpar/Makefile fortran/examples/Makefile fortran/examples/run-fortran-ex.sh -- cgit v0.12 From 86598573641dfa27278c9e29df0fa79bd7d8e07f Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 11 Mar 2019 17:29:14 -0500 Subject: Add API routines to retrieve, restore, reset, and free library state. (Primarily for use in the async VOL connector, which has to schedule API operations for future execution and then restore the state of the library when the operation actually executes) --- src/H5CX.c | 266 ++++++++++++++++++++++++++++++++++++--- src/H5CXprivate.h | 18 +++ src/H5VL.c | 159 +++++++++++++++++++++++ src/H5VLint.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/H5VLprivate.h | 14 ++- src/H5VLpublic.h | 4 + 6 files changed, 783 insertions(+), 46 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index c97bdcd..b56d66d 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -64,17 +64,22 @@ #define H5CX_get_my_context() (&H5CX_head_g) #endif /* H5_HAVE_THREADSAFE */ +/* Common macro for the retrieving the pointer to a property list */ +#define H5CX_RETRIEVE_PLIST(PL, FAILVAL) \ + /* Check if the property list is already available */ \ + if(NULL == (*head)->ctx.PL) \ + /* Get the property list pointer */ \ + if(NULL == ((*head)->ctx.PL = (H5P_genplist_t *)H5I_object((*head)->ctx.H5_GLUE(PL,_id)))) \ + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, (FAILVAL), "can't get property list") + /* Common macro for the duplicated code to retrieve properties from a property list */ #define H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD) \ /* Check for default property list */ \ if((*head)->ctx.H5_GLUE(PL,_id) == (DEF_PL)) \ HDmemcpy(&(*head)->ctx.PROP_FIELD, &H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD, sizeof(H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD)); \ else { \ - /* Check if the property list is already available */ \ - if(NULL == (*head)->ctx.PL) \ - /* Get the dataset transfer property list pointer */ \ - if(NULL == ((*head)->ctx.PL = (H5P_genplist_t *)H5I_object((*head)->ctx.H5_GLUE(PL,_id)))) \ - HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "can't get default dataset transfer property list") \ + /* Retrieve the property list */ \ + H5CX_RETRIEVE_PLIST(PL, FAIL) \ \ /* Get the property */ \ if(H5P_get((*head)->ctx.PL, (PROP_NAME), &(*head)->ctx.PROP_FIELD) < 0) \ @@ -108,11 +113,8 @@ \ /* Check if property exists in DXPL */ \ if(!(*head)->ctx.H5_GLUE(PROP_FIELD,_set)) { \ - /* Check if the property list is already available */ \ - if(NULL == (*head)->ctx.dxpl) \ - /* Get the dataset transfer property list pointer */ \ - if(NULL == ((*head)->ctx.dxpl = (H5P_genplist_t *)H5I_object((*head)->ctx.dxpl_id))) \ - HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "can't get default dataset transfer property list") \ + /* Retrieve the dataset transfer property list */ \ + H5CX_RETRIEVE_PLIST(dxpl, FAIL) \ \ if((check_prop = H5P_exist_plist((*head)->ctx.dxpl, PROP_NAME)) < 0) \ HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "error checking for property") \ @@ -129,15 +131,12 @@ /* Macro for the duplicated code to test and set properties for a property list */ #define H5CX_SET_PROP(PROP_NAME, PROP_FIELD) \ if((*head)->ctx.H5_GLUE(PROP_FIELD,_set)) { \ - /* Check if the property list is already available */ \ - if(NULL == (*head)->ctx.dxpl) \ - /* Get the dataset transfer property list pointer */ \ - if(NULL == ((*head)->ctx.dxpl = (H5P_genplist_t *)H5I_object((*head)->ctx.dxpl_id))) \ - HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, NULL, "can't get default dataset transfer property list") \ + /* Retrieve the dataset transfer property list */ \ + H5CX_RETRIEVE_PLIST(dxpl, NULL) \ \ - /* Set the chunk filter mask property */ \ + /* Set the property */ \ if(H5P_set((*head)->ctx.dxpl, PROP_NAME, &(*head)->ctx.PROP_FIELD) < 0) \ - HGOTO_ERROR(H5E_CONTEXT, H5E_CANTSET, NULL, "error setting filter mask xfer property") \ + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTSET, NULL, "error setting data xfer property") \ } /* end if */ #endif /* H5_HAVE_PARALLEL */ @@ -175,7 +174,7 @@ * corresponding property in the property list to be set when the API * context is popped, when returning from the API routine. Note that the * naming of these fields, and _set, is important for the -* H5CX_TEST_SET_PROP and H5CX_SET_PROP macros to work properly. + * H5CX_TEST_SET_PROP and H5CX_SET_PROP macros to work properly. */ typedef struct H5CX_t { /* DXPL */ @@ -378,6 +377,9 @@ static H5CX_dcpl_cache_t H5CX_def_dcpl_cache; /* Declare a static free list to manage H5CX_node_t structs */ H5FL_DEFINE_STATIC(H5CX_node_t); +/* Declare a static free list to manage H5CX_state_t structs */ +H5FL_DEFINE_STATIC(H5CX_state_t); + /*-------------------------------------------------------------------------- @@ -709,6 +711,226 @@ H5CX_push_special(void) /*------------------------------------------------------------------------- + * Function: H5CX_retrieve_state + * + * Purpose: Retrieve the state of an API context, for later resumption. + * + * Note: This routine _only_ tracks the state of API context information + * set before the VOL callback is invoked, not values that are + * set internal to the library. It's main purpose is to provide + * API context state to VOL connectors. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * January 8, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_retrieve_state(H5CX_state_t **api_state) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(head && *head); + HDassert(api_state); + + /* Allocate & clear API context state */ + if(NULL == (*api_state = H5FL_CALLOC(H5CX_state_t))) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTALLOC, FAIL, "unable to allocate new API context state") + + /* Check for non-default DXPL */ + if(H5P_DATASET_XFER_DEFAULT != (*head)->ctx.dxpl_id) { + /* Retrieve the DXPL property list */ + H5CX_RETRIEVE_PLIST(dxpl, FAIL) + + /* Copy the DXPL ID */ + if(((*api_state)->dxpl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.dxpl, FALSE)) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list") + } /* end if */ + else + (*api_state)->dxpl_id = H5P_DATASET_XFER_DEFAULT; + + /* Check for non-default LAPL */ + if(H5P_LINK_ACCESS_DEFAULT != (*head)->ctx.lapl_id) { + /* Retrieve the LAPL property list */ + H5CX_RETRIEVE_PLIST(lapl, FAIL) + + /* Copy the LAPL ID */ + if(((*api_state)->lapl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.lapl, FALSE)) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list") + } /* end if */ + else + (*api_state)->lapl_id = H5P_LINK_ACCESS_DEFAULT; + + /* Keep a reference to the current VOL wrapping context */ + (*api_state)->vol_wrap_ctx = (*head)->ctx.vol_wrap_ctx; + if(NULL != (*api_state)->vol_wrap_ctx) + if(H5VL_inc_vol_wrapper((*api_state)->vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTINC, FAIL, "can't increment refcount on VOL wrapping context") + + /* Keep a copy of the VOL connector property, if there is one */ + if((*head)->ctx.vol_connector_prop_valid && (*head)->ctx.vol_connector_prop.connector_id > 0) { + /* Get the connector property */ + HDmemcpy(&(*api_state)->vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t)); + + /* Check for actual VOL connector property */ + if((*api_state)->vol_connector_prop.connector_id) { + /* Copy connector info, if it exists */ + if((*api_state)->vol_connector_prop.connector_info) { + H5VL_class_t *connector; /* Pointer to connector */ + void *new_connector_info = NULL; /* Copy of connector info */ + + /* Retrieve the connector for the ID */ + if(NULL == (connector = (H5VL_class_t *)H5I_object((*api_state)->vol_connector_prop.connector_id))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Allocate and copy connector info */ + if(H5VL_copy_connector_info(connector, &new_connector_info, (*api_state)->vol_connector_prop.connector_info) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "connector info copy failed") + (*api_state)->vol_connector_prop.connector_info = new_connector_info; + } /* end if */ + + /* Increment the refcount on the connector ID */ + if(H5I_inc_ref((*api_state)->vol_connector_prop.connector_id, FALSE) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTINC, FAIL, "incrementing VOL connector ID failed") + } /* end if */ + } /* end if */ + +#ifdef H5_HAVE_PARALLEL + /* Save parallel I/O settings */ + (*api_state)->coll_metadata_read = (*head)->ctx.coll_metadata_read; +#endif /* H5_HAVE_PARALLEL */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_retrieve_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_restore_state + * + * Purpose: Restore an API context, from a previously retrieved state. + * + * Note: This routine _only_ resets the state of API context information + * set before the VOL callback is invoked, not values that are + * set internal to the library. It's main purpose is to restore + * API context state from VOL connectors. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_restore_state(const H5CX_state_t *api_state) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(head && *head); + HDassert(api_state); + + /* Restore the DXPL info */ + (*head)->ctx.dxpl_id = api_state->dxpl_id; + (*head)->ctx.dxpl = NULL; + + /* Restore the LAPL info */ + (*head)->ctx.lapl_id = api_state->lapl_id; + (*head)->ctx.lapl = NULL; + + /* Restore the VOL wrapper context */ + (*head)->ctx.vol_wrap_ctx = api_state->vol_wrap_ctx; + + /* Restore the VOL connector info */ + if(api_state->vol_connector_prop.connector_id) { + HDmemcpy(&(*head)->ctx.vol_connector_prop, &api_state->vol_connector_prop, sizeof(H5VL_connector_prop_t)); + (*head)->ctx.vol_connector_prop_valid = TRUE; + } /* end if */ + +#ifdef H5_HAVE_PARALLEL + /* Restore parallel I/O settings */ + (*head)->ctx.coll_metadata_read = api_state->coll_metadata_read; +#endif /* H5_HAVE_PARALLEL */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5CX_restore_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_free_state + * + * Purpose: Free a previously retrievedAPI context state + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_free_state(H5CX_state_t *api_state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(api_state); + + /* Release the DXPL */ + if(api_state->dxpl_id != H5P_DATASET_XFER_DEFAULT) + if(H5I_dec_ref(api_state->dxpl_id) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DXPL") + + /* Release the LAPL */ + if(api_state->lapl_id != H5P_LINK_ACCESS_DEFAULT) + if(H5I_dec_ref(api_state->lapl_id) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LAPL") + + /* Release the VOL wrapper context */ + if(api_state->vol_wrap_ctx) + if(H5VL_dec_vol_wrapper(api_state->vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on VOL wrapping context") + + /* Release the VOL connector property, if it was set */ + if(api_state->vol_connector_prop.connector_id) { + /* Clean up any VOL connector info */ + if(api_state->vol_connector_prop.connector_info) { + H5VL_class_t *connector; /* Pointer to connector */ + + /* Retrieve the connector for the ID */ + if(NULL == (connector = (H5VL_class_t *)H5I_object(api_state->vol_connector_prop.connector_id))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Free the connector info */ + if(H5VL_free_connector_info(connector, api_state->vol_connector_prop.connector_info) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTRELEASE, FAIL, "unable to release VOL connector info object") + } /* end if */ + + /* Decrement connector ID */ + if(H5I_dec_ref(api_state->vol_connector_prop.connector_id) < 0) + HDONE_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't close VOL connector ID") + } /* end if */ + + /* Free the state */ + api_state = H5FL_FREE(H5CX_state_t, api_state); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_free_state() */ + + +/*------------------------------------------------------------------------- * Function: H5CX_is_def_dxpl * * Purpose: Checks if the API context is using the library's default DXPL @@ -951,6 +1173,7 @@ H5CX_set_loc(hid_t #endif /* H5_HAVE_PARALLEL */ loc_id) { +#ifdef H5_HAVE_PARALLEL H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ herr_t ret_value = SUCCEED; /* Return value */ @@ -959,7 +1182,6 @@ H5CX_set_loc(hid_t /* Sanity check */ HDassert(head && *head); -#ifdef H5_HAVE_PARALLEL /* Set collective metadata read flag */ (*head)->ctx.coll_metadata_read = TRUE; @@ -980,10 +1202,14 @@ H5CX_set_loc(hid_t if(mpi_comm != MPI_COMM_NULL) MPI_Barrier(mpi_comm); } /* end if */ -#endif /* H5_HAVE_PARALLEL */ done: FUNC_LEAVE_NOAPI(ret_value) +#else /* H5_HAVE_PARALLEL */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(SUCCEED) +#endif /* H5_HAVE_PARALLEL */ } /* end H5CX_set_loc() */ diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index 51ee96b..80f1ac4 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -39,6 +39,19 @@ /* Library Private Typedefs */ /****************************/ +/* API context state */ +typedef struct H5CX_state_t { + hid_t dxpl_id; /* DXPL for operation */ + hid_t lapl_id; /* LAPL for operation */ + void *vol_wrap_ctx; /* VOL connector's "wrap context" for creating IDs */ + H5VL_connector_prop_t vol_connector_prop; /* VOL connector property */ + +#ifdef H5_HAVE_PARALLEL + /* Internal: Parallel I/O settings */ + hbool_t coll_metadata_read; /* Whether to use collective I/O for metadata read */ +#endif /* H5_HAVE_PARALLEL */ +} H5CX_state_t; + /*****************************/ /* Library-private Variables */ @@ -57,6 +70,11 @@ H5_DLL herr_t H5CX_pop(void); H5_DLL void H5CX_push_special(void); H5_DLL hbool_t H5CX_is_def_dxpl(void); +/* API context state routines */ +H5_DLL herr_t H5CX_retrieve_state(H5CX_state_t **api_state); +H5_DLL herr_t H5CX_restore_state(const H5CX_state_t *api_state); +H5_DLL herr_t H5CX_free_state(H5CX_state_t *api_state); + /* "Setter" routines for API context info */ H5_DLL void H5CX_set_dxpl(hid_t dxpl_id); H5_DLL void H5CX_set_lapl(hid_t lapl_id); diff --git a/src/H5VL.c b/src/H5VL.c index aa276ec..334de88 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -488,6 +488,9 @@ done: * * Purpose: Compares two connector classes (based on their value field) * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * * Return: Success: Non-negative, *cmp set to a value like strcmp * * Failure: Negative, *cmp unset @@ -587,3 +590,159 @@ done: FUNC_LEAVE_API(ret_value) } /* H5VLobject() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLretrieve_lib_state + * + * Purpose: Retrieves a copy of the internal state of the HDF5 library, + * so that it can be restored later. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Return: Success: Non-negative, *state set + * Failure: Negative, *state unset + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLretrieve_lib_state(void **state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ + FUNC_ENTER_API_NOINIT + H5TRACE1("e", "**x", state); + + /* Check args */ + if(NULL == state) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer") + + /* Retrieve the library state */ + if(H5VL_retrieve_lib_state(state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve library state") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* H5VLretrieve_lib_state() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLrestore_lib_state + * + * Purpose: Restores the internal state of the HDF5 library. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLrestore_lib_state(const void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ + FUNC_ENTER_API_NOINIT + H5TRACE1("e", "*x", state); + + /* Check args */ + if(NULL == state) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer") + + /* Restore the library state */ + if(H5VL_restore_lib_state(state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't restore library state") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* H5VLrestore_lib_state() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLreset_lib_state + * + * Purpose: Resets the internal state of the HDF5 library, undoing the + * affects of H5VLrestore_lib_state. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Note: This routine must be called as a "pair" with + * H5VLrestore_lib_state. It can be called before / after / + * independently of H5VLfree_lib_state. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Saturday, February 23, 2019 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLreset_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ + FUNC_ENTER_API_NOINIT + H5TRACE0("e",""); + + /* Reset the library state */ + if(H5VL_reset_lib_state() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* H5VLreset_lib_state() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLfree_lib_state + * + * Purpose: Free a retrieved library state. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Note: This routine must be called as a "pair" with + * H5VLretrieve_lib_state. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLfree_lib_state(void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "*x", state); + + /* Check args */ + if(NULL == state) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer") + + /* Free the library state */ + if(H5VL_free_lib_state(state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free library state") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLfree_lib_state() */ + diff --git a/src/H5VLint.c b/src/H5VLint.c index 5aa25d2..7aeea02 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -51,7 +51,7 @@ /* Object wrapping context info */ typedef struct H5VL_wrap_ctx_t { unsigned rc; /* Ref. count for the # of times the context was set / reset */ - const H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */ + H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */ void *obj_wrap_ctx; /* "wrap context" for outermost connector */ } H5VL_wrap_ctx_t; @@ -68,7 +68,10 @@ static herr_t H5VL__free_cls(H5VL_class_t *cls); static void *H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); +static int64_t H5VL__conn_inc_rc(H5VL_t *connector); +static int64_t H5VL__conn_dec_rc(H5VL_t *connector); static void *H5VL__object(hid_t id, H5I_type_t obj_type); +static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx); /*********************/ @@ -317,7 +320,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t new_vol_obj->data = object; /* Bump the reference count on the VOL connector */ - vol_connector->nrefs++; + H5VL__conn_inc_rc(vol_connector); /* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */ if(H5I_DATATYPE == type) { @@ -550,6 +553,76 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL__conn_inc_rc + * + * Purpose: Wrapper to increment the ref. count on a connector. + * + * Return: Current ref. count (can't fail) + * + * Programmer: Quincey Koziol + * February 23, 2019 + * + *------------------------------------------------------------------------- + */ +static int64_t +H5VL__conn_inc_rc(H5VL_t *connector) +{ + FUNC_ENTER_STATIC_NOERR + + /* Check arguments */ + HDassert(connector); + + /* Increment refcount for connector */ + connector->nrefs++; + + FUNC_LEAVE_NOAPI(connector->nrefs) +} /* end H5VL__conn_inc_rc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__conn_dec_rc + * + * Purpose: Wrapper to decrement the ref. count on a connector. + * + * Return: Current ref. count (>=0) on success, <0 on failure + * + * Programmer: Quincey Koziol + * February 23, 2019 + * + *------------------------------------------------------------------------- + */ +static int64_t +H5VL__conn_dec_rc(H5VL_t *connector) +{ + int64_t ret_value = -1; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + HDassert(connector); + + /* Decrement refcount for connector */ + connector->nrefs--; + + /* Check for last reference */ + if(0 == connector->nrefs) { + if(H5I_dec_ref(connector->id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + H5FL_FREE(H5VL_t, connector); + + /* Set return value */ + ret_value = 0; + } /* end if */ + else + /* Set return value */ + ret_value = connector->nrefs; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__conn_dec_rc() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_free_object * * Purpose: Wrapper to unregister an object ID with a VOL aux struct @@ -562,20 +635,16 @@ done: herr_t H5VL_free_object(H5VL_object_t *vol_obj) { - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(SUCCEED) + FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ HDassert(vol_obj); - vol_obj->connector->nrefs --; - - if(0 == vol_obj->connector->nrefs) { - if(H5I_dec_ref(vol_obj->connector->id) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") - vol_obj->connector = H5FL_FREE(H5VL_t, vol_obj->connector); - } /* end if */ + /* Decrement refcount on connector */ + if(H5VL__conn_dec_rc(vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") vol_obj = H5FL_FREE(H5VL_object_t, vol_obj); @@ -952,6 +1021,189 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_retrieve_lib_state + * + * Purpose: Retrieve the state of the library. + * + * Note: Currently just retrieves the API context state, but could be + * expanded in the future. + * + * Return: Success: Non-negative, *state set + * Failure: Negative, *state unset + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_retrieve_lib_state(void **state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Retrieve the API context state */ + if(H5CX_retrieve_state((H5CX_state_t **)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_retrieve_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_restore_lib_state + * + * Purpose: Restore the state of the library. + * + * Note: Currently just restores the API context state, but could be + * expanded in the future. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_restore_lib_state(const void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Push a new API context on the stack */ + if(H5CX_push() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") + + /* Restore the API context state */ + if(H5CX_restore_state((const H5CX_state_t *)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_restore_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_reset_lib_state + * + * Purpose: Reset the state of the library, undoing affects of + * H5VL_restore_lib_state. + * + * Note: Currently just resets the API context state, but could be + * expanded in the future. + * + * Note: This routine must be called as a "pair" with + * H5VL_restore_lib_state. It can be called before / after / + * independently of H5VL_free_lib_state. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, February 23, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_reset_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Pop the API context off the stack */ + if(H5CX_pop() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't pop API context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_reset_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_free_lib_state + * + * Purpose: Free a library state. + * + * Note: This routine must be called as a "pair" with + * H5VL_retrieve_lib_state. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_free_lib_state(void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Free the API context state */ + if(H5CX_free_state((H5CX_state_t *)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_free_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__free_vol_wrapper + * + * Purpose: Free object wrapping context for VOL connector + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(vol_wrap_ctx); + HDassert(0 == vol_wrap_ctx->rc); + HDassert(vol_wrap_ctx->connector); + HDassert(vol_wrap_ctx->connector->cls); + + /* If there is a VOL connector object wrapping context, release it */ + if(vol_wrap_ctx->obj_wrap_ctx) + /* Release the VOL connector's object wrapping context */ + if((*vol_wrap_ctx->connector->cls->wrap_cls.free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release connector's object wrapping context") + + /* Decrement refcount on connector */ + if(H5VL__conn_dec_rc(vol_wrap_ctx->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + + /* Release object wrapping context */ + H5FL_FREE(H5VL_wrap_ctx_t, vol_wrap_ctx); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__free_vol_wrapper() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_set_vol_wrapper * * Purpose: Set up object wrapping context for current VOL connector @@ -961,7 +1213,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) +H5VL_set_vol_wrapper(void *obj, H5VL_t *connector) { H5VL_wrap_ctx_t *vol_wrap_ctx = NULL; /* Object wrapping context */ void *obj_wrap_ctx = NULL; /* VOL connector's wrapping context */ @@ -993,8 +1245,11 @@ H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) if(NULL == (vol_wrap_ctx = H5FL_MALLOC(H5VL_wrap_ctx_t))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate VOL wrap context") + /* Increment the outstanding objects that are using the connector */ + H5VL__conn_inc_rc(connector); + /* Set up VOL object wrapper context */ - vol_wrap_ctx->rc = 1;; + vol_wrap_ctx->rc = 1; vol_wrap_ctx->connector = connector; vol_wrap_ctx->obj_wrap_ctx = obj_wrap_ctx; } /* end if */ @@ -1016,6 +1271,80 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_inc_vol_wrapper + * + * Purpose: Increment refcount on object wrapping context + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_inc_vol_wrapper(void *_vol_wrap_ctx) +{ + H5VL_wrap_ctx_t *vol_wrap_ctx = (H5VL_wrap_ctx_t *)_vol_wrap_ctx; /* VOL object wrapping context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check for valid, active VOL object wrap context */ + if(NULL == vol_wrap_ctx) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "no VOL object wrap context?") + if(0 == vol_wrap_ctx->rc) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "bad VOL object wrap context refcount?") + + /* Increment ref count on wrapping context */ + vol_wrap_ctx->rc++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_inc_vol_wrapper() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dec_vol_wrapper + * + * Purpose: Decrement refcount on object wrapping context, releasing it + * if the refcount drops to zero. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dec_vol_wrapper(void *_vol_wrap_ctx) +{ + H5VL_wrap_ctx_t *vol_wrap_ctx = (H5VL_wrap_ctx_t *)_vol_wrap_ctx; /* VOL object wrapping context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check for valid, active VOL object wrap context */ + if(NULL == vol_wrap_ctx) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "no VOL object wrap context?") + if(0 == vol_wrap_ctx->rc) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "bad VOL object wrap context refcount?") + + /* Decrement ref count on wrapping context */ + vol_wrap_ctx->rc--; + + /* Release context if the ref count drops to zero */ + if(0 == vol_wrap_ctx->rc) + if(H5VL__free_vol_wrapper(vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL object wrapping context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dec_vol_wrapper() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_reset_vol_wrapper * * Purpose: Reset object wrapping context for current VOL connector @@ -1045,25 +1374,18 @@ H5VL_reset_vol_wrapper(void) /* Release context if the ref count drops to zero */ if(0 == vol_wrap_ctx->rc) { - /* If there is a VOL connector object wrapping context, release it */ - if(vol_wrap_ctx->obj_wrap_ctx) { - /* Release the VOL connector's object wrapping context */ - if((*vol_wrap_ctx->connector->cls->wrap_cls.free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release connector's object wrapping context") - } /* end if */ - /* Release object wrapping context */ - H5FL_FREE(H5VL_wrap_ctx_t, vol_wrap_ctx); + if(H5VL__free_vol_wrapper(vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL object wrapping context") /* Reset the wrapper context */ if(H5CX_set_vol_wrap_ctx(NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL object wrap context") } /* end if */ - else { + else /* Save the updated wrapper context */ if(H5CX_set_vol_wrap_ctx(vol_wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL object wrap context") - } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 283c77a..ac77ee0 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -41,8 +41,8 @@ typedef struct H5VL_object_t { /* Internal structure to hold the connector ID & info for FAPLs */ typedef struct H5VL_connector_prop_t { - hid_t connector_id; /* VOL connector's ID */ - const void *connector_info; /* VOL connector info, for open callbacks */ + hid_t connector_id; /* VOL connector's ID */ + void *connector_info; /* VOL connector info, for open callbacks */ } H5VL_connector_prop_t; /* Which kind of VOL connector field to use for searching */ @@ -92,11 +92,19 @@ H5_DLL herr_t H5VL_free_object(H5VL_object_t *obj); H5_DLL herr_t H5VL_get_wrap_ctx(const H5VL_class_t *connector, void *obj, void **wrap_ctx); H5_DLL herr_t H5VL_free_wrap_ctx(const H5VL_class_t *connector, void *wrap_ctx); -H5_DLL herr_t H5VL_set_vol_wrapper(void *obj, const H5VL_t *vol_connector); +H5_DLL herr_t H5VL_set_vol_wrapper(void *obj, H5VL_t *vol_connector); +H5_DLL herr_t H5VL_inc_vol_wrapper(void *vol_wrap_ctx); +H5_DLL herr_t H5VL_dec_vol_wrapper(void *vol_wrap_ctx); H5_DLL herr_t H5VL_reset_vol_wrapper(void); H5_DLL void * H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx, void *obj, H5I_type_t obj_type); +/* Library state functions */ +H5_DLL herr_t H5VL_retrieve_lib_state(void **state); +H5_DLL herr_t H5VL_restore_lib_state(const void *state); +H5_DLL herr_t H5VL_reset_lib_state(void); +H5_DLL herr_t H5VL_free_lib_state(void *state); + /* ID registration functions */ H5_DLL hid_t H5VL_register(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t app_ref); H5_DLL hid_t H5VL_wrap_register(H5I_type_t type, void *obj, hbool_t app_ref); diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 72e69b8..cf6246b 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -450,6 +450,10 @@ H5_DLL herr_t H5VLunregister_connector(hid_t connector_id); H5_DLL herr_t H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2); H5_DLL hid_t H5VLwrap_register(void *obj, H5I_type_t type); H5_DLL void *H5VLobject(hid_t obj_id); +H5_DLL herr_t H5VLretrieve_lib_state(void **state); +H5_DLL herr_t H5VLrestore_lib_state(const void *state); +H5_DLL herr_t H5VLreset_lib_state(void); +H5_DLL herr_t H5VLfree_lib_state(void *state); /* Public wrappers for generic callbacks */ -- cgit v0.12 From 594cd935435d36801bee3dbb7fc531df7d398bcc Mon Sep 17 00:00:00 2001 From: Songyu Lu Date: Wed, 13 Mar 2019 10:20:30 -0500 Subject: HDFFV-10658: setting and getting properties in API context: 1. external file prefix and VDS prefix. 2. the datatype, dataspace, and LCPL of the dataset for VOL connector. --- src/H5CX.c | 342 ++++++++++++++++++++++++++++++++++++++++++++++- src/H5CXprivate.h | 12 ++ src/H5D.c | 21 +-- src/H5Ddeprec.c | 12 +- src/H5Dint.c | 36 ++--- src/H5VLnative_dataset.c | 10 +- 6 files changed, 391 insertions(+), 42 deletions(-) diff --git a/src/H5CX.c b/src/H5CX.c index b56d66d..2bfe559 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -189,6 +189,10 @@ typedef struct H5CX_t { hid_t dcpl_id; /* DCPL ID for API operation */ H5P_genplist_t *dcpl; /* Dataset Creation Property List */ + /* DAPL */ + hid_t dapl_id; /* DAPL ID for API operation */ + H5P_genplist_t *dapl; /* Dataset Access Property List */ + /* Internal: Object tagging info */ haddr_t tag; /* Current object's tag (ohdr chunk #0 address) */ @@ -275,8 +279,20 @@ typedef struct H5CX_t { hbool_t nlinks_valid; /* Whether number of soft / UD links to traverse is valid */ /* Cached DCPL properties */ - hbool_t do_min_dset_ohdr; /* Whether to minimize dataset object header */ - hbool_t do_min_dset_ohdr_valid; /* Whether minimize dataset object header flag is valid */ + hbool_t do_min_dset_ohdr; /* Whether to minimize dataset object header */ + hbool_t do_min_dset_ohdr_valid; /* Whether minimize dataset object header flag is valid */ + hid_t vl_prop_dset_type_id; + hbool_t vl_prop_dset_type_id_valid; + hid_t vl_prop_dset_space_id; + hbool_t vl_prop_dset_space_id_valid; + hid_t vl_prop_dset_lcpl_id; + hbool_t vl_prop_dset_lcpl_id_valid; + + /* Cached DAPL properties */ + char *extfile_prefix; + hbool_t extfile_prefix_valid; + char *vds_prefix; + hbool_t vds_prefix_valid; /* Cached VOL settings */ H5VL_connector_prop_t vol_connector_prop; /* Property for VOL connector ID & info */ @@ -336,8 +352,17 @@ typedef struct H5CX_lapl_cache_t { /* (Same as the cached DXPL struct, above, except for the default DCPL) */ typedef struct H5CX_dcpl_cache_t { hbool_t do_min_dset_ohdr; /* Whether to minimize dataset object header */ + hid_t vl_prop_dset_type_id; + hid_t vl_prop_dset_space_id; + hid_t vl_prop_dset_lcpl_id; } H5CX_dcpl_cache_t; +/* Typedef for cached default dataset access property list information */ +/* (Same as the cached DXPL struct, above, except for the default DXPL) */ +typedef struct H5CX_dapl_cache_t { + char *extfile_prefix; + char *vds_prefix; +} H5CX_dapl_cache_t; /********************/ /* Local Prototypes */ @@ -374,6 +399,9 @@ static H5CX_lapl_cache_t H5CX_def_lapl_cache; /* Define a "default" dataset creation property list cache structure to use for default DCPLs */ static H5CX_dcpl_cache_t H5CX_def_dcpl_cache; +/* Define a "default" dataset access property list cache structure to use for default DAPLs */ +static H5CX_dapl_cache_t H5CX_def_dapl_cache; + /* Declare a static free list to manage H5CX_node_t structs */ H5FL_DEFINE_STATIC(H5CX_node_t); @@ -398,6 +426,7 @@ H5CX__init_package(void) H5P_genplist_t *dx_plist; /* Data transfer property list */ H5P_genplist_t *la_plist; /* Link access property list */ H5P_genplist_t *dc_plist; /* Dataset creation property list */ + H5P_genplist_t *da_plist; /* Dataset access property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -511,6 +540,32 @@ H5CX__init_package(void) if(H5P_get(dc_plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &H5CX_def_dcpl_cache.do_min_dset_ohdr) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag") + if(H5P_get(dc_plist, H5VL_PROP_DSET_TYPE_ID, &H5CX_def_dcpl_cache.vl_prop_dset_type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for datatype id") + if(H5P_get(dc_plist, H5VL_PROP_DSET_SPACE_ID, &H5CX_def_dcpl_cache.vl_prop_dset_space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for space id") + if(H5P_get(dc_plist, H5VL_PROP_DSET_LCPL_ID, &H5CX_def_dcpl_cache.vl_prop_dset_lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl id") + + + + /* Reset the "default DAPL cache" information */ + HDmemset(&H5CX_def_dapl_cache, 0, sizeof(H5CX_dapl_cache_t)); + + /* Get the default DAPL cache information */ + + /* Get the default dataset access property list */ + if(NULL == (da_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list") + + /* Get the prefix for the external file */ + if(H5P_peek(da_plist, H5D_ACS_EFILE_PREFIX_NAME, &H5CX_def_dapl_cache.extfile_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for external file") + + /* Get the prefix for the VDS file */ + if(H5P_peek(da_plist, H5D_ACS_VDS_PREFIX_NAME, &H5CX_def_dapl_cache.vds_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for VDS") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX__init_package() */ @@ -634,6 +689,8 @@ H5CX__push_common(H5CX_node_t *cnode) /* Set non-zero context info */ cnode->ctx.dxpl_id = H5P_DATASET_XFER_DEFAULT; + cnode->ctx.dcpl_id = H5P_DATASET_CREATE_DEFAULT; + cnode->ctx.dapl_id = H5P_DATASET_ACCESS_DEFAULT; cnode->ctx.lapl_id = H5P_LINK_ACCESS_DEFAULT; cnode->ctx.tag = H5AC__INVALID_TAG; cnode->ctx.ring = H5AC_RING_USER; @@ -1083,6 +1140,7 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, *acspl_id = *libclass->def_plist_id; else { htri_t is_lapl; /* Whether the access property list is (or is derived from) a link access property list */ + htri_t is_dapl; /* Whether the access property list is (or is derived from) a dataset access property list */ #ifdef H5CX_DEBUG /* Sanity check the access property list class */ @@ -1096,6 +1154,12 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, else if(is_lapl) (*head)->ctx.lapl_id = *acspl_id; + /* Check for dataset access property and set API context if so */ + if((is_dapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_DACC->pclass)) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for dataset access class") + else if(is_dapl) + (*head)->ctx.dapl_id = *acspl_id; + #ifdef H5_HAVE_PARALLEL /* If this routine is not guaranteed to be collective (i.e. it doesn't * modify the structural metadata in a file), check if the application @@ -2324,6 +2388,180 @@ done: /*------------------------------------------------------------------------- + * Function: H5CX_get_vl_prop_dset_type_id + * + * Purpose: Retrieves the datatype ID of the dataset for VOL connector + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_vl_prop_dset_type_id(hid_t *dset_type_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(dset_type_id); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); + + H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5VL_PROP_DSET_TYPE_ID, vl_prop_dset_type_id); + + /* Get the value */ + *dset_type_id = (*head)->ctx.vl_prop_dset_type_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_vl_prop_dset_type_id */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_get_vl_prop_dset_space_id + * + * Purpose: Retrieves the space ID of the dataset for VOL connector + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_vl_prop_dset_space_id(hid_t *dset_space_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(dset_space_id); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); + + H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5VL_PROP_DSET_SPACE_ID, vl_prop_dset_space_id); + + /* Get the value */ + *dset_space_id = (*head)->ctx.vl_prop_dset_space_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_vl_prop_dset_space_id */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_get_vl_prop_dset_space_id + * + * Purpose: Retrieves the LCPL ID of the dataset for VOL connector + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_vl_prop_dset_lcpl_id(hid_t *dset_lcpl_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(dset_lcpl_id); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); + + H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5VL_PROP_DSET_TYPE_ID, vl_prop_dset_lcpl_id); + + /* Get the value */ + *dset_lcpl_id = (*head)->ctx.vl_prop_dset_lcpl_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_vl_prop_dset_lcpl_id */ + + + +/*------------------------------------------------------------------------- + * Function: H5CX_get_ext_file_prefix + * + * Purpose: Retrieves the prefix for external file + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_ext_file_prefix(char **extfile_prefix) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(extfile_prefix); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); + + H5CX_RETRIEVE_PROP_VALID(dapl, H5P_DATASET_ACCESS_DEFAULT, H5D_ACS_EFILE_PREFIX_NAME, extfile_prefix); + + /* Get the value */ + *extfile_prefix = (*head)->ctx.extfile_prefix; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_ext_file_prefix */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_get_vds_prefix + * + * Purpose: Retrieves the prefix for VDS + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_vds_prefix(char **vds_prefix) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(vds_prefix); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); + + H5CX_RETRIEVE_PROP_VALID(dapl, H5P_DATASET_ACCESS_DEFAULT, H5D_ACS_VDS_PREFIX_NAME, vds_prefix); + + /* Get the value */ + *vds_prefix = (*head)->ctx.vds_prefix; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_vds_prefix */ + + +/*------------------------------------------------------------------------- * Function: H5CX_set_tag * * Purpose: Sets the object tag for the current API call context. @@ -2639,6 +2877,106 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_nlinks() */ + +/*------------------------------------------------------------------------- + * Function: H5CX_set_vl_prop_dset_type_id + * + * Purpose: Sets the datatype ID of the dataset for the current API call context. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_set_vl_prop_dset_type_id(hid_t dset_type_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(head && *head); + + /* Set the API context value */ + (*head)->ctx.vl_prop_dset_type_id = dset_type_id; + + /* Mark the value as valid */ + (*head)->ctx.vl_prop_dset_type_id_valid = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_set_vl_prop_dset_type_id */ + +/*------------------------------------------------------------------------- + * Function: H5CX_set_vl_prop_dset_space_id + * + * Purpose: Sets the data space ID of the dataset for the current API call context. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_set_vl_prop_dset_space_id(hid_t dset_space_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(head && *head); + + /* Set the API context value */ + (*head)->ctx.vl_prop_dset_space_id = dset_space_id; + + /* Mark the value as valid */ + (*head)->ctx.vl_prop_dset_space_id_valid = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_set_vl_prop_dset_space_id */ + +/*------------------------------------------------------------------------- + * Function: H5CX_set_vl_prop_dset_lcpl_id + * + * Purpose: Sets the LCPL ID of the dataset for the current API call context. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 12, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_set_vl_prop_dset_lcpl_id(hid_t dset_lcpl_id) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(head && *head); + + /* Set the API context value */ + (*head)->ctx.vl_prop_dset_lcpl_id = dset_lcpl_id; + + /* Mark the value as valid */ + (*head)->ctx.vl_prop_dset_lcpl_id_valid = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index 80f1ac4..f022d8e 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -126,6 +126,13 @@ H5_DLL herr_t H5CX_get_nlinks(size_t *nlinks); /* "Getter" routines for DCPL properties cached in API context */ H5_DLL herr_t H5CX_get_dset_min_ohdr_flag(hbool_t *dset_min_ohdr_flag); +H5_DLL herr_t H5CX_get_vl_prop_dset_type_id(hid_t *dset_type_id); +H5_DLL herr_t H5CX_get_vl_prop_dset_space_id(hid_t *dset_space_id); +H5_DLL herr_t H5CX_get_vl_prop_dset_lcpl_id(hid_t *dset_lcpl_id); + +/* "Getter" routines for DAPL properties cached in API context */ +H5_DLL herr_t H5CX_get_ext_file_prefix(char **prefix_extfile); +H5_DLL herr_t H5CX_get_vds_prefix(char **prefix_vds); /* "Setter" routines for API context info */ H5_DLL void H5CX_set_tag(haddr_t tag); @@ -145,6 +152,11 @@ H5_DLL herr_t H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode); H5_DLL herr_t H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info); +/* "Setter" routines for DCPL properties cached in API context */ +H5_DLL herr_t H5CX_set_vl_prop_dset_type_id(hid_t dset_type_id); +H5_DLL herr_t H5CX_set_vl_prop_dset_space_id(hid_t dset_space_id); +H5_DLL herr_t H5CX_set_vl_prop_dset_lcpl_id(hid_t dset_lcpl_id); + /* "Setter" routines for LAPL properties cached in API context */ H5_DLL herr_t H5CX_set_nlinks(size_t nlinks); diff --git a/src/H5D.c b/src/H5D.c index fc350f2..a50518d 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -135,6 +135,9 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "dcpl_id is not a dataset create property list ID") + /* Set the DCPL for the API context */ + H5CX_set_dcpl(dcpl_id); + /* Verify access property list and set up collective metadata if appropriate */ if(H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") @@ -148,12 +151,9 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set creation properties */ - if(H5P_set(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for datatype id") - if(H5P_set(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for space id") - if(H5P_set(plist, H5VL_PROP_DSET_LCPL_ID, &lcpl_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for lcpl id") + H5CX_set_vl_prop_dset_type_id(type_id); + H5CX_set_vl_prop_dset_space_id(space_id); + H5CX_set_vl_prop_dset_lcpl_id(lcpl_id); /* Set location parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; @@ -228,6 +228,9 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not dataset create property list ID") + /* Set the DCPL for the API context */ + H5CX_set_dcpl(dcpl_id); + /* Verify access property list and set up collective metadata if appropriate */ if(H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") @@ -241,10 +244,8 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5I_INVALID_HID, "can't find object for ID") /* set creation properties */ - if(H5P_set(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for datatype id") - if(H5P_set(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for space id") + H5CX_set_vl_prop_dset_type_id(type_id); + H5CX_set_vl_prop_dset_space_id(space_id); /* Set location parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 76827b4..70e6f70 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -136,6 +136,9 @@ H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not dataset create property list ID") + /* Set the DCPL for the API context */ + H5CX_set_dcpl(dcpl_id); + /* Verify access property list and set up collective metadata if appropriate */ if(H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") @@ -145,12 +148,9 @@ H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5I_INVALID_HID, "can't find object for ID") /* set creation properties */ - if(H5P_set(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for datatype id") - if(H5P_set(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for space id") - if(H5P_set(plist, H5VL_PROP_DSET_LCPL_ID, &lcpl_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't set property value for lcpl id") + H5CX_set_vl_prop_dset_type_id(type_id); + H5CX_set_vl_prop_dset_space_id(space_id); + H5CX_set_vl_prop_dset_lcpl_id(lcpl_id); /* Set location parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; diff --git a/src/H5Dint.c b/src/H5Dint.c index 384c66b..ae9a40e 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -488,9 +488,6 @@ H5D__new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type) new_dset->dcpl_id = H5P_copy_plist(plist, FALSE); } /* end else */ - /* Set the DCPL for the API context */ - H5CX_set_dcpl(new_dset->dcpl_id); - /* Set return value */ ret_value = new_dset; @@ -1083,8 +1080,7 @@ done: *-------------------------------------------------------------------------- */ static herr_t -H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type, - char **file_prefix /*out*/) +H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type, char **file_prefix /*out*/) { char *prefix = NULL; /* prefix used to look for the file */ char *filepath = NULL; /* absolute path of directory the HDF5 file is in */ @@ -1105,20 +1101,22 @@ H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type /* XXX: Future thread-safety note - getenv is not required * to be reentrant. */ - if(HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) + if(HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) { prefix = HDgetenv("HDF5_VDS_PREFIX"); - else if(HDstrcmp(prefix_type, H5D_ACS_EFILE_PREFIX_NAME) == 0) + + if(prefix == NULL || *prefix == '\0') { + if(H5CX_get_vds_prefix(&prefix) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get the prefix for vds file") + } + } else if(HDstrcmp(prefix_type, H5D_ACS_EFILE_PREFIX_NAME) == 0) { prefix = HDgetenv("HDF5_EXTFILE_PREFIX"); - else - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "prefix name is not sensible") - if(prefix == NULL || *prefix == '\0') { - /* Set prefix to value of prefix_type property */ - if(NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - if(H5P_peek(plist, prefix_type, &prefix) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file prefix") - } /* end if */ + if(prefix == NULL || *prefix == '\0') { + if(H5CX_get_ext_file_prefix(&prefix) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get the prefix for the external file") + } + } else + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "prefix name is not sensible") /* Prefix has to be checked for NULL / empty string again because the * code above might have updated it. @@ -1552,8 +1550,10 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id) ret_value = dataset; done: - extfile_prefix = (char *)H5MM_xfree(extfile_prefix); - vds_prefix = (char *)H5MM_xfree(vds_prefix); + if(extfile_prefix) + extfile_prefix = (char *)H5MM_xfree(extfile_prefix); + if(vds_prefix) + vds_prefix = (char *)H5MM_xfree(vds_prefix); if(ret_value == NULL) { /* Free the location--casting away const*/ diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c index 8f7351c..ac25c55 100644 --- a/src/H5VLnative_dataset.c +++ b/src/H5VLnative_dataset.c @@ -18,6 +18,7 @@ #define H5D_FRIEND /* Suppress error about including H5Dpkg */ #include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ @@ -62,12 +63,9 @@ H5VL__native_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") /* Get creation properties */ - if(H5P_get(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") - if(H5P_get(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") - if(H5P_get(plist, H5VL_PROP_DSET_LCPL_ID, &lcpl_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id") + H5CX_get_vl_prop_dset_type_id(&type_id); + H5CX_get_vl_prop_dset_space_id(&space_id); + H5CX_get_vl_prop_dset_lcpl_id(&lcpl_id); /* Check arguments */ if(H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) -- cgit v0.12 From dc69df49e6a8896606c9e4bd0987613a02f7a25a Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Wed, 13 Mar 2019 13:50:20 -0500 Subject: CMake: fix pthread linking to only be private --- src/CMakeLists.txt | 6 +++--- test/CMakeLists.txt | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 83240bd..5f7bd48 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1120,7 +1120,7 @@ target_link_libraries (${HDF5_LIB_TARGET} ) if (NOT WIN32) target_link_libraries (${HDF5_LIB_TARGET} - PUBLIC $<$:Threads::Threads> + PRIVATE $<$:Threads::Threads> ) endif () set_global_variable (HDF5_LIBRARIES_TO_EXPORT ${HDF5_LIB_TARGET}) @@ -1152,8 +1152,8 @@ if (BUILD_SHARED_LIBS) ) TARGET_C_PROPERTIES (${HDF5_LIBSH_TARGET} SHARED) target_link_libraries (${HDF5_LIBSH_TARGET} - PRIVATE ${LINK_LIBS} ${LINK_COMP_LIBS} "$<$:${MPI_C_LIBRARIES}>" - PUBLIC $<$>:${CMAKE_DL_LIBS}> $<$:Threads::Threads> + PRIVATE ${LINK_LIBS} ${LINK_COMP_LIBS} "$<$:${MPI_C_LIBRARIES}>" $<$:Threads::Threads> + PUBLIC $<$>:${CMAKE_DL_LIBS}> ) set_global_variable (HDF5_LIBRARIES_TO_EXPORT "${HDF5_LIBRARIES_TO_EXPORT};${HDF5_LIBSH_TARGET}") H5_SET_LIB_OPTIONS (${HDF5_LIBSH_TARGET} ${HDF5_LIB_NAME} SHARED "LIB") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 276cf09..772f790 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -352,12 +352,17 @@ add_executable (ttsafe ${ttsafe_SOURCES}) target_include_directories(ttsafe PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") TARGET_C_PROPERTIES (ttsafe STATIC) target_link_libraries (ttsafe PRIVATE ${HDF5_LIB_TARGET} ${HDF5_TEST_LIB_TARGET}) +if (NOT WIN32) + target_link_libraries (ttsafe + PRIVATE $<$:Threads::Threads> + ) +endif () set_target_properties (ttsafe PROPERTIES FOLDER test) if (BUILD_SHARED_LIBS) add_executable (ttsafe-shared ${ttsafe_SOURCES}) target_include_directories(ttsafe-shared PRIVATE "${HDF5_SRC_DIR};${HDF5_BINARY_DIR};$<$:${MPI_C_INCLUDE_DIRS}>") TARGET_C_PROPERTIES (ttsafe-shared SHARED) - target_link_libraries (ttsafe-shared PRIVATE ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) + target_link_libraries (ttsafe-shared PRIVATE ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} $<$:Threads::Threads>) set_target_properties (ttsafe-shared PROPERTIES FOLDER test) endif () -- cgit v0.12 From 750b5c293076b6a446088fa3020e4e0787d489d7 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 15 Mar 2019 00:41:39 -0700 Subject: Adds _wopen support on Windows so that files with UTF-8 names can be opened. Fixes: HDFFV-2714, HDFFV-3914, HDFFV-3895, HDFFV-8237, HDFFV-10413, HDFFV-10691 --- release_docs/RELEASE.txt | 8 +++ src/H5system.c | 126 ++++++++++++++++++++++++++++++++++++++++ src/H5win32defs.h | 14 +++-- tools/test/perform/sio_engine.c | 6 ++ 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index aed539b..b5cc20c 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -135,6 +135,14 @@ New Features (DER - 2018/12/08, HDFFV-10252) + - Added the ability to open files with UTF-8 file names on Windows. + + The POSIX open(2) API call on Windows is limited to ASCII + file names. The library has been updated to convert incoming file + names to UTF-16 (via MultiByteToWideChar(CP_UTF8, ...) and use + _wopen() instead. + + (DER - 2019/03/15, HDFFV-2714, HDFFV-3914, HDFFV-3895, HDFFV-8237, HDFFV-10413, HDFFV-10691) Parallel Library: ----------------- diff --git a/src/H5system.c b/src/H5system.c index f47d057..2ddc29a 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -985,6 +985,132 @@ Wroundf(float arg) return (float)(arg < 0.0F ? HDceil(arg - 0.5F) : HDfloor(arg + 0.5F)); } +/*------------------------------------------------------------------------- +* Function: H5_get_utf16_str +* +* Purpose: Gets a UTF-16 string from an UTF-8 (or ASCII) string. +* +* Return: Success: A pointer to a UTF-16 string +* This must be freed by the caller using H5MM_xfree() +* Failure: NULL +* +* Programmer: Dana Robinson +* Spring 2019 +* +*------------------------------------------------------------------------- +*/ +const wchar_t * +H5_get_utf16_str(const char *s) +{ + int nwchars = -1; /* Length of the UTF-16 buffer */ + wchar_t *ret_s = NULL; /* UTF-16 version of the string */ + + /* Get the number of UTF-16 characters needed */ + if(0 == (nwchars = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0))) + goto error; + + /* Allocate a buffer for the UTF-16 string */ + if(NULL == (ret_s = (wchar_t *)H5MM_calloc(sizeof(wchar_t) * (size_t)nwchars))) + goto error; + + /* Convert the input UTF-8 string to UTF-16 */ + if(0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ret_s, nwchars)) + goto error; + + return ret_s; + +error: + if(ret_s) + H5MM_xfree((void *)ret_s); + return NULL; +} /* end H5_get_utf16_str() */ + +/*------------------------------------------------------------------------- + * Function: Wopen_utf8 + * + * Purpose: UTF-8 equivalent of open(2) for use on Windows. + * Converts a UTF-8 input path to UTF-16 and then opens the + * file via _wopen() under the hood + * + * Return: Success: A POSIX file descriptor + * Failure: -1 + * + * Programmer: Dana Robinson + * Spring 2019 + * + *------------------------------------------------------------------------- + */ +int +Wopen_utf8(const char *path, int oflag, ...) +{ + int fd = -1; /* POSIX file descriptor to be returned */ + wchar_t *wpath = NULL; /* UTF-16 version of the path */ + int pmode = 0; /* mode (optionally set via variable args) */ + + /* Convert the input UTF-8 path to UTF-16 */ + if(NULL == (wpath = H5_get_utf16_str(path))) + goto done; + + /* _O_BINARY must be set in Windows to avoid CR-LF <-> LF EOL + * transformations when performing I/O. Note that this will + * produce Unix-style text files, though. + */ + oflag |= _O_BINARY; + + /* Get the mode, if O_CREAT was specified */ + if(oflag & O_CREAT) { + va_list vl; + + HDva_start(vl, oflag); + pmode = HDva_arg(vl, int); + HDva_end(vl); + } + + /* Open the file */ + fd = _wopen(wpath, oflag, pmode); + +done: + if(wpath) + H5MM_xfree((void *)wpath); + + return fd; +} /* end Wopen_utf8() */ + +/*------------------------------------------------------------------------- + * Function: Wremove_utf8 + * + * Purpose: UTF-8 equivalent of remove(3) for use on Windows. + * Converts a UTF-8 input path to UTF-16 and then opens the + * file via _wremove() under the hood + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Dana Robinson + * Spring 2019 + * + *------------------------------------------------------------------------- + */ +int +Wremove_utf8(const char *path) +{ + wchar_t *wpath = NULL; /* UTF-16 version of the path */ + int ret; + + /* Convert the input UTF-8 path to UTF-16 */ + if(NULL == (wpath = H5_get_utf16_str(path))) + goto done; + + /* Open the file */ + ret = _wremove(wpath); + +done: + if(wpath) + H5MM_xfree((void *)wpath); + + return ret; +} /* end Wremove_utf8() */ + #endif /* H5_HAVE_WIN32_API */ diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 140afc3..2ae2575 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -34,6 +34,7 @@ typedef __int64 h5_stat_size_t; #define HDaccess(F,M) _access(F,M) #define HDchdir(S) _chdir(S) #define HDclose(F) _close(F) +#define HDcreat(S,M) Wopen_utf8(S,O_CREAT|O_TRUNC|O_RDWR,M) #define HDdup(F) _dup(F) #define HDfdopen(N,S) _fdopen(N,S) #define HDfileno(F) _fileno(F) @@ -47,15 +48,13 @@ typedef __int64 h5_stat_size_t; #define HDmkdir(S,M) _mkdir(S) #define HDnanosleep(N, O) Wnanosleep(N, O) #define HDoff_t __int64 -/* _O_BINARY must be set in Windows to avoid CR-LF <-> LF EOL - * transformations when performing I/O. Note that this will - * produce Unix-style text files, though. - * - * Also note that the variadic macro is using a VC++ extension + +/* Note that the variadic HDopen macro is using a VC++ extension * where the comma is dropped if nothing is passed to the ellipsis. */ -#define HDopen(S,F,...) _open(S, F | _O_BINARY, __VA_ARGS__) +#define HDopen(S,F,...) Wopen_utf8(S,F,__VA_ARGS__) #define HDread(F,M,Z) _read(F,M,Z) +#define HDremove(S) Wremove_utf8(S) #define HDrmdir(S) _rmdir(S) #define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,(Z>1?Z:2)) #define HDsleep(S) Sleep(S*1000) @@ -128,6 +127,9 @@ extern "C" { H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap); H5_DLL int Wnanosleep(const struct timespec *req, struct timespec *rem); H5_DLL herr_t H5_expand_windows_env_vars(char **env_var); + H5_DLL const wchar_t *H5_get_utf16_str(const char *s); + H5_DLL int Wopen_utf8(const char *path, int oflag, ...); + H5_DLL int Wremove_utf8(const char *path); /* Round functions only needed for VS2012 and earlier. * They are always built to ensure they don't go stale and diff --git a/tools/test/perform/sio_engine.c b/tools/test/perform/sio_engine.c index 4fead3f..11de229 100644 --- a/tools/test/perform/sio_engine.c +++ b/tools/test/perform/sio_engine.c @@ -54,6 +54,12 @@ } while(0) /* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S,F,...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ #define POSIXCREATE(fn) HDopen(fn, O_CREAT|O_TRUNC|O_RDWR, 0600) #define POSIXOPEN(fn, F) HDopen(fn, F, 0600) #define POSIXCLOSE(F) HDclose(F) -- cgit v0.12 From 0c20c65e2f3abf390ad87c9167daca4cdff2de39 Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Fri, 15 Mar 2019 08:45:38 -0700 Subject: Added the HDopen work-around on windows to pio_engine.c --- tools/test/perform/pio_engine.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/test/perform/pio_engine.c b/tools/test/perform/pio_engine.c index 1c0d621..43a0f64 100644 --- a/tools/test/perform/pio_engine.c +++ b/tools/test/perform/pio_engine.c @@ -82,6 +82,12 @@ /* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S,F,...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ #define POSIXCREATE(fn) HDopen(fn, O_CREAT|O_TRUNC|O_RDWR, 0600) #define POSIXOPEN(fn, F) HDopen(fn, F, 0600) #define POSIXCLOSE(F) HDclose(F) -- cgit v0.12 From 9d86314f8b71f090b71d7edec8014935f5cd3cc7 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 15 Mar 2019 20:14:41 -0500 Subject: Core changes to selection code from the hyperslab_updates branch. --- src/H5Dchunk.c | 372 +++- src/H5Dfill.c | 4 +- src/H5Dmpio.c | 22 +- src/H5Dpkg.h | 8 +- src/H5Dscatgath.c | 79 +- src/H5Dselect.c | 8 +- src/H5Sall.c | 94 +- src/H5Shyper.c | 5769 +++++++++++++++++++++++++++++++++++------------------ src/H5Smpio.c | 442 ++-- src/H5Snone.c | 63 +- src/H5Spkg.h | 129 +- src/H5Spoint.c | 481 +++-- src/H5Sprivate.h | 28 +- src/H5Spublic.h | 17 + src/H5Sselect.c | 205 +- src/H5Stest.c | 282 ++- src/H5TS.c | 12 + src/H5TSprivate.h | 1 + src/H5err.txt | 1 + test/tselect.c | 3250 ++++++++++++++++++++---------- 20 files changed, 7589 insertions(+), 3678 deletions(-) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index dcd3a8d..e7d1b15 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -276,6 +276,8 @@ static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, static herr_t H5D__free_chunk_info(void *item, void *key, void *opdata); static herr_t H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info); +static herr_t H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, + const H5D_io_info_t *io_info); static herr_t H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info); static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm); @@ -1044,7 +1046,6 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ unsigned f_ndims; /* The number of dimensions of the file's dataspace */ int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */ - H5SL_node_t *curr_node; /* Current node in skip list */ char bogus; /* "bogus" buffer to pass to selection iterator */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1168,25 +1169,17 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf /* Check if file selection is a not a hyperslab selection */ if(sel_hyper_flag) { /* Build the file selection for each chunk */ - if(H5D__create_chunk_file_map_hyper(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - - /* Clean file chunks' hyperslab span "scratch" information */ - curr_node = H5SL_first(fm->sel_chunks); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->fspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") + if(H5S_SEL_ALL == fm->fsel_type) { + if(H5D__create_chunk_file_map_all(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + } /* end if */ + else { + /* Sanity check */ + HDassert(fm->fsel_type == H5S_SEL_HYPERSLABS); - /* Get the next chunk node in the skip list */ - curr_node = H5SL_next(curr_node); - } /* end while */ + if(H5D__create_chunk_file_map_hyper(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + } /* end else */ } /* end if */ else { H5S_sel_iter_op_t iter_op; /* Operator for iteration */ @@ -1248,7 +1241,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf /* Create selection iterator for memory selection */ if(0 == (elmt_size = H5T_get_size(mem_type))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid") - if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size) < 0) + if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -1258,26 +1251,6 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf /* Spaces aren't the same shape, iterate over the memory selection directly */ if(H5S_select_iterate(&bogus, file_type, file_space, &iter_op, fm) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") - - /* Clean up hyperslab stuff, if necessary */ - if(fm->msel_type != H5S_SEL_POINTS) { - /* Clean memory chunks' hyperslab span "scratch" information */ - curr_node = H5SL_first(fm->sel_chunks); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->mspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") - - /* Get the next chunk node in the skip list */ - curr_node = H5SL_next(curr_node); - } /* end while */ - } /* end if */ } /* end else */ } /* end else */ @@ -1533,6 +1506,211 @@ done: /*------------------------------------------------------------------------- + * Function: H5D__create_chunk_file_map_all + * + * Purpose: Create all chunk selections in file, for an "all" selection. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, January 21, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t +#ifndef H5_HAVE_PARALLEL + H5_ATTR_UNUSED +#endif /* H5_HAVE_PARALLEL */ + *io_info) +{ + H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */ + hsize_t file_dims[H5S_MAX_RANK]; /* File dataspace dims */ + hsize_t sel_points; /* Number of elements in file selection */ + hsize_t zeros[H5S_MAX_RANK]; /* All zero vector (for start parameter to setting hyperslab on partial chunks) */ + hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */ + hsize_t end[H5S_MAX_RANK]; /* Final coordinates of chunk */ + hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */ + hsize_t chunk_index; /* "Index" of chunk */ + hsize_t curr_partial_clip[H5S_MAX_RANK]; /* Current partial dimension sizes to clip against */ + hsize_t partial_dim_size[H5S_MAX_RANK]; /* Size of a partial dimension */ + hbool_t is_partial_dim[H5S_MAX_RANK]; /* Whether a dimension is currently a partial chunk */ + unsigned num_partial_dims; /* Current number of partial dimensions */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(fm->f_ndims > 0); + + /* Get number of elements selected in file */ + sel_points = fm->nelmts; + + /* Get dataspace dimensions */ + if(H5S_get_simple_extent_dims(fm->file_space, file_dims, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") + + /* Set initial chunk location, partial dimensions, etc */ + num_partial_dims = 0; + HDmemset(zeros, 0, sizeof(zeros)); + for(u = 0; u < fm->f_ndims; u++) { + /* Validate this chunk dimension */ + if(fm->layout->u.chunk.dim[u] == 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u) + + /* Set up start / end coordinates for first chunk */ + scaled[u] = 0; + coords[u] = 0; + end[u] = fm->chunk_dim[u] - 1; + + /* Iniitialize partial chunk dimension information */ + partial_dim_size[u] = file_dims[u] % fm->chunk_dim[u]; + if(file_dims[u] < fm->chunk_dim[u]) { + curr_partial_clip[u] = partial_dim_size[u]; + is_partial_dim[u] = TRUE; + num_partial_dims++; + } /* end if */ + else { + curr_partial_clip[u] = fm->chunk_dim[u]; + is_partial_dim[u] = FALSE; + } /* end else */ + } /* end for */ + + /* Set the index of this chunk */ + chunk_index = 0; + + /* Create "temporary" chunk for selection operations (copy file space) */ + if(NULL == (tmp_fchunk = H5S_create_simple(fm->f_ndims, fm->chunk_dim, NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create dataspace for chunk") + + /* Iterate through each chunk in the dataset */ + while(sel_points) { + H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */ + hssize_t schunk_points; /* Number of elements in chunk selection */ + + /* Add temporary chunk to the list of chunks */ + + /* Allocate the file & memory chunk information */ + if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info") + + /* Initialize the chunk information */ + + /* Set the chunk index */ + new_chunk_info->index = chunk_index; + +#ifdef H5_HAVE_PARALLEL + /* Store chunk selection information, for multi-chunk I/O */ + if(io_info->using_mpi_vfd) + fm->select_chunk[chunk_index] = new_chunk_info; +#endif /* H5_HAVE_PARALLEL */ + + /* Set the file chunk dataspace */ + if(NULL == (new_chunk_info->fspace = H5S_copy(tmp_fchunk, TRUE, FALSE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy chunk dataspace") + new_chunk_info->fspace_shared = FALSE; + + /* If there are partial dimensions for this chunk, set the hyperslab for them */ + if(num_partial_dims > 0) + if(H5S_select_hyperslab(new_chunk_info->fspace, H5S_SELECT_SET, zeros, NULL, curr_partial_clip, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk selection") + + /* Set the memory chunk dataspace */ + new_chunk_info->mspace = NULL; + new_chunk_info->mspace_shared = FALSE; + + /* Copy the chunk's scaled coordinates */ + HDmemcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); + new_chunk_info->scaled[fm->f_ndims] = 0; + + /* Insert the new chunk into the skip list */ + if(H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) { + H5D__free_chunk_info(new_chunk_info, NULL, NULL); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") + } /* end if */ + + /* Get number of elements selected in chunk */ + if((schunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements") + H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, schunk_points, hssize_t); + + /* Decrement # of points left in file selection */ + sel_points -= (hsize_t)schunk_points; + + /* Advance to next chunk if we are not done */ + if(sel_points > 0) { + int curr_dim; /* Current dimension to increment */ + + /* Increment chunk index */ + chunk_index++; + + /* Set current increment dimension */ + curr_dim = (int)fm->f_ndims - 1; + + /* Increment chunk location in fastest changing dimension */ + coords[curr_dim] += fm->chunk_dim[curr_dim]; + scaled[curr_dim]++; + end[curr_dim] += fm->chunk_dim[curr_dim]; + + /* Bring chunk location back into bounds, if necessary */ + if(coords[curr_dim] >= file_dims[curr_dim]) { + do { + /* Reset current dimension's location to 0 */ + coords[curr_dim] = 0; + scaled[curr_dim] = 0; + end[curr_dim] = fm->chunk_dim[curr_dim] - 1; + + /* Check for previous partial chunk in this dimension */ + if(is_partial_dim[curr_dim] && end[curr_dim] < file_dims[curr_dim]) { + /* Sanity check */ + HDassert(num_partial_dims > 0); + + /* Reset partial chunk information for this dimension */ + curr_partial_clip[curr_dim] = fm->chunk_dim[curr_dim]; + is_partial_dim[curr_dim] = FALSE; + num_partial_dims--; + } /* end if */ + + /* Decrement current dimension */ + curr_dim--; + + /* Check for valid current dim */ + if(curr_dim >= 0) { + /* Increment chunk location in current dimension */ + coords[curr_dim] += fm->chunk_dim[curr_dim]; + scaled[curr_dim]++; + end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1; + } /* end if */ + } while(curr_dim >= 0 && (coords[curr_dim] >= file_dims[curr_dim])); + } /* end if */ + + /* Check for valid current dim */ + if(curr_dim >= 0) { + /* Check for partial chunk in this dimension */ + if(!is_partial_dim[curr_dim] && file_dims[curr_dim] <= end[curr_dim]) { + /* Set partial chunk information for this dimension */ + curr_partial_clip[curr_dim] = partial_dim_size[curr_dim]; + is_partial_dim[curr_dim] = TRUE; + num_partial_dims++; + + /* Sanity check */ + HDassert(num_partial_dims <= fm->f_ndims); + } /* end if */ + } /* end if */ + } /* end if */ + } /* end while */ + +done: + /* Clean up */ + if(tmp_fchunk && H5S_close(tmp_fchunk) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't release temporary dataspace") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__create_chunk_file_map_all() */ + + +/*------------------------------------------------------------------------- * Function: H5D__create_chunk_file_map_hyper * * Purpose: Create all chunk selections in file, for a hyperslab selection. @@ -1551,6 +1729,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t #endif /* H5_HAVE_PARALLEL */ *io_info) { + H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */ hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ hsize_t sel_points; /* Number of elements in file selection */ @@ -1594,45 +1773,28 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Check for intersection of current chunk and file selection */ /* (Casting away const OK - QAK) */ if(TRUE == H5S_hyper_intersect_block((H5S_t *)fm->file_space, coords, end)) { - H5S_t *tmp_fchunk; /* Temporary file dataspace */ H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */ hssize_t schunk_points; /* Number of elements in chunk selection */ - /* Create "temporary" chunk for selection operations (copy file space) */ - if(NULL == (tmp_fchunk = H5S_copy(fm->file_space, TRUE, FALSE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - - /* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */ - if(H5S_hyper_convert(tmp_fchunk) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") - } /* end if */ - - /* "AND" temporary chunk and current chunk */ - if(H5S_select_hyperslab(tmp_fchunk,H5S_SELECT_AND,coords,NULL,fm->chunk_dim,NULL) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create chunk selection") - } /* end if */ + /* Create dataspace for chunk, 'AND'ing the overall selection with + * the current chunk. + */ + if(H5S_combine_hyperslab(fm->file_space, H5S_SELECT_AND, coords, NULL, fm->chunk_dim, NULL, &tmp_fchunk) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to combine file space selection with chunk block") /* Resize chunk's dataspace dimensions to size of chunk */ - if(H5S_set_extent_real(tmp_fchunk,fm->chunk_dim) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions") - } /* end if */ + if(H5S_set_extent_real(tmp_fchunk, fm->chunk_dim) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions") /* Move selection back to have correct offset in chunk */ - if(H5S_SELECT_ADJUST_U(tmp_fchunk, coords) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") - } + if(H5S_SELECT_ADJUST_U(tmp_fchunk, coords) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") /* Add temporary chunk to the list of chunks */ /* Allocate the file & memory chunk information */ - if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") - } /* end if */ + if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info") /* Initialize the chunk information */ @@ -1648,6 +1810,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t /* Set the file chunk dataspace */ new_chunk_info->fspace = tmp_fchunk; new_chunk_info->fspace_shared = FALSE; + tmp_fchunk = NULL; /* Set the memory chunk dataspace */ new_chunk_info->mspace = NULL; @@ -1664,7 +1827,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t } /* end if */ /* Get number of elements selected in chunk */ - if((schunk_points = H5S_GET_SELECT_NPOINTS(tmp_fchunk)) < 0) + if((schunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements") H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, schunk_points, hssize_t); @@ -1713,6 +1876,11 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t } /* end while */ done: + /* Clean up on failure */ + if(ret_value < 0) + if(tmp_fchunk && H5S_close(tmp_fchunk) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't release temporary dataspace") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__create_chunk_file_map_hyper() */ @@ -1736,13 +1904,13 @@ done: static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) { + H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ H5SL_node_t *curr_node; /* Current node in skip list */ hsize_t file_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ hsize_t file_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */ hsize_t mem_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */ hssize_t adjust[H5S_MAX_RANK]; /* Adjustment to make to all file chunks */ - hssize_t chunk_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1753,8 +1921,6 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) /* Check for all I/O going to a single chunk */ if(H5SL_count(fm->sel_chunks)==1) { - H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ - /* Get the node */ curr_node = H5SL_first(fm->sel_chunks); @@ -1789,41 +1955,61 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) /* Iterate over each chunk in the chunk list */ curr_node = H5SL_first(fm->sel_chunks); while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ + hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */ + hssize_t chunk_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */ + H5S_sel_type chunk_sel_type; /* Chunk's selection type */ /* Get pointer to chunk's information */ chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); HDassert(chunk_info); + /* Compute the chunk coordinates from the scaled coordinates */ + for(u = 0; u < fm->f_ndims; u++) + coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u]; + /* Copy the information */ /* Copy the memory dataspace */ if((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - /* Release the current selection */ - if(H5S_SELECT_RELEASE(chunk_info->mspace) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection") + /* Get the chunk's selection type */ + if((chunk_sel_type = H5S_GET_SELECT_TYPE(chunk_info->fspace)) < H5S_SEL_NONE) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") - /* Copy the file chunk's selection */ - if(H5S_select_copy(chunk_info->mspace,chunk_info->fspace,FALSE) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection") + /* Set memory selection for "all" chunk selections */ + if(H5S_SEL_ALL == chunk_sel_type) { + /* Adjust the chunk coordinates */ + for(u = 0; u < fm->f_ndims; u++) + coords[u] -= adjust[u]; - /* Compute the adjustment for this chunk */ - for(u = 0; u < fm->f_ndims; u++) { - hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */ + /* Set to same shape as chunk */ + if(H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, coords, NULL, fm->chunk_dim, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection") + } /* end if */ + else { + /* Sanity check */ + HDassert(H5S_SEL_HYPERSLABS == chunk_sel_type); - /* Compute the chunk coordinates from the scaled coordinates */ - coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u]; + /* Release the current selection */ + if(H5S_SELECT_RELEASE(chunk_info->mspace) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection") - /* Compensate for the chunk offset */ - H5_CHECK_OVERFLOW(coords[u], hsize_t, hssize_t); - chunk_adjust[u] = adjust[u] - (hssize_t)coords[u]; /*lint !e771 The adjust array will always be initialized */ - } /* end for */ + /* Copy the file chunk's selection */ + if(H5S_select_copy(chunk_info->mspace, chunk_info->fspace, FALSE) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection") - /* Adjust the selection */ - if(H5S_hyper_adjust_s(chunk_info->mspace, chunk_adjust) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection") + /* Compute the adjustment for this chunk */ + for(u = 0; u < fm->f_ndims; u++) { + /* Compensate for the chunk offset */ + H5_CHECK_OVERFLOW(coords[u], hsize_t, hssize_t); + chunk_adjust[u] = adjust[u] - (hssize_t)coords[u]; /*lint !e771 The adjust array will always be initialized */ + } /* end for */ + + /* Adjust the selection */ + if(H5S_hyper_adjust_s(chunk_info->mspace, chunk_adjust) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection") + } /* end else */ /* Get the next chunk node in the skip list */ curr_node = H5SL_next(curr_node); @@ -4821,12 +5007,12 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk selection iterator") /* Create a selection iterator for scattering the elements to memory buffer */ - if(H5S_select_iter_init(chunk_iter, udata->chunk_space, layout->u.chunk.dim[rank]) < 0) + if(H5S_select_iter_init(chunk_iter, udata->chunk_space, layout->u.chunk.dim[rank], 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize chunk selection information") chunk_iter_init = TRUE; /* Scatter the data into memory */ - if(H5D__scatter_mem(udata->fb_info.fill_buf, udata->chunk_space, chunk_iter, (size_t)sel_nelmts, chunk/*out*/) < 0) + if(H5D__scatter_mem(udata->fb_info.fill_buf, chunk_iter, (size_t)sel_nelmts, chunk/*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed") diff --git a/src/H5Dfill.c b/src/H5Dfill.c index 619f699..61ce822 100644 --- a/src/H5Dfill.c +++ b/src/H5Dfill.c @@ -275,12 +275,12 @@ H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate memory selection iterator") /* Create a selection iterator for scattering the elements to memory buffer */ - if(H5S_select_iter_init(mem_iter, space, dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, space, dst_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; /* Scatter the data into memory */ - if(H5D__scatter_mem(tmp_buf, space, mem_iter, (size_t)nelmts, buf/*out*/) < 0) + if(H5D__scatter_mem(tmp_buf, mem_iter, (size_t)nelmts, buf/*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "scatter failed") } /* end if */ else { diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 2a6c05f..d1c70b0 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -2864,12 +2864,12 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to encode dataspace") /* Initialize iterator for memory selection */ - if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; /* Collect the modification data into the buffer */ - if(0 == H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t)iter_nelmts, mod_data_p)) + if(0 == H5D__gather_mem(io_info->u.wbuf, mem_iter, (size_t)iter_nelmts, mod_data_p)) HGOTO_ERROR(H5E_IO, H5E_CANTGATHER, FAIL, "couldn't gather from write buffer") /* Send modification data to new owner */ @@ -3170,7 +3170,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if (NULL == (mem_iter = (H5S_sel_iter_t *) H5MM_malloc(sizeof(H5S_sel_iter_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate memory iterator") - if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; @@ -3185,7 +3185,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if(NULL == (file_iter = (H5S_sel_iter_t *) H5MM_malloc(sizeof(H5S_sel_iter_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate file iterator") - if(H5S_select_iter_init(file_iter, chunk_info->fspace, type_info->src_type_size) < 0) + if(H5S_select_iter_init(file_iter, chunk_info->fspace, type_info->src_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") file_iter_init = TRUE; @@ -3195,13 +3195,13 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if(NULL == (tmp_gath_buf = H5MM_malloc((hsize_t) iter_nelmts * type_info->src_type_size))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer") - if(!H5D__gather_mem(chunk_entry->buf, chunk_info->fspace, file_iter, (size_t) iter_nelmts, tmp_gath_buf)) + if(!H5D__gather_mem(chunk_entry->buf, file_iter, (size_t) iter_nelmts, tmp_gath_buf)) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't gather from chunk buffer") if((iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - if(H5D__scatter_mem(tmp_gath_buf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, io_info->u.rbuf) < 0) + if(H5D__scatter_mem(tmp_gath_buf, mem_iter, (size_t) iter_nelmts, io_info->u.rbuf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to read buffer") break; @@ -3214,7 +3214,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate temporary gather buffer") /* Gather modification data from the application write buffer into a temporary buffer */ - if(0 == H5D__gather_mem(io_info->u.wbuf, chunk_info->mspace, mem_iter, (size_t) iter_nelmts, tmp_gath_buf)) + if(0 == H5D__gather_mem(io_info->u.wbuf, mem_iter, (size_t) iter_nelmts, tmp_gath_buf)) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't gather from write buffer") if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) @@ -3222,7 +3222,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk mem_iter_init = FALSE; /* Initialize iterator for file selection */ - if(H5S_select_iter_init(mem_iter, chunk_info->fspace, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, chunk_info->fspace, type_info->dst_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information") mem_iter_init = TRUE; @@ -3232,7 +3232,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk /* Scatter the owner's modification data into the chunk data buffer according to * the file space. */ - if(H5D__scatter_mem(tmp_gath_buf, chunk_info->fspace, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) + if(H5D__scatter_mem(tmp_gath_buf, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't scatter to chunk data buffer") if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) @@ -3254,7 +3254,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk if(NULL == (dataspace = H5S_decode(&mod_data_p))) HGOTO_ERROR(H5E_DATASET, H5E_CANTDECODE, FAIL, "unable to decode dataspace") - if(H5S_select_iter_init(mem_iter, dataspace, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, dataspace, type_info->dst_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; @@ -3262,7 +3262,7 @@ H5D__filtered_collective_chunk_entry_io(H5D_filtered_collective_io_info_t *chunk HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") /* Update the chunk data with the received modification data */ - if(H5D__scatter_mem(mod_data_p, dataspace, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) + if(H5D__scatter_mem(mod_data_p, mem_iter, (size_t) iter_nelmts, chunk_entry->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't scatter to write buffer") if(H5S_SELECT_ITER_RELEASE(mem_iter) < 0) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 2767aa1..fb74c1c 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -591,10 +591,10 @@ H5_DLL herr_t H5D__select_write(const H5D_io_info_t *io_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); /* Functions that perform scatter-gather serial I/O operations */ -H5_DLL herr_t H5D__scatter_mem(const void *_tscat_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, void *_buf); -H5_DLL size_t H5D__gather_mem(const void *_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, void *_tgath_buf/*out*/); +H5_DLL herr_t H5D__scatter_mem(const void *_tscat_buf, H5S_sel_iter_t *iter, + size_t nelmts, void *_buf); +H5_DLL size_t H5D__gather_mem(const void *_buf, H5S_sel_iter_t *iter, + size_t nelmts, void *_tgath_buf/*out*/); H5_DLL herr_t H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 266f5f5..8293562 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -43,13 +43,11 @@ /* Local Prototypes */ /********************/ static herr_t H5D__scatter_file(const H5D_io_info_t *io_info, - const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const void *buf); + H5S_sel_iter_t *file_iter, size_t nelmts, const void *buf); static size_t H5D__gather_file(const H5D_io_info_t *io_info, - const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - void *buf); -static herr_t H5D__compound_opt_read(size_t nelmts, const H5S_t *mem_space, - H5S_sel_iter_t *iter, const H5D_type_info_t *type_info, void *user_buf/*out*/); + H5S_sel_iter_t *file_iter, size_t nelmts, void *buf); +static herr_t H5D__compound_opt_read(size_t nelmts, H5S_sel_iter_t *iter, + const H5D_type_info_t *type_info, void *user_buf/*out*/); static herr_t H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info); @@ -90,9 +88,8 @@ H5FL_SEQ_EXTERN(hsize_t); *------------------------------------------------------------------------- */ static herr_t -H5D__scatter_file(const H5D_io_info_t *_io_info, - const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, - const void *_buf) +H5D__scatter_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, + size_t nelmts, const void *_buf) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ hsize_t *off = NULL; /* Pointer to sequence offsets */ @@ -111,7 +108,6 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, /* Check args */ HDassert(_io_info); - HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(_buf); @@ -138,7 +134,7 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, /* Loop until all elements are written */ while(nelmts > 0) { /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space, H5S_GET_SEQ_LIST_SORTED, iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Reset the current sequence information */ @@ -191,9 +187,8 @@ done: *------------------------------------------------------------------------- */ static size_t -H5D__gather_file(const H5D_io_info_t *_io_info, - const H5S_t *space, H5S_sel_iter_t *iter, size_t nelmts, - void *_buf/*out*/) +H5D__gather_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, + size_t nelmts, void *_buf/*out*/) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ hsize_t *off = NULL; /* Pointer to sequence offsets */ @@ -214,7 +209,6 @@ H5D__gather_file(const H5D_io_info_t *_io_info, HDassert(_io_info); HDassert(_io_info->dset); HDassert(_io_info->store); - HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(_buf); @@ -241,7 +235,7 @@ H5D__gather_file(const H5D_io_info_t *_io_info, /* Loop until all elements are read */ while(nelmts > 0) { /* Get list of sequences for selection to read */ - if(H5S_SELECT_GET_SEQ_LIST(space, H5S_GET_SEQ_LIST_SORTED, iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed") /* Reset the current sequence information */ @@ -288,8 +282,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__scatter_mem (const void *_tscat_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, void *_buf/*out*/) +H5D__scatter_mem(const void *_tscat_buf, H5S_sel_iter_t *iter, size_t nelmts, + void *_buf/*out*/) { uint8_t *buf = (uint8_t *)_buf; /* Get local copies for address arithmetic */ const uint8_t *tscat_buf = (const uint8_t *)_tscat_buf; @@ -307,7 +301,6 @@ H5D__scatter_mem (const void *_tscat_buf, const H5S_t *space, /* Check args */ HDassert(tscat_buf); - HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(buf); @@ -329,7 +322,7 @@ H5D__scatter_mem (const void *_tscat_buf, const H5S_t *space, /* Loop until all elements are written */ while(nelmts > 0) { /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed") /* Loop, while sequences left to process */ @@ -376,8 +369,8 @@ done: *------------------------------------------------------------------------- */ size_t -H5D__gather_mem(const void *_buf, const H5S_t *space, - H5S_sel_iter_t *iter, size_t nelmts, void *_tgath_buf/*out*/) +H5D__gather_mem(const void *_buf, H5S_sel_iter_t *iter, size_t nelmts, + void *_tgath_buf/*out*/) { const uint8_t *buf = (const uint8_t *)_buf; /* Get local copies for address arithmetic */ uint8_t *tgath_buf = (uint8_t *)_tgath_buf; @@ -395,7 +388,6 @@ H5D__gather_mem(const void *_buf, const H5S_t *space, /* Check args */ HDassert(buf); - HDassert(space); HDassert(iter); HDassert(nelmts > 0); HDassert(tgath_buf); @@ -417,7 +409,7 @@ H5D__gather_mem(const void *_buf, const H5S_t *space, /* Loop until all elements are written */ while(nelmts > 0) { /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, vec_size, nelmts, &nseq, &nelem, off, len) < 0) HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed") /* Loop, while sequences left to process */ @@ -495,13 +487,13 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator") /* Figure out the strip mine size. */ - if(H5S_select_iter_init(file_iter, file_space, type_info->src_type_size) < 0) + if(H5S_select_iter_init(file_iter, file_space, type_info->src_type_size, H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information") file_iter_init = TRUE; /*file selection iteration info has been initialized */ - if(H5S_select_iter_init(mem_iter, mem_space, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(mem_iter, mem_space, type_info->dst_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; /*file selection iteration info has been initialized */ - if(H5S_select_iter_init(bkg_iter, mem_space, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(bkg_iter, mem_space, type_info->dst_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information") bkg_iter_init = TRUE; /*file selection iteration info has been initialized */ @@ -522,7 +514,7 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf /* * Gather data */ - n = H5D__gather_file(io_info, file_space, file_iter, smine_nelmts, type_info->tconv_buf/*out*/); + n = H5D__gather_file(io_info, file_iter, smine_nelmts, type_info->tconv_buf/*out*/); if(n != smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed") @@ -531,12 +523,12 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf * bypass the rest of steps. */ if(type_info->cmpd_subset && H5T_SUBSET_FALSE != type_info->cmpd_subset->subset) { - if(H5D__compound_opt_read(smine_nelmts, mem_space, mem_iter, type_info, buf /*out*/) < 0) + if(H5D__compound_opt_read(smine_nelmts, mem_iter, type_info, buf /*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed") } /* end if */ else { if(H5T_BKG_YES == type_info->need_bkg) { - n = H5D__gather_mem(buf, mem_space, bkg_iter, smine_nelmts, type_info->bkg_buf/*out*/); + n = H5D__gather_mem(buf, bkg_iter, smine_nelmts, type_info->bkg_buf/*out*/); if(n != smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "mem gather failed") } /* end if */ @@ -562,7 +554,7 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf } /* Scatter the data into memory */ - if(H5D__scatter_mem(type_info->tconv_buf, mem_space, mem_iter, smine_nelmts, buf/*out*/) < 0) + if(H5D__scatter_mem(type_info->tconv_buf, mem_iter, smine_nelmts, buf/*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "scatter failed") } /* end else */ } /* end for */ @@ -635,13 +627,13 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator") /* Figure out the strip mine size. */ - if(H5S_select_iter_init(file_iter, file_space, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(file_iter, file_space, type_info->dst_type_size, H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information") file_iter_init = TRUE; /*file selection iteration info has been initialized */ - if(H5S_select_iter_init(mem_iter, mem_space, type_info->src_type_size) < 0) + if(H5S_select_iter_init(mem_iter, mem_space, type_info->src_type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information") mem_iter_init = TRUE; /*file selection iteration info has been initialized */ - if(H5S_select_iter_init(bkg_iter, file_space, type_info->dst_type_size) < 0) + if(H5S_select_iter_init(bkg_iter, file_space, type_info->dst_type_size, H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information") bkg_iter_init = TRUE; /*file selection iteration info has been initialized */ @@ -658,7 +650,7 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in * buffer. Also gather data from the file into the background buffer * if necessary. */ - n = H5D__gather_mem(buf, mem_space, mem_iter, smine_nelmts, type_info->tconv_buf/*out*/); + n = H5D__gather_mem(buf, mem_iter, smine_nelmts, type_info->tconv_buf/*out*/); if(n != smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed") @@ -675,7 +667,7 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in } /* end if */ else { if(H5T_BKG_YES == type_info->need_bkg) { - n = H5D__gather_file(io_info, file_space, bkg_iter, smine_nelmts, type_info->bkg_buf/*out*/); + n = H5D__gather_file(io_info, bkg_iter, smine_nelmts, type_info->bkg_buf/*out*/); if(n != smine_nelmts) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed") } /* end if */ @@ -705,7 +697,7 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in /* * Scatter the data out to the file. */ - if(H5D__scatter_file(io_info, file_space, file_iter, smine_nelmts, type_info->tconv_buf) < 0) + if(H5D__scatter_file(io_info, file_iter, smine_nelmts, type_info->tconv_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed") } /* end for */ @@ -761,7 +753,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__compound_opt_read(size_t nelmts, const H5S_t *space, H5S_sel_iter_t *iter, +H5D__compound_opt_read(size_t nelmts, H5S_sel_iter_t *iter, const H5D_type_info_t *type_info, void *user_buf/*out*/) { uint8_t *ubuf = (uint8_t *)user_buf; /* Cast for pointer arithmetic */ @@ -777,7 +769,6 @@ H5D__compound_opt_read(size_t nelmts, const H5S_t *space, H5S_sel_iter_t *iter, /* Check args */ HDassert(nelmts > 0); - HDassert(space); HDassert(iter); HDassert(type_info); HDassert(type_info->cmpd_subset); @@ -814,7 +805,7 @@ H5D__compound_opt_read(size_t nelmts, const H5S_t *space, H5S_sel_iter_t *iter, size_t elmtno; /* Element counter */ /* Get list of sequences for selection to write */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, vec_size, nelmts, &nseq, &elmtno, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, vec_size, nelmts, &nseq, &elmtno, off, len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed") /* Loop, while sequences left to process */ @@ -981,7 +972,7 @@ H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate selection iterator") /* Initialize selection iterator */ - if(H5S_select_iter_init(iter, dst_space, type_size) < 0) + if(H5S_select_iter_init(iter, dst_space, type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information") iter_init = TRUE; @@ -1005,7 +996,7 @@ H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback returned more elements than in selection") /* Scatter data */ - if(H5D__scatter_mem(src_buf, dst_space, iter, nelmts_scatter, dst_buf) < 0) + if(H5D__scatter_mem(src_buf, iter, nelmts_scatter, dst_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "scatter failed") nelmts -= (hssize_t)nelmts_scatter; @@ -1091,14 +1082,14 @@ H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate selection iterator") /* Initialize selection iterator */ - if(H5S_select_iter_init(iter, src_space, type_size) < 0) + if(H5S_select_iter_init(iter, src_space, type_size, 0) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information") iter_init = TRUE; /* Loop until all data has been scattered */ while(nelmts > 0) { /* Gather data */ - if(0 == (nelmts_gathered = H5D__gather_mem(src_buf, src_space, iter, MIN(dst_buf_nelmts, (size_t)nelmts), dst_buf))) + if(0 == (nelmts_gathered = H5D__gather_mem(src_buf, iter, MIN(dst_buf_nelmts, (size_t)nelmts), dst_buf))) HGOTO_ERROR(H5E_IO, H5E_CANTCOPY, FAIL, "gather failed") HDassert(nelmts_gathered == MIN(dst_buf_nelmts, (size_t)nelmts)); diff --git a/src/H5Dselect.c b/src/H5Dselect.c index 0ec3423..2f2ed66 100644 --- a/src/H5Dselect.c +++ b/src/H5Dselect.c @@ -175,12 +175,12 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator") /* Initialize file iterator */ - if(H5S_select_iter_init(file_iter, file_space, elmt_size) < 0) + if(H5S_select_iter_init(file_iter, file_space, elmt_size, H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") file_iter_init = 1; /* File selection iteration info has been initialized */ /* Initialize memory iterator */ - if(H5S_select_iter_init(mem_iter, mem_space, elmt_size) < 0) + if(H5S_select_iter_init(mem_iter, mem_space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") mem_iter_init = 1; /* Memory selection iteration info has been initialized */ @@ -193,7 +193,7 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, /* Check if more file sequences are needed */ if(curr_file_seq >= file_nseq) { /* Get sequences for file selection */ - if(H5S_SELECT_GET_SEQ_LIST(file_space, H5S_GET_SEQ_LIST_SORTED, file_iter, vec_size, nelmts, &file_nseq, &file_nelem, file_off, file_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(file_iter, vec_size, nelmts, &file_nseq, &file_nelem, file_off, file_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Start at the beginning of the sequences again */ @@ -203,7 +203,7 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, /* Check if more memory sequences are needed */ if(curr_mem_seq >= mem_nseq) { /* Get sequences for memory selection */ - if(H5S_SELECT_GET_SEQ_LIST(mem_space, 0, mem_iter, vec_size, nelmts, &mem_nseq, &mem_nelem, mem_off, mem_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(mem_iter, vec_size, nelmts, &mem_nseq, &mem_nelem, mem_off, mem_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Start at the beginning of the sequences again */ diff --git a/src/H5Sall.c b/src/H5Sall.c index 0aa2f05..083410a 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -51,9 +51,6 @@ /* Selection callbacks */ static herr_t H5S__all_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S__all_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__all_release(H5S_t *space); static htri_t H5S__all_is_valid(const H5S_t *space); static hssize_t H5S__all_serial_size(const H5S_t *space); @@ -66,10 +63,11 @@ static int H5S__all_unlim_dim(const H5S_t *space); static htri_t H5S__all_is_contiguous(const H5S_t *space); static htri_t H5S__all_is_single(const H5S_t *space); static htri_t H5S__all_is_regular(const H5S_t *space); +static htri_t H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2); static herr_t H5S__all_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__all_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S__all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static herr_t H5S__all_iter_init(const H5S_t *space, H5S_sel_iter_t *iter); /* Selection iteration callbacks */ static herr_t H5S__all_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); @@ -78,6 +76,8 @@ static hsize_t H5S__all_iter_nelmts(const H5S_sel_iter_t *iter); static htri_t H5S__all_iter_has_next_block(const H5S_sel_iter_t *iter); static herr_t H5S__all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); static herr_t H5S__all_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__all_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__all_iter_release(H5S_sel_iter_t *sel_iter); @@ -96,7 +96,6 @@ const H5S_select_class_t H5S_sel_all[1] = {{ /* Methods on selection */ H5S__all_copy, - H5S__all_get_seq_list, H5S__all_release, H5S__all_is_valid, H5S__all_serial_size, @@ -109,6 +108,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S__all_is_contiguous, H5S__all_is_single, H5S__all_is_regular, + H5S__all_shape_same, H5S__all_adjust_u, H5S__all_project_scalar, H5S__all_project_simple, @@ -131,6 +131,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{ H5S__all_iter_has_next_block, H5S__all_iter_next, H5S__all_iter_next_block, + H5S__all_iter_get_seq_list, H5S__all_iter_release, }}; @@ -149,7 +150,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5S__all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) +H5S__all_iter_init(const H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter) { FUNC_ENTER_STATIC_NOERR @@ -157,9 +158,6 @@ H5S__all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) HDassert(space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space)); HDassert(iter); - /* Initialize the number of elements to iterate over */ - iter->elmt_left = H5S_GET_SELECT_NPOINTS(space); - /* Start at the upper left location */ iter->u.all.elmt_offset = 0; iter->u.all.byte_offset = 0; @@ -362,13 +360,11 @@ H5S__all_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) /*-------------------------------------------------------------------------- NAME - H5S__all_get_seq_list + H5S__all_iter_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S__all_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation + herr_t H5S__all_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. size_t maxseq; IN: Maximum number of sequences to generate @@ -392,16 +388,14 @@ H5S__all_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__all_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, - size_t H5_ATTR_UNUSED maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__all_iter_get_seq_list(H5S_sel_iter_t *iter, size_t H5_ATTR_UNUSED maxseq, + size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { size_t elem_used; /* The number of elements used */ FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -431,7 +425,7 @@ H5S__all_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED iter->u.all.byte_offset += len[0]; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__all_get_seq_list() */ +} /* end H5S__all_iter_get_seq_list() */ /*-------------------------------------------------------------------------- @@ -892,6 +886,70 @@ H5S__all_is_regular(const H5S_t H5_ATTR_UNUSED *space) /*-------------------------------------------------------------------------- NAME + H5S__all_shape_same + PURPOSE + Check if a two "all" selections are the same shape + USAGE + htri_t H5S__all_shape_same(space1, space2) + const H5S_t *space1; IN: First dataspace to check + const H5S_t *space2; IN: Second dataspace to check + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in each dataspace are the same + shape. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2) +{ + int space1_dim; /* Current dimension in first dataspace */ + int space2_dim; /* Current dimension in second dataspace */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Check args */ + HDassert(space1); + HDassert(space2); + + /* Initialize dataspace dims */ + space1_dim = (int)space1->extent.rank - 1; + space2_dim = (int)space2->extent.rank - 1; + + /* Recall that space1_rank >= space2_rank. + * + * In the following while loop, we test to see if space1 and space2 + * have identical size in all dimensions they have in common. + */ + while(space2_dim >= 0) { + if(space1->extent.size[space1_dim] != space2->extent.size[space2_dim]) + HGOTO_DONE(FALSE) + + space1_dim--; + space2_dim--; + } /* end while */ + + /* Since we are selecting the entire space, we must also verify that space1 + * has size 1 in all dimensions that it does not share with space2. + */ + while(space1_dim >= 0) { + if(space1->extent.size[space1_dim] != 1) + HGOTO_DONE(FALSE) + + space1_dim--; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__all_shape_same() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__all_adjust_u PURPOSE Adjust an "all" selection by subtracting an offset diff --git a/src/H5Shyper.c b/src/H5Shyper.c index c9fab38..2857e13 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -40,46 +40,132 @@ /* Local Macros */ /****************/ +/* Macro for checking if two ranges overlap one another */ +/* + * Three possible conditions for overlapping: + * 1. The lower bound of range #1 is between the lower and + * higher bounds of range #2. In other words, the low + * part of range #1 will at least overlap with range #2. + * 2. The higher bound of range #1 is between the lower and + * higher bounds of range #2. In other words, the upper + * part of range #1 will at least overlap with range #2. + * 3. Range #1 includes range #2, i.e. the lower bound + * is smaller than that of range #2 and the higher bound + * is larger than that of range #2. + */ +/* (Assumes that low & high bounds are _inclusive_) */ +#define H5S_RANGE_OVERLAP(L1, H1, L2, H2) \ + /* condition 1 */ \ + (((L1) >= (L2) && (L1) <= (H2)) || \ + /* condition 2 */ \ + ((H1) >= (L2) && (H1) <= (H2)) || \ + /* condition 3 */ \ + ((L1) <= (L2) && (H1) >= (H2))) + +/* Flags for which hyperslab fragments to compute */ +#define H5S_HYPER_COMPUTE_B_NOT_A 0x01 +#define H5S_HYPER_COMPUTE_A_AND_B 0x02 +#define H5S_HYPER_COMPUTE_A_NOT_B 0x04 + +/* Macro to advance a span, possibly recycling it first */ +#define H5S_HYPER_ADVANCE_SPAN(recover, curr_span, next_span) \ + do { \ + H5S_hyper_span_t *saved_next_span = (next_span); \ + \ + /* Check if the span should be recovered */ \ + if(recover) { \ + H5S__hyper_free_span(curr_span); \ + (recover) = FALSE; \ + } /* end if */ \ + \ + /* Set the current span to saved next span */ \ + (curr_span) = saved_next_span; \ + } while(0) + +#ifdef H5_HAVE_THREADSAFE +/* + * The per-thread operation generation. pthread_once() initializes a special + * key that will be used by all threads to create a stack specific to + * each thread individually. The association of operation generations to threads + * will be handled by the pthread library. + * + * In order for this macro to work, H5S_hyper_get_my_op_gen() must be preceeded + * by "uint64_t *gen =". + */ +#define H5S_hyper_get_my_op_gen() H5S__hyper_op_gen() +#else /* H5_HAVE_THREADSAFE */ +/* + * The current operation generation. + */ +#define H5S_hyper_get_my_op_gen() (&H5S_hyper_op_gen_g) +#endif /* H5_HAVE_THREADSAFE */ + /******************/ /* Local Typedefs */ /******************/ +/* Define alias for hsize_t, for allocating H5S_hyper_span_info_t + bounds objects */ +/* (Makes it easier to understand the alloc / free calls) */ +typedef hsize_t hbounds_t; + /********************/ /* Local Prototypes */ /********************/ +#ifdef H5_HAVE_THREADSAFE +static uint64_t *H5S__hyper_op_gen(void); +#endif /* H5_HAVE_THREADSAFE */ static H5S_hyper_span_t *H5S__hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next); -static herr_t H5S__hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size); -static void H5S__hyper_span_scratch(H5S_hyper_span_info_t *spans); -static H5S_hyper_span_info_t *H5S__hyper_copy_span(H5S_hyper_span_info_t *spans); +static H5S_hyper_span_info_t *H5S__hyper_new_span_info(unsigned rank); +static H5S_hyper_span_info_t *H5S__hyper_copy_span(H5S_hyper_span_info_t *spans, + unsigned rank); static hbool_t H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_span_info_t *span_info2); -static herr_t H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info); -static herr_t H5S__hyper_free_span(H5S_hyper_span_t *span); -static hbool_t H5S__hyper_is_valid_helper(const H5S_hyper_span_info_t *spans, - const hssize_t *offset, const hsize_t *size); -static herr_t H5S__hyper_recover_span(hbool_t *recover, - H5S_hyper_span_t **curr_span, H5S_hyper_span_t *next_span); -static H5S_hyper_span_t *H5S__hyper_coord_to_span(unsigned rank, - const hsize_t *coords); -static herr_t H5S__hyper_append_span(H5S_hyper_span_t **prev_span, - H5S_hyper_span_info_t **span_tree, hsize_t low, hsize_t high, - H5S_hyper_span_info_t *down, H5S_hyper_span_t *next); +static void H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info); +static void H5S__hyper_free_span(H5S_hyper_span_t *span); +static herr_t H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, + hsize_t start[], hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, + hsize_t **buf); +static herr_t H5S__get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, + hsize_t numblocks, hsize_t *buf); +static H5S_hyper_span_t *H5S__hyper_coord_to_span(unsigned rank, const hsize_t *coords); +static herr_t H5S__hyper_append_span(H5S_hyper_span_info_t **span_tree, + unsigned ndims, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down); static herr_t H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, - H5S_hyper_span_info_t *b_spans, H5S_hyper_span_info_t **a_not_b, + H5S_hyper_span_info_t *b_spans, unsigned selector, + unsigned ndims, H5S_hyper_span_info_t **a_not_b, H5S_hyper_span_info_t **a_and_b, H5S_hyper_span_info_t **b_not_a); -static herr_t H5S__hyper_merge_spans(H5S_t *space, - H5S_hyper_span_info_t *new_spans, hbool_t can_own); -static hsize_t H5S__hyper_spans_nelem(const H5S_hyper_span_info_t *spans); +static herr_t H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans); +static hsize_t H5S__hyper_spans_nelem(H5S_hyper_span_info_t *spans); +static herr_t H5S__hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans); static H5S_hyper_span_info_t *H5S__hyper_make_spans(unsigned rank, - const hsize_t *start, const hsize_t *stride, const hsize_t *count, - const hsize_t *block); + const hsize_t *start, const hsize_t *stride, + const hsize_t *count, const hsize_t *block); +static herr_t H5S__hyper_update_diminfo(H5S_t *space, H5S_seloper_t op, + const H5S_hyper_dim_t *new_hyper_diminfo); static herr_t H5S__hyper_generate_spans(H5S_t *space); +static hbool_t H5S__check_spans_overlap(const H5S_hyper_span_info_t *spans1, + const H5S_hyper_span_info_t *spans2); +static herr_t H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, + H5S_hyper_span_info_t *space2_span_lst, hbool_t can_own_span2, + hbool_t *span2_owned, hbool_t *updated_spans, H5S_t **result); static herr_t H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]); +static herr_t H5S__set_regular_hyperslab(H5S_t *space, const hsize_t start[], + const hsize_t *app_stride, const hsize_t app_count[], const hsize_t *app_block, + const hsize_t *opt_stride, const hsize_t opt_count[], const hsize_t *opt_block); +static herr_t H5S__fill_in_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2, + H5S_t **result); +static H5S_t *H5S__combine_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2); +static herr_t H5S__hyper_iter_get_seq_list_gen(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len); +static herr_t H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len); +static herr_t H5S__hyper_iter_get_seq_list_single(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len); static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, hsize_t *block, hsize_t clip_size); static hsize_t H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, @@ -87,11 +173,9 @@ static hsize_t H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, /* Selection callbacks */ static herr_t H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S__hyper_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__hyper_release(H5S_t *space); static htri_t H5S__hyper_is_valid(const H5S_t *space); +static hsize_t H5S__hyper_span_nblocks(H5S_hyper_span_info_t *spans); static hssize_t H5S__hyper_serial_size(const H5S_t *space); static herr_t H5S__hyper_serialize(const H5S_t *space, uint8_t **p); static herr_t H5S__hyper_deserialize(H5S_t *space, uint32_t version, uint8_t flags, @@ -104,10 +188,11 @@ static herr_t H5S__hyper_num_elem_non_unlim(const H5S_t *space, static htri_t H5S__hyper_is_contiguous(const H5S_t *space); static htri_t H5S__hyper_is_single(const H5S_t *space); static htri_t H5S__hyper_is_regular(const H5S_t *space); +static htri_t H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2); static herr_t H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__hyper_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static herr_t H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter); /* Selection iteration callbacks */ static herr_t H5S__hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); @@ -116,12 +201,10 @@ static hsize_t H5S__hyper_iter_nelmts(const H5S_sel_iter_t *iter); static htri_t H5S__hyper_iter_has_next_block(const H5S_sel_iter_t *sel_iter); static herr_t H5S__hyper_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); static herr_t H5S__hyper_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__hyper_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__hyper_iter_release(H5S_sel_iter_t *sel_iter); -/* Static function for optimizing hyperslab */ -static hbool_t H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, - H5S_hyper_dim_t span_slab_info[], unsigned rank); -static hbool_t H5S__hyper_rebuild(H5S_t *space); /*****************************/ /* Library Private Variables */ @@ -138,7 +221,6 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ /* Methods on selection */ H5S__hyper_copy, - H5S__hyper_get_seq_list, H5S__hyper_release, H5S__hyper_is_valid, H5S__hyper_serial_size, @@ -151,6 +233,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S__hyper_is_contiguous, H5S__hyper_is_single, H5S__hyper_is_regular, + H5S__hyper_shape_same, H5S__hyper_adjust_u, H5S__hyper_project_scalar, H5S__hyper_project_simple, @@ -173,11 +256,10 @@ static const H5S_sel_iter_class_t H5S_sel_iter_hyper[1] = {{ H5S__hyper_iter_has_next_block, H5S__hyper_iter_next, H5S__hyper_iter_next_block, + H5S__hyper_iter_get_seq_list, H5S__hyper_iter_release, }}; -/* Static variables */ - /* Arrays for default stride, block, etc. */ static const hsize_t H5S_hyper_zeros_g[H5S_MAX_RANK] = { 0,0,0,0, 0,0,0,0, @@ -196,12 +278,19 @@ H5FL_DEFINE_STATIC(H5S_hyper_sel_t); /* Declare a free list to manage the H5S_hyper_span_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_span_t); -/* Declare a free list to manage the H5S_hyper_span_info_t struct */ -H5FL_DEFINE_STATIC(H5S_hyper_span_info_t); +/* Declare a free list to manage the H5S_hyper_span_info_t + hsize_t array struct */ +H5FL_BARR_DEFINE_STATIC(H5S_hyper_span_info_t, hbounds_t, H5S_MAX_RANK * 2); /* Declare extern free list to manage the H5S_sel_iter_t struct */ H5FL_EXTERN(H5S_sel_iter_t); +#ifndef H5_HAVE_THREADSAFE +static uint64_t H5S_hyper_op_gen_g = 1; /* Current operation generation */ + /* (Use '1' to avoid clashing with '0' value in newly allocated structs) */ +#endif /* H5_HAVE_THREADSAFE */ + + +/* Uncomment this, to provide the debugging routines for printing selection info */ /* #define H5S_HYPER_DEBUG */ #ifdef H5S_HYPER_DEBUG static herr_t @@ -210,9 +299,9 @@ H5S__hyper_print_spans_helper(FILE *f, const H5S_hyper_span_t *span, unsigned de FUNC_ENTER_STATIC_NOERR while(span) { - HDfprintf(f,"%s: depth=%u, span=%p, (%Hu, %Hu), nelem=%Hu, pstride=%Hu\n", FUNC, depth, span, span->low, span->high, span->nelem, span->pstride); - if(span->down && span->down->head) { - HDfprintf(f,"%s: spans=%p, count=%u, scratch=%p, head=%p\n", FUNC, span->down, span->down->count, span->down->scratch, span->down->head); + HDfprintf(f,"%s: %*sdepth=%u, span=%p, (%Hu, %Hu), next=%p\n", FUNC, depth * 2, "", depth, span, span->low, span->high, span->next); + if(span->down) { + HDfprintf(f,"%s: %*sspans=%p, count=%u, bounds[0]={%Hu, %Hu}, head=%p\n", FUNC, (depth + 1) * 2, "", span->down, span->down->count, span->down->low_bounds[0], span->down->high_bounds[0], span->down->head); H5S__hyper_print_spans_helper(f, span->down->head, depth + 1); } /* end if */ span = span->next; @@ -227,7 +316,7 @@ H5S__hyper_print_spans(FILE *f, const H5S_hyper_span_info_t *span_lst) FUNC_ENTER_STATIC_NOERR if(span_lst != NULL) { - HDfprintf(f, "%s: spans=%p, count=%u, scratch=%p, head=%p\n", FUNC, span_lst, span_lst->count, span_lst->scratch, span_lst->head); + HDfprintf(f, "%s: spans=%p, count=%u, bounds[0]={%Hu, %Hu}, head=%p\n", FUNC, span_lst, span_lst->count, span_lst->low_bounds[0], span_lst->high_bounds[0], span_lst->head); H5S__hyper_print_spans_helper(f, span_lst->head, 0); } /* end if */ @@ -276,13 +365,241 @@ H5S__hyper_print_diminfo(FILE *f, const H5S_t *space) { FUNC_ENTER_STATIC_NOERR - H5S__hyper_print_diminfo_helper(f, "opt_diminfo", space->extent.rank, space->select.sel_info.hslab->opt_diminfo); - H5S__hyper_print_diminfo_helper(f, "app_diminfo", space->extent.rank, space->select.sel_info.hslab->app_diminfo); + H5S__hyper_print_diminfo_helper(f, "diminfo.opt", space->extent.rank, space->select.sel_info.hslab->diminfo.opt); + H5S__hyper_print_diminfo_helper(f, "diminfo.app", space->extent.rank, space->select.sel_info.hslab->diminfo.app); FUNC_LEAVE_NOAPI(SUCCEED) } + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_print_spans_dfs + PURPOSE + Output the span elements for one span list in depth-first order + USAGE + herr_t H5S__hyper_print_spans_dfs(f, span_lst, depth) + FILE *f; IN: the file to output + const H5S_hyper_span_info_t *span_lst; IN: the span list to output + unsigned depth; IN: the level of this span list + RETURNS + non-negative on success, negative on failure + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_print_spans_dfs(FILE *f, const H5S_hyper_span_info_t *span_lst, + unsigned depth, unsigned dims) +{ + H5S_hyper_span_t *actual_tail = NULL; + H5S_hyper_span_t *cur_elem; + unsigned num_elems = 0; + unsigned u, elem_idx; + + FUNC_ENTER_STATIC_NOERR + + /* get the actual tail from head */ + cur_elem = span_lst->head; + HDassert(cur_elem); /* at least 1 element */ + while(cur_elem) { + actual_tail = cur_elem; + cur_elem = cur_elem->next; + num_elems++; + } /* end while */ + + for(u = 0; u < depth; u++) + HDfprintf(f, "\t"); + HDfprintf(f, "DIM[%u]: ref_count=%u, #elems=%u, head=%p, tail=%p, actual_tail=%p, matched=%t\n", depth, + span_lst->count, num_elems, span_lst->head, + span_lst->tail, actual_tail, (span_lst->tail == actual_tail)); + + for(u = 0; u < depth; u++) + HDfprintf(f, "\t"); + HDfprintf(f, "low_bounds=["); + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", span_lst->low_bounds[u]); + HDfprintf(f, "%llu]\n", span_lst->low_bounds[dims - 1]); + + for(u = 0; u < depth; u++) + HDfprintf(f, "\t"); + HDfprintf(f, "high_bounds=["); + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", span_lst->high_bounds[u]); + HDfprintf(f, "%llu]\n", span_lst->high_bounds[dims - 1]); + + cur_elem = span_lst->head; + elem_idx = 0; + while(cur_elem) { + for(u = 0; u < depth; u++) + HDfprintf(f, "\t"); + HDfprintf(f, "ELEM[%u]: ptr=%p, low=%Hu, high=%Hu, down=%p\n", + elem_idx++, cur_elem, cur_elem->low, cur_elem->high, cur_elem->down); + if(cur_elem->down) + H5S__hyper_print_spans_dfs(f, cur_elem->down, depth + 1, dims); + cur_elem = cur_elem->next; + } /* end while */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_print_spans_dfs() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_print_space_dfs + PURPOSE + Output the span elements for one hyperslab selection space in depth-first order + USAGE + herr_t H5S__hyper_print_space_dfs(f, space) + FILE *f; IN: the file to output + const H5S_t *space; IN: the selection space to output + RETURNS + non-negative on success, negative on failure + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_print_space_dfs(FILE *f, const H5S_t *space) +{ + const H5S_hyper_sel_t *hslab = space->select.sel_info.hslab; + const unsigned dims = space->extent.rank; + unsigned u; + + FUNC_ENTER_STATIC_NOERR + + HDassert(hslab); + + HDfprintf(f, "=======================\n"); + HDfprintf(f, "SPACE: span_lst=%p, #dims=%u, offset_changed=%d\n", hslab->span_lst, dims, space->select.offset_changed); + + HDfprintf(f, " offset=["); + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%lld,", space->select.offset[u]); + HDfprintf(f, "%lld]\n", space->select.offset[dims - 1]); + + HDfprintf(f, " low_bounds=["); + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", space->select.sel_info.hslab->diminfo.low_bounds[u]); + HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->diminfo.low_bounds[dims - 1]); + } /* end if */ + else { + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", space->select.sel_info.hslab->span_lst->low_bounds[u]); + HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->span_lst->low_bounds[dims - 1]); + } /* end else */ + + HDfprintf(f, " high_bounds=["); + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", space->select.sel_info.hslab->diminfo.high_bounds[u]); + HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->diminfo.high_bounds[dims - 1]); + } /* end if */ + else { + for(u = 0; u < dims - 1; u++) + HDfprintf(f, "%llu,", space->select.sel_info.hslab->span_lst->high_bounds[u]); + HDfprintf(f, "%llu]\n", space->select.sel_info.hslab->span_lst->high_bounds[dims - 1]); + } /* end else */ + + /* Print out diminfo, if it's valid */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) + H5S__hyper_print_diminfo(f, space); + + /* Start print out the highest-order of dimension */ + if(hslab->span_lst) + H5S__hyper_print_spans_dfs(f, hslab->span_lst, 0, dims); + HDfprintf(f, "=======================\n\n"); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5S__hyper_print_space_dfs() */ #endif /* H5S_HYPER_DEBUG */ +#ifdef H5_HAVE_THREADSAFE + +/*------------------------------------------------------------------------- + * Function: H5S__hyper_op_gen + * + * Purpose: Support function for H5S_hyper_get_my_op_gen() to initialize and + * acquire per-thread hyperslab operation generation. + * + * Return: Success: Non-NULL pointer to hyperslab operation generation for thread + * Failure: NULL + * + * Programmer: Quincey Koziol + * January 19, 2019 + * + *------------------------------------------------------------------------- + */ +static uint64_t * +H5S__hyper_op_gen(void) +{ + uint64_t *op_gen = NULL; + + FUNC_ENTER_STATIC_NOERR + + op_gen = (uint64_t *)H5TS_get_thread_local_value(H5TS_hyper_op_gen_key_g); + + if(!op_gen) { + /* No associated value with current thread - create one */ +#ifdef H5_HAVE_WIN_THREADS + /* Win32 has to use LocalAlloc to match the LocalFree in DllMain */ + op_gen = (uint64_t *)LocalAlloc(LPTR, sizeof(uint64_t)); +#else + /* Use HDmalloc here since this has to match the HDfree in the + * destructor and we want to avoid the codestack there. + */ + op_gen = (uint64_t *)HDmalloc(sizeof(uint64_t)); +#endif /* H5_HAVE_WIN_THREADS */ + HDassert(op_gen); + + /* Reset the thread-specific info */ + /* (Use '1' to avoid clashing with '0' value in newly allocated structs) */ + *op_gen = 1; + + /* (It's not necessary to release this in this API, it is + * released by the "key destructor" set up in the H5TS + * routines. See calls to pthread_key_create() in H5TS.c -QAK) + */ + H5TS_set_thread_local_value(H5TS_hyper_op_gen_key_g, (void *)op_gen); + } /* end if */ + + /* Set return value */ + FUNC_LEAVE_NOAPI(op_gen) +} /* end H5S__hyper_op_gen() */ +#endif /* H5_HAVE_THREADSAFE */ + + +/*------------------------------------------------------------------------- + * Function: H5S__hyper_get_op_gen + * + * Purpose: Acquire a unique operation generation value + * + * Return: Operation generation value (can't fail) + * + * Programmer: Quincey Koziol + * Saturday, January 19, 2019 + * + * Notes: Assumes that a 64-bit value will not wrap around during + * the lifespan of the process. + * + *------------------------------------------------------------------------- + */ +uint64_t +H5S__hyper_get_op_gen(void) +{ + uint64_t *op_gen = H5S_hyper_get_my_op_gen(); /* Get the pointer to the hyperslab operation generation, for this thread */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Check args */ + HDassert(op_gen); + + FUNC_LEAVE_NOAPI((*op_gen)++); +} /* end H5S__hyper_op_gen() */ + /*------------------------------------------------------------------------- * Function: H5S__hyper_iter_init @@ -294,7 +611,7 @@ H5S__hyper_print_diminfo(FILE *f, const H5S_t *space) * Programmer: Quincey Koziol * Saturday, February 24, 2001 * - * Notes: If the 'elmt_size' parameter is set to zero, the regular + * Notes: If the 'iter->elmt_size' field is set to zero, the regular * hyperslab selection iterator will not be 'flattened'. This * is used by the H5S_select_shape_same() code to avoid changing * the rank and appearance of the selection. @@ -302,37 +619,47 @@ H5S__hyper_print_diminfo(FILE *f, const H5S_t *space) *------------------------------------------------------------------------- */ static herr_t -H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) +H5S__hyper_iter_init(const H5S_t *space, H5S_sel_iter_t *iter) { - unsigned rank; /* Dataspace's dimension rank */ - unsigned u; /* Index variable */ + hsize_t *slab_size; /* Pointer to the dataspace dimensions to use for calc. slab */ + hsize_t acc; /* Accumulator for computing cumulative sizes */ + unsigned slab_dim; /* Rank of the fastest changing dimension for calc. slab */ + unsigned rank; /* Dataspace's dimension rank */ + unsigned u; /* Index variable */ + int i; /* Index variable */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC /* Check args */ HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); HDassert(iter); HDassert(space->select.sel_info.hslab->unlim_dim < 0); - /* Initialize the number of points to iterate over */ - iter->elmt_left = space->select.num_elem; + /* Initialize the hyperslab iterator's rank */ iter->u.hyp.iter_rank = 0; /* Get the rank of the dataspace */ - rank = space->extent.rank; + rank = iter->rank; + + /* Attempt to rebuild diminfo if it is invalid and has not been confirmed + * to be impossible. + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -NAF */ /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(space->select.sel_info.hslab->diminfo_valid) { + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { /* Initialize the information needed for regular hyperslab I/O */ const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ const hsize_t *mem_size; /* Temporary pointer to dataspace extent's dimension sizes */ unsigned cont_dim = 0; /* # of contiguous dimensions */ /* Set the temporary pointer to the dimension information */ - tdiminfo = space->select.sel_info.hslab->opt_diminfo; + tdiminfo = space->select.sel_info.hslab->diminfo.opt; /* Set the temporary pointer to the dataspace extent's dimension sizes */ - mem_size = space->extent.size; + mem_size = iter->dims; /* * For a regular hyperslab to be contiguous up to some dimension, it @@ -359,11 +686,9 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Check if the regular selection can be "flattened" */ if(cont_dim > 0) { - hsize_t acc; /* Accumulator for "flattened" dimension's sizes */ - hbool_t last_dim_flattened = TRUE; /* Flag to indicate that the last dimension was flattened */ + hbool_t last_dim_flattened = TRUE; /* Flag to indicate that the last dimension was flattened */ unsigned flat_rank = rank-cont_dim; /* Number of dimensions after flattening */ unsigned curr_dim; /* Current dimension */ - int i; /* Index variable */ /* Set the iterator's rank to the contiguous dimensions */ iter->u.hyp.iter_rank = flat_rank; @@ -392,7 +717,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) iter->u.hyp.diminfo[curr_dim].count = tdiminfo[i].count; iter->u.hyp.diminfo[curr_dim].block = tdiminfo[i].block * acc; iter->u.hyp.size[curr_dim] = mem_size[i] * acc; - iter->u.hyp.sel_off[curr_dim] = space->select.offset[i] * (hssize_t)acc; + iter->u.hyp.sel_off[curr_dim] = iter->sel_off[i] * (hssize_t)acc; /* Reset the "last dim flattened" flag to avoid flattened any further dimensions */ last_dim_flattened = FALSE; @@ -407,7 +732,7 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) iter->u.hyp.diminfo[curr_dim].count = tdiminfo[i].count; iter->u.hyp.diminfo[curr_dim].block = tdiminfo[i].block; iter->u.hyp.size[curr_dim] = mem_size[i]; - iter->u.hyp.sel_off[curr_dim] = space->select.offset[i]; + iter->u.hyp.sel_off[curr_dim] = iter->sel_off[i]; } /* end else */ /* Decrement "current" flattened dimension */ @@ -418,20 +743,23 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Initialize "flattened" iterator offset to initial location and dataspace extent and selection information to correct values */ for(u = 0; u < flat_rank; u++) iter->u.hyp.off[u] = iter->u.hyp.diminfo[u].start; + + /* Set up information for computing slab sizes */ + slab_dim = iter->u.hyp.iter_rank - 1; + slab_size = iter->u.hyp.size; } /* end if */ else { + /* Make local copy of the regular selection information */ + HDcompile_assert(sizeof(iter->u.hyp.diminfo) == sizeof(space->select.sel_info.hslab->diminfo.opt)); + HDmemcpy(iter->u.hyp.diminfo, tdiminfo, sizeof(iter->u.hyp.diminfo)); + /* Initialize position to initial location */ - /* Also make local copy of the regular selection information */ - for(u = 0; u < rank; u++) { - /* Regular selection information */ - iter->u.hyp.diminfo[u].start = tdiminfo[u].start; - iter->u.hyp.diminfo[u].stride = tdiminfo[u].stride; - iter->u.hyp.diminfo[u].count = tdiminfo[u].count; - iter->u.hyp.diminfo[u].block = tdiminfo[u].block; - - /* Position information */ + for(u = 0; u < rank; u++) iter->u.hyp.off[u] = tdiminfo[u].start; - } /* end if */ + + /* Set up information for computing slab sizes */ + slab_dim = iter->rank - 1; + slab_size = iter->dims; } /* end else */ /* Flag the diminfo information as valid in the iterator */ @@ -443,12 +771,10 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) else { /* Initialize the information needed for non-regular hyperslab I/O */ H5S_hyper_span_info_t *spans; /* Pointer to hyperslab span info node */ + /* Share the source dataspace's span tree by incrementing the reference count on it */ HDassert(space->select.sel_info.hslab->span_lst); - /* Make a copy of the span tree to iterate over */ - iter->u.hyp.spans = H5S__hyper_copy_span(space->select.sel_info.hslab->span_lst); - - /* Set the nelem & pstride values according to the element size */ - H5S__hyper_span_precompute(iter->u.hyp.spans, iter->elmt_size); + iter->u.hyp.spans = space->select.sel_info.hslab->span_lst; + iter->u.hyp.spans->count++; /* Initialize the starting span_info's and spans */ spans = iter->u.hyp.spans; @@ -467,14 +793,33 @@ H5S__hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) spans = spans->head->down; } /* end for */ + /* Set up information for computing slab sizes */ + slab_dim = iter->rank - 1; + slab_size = iter->dims; + /* Flag the diminfo information as not valid in the iterator */ iter->u.hyp.diminfo_valid = FALSE; } /* end else */ + /* Compute the cumulative size of dataspace dimensions */ + for(i = (int)slab_dim, acc = iter->elmt_size; i >= 0; i--) { + iter->u.hyp.slab[i] = acc; + acc *= slab_size[i]; + } /* end for */ + + /* Initialize more information for irregular hyperslab selections */ + if(!iter->u.hyp.diminfo_valid) { + /* Set the offset of the first element iterated on, in each dimension */ + for(u = 0; u < rank; u++) + /* Compute the sequential element offset */ + iter->u.hyp.loc_off[u] = ((hsize_t)((hssize_t)iter->u.hyp.off[u] + iter->sel_off[u])) * iter->u.hyp.slab[u]; + } /* end if */ + /* Initialize type of selection iterator */ iter->type = H5S_sel_iter_hyper; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_iter_init() */ @@ -602,13 +947,11 @@ H5S__hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) } /* end for */ } /* end if */ else { - /* Copy the start of the block */ - for(u = 0; u < iter->rank; u++) + /* Copy the start & end of the block */ + for(u = 0; u < iter->rank; u++) { start[u] = iter->u.hyp.span[u]->low; - - /* Copy the end of the block */ - for(u = 0; u < iter->rank; u++) end[u] = iter->u.hyp.span[u]->high; + } /* end for */ } /* end else */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -1079,12 +1422,11 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list_gen + H5S__hyper_iter_get_seq_list_gen PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S_select_hyper_get_file_list_gen(space,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. + herr_t H5S__hyper_iter_get_seq_list_gen(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. size_t maxseq; IN: Maximum number of sequences to generate @@ -1108,21 +1450,21 @@ H5S__hyper_iter_next_block(H5S_sel_iter_t *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__hyper_iter_get_seq_list_gen(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, + size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { H5S_hyper_span_t *curr_span; /* Current hyperslab span node */ H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */ - hsize_t slab[H5S_MAX_RANK]; /* Cumulative size of each dimension in bytes */ - hsize_t acc; /* Accumulator for computing cumulative sizes */ - hsize_t loc_off; /* Element offset in the dataspace */ + hsize_t *slab; /* Cumulative size of each dimension in bytes */ + hsize_t loc_off; /* Byte offset in the dataspace */ hsize_t last_span_end = 0; /* The offset of the end of the last span */ - hsize_t *abs_arr; /* Absolute hyperslab span position */ - const hssize_t *off_arr; /* Offset within the dataspace extent */ + hsize_t *abs_arr; /* Absolute hyperslab span position, in elements */ + hsize_t *loc_arr; /* Byte offset of hyperslab span position within buffer */ + const hssize_t *sel_off; /* Offset within the dataspace extent */ + size_t span_elmts = 0; /* Number of elements to actually use for this span */ size_t span_size = 0; /* Number of bytes in current span to actually process */ - size_t io_left; /* Number of elements left to process */ - size_t io_bytes_left; /* Number of bytes left to process */ + size_t io_left; /* Initial number of elements to process */ + size_t io_elmts_left; /* Number of elements left to process */ size_t io_used; /* Number of elements processed */ size_t curr_seq = 0; /* Number of sequence/offsets stored in the arrays */ size_t elem_size; /* Size of each element iterating over */ @@ -1130,12 +1472,10 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ int curr_dim; /* Current dimension being operated on */ unsigned u; /* Index variable */ - int i; /* Index variable */ FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -1145,45 +1485,39 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, HDassert(len); /* Set the rank of the fastest changing dimension */ - ndims = space->extent.rank; + ndims = iter->rank; fast_dim = (ndims - 1); /* Get the pointers to the current span info and span nodes */ curr_span = iter->u.hyp.span[fast_dim]; abs_arr = iter->u.hyp.off; - off_arr = space->select.offset; + loc_arr = iter->u.hyp.loc_off; + slab = iter->u.hyp.slab; + sel_off = iter->sel_off; ispan = iter->u.hyp.span; elem_size = iter->elmt_size; /* Set the amount of elements to perform I/O on, etc. */ H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); - io_left = MIN(maxelem, (size_t)iter->elmt_left); - io_bytes_left = io_left * elem_size; - - /* Compute the cumulative size of dataspace dimensions */ - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= space->extent.size[i]; - } /* end for */ + io_elmts_left = io_left = MIN(maxelem, (size_t)iter->elmt_left); /* Set the offset of the first element iterated on */ for(u = 0, loc_off = 0; u < ndims; u++) - /* Compute the sequential element offset */ - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; - - /* Range check against number of elements left in selection */ - HDassert(io_bytes_left <= (iter->elmt_left * elem_size)); + loc_off += loc_arr[u]; /* Take care of any partial spans leftover from previous I/Os */ if(abs_arr[fast_dim] != curr_span->low) { /* Finish the span in the fastest changing dimension */ - /* Compute the number of bytes to attempt in this span */ - H5_CHECKED_ASSIGN(span_size, size_t, ((curr_span->high - abs_arr[fast_dim])+1)*elem_size, hsize_t); + /* Compute the number of elements to attempt in this span */ + H5_CHECKED_ASSIGN(span_elmts, size_t, ((curr_span->high - abs_arr[fast_dim]) + 1), hsize_t); - /* Check number of bytes against upper bounds allowed */ - if(span_size > io_bytes_left) - span_size = io_bytes_left; + /* Check number of elements against upper bounds allowed */ + if(span_elmts > io_elmts_left) + span_elmts = io_elmts_left; + + /* Set the span_size, in bytes */ + span_size = span_elmts * elem_size; /* Add the partial span to the list of sequences */ off[curr_seq] = loc_off; @@ -1196,10 +1530,10 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, last_span_end = loc_off + span_size; /* Decrement I/O left to perform */ - io_bytes_left -= span_size; + io_elmts_left -= span_elmts; /* Check if we are done */ - if(io_bytes_left > 0) { + if(io_elmts_left > 0) { /* Move to next span in fastest changing dimension */ curr_span = curr_span->next; @@ -1209,15 +1543,21 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Move iterator for fastest changing dimension */ abs_arr[fast_dim] = curr_span->low; + loc_arr[fast_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[fast_dim])) * slab[fast_dim]; + ispan[fast_dim] = curr_span; } /* end if */ } /* end if */ else { /* Advance the hyperslab iterator */ - abs_arr[fast_dim] += span_size / elem_size; + abs_arr[fast_dim] += span_elmts; /* Check if we are still within the span */ if(abs_arr[fast_dim] <= curr_span->high) { - iter->u.hyp.span[fast_dim] = curr_span; + /* Sanity check */ + HDassert(ispan[fast_dim] == curr_span); + + /* Update byte offset */ + loc_arr[fast_dim] += span_size; } /* end if */ /* If we walked off that span, advance to the next span */ else { @@ -1228,7 +1568,12 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, if(NULL != curr_span) { /* Reset absolute position */ abs_arr[fast_dim] = curr_span->low; - iter->u.hyp.span[fast_dim] = curr_span; + + /* Update location offset */ + loc_arr[fast_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[fast_dim])) * slab[fast_dim]; + + /* Reset the span in the current dimension */ + ispan[fast_dim] = curr_span; } /* end if */ } /* end else */ } /* end else */ @@ -1243,13 +1588,16 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Work back up through the dimensions */ while(curr_dim >= 0) { /* Reset the current span */ - curr_span = iter->u.hyp.span[curr_dim]; + curr_span = ispan[curr_dim]; /* Increment absolute position */ abs_arr[curr_dim]++; /* Check if we are still within the span */ if(abs_arr[curr_dim] <= curr_span->high) { + /* Update location offset */ + loc_arr[curr_dim] += slab[curr_dim]; + break; } /* end if */ /* If we walked off that span, advance to the next span */ @@ -1265,6 +1613,9 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Reset absolute position */ abs_arr[curr_dim] = curr_span->low; + /* Update byte location */ + loc_arr[curr_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[curr_dim])) * slab[curr_dim]; + break; } /* end if */ else @@ -1285,49 +1636,58 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, curr_dim++; /* Set the new span_info & span for this dimension */ - iter->u.hyp.span[curr_dim] = curr_span->down->head; + ispan[curr_dim] = curr_span->down->head; /* Advance span down the tree */ curr_span = curr_span->down->head; /* Reset the absolute offset for the dim */ abs_arr[curr_dim] = curr_span->low; + + /* Update the location offset */ + loc_arr[curr_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[curr_dim])) * slab[curr_dim]; } /* end while */ /* Verify that the curr_span points to the fastest dim */ - HDassert(curr_span == iter->u.hyp.span[fast_dim]); + HDassert(curr_span == ispan[fast_dim]); /* Reset the buffer offset */ for(u = 0, loc_off = 0; u < ndims; u++) - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + loc_off += loc_arr[u]; } /* end else */ else /* We had better be done with I/O or bad things are going to happen... */ - HDassert(io_bytes_left == 0); + HDassert(io_elmts_left == 0); } /* end if */ } /* end if */ /* Perform the I/O on the elements, based on the position of the iterator */ - while(io_bytes_left > 0 && curr_seq < maxseq) { + while(io_elmts_left > 0 && curr_seq < maxseq) { + H5S_hyper_span_t *prev_span; /* Previous hyperslab span node */ + /* Sanity check */ HDassert(curr_span); - /* Adjust location offset of destination to compensate for initial increment below */ - loc_off -= curr_span->pstride; + /* Set to current span, so the first adjustment to loc_off is 0 */ + prev_span = curr_span; /* Loop over all the spans in the fastest changing dimension */ while(curr_span != NULL) { - /* Move location offset of destination */ - loc_off += curr_span->pstride; + hsize_t nelmts; /* # of elements covered by current span */ + + /* Move location offset of current span */ + loc_off += (curr_span->low - prev_span->low) * elem_size; /* Compute the number of elements to attempt in this span */ - H5_CHECKED_ASSIGN(span_size, size_t, curr_span->nelem, hsize_t); + nelmts = (curr_span->high - curr_span->low) + 1; + H5_CHECKED_ASSIGN(span_elmts, size_t, nelmts, hsize_t); /* Check number of elements against upper bounds allowed */ - if(span_size >= io_bytes_left) { - /* Trim the number of bytes to output */ - span_size = io_bytes_left; - io_bytes_left = 0; + if(span_elmts >= io_elmts_left) { + /* Trim the number of elements to output */ + span_elmts = io_elmts_left; + span_size = span_elmts * elem_size; + io_elmts_left = 0; /* COMMON */ /* Store the I/O information for the span */ @@ -1342,9 +1702,6 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Increment the number of sequences in arrays */ curr_seq++; } /* end else */ - - /* Set the location of the last span's end */ - last_span_end = loc_off + span_size; /* end COMMON */ /* Break out now, we are finished with I/O */ @@ -1352,7 +1709,8 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, } /* end if */ else { /* Decrement I/O left to perform */ - io_bytes_left -= span_size; + span_size = span_elmts * elem_size; + io_elmts_left -= span_elmts; /* COMMON */ /* Store the I/O information for the span */ @@ -1367,9 +1725,6 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Increment the number of sequences in arrays */ curr_seq++; } /* end else */ - - /* Set the location of the last span's end */ - last_span_end = loc_off + span_size; /* end COMMON */ /* If the sequence & offset arrays are full, do what? */ @@ -1378,18 +1733,30 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, break; } /* end else */ + /* Set the location of the last span's end */ + last_span_end = loc_off + span_size; + /* Move to next span in fastest changing dimension */ + prev_span = curr_span; curr_span = curr_span->next; } /* end while */ /* Check if we are done */ - if(io_bytes_left == 0 || curr_seq >= maxseq) { + if(io_elmts_left == 0 || curr_seq >= maxseq) { + /* Sanity checks */ HDassert(curr_span); - abs_arr[fast_dim] = curr_span->low + (span_size / elem_size); + + /* Update absolute position */ + abs_arr[fast_dim] = curr_span->low + span_elmts; /* Check if we are still within the span */ if(abs_arr[fast_dim] <= curr_span->high) { - iter->u.hyp.span[fast_dim]=curr_span; + /* Reset the span for the fast dimension */ + ispan[fast_dim] = curr_span; + + /* Update location offset */ + loc_arr[fast_dim] = ((hsize_t)((hssize_t)curr_span->low + (hssize_t)span_elmts + sel_off[fast_dim])) * slab[fast_dim]; + break; } /* end if */ /* If we walked off that span, advance to the next span */ @@ -1401,7 +1768,9 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, if(curr_span != NULL) { /* Reset absolute position */ abs_arr[fast_dim] = curr_span->low; - iter->u.hyp.span[fast_dim] = curr_span; + loc_arr[fast_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[fast_dim])) * slab[fast_dim]; + ispan[fast_dim] = curr_span; + break; } /* end if */ } /* end else */ @@ -1415,13 +1784,16 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Work back up through the dimensions */ while(curr_dim >= 0) { /* Reset the current span */ - curr_span=iter->u.hyp.span[curr_dim]; + curr_span = ispan[curr_dim]; /* Increment absolute position */ abs_arr[curr_dim]++; /* Check if we are still within the span */ - if(abs_arr[curr_dim]<=curr_span->high) { + if(abs_arr[curr_dim] <= curr_span->high) { + /* Update location offset */ + loc_arr[curr_dim] += slab[curr_dim]; + break; } /* end if */ /* If we walked off that span, advance to the next span */ @@ -1437,6 +1809,9 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Reset absolute position */ abs_arr[curr_dim] = curr_span->low; + /* Update location offset */ + loc_arr[curr_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[curr_dim])) * slab[curr_dim]; + break; } /* end if */ else @@ -1448,7 +1823,7 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, /* Check if we are finished with the spans in the tree */ if(curr_dim < 0) { /* We had better be done with I/O or bad things are going to happen... */ - HDassert(io_bytes_left == 0); + HDassert(io_elmts_left == 0); break; } /* end if */ else { @@ -1462,26 +1837,29 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, curr_dim++; /* Set the new span for the next dimension down */ - iter->u.hyp.span[curr_dim] = curr_span->down->head; + ispan[curr_dim] = curr_span->down->head; /* Advance span down the tree */ curr_span = curr_span->down->head; /* Reset the absolute offset for the dim */ abs_arr[curr_dim] = curr_span->low; + + /* Update location offset */ + loc_arr[curr_dim] = ((hsize_t)((hssize_t)curr_span->low + sel_off[curr_dim])) * slab[curr_dim]; } /* end while */ /* Verify that the curr_span points to the fastest dim */ - HDassert(curr_span == iter->u.hyp.span[fast_dim]); + HDassert(curr_span == ispan[fast_dim]); } /* end else */ /* Reset the buffer offset */ for(u = 0, loc_off = 0; u < ndims; u++) - loc_off += ((hsize_t)((hssize_t)abs_arr[u] + off_arr[u])) * slab[u]; + loc_off += loc_arr[u]; } /* end while */ /* Decrement number of elements left in iterator */ - io_used = (io_left - (io_bytes_left / elem_size)); + io_used = io_left - io_elmts_left; iter->elmt_left -= io_used; /* Set the number of sequences generated */ @@ -1491,17 +1869,16 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, *nelem = io_used; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_gen() */ +} /* end H5S__hyper_iter_get_seq_list_gen() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list_opt + H5S__hyper_iter_get_seq_list_opt PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S_select_hyper_get_file_list_opt(space,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. + herr_t H5S__hyper_iter_get_seq_list_opt(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. size_t maxseq; IN: Maximum number of sequences to generate @@ -1525,12 +1902,11 @@ H5S__hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter, REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, + size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { hsize_t *mem_size; /* Size of the source buffer */ - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + hsize_t *slab; /* Hyperslab size */ const hssize_t *sel_off; /* Selection offset in dataspace */ hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary block count */ @@ -1551,7 +1927,6 @@ H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Number of dimensions of dataset */ int temp_dim; /* Temporary rank holder */ - hsize_t acc; /* Accumulator */ hsize_t loc; /* Coordinate offset */ size_t curr_seq = 0; /* Current sequence being operated on */ size_t actual_elem; /* The actual number of elements to count */ @@ -1560,12 +1935,10 @@ H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, size_t start_io_left; /* The initial number of elements left in I/O operation */ size_t elem_size; /* Size of each element iterating over */ unsigned u; /* Local index variable */ - int i; /* Local index variable */ FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -1578,35 +1951,31 @@ H5S__hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter, tdiminfo = iter->u.hyp.diminfo; /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) { /* Set the aliases for a few important dimension ranks */ ndims = iter->u.hyp.iter_rank; - fast_dim = ndims - 1; /* Set the local copy of the selection offset */ sel_off = iter->u.hyp.sel_off; - /* Set up the pointer to the size of the memory space */ + /* Set up the pointer to the size of the memory dataspace */ mem_size = iter->u.hyp.size; } /* end if */ else { /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; - fast_dim = ndims - 1; + ndims = iter->rank; /* Set the local copy of the selection offset */ - sel_off = space->select.offset; + sel_off = iter->sel_off; - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; + /* Set up the pointer to the size of the memory dataspace */ + mem_size = iter->dims; } /* end else */ - /* initialize row sizes for each dimension */ + /* Set up some local variables */ + fast_dim = ndims - 1; elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; - } /* end for */ + slab = iter->u.hyp.slab; /* Calculate the number of elements to sequence through */ H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); @@ -1937,17 +2306,16 @@ loc += fast_dim_buf_off; *nelem += start_io_left - io_left; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_opt() */ +} /* end H5S__hyper_iter_get_seq_list_opt() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list_single + H5S__hyper_iter_get_seq_list_single PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S__hyper_get_seq_list_single(space, flags, iter, maxseq, maxelem, nseq, nelem, off, len) - H5S_t *space; IN: Dataspace containing selection to use. + herr_t H5S__hyper_iter_get_seq_list_single(flags, iter, maxseq, maxelem, nseq, nelem, off, len) unsigned flags; IN: Flags for extra information about operation H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. @@ -1972,18 +2340,16 @@ loc += fast_dim_buf_off; REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__hyper_iter_get_seq_list_single(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, + size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ const hssize_t *sel_off; /* Selection offset in dataspace */ hsize_t *mem_size; /* Size of the source buffer */ hsize_t base_offset[H5S_MAX_RANK]; /* Base coordinate offset in dataspace */ hsize_t offset[H5S_MAX_RANK]; /* Coordinate offset in dataspace */ - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + hsize_t *slab; /* Hyperslab size */ hsize_t fast_dim_block; /* Local copies of fastest changing dimension info */ - hsize_t acc; /* Accumulator */ hsize_t loc; /* Coordinate offset */ size_t tot_blk_count; /* Total number of blocks left to output */ size_t elem_size; /* Size of each element iterating over */ @@ -1993,12 +2359,10 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned skip_dim; /* Rank of the dimension to skip along */ unsigned u; /* Local index variable */ - int i; /* Local index variable */ FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -2011,34 +2375,31 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, tdiminfo = iter->u.hyp.diminfo; /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) { /* Set the aliases for a few important dimension ranks */ ndims = iter->u.hyp.iter_rank; /* Set the local copy of the selection offset */ sel_off = iter->u.hyp.sel_off; - /* Set up the pointer to the size of the memory space */ + /* Set up the pointer to the size of the memory dataspace */ mem_size = iter->u.hyp.size; } /* end if */ else { /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; + ndims = iter->rank; /* Set the local copy of the selection offset */ - sel_off = space->select.offset; + sel_off = iter->sel_off; - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; + /* Set up the pointer to the size of the memory dataspace */ + mem_size = iter->dims; } /* end else */ - fast_dim = ndims - 1; - /* initialize row sizes for each dimension */ + /* Set up some local variables */ + fast_dim = ndims - 1; elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; - } /* end for */ + slab = iter->u.hyp.slab; /* Copy the base location of the block */ /* (Add in the selection offset) */ @@ -2091,6 +2452,7 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, else { hsize_t skip_slab; /* Temporary copy of slab[fast_dim - 1] */ size_t blk_count; /* Total number of blocks left to output */ + int i; /* Local index variable */ /* Find first dimension w/block >1 */ skip_dim = fast_dim; @@ -2222,16 +2584,16 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, HDassert(*nelem > 0); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_get_seq_list_single() */ +} /* end H5S__hyper_iter_get_seq_list_single() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_get_seq_list + H5S__hyper_iter_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S__hyper_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) + herr_t H5S__hyper_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_t *space; IN: Dataspace containing selection to use. unsigned flags; IN: Flags for extra information about operation H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last @@ -2257,16 +2619,14 @@ H5S__hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter, REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__hyper_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { herr_t ret_value = FAIL; /* return value */ FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(iter->elmt_left > 0); HDassert(maxseq > 0); @@ -2275,13 +2635,11 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s HDassert(nelem); HDassert(off); HDassert(len); - HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(space->select.sel_info.hslab->diminfo_valid) { + if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ const hssize_t *sel_off; /* Selection offset in dataspace */ - hsize_t *mem_size; /* Size of the source buffer */ unsigned ndims; /* Number of dimensions of dataset */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ hbool_t single_block; /* Whether the selection is a single block */ @@ -2291,39 +2649,30 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s tdiminfo = iter->u.hyp.diminfo; /* Check if this is a "flattened" regular hyperslab selection */ - if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < space->extent.rank) { + if(iter->u.hyp.iter_rank != 0 && iter->u.hyp.iter_rank < iter->rank) { /* Set the aliases for a few important dimension ranks */ ndims = iter->u.hyp.iter_rank; /* Set the local copy of the selection offset */ sel_off = iter->u.hyp.sel_off; - - /* Set up the pointer to the size of the memory space */ - mem_size = iter->u.hyp.size; } /* end if */ else { /* Set the aliases for a few important dimension ranks */ - ndims = space->extent.rank; + ndims = iter->rank; /* Set the local copy of the selection offset */ - sel_off = space->select.offset; - - /* Set up the pointer to the size of the memory space */ - mem_size = space->extent.size; + sel_off = iter->sel_off; } /* end else */ fast_dim = ndims - 1; /* Check if we stopped in the middle of a sequence of elements */ if((iter->u.hyp.off[fast_dim] - tdiminfo[fast_dim].start) % tdiminfo[fast_dim].stride != 0 || ((iter->u.hyp.off[fast_dim] != tdiminfo[fast_dim].start) && tdiminfo[fast_dim].count == 1)) { - hsize_t slab[H5S_MAX_RANK]; /* Hyperslab size */ + hsize_t *slab; /* Hyperslab size */ hsize_t loc; /* Coordinate offset */ - hsize_t acc; /* Accumulator */ size_t leftover; /* The number of elements left over from the last sequence */ size_t actual_elem; /* The actual number of elements to count */ size_t elem_size; /* Size of each element iterating over */ - int i; /* Local index variable */ - /* Calculate the number of elements left in the sequence */ if(tdiminfo[fast_dim].count == 1) { @@ -2336,12 +2685,9 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s /* Make certain that we don't write too many */ actual_elem = MIN3(leftover, (size_t)iter->elmt_left, maxelem); - /* Initialize row sizes for each dimension */ + /* Set up some local variables */ elem_size = iter->elmt_size; - for(i = (int)fast_dim, acc = elem_size; i >= 0; i--) { - slab[i] = acc; - acc *= mem_size[i]; - } /* end for */ + slab = iter->u.hyp.slab; /* Compute the initial buffer offset */ for(u = 0, loc = 0; u < ndims; u++) @@ -2390,17 +2736,17 @@ H5S__hyper_get_seq_list(const H5S_t *space, unsigned H5_ATTR_UNUSED flags, H5S_s /* Check for single block selection */ if(single_block) /* Use single-block optimized call to generate sequence list */ - ret_value = H5S__hyper_get_seq_list_single(space, iter, maxseq, maxelem, nseq, nelem, off, len); + ret_value = H5S__hyper_iter_get_seq_list_single(iter, maxseq, maxelem, nseq, nelem, off, len); else /* Use optimized call to generate sequence list */ - ret_value = H5S__hyper_get_seq_list_opt(space, iter, maxseq, maxelem, nseq, nelem, off, len); + ret_value = H5S__hyper_iter_get_seq_list_opt(iter, maxseq, maxelem, nseq, nelem, off, len); } /* end if */ else /* Call the general sequence generator routine */ - ret_value = H5S__hyper_get_seq_list_gen(space, iter, maxseq, maxelem, nseq, nelem, off, len); + ret_value = H5S__hyper_iter_get_seq_list_gen(iter, maxseq, maxelem, nseq, nelem, off, len); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_get_seq_list() */ +} /* end H5S__hyper_iter_get_seq_list() */ /*-------------------------------------------------------------------------- @@ -2472,8 +2818,6 @@ H5S__hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, /* Copy the span's basic information */ ret_value->low = low; ret_value->high = high; - ret_value->nelem = (high - low) + 1; - ret_value->pstride = 0; ret_value->down = down; ret_value->next = next; @@ -2488,195 +2832,104 @@ done: /*-------------------------------------------------------------------------- NAME - H5S__hyper_span_precompute_helper + H5S__hyper_new_span_info PURPOSE - Helper routine to precompute the nelem and pstrides in bytes. + Make a new hyperslab span info node USAGE - void H5S__hyper_span_precompute_helper(span_info, elmt_size) - H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on - size_t elmt_size; IN: element size to work with + H5S_hyper_span_info_t *H5S__hyper_new_span_info(rank) + unsigned rank; IN: Rank of span info, in selection RETURNS - None + Pointer to new span node info on success, NULL on failure DESCRIPTION - Change the nelem and pstride values in the span tree from elements to - bytes using the elmt_size parameter. + Allocate and initialize a new hyperslab span info node of a given rank, + setting up the low & high bound array pointers. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Note that this uses the C99 "flexible array member" feature. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static void -H5S__hyper_span_precompute_helper(H5S_hyper_span_info_t *spans, size_t elmt_size) +static H5S_hyper_span_info_t * +H5S__hyper_new_span_info(unsigned rank) { - FUNC_ENTER_STATIC_NOERR - - /* Sanity checks */ - HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); - - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { - H5S_hyper_span_t *span; /* Hyperslab span */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); - - /* Set the scratch pointers in all the nodes */ - span = spans->head; + FUNC_ENTER_STATIC - /* Loop over all the spans for this down span tree */ - while(span != NULL) { - /* If there are down spans, precompute their values also */ - if(span->down != NULL) - H5S__hyper_span_precompute_helper(span->down, elmt_size); + /* Sanity check */ + HDassert(rank > 0); + HDassert(rank <= H5S_MAX_RANK); - /* Change the nelem & pstride values into bytes */ - span->nelem *= elmt_size; - span->pstride *= elmt_size; + /* Allocate a new span info node */ + if(NULL == (ret_value = (H5S_hyper_span_info_t *)H5FL_ARR_CALLOC(hbounds_t, rank * 2))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info") - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end if */ + /* Set low & high bound pointers into the 'bounds' array */ + ret_value->low_bounds = ret_value->bounds; + ret_value->high_bounds = &ret_value->bounds[rank]; - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_span_precompute_helper() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_new_span_info() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_span_precompute + H5S__hyper_copy_span_helper PURPOSE - Precompute the nelem and pstrides in bytes. + Helper routine to copy a hyperslab span tree USAGE - herr_t H5S__hyper_span_precompute(span_info, elmt_size) - H5S_hyper_span_info_t *span_info; IN/OUT: Span tree to work on - size_t elmt_size; IN: element size to work with + H5S_hyper_span_info_t * H5S__hyper_copy_span_helper(spans, rank) + H5S_hyper_span_info_t *spans; IN: Span tree to copy + unsigned rank; IN: Rank of span tree + uint64_t op_gen; IN: Operation generation RETURNS - Non-negative on success, negative on failure + Pointer to the copied span tree on success, NULL on failure DESCRIPTION - Change the nelem and pstride values in the span tree from elements to - bytes using the elmt_size parameter. + Copy a hyperslab span tree, using reference counting as appropriate. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size) +static H5S_hyper_span_info_t * +H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans, unsigned rank, + uint64_t op_gen) { - FUNC_ENTER_STATIC_NOERR + H5S_hyper_span_t *span; /* Hyperslab span */ + H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ + H5S_hyper_span_t *prev_span; /* Previous hyperslab span */ + H5S_hyper_span_info_t *new_down; /* New down span tree */ + H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_STATIC + /* Sanity checks */ HDassert(spans); - /* Call the helper routine to actually do the work */ - H5S__hyper_span_precompute_helper(spans, elmt_size); + /* Check if the span tree was already copied */ + if(spans->op_gen == op_gen) { + /* Just return the value of the already copied span tree */ + ret_value = spans->u.copied; - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(spans); + /* Increment the reference count of the span tree */ + ret_value->count++; + } /* end if */ + else { + /* Allocate a new span_info node */ + if(NULL == (ret_value = H5S__hyper_new_span_info(rank))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info") - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__hyper_span_precompute() */ + /* Set the non-zero span_info information */ + HDmemcpy(ret_value->low_bounds, spans->low_bounds, rank * sizeof(hsize_t)); + HDmemcpy(ret_value->high_bounds, spans->high_bounds, rank * sizeof(hsize_t)); + ret_value->count = 1; - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_span_scratch - PURPOSE - Reset the scratch pointers on hyperslab span trees - USAGE - void H5S__hyper_span_scratch(span_info) - H5S_hyper_span_info_t *span_info; IN: Span tree to reset - RETURNS - - DESCRIPTION - Reset the scratch pointers on a hyperslab span tree to NULL. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static void -H5S__hyper_span_scratch(H5S_hyper_span_info_t *spans) -{ - FUNC_ENTER_STATIC_NOERR + /* Set the operation generation for the span info, to avoid future copies */ + spans->op_gen = op_gen; - HDassert(spans); - - /* Check if we've already set this down span tree */ - if(spans->scratch != NULL) { - H5S_hyper_span_t *span; /* Hyperslab span */ - - /* Reset the tree's scratch pointer */ - spans->scratch = NULL; - - /* Set the scratch pointers in all the nodes */ - span = spans->head; - while(span != NULL) { - /* If there are down spans, set their scratch value also */ - if(span->down != NULL) - H5S__hyper_span_scratch(span->down); - - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end if */ - - FUNC_LEAVE_NOAPI_VOID -} /* end H5S__hyper_span_scratch() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_copy_span_helper - PURPOSE - Helper routine to copy a hyperslab span tree - USAGE - H5S_hyper_span_info_t * H5S__hyper_copy_span_helper(spans) - H5S_hyper_span_info_t *spans; IN: Span tree to copy - RETURNS - Pointer to the copied span tree on success, NULL on failure - DESCRIPTION - Copy a hyperslab span tree, using reference counting as appropriate. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static H5S_hyper_span_info_t * -H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans) -{ - H5S_hyper_span_t *span; /* Hyperslab span */ - H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ - H5S_hyper_span_t *prev_span; /* Previous hyperslab span */ - H5S_hyper_span_info_t *new_down; /* New down span tree */ - H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_STATIC - - /* Sanity checks */ - HDassert(spans); - HDassert(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)); - - /* Check if the span tree was already copied */ - if(spans->scratch != NULL) { - /* Just return the value of the already copied span tree */ - ret_value = spans->scratch; - - /* Increment the reference count of the span tree */ - ret_value->count++; - } /* end if */ - else { - /* Allocate a new span_info node */ - if(NULL == (ret_value = H5FL_CALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info") - - /* Copy the span_info information */ - ret_value->count = 1; - - /* Set the scratch pointer in the node being copied to the newly allocated node */ - spans->scratch = ret_value; + /* Set the 'copied' pointer in the node being copied to the newly allocated node */ + spans->u.copied = ret_value; /* Copy over the nodes in the span list */ span = spans->head; @@ -2692,12 +2945,9 @@ H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans) else prev_span->next = new_span; - /* Copy the pstride */ - new_span->pstride = span->pstride; - /* Recurse to copy the 'down' spans, if there are any */ if(span->down != NULL) { - if(NULL == (new_down = H5S__hyper_copy_span_helper(span->down))) + if(NULL == (new_down = H5S__hyper_copy_span_helper(span->down, rank - 1, op_gen))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab spans") new_span->down = new_down; } /* end if */ @@ -2708,6 +2958,9 @@ H5S__hyper_copy_span_helper(H5S_hyper_span_info_t *spans) /* Advance to next span */ span = span->next; } /* end while */ + + /* Retain a pointer to the last span */ + ret_value->tail = prev_span; } /* end else */ done: @@ -2721,10 +2974,11 @@ done: PURPOSE Copy a hyperslab span tree USAGE - H5S_hyper_span_info_t * H5S__hyper_copy_span(span_info) - H5S_hyper_span_info_t *span_info; IN: Span tree to copy + H5S_hyper_span_info_t * H5S__hyper_copy_span(span_info, rank) + H5S_hyper_span_info_t *span_info; IN: Span tree to copy + unsigned rank; IN: Rank of span tree RETURNS - Non-negative on success, negative on failure + Pointer to the copied span tree on success, NULL on failure DESCRIPTION Copy a hyperslab span tree, using reference counting as appropriate. (Which means that just the nodes in the top span tree are duplicated and @@ -2735,8 +2989,9 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static H5S_hyper_span_info_t * -H5S__hyper_copy_span(H5S_hyper_span_info_t *spans) +H5S__hyper_copy_span(H5S_hyper_span_info_t *spans, unsigned rank) { + uint64_t op_gen; /* Operation generation value */ H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -2744,13 +2999,13 @@ H5S__hyper_copy_span(H5S_hyper_span_info_t *spans) /* Sanity check */ HDassert(spans); + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); + /* Copy the hyperslab span tree */ - if(NULL == (ret_value = H5S__hyper_copy_span_helper(spans))) + if(NULL == (ret_value = H5S__hyper_copy_span_helper(spans, rank, op_gen))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(spans); - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_copy_span() */ @@ -2779,72 +3034,75 @@ static H5_ATTR_PURE hbool_t H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_span_info_t *span_info2) { - hbool_t ret_value = FALSE; /* Return value */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC_NOERR /* Check for redundant comparison (or both spans being NULL) */ - if(span_info1 == span_info2) - ret_value = TRUE; - else { + if(span_info1 != span_info2) { /* Check for one span being NULL */ if(span_info1 == NULL || span_info2 == NULL) - ret_value = FALSE; + HGOTO_DONE(FALSE) else { - const H5S_hyper_span_t *span1; - const H5S_hyper_span_t *span2; - - /* Get the pointers to the actual lists of spans */ - span1 = span_info1->head; - span2 = span_info2->head; - - /* Sanity checking */ - HDassert(span1); - HDassert(span2); - - /* infinite loop which must be broken out of */ - while(1) { - /* Check for both spans being NULL */ - if(span1 == NULL && span2 == NULL) { - ret_value = TRUE; - break; - } /* end if */ - else { - /* Check for one span being NULL */ - if(span1 == NULL || span2 == NULL) { - ret_value = FALSE; - break; - } /* end if */ + /* Compare low & high bounds for this span list */ + /* (Could compare lower dimensions also, but not certain if + * that's worth it. - QAK, 2019/01/23) + */ + if(span_info1->low_bounds[0] != span_info2->low_bounds[0]) + HGOTO_DONE(FALSE) + else if(span_info1->high_bounds[0] != span_info2->high_bounds[0]) + HGOTO_DONE(FALSE) + else { + const H5S_hyper_span_t *span1; + const H5S_hyper_span_t *span2; + + /* Get the pointers to the actual lists of spans */ + span1 = span_info1->head; + span2 = span_info2->head; + + /* Sanity checking */ + HDassert(span1); + HDassert(span2); + + /* infinite loop which must be broken out of */ + while(1) { + /* Check for both spans being NULL */ + if(span1 == NULL && span2 == NULL) + HGOTO_DONE(TRUE) else { - /* Check if the actual low & high span information is the same */ - if(span1->low != span2->low || span1->high != span2->high) { - ret_value = FALSE; - break; - } /* end if */ + /* Check for one span being NULL */ + if(span1 == NULL || span2 == NULL) + HGOTO_DONE(FALSE) else { - if(span1->down != NULL || span2 != NULL) { - if(!H5S__hyper_cmp_spans(span1->down, span2->down)) { - ret_value = FALSE; - break; + /* Check if the actual low & high span information is the same */ + if(span1->low != span2->low || span1->high != span2->high) + HGOTO_DONE(FALSE) + else { + if(span1->down != NULL || span2->down != NULL) { + if(!H5S__hyper_cmp_spans(span1->down, span2->down)) + HGOTO_DONE(FALSE) + else { + /* Keep going... */ + } /* end else */ } /* end if */ else { /* Keep going... */ } /* end else */ - } /* end if */ - else { - /* Keep going... */ } /* end else */ } /* end else */ } /* end else */ - } /* end else */ - /* Advance to the next nodes in the span list */ - span1 = span1->next; - span2 = span2->next; - } /* end while */ + /* Advance to the next nodes in the span list */ + span1 = span1->next; + span2 = span2->next; + } /* end while */ + } /* end else */ } /* end else */ - } /* end else */ + } /* end if */ + + /* Fall through, with default return value of 'TRUE' if spans were already visited */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_cmp_spans() */ @@ -2855,10 +3113,10 @@ H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, PURPOSE Free a hyperslab span info node USAGE - herr_t H5S__hyper_free_span_info(span_info) + void H5S__hyper_free_span_info(span_info) H5S_hyper_span_info_t *span_info; IN: Span info node to free RETURNS - Non-negative on success, negative on failure + None DESCRIPTION Free a hyperslab span info node, along with all the span nodes and the 'down spans' from the nodes, if reducing their reference count to zero @@ -2868,14 +3126,12 @@ H5S__hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t +static void H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) { - H5S_hyper_span_t *span, *next_span; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR + /* Sanity check */ HDassert(span_info); /* Decrement the span tree's reference count */ @@ -2883,22 +3139,28 @@ H5S__hyper_free_span_info(H5S_hyper_span_info_t *span_info) /* Free the span tree if the reference count drops to zero */ if(span_info->count == 0) { + H5S_hyper_span_t *span; /* Pointer to spans to iterate over */ /* Work through the list of spans pointed to by this 'info' node */ span = span_info->head; while(span != NULL) { + H5S_hyper_span_t *next_span; /* Pointer to next span to iterate over */ + + /* Keep a pointer to the next span */ next_span = span->next; - if(H5S__hyper_free_span(span) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span") + + /* Free the current span */ + H5S__hyper_free_span(span); + + /* Advance to next span */ span = next_span; } /* end while */ /* Free this span info */ - span_info = H5FL_FREE(H5S_hyper_span_info_t, span_info); + span_info = (H5S_hyper_span_info_t *)H5FL_ARR_FREE(hbounds_t, span_info); } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI_VOID } /* end H5S__hyper_free_span_info() */ @@ -2908,10 +3170,10 @@ done: PURPOSE Free a hyperslab span node USAGE - herr_t H5S__hyper_free_span(span) + void H5S__hyper_free_span(span) H5S_hyper_span_t *span; IN: Span node to free RETURNS - Non-negative on success, negative on failure + None DESCRIPTION Free a hyperslab span node, along with the 'down spans' from the node, if reducing their reference count to zero indicates it is appropriate to @@ -2921,25 +3183,22 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t +static void H5S__hyper_free_span(H5S_hyper_span_t *span) { - herr_t ret_value = SUCCEED; - - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR + /* Sanity check */ HDassert(span); /* Decrement the reference count of the 'down spans', freeing them if appropriate */ if(span->down != NULL) - if(H5S__hyper_free_span_info(span->down) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab span tree") + H5S__hyper_free_span_info(span->down); /* Free this span */ span = H5FL_FREE(H5S_hyper_span_t, span); -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI_VOID } /* end H5S__hyper_free_span() */ @@ -2954,7 +3213,7 @@ done: H5S_t *src; IN: Pointer to the source dataspace hbool_t; IN: Whether to share the selection between the dataspaces RETURNS - Non-negative on success/Negative on failure + Non-negative on success, negative on failure DESCRIPTION Copies all the hyperslab selection information from the source dataspace to the destination dataspace. @@ -2991,15 +3250,8 @@ H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) /* Copy the hyperslab information */ dst_hslab->diminfo_valid = src_hslab->diminfo_valid; - if(src_hslab->diminfo_valid) { - size_t u; /* Local index variable */ - - for(u=0; uextent.rank; u++) { - dst_hslab->opt_diminfo[u]=src_hslab->opt_diminfo[u]; - dst_hslab->app_diminfo[u]=src_hslab->app_diminfo[u]; - } /* end for */ - } /* end if */ - dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst; + if(src_hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) + HDmemcpy(&dst_hslab->diminfo, &src_hslab->diminfo, sizeof(H5S_hyper_diminfo_t)); /* Check if there is hyperslab span information to copy */ /* (Regular hyperslab information is copied with the selection structure) */ @@ -3011,7 +3263,7 @@ H5S__hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) } /* end if */ else /* Copy the hyperslab span information */ - dst->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(src->select.sel_info.hslab->span_lst); + dst->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(src->select.sel_info.hslab->span_lst, src->extent.rank); } /* end if */ else dst->select.sel_info.hslab->span_lst = NULL; @@ -3027,18 +3279,16 @@ done: /*-------------------------------------------------------------------------- NAME - H5S__hyper_is_valid_helper + H5S__hyper_is_valid PURPOSE Check whether the selection fits within the extent, with the current offset defined. USAGE - hbool_t H5S__hyper_is_valid_helper(spans, offset, rank); - const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree - const hssize_t *offset; IN: Pointer to offset array - const hsize_t *size; IN: Pointer to size array - hsize_t rank; IN: Current rank looking at + htri_t H5S__hyper_is_valid(space); + H5S_t *space; IN: Dataspace pointer to query RETURNS - TRUE if the selection fits within the extent, FALSE if it does not + TRUE if the selection fits within the extent, FALSE if it does not and + Negative on an error. DESCRIPTION Determines if the current selection at the current offset fits within the extent for the dataspace. @@ -3047,109 +3297,109 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_is_valid_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, - const hsize_t *size) +static htri_t +H5S__hyper_is_valid(const H5S_t *space) { - H5S_hyper_span_t *curr; /* Hyperslab information nodes */ - hbool_t ret_value = TRUE; /* Return value */ + const hsize_t *low_bounds, *high_bounds; /* Pointers to the correct pair of low & high bounds */ + unsigned u; /* Counter */ + htri_t ret_value = TRUE; /* return value */ FUNC_ENTER_STATIC_NOERR - HDassert(spans); - HDassert(offset); - HDassert(size); + HDassert(space); - /* Check each point to determine whether selection + offset is within extent */ - curr = spans->head; - while(curr != NULL) { - /* Check if an offset has been defined */ - /* Bounds check the selected point + offset against the extent */ - if((((hssize_t)curr->low + *offset) >= (hssize_t)*size) - || (((hssize_t)curr->low + *offset) < 0) - || (((hssize_t)curr->high + *offset) >= (hssize_t)*size) - || (((hssize_t)curr->high + *offset) < 0)) - HGOTO_DONE(FALSE) + /* Check for unlimited selection */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_DONE(FALSE) - /* Recurse if this node has down spans */ - if(curr->down != NULL) - if(!H5S__hyper_is_valid_helper(curr->down, offset + 1, size + 1)) - HGOTO_DONE(FALSE) + /* Check which set of low & high bounds we should be using */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + low_bounds = space->select.sel_info.hslab->diminfo.low_bounds; + high_bounds = space->select.sel_info.hslab->diminfo.high_bounds; + } /* end if */ + else { + low_bounds = space->select.sel_info.hslab->span_lst->low_bounds; + high_bounds = space->select.sel_info.hslab->span_lst->high_bounds; + } /* end else */ - /* Advance to next node */ - curr = curr->next; - } /* end while */ + /* Check each dimension */ + for(u = 0; u < space->extent.rank; u++) { + /* Bounds check the selected point + offset against the extent */ + if(((hssize_t)low_bounds[u] + space->select.offset[u]) < 0) + HGOTO_DONE(FALSE) + if((high_bounds[u] + (hsize_t)space->select.offset[u]) >= space->extent.size[u]) + HGOTO_DONE(FALSE) + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_valid_helper() */ +} /* end H5S__hyper_is_valid() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_is_valid + H5S__hyper_span_nblocks_helper PURPOSE - Check whether the selection fits within the extent, with the current - offset defined. + Helper routine to count the number of blocks in a span tree USAGE - htri_t H5S__hyper_is_valid(space); - H5S_t *space; IN: Dataspace pointer to query + hsize_t H5S__hyper_span_nblocks_helper(spans) + H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count blocks of + uint64_t op_gen; IN: Operation generation RETURNS - TRUE if the selection fits within the extent, FALSE if it does not and - Negative on an error. + Number of blocks in span tree on success; negative on failure DESCRIPTION - Determines if the current selection at the current offset fits within the - extent for the dataspace. + Counts the number of blocks described by the spans in a span tree. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static htri_t -H5S__hyper_is_valid(const H5S_t *space) +static hsize_t +H5S__hyper_span_nblocks_helper(H5S_hyper_span_info_t *spans, uint64_t op_gen) { - htri_t ret_value = TRUE; /* return value */ + hsize_t ret_value = 0; /* Return value */ FUNC_ENTER_STATIC_NOERR - HDassert(space); + /* Sanity check */ + HDassert(spans); - /* Check for unlimited selection */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_DONE(FALSE) + /* Check if the span tree was already counted */ + if(spans->op_gen == op_gen) + /* Just return the # of blocks in the already counted span tree */ + ret_value = spans->u.nblocks; + else { /* Count the number of elements in the span tree */ + H5S_hyper_span_t *span; /* Hyperslab span */ - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ - hssize_t end; /* The high bound of a region in a dimension */ - unsigned u; /* Counter */ + span = spans->head; + if(span->down) { + while(span) { + /* If there are down spans, add the total down span blocks */ + ret_value += H5S__hyper_span_nblocks_helper(span->down, op_gen); - /* Check each dimension */ - for(u = 0; u < space->extent.rank; u++) { - /* if block or count is zero, then can skip the test since */ - /* no data point is chosen */ - if(diminfo[u].count && diminfo[u].block) { - /* Bounds check the start point in this dimension */ - if(((hssize_t)diminfo[u].start + space->select.offset[u]) < 0 || - ((hssize_t)diminfo[u].start + space->select.offset[u]) >= (hssize_t)space->extent.size[u]) - HGOTO_DONE(FALSE) + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end if */ + else { + while(span) { + /* If there are no down spans, just count the block in this span */ + ret_value++; - /* Compute the largest location in this dimension */ - end = (hssize_t)(diminfo[u].start + diminfo[u].stride * (diminfo[u].count - 1) + (diminfo[u].block - 1)) + space->select.offset[u]; + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end else */ - /* Bounds check the end point in this dimension */ - if(end < 0 || end >= (hssize_t)space->extent.size[u]) - HGOTO_DONE(FALSE) - } /* end if */ - } /* end for */ - } /* end if */ - else - /* Call the recursive routine to validate the span tree */ - ret_value = H5S__hyper_is_valid_helper(space->select.sel_info.hslab->span_lst, space->select.offset, space->extent.size); + /* Set the operation generation for this span tree, to avoid re-computing */ + spans->op_gen = op_gen; + + /* Hold a copy of the # of blocks */ + spans->u.nblocks = ret_value; + } /* end else */ -done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_is_valid() */ +} /* end H5S__hyper_span_nblocks_helper() */ /*-------------------------------------------------------------------------- @@ -3159,7 +3409,7 @@ done: Count the number of blocks in a span tree USAGE hsize_t H5S__hyper_span_nblocks(spans) - const H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count elements of + H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to count blocks of RETURNS Number of blocks in span tree on success; negative on failure DESCRIPTION @@ -3170,7 +3420,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static hsize_t -H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans) +H5S__hyper_span_nblocks(H5S_hyper_span_info_t *spans) { hsize_t ret_value = 0; /* Return value */ @@ -3178,21 +3428,13 @@ H5S__hyper_span_nblocks(const H5S_hyper_span_info_t *spans) /* Count the number of elements in the span tree */ if(spans != NULL) { - H5S_hyper_span_t *span; /* Hyperslab span */ + uint64_t op_gen; /* Operation generation value */ - span = spans->head; - while(span != NULL) { - /* If there are down spans, add the total down span blocks */ - if(span->down != NULL) - ret_value += H5S__hyper_span_nblocks(span->down); - /* If there are no down spans, just count the block in this span */ - else - ret_value++; + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); - /* Advance to next span */ - span = span->next; - } /* end while */ - } /* end else */ + ret_value = H5S__hyper_span_nblocks_helper(spans, op_gen); + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_span_nblocks() */ @@ -3226,12 +3468,13 @@ H5S__get_select_hyper_nblocks(const H5S_t *space) HDassert(space->select.sel_info.hslab->unlim_dim < 0); /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { unsigned u; /* Local index variable */ /* Check each dimension */ for(ret_value = 1, u = 0; u < space->extent.rank; u++) - ret_value *= space->select.sel_info.hslab->app_diminfo[u].count; + ret_value *= space->select.sel_info.hslab->diminfo.app[u].count; } /* end if */ else ret_value = H5S__hyper_span_nblocks(space->select.sel_info.hslab->span_lst); @@ -3333,10 +3576,13 @@ H5S__hyper_serial_size(const H5S_t *space) ret_value = 24; /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { + /* (It would be useful to rebuild the regular hyperslab selection, if we + * encoded it efficiently, which we aren't currently. *sigh* -QAK) + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { /* Check each dimension */ for(block_count = 1, u = 0; u < space->extent.rank; u++) - block_count *= space->select.sel_info.hslab->opt_diminfo[u].count; + block_count *= space->select.sel_info.hslab->diminfo.opt[u].count; } /* end if */ else /* Spin through hyperslab spans, adding 8 * rank bytes for each block */ @@ -3494,22 +3740,25 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p) /* If there is an unlimited dimension, only encode opt_unlim_diminfo */ if(flags & H5S_SELECT_FLAG_UNLIM) { - unsigned i; + unsigned u; HDassert(H5S_UNLIMITED == HSIZE_UNDEF); /* Iterate over dimensions */ - for(i = 0; i < space->extent.rank; i++) { + for(u = 0; u < space->extent.rank; u++) { /* Encode start/stride/block/count */ - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].start); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].stride); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].count); - UINT64ENCODE(pp, space->select.sel_info.hslab->opt_diminfo[i].block); + UINT64ENCODE(pp, space->select.sel_info.hslab->diminfo.opt[u].start); + UINT64ENCODE(pp, space->select.sel_info.hslab->diminfo.opt[u].stride); + UINT64ENCODE(pp, space->select.sel_info.hslab->diminfo.opt[u].count); + UINT64ENCODE(pp, space->select.sel_info.hslab->diminfo.opt[u].block); } /* end for */ } /* end if */ /* Check for a "regular" hyperslab selection */ - else if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ + /* (It would be useful to rebuild the regular hyperslab selection, if we + * encoded it efficiently, which we aren't currently. *sigh* -QAK) + */ + else if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ @@ -3520,7 +3769,7 @@ H5S__hyper_serialize(const H5S_t *space, uint8_t **p) /* Set some convenience values */ ndims = space->extent.rank; fast_dim = ndims - 1; - diminfo = space->select.sel_info.hslab->opt_diminfo; + diminfo = space->select.sel_info.hslab->diminfo.opt; /* Check each dimension */ for(block_count = 1, u = 0; u < ndims; u++) @@ -3780,7 +4029,6 @@ H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t **buf) { const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */ - hsize_t u; /* Index variable */ herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_STATIC @@ -3818,19 +4066,19 @@ H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], /* Encode all the previous dimensions starting & ending points */ /* Copy previous starting points */ - for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &start[u], sizeof(hsize_t)); + HDmemcpy(*buf, start, rank * sizeof(hsize_t)); + (*buf) += rank; /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->low, sizeof(hsize_t)); + **buf = curr->low; (*buf)++; /* Copy previous ending points */ - for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &end[u], sizeof(hsize_t)); + HDmemcpy(*buf, end, rank * sizeof(hsize_t)); + (*buf) += rank; - /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->high, sizeof(hsize_t)); + /* Copy ending point for this span */ + **buf = curr->high; (*buf)++; /* Decrement the number of blocks processed */ @@ -3878,7 +4126,8 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblock, hsize_t numblocks, hsize_t *buf) +H5S__get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, + hsize_t numblocks, hsize_t *buf) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3888,11 +4137,18 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo HDassert(buf); HDassert(space->select.sel_info.hslab->unlim_dim < 0); + /* Attempt to rebuild diminfo if it is invalid and has not been confirmed + * to be impossible. + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild(space); + /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary hyperslab counts */ hsize_t offset[H5S_MAX_RANK]; /* Offset of element in dataspace */ + hsize_t end[H5S_MAX_RANK]; /* End of elements in dataspace */ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */ unsigned ndims; /* Rank of the dataspace */ hbool_t done; /* Whether we are done with the iteration */ @@ -3903,31 +4159,25 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo fast_dim = ndims - 1; /* Check which set of dimension information to use */ - if(internal) + if(space->select.sel_info.hslab->unlim_dim >= 0) /* - * Use the "optimized dimension information" to pass back information - * on the blocks set, not the "application information". + * There is an unlimited dimension so we must use diminfo.opt as + * it has been "clipped" to the current extent. */ - diminfo = space->select.sel_info.hslab->opt_diminfo; + diminfo = space->select.sel_info.hslab->diminfo.opt; else - if(space->select.sel_info.hslab->unlim_dim >= 0) - /* - * There is an unlimited dimension so we must use opt_diminfo as - * it has been "clipped" to the current extent. - */ - diminfo = space->select.sel_info.hslab->opt_diminfo; - else - /* - * Use the "application dimension information" to pass back to - * the user the blocks they set, not the optimized, internal - * information. - */ - diminfo = space->select.sel_info.hslab->app_diminfo; + /* + * Use the "application dimension information" to pass back to + * the user the blocks they set, not the optimized, internal + * information. + */ + diminfo = space->select.sel_info.hslab->diminfo.app; /* Build the tables of count sizes as well as the initial offset */ for(u = 0; u < ndims; u++) { tmp_count[u] = diminfo[u].count; offset[u] = diminfo[u].start; + end[u] = diminfo[u].start + (diminfo[u].block - 1); } /* end for */ /* We're not done with the iteration */ @@ -3935,31 +4185,45 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo /* Go iterate over the hyperslabs */ while(!done && numblocks > 0) { - hsize_t temp_off; /* Offset in a given dimension */ + /* Skip over initial blocks */ + if(startblock > 0) { + /* Skip all blocks in row */ + if(startblock >= tmp_count[fast_dim]) { + startblock -= tmp_count[fast_dim]; + tmp_count[fast_dim] = 0; + } /* end if */ + else { + /* Move the offset to the next sequence to start */ + offset[fast_dim] += diminfo[fast_dim].stride * startblock; + end[fast_dim] += diminfo[fast_dim].stride * startblock; + + /* Decrement the block count */ + tmp_count[fast_dim] -= startblock; + + /* Done with starting blocks */ + startblock = 0; + } /* end else */ + } /* end if */ /* Iterate over the blocks in the fastest dimension */ while(tmp_count[fast_dim] > 0 && numblocks > 0) { + /* Sanity check */ + HDassert(startblock == 0); - /* Check if we should copy this block information */ - if(startblock == 0) { - /* Copy the starting location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); - buf += ndims; + /* Copy the starting location */ + HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); + buf += ndims; - /* Compute the ending location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); - for(u = 0; u < ndims; u++) - buf[u] += (diminfo[u].block - 1); - buf += ndims; + /* Compute the ending location */ + HDmemcpy(buf, end, sizeof(hsize_t) * ndims); + buf += ndims; - /* Decrement the number of blocks to retrieve */ - numblocks--; - } /* end if */ - else - startblock--; + /* Decrement the number of blocks to retrieve */ + numblocks--; /* Move the offset to the next sequence to start */ offset[fast_dim] += diminfo[fast_dim].stride; + end[fast_dim] += diminfo[fast_dim].stride; /* Decrement the block count */ tmp_count[fast_dim]--; @@ -3982,23 +4246,24 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo if(tmp_count[temp_dim] > 0) break; + /* Reset the block count in this dimension */ + tmp_count[temp_dim] = diminfo[temp_dim].count; + /* Check for getting out of iterator */ if(temp_dim == 0) done = TRUE; - /* Reset the block count in this dimension */ - tmp_count[temp_dim] = diminfo[temp_dim].count; - /* Wrapped a dimension, go up to next dimension */ temp_dim--; } /* end while */ } /* end if */ - /* Re-compute offset array */ - for(u = 0; u < ndims; u++) { - temp_off = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); - offset[u] = temp_off; - } /* end for */ + /* Re-compute offset & end arrays */ + if(!done) + for(u = 0; u < ndims; u++) { + offset[u] = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]); + end[u] = offset[u] + (diminfo[u].block - 1); + } /* end for */ } /* end while */ } /* end if */ else { @@ -4024,7 +4289,7 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo hsize_t numblocks; IN: Number of hyperslab blocks to get hsize_t buf[]; OUT: List of hyperslab blocks selected RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION Puts a list of the hyperslab blocks into the user's buffer. The blocks start with the 'startblock'th block in the list of blocks and put @@ -4064,7 +4329,7 @@ H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, /* Go get the correct number of blocks */ if(numblocks > 0) - ret_value = H5S__get_select_hyper_blocklist(space, 0, startblock, numblocks, buf); + ret_value = H5S__get_select_hyper_blocklist(space, startblock, numblocks, buf); else ret_value = SUCCEED; /* Successfully got 0 blocks... */ @@ -4075,16 +4340,14 @@ done: /*-------------------------------------------------------------------------- NAME - H5S_hyper_bounds_helper + H5S__hyper_bounds PURPOSE Gets the bounding box containing the selection. USAGE - htri_t H5S_hyper_bounds_helper(spans, offset, rank); - const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree - const hssize_t *offset; IN: Pointer to offset array - hsize_t rank; IN: Current rank looking at - hsize_t *start; OUT: Start array bounds - hsize_t *end; OUT: End array bounds + herr_t H5S__hyper_bounds(space, hsize_t *start, hsize_t *end) + H5S_t *space; IN: Dataspace pointer of selection to query + hsize_t *start; OUT: Starting coordinate of bounding box + hsize_t *end; OUT: Opposite coordinate of bounding box RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -4102,119 +4365,46 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end) +H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) { - H5S_hyper_span_t *curr; /* Hyperslab information nodes */ - herr_t ret_value = SUCCEED; /* Return value */ + const hsize_t *low_bounds, *high_bounds; /* Pointers to the correct pair of low & high bounds */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - HDassert(spans); - HDassert(offset); - HDassert(rank < H5S_MAX_RANK); + /* Sanity check */ + HDassert(space); HDassert(start); HDassert(end); - /* Check each point to determine whether selection+offset is within extent */ - curr=spans->head; - while(curr!=NULL) { - /* Check for offset moving selection negative */ - if(((hssize_t)curr->low + offset[rank]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - - /* Check if the current span extends the bounding box */ - if((curr->low + (hsize_t)offset[rank]) < start[rank]) - start[rank] = curr->low + (hsize_t)offset[rank]; - if((curr->high + (hsize_t)offset[rank]) > end[rank]) - end[rank] = curr->high + (hsize_t)offset[rank]; - - /* Recurse if this node has down spans */ - if(curr->down != NULL) { - if(H5S_hyper_bounds_helper(curr->down, offset, (rank + 1), start, end) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "failure in lower dimension") - } /* end if */ - - /* Advance to next node */ - curr = curr->next; - } /* end while */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_bounds_helper() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S__hyper_bounds - PURPOSE - Gets the bounding box containing the selection. - USAGE - herr_t H5S__hyper_bounds(space, hsize_t *start, hsize_t *end) - H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *start; OUT: Starting coordinate of bounding box - hsize_t *end; OUT: Opposite coordinate of bounding box - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Retrieves the bounding box containing the current selection and places - it into the user's buffers. The start and end buffers must be large - enough to hold the dataspace rank number of coordinates. The bounding box - exactly contains the selection, ie. if a 2-D element selection is currently - defined with the following points: (4,5), (6,8) (10,7), the bounding box - with be (4, 5), (10, 8). - The bounding box calculations _does_ include the current offset of the - selection within the dataspace extent. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) -{ - unsigned rank; /* Dataspace rank */ - unsigned i; /* index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + /* Check which set of low & high bounds we should be using */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + low_bounds = space->select.sel_info.hslab->diminfo.low_bounds; + high_bounds = space->select.sel_info.hslab->diminfo.high_bounds; + } /* end if */ + else { + low_bounds = space->select.sel_info.hslab->span_lst->low_bounds; + high_bounds = space->select.sel_info.hslab->span_lst->high_bounds; + } /* end else */ - FUNC_ENTER_STATIC + /* Loop over dimensions */ + for(u = 0; u < space->extent.rank; u++) { + /* Sanity check */ + HDassert(low_bounds[u] <= high_bounds[u]); - /* Sanity check */ - HDassert(space); - HDassert(start); - HDassert(end); + /* Check for offset moving selection negative */ + if(((hssize_t)low_bounds[u] + space->select.offset[u]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - /* Set the start and end arrays up */ - rank = space->extent.rank; - for(i = 0; i < rank; i++) { - start[i] = HSIZET_MAX; - end[i] = 0; + /* Set the low & high bounds in this dimension */ + start[u] = (hsize_t)((hssize_t)low_bounds[u] + space->select.offset[u]); + if((int)u == space->select.sel_info.hslab->unlim_dim) + end[u] = H5S_UNLIMITED; + else + end[u] = (hsize_t)((hssize_t)high_bounds[u] + space->select.offset[u]); } /* end for */ - /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ - - /* Check each dimension */ - for(i = 0; i < rank; i++) { - /* Check for offset moving selection negative */ - if((space->select.offset[i] + (hssize_t)diminfo[i].start) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - - /* Compute the smallest location in this dimension */ - start[i] = diminfo[i].start + (hsize_t)space->select.offset[i]; - - /* Compute the largest location in this dimension */ - if((int)i == space->select.sel_info.hslab->unlim_dim) - end[i] = H5S_UNLIMITED; - else - end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i]; - } /* end for */ - } /* end if */ - else { - /* Call the recursive routine to get the bounds for the span tree */ - ret_value = H5S_hyper_bounds_helper(space->select.sel_info.hslab->span_lst, space->select.offset, (hsize_t)0, start, end); - } /* end if */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_bounds() */ @@ -4264,8 +4454,9 @@ H5S__hyper_offset(const H5S_t *space, hsize_t *offset) dim_size = space->extent.size; /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */ + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->diminfo.opt; /* Local alias for diminfo */ /* Loop through starting coordinates, calculating the linear offset */ accum = 1; @@ -4428,8 +4619,9 @@ H5S__hyper_is_contiguous(const H5S_t *space) HDassert(space); /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */ + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->diminfo.opt; /* local alias for diminfo */ /* * For a regular hyperslab to be contiguous, it must have only one @@ -4610,7 +4802,10 @@ H5S__hyper_is_single(const H5S_t *space) HDassert(space); /* Check for a "single" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { + /* (No need to rebuild the dimension info yet, since the span-tree + * algorithm is fast -QAK) + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { unsigned u; /* index variable */ /* @@ -4620,7 +4815,7 @@ H5S__hyper_is_single(const H5S_t *space) /* Check for a single block */ for(u = 0; u < space->extent.rank; u++) - if(space->select.sel_info.hslab->opt_diminfo[u].count > 1) + if(space->select.sel_info.hslab->diminfo.opt[u].count > 1) HGOTO_DONE(FALSE) } /* end if */ else { @@ -4668,7 +4863,6 @@ done: This is primarily used for reading the entire selection in one swoop. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Doesn't check for "regular" hyperslab selections composed of spans EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ @@ -4682,8 +4876,14 @@ H5S__hyper_is_regular(const H5S_t *space) /* Check args */ HDassert(space); + /* Attempt to rebuild diminfo if it is invalid and has not been confirmed + * to be impossible. + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -NAF */ + /* Only simple check for regular hyperslabs for now... */ - if(space->select.sel_info.hslab->diminfo_valid) + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) ret_value = TRUE; else ret_value = FALSE; @@ -4694,93 +4894,397 @@ H5S__hyper_is_regular(const H5S_t *space) /*-------------------------------------------------------------------------- NAME - H5S__hyper_release + H5S__hyper_spans_shape_same_helper PURPOSE - Release hyperslab selection information for a dataspace + Helper routine to check if two hyperslab span trees are the same shape USAGE - herr_t H5S__hyper_release(space) - H5S_t *space; IN: Pointer to dataspace + hbool_t H5S__hyper_spans_shape_same_helper(span1, span2, offset, rest_zeros) + H5S_hyper_span_info_t *span_info1; IN: First span tree to compare + H5S_hyper_span_info_t *span_info2; IN: Second span tree to compare + hssize_t offset[]; IN: Offset between the span trees + hbool_t rest_zeros[]; IN: Array of flags which indicate + the rest of the offset[] array + is zero values. RETURNS - Non-negative on success/Negative on failure + TRUE (1) or FALSE (0) on success, can't fail DESCRIPTION - Releases all hyperslab selection information for a dataspace + Compare two hyperslab span trees to determine if they refer to a selection + with the same shape, with a possible (constant) offset between their + elements. Very similar to H5S__hyper_cmp_spans, except the selected + elements can be offset by a vector. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG - * Robb Matzke, 1998-08-25 - * The fields which are freed are set to NULL to prevent them from being - * freed again later. This fixes some allocation problems where - * changing the hyperslab selection of one dataspace causes a core dump - * when closing some other dataspace. --------------------------------------------------------------------------*/ -static herr_t -H5S__hyper_release(H5S_t *space) +static H5_ATTR_PURE hbool_t +H5S__hyper_spans_shape_same_helper(const H5S_hyper_span_info_t *span_info1, + const H5S_hyper_span_info_t *span_info2, hssize_t offset[], + hbool_t rest_zeros[]) { - herr_t ret_value = SUCCEED; + hbool_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(span_info1); + HDassert(span_info2); + HDassert(offset); + HDassert(rest_zeros); + + /* Compare low & high bounds for this span list */ + /* (Could compare lower dimensions also, but not certain if + * that's worth it. - QAK, 2019/01/23) + */ + if((hsize_t)((hssize_t)span_info1->low_bounds[0] + offset[0]) != span_info2->low_bounds[0]) + HGOTO_DONE(FALSE) + else if((hsize_t)((hssize_t)span_info1->high_bounds[0] + offset[0]) != span_info2->high_bounds[0]) + HGOTO_DONE(FALSE) + else { + const H5S_hyper_span_t *span1; + const H5S_hyper_span_t *span2; + + /* Get the pointers to the actual lists of spans */ + span1 = span_info1->head; + span2 = span_info2->head; + + /* Sanity checking */ + HDassert(span1); + HDassert(span2); + + /* infinite loop which must be broken out of */ + while(1) { + /* Check for both spans being NULL */ + if(span1 == NULL && span2 == NULL) + HGOTO_DONE(TRUE) + else { + /* Check for one span being NULL */ + if(span1 == NULL || span2 == NULL) + HGOTO_DONE(FALSE) + else { + /* Check if the actual low & high span information is the same */ + if((hsize_t)((hssize_t)span1->low + offset[0]) != span2->low || (hsize_t)((hssize_t)span1->high + offset[0]) != span2->high) + HGOTO_DONE(FALSE) + else { + if(span1->down != NULL || span2->down != NULL) { + /* If the rest of the span trees have a zero offset, use the faster comparison routine */ + if(rest_zeros[0]) { + if(!H5S__hyper_cmp_spans(span1->down, span2->down)) + HGOTO_DONE(FALSE) + else { + /* Keep going... */ + } /* end else */ + } /* end if */ + else { + if(!H5S__hyper_spans_shape_same_helper(span1->down, span2->down, &offset[1], &rest_zeros[1])) + HGOTO_DONE(FALSE) + else { + /* Keep going... */ + } /* end else */ + } /* end else */ + } /* end if */ + else { + /* Keep going... */ + } /* end else */ + } /* end else */ + } /* end else */ + } /* end else */ + + /* Advance to the next nodes in the span list */ + span1 = span1->next; + span2 = span2->next; + } /* end while */ + } /* end else */ + + /* Fall through, with default return value of 'TRUE' if spans were already visited */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_spans_shape_same_helper() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_spans_shape_same + PURPOSE + Check if two hyperslab span trees are the same shape + USAGE + hbool_t H5S__hyper_spans_shape_same(span1, span2) + H5S_hyper_span_info_t *span_info1; IN: First span tree to compare + H5S_hyper_span_info_t *span_info2; IN: Second span tree to compare + RETURNS + TRUE (1) or FALSE (0) on success, can't fail + DESCRIPTION + Compare two hyperslab span trees to determine if they refer to a selection + with the same shape. Very similar to H5S__hyper_cmp_spans, except the + selected elements can be offset by a vector. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5_ATTR_PURE hbool_t +H5S__hyper_spans_shape_same(const H5S_hyper_span_info_t *span_info1, + const H5S_hyper_span_info_t *span_info2, unsigned ndims) +{ + const H5S_hyper_span_t *span1; /* Pointer to spans in first span tree */ + const H5S_hyper_span_t *span2; /* Pointer to spans in second span tree */ + hssize_t offset[H5S_MAX_RANK]; /* Offset vector for selections */ + hbool_t rest_zeros[H5S_MAX_RANK]; /* Vector of flags to indicate when remaining offset is all zero */ + hbool_t zero_offset; /* Whether the two selections have a non-zero offset */ + unsigned u; /* Local index variable */ + hbool_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(span_info1); + HDassert(span_info2); + HDassert(ndims > 0); + + /* Initialize arrays */ + HDmemset(offset, 0, sizeof(offset)); + HDmemset(rest_zeros, 0, sizeof(rest_zeros)); + + /* Check for an offset between the two selections */ + span1 = span_info1->head; + span2 = span_info2->head; + zero_offset = TRUE; + for(u = 0; u < ndims; u++) { + /* Check for offset in this dimension */ + if(span1->low != span2->low) { + offset[u] = (hssize_t)span2->low - (hssize_t)span1->low; + + /* Indicate that the offset vector is not all zeros */ + if(zero_offset) + zero_offset = FALSE; + } /* end if */ + + /* Sanity check */ + /* (Both span trees must have the same depth) */ + HDassert((span1->down && span2->down) || (NULL == span1->down && NULL == span2->down)); + + /* Advance to next dimension */ + if(span1->down) { + span1 = span1->down->head; + span2 = span2->down->head; + } /* end if */ + } /* end for */ + + /* Check if there's a "tail" of all zeros in a non-zero offset vector */ + if(!zero_offset) { + int i; /* Local index variable */ + + /* Find first non-zero offset, from the fastest dimension up */ + for(i = (int)(ndims - 1); i >= 0; i--) + if(offset[i]) { + rest_zeros[i] = TRUE; + break; + } /* end if */ + + /* Sanity check */ + /* (Must eventually have found a non-zero offset) */ + HDassert(i >= 0); + } /* end if */ + + /* If the offset vector is all zero, we can use the faster span tree + * comparison routine. Otherwise, use a generalized version of that + * routine. + */ + if(zero_offset) + ret_value = H5S__hyper_cmp_spans(span_info1, span_info2); + else + ret_value = H5S__hyper_spans_shape_same_helper(span_info1, span_info2, offset, rest_zeros); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_spans_shape_same() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_shape_same + PURPOSE + Check if a two hyperslab selections are the same shape + USAGE + htri_t H5S__hyper_shape_same(space1, space2) + const H5S_t *space1; IN: First dataspace to check + const H5S_t *space2; IN: Second dataspace to check + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in each dataspace are the same + shape. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Handles when both are regular in an efficient way, otherwise converts + both to span tree form (if necessary) and compares efficiently them in + that form. + + Rank of space1 must always be >= to rank of space2. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2) +{ + unsigned space1_rank; /* Number of dimensions of first dataspace */ + unsigned space2_rank; /* Number of dimensions of second dataspace */ + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC /* Check args */ - HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); + HDassert(space1); + HDassert(space2); - /* Reset the number of points selected */ - space->select.num_elem = 0; + /* Get dataspace ranks */ + space1_rank = space1->extent.rank; + space2_rank = space2->extent.rank; - /* Release irregular hyperslab information */ - if(space->select.sel_info.hslab) { - if(space->select.sel_info.hslab->span_lst != NULL) - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") + /* Sanity check */ + HDassert(space1_rank >= space2_rank); + HDassert(space2_rank > 0); + + /* Rebuild diminfo if it is invalid and has not been confirmed to be + * impossible */ + if(space1->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild((H5S_t *)space1); /* Casting away const OK -QAK */ + if(space2->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild((H5S_t *)space2); /* Casting away const OK -QAK */ + + /* If both are regular hyperslabs, compare their diminfo values */ + if(space1->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES + && space2->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + int space1_dim; /* Current dimension in first dataspace */ + int space2_dim; /* Current dimension in second dataspace */ + + /* Initialize dimensions */ + space1_dim = (int)space1_rank - 1; + space2_dim = (int)space2_rank - 1; + + /* Check that the shapes are the same in the common dimensions, and that + * block == 1 in all dimensions that appear only in space1. + */ + while(space2_dim >= 0) { + if(space1->select.sel_info.hslab->diminfo.opt[space1_dim].stride != + space2->select.sel_info.hslab->diminfo.opt[space2_dim].stride) + HGOTO_DONE(FALSE) - /* Release space for the hyperslab selection information */ - space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); + if(space1->select.sel_info.hslab->diminfo.opt[space1_dim].count != + space2->select.sel_info.hslab->diminfo.opt[space2_dim].count) + HGOTO_DONE(FALSE) + + if(space1->select.sel_info.hslab->diminfo.opt[space1_dim].block != + space2->select.sel_info.hslab->diminfo.opt[space2_dim].block) + HGOTO_DONE(FALSE) + + space1_dim--; + space2_dim--; + } /* end while */ + + while(space1_dim >= 0) { + if(space1->select.sel_info.hslab->diminfo.opt[space1_dim].block != 1) + HGOTO_DONE(FALSE) + + space1_dim--; + } /* end while */ } /* end if */ + /* If both aren't regular, use fast irregular comparison */ + else { + H5S_hyper_span_info_t *spans1; /* Hyperslab spans for first dataspace */ + + /* Make certain that both selections have span trees */ + if(NULL == space1->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans((H5S_t *)space1) < 0) /* Casting away const OK -QAK */ + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "can't construct span tree for hyperslab selection") + if(NULL == space2->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans((H5S_t *)space2) < 0) /* Casting away const OK -QAK */ + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "can't construct span tree for hyperslab selection") + + /* If rank of space A is different (guaranteed greater) than + * rank of space B, walk down the span tree, verifying + * that the block size is 1 on the way down. + */ + if(space1_rank > space2_rank) { + unsigned diff_rank = space1_rank - space2_rank; /* Difference in ranks */ + + /* Walk down the dimensions */ + spans1 = space1->select.sel_info.hslab->span_lst; + while(diff_rank > 0) { + H5S_hyper_span_t *span; /* Span for this dimension */ + + /* Get pointer to first span in tree */ + span = spans1->head; + + /* Check for more spans in this dimension */ + if(span->next) + HGOTO_DONE(FALSE) + + /* Check for span size > 1 element */ + if(span->low != span->high) + HGOTO_DONE(FALSE) + + /* Walk down to the next dimension */ + spans1 = span->down; + diff_rank--; + } /* end while */ + + /* Sanity check */ + HDassert(spans1); + } /* end if */ + else + spans1 = space1->select.sel_info.hslab->span_lst; + + /* Compare the span trees */ + ret_value = H5S__hyper_spans_shape_same(spans1, space2->select.sel_info.hslab->span_lst, space2_rank); + } /* end else */ + + /* Fall through with 'TRUE' value, if not set earlier */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_release() */ +} /* end H5S__hyper_shape_same() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_recover_span + H5S__hyper_release PURPOSE - Recover a generated span, if appropriate + Release hyperslab selection information for a dataspace USAGE - herr_t H5S__hyper_recover_span(recover, curr_span, next_span) - unsigned *recover; IN/OUT: Pointer recover flag - H5S_hyper_span_t **curr_span; IN/OUT: Pointer to current span in list - H5S_hyper_span_t *next_span; IN: Pointer to next span + herr_t H5S__hyper_release(space) + H5S_t *space; IN: Pointer to dataspace RETURNS - Non-negative on success, negative on failure + Non-negative on success/Negative on failure DESCRIPTION - Check if the current span needs to be recovered and free it if so. - Set the current span to the next span in any case. + Releases all hyperslab selection information for a dataspace GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_recover_span(hbool_t *recover, H5S_hyper_span_t **curr_span, H5S_hyper_span_t *next_span) +H5S__hyper_release(H5S_t *space) { FUNC_ENTER_STATIC_NOERR - HDassert(recover); - HDassert(curr_span); + /* Check args */ + HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); - /* Check if the span should be recovered */ - if(*recover) { - H5S__hyper_free_span(*curr_span); - *recover = FALSE; - } /* end if */ + /* Reset the number of points selected */ + space->select.num_elem = 0; - /* Set the current span to next span */ - *curr_span = next_span; + /* Release irregular hyperslab information */ + if(space->select.sel_info.hslab) { + if(space->select.sel_info.hslab->span_lst != NULL) + H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + + /* Release space for the hyperslab selection information */ + space->select.sel_info.hslab = H5FL_FREE(H5S_hyper_sel_t, space->select.sel_info.hslab); + } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5S__hyper_recover_span() */ +} /* end H5S__hyper_release() */ /*-------------------------------------------------------------------------- @@ -4793,7 +5297,7 @@ H5S__hyper_recover_span(hbool_t *recover, H5S_hyper_span_t **curr_span, H5S_hype unsigned rank; IN: Number of dimensions of coordinate hsize_t *coords; IN: Location of element RETURNS - Non-negative on success, negative on failure + Non-NULL pointer to new span tree on success, NULL on failure DESCRIPTION Create a span tree for a single element GLOBAL VARIABLES @@ -4815,14 +5319,20 @@ H5S__hyper_coord_to_span(unsigned rank, const hsize_t *coords) /* Search for location to insert new element in tree */ if(rank > 1) { - /* Allocate a span info node */ - if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t))) + /* Allocate a span info node for coordinates below this one */ + if(NULL == (down = H5S__hyper_new_span_info(rank - 1))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + /* Set the low & high bounds for this span info node */ + HDmemcpy(down->low_bounds, &coords[1], (rank - 1) * sizeof(hsize_t)); + HDmemcpy(down->high_bounds, &coords[1], (rank - 1) * sizeof(hsize_t)); /* Build span tree for coordinates below this one */ if(NULL == (down->head = H5S__hyper_coord_to_span(rank - 1, &coords[1]))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") + + /* Update the tail pointer of the down dimension, and it's a single span element */ + down->tail = down->head; } /* end if */ /* Build span for this coordinate */ @@ -4844,12 +5354,13 @@ done: NAME H5S__hyper_add_span_element_helper PURPOSE - Add a single element to a span tree + Helper routine to add a single element to a span tree USAGE - herr_t H5S_hyper_add_span_element_helper(prev_span, span_tree, rank, coords) + herr_t H5S__hyper_add_span_element_helper(span_tree, rank, coords, first_dim_modified) H5S_hyper_span_info_t *span_tree; IN/OUT: Pointer to span tree to append to unsigned rank; IN: Number of dimensions of coordinates - hsize_t *coords; IN: Location of element to add to span tree + hsize_t *coords; IN: Location of element to add to span tree + int *first_dim_modified; IN: Index of the first dimension modified RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -4862,13 +5373,9 @@ done: --------------------------------------------------------------------------*/ static herr_t H5S__hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, - unsigned rank, const hsize_t *coords) + unsigned rank, const hsize_t *coords, int *first_dim_modified) { - H5S_hyper_span_info_t *tspan_info; /* Temporary pointer to span info */ - H5S_hyper_span_info_t *prev_span_info; /* Pointer to span info for level above current position */ - H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */ - H5S_hyper_span_t *tmp2_span; /* Another temporary pointer to a span */ - H5S_hyper_span_t *new_span; /* New span created for element */ + H5S_hyper_span_t *tail_span; /* Pointer to the tail span of one dimension */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -4877,166 +5384,196 @@ H5S__hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, HDassert(span_tree); HDassert(rank > 0); HDassert(coords); + HDassert(first_dim_modified); /* Get pointer to last span in span tree */ - tspan_info=span_tree; - if(span_tree->scratch) - tmp_span=(H5S_hyper_span_t *)span_tree->scratch; - else { - tmp_span=span_tree->head; - HDassert(tmp_span); - span_tree->scratch=(H5S_hyper_span_info_t *)tmp_span; - } /* end else */ + tail_span = span_tree->tail; + + /* Determine if tail span includes a portion of the coordinate */ + /* (Should never happen with the lowest level in the span tree) */ + if(coords[0] >= tail_span->low && coords[0] <= tail_span->high) { + H5S_hyper_span_t *prev_down_tail_span; /* Pointer to previous down spans' tail pointer */ + hsize_t prev_down_tail_span_high; /* Value of previous down spans' tail's high value */ + + /* Retain into about down spans' tail */ + prev_down_tail_span = tail_span->down->tail; + prev_down_tail_span_high = tail_span->down->tail->high; + + /* Drop down a dimension */ + HDassert(rank > 1); + if(H5S__hyper_add_span_element_helper(tail_span->down, rank - 1, &coords[1], first_dim_modified) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert coordinate into span tree") + + /* Check & update high bounds for lower dimensions */ + if(*first_dim_modified >= 0) { + unsigned first_dim; /* First dimension modified, relative to this span tree */ + hbool_t first_dim_set = FALSE; /* Whether first dimension modified is set */ + unsigned u; /* Local index variable */ - /* Find last span tree which includes a portion of the coordinate */ - prev_span_info=NULL; - while(coords[0]>=tmp_span->low && coords[0]<=tmp_span->high) { - /* Move rank & coordinate offset down a dimension */ - rank--; - coords++; + /* Adjust first dimension modified to be relative to this span tree */ + first_dim = (unsigned)(*first_dim_modified + 1); - /* Remember the span tree we are descending into */ - prev_span_info=tspan_info; - tspan_info=tmp_span->down; + /* Reset modified dimension, in case no bounds in this span tree change */ + *first_dim_modified = -1; - /* Get the last span in this span's 'down' tree */ - if(tspan_info->scratch) - tmp_span=(H5S_hyper_span_t *)tspan_info->scratch; - else { - tmp_span=tspan_info->head; - HDassert(tmp_span); - tspan_info->scratch=(H5S_hyper_span_info_t *)tmp_span; - } /* end else */ - } /* end while */ - - /* Check if we made it all the way to the bottom span in the tree */ - if(rank>1) { - /* Before we create another span at this level in the tree, check if - * the last span's "down tree" was equal to any other spans in this - * list of spans in the span tree. - * - * If so, release last span information and make last span merge into - * previous span (if possible), or at least share their "down tree" - * information. - */ - tmp2_span=tspan_info->head; - while(tmp2_span!=tmp_span) { - if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { - /* Check for merging into previous span */ - if(tmp2_span->high+1==tmp_span->low) { - /* Release last span created */ - H5S__hyper_free_span(tmp_span); + /* Iterate through coordinates */ + for(u = first_dim; u < rank; u++) { + /* Check if coordinate is outside the bounds for this span tree */ + if(coords[u] > span_tree->high_bounds[u]) { + /* Update high bounds for this tree */ + span_tree->high_bounds[u] = coords[u]; - /* Increase size of previous span */ - tmp2_span->high++; - tmp2_span->nelem++; - - /* Reset the 'tmp_span' for the rest of this block's algorithm */ - tmp_span=tmp2_span; + /* Need to signal to higher dimensions if high bounds changed */ + if(!first_dim_set) { + *first_dim_modified = (int)u; + first_dim_set = TRUE; + } /* end if */ } /* end if */ - /* Span is disjoint, but has the same "down tree" selection */ - else { - /* Release "down tree" information */ - H5S__hyper_free_span_info(tmp_span->down); + } /* end for */ + } /* end if */ - /* Point at earlier span's "down tree" */ - tmp_span->down=tmp2_span->down; + /* Check if previous tail span in down spans is different than current + * tail span, or if its high value changed, in which case we should + * check if the updated node can share down spans with other nodes. + */ + if(tail_span->down->tail != prev_down_tail_span || + prev_down_tail_span_high != tail_span->down->tail->high) { + H5S_hyper_span_t *stop_span; /* Pointer to span to stop at */ + H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */ + uint64_t op_gen; /* Operation generation value */ + + /* Determine which span to stop at */ + if(tail_span->down->tail != prev_down_tail_span) { + /* Sanity check */ + HDassert(prev_down_tail_span->next == tail_span->down->tail); + + /* Set the span to stop at */ + stop_span = prev_down_tail_span; + } /* end if */ + else { + /* Sanity check */ + HDassert(prev_down_tail_span_high != tail_span->down->tail->high); - /* Increment reference count on shared "down tree" */ - tmp_span->down->count++; - } /* end else */ + /* Set the span to stop at */ + stop_span = tail_span->down->tail; + } /* end else */ - /* Found span to merge into, break out now */ - break; - } /* end if */ + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); - /* Advance to next span to check */ - tmp2_span=tmp2_span->next; - } /* end while */ + /* Check if the 'stop' span in the "down tree" is equal to any other + * spans in the list of spans in the span tree. + * + * If so, release last span information and make last span merge into + * previous span (if possible), or at least share their "down tree" + * information. + */ + tmp_span = tail_span->down->head; + while(tmp_span != stop_span) { + hbool_t attempt_merge_spans = FALSE; /* Whether to merge spans */ - /* Make span tree for current coordinates */ - if(NULL == (new_span = H5S__hyper_coord_to_span(rank, coords))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") + /* Different tests for when to run the 'merge' algorithm, + * depending whether there's "down trees" or not. + */ + if(NULL == tmp_span->down) { + /* Spin through spans until we find the one before the 'stop' span */ + if(tmp_span->next == stop_span) + attempt_merge_spans = TRUE; + } /* end if */ + else { + /* Check if we've compared the 'stop' span's "down tree" to + * this span's "down tree" already. + */ + if(tmp_span->down->op_gen != op_gen) { + if(H5S__hyper_cmp_spans(tmp_span->down, stop_span->down)) + attempt_merge_spans = TRUE; + + /* Remember that we visited this span's "down tree" already */ + /* (Because it wasn't the same as the 'stop' span's down tree + * and we don't need to compare it again) + */ + tmp_span->down->op_gen = op_gen; + } /* end if */ + } /* end else */ - /* Add new span tree as span */ - HDassert(tmp_span); - tmp_span->next=new_span; + /* Check for merging into previous span */ + if(attempt_merge_spans) { + if(tmp_span->high + 1 == stop_span->low) { + /* Increase size of previous span */ + tmp_span->high++; - /* Make scratch pointer point to last span in list */ - HDassert(tspan_info); - tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; + /* Update pointers appropriately */ + if(stop_span == prev_down_tail_span) { + /* Sanity check */ + HDassert(stop_span->next == tail_span->down->tail); - /* Set the proper 'pstride' for new span */ - new_span->pstride=new_span->low-tmp_span->low; - } /* end if */ - else { - /* Does new node adjoin existing node? */ - if(tmp_span->high+1==coords[0]) { - tmp_span->high++; - tmp_span->nelem++; - - /* Check if this span tree should now be merged with a level higher in the tree */ - if(prev_span_info!=NULL) { - /* Before we create another span at this level in the tree, check if - * the last span's "down tree" was equal to any other spans in this - * list of spans in the span tree. - * - * If so, release last span information and make last span merge into - * previous span (if possible), or at least share their "down tree" - * information. - */ - tmp2_span=prev_span_info->head; - tmp_span=(H5S_hyper_span_t *)prev_span_info->scratch; - while(tmp2_span!=tmp_span) { - if(H5S__hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) { - /* Check for merging into previous span */ - if(tmp2_span->high+1==tmp_span->low) { - /* Release last span created */ - H5S__hyper_free_span(tmp_span); - - /* Increase size of previous span */ - tmp2_span->high++; - tmp2_span->nelem++; - - /* Update pointers */ - tmp2_span->next=NULL; - prev_span_info->scratch=(H5S_hyper_span_info_t *)tmp2_span; + tmp_span->next = stop_span->next; } /* end if */ - /* Span is disjoint, but has the same "down tree" selection */ else { - /* Release "down tree" information */ - H5S__hyper_free_span_info(tmp_span->down); + /* Sanity check */ + HDassert(tmp_span->next == tail_span->down->tail); - /* Point at earlier span's "down tree" */ - tmp_span->down=tmp2_span->down; - - /* Increment reference count on shared "down tree" */ - tmp_span->down->count++; + tmp_span->next = NULL; + tail_span->down->tail = tmp_span; } /* end else */ - /* Found span to merge into, break out now */ - break; + /* Release last span created */ + H5S__hyper_free_span(stop_span); } /* end if */ + /* Span is disjoint, but has the same "down tree" selection */ + /* (If it has a "down tree") */ + else if(stop_span->down) { + /* Release "down tree" information */ + H5S__hyper_free_span_info(stop_span->down); - /* Advance to next span to check */ - tmp2_span=tmp2_span->next; - } /* end while */ - } /* end if */ + /* Point at earlier span's "down tree" */ + stop_span->down = tmp_span->down; + + /* Increment reference count on shared "down tree" */ + stop_span->down->count++; + } /* end else */ + + /* Found span to merge into, break out now */ + break; + } /* end if */ + + /* Advance to next span to check */ + tmp_span = tmp_span->next; + } /* end while */ } /* end if */ - else { - if(NULL == (new_span = H5S__hyper_new_span(coords[0], coords[0], NULL, NULL))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") + } /* end if */ + else { + unsigned u; /* Local index variable */ - /* Add new span tree as span */ - HDassert(tmp_span); - tmp_span->next=new_span; + /* Check if we made it all the way to the bottom span list in the tree + * and the new coordinate adjoins the current tail span. + */ + if(rank == 1 && (tail_span->high + 1) == coords[0]) + /* Append element to current tail span */ + tail_span->high++; + else { + H5S_hyper_span_t *new_span; /* New span created for element */ - /* Make scratch pointer point to last span in list */ - tspan_info->scratch=(H5S_hyper_span_info_t *)new_span; + /* Make span tree for current coordinate(s) */ + if(NULL == (new_span = H5S__hyper_coord_to_span(rank, coords))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab spans for coordinate") - /* Set the proper 'pstride' for new span */ - new_span->pstride = new_span->low - tmp_span->low; + /* Add new span to span tree list */ + tail_span->next = new_span; + span_tree->tail = new_span; } /* end else */ + + /* Update high bound for current span tree */ + HDassert(coords[0] > span_tree->high_bounds[0]); + span_tree->high_bounds[0] = coords[0]; + + /* Update high bounds for dimensions below this one */ + for(u = 1; u < rank; u++) + if(coords[u] > span_tree->high_bounds[u]) + span_tree->high_bounds[u] = coords[u]; + + /* Need to signal to higher dimensions that high bounds changed */ + *first_dim_modified = 0; } /* end else */ done: @@ -5061,6 +5598,24 @@ done: GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Assumes that the element is not already in the dataspace's selection + + NOTE: There's also an assumption about the context of this function call - + This function is only called is only being called from H5D_chunk_mem_cb + in src/H5Dchunk.c, when the library is iterating over a memory + selection, so the coordinates passed to H5S_hyper_add_span_element will + always be in increasing order (according to a row-major (i.e. C, not + FORTRAN) scan) over the dataset. Therefore, for every input of + coordinates, only the last span element (i.e., the tail pointer) in + one dimension is checked against the input. + + NOTE: This algorithm is definitely "correct" and tries to conserve memory + as much as possible, but it's doing a _lot_ of work that might be + better spent running a similar algorithm to "condense" the span tree + (possibly even back into a regular selection) just before the selection + is used for I/O on the chunk. I'm not going to spend the time on this + currently, but it does sound like a good direction to explore. + QAK, 2019/01/24 + EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ @@ -5080,9 +5635,13 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) /* Check if this is the first element in the selection */ if(NULL == space->select.sel_info.hslab) { /* Allocate a span info node */ - if(NULL == (head = H5FL_CALLOC(H5S_hyper_span_info_t))) + if(NULL == (head = H5S__hyper_new_span_info(rank))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") + /* Set the low & high bounds for this span info node */ + HDmemcpy(head->low_bounds, coords, rank * sizeof(hsize_t)); + HDmemcpy(head->high_bounds, coords, rank * sizeof(hsize_t)); + /* Set the reference count */ head->count = 1; @@ -5090,6 +5649,9 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) if(NULL == (head->head = H5S__hyper_coord_to_span(rank, coords))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab spans for coordinate") + /* Update the tail pointer of this newly created span in dimension "rank" */ + head->tail = head->head; + /* Allocate selection info */ if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab selection") @@ -5101,7 +5663,7 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) space->select.type = H5S_sel_hyper; /* Reset "regular" hyperslab flag */ - space->select.sel_info.hslab->diminfo_valid = FALSE; + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; /* Set unlim_dim */ space->select.sel_info.hslab->unlim_dim = -1; @@ -5110,7 +5672,10 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords) space->select.num_elem = 1; } /* end if */ else { - if(H5S__hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst, rank, coords) < 0) + int first_dim_modified = -1; /* Index of first dimension modified */ + + /* Add the element to the current set of spans */ + if(H5S__hyper_add_span_element_helper(space->select.sel_info.hslab->span_lst, rank, coords, &first_dim_modified) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert coordinate into span tree") /* Increment # of elements in selection */ @@ -5128,117 +5693,16 @@ done: /*-------------------------------------------------------------------------- NAME - H5S_hyper_reset_scratch - PURPOSE - Reset the scratch information for span tree - USAGE - herr_t H5S_hyper_reset_scratch(space) - H5S_t *space; IN/OUT: Pointer to dataspace to reset scratch pointers - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Resets the "scratch" pointers used for various tasks in computing hyperslab - spans. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5S_hyper_reset_scratch(H5S_t *space) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(space); - - /* Check if there are spans in the span tree */ - if(space->select.sel_info.hslab->span_lst != NULL) - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_reset_scratch() */ - - -/*-------------------------------------------------------------------------- - NAME - H5S_hyper_convert - PURPOSE - Convert a compatible selection to span tree form - USAGE - herr_t H5S_hyper_convert(space) - H5S_t *space; IN/OUT: Pointer to dataspace to convert - RETURNS - Non-negative on success, negative on failure - DESCRIPTION - Converts a compatible selection (currently only "all" selections) to the - span-tree form of a hyperslab selection. (Point and "none" selection aren't - currently supported and hyperslab selection always have the span-tree form - available). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5S_hyper_convert(H5S_t *space) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(space); - - /* Check the type of selection */ - switch(H5S_GET_SELECT_TYPE(space)) { - case H5S_SEL_ALL: /* All elements selected in dataspace */ - /* Convert current "all" selection to "real" hyperslab selection */ - { - const hsize_t *tmp_start; /* Temporary start information */ - const hsize_t *tmp_stride; /* Temporary stride information */ - const hsize_t *tmp_count; /* Temporary count information */ - const hsize_t *tmp_block; /* Temporary block information */ - - /* Set up temporary information for the dimensions */ - tmp_start = H5S_hyper_zeros_g; - tmp_stride = tmp_count = H5S_hyper_ones_g; - tmp_block = space->extent.size; - - /* Convert to hyperslab selection */ - if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't convert selection") - } /* end case */ - break; - - case H5S_SEL_HYPERSLABS: /* Hyperslab selection */ - break; - - case H5S_SEL_NONE: /* No elements selected in dataspace */ - case H5S_SEL_POINTS: /* Point selection */ - case H5S_SEL_ERROR: /* Selection error */ - case H5S_SEL_N: /* Selection count */ - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "can't convert to span tree selection") - } /* end switch */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_convert() */ - - -/*-------------------------------------------------------------------------- - NAME H5S__hyper_intersect_block_helper PURPOSE Helper routine to detect intersections in span trees USAGE hbool_t H5S__hyper_intersect_block_helper(spans, start, end) H5S_hyper_span_info_t *spans; IN: First span tree to operate with + unsigned rank; IN: Number of dimensions for span tree hsize_t *start; IN: Starting coordinate for block hsize_t *end; IN: Ending coordinate for block + uint64_t op_gen; IN: Operation generation RETURN Non-negative (TRUE/FALSE) on success, can't fail DESCRIPTION @@ -5249,10 +5713,9 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static hbool_t -H5S__hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans, - const hsize_t *start, const hsize_t *end) +H5S__hyper_intersect_block_helper(H5S_hyper_span_info_t *spans, + unsigned rank, const hsize_t *start, const hsize_t *end, uint64_t op_gen) { - H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */ hbool_t ret_value = FALSE; /* Return value */ FUNC_ENTER_STATIC_NOERR @@ -5262,37 +5725,52 @@ H5S__hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans, HDassert(start); HDassert(end); - /* Get the span list for spans in this tree */ - curr = spans->head; - - /* Iterate over the spans in the tree */ - while(curr != NULL) { - /* Check for span entirely before block */ - if(curr->high < *start) - /* Advance to next span in this dimension */ - curr = curr->next; - /* If this span is past the end of the block, then we're done in this dimension */ - else if(curr->low > *end) - HGOTO_DONE(FALSE) - /* block & span overlap */ - else { - if(curr->down == NULL) - HGOTO_DONE(TRUE) - else { - hbool_t status; /* Status from recursive call */ + /* Check if we've already visited this span tree */ + if(spans->op_gen != op_gen) { + H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */ + unsigned u; /* Local index variable */ - /* Recursively check spans in next dimension down */ - status = H5S__hyper_intersect_block_helper(curr->down, start + 1, end + 1); + /* Verify that there is a possibility of an overlap by checking the block + * against the low & high bounds for the span tree. + */ + for(u = 0; u < rank; u++) + if(start[u] > spans->high_bounds[u] || end[u] < spans->low_bounds[u]) + HGOTO_DONE(FALSE) - /* If there is a span intersection in the down dimensions, the span trees overlap */ - if(status == TRUE) - HGOTO_DONE(TRUE); + /* Get the span list for spans in this tree */ + curr = spans->head; - /* No intersection in down dimensions, advance to next span */ + /* Iterate over the spans in the tree */ + while(curr != NULL) { + /* Check for span entirely before block */ + if(curr->high < *start) + /* Advance to next span in this dimension */ curr = curr->next; + /* If this span is past the end of the block, then we're done in this dimension */ + else if(curr->low > *end) + HGOTO_DONE(FALSE) + /* block & span overlap */ + else { + /* If this is the bottom dimension, then the span tree overlaps the block */ + if(curr->down == NULL) + HGOTO_DONE(TRUE) + /* Recursively check spans in next dimension down */ + else { + /* If there is an intersection in the "down" dimensions, + * the span trees overlap. + */ + if(H5S__hyper_intersect_block_helper(curr->down, rank - 1, start + 1, end + 1, op_gen)) + HGOTO_DONE(TRUE) + + /* No intersection in down dimensions, advance to next span */ + curr = curr->next; + } /* end else */ } /* end else */ - } /* end else */ - } /* end while */ + } /* end while */ + + /* Set the tree's operation generation */ + spans->op_gen = op_gen; + } /* end if */ /* Fall through with 'FALSE' return value */ @@ -5317,33 +5795,130 @@ done: Quickly detect intersections between span tree and block GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Does not use selection offset. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ htri_t H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end) { + const hsize_t *low_bounds, *high_bounds; /* Pointers to the correct pair of low & high bounds */ + unsigned u; /* Local index variable */ htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(space); + HDassert(H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space)); HDassert(start); HDassert(end); - /* Check for 'all' selection, instead of a hyperslab selection */ - /* (Technically, this shouldn't be in the "hyperslab" routines...) */ - if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL) - HGOTO_DONE(TRUE); + /* Attempt to rebuild diminfo if it is invalid and has not been confirmed + * to be impossible. + */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild(space); - /* Check that the space selection has a span tree */ - if(NULL == space->select.sel_info.hslab->span_lst) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Check which set of low & high bounds we should be using */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + low_bounds = space->select.sel_info.hslab->diminfo.low_bounds; + high_bounds = space->select.sel_info.hslab->diminfo.high_bounds; + } /* end if */ + else { + low_bounds = space->select.sel_info.hslab->span_lst->low_bounds; + high_bounds = space->select.sel_info.hslab->span_lst->high_bounds; + } /* end else */ + + /* Loop over selection bounds and block, checking for overlap */ + for(u = 0; u < space->extent.rank; u++) + /* If selection bounds & block don't overlap, can leave now */ + if(!H5S_RANGE_OVERLAP(low_bounds[u], high_bounds[u], start[u], end[u])) + HGOTO_DONE(FALSE) + + /* Check for regular hyperslab intersection */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + hbool_t single_block; /* Whether the regular selection is a single block */ + + /* Check for a single block */ + /* For a regular hyperslab to be single, it must have only one block + * (i.e. count == 1 in all dimensions). + */ + single_block = TRUE; + for(u = 0; u < space->extent.rank; u++) + if(space->select.sel_info.hslab->diminfo.opt[u].count > 1) + single_block = FALSE; + + /* Single blocks have already been "compared" above, in the low / high + * bound checking, so just return TRUE if we've reached here - they + * would have been rejected earlier, if they didn't intersect. + */ + if(single_block) + HGOTO_DONE(TRUE) + else { + /* Loop over the dimensions, checking for an intersection */ + for(u = 0; u < space->extent.rank; u++) { + /* If the block's start is <= the hyperslab start, they intersect */ + /* (So, if the start is > the hyperslab start, check more conditions) */ + if(start[u] > space->select.sel_info.hslab->diminfo.opt[u].start) { + hsize_t adj_start; /* Start coord, adjusted for hyperslab selection parameters */ + hsize_t nstride; /* Number of strides into the selection */ + + /* Adjust start coord for selection's 'start' offset */ + adj_start = start[u] - space->select.sel_info.hslab->diminfo.opt[u].start; + + /* Compute # of strides into the selection */ + if(space->select.sel_info.hslab->diminfo.opt[u].count > 1) + nstride = adj_start / space->select.sel_info.hslab->diminfo.opt[u].stride; + else + nstride = 0; + + /* Sanity check */ + HDassert(nstride <= space->select.sel_info.hslab->diminfo.opt[u].count); + + /* "Rebase" the adjusted start coord into the same range + * range of values as the selections's first block. + */ + adj_start -= nstride * space->select.sel_info.hslab->diminfo.opt[u].stride; - /* Perform the span-by-span intersection check */ - ret_value = H5S__hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst, start, end); + /* If the adjusted start doesn't fall within the first hyperslab + * span, check for the block overlapping with the next one. + */ + if(adj_start >= space->select.sel_info.hslab->diminfo.opt[u].block) { + hsize_t adj_end; /* End coord, adjusted for hyperslab selection parameters */ + + /* Adjust end coord for selection's 'start' offset */ + adj_end = end[u] - space->select.sel_info.hslab->diminfo.opt[u].start; + + /* "Rebase" the adjusted end coord into the same range + * range of values as the selections's first block. + */ + adj_end -= nstride * space->select.sel_info.hslab->diminfo.opt[u].stride; + + /* If block doesn't extend over beginning of next span, + * it doesn't intersect. + */ + if(adj_end < space->select.sel_info.hslab->diminfo.opt[u].stride) + HGOTO_DONE(FALSE) + } /* end if */ + } /* end if */ + } /* end for */ + + /* If we've looped through all dimensions and none of them didn't + * overlap, then all of them do, so we report TRUE. + */ + HGOTO_DONE(TRUE) + } /* end else */ + } /* end if */ + else { + uint64_t op_gen; /* Operation generation value */ + + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); + + /* Perform the span-by-span intersection check */ + ret_value = H5S__hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst, space->extent.rank, start, end, op_gen); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -5358,7 +5933,9 @@ done: USAGE void H5S__hyper_adjust_u_helper(spans, offset) H5S_hyper_span_info_t *spans; IN: Span tree to operate with + unsigned rank; IN: Number of dimensions for span tree const hsize_t *offset; IN: Offset to subtract + uint64_t op_gen; IN: Operation generation RETURNS None DESCRIPTION @@ -5369,23 +5946,26 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static void -H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, - const hsize_t *offset) +H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, unsigned rank, + const hsize_t *offset, uint64_t op_gen) { FUNC_ENTER_STATIC_NOERR /* Sanity checks */ HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); HDassert(offset); - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { + /* Check if we've already set this span tree */ + if(spans->op_gen != op_gen) { H5S_hyper_span_t *span; /* Pointer to current span in span tree */ + unsigned u; /* Local index variable */ - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); + /* Adjust the span tree's low & high bounds */ + for(u = 0; u < rank; u++) { + HDassert(spans->low_bounds[u] >= offset[u]); + spans->low_bounds[u] -= offset[u]; + spans->high_bounds[u] -= offset[u]; + } /* end for */ /* Iterate over the spans in tree */ span = spans->head; @@ -5397,11 +5977,14 @@ H5S__hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, /* Recursively adjust spans in next dimension down */ if(span->down != NULL) - H5S__hyper_adjust_u_helper(span->down, offset + 1); + H5S__hyper_adjust_u_helper(span->down, rank - 1, offset + 1, op_gen); /* Advance to next span in this dimension */ span = span->next; } /* end while */ + + /* Set the tree's operation generation */ + spans->op_gen = op_gen; } /* end if */ FUNC_LEAVE_NOAPI_VOID @@ -5436,21 +6019,29 @@ H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset) HDassert(offset); /* Subtract the offset from the "regular" coordinates, if they exist */ - if(space->select.sel_info.hslab->diminfo_valid) { + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { unsigned u; /* Local index variable */ for(u = 0; u < space->extent.rank; u++) { - HDassert(space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); - space->select.sel_info.hslab->opt_diminfo[u].start -= offset[u]; + HDassert(space->select.sel_info.hslab->diminfo.opt[u].start >= offset[u]); + space->select.sel_info.hslab->diminfo.opt[u].start -= offset[u]; + + /* Adjust the low & high bounds */ + HDassert(space->select.sel_info.hslab->diminfo.low_bounds[u] >= offset[u]); + space->select.sel_info.hslab->diminfo.low_bounds[u] -= offset[u]; + space->select.sel_info.hslab->diminfo.high_bounds[u] -= offset[u]; } /* end for */ } /* end if */ /* Subtract the offset from the span tree coordinates, if they exist */ if(space->select.sel_info.hslab->span_lst) { - H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, offset); + uint64_t op_gen; /* Operation generation value */ + + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + H5S__hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, space->extent.rank, offset, op_gen); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -5482,12 +6073,20 @@ H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset) HDassert(offset); /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab->diminfo_valid) { - const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->diminfo.opt; /* Alias for dataspace's diminfo information */ unsigned u; /* Counter */ /* Build the table of the initial offset */ for(u = 0; u < space->extent.rank; u++) { + /* Sanity check diminfo */ + HDassert(1 == diminfo[u].count); + HDassert(1 == diminfo[u].block); + + /* Sanity check bounds, while we're here */ + HDassert(diminfo[u].start == space->select.sel_info.hslab->diminfo.low_bounds[u]); + /* Keep the offset for later */ block[u] = diminfo[u].start; } /* end for */ @@ -5499,17 +6098,22 @@ H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset) /* Advance down selected spans */ curr = space->select.sel_info.hslab->span_lst->head; curr_dim = 0; - while(curr) { - /* Sanity check for more than one span */ + while(1) { + /* Sanity checks */ HDassert(NULL == curr->next); HDassert(curr->low == curr->high); + HDassert(curr_dim < space->extent.rank); /* Save the location of the selection in current dimension */ block[curr_dim] = curr->low; /* Advance down to next dimension */ - curr = curr->down->head; - curr_dim++; + if(curr->down) { + curr = curr->down->head; + curr_dim++; + } /* end if */ + else + break; } /* end while */ } /* end else */ @@ -5586,6 +6190,7 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) H5S_hyper_span_t *prev_span = NULL; /* Pointer to previous list of spans */ unsigned delta_rank; /* Difference in dataspace ranks */ unsigned curr_dim; /* Current dimension being operated on */ + unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -5604,10 +6209,9 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) H5S_hyper_span_t *new_span; /* Temporary hyperslab span */ /* Allocate a new span_info node */ - if(NULL == (new_span_info = H5FL_CALLOC(H5S_hyper_span_info_t))) { + if(NULL == (new_span_info = H5S__hyper_new_span_info(new_space->extent.rank))) { if(prev_span) - if(H5S__hyper_free_span(prev_span) < 0) - HERROR(H5E_DATASPACE, H5E_CANTFREE, "can't free hyperslab span"); + H5S__hyper_free_span(prev_span); HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info") } /* end if */ @@ -5619,13 +6223,24 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) if(NULL == (new_span = H5S__hyper_new_span((hsize_t)0, (hsize_t)0, NULL, NULL))) { HDassert(new_span_info); if(!prev_span) - (void)H5FL_FREE(H5S_hyper_span_info_t, new_span_info); + (void)H5FL_ARR_FREE(hbounds_t, new_span_info); HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") } /* end if */ /* Set the span_info information */ new_span_info->count = 1; new_span_info->head = new_span; + new_span_info->tail = new_span; + + /* Set the bounding box */ + for(u = 0; u < delta_rank; u++) { + new_span_info->low_bounds[u] = 0; + new_span_info->high_bounds[u] = 0; + } /* end for */ + for(; u < new_space->extent.rank; u++) { + new_span_info->low_bounds[u] = base_space->select.sel_info.hslab->span_lst->low_bounds[u - delta_rank]; + new_span_info->high_bounds[u] = base_space->select.sel_info.hslab->span_lst->high_bounds[u - delta_rank]; + } /* end for */ /* Attach to new space, if top span info */ if(NULL == new_space->select.sel_info.hslab->span_lst) @@ -5647,10 +6262,9 @@ H5S__hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space) done: if(ret_value < 0 && new_space->select.sel_info.hslab->span_lst) { if(new_space->select.sel_info.hslab->span_lst->head) - if(H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free hyperslab span") + H5S__hyper_free_span(new_space->select.sel_info.hslab->span_lst->head); - new_space->select.sel_info.hslab->span_lst = H5FL_FREE(H5S_hyper_span_info_t, new_space->select.sel_info.hslab->span_lst); + new_space->select.sel_info.hslab->span_lst = (H5S_hyper_span_info_t *)H5FL_ARR_FREE(hbounds_t, new_space->select.sel_info.hslab->span_lst); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -5695,15 +6309,16 @@ H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, new_space->select.sel_info.hslab->unlim_dim = -1; /* Check for a "regular" hyperslab selection */ - if(base_space->select.sel_info.hslab->diminfo_valid) { + /* (No need to rebuild the dimension info yet -QAK) */ + if(base_space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { unsigned base_space_dim; /* Current dimension in the base dataspace */ unsigned new_space_dim; /* Current dimension in the new dataspace */ + unsigned u; /* Local index variable */ /* Check if the new space's rank is < or > base space's rank */ if(new_space->extent.rank < base_space->extent.rank) { - const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */ + const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->diminfo.opt; /* Alias for dataspace's diminfo information */ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */ - unsigned u; /* Local index variable */ /* Compute the offset for the down-projection */ HDmemset(block, 0, sizeof(block)); @@ -5723,15 +6338,15 @@ H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, /* Set the diminfo information for the higher dimensions */ for(new_space_dim = 0; new_space_dim < (new_space->extent.rank - base_space->extent.rank); new_space_dim++) { - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = 0; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = 1; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = 1; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = 1; - - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = 0; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = 1; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = 1; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = 1; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].start = 0; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].stride = 1; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].count = 1; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].block = 1; + + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].start = 0; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].stride = 1; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].count = 1; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].block = 1; } /* end for */ /* Start at beginning of base space's dimension info */ @@ -5740,31 +6355,37 @@ H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, /* Copy the diminfo */ while(base_space_dim < base_space->extent.rank) { - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].start; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].stride; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].count; - new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = - base_space->select.sel_info.hslab->app_diminfo[base_space_dim].block; - - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].start; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].stride; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].count; - new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = - base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].block; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].start = + base_space->select.sel_info.hslab->diminfo.app[base_space_dim].start; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].stride = + base_space->select.sel_info.hslab->diminfo.app[base_space_dim].stride; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].count = + base_space->select.sel_info.hslab->diminfo.app[base_space_dim].count; + new_space->select.sel_info.hslab->diminfo.app[new_space_dim].block = + base_space->select.sel_info.hslab->diminfo.app[base_space_dim].block; + + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].start = + base_space->select.sel_info.hslab->diminfo.opt[base_space_dim].start; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].stride = + base_space->select.sel_info.hslab->diminfo.opt[base_space_dim].stride; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].count = + base_space->select.sel_info.hslab->diminfo.opt[base_space_dim].count; + new_space->select.sel_info.hslab->diminfo.opt[new_space_dim].block = + base_space->select.sel_info.hslab->diminfo.opt[base_space_dim].block; /* Advance to next dimensions */ base_space_dim++; new_space_dim++; } /* end for */ + /* Update the bounding box */ + for(u = 0; u < new_space->extent.rank; u++) { + new_space->select.sel_info.hslab->diminfo.low_bounds[u] = new_space->select.sel_info.hslab->diminfo.opt[u].start; + new_space->select.sel_info.hslab->diminfo.high_bounds[u] = new_space->select.sel_info.hslab->diminfo.low_bounds[u] + new_space->select.sel_info.hslab->diminfo.opt[u].stride * (new_space->select.sel_info.hslab->diminfo.opt[u].count - 1) + (new_space->select.sel_info.hslab->diminfo.opt[u].block - 1); + } /* end for */ + /* Indicate that the dimension information is valid */ - new_space->select.sel_info.hslab->diminfo_valid = TRUE; + new_space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES; /* Indicate that there's no slab information */ new_space->select.sel_info.hslab->span_lst = NULL; @@ -5809,8 +6430,8 @@ H5S__hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions") } /* end else */ - /* Indicate that the dimension information is not valid */ - new_space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Copy the status of the dimension information */ + new_space->select.sel_info.hslab->diminfo_valid = base_space->select.sel_info.hslab->diminfo_valid; } /* end else */ /* Number of elements selected will be the same */ @@ -5832,7 +6453,9 @@ done: USAGE void H5S__hyper_adjust_s_helper(spans, offset) H5S_hyper_span_info_t *spans; IN: Span tree to operate with + unsigned rank; IN: Number of dimensions for span tree const hssize_t *offset; IN: Offset to subtract + uint64_t op_gen; IN: Operation generation RETURNS None DESCRIPTION @@ -5843,23 +6466,26 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static void -H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, - const hssize_t *offset) +H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, unsigned rank, + const hssize_t *offset, uint64_t op_gen) { FUNC_ENTER_STATIC_NOERR /* Sanity checks */ HDassert(spans); - HDassert(spans->scratch == (H5S_hyper_span_info_t *)~((size_t)NULL) || - spans->scratch == NULL); HDassert(offset); - /* Check if we've already set this down span tree */ - if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) { + /* Check if we've already set this span tree */ + if(spans->op_gen != op_gen) { H5S_hyper_span_t *span; /* Pointer to current span in span tree */ + unsigned u; /* Local index variable */ - /* Set the tree's scratch pointer */ - spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL); + /* Adjust the span tree's low & high bounds */ + for(u = 0; u < rank; u++) { + HDassert((hssize_t)spans->low_bounds[u] >= offset[u]); + spans->low_bounds[u] = (hsize_t)((hssize_t)spans->low_bounds[u] - offset[u]); + spans->high_bounds[u] = (hsize_t)((hssize_t)spans->high_bounds[u] - offset[u]); + } /* end for */ /* Iterate over the spans in tree */ span = spans->head; @@ -5871,11 +6497,14 @@ H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, /* Recursively adjust spans in next dimension down */ if(span->down != NULL) - H5S__hyper_adjust_s_helper(span->down, offset + 1); + H5S__hyper_adjust_s_helper(span->down, rank - 1, offset + 1, op_gen); /* Advance to next span in this dimension */ span = span->next; } /* end while */ + + /* Set the tree's operation generation */ + spans->op_gen = op_gen; } /* end if */ FUNC_LEAVE_NOAPI_VOID @@ -5903,6 +6532,8 @@ H5S__hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset) { + hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */ + unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -5911,22 +6542,38 @@ H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset) HDassert(space); HDassert(offset); - /* Subtract the offset from the "regular" coordinates, if they exist */ - if(space->select.sel_info.hslab->diminfo_valid) { - unsigned u; /* Local index variable */ + /* Check for an all-zero offset vector */ + for(u = 0; u < space->extent.rank; u++) + if(0 != offset[u]) { + non_zero_offset = TRUE; + break; + } /* end if */ - for(u = 0; u < space->extent.rank; u++) { - HDassert((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]); - space->select.sel_info.hslab->opt_diminfo[u].start = (hsize_t)((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start - offset[u]); - } /* end for */ - } /* end if */ + /* Only perform operation if the offset is non-zero */ + if(non_zero_offset) { + /* Subtract the offset from the "regular" coordinates, if they exist */ + /* (No need to rebuild the dimension info yet -QAK) */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + for(u = 0; u < space->extent.rank; u++) { + HDassert((hssize_t)space->select.sel_info.hslab->diminfo.opt[u].start >= offset[u]); + space->select.sel_info.hslab->diminfo.opt[u].start = (hsize_t)((hssize_t)space->select.sel_info.hslab->diminfo.opt[u].start - offset[u]); - /* Subtract the offset from the span tree coordinates, if they exist */ - if(space->select.sel_info.hslab->span_lst) { - H5S__hyper_adjust_s_helper(space->select.sel_info.hslab->span_lst, offset); + /* Adjust the low & high bounds */ + HDassert((hssize_t)space->select.sel_info.hslab->diminfo.low_bounds[u] >= offset[u]); + space->select.sel_info.hslab->diminfo.low_bounds[u] = (hsize_t)((hssize_t)space->select.sel_info.hslab->diminfo.low_bounds[u] - offset[u]); + space->select.sel_info.hslab->diminfo.high_bounds[u] = (hsize_t)((hssize_t)space->select.sel_info.hslab->diminfo.high_bounds[u] - offset[u]); + } /* end for */ + } /* end if */ + + /* Subtract the offset from the span tree coordinates, if they exist */ + if(space->select.sel_info.hslab->span_lst) { + uint64_t op_gen; /* Operation generation value */ - /* Reset the scratch pointers for the next routine which needs them */ - H5S__hyper_span_scratch(space->select.sel_info.hslab->span_lst); + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); + + H5S__hyper_adjust_s_helper(space->select.sel_info.hslab->span_lst, space->extent.rank, offset, op_gen); + } /* end if */ } /* end if */ done: @@ -6042,12 +6689,11 @@ done: PURPOSE Create a new span and append to span list USAGE - herr_t H5S__hyper_append_span(prev_span, span_tree, low, high, down, next) - H5S_hyper_span_t **prev_span; IN/OUT: Pointer to previous span in list + herr_t H5S__hyper_append_span(span_tree, ndims, low, high, down) H5S_hyper_span_info_t **span_tree; IN/OUT: Pointer to span tree to append to - hsize_t low, high; IN: Low and high bounds for new span node + unsigned ndims; IN: Number of dimension for span + hsize_t low, high; IN: Low and high bounds for new span node H5S_hyper_span_info_t *down; IN: Down span tree for new node - H5S_hyper_span_t *next; IN: Next span for new node RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -6059,81 +6705,117 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_append_span(H5S_hyper_span_t **prev_span, - H5S_hyper_span_info_t **span_tree, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next) +H5S__hyper_append_span(H5S_hyper_span_info_t **span_tree, unsigned ndims, + hsize_t low, hsize_t high, H5S_hyper_span_info_t *down) { H5S_hyper_span_t *new_span = NULL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - HDassert(prev_span); + /* Sanity check */ HDassert(span_tree); /* Check for adding first node to merged spans */ - if(*prev_span == NULL) { + if(*span_tree == NULL) { /* Allocate new span node to append to list */ - if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) + if(NULL == (new_span = H5S__hyper_new_span(low, high, down, NULL))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - /* Make first node in span list */ - - /* Check that we haven't already allocated a span tree */ - HDassert(*span_tree == NULL); + /* Make new span the first node in span list */ /* Allocate a new span_info node */ - if(NULL == (*span_tree = H5FL_CALLOC(H5S_hyper_span_info_t))) + if(NULL == (*span_tree = H5S__hyper_new_span_info(ndims))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") /* Set the span tree's basic information */ (*span_tree)->count = 1; (*span_tree)->head = new_span; + (*span_tree)->tail = new_span; + + /* Set low & high bounds for new span tree */ + (*span_tree)->low_bounds[0] = low; + (*span_tree)->high_bounds[0] = high; + if(down) { + /* Sanity check */ + HDassert(ndims > 1); - /* Update previous merged span */ - *prev_span = new_span; + HDmemcpy(&((*span_tree)->low_bounds[1]), down->low_bounds, sizeof(hsize_t) * (ndims - 1)); + HDmemcpy(&((*span_tree)->high_bounds[1]), down->high_bounds, sizeof(hsize_t) * (ndims - 1)); + } /* end if */ } /* end if */ /* Merge or append to existing merged spans list */ else { + htri_t down_cmp = (-1); /* Comparison value for down spans */ + /* Check if span can just extend the previous merged span */ - if((((*prev_span)->high + 1) == low) && - H5S__hyper_cmp_spans(down, (*prev_span)->down)==TRUE) { + if((((*span_tree)->tail->high + 1) == low) && + (down_cmp = H5S__hyper_cmp_spans(down, (*span_tree)->tail->down))) { /* Extend previous merged span to include new high bound */ - (*prev_span)->high = high; - (*prev_span)->nelem += (high - low) + 1; + (*span_tree)->tail->high = high; + + /* Extend span tree's high bound in this dimension */ + /* (No need to update lower dimensions, since this span shares them with previous span) */ + (*span_tree)->high_bounds[0] = high; } /* end if */ else { - /* Allocate new span node to append to list */ - if(NULL == (new_span = H5S__hyper_new_span(low, high, down, next))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") + H5S_hyper_span_info_t *new_down; /* Down pointer for new span node */ + + /* Sanity check */ + /* (If down_cmp was set to TRUE above, we won't be in this branch) */ + HDassert(down_cmp != TRUE); /* Check if there is actually a down span */ - if(new_span->down) { + if(down) { /* Check if the down spans for the new span node are the same as the previous span node */ - if(H5S__hyper_cmp_spans(new_span->down, (*prev_span)->down)) { - /* Release the down span for the new node */ - H5S__hyper_free_span_info(new_span->down); - - /* Point the new node's down span at the previous node's down span */ - new_span->down = (*prev_span)->down; + /* (Uses the 'down span comparison' from earlier, if already computed) */ + if(down_cmp < 0 && (down_cmp = H5S__hyper_cmp_spans(down, (*span_tree)->tail->down))) + /* Share the previous span's down span tree */ + new_down = (*span_tree)->tail->down; + else + new_down = down; + } /* end if */ + else + new_down = NULL; - /* Increment the reference count to the shared down span */ - new_span->down->count++; + /* Allocate new span node to append to list */ + if(NULL == (new_span = H5S__hyper_new_span(low, high, new_down, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") + + /* Update the high bounds for current dimension */ + (*span_tree)->high_bounds[0] = high; + + /* Update low & high bounds in lower dimensions, if there are any */ + if(down) { + /* Sanity checks */ + HDassert(ndims > 1); + HDassert(down_cmp >= 0); + + /* Check if we are sharing down spans with a previous node */ + /* (Only need to check for bounds changing if down spans aren't shared) */ + if(down_cmp == FALSE) { + unsigned u; /* Local index variable */ + + /* Loop over lower dimensions, checking & updating low & high bounds */ + for(u = 0; u < (ndims - 1); u++) { + if(down->low_bounds[u] < (*span_tree)->low_bounds[u + 1]) + (*span_tree)->low_bounds[u + 1] = down->low_bounds[u]; + if(down->high_bounds[u] > (*span_tree)->high_bounds[u + 1]) + (*span_tree)->high_bounds[u + 1] = down->high_bounds[u]; + } /* end for */ } /* end if */ } /* end if */ - /* Indicate elements from previous span */ - new_span->pstride = low - (*prev_span)->low; - /* Append to end of merged spans list */ - (*prev_span)->next = new_span; - *prev_span = new_span; + (*span_tree)->tail->next = new_span; + (*span_tree)->tail = new_span; } /* end else */ } /* end else */ done: if(ret_value < 0) - if(new_span && H5S__hyper_free_span(new_span) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span") + if(new_span) + H5S__hyper_free_span(new_span); FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_append_span() */ @@ -6145,9 +6827,18 @@ done: PURPOSE Clip a new span tree against the current spans in the hyperslab selection USAGE - herr_t H5S__hyper_clip_spans(span_a, span_b, a_not_b, a_and_b, b_not_a) + herr_t H5S__hyper_clip_spans(span_a, span_b, selector, curr_dim, dim_size, + span_a_b_bounds[4], all_clips_bound, + a_not_b, a_and_b, b_not_a) H5S_hyper_span_t *a_spans; IN: Span tree 'a' to clip with. H5S_hyper_span_t *b_spans; IN: Span tree 'b' to clip with. + unsigned selector; IN: The parameter deciding which output is needed + (only considering the last three bits ABC: + If A is set, then a_not_b is needed; + If B is set, then a_and_b is needed; + If C is set, then b_not_a is needed; + ) + unsigned ndims; IN: Number of dimensions of this span tree H5S_hyper_span_t **a_not_b; OUT: Span tree of 'a' hyperslab spans which doesn't overlap with 'b' hyperslab spans. @@ -6172,20 +6863,14 @@ done: --------------------------------------------------------------------------*/ static herr_t H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans, + unsigned selector, unsigned ndims, H5S_hyper_span_info_t **a_not_b, H5S_hyper_span_info_t **a_and_b, H5S_hyper_span_info_t **b_not_a) { - H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */ - H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */ - H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */ - H5S_hyper_span_t *last_a_not_b; /* Pointer to previous node in span tree 'a_not_b' */ - H5S_hyper_span_t *last_a_and_b; /* Pointer to previous node in span tree 'a_and_b' */ - H5S_hyper_span_t *last_b_not_a; /* Pointer to previous node in span tree 'b_not_a' */ - H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */ - H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */ - H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */ - hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t need_a_not_b; /* Whether to generate a_not_b list */ + hbool_t need_a_and_b; /* Whether to generate a_and_b list */ + hbool_t need_b_not_a; /* Whether to generate b_not_a list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -6196,6 +6881,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HDassert(a_and_b); HDassert(b_not_a); + /* Set which list(s) to be generated, based on selector */ + need_a_not_b = ((selector & H5S_HYPER_COMPUTE_A_NOT_B) != 0); + need_a_and_b = ((selector & H5S_HYPER_COMPUTE_A_AND_B) != 0); + need_b_not_a = ((selector & H5S_HYPER_COMPUTE_B_NOT_A) != 0); + /* Check if both span trees are not defined */ if(a_spans == NULL && b_spans == NULL) { *a_not_b = NULL; @@ -6206,38 +6896,56 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s else if(a_spans == NULL) { *a_not_b = NULL; *a_and_b = NULL; - if(NULL == (*b_not_a = H5S__hyper_copy_span(b_spans))) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + if(need_b_not_a) { + if(NULL == (*b_not_a = H5S__hyper_copy_span(b_spans, ndims))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + } /* end if */ + else + *b_not_a = NULL; } /* end if */ /* If span 'b' is not defined, but 'a' is, copy 'a' and set the other return span trees to empty */ else if(b_spans == NULL) { - if(NULL == (*a_not_b = H5S__hyper_copy_span(a_spans)) ) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") *a_and_b = NULL; *b_not_a = NULL; + if(need_a_not_b) { + if(NULL == (*a_not_b = H5S__hyper_copy_span(a_spans, ndims))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + } /* end if */ + else + *a_not_b = NULL; } /* end if */ /* If span 'a' and 'b' are both defined, calculate the proper span trees */ else { /* Check if both span trees completely overlap */ if(H5S__hyper_cmp_spans(a_spans, b_spans)) { *a_not_b = NULL; - if(NULL == (*a_and_b = H5S__hyper_copy_span(a_spans))) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") *b_not_a = NULL; + if(need_a_and_b) { + if(NULL == (*a_and_b = H5S__hyper_copy_span(a_spans, ndims))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree") + } /* end if */ + else + *a_and_b = NULL; } /* end if */ else { + H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */ + H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */ + hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ + /* Get the pointers to the new and old span lists */ span_a = a_spans->head; span_b = b_spans->head; - /* Reset the pointers to the previous spans */ - last_a_not_b = last_a_and_b = last_b_not_a = NULL; - /* No spans to recover yet */ recover_a = recover_b = FALSE; /* Work through the list of spans in the new list */ while(span_a != NULL && span_b != NULL) { + H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */ + H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */ + H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */ + H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */ + /* Check if span 'a' is completely before span 'b' */ /* AAAAAAA */ /* <-----------------------------------> */ @@ -6246,11 +6954,12 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Copy span 'a' and add to a_not_b list */ /* Merge/add span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, span_a->down, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_not_b) + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance span 'a', leave span 'b' */ - H5S__hyper_recover_span(&recover_a, &span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); } /* end if */ /* Check if span 'a' overlaps only the lower bound */ /* of span 'b' , up to the upper bound of span 'b' */ @@ -6261,8 +6970,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Split span 'a' into two parts at the low bound of span 'b' */ /* Merge/add lower part of span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->low - 1, span_a->down, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_not_b) + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_b->low - 1, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Check for overlaps between upper part of span 'a' and lower part of span 'b' */ @@ -6272,8 +6982,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* If there are no down spans, just add the overlapping area to the a_and_b list */ if(span_a->down == NULL) { /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_a->high, NULL, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_and_b) + if(H5S__hyper_append_span(a_and_b, ndims, span_b->low, span_a->high, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ /* If there are down spans, check for the overlap in them and add to each appropriate list */ else { @@ -6283,14 +6994,20 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s down_b_not_a = NULL; /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + /** Note: since the bound box of remaining dimensions + * has been updated in the following clip function (via + * all_clips_bounds), there's no need updating the bound box + * after each append call in the following codes */ + if(H5S__hyper_clip_spans(span_a->down, span_b->down, selector, ndims - 1, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") /* Check for additions to the a_not_b list */ if(down_a_not_b) { + HDassert(need_a_not_b == TRUE); + /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_a->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_not_b, ndims, span_b->low, span_a->high, down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_not_b); @@ -6298,9 +7015,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check for additions to the a_and_b list */ if(down_a_and_b) { + HDassert(need_a_and_b == TRUE); + /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_a->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_and_b, ndims, span_b->low, span_a->high, down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_and_b); @@ -6308,9 +7027,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check for additions to the b_not_a list */ if(down_b_not_a) { + HDassert(need_b_not_a == TRUE); + /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_a->high, down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_b_not_a); @@ -6326,17 +7047,17 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); /* Make upper part of span 'b' into new span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); recover_b = TRUE; } /* end if */ /* No upper part of span 'b' to split */ else { /* Advance both 'a' and 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end if */ /* Check if span 'a' overlaps the lower & upper bound */ @@ -6348,8 +7069,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Split off lower part of span 'a' at lower span of span 'b' */ /* Merge/add lower part of span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_not_b) + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_b->low - 1, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Check for overlaps between middle part of span 'a' and span 'b' */ @@ -6359,8 +7081,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* If there are no down spans, just add the overlapping area to the a_and_b list */ if(span_a->down == NULL) { /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_and_b) + if(H5S__hyper_append_span(a_and_b, ndims, span_b->low, span_b->high, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ /* If there are down spans, check for the overlap in them and add to each appropriate list */ else { @@ -6370,14 +7093,16 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s down_b_not_a = NULL; /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + if(H5S__hyper_clip_spans(span_a->down, span_b->down, selector, ndims - 1, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") /* Check for additions to the a_not_b list */ if(down_a_not_b) { + HDassert(need_a_not_b == TRUE); + /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_b->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_not_b, ndims, span_b->low, span_b->high, down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_not_b); @@ -6385,9 +7110,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check for additions to the a_and_b list */ if(down_a_and_b) { + HDassert(need_a_and_b == TRUE); + /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_and_b, ndims, span_b->low, span_b->high, down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_and_b); @@ -6395,9 +7122,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check for additions to the b_not_a list */ if(down_b_not_a) { + HDassert(need_b_not_a == TRUE); + /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_b->high, down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_b_not_a); @@ -6411,11 +7140,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") /* Make upper part of span 'a' the new span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); recover_a = TRUE; /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end if */ /* Check if span 'a' is entirely within span 'b' */ /* AAAAA */ @@ -6427,8 +7156,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check if there is actually a lower part of span 'b' to split off */ if(span_a->low > span_b->low) { /* Merge/add lower part of span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_b_not_a) + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_a->low - 1, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ else { /* Keep going, nothing to split off */ @@ -6442,8 +7172,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* If there are no down spans, just add the overlapping area to the a_and_b list */ if(span_a->down == NULL) { /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_and_b) + if(H5S__hyper_append_span(a_and_b, ndims, span_a->low, span_a->high, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ /* If there are down spans, check for the overlap in them and add to each appropriate list */ else { @@ -6453,34 +7184,40 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s down_b_not_a = NULL; /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + if(H5S__hyper_clip_spans(span_a->down, span_b->down, selector, ndims - 1, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") /* Check for additions to the a_not_b list */ if(down_a_not_b) { + HDassert(need_a_not_b == TRUE); + /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_a->high, down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_not_b); } /* end if */ /* Check for additions to the a_and_b list */ - if(down_a_and_b!=NULL) { + if(down_a_and_b) { + HDassert(need_a_and_b == TRUE); + /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_and_b, ndims, span_a->low, span_a->high, down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_and_b); } /* end if */ /* Check for additions to the b_not_a list */ - if(down_b_not_a!=NULL) { + if(down_b_not_a) { + HDassert(need_b_not_a == TRUE); + /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_a->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(b_not_a, ndims, span_a->low, span_a->high, down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_b_not_a); @@ -6496,16 +7233,16 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") /* And advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); /* Make upper part of span 'b' the new span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); - recover_b=1; + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); + recover_b = TRUE; } /* end if */ else { /* Advance both span 'a' & span 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end if */ /* Check if span 'a' overlaps only the upper bound */ @@ -6519,8 +7256,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Split off lower part of span 'b' at lower span of span 'a' */ /* Merge/add lower part of span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_b_not_a) + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_a->low - 1, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ else { /* Keep going, nothing to split off */ @@ -6534,8 +7272,9 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* If there are no down spans, just add the overlapping area to the a_and_b list */ if(span_a->down == NULL) { /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,NULL,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_a_and_b) + if(H5S__hyper_append_span(a_and_b, ndims, span_a->low, span_b->high, NULL) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") } /* end if */ /* If there are down spans, check for the overlap in them and add to each appropriate list */ else { @@ -6545,24 +7284,28 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s down_b_not_a = NULL; /* Check for overlaps in the 'down spans' of span 'a' & 'b' */ - if(H5S__hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0) + if(H5S__hyper_clip_spans(span_a->down, span_b->down, selector, ndims - 1, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") /* Check for additions to the a_not_b list */ if(down_a_not_b) { + HDassert(need_a_not_b == TRUE); + /* Merge/add overlapped part with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->high,down_a_not_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_b->high, down_a_not_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_not_b); } /* end if */ /* Check for additions to the a_and_b list */ - if(down_a_and_b!=NULL) { + if(down_a_and_b) { + HDassert(need_a_and_b == TRUE); + /* Merge/add overlapped part with/to a_and_b list */ - if(H5S__hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,down_a_and_b,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(a_and_b, ndims, span_a->low, span_b->high, down_a_and_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_a_and_b); @@ -6570,9 +7313,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Check for additions to the b_not_a list */ if(down_b_not_a) { + HDassert(need_b_not_a == TRUE); + /* Merge/add overlapped part with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_b->high,down_b_not_a,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(b_not_a, ndims, span_a->low, span_b->high, down_b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Release the down span tree generated */ H5S__hyper_free_span_info(down_b_not_a); @@ -6586,11 +7331,11 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") /* Make upper part of span 'a' into new span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); - recover_a=1; + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); + recover_a = TRUE; /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end if */ /* span 'a' must be entirely above span 'b' */ /* AAAAA */ @@ -6600,40 +7345,70 @@ H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_s /* Copy span 'b' and add to b_not_a list */ /* Merge/add span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + if(need_b_not_a) + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_b->high, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Advance span 'b', leave span 'a' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end while */ /* Clean up 'a' spans which haven't been covered yet */ if(span_a != NULL && span_b == NULL) { - while(span_a != NULL) { - /* Copy span 'a' and add to a_not_b list */ - - /* Merge/add span 'a' with/to a_not_b list */ - if(H5S__hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + /* Check if need to merge/add 'a' spans with/to a_not_b list */ + if(need_a_not_b) { + /* (This loop, and the similar one below for 'b' spans, + * could be replaced with an optimized routine that quickly + * appended the remaining spans to the 'not' list, but + * until it looks like it's taking a lot of time for an + * important use case, it's been left generic, and similar + * to other code above. -QAK, 2019/02/01) + */ + while(span_a != NULL) { + /* Copy span 'a' and add to a_not_b list */ + if(H5S__hyper_append_span(a_not_b, ndims, span_a->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Advance to the next 'a' span */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - } /* end while */ + /* Advance to the next 'a' span */ + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + } /* end while */ + } /* end if */ + else { + /* Free the span, if it's generated */ + if(recover_a) + H5S__hyper_free_span(span_a); + } /* end else */ } /* end if */ /* Clean up 'b' spans which haven't been covered yet */ else if(span_a == NULL && span_b != NULL) { - while(span_b != NULL) { - /* Copy span 'b' and add to b_not_a list */ - - /* Merge/add span 'b' with/to b_not_a list */ - if(H5S__hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") + /* Check if need to merge/add 'b' spans with/to b_not_a list */ + if(need_b_not_a) { + /* (This loop, and the similar one above for 'a' spans, + * could be replaced with an optimized routine that quickly + * appended the remaining spans to the 'not' list, but + * until it looks like it's taking a lot of time for an + * important use case, it's been left generic, and similar + * to other code above. -QAK, 2019/02/01) + */ + while(span_b != NULL) { + /* Copy span 'b' and add to b_not_a list */ + if(H5S__hyper_append_span(b_not_a, ndims, span_b->low, span_b->high, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") - /* Advance to the next 'b' span */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); - } /* end while */ + /* Advance to the next 'b' span */ + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); + } /* end while */ + } /* end if */ + else { + /* Free the span, if it's generated */ + if(recover_b) + H5S__hyper_free_span(span_b); + } /* end else */ } /* end if */ + else + /* Sanity check */ + HDassert(span_a == NULL && span_b == NULL); } /* end else */ } /* end else */ @@ -6653,6 +7428,7 @@ done: together H5S_hyper_span_info_t *b_spans; IN: Second hyperslab spans to merge together + unsigned ndims; IN: Number of dimensions of this span tree RETURNS Pointer to span tree containing the merged spans on success, NULL on failure DESCRIPTION @@ -6660,11 +7436,13 @@ done: the merged set. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + Handles merging span trees that overlap. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static H5S_hyper_span_info_t * -H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans) +H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans, + unsigned ndims) { H5S_hyper_span_info_t *merged_spans = NULL; /* Pointer to the merged span tree */ H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ @@ -6680,23 +7458,19 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf merged_spans = NULL; else { /* Copy one of the span trees to return */ - if(NULL == (merged_spans = H5S__hyper_copy_span(a_spans))) + if(NULL == (merged_spans = H5S__hyper_copy_span(a_spans, ndims))) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree") } /* end else */ } /* end if */ else { H5S_hyper_span_t *span_a; /* Pointer to current span 'a' working on */ H5S_hyper_span_t *span_b; /* Pointer to current span 'b' working on */ - H5S_hyper_span_t *prev_span_merge; /* Pointer to previous merged span */ hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */ /* Get the pointers to the 'a' and 'b' span lists */ span_a = a_spans->head; span_b = b_spans->head; - /* Set the pointer to the previous spans */ - prev_span_merge = NULL; - /* No spans to recover yet */ recover_a = recover_b = FALSE; @@ -6711,11 +7485,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* BBBBBBBBBB */ if(span_a->high < span_b->low) { /* Merge/add span 'a' with/to the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); } /* end if */ /* Check if span 'a' overlaps only the lower bound */ /* of span 'b', up to the upper bound of span 'b' */ @@ -6726,20 +7500,20 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* Check if span 'a' and span 'b' down spans are equal */ if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { /* Merge/add copy of span 'a' with/to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* Merge/add lower part of span 'a' with/to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->low - 1, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down, span_b->down, ndims - 1); /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_a->high, tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ H5S__hyper_free_span_info(tmp_spans); @@ -6750,20 +7524,20 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* Copy upper part of span 'b' as new span 'b' */ /* Allocate new span node to append to list */ - if((tmp_span = H5S__hyper_new_span(span_a->high+1,span_b->high,span_b->down,span_b->next))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span") + if(NULL == (tmp_span = H5S__hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); /* Set new span 'b' to tmp_span */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); recover_b = TRUE; } /* end if */ else { /* Advance both span 'a' & 'b' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end if */ /* Check if span 'a' overlaps the lower & upper bound */ @@ -6775,20 +7549,20 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* Check if span 'a' and span 'b' down spans are equal */ if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { /* Merge/add copy of lower & middle parts of span 'a' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* Merge/add lower part of span 'a' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->low - 1, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down, span_b->down, ndims - 1); /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_b->high, tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ H5S__hyper_free_span_info(tmp_spans); @@ -6801,11 +7575,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set new span 'a' to tmp_span */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); recover_a = TRUE; /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end if */ /* Check if span 'a' is entirely within span 'b' */ /* AAAAA */ @@ -6815,26 +7589,26 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* Check if span 'a' and span 'b' down spans are equal */ if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { /* Merge/add copy of lower & middle parts of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* Check if there is a lower part of span 'b' */ if(span_a->low > span_b->low) { /* Merge/add lower part of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_a->low - 1, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* No lower part of span 'b' , keep going... */ } /* end else */ /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down, span_b->down, ndims - 1); /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_a->high, tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ H5S__hyper_free_span_info(tmp_spans); @@ -6849,16 +7623,16 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Advance span 'a' */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); /* Set new span 'b' to tmp_span */ - H5S__hyper_recover_span(&recover_b,&span_b,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span); recover_b = TRUE; } /* end if */ else { /* Advance both spans */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end if */ /* Check if span 'a' overlaps only the upper bound */ @@ -6870,26 +7644,26 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* Check if span 'a' and span 'b' down spans are equal */ if(H5S__hyper_cmp_spans(span_a->down, span_b->down)) { /* Merge/add copy of span 'b' to merged spans if so */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_b->high, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* Check if there is a lower part of span 'b' */ if(span_a->low > span_b->low) { /* Merge/add lower part of span 'b' to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_a->low - 1, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") } /* end if */ else { /* No lower part of span 'b' , keep going... */ } /* end else */ /* Get merged span tree for overlapped section */ - tmp_spans = H5S__hyper_merge_spans_helper(span_a->down,span_b->down); + tmp_spans = H5S__hyper_merge_spans_helper(span_a->down, span_b->down, ndims - 1); /* Merge/add overlapped section to merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_b->high,tmp_spans,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_b->high, tmp_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Release merged span tree for overlapped section */ H5S__hyper_free_span_info(tmp_spans); @@ -6902,11 +7676,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set new span 'a' to tmp_span */ - H5S__hyper_recover_span(&recover_a,&span_a,tmp_span); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span); recover_a = TRUE; /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end if */ /* Span 'a' must be entirely above span 'b' */ /* AAAAA */ @@ -6914,11 +7688,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf /* BBBBBBBBBB */ else { /* Merge/add span 'b' with the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_b->high, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance span 'b' */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end else */ } /* end while */ @@ -6926,11 +7700,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if(span_a != NULL && span_b == NULL) { while(span_a != NULL) { /* Merge/add all 'a' spans into the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_a->low, span_a->high, span_a->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance to next 'a' span, until all processed */ - H5S__hyper_recover_span(&recover_a,&span_a,span_a->next); + H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next); } /* end while */ } /* end if */ @@ -6938,11 +7712,11 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf if(span_a == NULL && span_b != NULL) { while(span_b != NULL) { /* Merge/add all 'b' spans into the merged spans */ - if(H5S__hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_b->high,span_b->down,NULL)==FAIL) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") + if(H5S__hyper_append_span(&merged_spans, ndims, span_b->low, span_b->high, span_b->down) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, NULL, "can't allocate hyperslab span") /* Advance to next 'b' span, until all processed */ - H5S__hyper_recover_span(&recover_b,&span_b,span_b->next); + H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next); } /* end while */ } /* end if */ } /* end else */ @@ -6952,8 +7726,8 @@ H5S__hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_inf done: if(ret_value == NULL) - if(merged_spans && H5S__hyper_free_span_info(merged_spans) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans") + if(merged_spans) + H5S__hyper_free_span_info(merged_spans); FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_merge_spans_helper() */ @@ -6970,44 +7744,37 @@ done: selection. H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to hyperslab selection - hbool_t can_own; IN: Flag to indicate that it is OK to point - directly to the new spans, instead of - copying them. RETURNS non-negative on success, negative on failure DESCRIPTION - Add a set of hyperslab spans to an existing hyperslab selection. The - new spans are required to be non-overlapping with the existing spans in - the dataspace's current hyperslab selection. + Add a set of hyperslab spans to an existing hyperslab selection. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t can_own) +H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans) { - FUNC_ENTER_STATIC_NOERR + herr_t ret_value = SUCCEED; /* Return value */ - /* Check args */ + FUNC_ENTER_STATIC + + /* Sanity checks */ HDassert(space); HDassert(new_spans); /* If this is the first span tree in the hyperslab selection, just use it */ if(space->select.sel_info.hslab->span_lst == NULL) { - if(can_own) - space->select.sel_info.hslab->span_lst = new_spans; - else - space->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(new_spans); + space->select.sel_info.hslab->span_lst = new_spans; + space->select.sel_info.hslab->span_lst->count++; } /* end if */ else { H5S_hyper_span_info_t *merged_spans; /* Get the merged spans */ - merged_spans = H5S__hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans); - - /* Sanity checking since we started with some spans, we should still have some after the merge */ - HDassert(merged_spans); + if(NULL == (merged_spans = H5S__hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans, space->extent.rank))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTMERGE, FAIL, "can't merge hyperslab spans") /* Free the previous spans */ H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); @@ -7016,18 +7783,20 @@ H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t c space->select.sel_info.hslab->span_lst = merged_spans; } /* end else */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_merge_spans() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_spans_nelem + H5S__hyper_spans_nelem_helper PURPOSE Count the number of elements in a span tree USAGE - hsize_t H5S__hyper_spans_nelem(spans) + hsize_t H5S__hyper_spans_nelem_helper(spans, op_gen) const H5S_hyper_span_info_t *spans; IN: Hyperslan span tree to count elements of + uint64_t op_gen; IN: Operation generation RETURNS Number of elements in span tree on success; negative on failure DESCRIPTION @@ -7038,36 +7807,147 @@ H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t c REVISION LOG --------------------------------------------------------------------------*/ static hsize_t -H5S__hyper_spans_nelem(const H5S_hyper_span_info_t *spans) +H5S__hyper_spans_nelem_helper(H5S_hyper_span_info_t *spans, uint64_t op_gen) { hsize_t ret_value = 0; /* Return value */ FUNC_ENTER_STATIC_NOERR - /* Count the number of elements in the span tree */ - if(spans != NULL) { + /* Sanity check */ + HDassert(spans); + + /* Check if the span tree was already counted */ + if(spans->op_gen == op_gen) + /* Just return the # of elements in the already counted span tree */ + ret_value = spans->u.nelmts; + else { /* Count the number of elements in the span tree */ const H5S_hyper_span_t *span; /* Hyperslab span */ span = spans->head; - while(span != NULL) { - /* If there are down spans, multiply the size of this span by the total down span elements */ - if(span->down != NULL) - ret_value += span->nelem * H5S__hyper_spans_nelem(span->down); - /* If there are no down spans, just count the elements in this span */ - else - ret_value += span->nelem; + if(NULL == span->down) { + while(span != NULL) { + /* Compute # of elements covered */ + ret_value += (span->high - span->low) + 1; - /* Advance to next span */ - span = span->next; - } /* end while */ + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end if */ + else { + while(span != NULL) { + hsize_t nelmts; /* # of elements covered by current span */ + + /* Compute # of elements covered */ + nelmts = (span->high - span->low) + 1; + + /* Multiply the size of this span by the total down span elements */ + ret_value += nelmts * H5S__hyper_spans_nelem_helper(span->down, op_gen); + + /* Advance to next span */ + span = span->next; + } /* end while */ + } /* end else */ + + /* Set the operation generation for this span tree, to avoid re-computing */ + spans->op_gen = op_gen; + + /* Hold a copy of the # of elements */ + spans->u.nelmts = ret_value; } /* end else */ FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_spans_nelem_helper() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_spans_nelem + PURPOSE + Count the number of elements in a span tree + USAGE + hsize_t H5S__hyper_spans_nelem(spans) + const H5S_hyper_span_info_t *spans; IN: Hyperslan span tree to count elements of + RETURNS + Number of elements in span tree on success; negative on failure + DESCRIPTION + Counts the number of elements described by the spans in a span tree. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static hsize_t +H5S__hyper_spans_nelem(H5S_hyper_span_info_t *spans) +{ + uint64_t op_gen; /* Operation generation value */ + hsize_t ret_value = 0; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(spans); + + /* Acquire an operation generation value for this operation */ + op_gen = H5S__hyper_get_op_gen(); + + /* Count the number of elements in the span tree */ + ret_value = H5S__hyper_spans_nelem_helper(spans, op_gen); + + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__hyper_spans_nelem() */ /*-------------------------------------------------------------------------- NAME + H5S__hyper_add_disjoint_spans + PURPOSE + Add new hyperslab spans to existing hyperslab selection in the case the + new hyperslab spans don't overlap with the existing hyperslab selection + USAGE + herr_t H5S__hyper_add_disjoint_spans(space, new_spans) + H5S_t *space; IN: Dataspace to add new spans to hyperslab + selection. + H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to + hyperslab selection + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Add a set of hyperslab spans to an existing hyperslab selection. The + new spans are required not to overlap with the existing spans in the + dataspace's current hyperslab selection in terms of bound box. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + HDassert(space); + HDassert(new_spans); + + /* Update the number of elements in the selection */ + space->select.num_elem += H5S__hyper_spans_nelem(new_spans); + + /* Add the new spans to the existing selection in the dataspace */ + if(H5S__hyper_merge_spans(space, new_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't merge hyperslabs") + + /* Free the memory space for new spans */ + H5S__hyper_free_span_info(new_spans); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_add_disjoint_spans */ + + +/*-------------------------------------------------------------------------- + NAME H5S__hyper_make_spans PURPOSE Create a span tree @@ -7098,9 +7978,7 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride H5S_hyper_span_info_t *down = NULL; /* Pointer to spans in next dimension down */ H5S_hyper_span_t *last_span; /* Current position in hyperslab span list */ H5S_hyper_span_t *head = NULL; /* Head of new hyperslab span list */ - hsize_t stride_iter; /* Iterator over the stride values */ int i; /* Counters */ - unsigned u; /* Counters */ H5S_hyper_span_info_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -7114,6 +7992,9 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride /* Start creating spans in fastest changing dimension */ for(i = (int)(rank - 1); i >= 0; i--) { + hsize_t curr_low, curr_high; /* Current low & high values */ + hsize_t dim_stride; /* Current dim's stride */ + unsigned u; /* Local index variable */ /* Sanity check */ if(0 == count[i]) @@ -7124,8 +8005,10 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride last_span = NULL; /* Generate all the span segments for this dimension */ - for(u = 0, stride_iter = 0; u < count[i]; u++, stride_iter += stride[i]) - { + curr_low = start[i]; + curr_high = start[i] + (block[i] - 1); + dim_stride = stride[i]; + for(u = 0; u < count[i]; u++, curr_low += dim_stride, curr_high += dim_stride) { H5S_hyper_span_t *span; /* New hyperslab span */ /* Allocate a span node */ @@ -7133,12 +8016,14 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Set the span's basic information */ - span->low = start[i] + stride_iter; - span->high = span->low + (block[i] - 1); - span->nelem = block[i]; - span->pstride = stride[i]; + span->low = curr_low; + span->high = curr_high; span->next = NULL; + /* Set the information for the next dimension down's spans */ + /* (Will be NULL for fastest changing dimension) */ + span->down = down; + /* Append to the list of spans in this dimension */ if(head == NULL) head = span; @@ -7147,23 +8032,32 @@ H5S__hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride /* Move current pointer */ last_span = span; - - /* Set the information for the next dimension down's spans, if appropriate */ - if(down != NULL) { - span->down = down; - down->count++; /* Increment reference count for shared span */ - } /* end if */ - else - span->down = NULL; } /* end for */ + /* Increment ref. count of shared span */ + if(down != NULL) + down->count = (unsigned)count[i]; + /* Allocate a span info node */ - if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t))) + if(NULL == (down = H5S__hyper_new_span_info(rank))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span") /* Keep the pointer to the next dimension down's completed list */ down->head = head; + /* Keep the tail pointer to the next dimension down's completed list */ + down->tail = last_span; + + /* Set the low & high bounds for this dimension */ + down->low_bounds[0] = down->head->low; + down->high_bounds[0] = down->tail->high; + + /* Copy bounds from lower dimensions */ + /* (head & tail pointers share lower dimensions, so using either is OK) */ + if(head->down) { + HDmemcpy(&down->low_bounds[1], &head->down->low_bounds[0], sizeof(hsize_t) * ((rank - 1) - (unsigned)i)); + HDmemcpy(&down->high_bounds[1], &head->down->high_bounds[0], sizeof(hsize_t) * ((rank - 1) - (unsigned)i)); + } /* end if */ } /* end for */ /* Indicate that there is a pointer to this tree */ @@ -7184,7 +8078,7 @@ done: do { if(down) { head = down->head; - down = H5FL_FREE(H5S_hyper_span_info_t, down); + down = (H5S_hyper_span_info_t *)H5FL_ARR_FREE(hbounds_t, down); } /* end if */ down = head->down; @@ -7203,146 +8097,234 @@ done: /*-------------------------------------------------------------------------- NAME - H5S__hyper_rebuild_helper + H5S__hyper_update_diminfo PURPOSE - Helper routine to rebuild optimized hyperslab information if possible. - (It can be recovered with regular selection) + Attempt to update optimized hyperslab information quickly. (It can be + recovered with regular selection). If this algorithm cannot determine + the optimized dimension info quickly, this function will simply mark it + as invalid and unknown if it can be built (H5S_DIMINFO_VALID_NO), so + H5S__hyper_rebuild can be run later to determine for sure. USAGE - herr_t H5S__hyper_rebuild_helper(space) - const H5S_hyper_span_t *span; IN: Portion of span tree to check - H5S_hyper_dim_t span_slab[]; OUT: Rebuilt section of hyperslab description - unsigned rank; IN: Current dimension to work on + herr_t H5S__hyper_update_diminfo(space, op, new_hyper_diminfo) + H5S_t *space; IN: Dataspace to check + H5S_seloper_t op; IN: The operation being performed on the + selection + const H5S_hyper_dim_t new_hyper_diminfo; IN: The new selection that + is being combined with + the current RETURNS - TRUE/FALSE for hyperslab selection rebuilt + >=0 on success, <0 on failure DESCRIPTION Examine the span tree for a hyperslab selection and rebuild the start/stride/count/block information for the selection, if possible. + GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - To be able to recover the optimized information, the span tree must conform - to span tree able to be generated from a single H5S_SELECT_SET operation. EXAMPLES REVISION LOG - KY, 2005/9/22 --------------------------------------------------------------------------*/ -static hbool_t -H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab_info[], - unsigned rank) +static herr_t +H5S__hyper_update_diminfo(H5S_t *space, H5S_seloper_t op, + const H5S_hyper_dim_t *new_hyper_diminfo) { - hbool_t ret_value = TRUE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC_NOERR - if(span) { - const H5S_hyper_span_t *prev_span = NULL; /* Previous span in list */ - H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK]; - hsize_t curr_stride; - hsize_t curr_block; - hsize_t curr_start; - hsize_t curr_low; - size_t outcount; /* Number of spans encountered in this dimension */ - - /* Initialization */ - curr_stride = 1; - curr_low = 0; - outcount = 0; - - /* Get "canonical" down span information */ - if(span->down) { - HDassert(span->down->head); - - /* Go to the next down span and check whether the selection can be rebuilt */ - if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) - HGOTO_DONE(FALSE) - - HDmemcpy(canon_down_span_slab_info, span_slab_info, sizeof(H5S_hyper_dim_t) * rank); - } /* end if */ + /* Check args */ + HDassert(space); + HDassert(new_hyper_diminfo); + + /* Check for conditions that prevent us from using the fast algorithm here */ + /* (and instead require H5S__hyper_rebuild) */ + if(!((op == H5S_SELECT_OR) || (op == H5S_SELECT_XOR)) + || space->select.sel_info.hslab->diminfo_valid != H5S_DIMINFO_VALID_YES + || !space->select.sel_info.hslab->span_lst->head) + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + else { + H5S_hyper_dim_t tmp_diminfo[H5S_MAX_RANK]; /* Temporary dimension info */ + hbool_t found_nonidentical_dim = FALSE; + unsigned curr_dim; + + /* Copy current diminfo.opt values */ + HDmemcpy(tmp_diminfo, space->select.sel_info.hslab->diminfo.opt, sizeof(tmp_diminfo)); + + /* Loop over dimensions */ + for(curr_dim = 0; curr_dim < space->extent.rank; curr_dim++) { + /* Check for this being identical */ + if((tmp_diminfo[curr_dim].start != new_hyper_diminfo[curr_dim].start) + || (tmp_diminfo[curr_dim].stride != new_hyper_diminfo[curr_dim].stride) + || (tmp_diminfo[curr_dim].count != new_hyper_diminfo[curr_dim].count) + || (tmp_diminfo[curr_dim].block != new_hyper_diminfo[curr_dim].block)) { + hsize_t high_start, high_count, high_block; /* The start, count & block values for the higher block */ + + /* Dimension is not identical */ + /* Check if we already found a nonidentical dim - only one is + * allowed */ + if(found_nonidentical_dim) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Assign the initial starting point & block size */ - curr_start = span->low; - curr_block = (span->high - span->low) + 1; + /* Check that strides are the same, or count is 1 for one of the + * slabs */ + if((tmp_diminfo[curr_dim].stride != new_hyper_diminfo[curr_dim].stride) + && (tmp_diminfo[curr_dim].count > 1) + && (new_hyper_diminfo[curr_dim].count > 1)) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Loop the spans */ - while(span) { - if(outcount > 0) { - hsize_t next_stride; /* Stride from previous span */ - hsize_t next_block; /* Block size of current span */ + /* Patch tmp_diminfo.stride if its count is 1 */ + if((tmp_diminfo[curr_dim].count == 1) + && (new_hyper_diminfo[curr_dim].count > 1)) + tmp_diminfo[curr_dim].stride = new_hyper_diminfo[curr_dim].stride; - /* Check that down spans match current slab info */ - /* (Can skip check if previous span's down pointer is same as current one) */ - if(span->down && (NULL == prev_span || prev_span->down != span->down)) { - H5S_hyper_dim_t *curr_down_span_slab_info; - unsigned u; /* Local index variable */ + /* Determine lowest start, and set tmp_diminfo.start, count and + * block to use the lowest, and high_start, high_count and + * high_block to use the highest + */ + if(tmp_diminfo[curr_dim].start < new_hyper_diminfo[curr_dim].start) { + high_start = new_hyper_diminfo[curr_dim].start; + high_count = new_hyper_diminfo[curr_dim].count; + high_block = new_hyper_diminfo[curr_dim].block; + } /* end if */ + else { + high_start = tmp_diminfo[curr_dim].start; + tmp_diminfo[curr_dim].start = new_hyper_diminfo[curr_dim].start; + high_count = tmp_diminfo[curr_dim].count; + tmp_diminfo[curr_dim].count = new_hyper_diminfo[curr_dim].count; + high_block = tmp_diminfo[curr_dim].block; + tmp_diminfo[curr_dim].block = new_hyper_diminfo[curr_dim].block; + } /* end else */ - HDassert(span->down->head); + /* If count is 1 for both slabs, take different actions */ + if((tmp_diminfo[curr_dim].count == 1) && (high_count == 1)) { + /* Check for overlap */ + if((tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block) + > high_start) { + /* Check operation type */ + if(op == H5S_SELECT_OR) + /* Merge blocks */ + tmp_diminfo[curr_dim].block = ((high_start + high_block) + >= (tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block)) + ? (high_start + high_block - tmp_diminfo[curr_dim].start) + : tmp_diminfo[curr_dim].block; + else { + /* Block values must be the same */ + if(tmp_diminfo[curr_dim].block != high_block) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Go to the next down span and check whether the selection can be rebuilt.*/ - if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) - HGOTO_DONE(FALSE) + /* XOR - overlap creates 2 blocks */ + tmp_diminfo[curr_dim].stride = high_block; + tmp_diminfo[curr_dim].count = 2; + tmp_diminfo[curr_dim].block = high_start - tmp_diminfo[curr_dim].start; + } /* end else */ + } /* end if */ + else if((tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block) + == high_start) + /* Blocks border, merge them */ + tmp_diminfo[curr_dim].block += high_block; + else { + /* Distinct blocks */ + /* Block values must be the same */ + if(tmp_diminfo[curr_dim].block != high_block) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Compare the slab information of the adjacent spans in the down span tree. - We have to compare all the sub-tree slab information with the canon_down_span_slab_info.*/ - for(u = 0; u < rank - 1; u++) { - curr_down_span_slab_info = &span_slab_info[u]; - - if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[u].count > 0) { - if(curr_down_span_slab_info->start != canon_down_span_slab_info[u].start - || curr_down_span_slab_info->stride != canon_down_span_slab_info[u].stride - || curr_down_span_slab_info->block != canon_down_span_slab_info[u].block - || curr_down_span_slab_info->count != canon_down_span_slab_info[u].count) - HGOTO_DONE(FALSE) - } /* end if */ - else if(!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0))) - HGOTO_DONE(FALSE) - } /* end for */ + /* Create strided selection */ + tmp_diminfo[curr_dim].stride = high_start - tmp_diminfo[curr_dim].start; + tmp_diminfo[curr_dim].count = 2; + } /* end else */ } /* end if */ + else { + /* Check if block values are the same */ + if(tmp_diminfo[curr_dim].block != new_hyper_diminfo[curr_dim].block) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Obtain values for stride and block */ - next_stride = span->low - curr_low; - next_block = (span->high - span->low) + 1; - - /* Compare stride and block in this span, to compare stride, - * three spans are needed. Account for the first two spans. - */ - if(next_block != curr_block) - HGOTO_DONE(FALSE) - if(outcount > 1 && curr_stride != next_stride) - HGOTO_DONE(FALSE) + /* Check phase of strides */ + if((tmp_diminfo[curr_dim].start % tmp_diminfo[curr_dim].stride) + != (new_hyper_diminfo[curr_dim].start % tmp_diminfo[curr_dim].stride)) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Keep the isolated stride to be 1 */ - curr_stride = next_stride; - } /* end if */ + /* Check operation type */ + if(op == H5S_SELECT_OR) { + /* Make sure the slabs border or overlap */ + if(high_start > (tmp_diminfo[curr_dim].start + + (tmp_diminfo[curr_dim].count + * tmp_diminfo[curr_dim].stride))) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ + } /* end if */ + else + /* XOR: Make sure the slabs border */ + if(high_start != (tmp_diminfo[curr_dim].start + + (tmp_diminfo[curr_dim].count + * tmp_diminfo[curr_dim].stride))) { + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + break; + } /* end if */ - /* Keep current starting point */ - curr_low = span->low; + /* Set count for combined selection */ + tmp_diminfo[curr_dim].count = ((high_start + - tmp_diminfo[curr_dim].start) + / tmp_diminfo[curr_dim].stride) + high_count; + } /* end else */ - /* Advance to next span */ - prev_span = span; - span = span->next; - outcount++; - } /* end while */ + /* Indicate that we found a nonidentical dim */ + found_nonidentical_dim = TRUE; + } /* end if */ + } /* end for */ - /* Save the span information. */ - span_slab_info[rank - 1].start = curr_start; - span_slab_info[rank - 1].count = outcount; - span_slab_info[rank - 1].block = curr_block; - span_slab_info[rank - 1].stride = curr_stride; - } /* end if */ + /* Check if we succeeded, if so, set the new diminfo values */ + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) + for(curr_dim = 0; curr_dim < space->extent.rank; curr_dim++) { + hsize_t tmp_high_bound; + + /* Set the new diminfo values */ + space->select.sel_info.hslab->diminfo.app[curr_dim].start = space->select.sel_info.hslab->diminfo.opt[curr_dim].start = tmp_diminfo[curr_dim].start; + HDassert(tmp_diminfo[curr_dim].stride > 0); + space->select.sel_info.hslab->diminfo.app[curr_dim].stride = space->select.sel_info.hslab->diminfo.opt[curr_dim].stride = tmp_diminfo[curr_dim].stride; + HDassert(tmp_diminfo[curr_dim].count > 0); + space->select.sel_info.hslab->diminfo.app[curr_dim].count = space->select.sel_info.hslab->diminfo.opt[curr_dim].count = tmp_diminfo[curr_dim].count; + HDassert(tmp_diminfo[curr_dim].block > 0); + space->select.sel_info.hslab->diminfo.app[curr_dim].block = space->select.sel_info.hslab->diminfo.opt[curr_dim].block = tmp_diminfo[curr_dim].block; + + /* Check for updating the low & high bounds */ + if(tmp_diminfo[curr_dim].start < space->select.sel_info.hslab->diminfo.low_bounds[curr_dim]) + space->select.sel_info.hslab->diminfo.low_bounds[curr_dim] = tmp_diminfo[curr_dim].start; + tmp_high_bound = tmp_diminfo[curr_dim].start + + (tmp_diminfo[curr_dim].block - 1) + + (tmp_diminfo[curr_dim].stride * (tmp_diminfo[curr_dim].count - 1)); + if(tmp_high_bound > space->select.sel_info.hslab->diminfo.low_bounds[curr_dim]) + space->select.sel_info.hslab->diminfo.high_bounds[curr_dim] = tmp_high_bound; + } /* end for */ + } /* end else */ -done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_rebuild_helper() */ +} /* end H5S__hyper_update_diminfo() */ /*-------------------------------------------------------------------------- NAME - H5S__hyper_rebuild + H5S__hyper_rebuild_helper PURPOSE - Rebuild optimized hyperslab information if possible. + Helper routine to rebuild optimized hyperslab information if possible. (It can be recovered with regular selection) USAGE - hbool_t H5S__hyper_rebuild(space) - const H5S_t *space; IN: Dataspace to check + herr_t H5S__hyper_rebuild_helper(space) + const H5S_hyper_span_t *span; IN: Portion of span tree to check + H5S_hyper_dim_t span_slab[]; OUT: Rebuilt section of hyperslab description + unsigned rank; IN: Current dimension to work on + uint64_t op_gen; IN: Operation generation RETURNS TRUE/FALSE for hyperslab selection rebuilt DESCRIPTION @@ -7354,52 +8336,141 @@ done: to span tree able to be generated from a single H5S_SELECT_SET operation. EXAMPLES REVISION LOG - This routine is the optimization of the old version. The previous version - can only detect a singluar selection. This version is general enough to - detect any regular selection. KY, 2005/9/22 --------------------------------------------------------------------------*/ static hbool_t -H5S__hyper_rebuild(H5S_t *space) +H5S__hyper_rebuild_helper(const H5S_hyper_span_info_t *spans, H5S_hyper_dim_t span_slab_info[]) { - H5S_hyper_dim_t top_span_slab_info[H5S_MAX_RANK]; - unsigned rank, curr_dim; - hbool_t ret_value = TRUE; /* Return value */ + const H5S_hyper_span_t *span; /* Hyperslab span */ + const H5S_hyper_span_t *prev_span; /* Previous span in list */ + hsize_t start; /* Starting element for this dimension */ + hsize_t stride; /* Stride for this dimension */ + hsize_t block; /* Block size for this dimension */ + hsize_t prev_low; /* Low bound for previous span */ + size_t spancount; /* Number of spans encountered in this dimension */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC_NOERR - /* Check args */ - HDassert(space); - HDassert(space->select.sel_info.hslab->span_lst); + /* Sanity check */ + HDassert(spans); - /* Check the rank of space */ - rank = space->extent.rank; + /* Initialization */ + span = spans->head; + stride = 1; + prev_low = 0; + spancount = 0; - /* Check whether the slab can be rebuilt. Only regular selection can be rebuilt. If yes, fill in correct values.*/ - if(!H5S__hyper_rebuild_helper(space->select.sel_info.hslab->span_lst->head, top_span_slab_info, rank)) { - HGOTO_DONE(FALSE) - } /* end if */ - else { - H5S_hyper_dim_t *diminfo; - H5S_hyper_dim_t *app_diminfo; + /* Get "canonical" down span information */ + if(span->down) + /* Go to the next down span and check whether the selection can be rebuilt */ + if(!H5S__hyper_rebuild_helper(span->down, &span_slab_info[1])) + HGOTO_DONE(FALSE) - diminfo = space->select.sel_info.hslab->opt_diminfo; - app_diminfo = space->select.sel_info.hslab->app_diminfo; + /* Assign the initial starting point & block size for this dimension */ + start = span->low; + block = (span->high - span->low) + 1; - for(curr_dim = 0; curr_dim < rank; curr_dim++) { + /* Loop the spans */ + prev_span = NULL; + while(span) { + if(spancount > 0) { + hsize_t curr_stride; /* Current stride from previous span */ + hsize_t curr_block; /* Block size of current span */ - app_diminfo[(rank - curr_dim) - 1].start = diminfo[(rank - curr_dim) - 1].start = top_span_slab_info[curr_dim].start; - app_diminfo[(rank - curr_dim) - 1].stride = diminfo[(rank - curr_dim) - 1].stride = top_span_slab_info[curr_dim].stride; - app_diminfo[(rank - curr_dim) - 1].count = diminfo[(rank - curr_dim) - 1].count = top_span_slab_info[curr_dim].count; - app_diminfo[(rank - curr_dim) - 1].block = diminfo[(rank - curr_dim) - 1].block = top_span_slab_info[curr_dim].block; + /* Sanity check */ + HDassert(prev_span); - } /* end for */ + /* Check that down spans match current slab info */ + /* (Can skip check if previous span's down pointer is same as current one) */ + if(span->down && prev_span->down != span->down) + if(!H5S__hyper_cmp_spans(span->down, prev_span->down)) + HGOTO_DONE(FALSE) - space->select.sel_info.hslab->diminfo_valid = TRUE; - } /* end else */ + /* Obtain values for stride and block */ + curr_stride = span->low - prev_low; + curr_block = (span->high - span->low) + 1; + + /* Compare stride and block for this span. To compare stride, + * three spans are needed. Account for the first two spans. + */ + if(curr_block != block) + HGOTO_DONE(FALSE) + if(spancount > 1) { + if(stride != curr_stride) + HGOTO_DONE(FALSE) + } /* end if */ + else + stride = curr_stride; + } /* end if */ + + /* Keep current starting point */ + prev_low = span->low; + + /* Advance to next span */ + prev_span = span; + span = span->next; + spancount++; + } /* end while */ + + /* Save the span information. */ + span_slab_info[0].start = start; + span_slab_info[0].count = spancount; + span_slab_info[0].block = block; + span_slab_info[0].stride = stride; done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__hyper_rebuild_helper() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__hyper_rebuild + PURPOSE + Rebuild optimized hyperslab information if possible. + (It can be recovered with regular selection) + USAGE + void H5S__hyper_rebuild(space) + H5S_t *space; IN: Dataspace to check + RETURNS + None + DESCRIPTION + Examine the span tree for a hyperslab selection and rebuild a regular + start/stride/count/block hyperslab selection, if possible. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + To be able to recover the optimized information, the span tree must conform + to span tree able to be generated from a single H5S_SELECT_SET operation. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +void +H5S__hyper_rebuild(H5S_t *space) +{ + H5S_hyper_dim_t rebuilt_slab_info[H5S_MAX_RANK]; + + FUNC_ENTER_PACKAGE_NOERR + + /* Check args */ + HDassert(space); + HDassert(space->select.sel_info.hslab->span_lst); + + /* Check whether the slab can be rebuilt */ + /* (Only regular selection can be rebuilt. If yes, fill in correct values) */ + if(FALSE == H5S__hyper_rebuild_helper(space->select.sel_info.hslab->span_lst, rebuilt_slab_info)) + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_IMPOSSIBLE; + else { + /* Set the dimension info & bounds for the dataspace, from the rebuilt info */ + HDmemcpy(space->select.sel_info.hslab->diminfo.app, rebuilt_slab_info, sizeof(rebuilt_slab_info)); + HDmemcpy(space->select.sel_info.hslab->diminfo.opt, rebuilt_slab_info, sizeof(rebuilt_slab_info)); + HDmemcpy(space->select.sel_info.hslab->diminfo.low_bounds, space->select.sel_info.hslab->span_lst->low_bounds, sizeof(hsize_t) * space->extent.rank); + HDmemcpy(space->select.sel_info.hslab->diminfo.high_bounds, space->select.sel_info.hslab->span_lst->high_bounds, sizeof(hsize_t) * space->extent.rank); + + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES; + } /* end else */ + + FUNC_LEAVE_NOAPI_VOID } /* end H5S__hyper_rebuild() */ @@ -7442,15 +8513,15 @@ H5S__hyper_generate_spans(H5S_t *space) /* These should be able to be converted to assertions once everything * that calls this function checks for unlimited selections first * (especially the new hyperslab API) -NAF */ - if(space->select.sel_info.hslab->opt_diminfo[u].count == H5S_UNLIMITED) + if(space->select.sel_info.hslab->diminfo.opt[u].count == H5S_UNLIMITED) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited count") - if(space->select.sel_info.hslab->opt_diminfo[u].block == H5S_UNLIMITED) + if(space->select.sel_info.hslab->diminfo.opt[u].block == H5S_UNLIMITED) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't generate spans with unlimited block") - tmp_start[u]=space->select.sel_info.hslab->opt_diminfo[u].start; - tmp_stride[u]=space->select.sel_info.hslab->opt_diminfo[u].stride; - tmp_count[u]=space->select.sel_info.hslab->opt_diminfo[u].count; - tmp_block[u]=space->select.sel_info.hslab->opt_diminfo[u].block; + tmp_start[u] = space->select.sel_info.hslab->diminfo.opt[u].start; + tmp_stride[u] = space->select.sel_info.hslab->diminfo.opt[u].stride; + tmp_count[u] = space->select.sel_info.hslab->diminfo.opt[u].count; + tmp_block[u] = space->select.sel_info.hslab->diminfo.opt[u].block; } /* end for */ /* Build the hyperslab information also */ @@ -7462,6 +8533,386 @@ done: } /* end H5S__hyper_generate_spans() */ +/*-------------------------------------------------------------------------- + NAME + H5S__check_spans_overlap + PURPOSE + Check if two selections' bounds overlap. + USAGE + hbool_t H5S__check_spans_overlap(spans1, spans2) + const H5S_hyper_span_info_t *spans1; IN: Second span list + const H5S_hyper_span_info_t *spans2; IN: Second span list + RETURNS + TRUE for overlap, FALSE for no overlap + PROGRAMMER + Quincey Koziol - January 24, 2019 + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static H5_ATTR_PURE hbool_t +H5S__check_spans_overlap(const H5S_hyper_span_info_t *spans1, + const H5S_hyper_span_info_t *spans2) +{ + hbool_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(spans1); + HDassert(spans2); + + /* Use low & high bounds to try to avoid spinning through the span lists */ + if(H5S_RANGE_OVERLAP(spans1->low_bounds[0], spans1->high_bounds[0], + spans2->low_bounds[0], spans2->high_bounds[0])) { + H5S_hyper_span_t *span1, *span2; /* Hyperslab spans */ + + /* Walk over spans, comparing them for overlap */ + span1 = spans1->head; + span2 = spans2->head; + while(span1 && span2) { + /* Check current two spans for overlap */ + if(H5S_RANGE_OVERLAP(span1->low, span1->high, span2->low, span2->high)) { + /* Check for spans in lowest dimension already */ + if(span1->down) { + /* Sanity check */ + HDassert(span2->down); + + /* Check lower dimensions for overlap */ + if(H5S__check_spans_overlap(span1->down, span2->down)) + HGOTO_DONE(TRUE); + } /* end if */ + else + HGOTO_DONE(TRUE); + } /* end if */ + + /* Advance one of the spans */ + if(span1->high <= span2->high) { + /* Advance span1, unless it would be off the list and span2 has more nodes */ + if(NULL == span1->next && NULL != span2->next) + span2 = span2->next; + else + span1 = span1->next; + } /* end if */ + else { + /* Advance span2, unless it would be off the list and span1 has more nodes */ + if(NULL == span2->next && NULL != span1->next) + span1 = span1->next; + else + span2 = span2->next; + } /* end else */ + } /* end while */ + + /* Make certain we've exhausted our comparisons */ + HDassert((NULL == span1 && (NULL != span2 && NULL == span2->next)) || + ((NULL != span1 && NULL == span1->next) && NULL == span2)); + } /* end of */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__check_spans_overlap() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__fill_in_new_space + PURPOSE + Combine two span lists, one from an existing dataspace and the + other from input arguments, into a new selection depending on the + selection operator. The new selection is put into a resulting dataspace + which could be allocated inside the function. + USAGE + herr_t H5S__fill_in_new_space(space1, op, space2_span_lst, can_own_span2, + span2_owned, result) + H5S_t *space1; IN: Dataspace containing the first span list + H5S_seloper_t op; IN: Selection operation + H5S_hyper_span_info_t *space2_span_lst; IN: Second span list + hbool_t can_own_span2; IN: Indicates whether the 2nd span list could be + owned by the result. If not, the 2nd span list + has to be copied. + hbool_t *span2_owned; OUT: Indicates if the 2nd span list is actually owned + H5S_t **result; OUT: The dataspace containing the the new selection. It + could be same with the 1st dataspace. + RETURNS + Non-negative on success, negative on failure + PROGRAMMER + Chao Mei July 8, 2011 + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__fill_in_new_space(H5S_t *space1, H5S_seloper_t op, + H5S_hyper_span_info_t *space2_span_lst, hbool_t can_own_span2, + hbool_t *span2_owned, hbool_t *updated_spans, H5S_t **result) +{ + H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ + H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ + H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ + hbool_t overlapped = FALSE; /* Whether selections overlap */ + hbool_t is_result_new = FALSE; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(space1); + HDassert(space2_span_lst); + HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA); + /* The result is either a to-be-created space or an empty one */ + HDassert(*result == NULL || *result == space1); + HDassert(space1->select.sel_info.hslab->span_lst); + HDassert(span2_owned); + + /* Reset flags to return */ + *span2_owned = FALSE; + *updated_spans = FALSE; + + /* The result shares the same info from space1 */ + if(*result == NULL) { + if(NULL == ((*result) = H5S_copy(space1, TRUE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace") + space1->select.sel_info.hslab->span_lst->count--; + (*result)->select.sel_info.hslab->span_lst = NULL; + is_result_new = TRUE; + } /* end if */ + + /* Check both spaces to see if they overlap */ + overlapped = H5S__check_spans_overlap(space1->select.sel_info.hslab->span_lst, space2_span_lst); + + if(!overlapped) { + switch(op) { + case H5S_SELECT_OR: + case H5S_SELECT_XOR: + /* Add the new disjoint spans to the space */ + /* Copy of space1's spans to *result, and another copy of space2's spans */ + if(is_result_new) + (*result)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(space1->select.sel_info.hslab->span_lst, space1->extent.rank); + if(!can_own_span2) { + b_not_a = H5S__hyper_copy_span(space2_span_lst, space1->extent.rank); + if(H5S__hyper_add_disjoint_spans(*result, b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs") + + /* The new_spans are now owned by 'space', so they should not be released */ + b_not_a = NULL; + } /* end if */ + else { + if(H5S__hyper_add_disjoint_spans(*result, space2_span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs") + *span2_owned = TRUE; + } /* end else */ + + /* Indicate that the spans changed */ + *updated_spans = TRUE; + break; + + case H5S_SELECT_AND: + /* Convert *result to "none" selection */ + if(H5S_select_none(*result) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + HGOTO_DONE(SUCCEED); + + case H5S_SELECT_NOTB: + /* Copy space1's spans to *result */ + if(is_result_new) + (*result)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(space1->select.sel_info.hslab->span_lst, space1->extent.rank); + + /* Indicate that the spans changed */ + *updated_spans = TRUE; + break; + + case H5S_SELECT_NOTA: + if(!is_result_new) { + HDassert(space1 == *result); + + /* Free the current selection */ + H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst); + space1->select.sel_info.hslab->span_lst = NULL; + } /* end if */ + + /* Copy space2's spans to *result */ + if(!can_own_span2) + (*result)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(space2_span_lst, space1->extent.rank); + else { + (*result)->select.sel_info.hslab->span_lst = space2_span_lst; + *span2_owned = TRUE; + } /* end else */ + + /* Reset the number of items in selection */ + (*result)->select.num_elem = H5S__hyper_spans_nelem(space2_span_lst); + + /* Indicate that the spans changed */ + *updated_spans = TRUE; + break; + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + } /* end if */ + else { + unsigned selector = 0; /* Select which clipping spans to generate */ + + /* Generate mask for clip operation depending on the op */ + switch(op) { + case H5S_SELECT_OR: /* a + b_not_a */ + selector = H5S_HYPER_COMPUTE_B_NOT_A; + break; + + case H5S_SELECT_XOR: /* a_not_b + b_not_a */ + selector = H5S_HYPER_COMPUTE_A_NOT_B | H5S_HYPER_COMPUTE_B_NOT_A; + break; + + case H5S_SELECT_AND: /* a_and_b */ + selector = H5S_HYPER_COMPUTE_A_AND_B; + break; + + case H5S_SELECT_NOTB: /* a_not_b */ + selector = H5S_HYPER_COMPUTE_A_NOT_B; + break; + + case H5S_SELECT_NOTA: /* b_not_a */ + selector = H5S_HYPER_COMPUTE_B_NOT_A; + break; + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + + /* Generate lists of spans which overlap and don't overlap */ + if(H5S__hyper_clip_spans(space1->select.sel_info.hslab->span_lst, + space2_span_lst, selector, space1->extent.rank, + &a_not_b, &a_and_b, &b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") + switch(op) { + case H5S_SELECT_OR: + if(is_result_new) + (*result)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(space1->select.sel_info.hslab->span_lst, space1->extent.rank); + break; + + case H5S_SELECT_AND: + case H5S_SELECT_XOR: + case H5S_SELECT_NOTB: + case H5S_SELECT_NOTA: + if(!is_result_new) { + HDassert(space1 == *result); + + /* Free the current selection */ + H5S__hyper_free_span_info(space1->select.sel_info.hslab->span_lst); + space1->select.sel_info.hslab->span_lst = NULL; + } /* end if */ + + /* Reset the number of items in selection */ + /* (Will be set below) */ + (*result)->select.num_elem = 0; + break; + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + + /* Check if there are any non-overlapped selections */ + if(a_not_b) { + /* Other than OR, the span_lst is set to NULL. And in OR, + * a_not_b is not needed + */ + HDassert(NULL == (*result)->select.sel_info.hslab->span_lst); + + /* The results dataspace takes ownership of the spans */ + /* (Since it must be NULL) */ + (*result)->select.sel_info.hslab->span_lst = a_not_b; + + /* Update the number of elements in current selection */ + (*result)->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + + /* Indicate that the spans were updated */ + *updated_spans = TRUE; + + /* Indicate that the a_not_b spans are owned */ + a_not_b = NULL; + } /* end if */ + + if(a_and_b) { + /** + * 1. Other than OR, the span_lst is set to NULL. And in OR, + * a_and_b is not needed + * 2. a_not_b will never be computed together with a_and_b + * because merging these two equals to a. + */ + HDassert(NULL == (*result)->select.sel_info.hslab->span_lst); + + /* The results dataspace takes ownership of the spans */ + /* (Since it must be NULL) */ + (*result)->select.sel_info.hslab->span_lst = a_and_b; + + /* Update the number of elements in current selection */ + (*result)->select.num_elem = H5S__hyper_spans_nelem(a_and_b); + + /* Indicate that the spans were updated */ + *updated_spans = TRUE; + + /* Indicate that the a_and_b spans are owned */ + a_and_b = NULL; + } /* end if */ + + if(b_not_a) { + /* Merge the b_not_a spans into the result dataspace */ + if(H5S__hyper_merge_spans(*result, b_not_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + + /* Update the number of elements in current selection */ + (*result)->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + + /* Indicate that the spans were updated */ + *updated_spans = TRUE; + } /* end if */ + } /* end else for the case the new span overlaps with the old (i.e. space) */ + + /* Check if the spans weren't updated, and reset selection if so */ + if(!*updated_spans) { + /* If updated_spans remains FALSE as in this branch, it means the + * result has been cleared in XOR / AND / NOTB / NOTA cases, and the + * result is a copy of the dataspace in the OR case. + * + * If two dataspaces have generated any of the three clipped + * span trees (i.e. a_not_b, a_and_b, and b_not_a), the + * updated_spans must be TRUE. + */ + if(H5S_SELECT_OR != op) { + /* Convert *result to "none" selection */ + if(H5S_select_none(*result) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + } /* end else */ + } /* end if */ + +done: + /* Free resources */ + if(a_not_b) + H5S__hyper_free_span_info(a_not_b); + if(a_and_b) + H5S__hyper_free_span_info(a_and_b); + if(b_not_a) + H5S__hyper_free_span_info(b_not_a); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__fill_in_new_space() */ + + /*------------------------------------------------------------------------- * Function: H5S__generate_hyperlab * @@ -7478,10 +8929,7 @@ static herr_t H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]) { - H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ - H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ - H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ - H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ + H5S_hyper_span_info_t *new_spans = NULL; /* Span tree for new hyperslab */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -7499,10 +8947,13 @@ H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information") /* Generate list of blocks to add/remove based on selection operation */ - if(op==H5S_SELECT_SET) { - /* Add new spans to current selection */ - if(H5S__hyper_merge_spans(space,new_spans,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + if(op == H5S_SELECT_SET) { + /* Free current selection */ + if(NULL != space->select.sel_info.hslab->span_lst) + H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst); + + /* Set the hyperslab selection to the new span tree */ + space->select.sel_info.hslab->span_lst = new_spans; /* Set the number of elements in current selection */ space->select.num_elem = H5S__hyper_spans_nelem(new_spans); @@ -7511,194 +8962,375 @@ H5S__generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], new_spans = NULL; } /* end if */ else { - hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */ + hbool_t new_spans_owned = FALSE; + hbool_t updated_spans = FALSE; - /* Generate lists of spans which overlap and don't overlap */ - if(H5S__hyper_clip_spans(space->select.sel_info.hslab->span_lst,new_spans,&a_not_b,&a_and_b,&b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") + /* Generate new spans for space */ + if(H5S__fill_in_new_space(space, op, new_spans, TRUE, &new_spans_owned, &updated_spans, &space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't generate the specified hyperslab") - switch(op) { - case H5S_SELECT_OR: - /* Add any new spans from b_not_a to current selection */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Check if the spans were updated by H5S__fill_in_new_space */ + if(updated_spans) { + H5S_hyper_dim_t new_hyper_diminfo[H5S_MAX_RANK]; + unsigned u; /* Local index variable */ - /* Update the number of elements in current selection */ - space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + /* Sanity check */ + HDassert(space->select.sel_info.hslab->span_lst->head); + + /* Build diminfo struct */ + for(u = 0; u extent.rank; u++) { + new_hyper_diminfo[u].start = start[u]; + new_hyper_diminfo[u].stride = stride[u]; + new_hyper_diminfo[u].count = count[u]; + new_hyper_diminfo[u].block = block[u]; + } /* end for */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Update space's dim info */ + if(H5S__hyper_update_diminfo(space, op, new_hyper_diminfo) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info") + } /* end if */ - case H5S_SELECT_AND: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Indicate that the new_spans are owned, there's no need to free */ + if(new_spans_owned) + new_spans = NULL; + } /* end else */ - /* Reset the number of items in selection */ - space->select.num_elem=0; +done: + if(new_spans) + H5S__hyper_free_span_info(new_spans); - /* Check if there are any overlapped selections */ - if(a_and_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_and_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__generate_hyperslab() */ - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_and_b); + +/*------------------------------------------------------------------------- + * Function: H5S__set_regular_hyperslab + * + * Purpose: Set a regular hyperslab + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, October 2, 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5S__set_regular_hyperslab(H5S_t *space, const hsize_t start[], + const hsize_t *app_stride, const hsize_t app_count[], const hsize_t *app_block, + const hsize_t *opt_stride, const hsize_t opt_count[], const hsize_t *opt_block) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Indicate that the a_and_b spans are owned */ - a_and_b=NULL; + FUNC_ENTER_STATIC - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Check args */ + HDassert(space); + HDassert(start); + HDassert(app_stride); + HDassert(app_count); + HDassert(app_block); + HDassert(opt_stride); + HDassert(opt_count); + HDassert(opt_block); + + /* If we are setting a new selection, remove current selection first */ + if(H5S_SELECT_RELEASE(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") - case H5S_SELECT_XOR: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Allocate space for the hyperslab selection information */ + if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info") - /* Reset the number of items in selection */ - space->select.num_elem=0; + /* Set the diminfo */ + space->select.num_elem = 1; + space->select.sel_info.hslab->unlim_dim = -1; + for(u = 0; u < space->extent.rank; u++) { + /* Set application and optimized hyperslab info */ + space->select.sel_info.hslab->diminfo.app[u].start = start[u]; + space->select.sel_info.hslab->diminfo.app[u].stride = app_stride[u]; + space->select.sel_info.hslab->diminfo.app[u].count = app_count[u]; + space->select.sel_info.hslab->diminfo.app[u].block = app_block[u]; + + space->select.sel_info.hslab->diminfo.opt[u].start = start[u]; + space->select.sel_info.hslab->diminfo.opt[u].stride = opt_stride[u]; + space->select.sel_info.hslab->diminfo.opt[u].count = opt_count[u]; + space->select.sel_info.hslab->diminfo.opt[u].block = opt_block[u]; + + /* Update # of elements selected */ + space->select.num_elem *= (opt_count[u] * opt_block[u]); + + /* Set low bound of bounding box for the hyperslab selection */ + space->select.sel_info.hslab->diminfo.low_bounds[u] = start[u]; + + /* Check for unlimited dimension & set high bound */ + if((app_count[u] == H5S_UNLIMITED) || (app_block[u] == H5S_UNLIMITED)) { + space->select.sel_info.hslab->unlim_dim = (int)u; + space->select.sel_info.hslab->diminfo.high_bounds[u] = H5S_UNLIMITED; + } /* end if */ + else + space->select.sel_info.hslab->diminfo.high_bounds[u] = start[u] + opt_stride[u] * (opt_count[u] - 1) + (opt_block[u] - 1); + } /* end for */ - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_not_b,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Handle unlimited selections */ + if(space->select.sel_info.hslab->unlim_dim >= 0) { + /* Calculate num_elem_non_unlim */ + space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; + for(u = 0; u < space->extent.rank; u++) + if((int)u != space->select.sel_info.hslab->unlim_dim) + space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + /* Update num_elem */ + space->select.num_elem = H5S_UNLIMITED; + } /* end if */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,FALSE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Indicate that the dimension information is valid */ + space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES; - /* Update the number of elements in current selection */ - space->select.num_elem += H5S__hyper_spans_nelem(b_not_a); + /* Indicate that there's no slab information */ + space->select.sel_info.hslab->span_lst = NULL; - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ - break; + /* Set selection type */ + space->select.type = H5S_sel_hyper; - case H5S_SELECT_NOTB: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__set_regular_hyperslab() */ - /* Reset the number of items in selection */ - space->select.num_elem=0; + +/*------------------------------------------------------------------------- + * Function: H5S__hyper_regular_and_single_block + * + * Purpose: Optimized routine to perform "AND" operation of a single + * block against a regular hyperslab selection. + * + * Note: This algorithm is invoked when constructing the chunk map + * and a regular hyperslab is selected in the file's dataspace. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, February 9, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__hyper_regular_and_single_block(H5S_t *space, const hsize_t start[], + const hsize_t block[]) +{ + hsize_t select_end, block_end; /* End of block & selection */ + hbool_t single_block; /* Whether the selection is a single block */ + hbool_t overlap; /* Whether block & selection overlap */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Check if there are any non-overlapped selections */ - if(a_not_b!=NULL) { - if(H5S__hyper_merge_spans(space,a_not_b,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + FUNC_ENTER_NOAPI(FAIL) - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(a_not_b); + /* Check args */ + HDassert(space); + HDassert(start); + HDassert(block); + + /* Check for single block selection in dataspace */ + single_block = TRUE; + for(u = 0; u < space->extent.rank; u++) + if(1 != space->select.sel_info.hslab->diminfo.opt[u].count) { + single_block = FALSE; + break; + } /* end if */ - /* Indicate that the a_not_b are owned */ - a_not_b=NULL; + /* Perform different optimizations, based on type of regular selection */ + if(single_block) { + hsize_t new_start[H5S_MAX_RANK]; /* New starting coordinate */ + hsize_t new_block[H5S_MAX_RANK]; /* New block size */ - /* Indicate that the spans were updated */ - updated_spans = TRUE; - } /* end if */ + /* Check for overlap and compute new start offset & block sizes */ + overlap = TRUE; + for(u = 0; u < space->extent.rank; u++) { + /* Compute the end of the selection & block in this dimension */ + select_end = space->select.sel_info.hslab->diminfo.high_bounds[u]; + block_end = (start[u] + block[u]) - 1; + + /* Check for overlap */ + if(!H5S_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], block_end)) { + overlap = FALSE; break; + } /* end if */ - case H5S_SELECT_NOTA: - /* Free the current selection */ - if(H5S__hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans") - space->select.sel_info.hslab->span_lst=NULL; + /* Set new start & block size in this dimension */ + new_start[u] = MAX(space->select.sel_info.hslab->diminfo.opt[u].start, start[u]); + new_block[u] = (MIN(select_end, block_end) - new_start[u]) + 1; + } /* end for */ - /* Reset the number of items in selection */ - space->select.num_elem=0; + /* Check for overlap of selection & block */ + if(overlap) { + /* Set selection to regular hyperslab */ + if(H5S__set_regular_hyperslab(space, new_start, H5S_hyper_ones_g, H5S_hyper_ones_g, new_block, + H5S_hyper_ones_g, H5S_hyper_ones_g, new_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't set regular hyperslab selection") + } /* end if */ + else + /* Selection & block don't overlap, set to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + } /* end if */ + else { + hsize_t new_start[H5S_MAX_RANK]; /* New start for hyperslab selection */ + hsize_t new_count[H5S_MAX_RANK]; /* New count for hyperslab selection */ + hsize_t stride[H5S_MAX_RANK]; /* Stride for hyperslab selection */ + hsize_t new_block[H5S_MAX_RANK]; /* New block for hyperslab selection */ + hbool_t partial_first_span; /* Whether first span in intersection is partial */ + hbool_t partial_last_span; /* Whether last span in intersection is partial */ + + /* Iterate over selection, checking for overlap and computing first / last + * span that intersects with the block. + */ + overlap = TRUE; + partial_first_span = FALSE; + partial_last_span = FALSE; + for(u = 0; u < space->extent.rank; u++) { + hsize_t first_span_start, first_span_end; /* Start / end of first span */ + hsize_t last_span_start, last_span_end; /* Start / end of last span */ + hsize_t nstride; /* Number of strides into the selection */ + + /* Compute the end of the selection & block in this dimension */ + select_end = space->select.sel_info.hslab->diminfo.high_bounds[u]; + block_end = (start[u] + block[u]) - 1; - /* Check if there are any non-overlapped selections */ - if(b_not_a!=NULL) { - if(H5S__hyper_merge_spans(space,b_not_a,TRUE)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs") + /* Check for overlap */ + if(!H5S_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], block_end)) { + overlap = FALSE; + break; + } /* end if */ - /* Update the number of elements in current selection */ - space->select.num_elem = H5S__hyper_spans_nelem(b_not_a); + /* Find first span that is before or overlaps with start of block */ + if(space->select.sel_info.hslab->diminfo.opt[u].start >= start[u]) { + /* Calculate start & end of first span */ + first_span_start = space->select.sel_info.hslab->diminfo.opt[u].start; + first_span_end = (first_span_start + + space->select.sel_info.hslab->diminfo.opt[u].block) - 1; - /* Indicate that the b_not_a are owned */ - b_not_a=NULL; + /* Check if first span overlaps _end_ of block */ + if(block_end >= first_span_start && block_end <= first_span_end) + partial_first_span = TRUE; + } /* end if */ + else { + hsize_t adj_start; /* Start coord, adjusted for hyperslab selection parameters */ + + /* Adjust start coord for selection's 'start' offset */ + adj_start = start[u] - space->select.sel_info.hslab->diminfo.opt[u].start; + + /* Compute # of strides into the selection */ + if(space->select.sel_info.hslab->diminfo.opt[u].count > 1) + nstride = adj_start / space->select.sel_info.hslab->diminfo.opt[u].stride; + else + nstride = 0; - /* Indicate that the spans were updated */ - updated_spans = TRUE; + /* Calculate start & end of first span */ + first_span_start = space->select.sel_info.hslab->diminfo.opt[u].start + + (nstride * space->select.sel_info.hslab->diminfo.opt[u].stride); + first_span_end = (first_span_start + + space->select.sel_info.hslab->diminfo.opt[u].block) - 1; + + /* Check if first span overlaps start of block */ + if(first_span_start < start[u] && first_span_end >= start[u]) + partial_first_span = TRUE; + + /* Advance first span to start higher than block's start, + * if it's not partial. + */ + if(first_span_end < start[u]) { + first_span_start += space->select.sel_info.hslab->diminfo.opt[u].stride; + first_span_end += space->select.sel_info.hslab->diminfo.opt[u].stride; } /* end if */ - break; + } /* end else */ - case H5S_SELECT_NOOP: - case H5S_SELECT_SET: - case H5S_SELECT_APPEND: - case H5S_SELECT_PREPEND: - case H5S_SELECT_INVALID: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ + /* Find last span that is before or overlaps with end of block */ + if(select_end < block_end) { + /* Calculate start & end of last span */ + last_span_start = (select_end - + space->select.sel_info.hslab->diminfo.opt[u].block) + 1; + last_span_end = select_end; + + /* Check if last span overlaps _start_ of block */ + if(start[u] >= last_span_start && start[u] <= last_span_end) + partial_last_span = TRUE; + } /* end if */ + else { + hsize_t adj_end; /* End coord, adjusted for hyperslab selection parameters */ + + /* Adjust end coord for selection's 'start' offset */ + adj_end = block_end - space->select.sel_info.hslab->diminfo.opt[u].start; + + /* Compute # of strides into the selection */ + if(space->select.sel_info.hslab->diminfo.opt[u].count > 1) + nstride = adj_end / space->select.sel_info.hslab->diminfo.opt[u].stride; + else + nstride = 0; + + /* Calculate start & end of last span */ + last_span_start = space->select.sel_info.hslab->diminfo.opt[u].start + + (nstride * space->select.sel_info.hslab->diminfo.opt[u].stride); + last_span_end = (last_span_start + + space->select.sel_info.hslab->diminfo.opt[u].block) - 1; - /* Check if the resulting hyperslab span tree is empty */ - if(space->select.sel_info.hslab->span_lst==NULL) { - H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + /* Check if last span overlaps end of block */ + if(block_end >= last_span_start && block_end <= last_span_end) + partial_last_span = TRUE; + } /* end else */ + + /* Check if no spans are inside block */ + /* (Can happen when block falls in "gap" between spans) */ + if(last_span_end < start[u]) { + overlap = FALSE; + break; + } /* end if */ /* Sanity check */ - HDassert(space->select.num_elem == 0); + HDassert(first_span_start <= last_span_start); - /* Allocate a span info node */ - if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span") + /* Compute new start / count / block values */ + new_start[u] = first_span_start; + if(last_span_start != first_span_start) + new_count[u] = ((last_span_start - first_span_start) / + space->select.sel_info.hslab->diminfo.opt[u].stride) + 1; + else + new_count[u] = 1; + new_block[u] = space->select.sel_info.hslab->diminfo.opt[u].block; - /* Set the reference count */ - spans->count=1; + /* Keep same stride */ + stride[u] = space->select.sel_info.hslab->diminfo.opt[u].stride; + } /* end for */ - /* Reset the scratch pad space */ - spans->scratch=0; + /* Check for overlap of selection & block */ + if(overlap) { + /* Set selection to regular hyperslab */ + if(H5S__set_regular_hyperslab(space, new_start, stride, new_count, new_block, + stride, new_count, new_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't set regular hyperslab selection") - /* Set to empty tree */ - spans->head=NULL; + /* If there's a partial first or last span, have to 'AND' against selection */ + if(partial_first_span || partial_last_span) { + /* Generate span tree for regular selection */ + if(H5S__hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - /* Set pointer to empty span tree */ - space->select.sel_info.hslab->span_lst=spans; + /* 'AND' against block */ + if(H5S__generate_hyperslab(space, H5S_SELECT_AND, start, H5S_hyper_ones_g, H5S_hyper_ones_g, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") + } /* end if */ } /* end if */ else { - /* Check if we updated the spans */ - if(updated_spans) { - /* Attempt to rebuild "optimized" start/stride/count/block information. - * from resulting hyperslab span tree - */ - H5S__hyper_rebuild(space); - } /* end if */ + /* Selection & block don't overlap, set to "none" selection */ + if(H5S_select_none(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") } /* end else */ } /* end else */ done: - /* Free resources */ - if(a_not_b) - if(H5S__hyper_free_span_info(a_not_b) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(a_and_b) - if(H5S__hyper_free_span_info(a_and_b) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(b_not_a) - if(H5S__hyper_free_span_info(b_not_a) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - if(new_spans) - if(H5S__hyper_free_span_info(new_spans) < 0) - HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__generate_hyperslab() */ +} /* end H5S__hyper_regular_and_single_block() */ /*------------------------------------------------------------------------- @@ -7923,70 +9555,27 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], case H5S_SEL_HYPERSLABS: /* Hyperslab operation on hyperslab selection, OK */ - break; - - case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */ - if(op == H5S_SELECT_SET) /* Allow only "set" operation to proceed */ - break; - /* Else fall through to error */ - - case H5S_SEL_ERROR: - case H5S_SEL_N: - default: - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") - } /* end switch */ - - if(op == H5S_SELECT_SET) { - /* If we are setting a new selection, remove current selection first */ - if(H5S_SELECT_RELEASE(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") - - /* Allocate space for the hyperslab selection information */ - if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") - - /* Save the diminfo */ - space->select.num_elem = 1; - for(u = 0; u < space->extent.rank; u++) { - space->select.sel_info.hslab->app_diminfo[u].start = start[u]; - space->select.sel_info.hslab->app_diminfo[u].stride = stride[u]; - space->select.sel_info.hslab->app_diminfo[u].count = count[u]; - space->select.sel_info.hslab->app_diminfo[u].block = block[u]; - - space->select.sel_info.hslab->opt_diminfo[u].start = start[u]; - space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u]; - space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u]; - space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u]; - - space->select.num_elem *= (opt_count[u] * opt_block[u]); - } /* end for */ - - /* Save unlim_dim */ - space->select.sel_info.hslab->unlim_dim = unlim_dim; - - /* Indicate that the dimension information is valid */ - space->select.sel_info.hslab->diminfo_valid = TRUE; - - /* Indicate that there's no slab information */ - space->select.sel_info.hslab->span_lst = NULL; - - /* Handle unlimited selections */ - if(unlim_dim >= 0) { - /* Calculate num_elem_non_unlim */ - space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; - for(u = 0; u < space->extent.rank; u++) - if((int)u != unlim_dim) - space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); + break; - /* Set num_elem */ - if(space->select.num_elem != (hsize_t)0) - space->select.num_elem = H5S_UNLIMITED; - } /* end if */ + case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */ + if(op == H5S_SELECT_SET) /* Allow only "set" operation to proceed */ + break; + /* Else fall through to error */ - /* Set selection type */ - space->select.type = H5S_sel_hyper; + case H5S_SEL_ERROR: + case H5S_SEL_N: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + + if(op == H5S_SELECT_SET) { + /* Set selection to regular hyperslab */ + if(H5S__set_regular_hyperslab(space, start, stride, count, block, opt_stride, opt_count, opt_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't set regular hyperslab selection") } /* end if */ else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) { + hbool_t single_block; /* Whether the selection is a single block */ + /* Sanity check */ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); @@ -8023,21 +9612,35 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], } /* end if */ } /* end if */ - /* Check if there's no hyperslab span information currently */ - if(NULL == space->select.sel_info.hslab->span_lst) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Check for a single block selected */ + single_block = TRUE; + for(u = 0; u < space->extent.rank; u++) + if(1 != opt_count[u]) { + single_block = FALSE; + break; + } /* end if */ - /* Indicate that the regular dimensions are no longer valid */ - space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Check for single block "AND" operation on a regular hyperslab, which + * is used for constructing chunk maps and can be optimized for. + */ + if(H5S_SELECT_AND == op && single_block && + space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + if(H5S__hyper_regular_and_single_block(space, start, opt_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTOPERATE, FAIL, "can't 'AND' single block against regular hyperslab") + } /* end if */ + else { + /* Check if there's no hyperslab span information currently */ + if(NULL == space->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - /* Set selection type */ - /* (Could be overridden by resetting selection to 'none', below) */ - space->select.type = H5S_sel_hyper; + /* Set selection type */ + space->select.type = H5S_sel_hyper; - /* Add in the new hyperslab information */ - if(H5S__generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") + /* Add in the new hyperslab information */ + if(H5S__generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") + } /* end else */ } /* end if */ else HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") @@ -8113,6 +9716,325 @@ done: /*-------------------------------------------------------------------------- NAME + H5S_combine_hyperslab + PURPOSE + Specify a hyperslab to combine with the current hyperslab selection, and + store the result in the new hyperslab selection. + USAGE + herr_t H5S_combine_hyperslab(new_space, old_space, op, start, stride, count, block) + H5S_t *old_space; IN: The old space the selection is performed on + H5S_seloper_t op; IN: Operation to perform on current selection + const hsize_t start[]; IN: Offset of start of hyperslab + const hsize_t *stride; IN: Hyperslab stride + const hsize_t count[]; IN: Number of blocks included in hyperslab + const hsize_t *block; IN: Size of block in hyperslab + H5S_t **new_space; OUT: The new dataspace to store the selection result + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Combines a hyperslab selection with the current selection for a dataspace. + If STRIDE or BLOCK is NULL, they are assumed to be set to all '1'. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + In some cases, copying the whole span tree from old_space to new_space + can be avoided. Deal with such cases directly, otherwise this function + is equivalent to: + 1. Copy the whole span tree from old_space into new_space + 2. Call H5S_select_hyperslab with the new_space. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_combine_hyperslab(H5S_t *old_space, H5S_seloper_t op, const hsize_t start[], + const hsize_t *stride, const hsize_t count[], const hsize_t *block, + H5S_t **new_space) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(old_space); + HDassert(start); + HDassert(count); + HDassert(op >= H5S_SELECT_SET && op <= H5S_SELECT_NOTA); + HDassert(new_space); + HDassert(*new_space == NULL); + + /* Point to the correct stride values */ + if(stride == NULL) + stride = H5S_hyper_ones_g; + + /* Point to the correct block values */ + if(block == NULL) + block = H5S_hyper_ones_g; + + /* Check new selection. */ + for(u = 0; u < old_space->extent.rank; u++) { + /* Check for overlapping hyperslab blocks in new selection. */ + if(count[u] > 1 && stride[u] < block[u]) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap") + + /* Detect zero-sized hyperslabs in new selection */ + if(count[u] == 0 || block[u] == 0) { + switch(op) { + case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */ + case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */ + /* Convert to "none" selection */ + /* Copy the first dataspace without sharing the list of spans */ + if(NULL == ((*new_space) = H5S_copy(old_space, TRUE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace") + if(H5S_select_none((*new_space)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + HGOTO_DONE(SUCCEED); + + case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */ + case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */ + case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */ + /* Copy the first dataspace with sharing the list of spans */ + if(NULL == ((*new_space) = H5S_copy(old_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace") + HGOTO_DONE(SUCCEED); /* Selection stays same */ + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + } /* end if */ + } /* end for */ + + if(H5S_GET_SELECT_TYPE(old_space) == H5S_SEL_HYPERSLABS) { + hsize_t *old_low_bounds; /* Pointer to old space's low & high bounds */ + hsize_t *old_high_bounds; + hsize_t new_low_bounds[H5S_MAX_RANK]; /* New space's low & high bounds */ + hsize_t new_high_bounds[H5S_MAX_RANK]; + hbool_t overlapped = FALSE; + + /* Set up old space's low & high bounds */ + if(old_space->select.sel_info.hslab->span_lst) { + old_low_bounds = old_space->select.sel_info.hslab->span_lst->low_bounds; + old_high_bounds = old_space->select.sel_info.hslab->span_lst->high_bounds; + } /* end if */ + else { + old_low_bounds = old_space->select.sel_info.hslab->diminfo.low_bounds; + old_high_bounds = old_space->select.sel_info.hslab->diminfo.high_bounds; + } /* end else */ + + /* Generate bounding box for hyperslab parameters */ + for(u = 0; u < old_space->extent.rank; u++) { + new_low_bounds[u] = start[u]; + new_high_bounds[u] = start[u] + stride[u] * (count[u] - 1) + (block[u] - 1); + } /* end for */ + + /* Check bound box of both spaces to see if they overlap */ + if(H5S_RANGE_OVERLAP(old_low_bounds[0], old_high_bounds[0], + new_low_bounds[0], new_high_bounds[0])) + overlapped = TRUE; + + /* Non-overlapping situations can be handled in special ways */ + if(!overlapped) { + H5S_hyper_span_info_t *new_spans = NULL; + H5S_hyper_dim_t new_hyper_diminfo[H5S_MAX_RANK]; + + if(NULL == ((*new_space) = H5S_copy(old_space, TRUE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") + if(NULL != (*new_space)->select.sel_info.hslab->span_lst) { + old_space->select.sel_info.hslab->span_lst->count--; + (*new_space)->select.sel_info.hslab->span_lst = NULL; + } /* end if */ + + /* Generate hyperslab info for new space */ + switch(op) { + case H5S_SELECT_OR: + case H5S_SELECT_XOR: + /* Add the new space to the space */ + if(NULL == (new_spans = H5S__hyper_make_spans(old_space->extent.rank, start, stride, count, block))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information") + if(NULL != old_space->select.sel_info.hslab->span_lst) + (*new_space)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(old_space->select.sel_info.hslab->span_lst, old_space->extent.rank); + if(H5S__hyper_add_disjoint_spans(*new_space, new_spans) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs") + + /* Build diminfo struct */ + for(u = 0; u < (*new_space)->extent.rank; u++) { + new_hyper_diminfo[u].start = start[u]; + new_hyper_diminfo[u].stride = stride[u]; + new_hyper_diminfo[u].count = count[u]; + new_hyper_diminfo[u].block = block[u]; + } /* end for */ + + /* Update space's dim info */ + if(H5S__hyper_update_diminfo(*new_space, op, new_hyper_diminfo) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info") + break; + + case H5S_SELECT_AND: + if(H5S_select_none((*new_space)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + break; + + case H5S_SELECT_NOTB: + if(NULL != old_space->select.sel_info.hslab->span_lst) { + if(NULL == ((*new_space)->select.sel_info.hslab->span_lst = H5S__hyper_copy_span(old_space->select.sel_info.hslab->span_lst, old_space->extent.rank))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy dataspace") + } /* end if */ + else { + if(H5S_select_none((*new_space)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") + } /* end else */ + break; + + case H5S_SELECT_NOTA: + if(H5S__set_regular_hyperslab(*new_space, start, stride, count, block, stride, count, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't set regular selection") + break; + + case H5S_SELECT_NOOP: + case H5S_SELECT_SET: + case H5S_SELECT_APPEND: + case H5S_SELECT_PREPEND: + case H5S_SELECT_INVALID: + default: + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + } /* end switch */ + + HGOTO_DONE(SUCCEED); + } /* end if(!overlapped) */ + } /* end if the selection of old space is H5S_SEL_HYPERSLABS */ + + /* Copy the first dataspace with sharing the list of spans */ + if(NULL == ((*new_space) = H5S_copy(old_space, TRUE, TRUE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace") + + /* Note: a little overhead in calling the function as some conditions are checked again */ + if(H5S_select_hyperslab(*new_space, op, start, stride, count, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_combine_hyperslab() */ + + +/*------------------------------------------------------------------------- + * Function: H5S__fill_in_select + * + * Purpose: Combines two hyperslabs with an operation, putting the + * result into a third hyperslab selection + * + * Return: Non-negative on success/negative on failure + * + * Programmer: Chao Mei + * Tuesday, July 5, 2011 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__fill_in_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2, H5S_t **result) +{ + hbool_t span2_owned; + hbool_t updated_spans; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(space1); + HDassert(space2); + HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA); + HDassert(space1->extent.rank == space2->extent.rank); + /* The result is either a to-be-created space or an empty one */ + HDassert(NULL == *result || *result == space1); + HDassert(space1->select.sel_info.hslab->span_lst); + HDassert(space2->select.sel_info.hslab->span_lst); + + /* Note: the offset of space2 is not considered here for bounding box */ + if(H5S__fill_in_new_space(space1, op, space2->select.sel_info.hslab->span_lst, FALSE, &span2_owned, &updated_spans, result) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create the specified selection") + + /* Update diminfo if space2's diminfo was valid, otherwise just mark it as + * invalid if the spans were updated */ + HDassert(result); + if(updated_spans) { + if(space2->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + if(H5S__hyper_update_diminfo(*result, op, space2->select.sel_info.hslab->diminfo.opt) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info") + } /* end if */ + else + (*result)->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__fill_in_select() */ + + +/*------------------------------------------------------------------------- + * Function: H5S__modify_select + * + * Purpose: Internal version of H5Smodify_select(). + * + * Return: New dataspace on success/NULL on failure + * + * Programmer: Quincey Koziol + * Tuesday, October 30, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5S__modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check args */ + HDassert(space1); + HDassert(space2); + HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA); + + /* Check that the space selections both have span trees */ + if(NULL == space1->select.sel_info.hslab->span_lst) + if(H5S__hyper_generate_spans(space1) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + + /* Set unlim_dim */ + space1->select.sel_info.hslab->unlim_dim = -1; + + if(NULL == space2->select.sel_info.hslab->span_lst) { + hsize_t tmp_start[H5S_MAX_RANK]; + hsize_t tmp_stride[H5S_MAX_RANK]; + hsize_t tmp_count[H5S_MAX_RANK]; + hsize_t tmp_block[H5S_MAX_RANK]; + unsigned u; + + for(u = 0; u < space2->extent.rank; u++) { + tmp_start[u] = space2->select.sel_info.hslab->diminfo.opt[u].start; + tmp_stride[u] = space2->select.sel_info.hslab->diminfo.opt[u].stride; + tmp_count[u] = space2->select.sel_info.hslab->diminfo.opt[u].count; + tmp_block[u] = space2->select.sel_info.hslab->diminfo.opt[u].block; + } /* end for */ + + /* Call H5S_select_hyperslab directly */ + if(H5S_select_hyperslab(space1, op, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection") + } /* end if */ + else + /* Combine spans from space1 & spans from space2, with the result in space1 */ + if(H5S__fill_in_select(space1, op, space2, &space1) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't perform operation on two selections") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__modify_select() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__hyper_project_intersection PURPOSE Projects the intersection of of the selections of src_space and @@ -8148,15 +10070,15 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, size_t ss_nelem; /* Number of elements for src_space */ size_t ss_i = (size_t)0; /* Index into offset/length arrays for src_space */ hbool_t advance_ss = FALSE; /* Whether to advance ss_i on the next iteration */ - H5S_sel_iter_t *ss_iter = NULL; /* Selection iterator for src_space */ + H5S_sel_iter_t *ss_iter = NULL; /* Selection iterator for src_space */ hbool_t ss_iter_init = FALSE; /* Whether ss_iter is initialized */ hsize_t ss_sel_off = (hsize_t)0; /* Offset within src_space selection */ hsize_t ds_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for dst_space */ size_t ds_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for dst_space */ size_t ds_nseq; /* Number of sequences for dst_space */ size_t ds_nelem; /* Number of elements for dst_space */ - size_t ds_i = (size_t)0; /* Index into offset/length arrays for dst_space */ - H5S_sel_iter_t *ds_iter = NULL; /* Selection iterator for dst_space */ + size_t ds_i = (size_t)0; /* Index into offset/length arrays for dst_space */ + H5S_sel_iter_t *ds_iter = NULL; /* Selection iterator for dst_space */ hbool_t ds_iter_init = FALSE; /* Whether ds_iter is initialized */ hsize_t ds_sel_off = (hsize_t)0; /* Offset within dst_space selection */ hsize_t sis_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for src_intersect_space */ @@ -8165,7 +10087,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, size_t sis_nelem; /* Number of elements for src_intersect_space */ size_t sis_i = (size_t)0; /* Index into offset/length arrays for src_intersect_space */ hbool_t advance_sis = FALSE; /* Whether to advance sis_i on the next iteration */ - H5S_sel_iter_t *sis_iter = NULL; /* Selection iterator for src_intersect_space */ + H5S_sel_iter_t *sis_iter = NULL; /* Selection iterator for src_intersect_space */ hbool_t sis_iter_init = FALSE; /* Whether sis_iter is initialized */ hsize_t int_sel_off; /* Offset within intersected selections (ss/sis and ds/ps) */ size_t int_len; /* Length of segment in intersected selections */ @@ -8174,14 +10096,11 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, size_t proj_len_rem; /* Remaining length in proj_space for segment */ hsize_t proj_down_dims[H5S_MAX_RANK]; /* "Down" dimensions in proj_space */ H5S_hyper_span_info_t *curr_span_tree[H5S_MAX_RANK]; /* Current span tree being built (in each dimension) */ - H5S_hyper_span_t *prev_span[H5S_MAX_RANK]; /* Previous span in tree (in each dimension) */ hsize_t curr_span_up_dim[H5S_MAX_RANK]; /* "Up" dimensions for current span */ unsigned proj_rank; /* Rank of proj_space */ hsize_t low; /* Low value of span */ - hsize_t high; /* High value of span */ - size_t span_len; /* Length of span */ size_t nelem; /* Number of elements returned for get_seq_list op */ - unsigned i; /* Local index variable */ + unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -8203,7 +10122,6 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, /* Initialize prev_space, curr_span_tree, and curr_span_up_dim */ HDmemset(curr_span_tree, 0, sizeof(curr_span_tree)); - HDmemset(prev_span, 0, sizeof(prev_span)); HDmemset(curr_span_up_dim, 0, sizeof(curr_span_up_dim)); /* Save rank of projected space */ @@ -8244,12 +10162,12 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source selection iterator") /* Initialize source space iterator */ - if(H5S_select_iter_init(ss_iter, src_space, (size_t)1) < 0) + if(H5S_select_iter_init(ss_iter, src_space, (size_t)1, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") ss_iter_init = TRUE; /* Get sequence list for source space */ - if(H5S_SELECT_GET_SEQ_LIST(src_space, 0u, ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") ss_nelem -= nelem; HDassert(ss_nseq > 0); @@ -8259,12 +10177,12 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate destination selection iterator") /* Initialize destination space iterator */ - if(H5S_select_iter_init(ds_iter, dst_space, (size_t)1) < 0) + if(H5S_select_iter_init(ds_iter, dst_space, (size_t)1, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") ds_iter_init = TRUE; /* Get sequence list for destination space */ - if(H5S_SELECT_GET_SEQ_LIST(dst_space, 0u, ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") ds_nelem -= nelem; HDassert(ds_nseq > 0); @@ -8274,12 +10192,12 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source intersect space iterator") /* Initialize source intersect space iterator */ - if(H5S_select_iter_init(sis_iter, src_intersect_space, (size_t)1) < 0) + if(H5S_select_iter_init(sis_iter, src_intersect_space, (size_t)1, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") sis_iter_init = TRUE; /* Get sequence list for source intersect space */ - if(H5S_SELECT_GET_SEQ_LIST(src_intersect_space, 0u, sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") sis_nelem -= nelem; HDassert(sis_nseq > 0); @@ -8294,7 +10212,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, if(++ss_i == ss_nseq) { if(ss_nelem > 0) { /* Try to grab more sequences from src_space */ - if(H5S_SELECT_GET_SEQ_LIST(src_space, 0u, ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") HDassert(ss_len[0] > 0); @@ -8325,7 +10243,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, if(sis_nelem > 0) { /* Try to grab more sequences from src_intersect_space */ - if(H5S_SELECT_GET_SEQ_LIST(src_intersect_space, 0u, sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") HDassert(sis_len[0] > 0); @@ -8377,7 +10295,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, HDassert(ds_nelem > 0); /* Try to grab more sequences from dst_space */ - if(H5S_SELECT_GET_SEQ_LIST(dst_space, 0u, ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") HDassert(ds_len[0] > 0); @@ -8399,34 +10317,33 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, /* Add to span tree */ while(proj_len_rem > (size_t)0) { - /* Check for more than one full row (in every dim) and - * append multiple spans at once? -NAF */ + hsize_t high; /* High value of span */ + size_t span_len; /* Length of span */ + /* Append spans in higher dimensions if we're going ouside * the plane of the span currently being built (i.e. it's * finished being built) */ - for(i = proj_rank - 1; ((i > 0) - && ((proj_off / proj_down_dims[i - 1]) - != curr_span_up_dim[i - 1])); i--) { - if(curr_span_tree[i]) { - HDassert(prev_span[i]); - + /* Check for more than one full row (in every dim) and + * append multiple spans at once? -NAF */ + for(u = proj_rank - 1; ((u > 0) + && ((proj_off / proj_down_dims[u - 1]) + != curr_span_up_dim[u - 1])); u--) { + if(curr_span_tree[u]) { /* Append complete lower dimension span tree to * current dimension */ - low = curr_span_up_dim[i - 1] % proj_space->extent.size[i - 1]; - if(H5S__hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], low, low, curr_span_tree[i], NULL) < 0) + low = curr_span_up_dim[u - 1] % proj_space->extent.size[u - 1]; + if(H5S__hyper_append_span(&curr_span_tree[u - 1], (proj_rank - u) + 1, low, low, curr_span_tree[u]) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Reset lower dimension's span tree and previous * span since we just committed it and will start * over with a new one */ - if(H5S__hyper_free_span_info(curr_span_tree[i]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") - curr_span_tree[i] = NULL; - prev_span[i] = NULL; + H5S__hyper_free_span_info(curr_span_tree[u]); + curr_span_tree[u] = NULL; } /* end if */ /* Update curr_span_up_dim */ - curr_span_up_dim[i - 1] = proj_off / proj_down_dims[i - 1]; + curr_span_up_dim[u - 1] = proj_off / proj_down_dims[u - 1]; } /* end for */ /* Compute bounds for new span in lowest dimension */ @@ -8438,7 +10355,7 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, high = (low + (hsize_t)span_len) - (hsize_t)1; /* Append span in lowest dimension */ - if(H5S__hyper_append_span(&prev_span[proj_rank - 1], &curr_span_tree[proj_rank - 1], low, high, NULL, NULL) < 0) + if(H5S__hyper_append_span(&curr_span_tree[proj_rank - 1], 1, low, high, NULL) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Update remaining offset and length */ @@ -8455,19 +10372,16 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, loop_end: /* Add remaining spans to span tree */ - for(i = proj_rank - 1; i > 0; i--) - if(curr_span_tree[i]) { - HDassert(prev_span[i]); - + for(u = proj_rank - 1; u > 0; u--) + if(curr_span_tree[u]) { /* Append remaining span tree to higher dimension */ - low = curr_span_up_dim[i - 1] % proj_space->extent.size[i - 1]; - if(H5S__hyper_append_span(&prev_span[i - 1], &curr_span_tree[i - 1], low, low, curr_span_tree[i], NULL) < 0) + low = curr_span_up_dim[u - 1] % proj_space->extent.size[u - 1]; + if(H5S__hyper_append_span(&curr_span_tree[u - 1], (proj_rank - u) + 1, low, low, curr_span_tree[u]) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span") /* Reset span tree */ - if(H5S__hyper_free_span_info(curr_span_tree[i]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") - curr_span_tree[i] = NULL; + H5S__hyper_free_span_info(curr_span_tree[u]); + curr_span_tree[u] = NULL; } /* end if */ /* Add span tree to proj_space */ @@ -8514,12 +10428,9 @@ done: HDONE_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") /* Free span trees */ - for(i = 0; i < proj_rank; i++) - if(curr_span_tree[i]) { - if(H5S__hyper_free_span_info(curr_span_tree[i]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't free span info") - curr_span_tree[i] = NULL; - } /* end if */ + for(u = 0; u < proj_rank; u++) + if(curr_span_tree[u]) + H5S__hyper_free_span_info(curr_span_tree[u]); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -8528,118 +10439,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5S__hyper_subtract - PURPOSE - Subtract one hyperslab selection from another - USAGE - herr_t H5S__hyper_subtract(space,subtract_space) - H5S_t *space; IN/OUT: Selection to be operated on - H5S_t *subtract_space; IN: Selection that will be subtracted from space - RETURNS - Non-negative on success/Negative on failure. - DESCRIPTION - Removes any and all portions of space that are also present in - subtract_space. In essence, performs an A_NOT_B operation with the - two selections. - - Note this function basically duplicates a subset of the functionality - of H5S_select_select(). It should probably be removed when that - function is enabled. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space) -{ - H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ - H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */ - H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Check args */ - HDassert(space); - HDassert(subtract_space); - - /* Check that the space selections both have span trees */ - if(space->select.sel_info.hslab->span_lst == NULL) - if(H5S__hyper_generate_spans(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - if(subtract_space->select.sel_info.hslab->span_lst == NULL) - if(H5S__hyper_generate_spans(subtract_space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") - - /* Generate lists of spans which overlap and don't overlap */ - if(H5S__hyper_clip_spans(space->select.sel_info.hslab->span_lst, subtract_space->select.sel_info.hslab->span_lst, &a_not_b, &a_and_b, &b_not_a)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information") - - /* Reset the other dataspace selection information */ - if(H5S_SELECT_RELEASE(space) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection") - - /* Allocate space for the hyperslab selection information */ - if((space->select.sel_info.hslab = H5FL_CALLOC(H5S_hyper_sel_t)) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") - - /* Set unlim_dim */ - space->select.sel_info.hslab->unlim_dim = -1; - - /* Check for anything returned in a_not_b */ - if(a_not_b) { - /* Update spans in space */ - space->select.sel_info.hslab->span_lst = a_not_b; - a_not_b = NULL; - - /* Update number of elements */ - space->select.num_elem = H5S__hyper_spans_nelem(space->select.sel_info.hslab->span_lst); - - /* Attempt to rebuild "optimized" start/stride/count/block information. - * from resulting hyperslab span tree */ - H5S__hyper_rebuild(space); - } /* end if */ - else { - H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ - - /* Set number of elements */ - space->select.num_elem = 0; - - /* Allocate a span info node */ - if(NULL == (spans = H5FL_MALLOC(H5S_hyper_span_info_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span") - - /* Set the reference count */ - spans->count = 1; - - /* Reset the scratch pad space */ - spans->scratch = 0; - - /* Set to empty tree */ - spans->head = NULL; - - /* Set pointer to empty span tree */ - space->select.sel_info.hslab->span_lst = spans; - } /* end if */ - -done: - /* Free span trees */ - if(a_and_b) - H5S__hyper_free_span_info(a_and_b); - if(b_not_a) - H5S__hyper_free_span_info(b_not_a); - if(a_not_b) { - HDassert(ret_value < 0); - H5S__hyper_free_span_info(b_not_a); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__hyper_subtract() */ - - -/*-------------------------------------------------------------------------- - NAME H5S__hyper_get_clip_diminfo PURPOSE Calculates the count and block required to clip the specified @@ -8706,7 +10505,7 @@ H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, RETURNS Non-negative on success/Negative on failure. DESCRIPTION - This function changes the unlimited selection into a limited selection + This function changes the unlimited selection into a fixed-dimension selection with the extent of the formerly unlimited dimension specified by clip_size. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -8720,7 +10519,7 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ hsize_t orig_count; /* Original count in unlimited dimension */ int orig_unlim_dim; /* Original unliminted dimension */ - H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ + H5S_hyper_dim_t *diminfo; /* Convenience pointer to diminfo.opt in unlimited dimension */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -8735,7 +10534,8 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Save original unlimited dimension */ orig_unlim_dim = hslab->unlim_dim; - diminfo = &hslab->opt_diminfo[orig_unlim_dim]; + /* Set up convenience pointer */ + diminfo = &hslab->diminfo.opt[orig_unlim_dim]; /* Save original count in unlimited dimension */ orig_count = diminfo->count; @@ -8757,8 +10557,8 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Calculate number of elements */ space->select.num_elem = diminfo->block * hslab->num_elem_non_unlim; - /* Mark that opt_diminfo is valid */ - hslab->diminfo_valid = TRUE; + /* Mark that diminfo.opt is valid */ + hslab->diminfo_valid = H5S_DIMINFO_VALID_YES; } /* end if */ else { /* Calculate number of elements */ @@ -8771,7 +10571,7 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) > (clip_size - diminfo->start)) { hsize_t start[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; - unsigned i; + unsigned u; /* Last block is partial, need to construct compound selection */ /* Fill start with zeros */ @@ -8779,11 +10579,11 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Set block to clip_size in unlimited dimension, H5S_MAX_SIZE in * others so only unlimited dimension is clipped */ - for(i = 0; i < space->extent.rank; i++) - if((int)i == orig_unlim_dim) - block[i] = clip_size; + for(u = 0; u < space->extent.rank; u++) + if((int)u == orig_unlim_dim) + block[u] = clip_size; else - block[i] = H5S_MAX_SIZE; + block[u] = H5S_MAX_SIZE; /* Generate span tree in selection */ if(!hslab->span_lst) @@ -8791,17 +10591,24 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to generate span tree") /* Indicate that the regular dimensions are no longer valid */ - hslab->diminfo_valid = FALSE; + hslab->diminfo_valid = H5S_DIMINFO_VALID_NO; /* "And" selection with calculated block to perform clip operation */ if(H5S__generate_hyperslab(space, H5S_SELECT_AND, start, H5S_hyper_ones_g, H5S_hyper_ones_g, block) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") } /* end if */ else - /* Last block is complete, simply mark that opt_diminfo is valid */ - hslab->diminfo_valid = TRUE; + /* Last block is complete, simply mark that diminfo.opt is valid */ + hslab->diminfo_valid = H5S_DIMINFO_VALID_YES; } /* end else */ + /* Update the upper bound, if the diminfo is valid */ + if(H5S_DIMINFO_VALID_YES == hslab->diminfo_valid) + hslab->diminfo.high_bounds[orig_unlim_dim] = + hslab->diminfo.opt[orig_unlim_dim].start + + hslab->diminfo.opt[orig_unlim_dim].stride * (hslab->diminfo.opt[orig_unlim_dim].count - 1) + + (hslab->diminfo.opt[orig_unlim_dim].block - 1); + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_clip_unlim() */ @@ -8850,7 +10657,7 @@ H5S__hyper_get_clip_extent_real(const H5S_t *clip_space, hsize_t num_slices, HDassert(clip_space->select.sel_info.hslab); HDassert(clip_space->select.sel_info.hslab->unlim_dim >= 0); - diminfo = &clip_space->select.sel_info.hslab->opt_diminfo[clip_space->select.sel_info.hslab->unlim_dim]; + diminfo = &clip_space->select.sel_info.hslab->diminfo.opt[clip_space->select.sel_info.hslab->unlim_dim]; if(num_slices == 0) ret_value = incl_trail ? diminfo->start : 0; @@ -9004,7 +10811,7 @@ H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, HDassert(clip_space->select.sel_info.hslab->num_elem_non_unlim == match_space->select.sel_info.hslab->num_elem_non_unlim); - match_diminfo = &match_space->select.sel_info.hslab->opt_diminfo[match_space->select.sel_info.hslab->unlim_dim]; + match_diminfo = &match_space->select.sel_info.hslab->diminfo.opt[match_space->select.sel_info.hslab->unlim_dim]; /* Get initial count and block */ count = match_diminfo->count; @@ -9068,13 +10875,13 @@ H5S_t * H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index) { H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ - H5S_t *space_out = NULL; - hsize_t start[H5S_MAX_RANK]; + H5S_t *space_out = NULL; /* Dataspace to return */ + hsize_t start[H5S_MAX_RANK];/* Hyperslab selection info for unlim. selection */ hsize_t stride[H5S_MAX_RANK]; hsize_t count[H5S_MAX_RANK]; hsize_t block[H5S_MAX_RANK]; - unsigned i; - H5S_t *ret_value = NULL; + unsigned u; /* Local index variable */ + H5S_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -9083,23 +10890,23 @@ H5S_hyper_get_unlim_block(const H5S_t *space, hsize_t block_index) hslab = space->select.sel_info.hslab; HDassert(hslab); HDassert(hslab->unlim_dim >= 0); - HDassert(hslab->opt_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); + HDassert(hslab->diminfo.opt[hslab->unlim_dim].count == H5S_UNLIMITED); /* Set start to select block_indexth block in unlimited dimension and set * count to 1 in that dimension to only select that block. Copy all other * diminfo parameters. */ - for(i = 0; i < space->extent.rank; i++) { - if((int)i == hslab->unlim_dim){ - start[i] = hslab->opt_diminfo[i].start + (block_index - * hslab->opt_diminfo[i].stride); - count[i] = (hsize_t)1; + for(u = 0; u < space->extent.rank; u++) { + if((int)u == hslab->unlim_dim){ + start[u] = hslab->diminfo.opt[u].start + (block_index + * hslab->diminfo.opt[u].stride); + count[u] = (hsize_t)1; } /* end if */ else { - start[i] = hslab->opt_diminfo[i].start; - count[i] = hslab->opt_diminfo[i].count; + start[u] = hslab->diminfo.opt[u].start; + count[u] = hslab->diminfo.opt[u].count; } /* end else */ - stride[i] = hslab->opt_diminfo[i].stride; - block[i] = hslab->opt_diminfo[i].block; + stride[u] = hslab->diminfo.opt[u].stride; + block[u] = hslab->diminfo.opt[u].block; } /* end for */ /* Create output space, copy extent */ @@ -9154,7 +10961,7 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hbool_t *partial) { H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */ - H5S_hyper_dim_t *diminfo; /* Convenience pointer to opt_diminfo in unlimited dimension */ + H5S_hyper_dim_t *diminfo; /* Convenience pointer to diminfo.opt in unlimited dimension */ hsize_t ret_value = 0; FUNC_ENTER_NOAPI(0) @@ -9164,9 +10971,9 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, hslab = space->select.sel_info.hslab; HDassert(hslab); HDassert(hslab->unlim_dim >= 0); - HDassert(hslab->opt_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); + HDassert(hslab->diminfo.opt[hslab->unlim_dim].count == H5S_UNLIMITED); - diminfo = &hslab->opt_diminfo[hslab->unlim_dim]; + diminfo = &hslab->diminfo.opt[hslab->unlim_dim]; /* Check for selection outside of clip_size */ if(diminfo->start >= clip_size) { @@ -9283,16 +11090,16 @@ H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[], hsize_t stride[], /* Retrieve hyperslab parameters */ if(start) for(u = 0; u < space->extent.rank; u++) - start[u] = space->select.sel_info.hslab->app_diminfo[u].start; + start[u] = space->select.sel_info.hslab->diminfo.app[u].start; if(stride) for(u = 0; u < space->extent.rank; u++) - stride[u] = space->select.sel_info.hslab->app_diminfo[u].stride; + stride[u] = space->select.sel_info.hslab->diminfo.app[u].stride; if(count) for(u = 0; u < space->extent.rank; u++) - count[u] = space->select.sel_info.hslab->app_diminfo[u].count; + count[u] = space->select.sel_info.hslab->diminfo.app[u].count; if(block) for(u = 0; u < space->extent.rank; u++) - block[u] = space->select.sel_info.hslab->app_diminfo[u].block; + block[u] = space->select.sel_info.hslab->diminfo.app[u].block; done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 01ec3e1..aeec566 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -31,6 +31,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5MMprivate.h" /* Memory management */ #include "H5Spkg.h" /* Dataspaces */ #include "H5VMprivate.h" /* Vector and array functions */ @@ -51,6 +52,18 @@ /* Local Typedefs */ /******************/ +/* Node in linked list of MPI data types created during traversal of irregular hyperslab selection */ +typedef struct H5S_mpio_mpitype_node_t { + MPI_Datatype type; /* MPI Datatype */ + struct H5S_mpio_mpitype_node_t *next; /* Pointer to next node in list */ +} H5S_mpio_mpitype_node_t; + +/* List to track MPI data types generated during traversal of irregular hyperslab selection */ +typedef struct H5S_mpio_mpitype_list_t { + H5S_mpio_mpitype_node_t *head; /* Pointer to head of list */ + H5S_mpio_mpitype_node_t *tail; /* Pointer to tail of list */ +} H5S_mpio_mpitype_list_t; + /********************/ /* Local Prototypes */ @@ -71,9 +84,12 @@ static herr_t H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); static herr_t H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type); -static herr_t H5S__obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span, - const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size); -static herr_t H5S__mpio_create_large_type(hsize_t, MPI_Aint, MPI_Datatype , MPI_Datatype *); +static herr_t H5S__release_datatype(H5S_mpio_mpitype_list_t *type_list); +static herr_t H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, + size_t elmt_size, const MPI_Datatype *elmt_type, MPI_Datatype *span_type, + H5S_mpio_mpitype_list_t *type_list, uint64_t op_gen); +static herr_t H5S__mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, + MPI_Datatype old_type, MPI_Datatype *new_type); /*****************************/ @@ -91,6 +107,8 @@ static herr_t H5S__mpio_create_large_type(hsize_t, MPI_Aint, MPI_Datatype , MPI_ /*******************/ static hsize_t bigio_count = H5S_MAX_MPI_COUNT; +/* Declare a free list to manage the H5S_mpio_mpitype_node_t struct */ +H5FL_DEFINE_STATIC(H5S_mpio_mpitype_node_t); @@ -542,7 +560,7 @@ H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") /* Initialize selection iterator */ - if(H5S_select_iter_init(&sel_iter, space, elmt_size) < 0) + if(H5S_select_iter_init(&sel_iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") sel_iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -559,7 +577,7 @@ H5S__mpio_permute_type(const H5S_t *space, size_t elmt_size, hsize_t **permute, size_t curr_seq; /* Current sequence being worked on */ /* Get the sequences of bytes */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, &sel_iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(&sel_iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Loop, while sequences left to process */ @@ -679,7 +697,7 @@ H5S__mpio_reg_hyper_type(const H5S_t *space, size_t elmt_size, HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size)); /* Initialize selection iterator */ - if(H5S_select_iter_init(&sel_iter, space, elmt_size) < 0) + if(H5S_select_iter_init(&sel_iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") sel_iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -979,10 +997,12 @@ static herr_t H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type, int *count, hbool_t *is_derived_type) { + H5S_mpio_mpitype_list_t type_list; /* List to track MPI data types created */ MPI_Datatype elmt_type; /* MPI datatype for an element */ hbool_t elmt_type_is_derived = FALSE; /* Whether the element type has been created */ MPI_Datatype span_type; /* MPI datatype for overall span tree */ hsize_t down[H5S_MAX_RANK]; /* 'down' sizes for each dimension */ + uint64_t op_gen; /* Operation generation value */ int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1008,12 +1028,21 @@ H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, if(H5VM_array_down(space->extent.rank, space->extent.size, down) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGETSIZE, FAIL, "couldn't compute 'down' dimension sizes") - /* Obtain derived data type */ - if(H5S__obtain_datatype(down, space->select.sel_info.hslab->span_lst->head, &elmt_type, &span_type, elmt_size) < 0) + /* Acquire an operation generation value for creating MPI datatypes */ + op_gen = H5S__hyper_get_op_gen(); + + /* Obtain derived MPI data type */ + type_list.head = type_list.tail = NULL; + if(H5S__obtain_datatype(space->select.sel_info.hslab->span_lst, down, elmt_size, &elmt_type, &span_type, &type_list, op_gen) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") - if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type))) + if(MPI_SUCCESS != (mpi_code = MPI_Type_dup(span_type, new_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type))) HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - *new_type = span_type; + + /* Release MPI data types generated during span tree traversal */ + if(H5S__release_datatype(&type_list) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "couldn't release MPI derived data type") /* fill in the remaining return values */ *count = 1; @@ -1030,6 +1059,53 @@ done: /*------------------------------------------------------------------------- + * Function: H5S__release_datatype + * + * Purpose: Release the MPI derived datatypes for span-tree hyperslab selection + * + * Return: Non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol, February 2, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S__release_datatype(H5S_mpio_mpitype_list_t *type_list) +{ + H5S_mpio_mpitype_node_t *curr; /* Pointer to head of list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(type_list); + + /* Iterate over the list, freeing the MPI data types */ + curr = type_list->head; + while(curr) { + H5S_mpio_mpitype_node_t *next; /* Pointer to next node in list */ + int mpi_code; /* MPI return status code */ + + /* Release the MPI data type for this span tree */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&curr->type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + + /* Get pointer to next node in list */ + next = curr->next; + + /* Free the current node */ + curr = H5FL_FREE(H5S_mpio_mpitype_node_t, curr); + + /* Advance to next node */ + curr = next; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__release_datatype() */ + + +/*------------------------------------------------------------------------- * Function: H5S__obtain_datatype * * Purpose: Obtain an MPI derived datatype for span-tree hyperslab selection @@ -1043,206 +1119,219 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5S__obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, - const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size) +H5S__obtain_datatype(H5S_hyper_span_info_t *spans, const hsize_t *down, + size_t elmt_size, const MPI_Datatype *elmt_type, MPI_Datatype *span_type, + H5S_mpio_mpitype_list_t *type_list, uint64_t op_gen) { + H5S_hyper_span_t *span; /* Hyperslab span to iterate with */ size_t alloc_count = 0; /* Number of span tree nodes allocated at this level */ size_t outercount; /* Number of span tree nodes at this level */ MPI_Datatype *inner_type = NULL; hbool_t inner_types_freed = FALSE; /* Whether the inner_type MPI datatypes have been freed */ - hbool_t span_type_valid = FALSE; /* Whether the span_type MPI datatypes is valid */ - hbool_t large_block = FALSE; /* Wether the block length is larger than 32 bit integer */ int *blocklen = NULL; MPI_Aint *disp = NULL; - H5S_hyper_span_t *tspan = NULL; /* Temporary pointer to span tree node */ + size_t u; /* Local index variable */ int mpi_code; /* MPI return status code */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Sanity check */ - HDassert(span); + HDassert(spans); + HDassert(type_list); + + /* Check if we've visited this span tree before */ + if(spans->op_gen != op_gen) { + H5S_mpio_mpitype_node_t *type_node; /* Pointer to new node in MPI data type list */ + + /* Allocate the initial displacement & block length buffers */ + alloc_count = H5S_MPIO_INITIAL_ALLOC_COUNT; + if(NULL == (disp = (MPI_Aint *)H5MM_malloc(alloc_count * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") + if(NULL == (blocklen = (int *)H5MM_malloc(alloc_count * sizeof(int)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") + + /* If this is the fastest changing dimension, it is the base case for derived datatype. */ + span = spans->head; + if(NULL == span->down) { + hbool_t large_block = FALSE; /* Wether the block length is larger than 32 bit integer */ + + outercount = 0; + while(span) { + hsize_t nelmts; /* # of elements covered by current span */ + + /* Check if we need to increase the size of the buffers */ + if(outercount >= alloc_count) { + MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */ + int *tmp_blocklen; /* Temporary pointer to new block length buffer */ + + /* Double the allocation count */ + alloc_count *= 2; + + /* Re-allocate the buffers */ + if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") + disp = tmp_disp; + if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") + blocklen = tmp_blocklen; + } /* end if */ - /* Allocate the initial displacement & block length buffers */ - alloc_count = H5S_MPIO_INITIAL_ALLOC_COUNT; - if(NULL == (disp = (MPI_Aint *)H5MM_malloc(alloc_count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") - if(NULL == (blocklen = (int *)H5MM_malloc(alloc_count * sizeof(int)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") - - /* if this is the fastest changing dimension, it is the base case for derived datatype. */ - if(NULL == span->down) { - tspan = span; - outercount = 0; - while(tspan) { - /* Check if we need to increase the size of the buffers */ - if(outercount >= alloc_count) { - MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */ - int *tmp_blocklen; /* Temporary pointer to new block length buffer */ - - /* Double the allocation count */ - alloc_count *= 2; - - /* Re-allocate the buffers */ - if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") - disp = tmp_disp; - if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") - blocklen = tmp_blocklen; - } /* end if */ + /* Compute the number of elements to attempt in this span */ + nelmts = (span->high - span->low) + 1; - /* Store displacement & block length */ - disp[outercount] = (MPI_Aint)elmt_size * tspan->low; - H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int) - blocklen[outercount] = (int)tspan->nelem; - tspan = tspan->next; + /* Store displacement & block length */ + disp[outercount] = (MPI_Aint)elmt_size * span->low; + H5_CHECK_OVERFLOW(nelmts, hsize_t, int) + blocklen[outercount] = (int)nelmts; - if(bigio_count < blocklen[outercount]) - large_block = TRUE; /* at least one block type is large, so set this flag to true */ + if(bigio_count < blocklen[outercount]) + large_block = TRUE; /* at least one block type is large, so set this flag to true */ - outercount++; - } /* end while */ + span = span->next; + outercount++; + } /* end while */ - /* Everything fits into integers, so cast them and use hindexed */ - if(bigio_count >= outercount && large_block == FALSE) { - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)outercount, blocklen, disp, *elmt_type, span_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) - span_type_valid = TRUE; - } - else { /* LARGE_DATATYPE:: Something doesn't fit into a 32 bit integer */ - size_t i; - - for (i=0 ; i bigio_count) { - if (H5S__mpio_create_large_type (blocklen[i], 0, *elmt_type, &temp_type) < 0) { - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, - "couldn't create a large element datatype in span_hyper selection") - } - } - else { - if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)blocklen[i], - *elmt_type, - &temp_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) - } - - /* combine the current datatype that is created with this current block type */ - if (0 == i) { /* first iteration, there is no combined datatype yet */ - *span_type = temp_type; - } - else { - int bl[2] = {1,1}; - MPI_Aint ds[2] = {disp[i-1],disp[i]}; - MPI_Datatype dt[2] = {*span_type, temp_type}; - - if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct (2, /* count */ - bl, /* blocklength */ - ds, /* stride in bytes*/ - dt, /* old type */ - &outer_type))){ /* new type */ - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - } - *span_type = outer_type; - } - - if (outer_type != MPI_DATATYPE_NULL) - MPI_Type_free(&outer_type); - /* temp_type shouldn't be freed here... - * Note that we have simply copied it above (not MPI_Type_dup) - * into the 'span_type' argument of the caller. - * The caller needs to deal with it there! - */ - } - } /* end (LARGE_DATATYPE::) */ + /* Everything fits into integers, so cast them and use hindexed */ + if(bigio_count >= outercount && large_block == FALSE) { + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)outercount, blocklen, disp, *elmt_type, &spans->u.down_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code) + } /* end if */ + else { /* LARGE_DATATYPE:: Something doesn't fit into a 32 bit integer */ + for(u = 0 ; u < outercount; u++) { + MPI_Datatype temp_type = MPI_DATATYPE_NULL; + + /* create the block type from elmt_type while checking the 32 bit int limit */ + if(blocklen[u] > bigio_count) { + if(H5S__mpio_create_large_type(blocklen[u], 0, *elmt_type, &temp_type) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create a large element datatype in span_hyper selection") + } /* end if */ + else + if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)blocklen[u], *elmt_type, &temp_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code) + + /* Combine the current datatype that is created with this current block type */ + if(0 == u) /* first iteration, there is no combined datatype yet */ + spans->u.down_type = temp_type; + else { + int bl[2] = {1, 1}; + MPI_Aint ds[2] = {disp[u - 1], disp[u]}; + MPI_Datatype dt[2] = {spans->u.down_type, temp_type}; + + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(2, /* count */ + bl, /* blocklength */ + ds, /* stride in bytes*/ + dt, /* old type */ + &spans->u.down_type))) /* new type */ + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + /* Release previous temporary datatype */ + if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&temp_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + } /* end else */ + } /* end for */ + } /* end else (LARGE_DATATYPE::) */ + } /* end if */ + else { + MPI_Aint stride; /* Distance between inner MPI datatypes */ - } /* end if */ - else { - size_t u; /* Local index variable */ + if(NULL == (inner_type = (MPI_Datatype *)H5MM_malloc(alloc_count * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes") - if(NULL == (inner_type = (MPI_Datatype *)H5MM_malloc(alloc_count * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes") + /* Calculate the total bytes of the lower dimension */ + stride = (*down) * elmt_size; - tspan = span; - outercount = 0; - while(tspan) { - MPI_Datatype down_type; /* Temporary MPI datatype for a span tree node's children */ - MPI_Aint stride; /* Distance between inner MPI datatypes */ + /* Loop over span nodes */ + outercount = 0; + while(span) { + MPI_Datatype down_type; /* Temporary MPI datatype for a span tree node's children */ + hsize_t nelmts; /* # of elements covered by current span */ + + /* Check if we need to increase the size of the buffers */ + if(outercount >= alloc_count) { + MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */ + int *tmp_blocklen; /* Temporary pointer to new block length buffer */ + MPI_Datatype *tmp_inner_type; /* Temporary pointer to inner MPI datatype buffer */ + + /* Double the allocation count */ + alloc_count *= 2; + + /* Re-allocate the buffers */ + if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") + disp = tmp_disp; + if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") + blocklen = tmp_blocklen; + if(NULL == (tmp_inner_type = (MPI_Datatype *)H5MM_realloc(inner_type, alloc_count * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes") + inner_type = tmp_inner_type; + } /* end if */ - /* Check if we need to increase the size of the buffers */ - if(outercount >= alloc_count) { - MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */ - int *tmp_blocklen; /* Temporary pointer to new block length buffer */ - MPI_Datatype *tmp_inner_type; /* Temporary pointer to inner MPI datatype buffer */ - - /* Double the allocation count */ - alloc_count *= 2; - - /* Re-allocate the buffers */ - if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements") - disp = tmp_disp; - if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths") - blocklen = tmp_blocklen; - if(NULL == (tmp_inner_type = (MPI_Datatype *)H5MM_realloc(inner_type, alloc_count * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes") - inner_type = tmp_inner_type; - } /* end if */ + /* Displacement should be in byte and should have dimension information */ + /* First using MPI Type vector to build derived data type for this span only */ + /* Need to calculate the disp in byte for this dimension. */ + disp[outercount] = span->low * stride; + blocklen[outercount] = 1; - /* Displacement should be in byte and should have dimension information */ - /* First using MPI Type vector to build derived data type for this span only */ - /* Need to calculate the disp in byte for this dimension. */ - /* Calculate the total bytes of the lower dimension */ - disp[outercount] = tspan->low * (*down) * elmt_size; - blocklen[outercount] = 1; + /* Generate MPI datatype for next dimension down */ + if(H5S__obtain_datatype(span->down, down + 1, elmt_size, elmt_type, &down_type, type_list, op_gen) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") - /* Generate MPI datatype for next dimension down */ - if(H5S__obtain_datatype(down + 1, tspan->down->head, elmt_type, &down_type, elmt_size) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type") + /* Compute the number of elements to attempt in this span */ + nelmts = (span->high - span->low) + 1; - /* Build the MPI datatype for this node */ - stride = (*down) * elmt_size; - H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int) - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)tspan->nelem, 1, stride, down_type, &inner_type[outercount]))) { - MPI_Type_free(&down_type); - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - } /* end if */ + /* Build the MPI datatype for this node */ + H5_CHECK_OVERFLOW(nelmts, hsize_t, int) + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector((int)nelmts, 1, stride, down_type, &inner_type[outercount]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code) - /* Release MPI datatype for next dimension down */ - if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&down_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + span = span->next; + outercount++; + } /* end while */ - tspan = tspan->next; - outercount++; - } /* end while */ + /* Building the whole vector datatype */ + H5_CHECK_OVERFLOW(outercount, size_t, int) + if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)outercount, blocklen, disp, inner_type, &spans->u.down_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - /* building the whole vector datatype */ - H5_CHECK_OVERFLOW(outercount, size_t, int) - if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)outercount, blocklen, disp, inner_type, span_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - span_type_valid = TRUE; + /* Release inner node types */ + for(u = 0; u < outercount; u++) + if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[u]))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + inner_types_freed = TRUE; + } /* end else */ + + /* Allocate space for the MPI data type list node */ + if(NULL == (type_node = H5FL_MALLOC(H5S_mpio_mpitype_node_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate MPI data type list node") - /* Release inner node types */ - for(u = 0; u < outercount; u++) - if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[u]))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code) - inner_types_freed = TRUE; + /* Set up MPI type node */ + type_node->type = spans->u.down_type; + type_node->next = NULL; + + /* Add MPI type node to list */ + if(type_list->head == NULL) + type_list->head = type_list->tail = type_node; + else { + type_list->tail->next = type_node; + type_list->tail = type_node; + } /* end else */ + + /* Remember that we've visited this span tree */ + spans->op_gen = op_gen; } /* end else */ + /* Return MPI data type for span tree */ + *span_type = spans->u.down_type; + done: /* General cleanup */ if(inner_type != NULL) { - if(!inner_types_freed) { - size_t u; /* Local index variable */ - + if(!inner_types_freed) for(u = 0; u < outercount; u++) if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[u]))) HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) - } /* end if */ - H5MM_free(inner_type); } /* end if */ if(blocklen != NULL) @@ -1250,13 +1339,6 @@ done: if(disp != NULL) H5MM_free(disp); - /* Error cleanup */ - if(ret_value < 0) { - if(span_type_valid) - if(MPI_SUCCESS != (mpi_code = MPI_Type_free(span_type))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) - } /* end if */ - FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__obtain_datatype() */ diff --git a/src/H5Snone.c b/src/H5Snone.c index 86994dd..de85bad 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -51,9 +51,6 @@ /* Selection callbacks */ static herr_t H5S__none_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S__none_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__none_release(H5S_t *space); static htri_t H5S__none_is_valid(const H5S_t *space); static hssize_t H5S__none_serial_size(const H5S_t *space); @@ -66,10 +63,11 @@ static int H5S__none_unlim_dim(const H5S_t *space); static htri_t H5S__none_is_contiguous(const H5S_t *space); static htri_t H5S__none_is_single(const H5S_t *space); static htri_t H5S__none_is_regular(const H5S_t *space); +static htri_t H5S__none_shape_same(const H5S_t *space1, const H5S_t *space2); static herr_t H5S__none_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__none_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S__none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static herr_t H5S__none_iter_init(const H5S_t *space, H5S_sel_iter_t *iter); /* Selection iteration callbacks */ static herr_t H5S__none_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); @@ -78,6 +76,8 @@ static hsize_t H5S__none_iter_nelmts(const H5S_sel_iter_t *iter); static htri_t H5S__none_iter_has_next_block(const H5S_sel_iter_t *iter); static herr_t H5S__none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); static herr_t H5S__none_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__none_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__none_iter_release(H5S_sel_iter_t *sel_iter); @@ -96,7 +96,6 @@ const H5S_select_class_t H5S_sel_none[1] = {{ /* Methods on selection */ H5S__none_copy, - H5S__none_get_seq_list, H5S__none_release, H5S__none_is_valid, H5S__none_serial_size, @@ -109,6 +108,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{ H5S__none_is_contiguous, H5S__none_is_single, H5S__none_is_regular, + H5S__none_shape_same, H5S__none_adjust_u, H5S__none_project_scalar, H5S__none_project_simple, @@ -131,6 +131,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_none[1] = {{ H5S__none_iter_has_next_block, H5S__none_iter_next, H5S__none_iter_next_block, + H5S__none_iter_get_seq_list, H5S__none_iter_release, }}; @@ -149,7 +150,7 @@ static const H5S_sel_iter_class_t H5S_sel_iter_none[1] = {{ *------------------------------------------------------------------------- */ static herr_t -H5S__none_iter_init(H5S_sel_iter_t *iter, const H5S_t H5_ATTR_UNUSED *space) +H5S__none_iter_init(const H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter) { FUNC_ENTER_STATIC_NOERR @@ -334,13 +335,11 @@ H5S__none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) /*-------------------------------------------------------------------------- NAME - H5S__none_get_seq_list + H5S__none_iter_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S__none_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation + herr_t H5S__none_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. size_t maxseq; IN: Maximum number of sequences to generate @@ -364,14 +363,13 @@ H5S__none_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSED flags, H5S_sel_iter_t H5_ATTR_UNUSED *iter, - size_t H5_ATTR_UNUSED maxseq, size_t H5_ATTR_UNUSED maxelem, size_t *nseq, size_t *nelem, - hsize_t H5_ATTR_UNUSED *off, size_t H5_ATTR_UNUSED *len) +H5S__none_iter_get_seq_list(H5S_sel_iter_t H5_ATTR_UNUSED *iter, + size_t H5_ATTR_UNUSED maxseq, size_t H5_ATTR_UNUSED maxelem, size_t *nseq, + size_t *nelem, hsize_t H5_ATTR_UNUSED *off, size_t H5_ATTR_UNUSED *len) { FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -387,7 +385,7 @@ H5S__none_get_seq_list(const H5S_t H5_ATTR_UNUSED *space, unsigned H5_ATTR_UNUSE *nelem = 0; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S__none_get_seq_list() */ +} /* end H5S__none_iter_get_seq_list() */ /*-------------------------------------------------------------------------- @@ -830,7 +828,40 @@ H5S__none_is_regular(const H5S_t H5_ATTR_UNUSED *space) /*-------------------------------------------------------------------------- NAME - H5S_none_adjust_u + H5S__none_shape_same + PURPOSE + Check if a two "none" selections are the same shape + USAGE + htri_t H5S__none_shape_same(space1, space2) + const H5S_t *space1; IN: First dataspace to check + const H5S_t *space2; IN: Second dataspace to check + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in each dataspace are the same + shape. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S__none_shape_same(const H5S_t H5_ATTR_UNUSED *space1, + const H5S_t H5_ATTR_UNUSED *space2) +{ + FUNC_ENTER_STATIC_NOERR + + /* Check args */ + HDassert(space1); + HDassert(space2); + + FUNC_LEAVE_NOAPI(TRUE) +} /* end H5S__none_shape_same() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__none_adjust_u PURPOSE Adjust an "none" selection by subtracting an offset USAGE diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 0575f03..9de0bec 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -84,49 +84,97 @@ struct H5S_extent_t { /* Node in point selection list (typedef'd in H5Sprivate.h) */ struct H5S_pnt_node_t { - hsize_t *pnt; /* Pointer to a selected point */ - struct H5S_pnt_node_t *next; /* pointer to next point in list */ + struct H5S_pnt_node_t *next; /* Pointer to next point in list */ + hsize_t pnt[]; /* Selected point */ + /* (NOTE: This uses the C99 "flexible array member" feature) */ }; -/* Information about point selection list */ -typedef struct { +/* Information about point selection list (typedef'd in H5Sprivate.h) */ +struct H5S_pnt_list_t { + /* The following two fields defines the bounding box of the whole set of points, relative to the offset */ + hsize_t low_bounds[H5S_MAX_RANK]; /* The smallest element selected in each dimension */ + hsize_t high_bounds[H5S_MAX_RANK]; /* The largest element selected in each dimension */ + H5S_pnt_node_t *head; /* Pointer to head of point list */ -} H5S_pnt_list_t; + H5S_pnt_node_t *tail; /* Pointer to tail of point list */ +}; /* Information about hyperslab spans */ /* Information a particular hyperslab span (typedef'd in H5Sprivate.h) */ struct H5S_hyper_span_t { - hsize_t low, high; /* Low & high bounds of span */ - hsize_t nelem; /* Number of elements in span (only needed during I/O) */ - hsize_t pstride; /* Pseudo-stride from start of previous span (only used during I/O) */ - struct H5S_hyper_span_info_t *down; /* Pointer to list of spans in next dimension down */ - struct H5S_hyper_span_t *next; /* Pointer to next span in list */ + hsize_t low, high; /* Low & high bounds of elements selected for span, inclusive */ + struct H5S_hyper_span_info_t *down; /* Pointer to list of spans in next dimension down */ + struct H5S_hyper_span_t *next; /* Pointer to next span in list */ }; -/* Information about a list of hyperslab spans in one dimension */ +/* Information about a list of hyperslab spans in one dimension (typedef'd in H5Sprivate.h) */ struct H5S_hyper_span_info_t { - unsigned count; /* Ref. count of number of spans which share this span */ - struct H5S_hyper_span_info_t *scratch; /* Scratch pointer - * (used during copies, as mark - * during precomputes for I/O & - * to point to the last span in a - * list during single element adds) - */ - struct H5S_hyper_span_t *head; /* Pointer to list of spans in next dimension down */ + unsigned count; /* Ref. count of number of spans which share this span */ + + /* The following two fields define the bounding box of this set of spans + * and all lower dimensions, relative to the offset. + */ + /* (NOTE: The bounds arrays are _relative_ to the depth of the span_info + * node in the span tree, so the top node in a 5-D span tree will + * use indices 0-4 in the arrays to store it's bounds information, + * but the next level down in the span tree will use indices 0-3. + * So, each level in the span tree will have the 0th index in the + * arrays correspond to the bounds in "this" dimension, even if + * it's not the highest level in the span tree. + */ + hsize_t *low_bounds; /* The smallest element selected in each dimension */ + hsize_t *high_bounds; /* The largest element selected in each dimension */ + + /* "Operation generation" fields */ + /* (Used during copies, 'adjust', 'nelem', and 'rebuild' operations) */ + uint64_t op_gen; /* Generation of the scratch info */ + union { + struct H5S_hyper_span_info_t *copied; /* Pointer to already copied span tree */ + hsize_t nelmts; /* # of elements */ + hsize_t nblocks; /* # of blocks */ +#ifdef H5_HAVE_PARALLEL + MPI_Datatype down_type; /* MPI datatype for span tree */ +#endif /* H5_HAVE_PARALLEL */ + }u; + + struct H5S_hyper_span_t *head; /* Pointer to the first span of list of spans in the current dimension */ + struct H5S_hyper_span_t *tail; /* Pointer to the last span of list of spans in the current dimension */ + hsize_t bounds[]; /* Array for storing low & high bounds */ + /* (NOTE: This uses the C99 "flexible array member" feature) */ }; +/* Enum for diminfo_valid field in H5S_hyper_sel_t */ +typedef enum { + H5S_DIMINFO_VALID_IMPOSSIBLE, /* 0: diminfo is not valid and can never be valid with the current selection */ + H5S_DIMINFO_VALID_NO, /* 1: diminfo is not valid but may or may not be possible to constuct */ + H5S_DIMINFO_VALID_YES /* 2: diminfo is valid */ +} H5S_diminfo_valid_t; + /* Information about 'diminfo' form of hyperslab selection */ typedef struct { - hbool_t diminfo_valid; /* Whether the dataset has valid diminfo */ - H5S_hyper_dim_t opt_diminfo[H5S_MAX_RANK]; /* per-dim selection info */ - H5S_hyper_dim_t app_diminfo[H5S_MAX_RANK]; /* per-dim selection info */ - /* 'opt_diminfo' points to a [potentially] optimized version of the user's - * hyperslab information. 'app_diminfo' points to the actual parameters - * that the application used for setting the hyperslab selection. These - * are only used for re-gurgitating the original values used to set the - * hyperslab to the application when it queries the hyperslab selection - * information. */ + /* 'opt' points to a [potentially] optimized version of the user's + * regular hyperslab information. 'app' points to the actual parameters + * that the application used for setting the hyperslab selection. + * + * The 'app' values are only used for regurgitating the original values + * used to set the hyperslab to the application when it queries the + * hyperslab selection information. + */ + H5S_hyper_dim_t app[H5S_MAX_RANK]; /* Application-set per-dim selection info */ + H5S_hyper_dim_t opt[H5S_MAX_RANK]; /* Optimized per-dim selection info */ + + /* The following two fields defines the bounding box of the diminfo selection */ + /* (relative to the offset) */ + hsize_t low_bounds[H5S_MAX_RANK]; /* The smallest element selected in each dimension */ + hsize_t high_bounds[H5S_MAX_RANK]; /* The largest element selected in each dimension */ +} H5S_hyper_diminfo_t; + +/* Information about hyperslab selection */ +typedef struct { + H5S_diminfo_valid_t diminfo_valid; /* Whether the dataset has valid diminfo */ + + H5S_hyper_diminfo_t diminfo; /* Dimension info form of hyperslab selection */ int unlim_dim; /* Dimension where selection is unlimited, or -1 if none */ hsize_t num_elem_non_unlim; /* # of elements in a "slice" excluding the unlimited dimension */ H5S_hyper_span_info_t *span_lst; /* List of hyperslab span information of all dimensions */ @@ -135,10 +183,6 @@ typedef struct { /* Selection information methods */ /* Method to copy a selection */ typedef herr_t (*H5S_sel_copy_func_t)(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -/* Method to retrieve a list of offset/length sequences for selection */ -typedef herr_t (*H5S_sel_get_seq_list_func_t)(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); /* Method to release current selection */ typedef herr_t (*H5S_sel_release_func_t)(H5S_t *space); /* Method to determine if current selection is valid for dataspace */ @@ -165,6 +209,8 @@ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space); typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space); /* Method to determine if current selection is "regular" */ typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space); +/* Method to determine if two dataspaces' selections are the same shape */ +typedef htri_t (*H5S_sel_shape_same_func_t)(const H5S_t *space1, const H5S_t *space2); /* Method to adjust a selection by an offset */ typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset); /* Method to construct single element projection onto scalar dataspace */ @@ -172,7 +218,7 @@ typedef herr_t (*H5S_sel_project_scalar)(const H5S_t *space, hsize_t *offset); /* Method to construct selection projection onto/into simple dataspace */ typedef herr_t (*H5S_sel_project_simple)(const H5S_t *space, H5S_t *new_space, hsize_t *offset); /* Method to initialize iterator for current selection */ -typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_sel_iter_t *sel_iter, const H5S_t *space); +typedef herr_t (*H5S_sel_iter_init_func_t)(const H5S_t *space, H5S_sel_iter_t *sel_iter); /* Selection class information */ typedef struct { @@ -180,7 +226,6 @@ typedef struct { /* Methods */ H5S_sel_copy_func_t copy; /* Method to make a copy of a selection */ - H5S_sel_get_seq_list_func_t get_seq_list; /* Method to retrieve a list of offset/length sequences for selection */ H5S_sel_release_func_t release; /* Method to release current selection */ H5S_sel_is_valid_func_t is_valid; /* Method to determine if current selection is valid for dataspace */ H5S_sel_serial_size_func_t serial_size; /* Method to determine number of bytes required to store current selection */ @@ -193,6 +238,7 @@ typedef struct { H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */ H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */ H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */ + H5S_sel_shape_same_func_t shape_same; /* Method to determine if two dataspaces' selections are the same shape */ H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */ H5S_sel_project_scalar project_scalar; /* Method to construct scalar dataspace projection */ H5S_sel_project_simple project_simple; /* Method to construct simple dataspace projection */ @@ -235,6 +281,10 @@ typedef htri_t (*H5S_sel_iter_has_next_block_func_t)(const H5S_sel_iter_t *iter) typedef herr_t (*H5S_sel_iter_next_func_t)(H5S_sel_iter_t *iter, size_t nelem); /* Method to move selection iterator to the next block in the selection */ typedef herr_t (*H5S_sel_iter_next_block_func_t)(H5S_sel_iter_t *iter); +/* Method to retrieve a list of offset/length sequences for selection iterator */ +typedef herr_t (*H5S_sel_iter_get_seq_list_func_t)(H5S_sel_iter_t *iter, + size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, + size_t *len); /* Method to release iterator for current selection */ typedef herr_t (*H5S_sel_iter_release_func_t)(H5S_sel_iter_t *iter); @@ -249,6 +299,7 @@ typedef struct H5S_sel_iter_class_t { H5S_sel_iter_has_next_block_func_t iter_has_next_block; /* Method to query if there is another block left in the selection */ H5S_sel_iter_next_func_t iter_next; /* Method to move selection iterator to the next element in the selection */ H5S_sel_iter_next_block_func_t iter_next_block; /* Method to move selection iterator to the next block in the selection */ + H5S_sel_iter_get_seq_list_func_t iter_get_seq_list; /* Method to retrieve a list of offset/length sequences for selection iterator */ H5S_sel_iter_release_func_t iter_release; /* Method to release iterator for current selection */ } H5S_sel_iter_class_t; @@ -281,14 +332,20 @@ H5_DLL herr_t H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max); /* Operations on hyperslab selections */ +H5_DLL uint64_t H5S__hyper_get_op_gen(void); +H5_DLL void H5S__hyper_rebuild(H5S_t *space); +H5_DLL herr_t H5S__modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2); H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, const H5S_t *src_intersect_space, H5S_t *proj_space); -H5_DLL herr_t H5S__hyper_subtract(H5S_t *space, H5S_t *subtract_space); /* Testing functions */ #ifdef H5S_TESTING H5_DLL htri_t H5S__select_shape_same_test(hid_t sid1, hid_t sid2); -H5_DLL htri_t H5S__get_rebuild_status_test(hid_t space_id); +H5_DLL herr_t H5S__get_rebuild_status_test(hid_t space_id, + H5S_diminfo_valid_t *status1, H5S_diminfo_valid_t *status2); +H5_DLL herr_t H5S__get_diminfo_status_test(hid_t space_id, + H5S_diminfo_valid_t *status); +H5_DLL htri_t H5S__internal_consistency_test(hid_t space_id); #endif /* H5S_TESTING */ #endif /*_H5Spkg_H*/ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 6411b94..2970a99 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -46,16 +46,22 @@ /* Local Typedefs */ /******************/ +/* Define alias for hsize_t, for allocating H5S_pnt_node_t + point objects */ +/* (Makes it easier to understand the alloc / free calls) */ +typedef hsize_t hcoords_t; + /********************/ /* Local Prototypes */ /********************/ +static herr_t H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, + const hsize_t *coord); +static H5S_pnt_list_t *H5S__copy_pnt_list(const H5S_pnt_list_t *src, + unsigned rank); +static void H5S__free_pnt_list(H5S_pnt_list_t *pnt_lst); /* Selection callbacks */ static herr_t H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); -static herr_t H5S__point_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__point_release(H5S_t *space); static htri_t H5S__point_is_valid(const H5S_t *space); static hssize_t H5S__point_serial_size(const H5S_t *space); @@ -68,11 +74,12 @@ static int H5S__point_unlim_dim(const H5S_t *space); static htri_t H5S__point_is_contiguous(const H5S_t *space); static htri_t H5S__point_is_single(const H5S_t *space); static htri_t H5S__point_is_regular(const H5S_t *space); +static htri_t H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2); static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); -static herr_t H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); +static herr_t H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter); /* Selection iteration callbacks */ static herr_t H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords); @@ -82,6 +89,8 @@ static hsize_t H5S__point_iter_nelmts(const H5S_sel_iter_t *iter); static htri_t H5S__point_iter_has_next_block(const H5S_sel_iter_t *iter); static herr_t H5S__point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); static herr_t H5S__point_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S__point_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); static herr_t H5S__point_iter_release(H5S_sel_iter_t *sel_iter); @@ -100,7 +109,6 @@ const H5S_select_class_t H5S_sel_point[1] = {{ /* Methods on selection */ H5S__point_copy, - H5S__point_get_seq_list, H5S__point_release, H5S__point_is_valid, H5S__point_serial_size, @@ -113,6 +121,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{ H5S__point_is_contiguous, H5S__point_is_single, H5S__point_is_regular, + H5S__point_shape_same, H5S__point_adjust_u, H5S__point_project_scalar, H5S__point_project_simple, @@ -135,11 +144,12 @@ static const H5S_sel_iter_class_t H5S_sel_iter_point[1] = {{ H5S__point_iter_has_next_block, H5S__point_iter_next, H5S__point_iter_next_block, + H5S__point_iter_get_seq_list, H5S__point_iter_release, }}; -/* Declare a free list to manage the H5S_pnt_node_t struct */ -H5FL_DEFINE_STATIC(H5S_pnt_node_t); +/* Declare a free list to manage the H5S_pnt_node_t + hcoords_t array struct */ +H5FL_BARR_DEFINE_STATIC(H5S_pnt_node_t, hcoords_t, H5S_MAX_RANK); /* Declare a free list to manage the H5S_pnt_list_t struct */ H5FL_DEFINE_STATIC(H5S_pnt_list_t); @@ -159,7 +169,7 @@ H5FL_DEFINE_STATIC(H5S_pnt_list_t); *------------------------------------------------------------------------- */ static herr_t -H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) +H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter) { FUNC_ENTER_STATIC_NOERR @@ -167,11 +177,11 @@ H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space)); HDassert(iter); - /* Initialize the number of points to iterate over */ - iter->elmt_left = space->select.num_elem; + /* Share point list for internal iterations */ + iter->u.pnt.pnt_lst = space->select.sel_info.pnt_lst; /* Start at the head of the list of points */ - iter->u.pnt.curr=space->select.sel_info.pnt_lst->head; + iter->u.pnt.curr = iter->u.pnt.pnt_lst->head; /* Initialize type of selection iterator */ iter->type = H5S_sel_iter_point; @@ -371,13 +381,11 @@ H5S__point_iter_next_block(H5S_sel_iter_t *iter) /*-------------------------------------------------------------------------- NAME - H5S__point_get_seq_list + H5S__point_iter_get_seq_list PURPOSE Create a list of offsets & lengths for a selection USAGE - herr_t H5S__point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len) - H5S_t *space; IN: Dataspace containing selection to use. - unsigned flags; IN: Flags for extra information about operation + herr_t H5S__point_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len) H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last position of interest in selection. size_t maxseq; IN: Maximum number of sequences to generate @@ -401,25 +409,22 @@ H5S__point_iter_next_block(H5S_sel_iter_t *iter) REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter, - size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, - hsize_t *off, size_t *len) +H5S__point_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem, + size_t *nseq, size_t *nelem, hsize_t *off, size_t *len) { size_t io_left; /* The number of bytes left in the selection */ size_t start_io_left; /* The initial number of bytes left in the selection */ H5S_pnt_node_t *node; /* Point node */ - hsize_t dims[H5S_MAX_RANK]; /* Total size of memory buf */ - int ndims; /* Dimensionality of space*/ + unsigned ndims; /* Dimensionality of dataspace*/ hsize_t acc; /* Coordinate accumulator */ hsize_t loc; /* Coordinate offset */ size_t curr_seq; /* Current sequence being operated on */ int i; /* Local index variable */ herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR /* Check args */ - HDassert(space); HDassert(iter); HDassert(maxseq > 0); HDassert(maxelem > 0); @@ -432,9 +437,8 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t); start_io_left = io_left = (size_t)MIN(iter->elmt_left, maxelem); - /* Get the dataspace dimensions */ - if((ndims = H5S_get_simple_extent_dims (space, dims, NULL)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve dataspace dimensions") + /* Get the dataspace's rank */ + ndims = iter->rank; /* Walk through the points in the selection, starting at the current */ /* location in the iterator */ @@ -442,15 +446,15 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter curr_seq = 0; while(NULL != node) { /* Compute the offset of each selected point in the buffer */ - for(i = ndims - 1, acc = iter->elmt_size, loc = 0; i >= 0; i--) { - loc += (hsize_t)((hssize_t)node->pnt[i] + space->select.offset[i]) * acc; - acc *= dims[i]; + for(i = (int)(ndims - 1), acc = iter->elmt_size, loc = 0; i >= 0; i--) { + loc += (hsize_t)((hssize_t)node->pnt[i] + iter->sel_off[i]) * acc; + acc *= iter->dims[i]; } /* end for */ /* Check if this is a later point in the selection */ if(curr_seq > 0) { /* If a sorted sequence is requested, make certain we don't go backwards in the offset */ - if((flags&H5S_GET_SEQ_LIST_SORTED) && locflags & H5S_SEL_ITER_GET_SEQ_LIST_SORTED) && loc < off[curr_seq - 1]) break; /* Check if this point extends the previous sequence */ @@ -502,9 +506,8 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter /* Set the number of elements used */ *nelem = start_io_left - io_left; -done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S__point_get_seq_list() */ +} /* end H5S__point_iter_get_seq_list() */ /*-------------------------------------------------------------------------- @@ -571,14 +574,14 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c HDassert(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND); for(u = 0; u < num_elem; u++) { + unsigned dim; /* Counter for dimensions */ + /* Allocate space for the new node */ - if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t))) + if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, space->extent.rank))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node") /* Initialize fields in node */ new_node->next = NULL; - if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(space->extent.rank * sizeof(hsize_t)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") /* Copy over the coordinates */ HDmemcpy(new_node->pnt, coord + (u * space->extent.rank), (space->extent.rank * sizeof(hsize_t))); @@ -589,6 +592,17 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c else curr->next = new_node; curr = new_node; + + /* Update bound box */ + /* (Note: when op is H5S_SELECT_SET, the bound box has been reset + * inside H5S_select_elements, the only caller of this function. + * So the following bound box update procedure works correctly + * for the SET operation) + */ + for(dim = 0; dim < space->extent.rank; dim++) { + space->select.sel_info.pnt_lst->low_bounds[dim] = MIN(space->select.sel_info.pnt_lst->low_bounds[dim], curr->pnt[dim]); + space->select.sel_info.pnt_lst->high_bounds[dim] = MAX(space->select.sel_info.pnt_lst->high_bounds[dim], curr->pnt[dim]); + } /* end for */ } /* end for */ new_node = NULL; @@ -600,20 +614,22 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c /* Put new list in point selection */ space->select.sel_info.pnt_lst->head = top; + + /* Change the tail pointer if tail has not been set */ + if(NULL == space->select.sel_info.pnt_lst->tail) + space->select.sel_info.pnt_lst->tail = curr; } /* end if */ else { /* op==H5S_SELECT_APPEND */ H5S_pnt_node_t *tmp_node; /* Temporary point selection node */ tmp_node = space->select.sel_info.pnt_lst->head; if(tmp_node != NULL) { - while(tmp_node->next != NULL) - tmp_node = tmp_node->next; - - /* Append new list to point selection */ - tmp_node->next = top; + HDassert(space->select.sel_info.pnt_lst->tail); + space->select.sel_info.pnt_lst->tail->next = top; } /* end if */ else space->select.sel_info.pnt_lst->head = top; + space->select.sel_info.pnt_lst->tail = curr; } /* end else */ /* Set the number of elements in the new selection */ @@ -626,13 +642,12 @@ done: if(ret_value < 0) { /* Release possibly partially initialized new node */ if(new_node) - new_node = H5FL_FREE(H5S_pnt_node_t, new_node); + new_node = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, new_node); /* Release possible linked list of nodes */ while(top) { - curr = top->next; - H5MM_xfree(top->pnt); - top = H5FL_FREE(H5S_pnt_node_t, top); + curr = top->next; + top = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, top); top = curr; } /* end while */ } /* end if */ @@ -661,24 +676,16 @@ done: static herr_t H5S__point_release(H5S_t *space) { - H5S_pnt_node_t *curr, *next; /* Point selection nodes */ - FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(space); - /* Delete all the nodes from the list */ - curr = space->select.sel_info.pnt_lst->head; - while(curr != NULL) { - next = curr->next; - H5MM_xfree(curr->pnt); - curr = H5FL_FREE(H5S_pnt_node_t, curr); - curr = next; - } /* end while */ + /* Free the point list */ + H5S__free_pnt_list(space->select.sel_info.pnt_lst); - /* Free & reset the point list header */ - space->select.sel_info.pnt_lst = H5FL_FREE(H5S_pnt_list_t, space->select.sel_info.pnt_lst); + /* Reset the point list header */ + space->select.sel_info.pnt_lst = NULL; /* Reset the number of elements in the selection */ space->select.num_elem = 0; @@ -734,10 +741,17 @@ H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release point selection") /* Allocate space for the point selection information if necessary */ - if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS || space->select.sel_info.pnt_lst == NULL) + if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS || space->select.sel_info.pnt_lst == NULL) { + hsize_t tmp = HSIZET_MAX; + if(NULL == (space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information") + /* Set the bound box to the default value */ + H5VM_array_fill(space->select.sel_info.pnt_lst->low_bounds, &tmp, sizeof(hsize_t), space->extent.rank); + HDmemset(space->select.sel_info.pnt_lst->high_bounds, 0, sizeof(hsize_t) * space->extent.rank); + } /* end if */ + /* Add points to selection */ if(H5S__point_add(space, op, num_elem, coord) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert elements") @@ -752,58 +766,56 @@ done: /*-------------------------------------------------------------------------- NAME - H5S__point_copy + H5S__copy_pnt_list PURPOSE - Copy a selection from one dataspace to another + Copy a point selection list USAGE - herr_t H5S__point_copy(dst, src, share_selection) - H5S_t *dst; OUT: Pointer to the destination dataspace - H5S_t *src; IN: Pointer to the source dataspace - hbool_t share_selection; IN: Whether to share the selection between the dataspaces + H5S_pnt_list_t *H5S__copy_pnt_list(src) + const H5S_pnt_list_t *src; IN: Pointer to the source point list + unsigned rank; IN: # of dimensions for points RETURNS - Non-negative on success/Negative on failure + Non-NULL pointer to new point list on success / NULL on failure DESCRIPTION - Copies all the point selection information from the source - dataspace to the destination dataspace. + Copies point selection information from the source point list to newly + created point list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t -H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection) +static H5S_pnt_list_t * +H5S__copy_pnt_list(const H5S_pnt_list_t *src, unsigned rank) { - H5S_pnt_node_t *curr, *new_node, *new_tail; /* Point information nodes */ - herr_t ret_value = SUCCEED; /* Return value */ + H5S_pnt_list_t *dst = NULL; /* New point list */ + H5S_pnt_node_t *curr, *new_tail; /* Point information nodes */ + H5S_pnt_list_t *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC /* Sanity checks */ HDassert(src); - HDassert(dst); + HDassert(rank > 0); /* Allocate room for the head of the point list */ - if(NULL == (dst->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node") + if(NULL == (dst = H5FL_MALLOC(H5S_pnt_list_t))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point list node") - curr = src->select.sel_info.pnt_lst->head; + curr = src->head; new_tail = NULL; while(curr) { + H5S_pnt_node_t *new_node; /* New point information node */ + /* Create new point */ - if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node") + if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, rank))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point node") new_node->next = NULL; - if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank * sizeof(hsize_t)))) { - new_node = H5FL_FREE(H5S_pnt_node_t, new_node); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") - } /* end if */ /* Copy over the point's coordinates */ - HDmemcpy(new_node->pnt, curr->pnt, (src->extent.rank * sizeof(hsize_t))); + HDmemcpy(new_node->pnt, curr->pnt, (rank * sizeof(hsize_t))); /* Keep the order the same when copying */ if(NULL == new_tail) - new_tail = dst->select.sel_info.pnt_lst->head = new_node; + new_tail = dst->head = new_node; else { new_tail->next = new_node; new_tail = new_node; @@ -811,22 +823,101 @@ H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selec curr = curr->next; } /* end while */ + dst->tail = new_tail; + + /* Copy the selection bounds */ + HDmemcpy(dst->high_bounds, src->high_bounds, (rank * sizeof(hsize_t))); + HDmemcpy(dst->low_bounds, src->low_bounds, (rank * sizeof(hsize_t))); + + /* Set return value */ + ret_value = dst; done: - if(ret_value < 0 && dst->select.sel_info.pnt_lst) { - /* Traverse the (incomplete?) dst list, freeing all memory */ - curr = dst->select.sel_info.pnt_lst->head; - while(curr) { - H5S_pnt_node_t *tmp_node = curr; - - curr->pnt = (hsize_t *)H5MM_xfree(curr->pnt); - curr = curr->next; - tmp_node = H5FL_FREE(H5S_pnt_node_t, tmp_node); - } /* end while */ + if(NULL == ret_value && dst) + H5S__free_pnt_list(dst); - dst->select.sel_info.pnt_lst = H5FL_FREE(H5S_pnt_list_t, dst->select.sel_info.pnt_lst); - } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__copy_pnt_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__free_pnt_list + PURPOSE + Free a point selection list + USAGE + void H5S__free_pnt_list(pnt_lst) + H5S_pnt_list_t *pnt_lst; IN: Pointer to the point list to free + RETURNS + None + DESCRIPTION + Frees point selection information from the point list + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5S__free_pnt_list(H5S_pnt_list_t *pnt_lst) +{ + H5S_pnt_node_t *curr; /* Point information nodes */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(pnt_lst); + + /* Traverse the list, freeing all memory */ + curr = pnt_lst->head; + while(curr) { + H5S_pnt_node_t *tmp_node = curr; + + curr = curr->next; + tmp_node = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, tmp_node); + } /* end while */ + + H5FL_FREE(H5S_pnt_list_t, pnt_lst); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__free_pnt_list() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__point_copy + PURPOSE + Copy a selection from one dataspace to another + USAGE + herr_t H5S__point_copy(dst, src, share_selection) + H5S_t *dst; OUT: Pointer to the destination dataspace + H5S_t *src; IN: Pointer to the source dataspace + hbool_t share_selection; IN: Whether to share the selection between the dataspaces + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Copies all the point selection information from the source + dataspace to the destination dataspace. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Sanity check */ + HDassert(src); + HDassert(dst); + + /* Allocate room for the head of the point list */ + if(NULL == (dst->select.sel_info.pnt_lst = H5S__copy_pnt_list(src->select.sel_info.pnt_lst, src->extent.rank))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy point list") + +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__point_copy() */ @@ -854,7 +945,6 @@ done: static htri_t H5S__point_is_valid(const H5S_t *space) { - H5S_pnt_node_t *curr; /* Point information nodes */ unsigned u; /* Counter */ htri_t ret_value = TRUE; /* Return value */ @@ -862,20 +952,14 @@ H5S__point_is_valid(const H5S_t *space) HDassert(space); - /* Check each point to determine whether selection+offset is within extent */ - curr = space->select.sel_info.pnt_lst->head; - while(curr != NULL) { - /* Check each dimension */ - for(u = 0; u < space->extent.rank; u++) { - /* Check if an offset has been defined */ - /* Bounds check the selected point + offset against the extent */ - if(((curr->pnt[u] + (hsize_t)space->select.offset[u]) > space->extent.size[u]) - || (((hssize_t)curr->pnt[u] + space->select.offset[u]) < 0)) - HGOTO_DONE(FALSE) - } /* end for */ - - curr = curr->next; - } /* end while */ + /* Check each dimension */ + for(u = 0; u < space->extent.rank; u++) { + /* Bounds check the selected point + offset against the extent */ + if((space->select.sel_info.pnt_lst->high_bounds[u] + (hsize_t)space->select.offset[u]) > space->extent.size[u]) + HGOTO_DONE(FALSE) + if(((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]) < 0) + HGOTO_DONE(FALSE) + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1258,8 +1342,6 @@ done: static herr_t H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) { - H5S_pnt_node_t *node; /* Point node */ - unsigned rank; /* Dataspace rank */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1270,30 +1352,19 @@ H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) HDassert(start); HDassert(end); - /* Get the dataspace extent rank */ - rank = space->extent.rank; - - /* Set the start and end arrays up */ - for(u = 0; u < rank; u++) { - start[u] = HSIZET_MAX; - end[u] = 0; - } /* end for */ + /* Loop over dimensions */ + for(u = 0; u < space->extent.rank; u++) { + /* Sanity check */ + HDassert(space->select.sel_info.pnt_lst->low_bounds[u] <= space->select.sel_info.pnt_lst->high_bounds[u]); - /* Iterate through the node, checking the bounds on each element */ - node = space->select.sel_info.pnt_lst->head; - while(node != NULL) { - for(u = 0; u < rank; u++) { - /* Check for offset moving selection negative */ - if(((hssize_t)node->pnt[u] + space->select.offset[u]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + /* Check for offset moving selection negative */ + if(((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") - if(start[u] > (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u])) - start[u] = (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]); - if(end[u] < (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u])) - end[u] = (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]); - } /* end for */ - node = node->next; - } /* end while */ + /* Set the low & high bounds in this dimension */ + start[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]); + end[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->high_bounds[u] + space->select.offset[u]); + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1513,6 +1584,114 @@ H5S__point_is_regular(const H5S_t *space) /*-------------------------------------------------------------------------- NAME + H5S__point_shape_same + PURPOSE + Check if a two "point" selections are the same shape + USAGE + htri_t H5S__point_shape_same(space1, space2) + const H5S_t *space1; IN: First dataspace to check + const H5S_t *space2; IN: Second dataspace to check + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in each dataspace are the same + shape. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2) +{ + H5S_pnt_node_t *pnt1, *pnt2; /* Point information nodes */ + hssize_t offset[H5S_MAX_RANK]; /* Offset between the selections */ + unsigned space1_rank; /* Number of dimensions of first dataspace */ + unsigned space2_rank; /* Number of dimensions of second dataspace */ + int space1_dim; /* Current dimension in first dataspace */ + int space2_dim; /* Current dimension in second dataspace */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Check args */ + HDassert(space1); + HDassert(space2); + + /* Get dataspace ranks */ + space1_rank = space1->extent.rank; + space2_rank = space2->extent.rank; + + /* Sanity check */ + HDassert(space1_rank >= space2_rank); + HDassert(space2_rank > 0); + + /* Initialize dimensions */ + space1_dim = (int)space1_rank - 1; + space2_dim = (int)space2_rank - 1; + + /* Look at first point in each selection to compute the offset for common + * dimensions. + */ + pnt1 = space1->select.sel_info.pnt_lst->head; + pnt2 = space2->select.sel_info.pnt_lst->head; + while(space2_dim >= 0) { + /* Set the relative locations of the selections */ + offset[space1_dim] = (hssize_t)pnt2->pnt[space2_dim] - (hssize_t)pnt1->pnt[space1_dim]; + + space1_dim--; + space2_dim--; + } /* end while */ + + /* For dimensions that appear only in space1: */ + while(space1_dim >= 0) { + /* Set the absolute offset of the remaining dimensions */ + offset[space1_dim] = (hssize_t)pnt1->pnt[space1_dim]; + + space1_dim--; + } /* end while */ + + /* Advance to next point */ + pnt1 = pnt1->next; + pnt2 = pnt2->next; + + /* Loop over remaining points */ + while(pnt1 && pnt2) { + /* Initialize dimensions */ + space1_dim = (int)space1_rank - 1; + space2_dim = (int)space2_rank - 1; + + /* Compare locations in common dimensions, including relative offset */ + while(space2_dim >= 0) { + if((hsize_t)((hssize_t)pnt1->pnt[space1_dim] + offset[space1_dim]) != pnt2->pnt[space2_dim]) + HGOTO_DONE(FALSE) + + space1_dim--; + space2_dim--; + } /* end while */ + + /* For dimensions that appear only in space1: */ + while(space1_dim >= 0) { + /* Compare the absolute offset in the remaining dimensions */ + if((hssize_t)pnt1->pnt[space1_dim] != offset[space1_dim]) + HGOTO_DONE(FALSE) + + space1_dim--; + } /* end while */ + + + /* Advance to next point */ + pnt1 = pnt1->next; + pnt2 = pnt2->next; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__point_shape_same() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__point_adjust_u PURPOSE Adjust a "point" selection by subtracting an offset @@ -1534,6 +1713,7 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset) { H5S_pnt_node_t *node; /* Point node */ unsigned rank; /* Dataspace rank */ + unsigned u; /* Local index variable */ FUNC_ENTER_STATIC_NOERR @@ -1544,8 +1724,6 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset) node = space->select.sel_info.pnt_lst->head; rank = space->extent.rank; while(node) { - unsigned u; /* Local index variable */ - /* Adjust each coordinate for point node */ for(u = 0; u < rank; u++) { /* Check for offset moving selection negative */ @@ -1559,6 +1737,12 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset) node = node->next; } /* end while */ + /* update the bound box of the selection */ + for(u = 0; u < rank; u++) { + space->select.sel_info.pnt_lst->low_bounds[u] -= offset[u]; + space->select.sel_info.pnt_lst->high_bounds[u] -= offset[u]; + } /* end for */ + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5S__point_adjust_u() */ @@ -1623,6 +1807,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of H5S_pnt_node_t *new_node; /* Point node in new space */ H5S_pnt_node_t *prev_node; /* Previous point node in new space */ unsigned rank_diff; /* Difference in ranks between spaces */ + unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1657,13 +1842,9 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of prev_node = NULL; while(base_node) { /* Create new point */ - if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t))) + if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node") new_node->next = NULL; - if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) { - new_node = H5FL_FREE(H5S_pnt_node_t, new_node); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") - } /* end if */ /* Copy over the point's coordinates */ HDmemcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t))); @@ -1679,6 +1860,12 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of /* Advance to next node */ base_node = base_node->next; } /* end while */ + + /* Update the bounding box */ + for(u = 0; u < new_space->extent.rank; u++) { + new_space->select.sel_info.pnt_lst->low_bounds[u] = base_space->select.sel_info.pnt_lst->low_bounds[u + rank_diff]; + new_space->select.sel_info.pnt_lst->high_bounds[u] = base_space->select.sel_info.pnt_lst->high_bounds[u + rank_diff]; + } /* end for */ } /* end if */ else { HDassert(new_space->extent.rank > base_space->extent.rank); @@ -1694,13 +1881,9 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of prev_node = NULL; while(base_node) { /* Create new point */ - if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t))) + if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node") new_node->next = NULL; - if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) { - new_node = H5FL_FREE(H5S_pnt_node_t, new_node); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") - } /* end if */ /* Copy over the point's coordinates */ HDmemset(new_node->pnt, 0, sizeof(hsize_t) * rank_diff); @@ -1717,6 +1900,16 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of /* Advance to next node */ base_node = base_node->next; } /* end while */ + + /* Update the bounding box */ + for(u = 0; u < rank_diff; u++) { + new_space->select.sel_info.pnt_lst->low_bounds[u] = 0; + new_space->select.sel_info.pnt_lst->high_bounds[u] = 0; + } /* end for */ + for(; u < new_space->extent.rank; u++) { + new_space->select.sel_info.pnt_lst->low_bounds[u] = base_space->select.sel_info.pnt_lst->low_bounds[u - rank_diff]; + new_space->select.sel_info.pnt_lst->high_bounds[u] = base_space->select.sel_info.pnt_lst->high_bounds[u - rank_diff]; + } /* end for */ } /* end else */ /* Number of elements selected will be the same */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index f4e0006..6646f84 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -39,12 +39,10 @@ #define H5S_CONV_STORAGE_CHUNKED 0x0004 /* i.e. '2' */ #define H5S_CONV_STORAGE_MASK 0x0006 -/* Flags for "get_seq_list" methods */ -#define H5S_GET_SEQ_LIST_SORTED 0x0001 - /* Forward references of package typedefs */ typedef struct H5S_extent_t H5S_extent_t; typedef struct H5S_pnt_node_t H5S_pnt_node_t; +typedef struct H5S_pnt_list_t H5S_pnt_list_t; typedef struct H5S_hyper_span_t H5S_hyper_span_t; typedef struct H5S_hyper_span_info_t H5S_hyper_span_info_t; @@ -58,6 +56,7 @@ typedef struct H5S_hyper_dim_t { /* Point selection iteration container */ typedef struct { + H5S_pnt_list_t *pnt_lst; /* Pointer to point list */ H5S_pnt_node_t *curr; /* Pointer to next node to output */ } H5S_point_iter_t; @@ -65,6 +64,7 @@ typedef struct { typedef struct { /* Common fields for all hyperslab selections */ hsize_t off[H5S_MAX_RANK]; /* Offset in span node (used as position for regular hyperslabs) */ + hsize_t slab[H5S_MAX_RANK]; /* Cumulative size of each dimension in bytes */ unsigned iter_rank; /* Rank of iterator information */ /* (This should always be the same as the dataspace * rank, except for regular hyperslab selections in @@ -80,6 +80,7 @@ typedef struct { hbool_t flattened[H5S_MAX_RANK]; /* Whether this dimension has been flattened */ /* Irregular hyperslab selection fields */ + hsize_t loc_off[H5S_MAX_RANK]; /* Byte offset in buffer, for each dimension's current offset */ H5S_hyper_span_info_t *spans; /* Pointer to copy of the span tree */ H5S_hyper_span_t *span[H5S_MAX_RANK];/* Array of pointers to span nodes */ } H5S_hyper_iter_t; @@ -100,9 +101,11 @@ typedef struct H5S_sel_iter_t { /* Information common to all iterators */ unsigned rank; /* Rank of dataspace the selection iterator is operating on */ - hsize_t *dims; /* Dimensions of dataspace the selection is operating on */ + hsize_t dims[H5S_MAX_RANK]; /* Dimensions of dataspace the selection is operating on */ + hssize_t sel_off[H5S_MAX_RANK]; /* Selection offset in dataspace */ hsize_t elmt_left; /* Number of elements left to iterate over */ size_t elmt_size; /* Size of elements to iterate over */ + unsigned flags; /* Flags controlling iterator behavior */ /* Information specific to each type of iterator */ union { @@ -142,7 +145,6 @@ typedef struct H5S_sel_iter_op_t { #define H5S_GET_EXTENT_NPOINTS(S) ((S)->extent.nelem) #define H5S_GET_SELECT_NPOINTS(S) ((S)->select.num_elem) #define H5S_GET_SELECT_TYPE(S) ((S)->select.type->type) -#define H5S_SELECT_GET_SEQ_LIST(S,FLAGS,ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN) ((*(S)->select.type->get_seq_list)(S,FLAGS,ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN)) #define H5S_SELECT_VALID(S) ((*(S)->select.type->is_valid)(S)) #define H5S_SELECT_SERIAL_SIZE(S) ((*(S)->select.type->serial_size)(S)) #define H5S_SELECT_SERIALIZE(S,BUF) ((*(S)->select.type->serialize)(S,BUF)) @@ -160,6 +162,7 @@ typedef struct H5S_sel_iter_op_t { #define H5S_SELECT_ITER_HAS_NEXT_BLOCK(ITER) ((*(ITER)->type->iter_has_next_block)(ITER)) #define H5S_SELECT_ITER_NEXT(ITER,NELEM)((*(ITER)->type->iter_next)(ITER,NELEM)) #define H5S_SELECT_ITER_NEXT_BLOCK(ITER) ((*(ITER)->type->iter_next_block)(ITER)) +#define H5S_SELECT_ITER_GET_SEQ_LIST(ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN) ((*(ITER)->type->iter_get_seq_list)(ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN)) #define H5S_SELECT_ITER_RELEASE(ITER) ((*(ITER)->type->iter_release)(ITER)) #else /* H5S_MODULE */ #define H5S_GET_EXTENT_TYPE(S) (H5S_get_simple_extent_type(S)) @@ -167,7 +170,6 @@ typedef struct H5S_sel_iter_op_t { #define H5S_GET_EXTENT_NPOINTS(S) (H5S_get_simple_extent_npoints(S)) #define H5S_GET_SELECT_NPOINTS(S) (H5S_get_select_npoints(S)) #define H5S_GET_SELECT_TYPE(S) (H5S_get_select_type(S)) -#define H5S_SELECT_GET_SEQ_LIST(S,FLAGS,ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN) (H5S_select_get_seq_list(S,FLAGS,ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN)) #define H5S_SELECT_VALID(S) (H5S_select_valid(S)) #define H5S_SELECT_SERIAL_SIZE(S) (H5S_select_serial_size(S)) #define H5S_SELECT_SERIALIZE(S,BUF) (H5S_select_serialize(S,BUF)) @@ -185,6 +187,7 @@ typedef struct H5S_sel_iter_op_t { #define H5S_SELECT_ITER_HAS_NEXT_BLOCK(ITER) (H5S_select_iter_has_next_block(ITER)) #define H5S_SELECT_ITER_NEXT(ITER,NELEM)(H5S_select_iter_next(ITER,NELEM)) #define H5S_SELECT_ITER_NEXT_BLOCK(ITER) (H5S_select_iter_next_block(ITER)) +#define H5S_SELECT_ITER_GET_SEQ_LIST(ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN) (H5S_select_iter_get_seq_list(ITER,MAXSEQ,MAXBYTES,NSEQ,NBYTES,OFF,LEN)) #define H5S_SELECT_ITER_RELEASE(ITER) (H5S_select_iter_release(ITER)) #endif /* H5S_MODULE */ /* Handle these callbacks in a special way, since they have prologs that need to be executed */ @@ -253,9 +256,6 @@ H5_DLL herr_t H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank, const void *buf, void const **adj_buf_ptr, hsize_t element_size); H5_DLL herr_t H5S_select_release(H5S_t *ds); -H5_DLL herr_t H5S_select_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); H5_DLL hssize_t H5S_select_serial_size(const H5S_t *space); H5_DLL herr_t H5S_select_serialize(const H5S_t *space, uint8_t **p); H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space); @@ -282,10 +282,11 @@ H5_DLL herr_t H5S_select_elements(H5S_t *space, H5S_seloper_t op, /* Operations on hyperslab selections */ H5_DLL herr_t H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[], const hsize_t *stride, const hsize_t count[], const hsize_t *block); +H5_DLL herr_t H5S_combine_hyperslab(H5S_t *old_space, H5S_seloper_t op, + const hsize_t start[], const hsize_t *stride, const hsize_t count[], + const hsize_t *block, H5S_t **new_space); H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords); -H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space); -H5_DLL herr_t H5S_hyper_convert(H5S_t *space); H5_DLL htri_t H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end); H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset); H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); @@ -302,11 +303,14 @@ H5_DLL hsize_t H5S_hyper_get_first_inc_block(const H5S_t *space, /* Operations on selection iterators */ H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, - size_t elmt_size); + size_t elmt_size, unsigned flags); H5_DLL herr_t H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords); H5_DLL hsize_t H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter); H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +H5_DLL herr_t H5S_select_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, + size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len); H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter); +H5_DLL herr_t H5S_sel_iter_close(H5S_sel_iter_t *sel_iter); #ifdef H5_HAVE_PARALLEL H5_DLL hsize_t H5S_mpio_set_bigio_count(hsize_t new_count); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 561875a..a65ce71 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -28,6 +28,23 @@ /* Define user-level maximum number of dimensions */ #define H5S_MAX_RANK 32 +/* Flags for selection iterators */ +#define H5S_SEL_ITER_GET_SEQ_LIST_SORTED 0x0001 /* Retrieve elements from iterator + * in increasing offset order, for + * each call to retrieve sequences. + * Currently, this only applies to + * point selections, as hyperslab + * selections are always returned + * in increasing offset order. + * + * Note that the order is only + * increasing for each call to + * get_seq_list, the next set of + * sequences could start with an + * earlier offset than the previous + * one. + */ + /* Different types of dataspaces */ typedef enum H5S_class_t { H5S_NO_CLASS = -1, /*error */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 24586de..d4ca1c7 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -32,7 +32,6 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ #include "H5Spkg.h" /* Dataspaces */ #include "H5VMprivate.h" /* Vector and array functions */ @@ -998,7 +997,9 @@ H5S_select_is_regular(const H5S_t *space) herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset) { - herr_t ret_value = FAIL; /* Return value */ + hbool_t non_zero_offset = FALSE; /* Whether any offset is non-zero */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -1006,7 +1007,16 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset) HDassert(space); HDassert(offset); - ret_value = (*space->select.type->adjust_u)(space, offset); + /* Check for an all-zero offset vector */ + for(u = 0; u < space->extent.rank; u++) + if(0 != offset[u]) { + non_zero_offset = TRUE; + break; + } /* end if */ + + /* Only perform operation if the offset is non-zero */ + if(non_zero_offset) + ret_value = (*space->select.type->adjust_u)(space, offset); FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_select_adjust_u() */ @@ -1098,11 +1108,12 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset) PURPOSE Initializes iteration information for a selection. USAGE - herr_t H5S_select_iter_init(sel_iter, space, elmt_size) + herr_t H5S_select_iter_init(sel_iter, space, elmt_size, flags) H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize. H5S_t *space; IN: Dataspace object containing selection to iterate over size_t elmt_size; IN: Size of elements in the selection + unsigned flags; IN: Flags to control iteration behavior RETURNS Non-negative on success, negative on failure. DESCRIPTION @@ -1110,7 +1121,8 @@ H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset) in the dataspace's selection. --------------------------------------------------------------------------*/ herr_t -H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size) +H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, + size_t elmt_size, unsigned flags) { herr_t ret_value = FAIL; /* Return value */ @@ -1125,17 +1137,23 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s /* Save the dataspace's rank */ sel_iter->rank = space->extent.rank; - /* Point to the dataspace dimensions, if there are any */ - if(sel_iter->rank > 0) - sel_iter->dims = space->extent.size; - else - sel_iter->dims = NULL; + /* If dims > 0, copy the dataspace dimensions & selection offset */ + if(sel_iter->rank > 0) { + HDmemcpy(sel_iter->dims, space->extent.size, sizeof(hsize_t) * space->extent.rank); + HDmemcpy(sel_iter->sel_off, space->select.offset, sizeof(hsize_t) * space->extent.rank); + } /* end if */ /* Save the element size */ sel_iter->elmt_size = elmt_size; + /* Initialize the number of elements to iterate over */ + sel_iter->elmt_left = space->select.num_elem; + + /* Set the flags for the iterator */ + sel_iter->flags = flags; + /* Call initialization routine for selection type */ - ret_value = (*space->select.type->iter_init)(sel_iter, space); + ret_value = (*space->select.type->iter_init)(space, sel_iter); HDassert(sel_iter->type); FUNC_LEAVE_NOAPI(ret_value) @@ -1389,7 +1407,7 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter) /*------------------------------------------------------------------------- - * Function: H5S_select_get_seq_list + * Function: H5S_select_iter_get_seq_list * * Purpose: Retrieves the next sequence of offset/length pairs for an * iterator on a dataspace @@ -1406,24 +1424,23 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter) *------------------------------------------------------------------------- */ herr_t -H5S_select_get_seq_list(const H5S_t *space, unsigned flags, - H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, - size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len) +H5S_select_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelmts, + size_t *nseq, size_t *nelmts, hsize_t *off, size_t *len) { herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ - HDassert(space); + HDassert(iter); /* Call the selection type's get_seq_list function */ - if((ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len)) < 0) + if((ret_value = (*iter->type->iter_get_seq_list)(iter, maxseq, maxelmts, nseq, nelmts, off, len)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_select_get_seq_list() */ +} /* end H5S_select_iter_get_seq_list() */ /*-------------------------------------------------------------------------- @@ -1524,7 +1541,7 @@ H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator") /* Initialize iterator */ - if(H5S_select_iter_init(iter, space, elmt_size) < 0) + if(H5S_select_iter_init(iter, space, elmt_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -1558,7 +1575,7 @@ H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, size_t curr_seq; /* Current sequence being worked on */ /* Get the sequences of bytes */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Loop, while sequences left to process */ @@ -1729,7 +1746,6 @@ H5S_get_select_type(const H5S_t *space) This is primarily used for reading the entire selection in one swoop. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - Assumes that there is only a single "block" for hyperslab selections. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ @@ -1759,6 +1775,10 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) const H5S_t *space_b; /* Dataspace with smaller rank */ unsigned space_a_rank; /* Number of dimensions of dataspace A */ unsigned space_b_rank; /* Number of dimensions of dataspace B */ + int space_a_dim; /* Current dimension in dataspace A */ + int space_b_dim; /* Current dimension in dataspace B */ + H5S_sel_type sel_a_type; /* Selection type for dataspace A */ + H5S_sel_type sel_b_type; /* Selection type for dataspace B */ /* Need to be able to handle spaces of different rank: * @@ -1776,106 +1796,77 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) */ if(space1->extent.rank >= space2->extent.rank) { space_a = space1; - space_a_rank = space_a->extent.rank; - space_b = space2; - space_b_rank = space_b->extent.rank; } /* end if */ else { space_a = space2; - space_a_rank = space_a->extent.rank; - space_b = space1; - space_b_rank = space_b->extent.rank; } /* end else */ + space_a_rank = space_a->extent.rank; + space_b_rank = space_b->extent.rank; HDassert(space_a_rank >= space_b_rank); HDassert(space_b_rank > 0); - /* Check for "easy" cases before getting into generalized block iteration code */ - if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_ALL) && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_ALL)) { - hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */ - hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */ - int space_a_dim; /* Current dimension in dataspace A */ - int space_b_dim; /* Current dimension in dataspace B */ + /* Get selection type for both dataspaces */ + sel_a_type = H5S_GET_SELECT_TYPE(space_a); + sel_b_type = H5S_GET_SELECT_TYPE(space_b); - if(H5S_get_simple_extent_dims(space_a, dims1, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality") - if(H5S_get_simple_extent_dims(space_b, dims2, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality") + /* If selections aren't "none", compare their bounds */ + if(sel_a_type != H5S_SEL_NONE && sel_b_type != H5S_SEL_NONE) { + hsize_t low_a[H5S_MAX_RANK]; /* Low bound of selection in dataspace a */ + hsize_t low_b[H5S_MAX_RANK]; /* Low bound of selection in dataspace b */ + hsize_t high_a[H5S_MAX_RANK]; /* High bound of selection in dataspace a */ + hsize_t high_b[H5S_MAX_RANK]; /* High bound of selection in dataspace b */ - space_a_dim = (int)space_a_rank - 1; - space_b_dim = (int)space_b_rank - 1; - - /* recall that space_a_rank >= space_b_rank. - * - * In the following while loop, we test to see if space_a and space_b - * have identical size in all dimensions they have in common. - */ - while(space_b_dim >= 0) { - if(dims1[space_a_dim] != dims2[space_b_dim]) - HGOTO_DONE(FALSE) - - space_a_dim--; - space_b_dim--; - } /* end while */ - - /* Since we are selecting the entire space, we must also verify that space_a - * has size 1 in all dimensions that it does not share with space_b. - */ - while(space_a_dim >= 0) { - if(dims1[space_a_dim] != 1) - HGOTO_DONE(FALSE) - - space_a_dim--; - } /* end while */ - } /* end if */ - else if((H5S_GET_SELECT_TYPE(space1) == H5S_SEL_NONE) || (H5S_GET_SELECT_TYPE(space2) == H5S_SEL_NONE)) { - /* (Both must be, at this point, if one is) */ - HGOTO_DONE(TRUE) - } /* end if */ - else if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_HYPERSLABS && space_a->select.sel_info.hslab->diminfo_valid) - && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_HYPERSLABS && space_b->select.sel_info.hslab->diminfo_valid)) { - int space_a_dim; /* Current dimension in dataspace A */ - int space_b_dim; /* Current dimension in dataspace B */ + /* Get low & high bounds for both dataspaces */ + if(H5S_SELECT_BOUNDS(space_a, low_a, high_a) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for first dataspace") + if(H5S_SELECT_BOUNDS(space_b, low_b, high_b) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for second dataspace") + /* Check that the range between the low & high bounds are the same */ space_a_dim = (int)space_a_rank - 1; space_b_dim = (int)space_b_rank - 1; - - /* check that the shapes are the same in the common dimensions, and that - * block == 1 in all dimensions that appear only in space_a. - */ while(space_b_dim >= 0) { - if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].stride != - space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].stride) - HGOTO_DONE(FALSE) - - if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].count != - space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].count) - HGOTO_DONE(FALSE) + /* Sanity check */ + HDassert(low_a[space_a_dim] <= high_a[space_a_dim]); + HDassert(low_a[space_b_dim] <= high_a[space_b_dim]); - if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != - space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].block) + /* Verify that the ranges are the same */ + if((high_a[space_a_dim] - low_a[space_a_dim]) + != (high_b[space_b_dim] - low_b[space_b_dim])) HGOTO_DONE(FALSE) + /* Go to next dimension */ space_a_dim--; space_b_dim--; } /* end while */ + /* Check that the rest of the ranges in space a are "flat" */ while(space_a_dim >= 0) { - if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != 1) + /* Sanity check */ + HDassert(low_a[space_a_dim] <= high_a[space_a_dim]); + + /* This range should be flat to be the same in a lower dimension */ + if(low_a[space_a_dim] != high_a[space_a_dim]) HGOTO_DONE(FALSE) space_a_dim--; } /* end while */ } /* end if */ - /* Iterate through all the blocks in the selection */ + + /* If the dataspaces have the same selection type, use the selection's + * shape_same operator. + */ + if(sel_a_type == sel_b_type) + ret_value = (*space_a->select.type->shape_same)(space_a, space_b); + /* Otherwise, iterate through all the blocks in the selection */ else { hsize_t start_a[H5S_MAX_RANK]; /* Start point of selection block in dataspace a */ hsize_t start_b[H5S_MAX_RANK]; /* Start point of selection block in dataspace b */ hsize_t end_a[H5S_MAX_RANK]; /* End point of selection block in dataspace a */ hsize_t end_b[H5S_MAX_RANK]; /* End point of selection block in dataspace b */ - hsize_t off_a[H5S_MAX_RANK]; /* Offset of selection a blocks */ - hsize_t off_b[H5S_MAX_RANK]; /* Offset of selection b blocks */ + hssize_t offset[H5S_MAX_RANK]; /* Offset of selection b blocks relative to selection a blocks */ hbool_t first_block = TRUE; /* Flag to indicate the first block */ /* Allocate the selection iterators */ @@ -1889,17 +1880,15 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) * that the selection iterator shouldn't be "flattened", since we * aren't actually going to be doing I/O with the iterators. */ - if(H5S_select_iter_init(iter_a, space_a, (size_t)0) < 0) + if(H5S_select_iter_init(iter_a, space_a, (size_t)0, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a") iter_a_init = TRUE; - if(H5S_select_iter_init(iter_b, space_b, (size_t)0) < 0) + if(H5S_select_iter_init(iter_b, space_b, (size_t)0, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b") iter_b_init = TRUE; /* Iterate over all the blocks in each selection */ while(1) { - int space_a_dim; /* Current dimension in dataspace A */ - int space_b_dim; /* Current dimension in dataspace B */ htri_t status_a, status_b; /* Status from next block checks */ /* Get the current block for each selection iterator */ @@ -1924,8 +1913,7 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) HGOTO_DONE(FALSE) /* Set the relative locations of the selections */ - off_a[space_a_dim] = start_a[space_a_dim]; - off_b[space_b_dim] = start_b[space_b_dim]; + offset[space_a_dim] = (hssize_t)start_b[space_b_dim] - (hssize_t)start_a[space_a_dim]; space_a_dim--; space_b_dim--; @@ -1935,12 +1923,9 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) * in space_a is not equal to 1, get out. */ while(space_a_dim >= 0) { - if((end_a[space_a_dim] - start_a[space_a_dim]) != 0) + if(start_a[space_a_dim] != end_a[space_a_dim]) HGOTO_DONE(FALSE) - /* Set the relative locations of the selections */ - off_a[space_a_dim] = start_a[space_a_dim]; - space_a_dim--; } /* end while */ @@ -1952,8 +1937,7 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) /* For dimensions that space_a and space_b have in common: */ while(space_b_dim >= 0) { /* Check if the blocks are in the same relative location */ - if((start_a[space_a_dim] - off_a[space_a_dim]) != - (start_b[space_b_dim] - off_b[space_b_dim])) + if((hsize_t)((hssize_t)start_a[space_a_dim] + offset[space_a_dim]) != start_b[space_b_dim]) HGOTO_DONE(FALSE) /* If the block sizes from each selection doesn't match, get out */ @@ -1968,7 +1952,7 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2) /* For dimensions that appear only in space_a: */ while(space_a_dim >= 0) { /* If the block size isn't 1, get out */ - if((end_a[space_a_dim] - start_a[space_a_dim]) != 0) + if(start_a[space_a_dim] != end_a[space_a_dim]) HGOTO_DONE(FALSE) space_a_dim--; @@ -2329,7 +2313,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator") /* Initialize iterator */ - if(H5S_select_iter_init(iter, space, fill_size) < 0) + if(H5S_select_iter_init(iter, space, fill_size, 0) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") iter_init = TRUE; /* Selection iteration info has been initialized */ @@ -2353,7 +2337,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b size_t nelem; /* Number of elements used in sequences */ /* Get the sequences of bytes */ - if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) + if(H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed") /* Loop over sequences */ @@ -2528,12 +2512,13 @@ H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) if(H5S_select_none(space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection") } /* end if */ + /* If either selection is a point selection, fail currently */ + else if((subtract_space->select.type->type == H5S_SEL_POINTS) || + (space->select.type->type == H5S_SEL_POINTS)) { + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") + } /* end if */ else { - /* Check for point selection in subtract_space, convert to hyperslab */ - if(subtract_space->select.type->type == H5S_SEL_POINTS) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") - - /* Check for point or all selection in space, convert to hyperslab */ + /* Check for all selection in space, convert to hyperslab */ if(space->select.type->type == H5S_SEL_ALL) { /* Convert current "all" selection to "real" hyperslab selection */ /* Then allow operation to proceed */ @@ -2555,14 +2540,12 @@ H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) if(H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") } /* end if */ - else if(space->select.type->type == H5S_SEL_POINTS) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") HDassert(space->select.type->type == H5S_SEL_HYPERSLABS); HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS); /* Both spaces are now hyperslabs, perform the operation */ - if(H5S__hyper_subtract(space, subtract_space) < 0) + if(H5S__modify_select(space, H5S_SELECT_NOTB, subtract_space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab") } /* end else */ } /* end if */ diff --git a/src/H5Stest.c b/src/H5Stest.c index 50f5fa9..2c42713 100644 --- a/src/H5Stest.c +++ b/src/H5Stest.c @@ -112,12 +112,18 @@ done: NAME H5S__get_rebuild_status_test PURPOSE - Determine the status of hyperslab rebuild + Determine the status of the diminfo_valid field (whether we know the + selection information for an equivalent single hyperslab selection) + before and after calling H5S__hyper_rebuild. USAGE - htri_t H5S__get_rebuild_status_test(hid_t space_id) + herr_t H5S__get_rebuild_status_test(space_id, status1, status2) hid_t space_id; IN: dataspace id + H5S_diminfo_valid_t *status1; OUT: status before calling + H5S__hyper_rebuild + H5S_diminfo_valid_t *status2; OUT: status after calling + H5S__hyper_rebuild RETURNS - Non-negative TRUE/FALSE on success, negative on failure + Non-negative on success, negative on failure DESCRIPTION Query the status of rebuilding the hyperslab GLOBAL VARIABLES @@ -126,21 +132,283 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -htri_t -H5S__get_rebuild_status_test(hid_t space_id) +herr_t +H5S__get_rebuild_status_test(hid_t space_id, H5S_diminfo_valid_t *status1, + H5S_diminfo_valid_t *status2) { H5S_t *space; /* Pointer to 1st dataspace */ - htri_t ret_value = FAIL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE + HDassert(status1); + HDassert(status2); + /* Get dataspace structures */ if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - ret_value = (htri_t)space->select.sel_info.hslab->diminfo_valid; + *status1 = space->select.sel_info.hslab->diminfo_valid; + + /* Fully rebuild diminfo, if necessary */ + if(*status1 == H5S_DIMINFO_VALID_NO) + H5S__hyper_rebuild(space); + + *status2 = space->select.sel_info.hslab->diminfo_valid; done: FUNC_LEAVE_NOAPI(ret_value) } /* H5S__get_rebuild_status_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5S__get_diminfo_status_test + PURPOSE + Determine the status of the diminfo_valid field (whether we know the + selection information for an equivalent single hyperslab selection) + USAGE + herr_t H5S__get_diminfo_status_test(space_id, status) + hid_t space_id; IN: dataspace id + H5S_diminfo_valid_t *status; OUT: status of diminfo_valid + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Query the status of rebuilding the hyperslab + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S__get_diminfo_status_test(hid_t space_id, H5S_diminfo_valid_t *status) +{ + H5S_t *space; /* Pointer to 1st dataspace */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + HDassert(status); + + /* Get dataspace structures */ + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + *status = space->select.sel_info.hslab->diminfo_valid; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S__get_diminfo_status_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5S__check_spans_tail_ptr + PURPOSE + Determine if the tail pointer of the spans are correctly set + USAGE + herr_t H5S__check_spans_tail_ptr(span_lst) + const H5S_hyper_span_info_t *span_lst; IN: the spans to check for taill pointers + RETURNS + SUCCEED/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspaces has tail pointers of each + dimension correctly set. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Only check the hyperslab selection + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__check_spans_tail_ptr(const H5S_hyper_span_info_t *span_lst) +{ + H5S_hyper_span_t *cur_elem; + H5S_hyper_span_t *actual_tail = NULL; + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(span_lst); + + cur_elem = span_lst->head; + while(cur_elem) { + actual_tail = cur_elem; + + /* check the next dimension of lower order */ + if(NULL != cur_elem->down) + if((ret_value = H5S__check_spans_tail_ptr(cur_elem->down)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers") + + cur_elem = cur_elem->next; + } /* end while */ + if(actual_tail != span_lst->tail) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S__check_spans_tail_ptr */ + +/*-------------------------------------------------------------------------- + NAME + H5S__check_points_tail_ptr + PURPOSE + Determine if the tail pointer of the points list are correctly set + USAGE + herr_t H5S__check_points_tail_ptr(pnt_lst) + const H5S_pnt_list_t *pnt_lst; IN: the points list to check for taill pointers + RETURNS + SUCCEED/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspaces has tail pointers correctly set. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Only check the points selection + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__check_points_tail_ptr(const H5S_pnt_list_t *pnt_lst) +{ + H5S_pnt_node_t *cur_elem; + H5S_pnt_node_t *actual_tail = NULL; + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC + + HDassert(pnt_lst); + + cur_elem = pnt_lst->head; + while(cur_elem) { + actual_tail = cur_elem; + cur_elem = cur_elem->next; + } /* end while */ + if(actual_tail != pnt_lst->tail) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S__check_points_tail_ptr */ + + +/*-------------------------------------------------------------------------- + NAME + H5S__check_internal_consistency + PURPOSE + Determine if internal data structures are consistent + USAGE + herr_t H5S__check_internal_consistency(space) + const H5S_t *space; IN: 1st Dataspace pointer to compare + RETURNS + SUCCEED/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspaces has consistent + state of internal data structure. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Currently only check the hyperslab selection + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S__check_internal_consistency(const H5S_t *space) +{ + hsize_t low_bounds[H5S_MAX_RANK]; + hsize_t high_bounds[H5S_MAX_RANK]; + unsigned u; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + HDassert(space); + + if(space->select.type->type == H5S_SEL_NONE) + HGOTO_DONE(ret_value); + + /* Initialize the inputs */ + for(u = 0; u < space->extent.rank; u++) { + low_bounds[u] = HSIZET_MAX; + high_bounds[u] = 0; + } /* end for */ + + /* Check the bound box */ + if(H5S_get_select_bounds(space, low_bounds, high_bounds) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the bound box could not be retrieved") + + if(space->select.type->type == H5S_SEL_HYPERSLABS) { + H5S_hyper_sel_t *hslab = space->select.sel_info.hslab; + + if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { + for(u = 0; u < space->extent.rank; u++) { + if((hsize_t)((hssize_t)hslab->diminfo.low_bounds[u] + space->select.offset[u]) != low_bounds[u]) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the lower bound box of the selection is inconsistent") + if((hsize_t)((hssize_t)hslab->diminfo.high_bounds[u] + space->select.offset[u]) != high_bounds[u]) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the higher bound box of the selection is inconsistent") + } /* end for */ + } /* end if */ + else { + for(u = 0; u < space->extent.rank; u++) { + if((hsize_t)((hssize_t)hslab->span_lst->low_bounds[u] + space->select.offset[u]) != low_bounds[u]) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the lower bound box of the selection is inconsistent") + if((hsize_t)((hssize_t)hslab->span_lst->high_bounds[u] + space->select.offset[u]) != high_bounds[u]) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the higher bound box of the selection is inconsistent") + } /* end for */ + } /* end else */ + + /* check the tail pointer */ + if((NULL != hslab) && (NULL != hslab->span_lst)) + if(H5S__check_spans_tail_ptr(hslab->span_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers") + } /* end if */ + else if(space->select.type->type == H5S_SEL_POINTS) { + H5S_pnt_list_t *pnt_lst = space->select.sel_info.pnt_lst; + + if(NULL != pnt_lst) + if(H5S__check_points_tail_ptr(pnt_lst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "the seletion has inconsistent tail pointers") + } /* end else-if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S__check_internal_consistency */ + +/*-------------------------------------------------------------------------- + NAME + H5S__internal_consistency_test + PURPOSE + Determine if states of internal data structures are consistent + USAGE + htri_t H5S__internal_consistency_test(hid_t space_id) + hid_t space_id; IN: dataspace id + RETURNS + Non-negative TRUE/FALSE on success, negative on failure + DESCRIPTION + Check the states of internal data structures of the hyperslab, and see + whether they are consistent or not + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S__internal_consistency_test(hid_t space_id) +{ + H5S_t *space; /* Pointer to 1st dataspace */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Get dataspace structures */ + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Check if the dataspace selections are the same shape */ + if(FAIL == H5S__check_internal_consistency(space)) + HGOTO_ERROR(H5E_DATASPACE, H5E_INCONSISTENTSTATE, FAIL, "The dataspace has inconsistent internal state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S__internal_consistency_test() */ + diff --git a/src/H5TS.c b/src/H5TS.c index 10e14d5..f386421 100644 --- a/src/H5TS.c +++ b/src/H5TS.c @@ -35,6 +35,7 @@ H5TS_once_t H5TS_first_init_g = PTHREAD_ONCE_INIT; H5TS_key_t H5TS_errstk_key_g; H5TS_key_t H5TS_funcstk_key_g; H5TS_key_t H5TS_apictx_key_g; +H5TS_key_t H5TS_hyper_op_gen_key_g; H5TS_key_t H5TS_cancel_key_g; @@ -113,6 +114,9 @@ H5TS_pthread_first_thread_init(void) /* initialize key for thread-specific API contexts */ pthread_key_create(&H5TS_apictx_key_g, H5TS_key_destructor); + /* initialize key for thread-specific hyperslab operation generation */ + pthread_key_create(&H5TS_hyper_op_gen_key_g, H5TS_key_destructor); + /* initialize key for thread cancellability mechanism */ pthread_key_create(&H5TS_cancel_key_g, H5TS_key_destructor); } @@ -362,6 +366,9 @@ H5TS_win32_process_enter(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContex) if(TLS_OUT_OF_INDEXES == (H5TS_apictx_key_g = TlsAlloc())) ret_value = FALSE; + if(TLS_OUT_OF_INDEXES == (H5TS_hyper_op_gen_key_g = TlsAlloc())) + ret_value = FALSE; + return ret_value; } /* H5TS_win32_process_enter() */ #endif /* H5_HAVE_WIN_THREADS */ @@ -431,6 +438,7 @@ H5TS_win32_process_exit(void) TlsFree(H5TS_funcstk_key_g); #endif /* H5_HAVE_CODESTACK */ TlsFree(H5TS_apictx_key_g); + TlsFree(H5TS_hyper_op_gen_key_g); return; } /* H5TS_win32_process_exit() */ @@ -479,6 +487,10 @@ H5TS_win32_thread_exit(void) if(lpvData) LocalFree((HLOCAL)lpvData); + lpvData = TlsGetValue(H5TS_hyper_op_gen_key_g); + if(lpvData) + LocalFree((HLOCAL)lpvData); + return ret_value; } /* H5TS_win32_thread_exit() */ #endif /* H5_HAVE_WIN_THREADS */ diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h index 9e093a6..94791bc 100644 --- a/src/H5TSprivate.h +++ b/src/H5TSprivate.h @@ -110,6 +110,7 @@ extern H5TS_once_t H5TS_first_init_g; extern H5TS_key_t H5TS_errstk_key_g; extern H5TS_key_t H5TS_funcstk_key_g; extern H5TS_key_t H5TS_apictx_key_g; +extern H5TS_key_t H5TS_hyper_op_gen_key_g; #if defined c_plusplus || defined __cplusplus extern "C" diff --git a/src/H5err.txt b/src/H5err.txt index 93a3abd..4eedc0f 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -226,6 +226,7 @@ MINOR, DSPACE, H5E_CANTSELECT, Can't select hyperslab MINOR, DSPACE, H5E_CANTNEXT, Can't move to next iterator location MINOR, DSPACE, H5E_BADSELECT, Invalid selection MINOR, DSPACE, H5E_CANTCOMPARE, Can't compare objects +MINOR, DSPACE, H5E_INCONSISTENTSTATE, Internal states are inconsistent MINOR, DSPACE, H5E_CANTAPPEND, Can't append object # Property list errors diff --git a/test/tselect.c b/test/tselect.c index 424c144..842fe17 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -157,6 +157,12 @@ #define SPACERE5_DIM3 12 #define SPACERE5_DIM4 8 +/* Information for Space update diminfo test */ +#define SPACEUD1_DIM0 20 +#define SPACEUD3_DIM0 9 +#define SPACEUD3_DIM1 12 +#define SPACEUD3_DIM2 13 + /* #defines for shape same / different rank tests */ #define SS_DR_MAX_RANK 5 @@ -11489,7 +11495,8 @@ test_space_rebuild(void) hid_t sid_irreg1,sid_irreg2,sid_irreg3,sid_irreg4,sid_irreg5; /* rebuild status state */ - htri_t rebuild_stat,rebuild_check; + H5S_diminfo_valid_t rebuild_stat1,rebuild_stat2; + htri_t rebuild_check; herr_t ret; /* dimensions of rank 1 to rank 5 */ @@ -11558,19 +11565,23 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_reg1,H5S_SELECT_OR,start1,stride1,count1,block1); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_reg1); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_reg1,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - } - else { + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(ret != FAIL) { /* In this case, rebuild_check should be TRUE. */ rebuild_check = H5S__select_shape_same_test(sid_reg1,sid_reg_ori1); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); - } + } /* end if */ /* For irregular hyperslab */ sid_irreg1 = H5Screate_simple(SPACERE1_RANK,dims1,NULL); @@ -11590,14 +11601,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_irreg1,H5S_SELECT_OR,start1,stride1,count1,block1); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_irreg1); - assert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_irreg1,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ MESSAGE(7, ("Testing functionality to rebuild 2-D hyperslab selection\n")); @@ -11637,19 +11653,23 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_reg2,H5S_SELECT_OR,start2,stride2,count2,block2); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_reg2); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_reg2,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - } - else { + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(ret != FAIL) { /* In this case, rebuild_check should be TRUE. */ rebuild_check = H5S__select_shape_same_test(sid_reg2,sid_reg_ori2); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); - } + } /* end if */ /* 2-D irregular case */ sid_irreg2 = H5Screate_simple(SPACERE2_RANK,dims2,NULL); @@ -11674,14 +11694,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_irreg2,H5S_SELECT_OR,start2,stride2,count2,block2); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_irreg2); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_irreg2,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ MESSAGE(7, ("Testing functionality to rebuild 3-D hyperslab selection\n")); @@ -11726,20 +11751,23 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_reg3,H5S_SELECT_OR,start3,stride3,count3,block3); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_reg3); - HDassert(rebuild_stat!=FAIL); - - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_reg3,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - } - else { + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(ret != FAIL) { /* In this case, rebuild_check should be TRUE. */ rebuild_check = H5S__select_shape_same_test(sid_reg3,sid_reg_ori3); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); - } + } /* end if */ sid_irreg3 = H5Screate_simple(SPACERE3_RANK,dims3,NULL); @@ -11769,14 +11797,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_irreg3,H5S_SELECT_OR,start3,stride3,count3,block3); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_irreg3); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_irreg3,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ MESSAGE(7, ("Testing functionality to rebuild 4-D hyperslab selection\n")); @@ -11829,19 +11862,23 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_reg4); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_reg4,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - } - else { + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(ret != FAIL) { /* In this case, rebuild_check should be TRUE. */ rebuild_check = H5S__select_shape_same_test(sid_reg4,sid_reg_ori4); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); - } + } /* end if */ /* Testing irregular selection */ sid_irreg4 = H5Screate_simple(SPACERE4_RANK,dims4,NULL); @@ -11882,14 +11919,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_irreg4,H5S_SELECT_OR,start4,stride4,count4,block4); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_irreg4); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_irreg4,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ MESSAGE(7, ("Testing functionality to rebuild 5-D hyperslab selection\n")); @@ -11946,19 +11988,23 @@ test_space_rebuild(void) CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_reg5); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_reg5,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - } - else { + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(ret != FAIL) { /* In this case, rebuild_check should be TRUE. */ rebuild_check = H5S__select_shape_same_test(sid_reg5,sid_reg_ori5); CHECK(rebuild_check,FALSE,"H5S_hyper_rebuild"); - } + } /* end if */ sid_irreg5 = H5Screate_simple(SPACERE5_RANK,dims5,NULL); @@ -12004,14 +12050,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_irreg5,H5S_SELECT_OR,start5,stride5,count5,block5); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_irreg5); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_irreg5,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ /* We use 5-D to test a special case with rebuilding routine TRUE, FALSE and TRUE */ @@ -12045,13 +12096,20 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_spec,H5S_SELECT_SET,start5,stride5,count5,block5); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_spec); - /* In this case, rebuild_stat should be TRUE. */ - if(!rebuild_stat){ + + ret = H5S__get_rebuild_status_test(sid_spec,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 and rebuild_stat2 should both be + * H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ /* Adding some selections to make it real irregular */ start5[3] = 1; @@ -12067,14 +12125,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_spec,H5S_SELECT_OR,start5,stride5,count5,block5); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = TRUE; - rebuild_stat = H5S__get_rebuild_status_test(sid_spec); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_spec,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_IMPOSSIBLE. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_IMPOSSIBLE) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ /* Add more selections to make it regular again */ start5[3] = 5; @@ -12090,14 +12153,19 @@ test_space_rebuild(void) ret = H5Sselect_hyperslab(sid_spec,H5S_SELECT_OR,start5,stride5,count5,block5); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - rebuild_stat = FALSE; - rebuild_stat = H5S__get_rebuild_status_test(sid_spec); - HDassert(rebuild_stat!=FAIL); - /* In this case, rebuild_stat should be FALSE. */ - if(!rebuild_stat){ + ret = H5S__get_rebuild_status_test(sid_spec,&rebuild_stat1,&rebuild_stat2); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + /* In this case, rebuild_stat1 should be H5S_DIMINFO_VALID_NO and + * rebuild_stat2 should be H5S_DIMINFO_VALID_YES. */ + if(rebuild_stat1 != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret,FAIL,"H5S_hyper_rebuild"); + } /* end if */ + if(rebuild_stat2 != H5S_DIMINFO_VALID_YES) { ret = FAIL; CHECK(ret,FAIL,"H5S_hyper_rebuild"); - }/* No need to do shape comparision */ + } /* end if */ + /* No need to do shape comparision */ H5Sclose(sid_reg1); CHECK(ret, FAIL, "H5Sclose"); @@ -12131,1113 +12199,2257 @@ test_space_rebuild(void) /**************************************************************** ** -** test_select_hyper_chunk_offset(): Tests selections on dataspace, -** verify that offsets for hyperslab selections are working in -** chunked datasets. +** test_space_update_diminfo(): Tests selection diminfo update +** routine. We will test whether regular selections can be +** quickly updated when the selection is modified. +** ** ****************************************************************/ static void -test_select_hyper_chunk_offset(void) +test_space_update_diminfo(void) { - hid_t fid; /* File ID */ - hid_t sid; /* Dataspace ID */ - hid_t msid; /* Memory dataspace ID */ - hid_t did; /* Dataset ID */ - const hsize_t mem_dims[1] = { SPACE10_DIM1 }; /* Dataspace dimensions for memory */ - const hsize_t dims[1] = { 0 }; /* Dataspace initial dimensions */ - const hsize_t maxdims[1] = { H5S_UNLIMITED }; /* Dataspace mam dims */ - int *wbuf; /* Buffer for writing data */ - int *rbuf; /* Buffer for reading data */ - hid_t dcpl; /* Dataset creation property list ID */ - hsize_t chunks[1]={SPACE10_CHUNK_SIZE }; /* Chunk size */ - hsize_t start[1] = { 0 }; /* The start of the hyperslab */ - hsize_t count[1] = { SPACE10_CHUNK_SIZE }; /* The size of the hyperslab */ - int i,j; /* Local index */ - herr_t ret; /* Generic return value */ + hid_t space_id; /* Dataspace id */ + H5S_diminfo_valid_t diminfo_valid; /* Diminfo status */ + H5S_diminfo_valid_t rebuild_status; /* Diminfo status after rebuid */ + H5S_sel_type sel_type; /* Selection type */ + herr_t ret; /* Return value */ - /* Output message about test being performed */ - MESSAGE(6, ("Testing hyperslab selections using offsets in chunked datasets\n")); + /* dimensions of rank 1 to rank 5 */ + hsize_t dims1[] ={SPACEUD1_DIM0}; + hsize_t dims3[] ={SPACEUD3_DIM0, SPACEUD3_DIM1, SPACEUD3_DIM2}; - /* Allocate buffers */ - wbuf = (int *)HDmalloc(sizeof(int) * SPACE10_DIM1); - CHECK_PTR(wbuf, "HDmalloc"); - rbuf = (int *)HDcalloc(sizeof(int), SPACE10_DIM1); - CHECK_PTR(rbuf, "HDcalloc"); + /* The start of the hyperslab */ + hsize_t start1[1], start3[3]; - /* Initialize the write buffer */ - for(i=0; i=((2*SPACE10_CHUNK_SIZE)/3)) - if(wbuf[i+j]!=rbuf[((SPACE10_DIM1-i)-SPACE10_CHUNK_SIZE)+j]) - TestErrPrintf("Line: %d - Error! i=%d, j=%d, rbuf=%d, wbuf=%d\n",__LINE__,i,j,rbuf[((SPACE10_DIM1-i)-SPACE10_CHUNK_SIZE)+j],wbuf[i+j]); + /* Add differently size block immediately after current, with OR */ + start1[0] = 7; + count1[0] = 1; + block1[0] = 7; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Close the memory dataspace */ - ret=H5Sclose (msid); - CHECK(ret, FAIL, "H5Sclose"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Close the dataset */ - ret=H5Dclose (did); - CHECK(ret, FAIL, "H5Dclose"); + /* + * Test adding overlapping blocks + */ - /* Close the file */ - ret=H5Fclose (fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Create single block */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Free the buffers */ - HDfree(wbuf); - HDfree(rbuf); -} /* test_select_hyper_chunk_offset() */ + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ -/**************************************************************** -** -** test_select_hyper_chunk_offset2(): Tests selections on dataspace, -** another test to verify that offsets for hyperslab selections are -** working in chunked datasets. -** -****************************************************************/ -static void -test_select_hyper_chunk_offset2(void) -{ - hid_t file, dataset; /* handles */ - hid_t dataspace; - hid_t memspace; - hid_t dcpl; /* Dataset creation property list */ - herr_t status; - unsigned data_out[SPACE12_DIM0]; /* output buffer */ - unsigned data_in[SPACE12_CHUNK_DIM0]; /* input buffer */ - hsize_t dims[SPACE12_RANK]={SPACE12_DIM0}; /* Dimension size */ - hsize_t chunk_dims[SPACE12_RANK]={SPACE12_CHUNK_DIM0}; /* Chunk size */ - hsize_t start[SPACE12_RANK]; /* Start of hyperslab */ - hsize_t count[SPACE12_RANK]; /* Size of hyperslab */ - hssize_t offset[SPACE12_RANK]; /* hyperslab offset in the file */ - unsigned u, v; /* Local index variables */ + /* Add block completely overlapping first, with OR */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Output message about test being performed */ - MESSAGE(6, ("Testing more hyperslab selections using offsets in chunked datasets\n")); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Initialize data to write out */ - for (u = 0; u < SPACE12_DIM0; u++) - data_out[u] = u; + /* Add block parially overlapping first, with OR */ + start1[0] = 4; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Create the file */ - file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(file, FAIL, "H5Fcreate"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Create dataspace */ - dataspace = H5Screate_simple(SPACE12_RANK, dims, NULL); - CHECK(dataspace, FAIL, "H5Screate_simple"); + /* Add block completely enclosing current, with OR */ + start1[0] = 2; + count1[0] = 1; + block1[0] = 5; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Create dataset creation property list */ - dcpl = H5Pcreate(H5P_DATASET_CREATE); - CHECK(dcpl, FAIL, "H5Pcreate"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set chunk sizes */ - status = H5Pset_chunk(dcpl, SPACE12_RANK, chunk_dims); - CHECK(status, FAIL, "H5Pset_chunk"); + /* Add block completely enclosed by current, with OR */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Create dataset */ - dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_UINT, dataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); - CHECK(dataset, FAIL, "H5Dcreate2"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Close DCPL */ - status = H5Pclose(dcpl); - CHECK(status, FAIL, "H5Pclose"); + /* Add equally sized block parially overlapping current, with XOR */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 5; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_XOR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Write out entire dataset */ - status = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_out); - CHECK(status, FAIL, "H5Dclose"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Create memory dataspace (same size as a chunk) */ - memspace = H5Screate_simple(SPACE12_RANK, chunk_dims, NULL); - CHECK(dataspace, FAIL, "H5Screate_simple"); + /* Fill in hole in block */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 4; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* - * Define hyperslab in the file dataspace. - */ - start[0] = 0; - count[0] = SPACE12_CHUNK_DIM0; - status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, NULL, count, NULL); - CHECK(status, FAIL, "H5Sselect_hyperslab"); + /* diminfo_valid should be NO, after rebuild it should be YES */ + ret = H5S__get_rebuild_status_test(space_id, &diminfo_valid, + &rebuild_status); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + if(rebuild_status != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_rebuild"); + } /* end if */ - /* Loop through retrieving data from file, checking it against data written */ - for(u = 0; u < SPACE12_DIM0; u += SPACE12_CHUNK_DIM0) { - /* Set the offset of the file selection */ - offset[0] = u; - status = H5Soffset_simple(dataspace, offset); - CHECK(status, FAIL, "H5Soffset_simple"); + /* Add differently sized block parially overlapping current, with XOR */ + start1[0] = 4; + count1[0] = 1; + block1[0] = 5; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_XOR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Read in buffer of data */ - status = H5Dread(dataset, H5T_NATIVE_UINT, memspace, dataspace, - H5P_DEFAULT, data_in); - CHECK(status, FAIL, "H5Dread"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Check data read in */ - for(v = 0; v < SPACE12_CHUNK_DIM0; v++) - if(data_out[u + v] != data_in[v]) - TestErrPrintf("Error! data_out[%u]=%u, data_in[%u]=%u\n",(unsigned)(u + v), data_out[u + v], v, data_in[v]); - } /* end for */ + /* Fill in hole in block */ + start1[0] = 4; + count1[0] = 1; + block1[0] = 4; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - status = H5Dclose(dataset); - CHECK(status, FAIL, "H5Dclose"); + /* diminfo_valid should be NO, after rebuild it should be YES */ + ret = H5S__get_rebuild_status_test(space_id, &diminfo_valid, + &rebuild_status); + CHECK(ret, FAIL, "H5S__get_rebuild_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + if(rebuild_status != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_rebuild"); + } /* end if */ - status = H5Sclose(dataspace); - CHECK(status, FAIL, "H5Sclose"); + /* Add block completely overlapping current, with XOR */ + start1[0] = 2; + count1[0] = 1; + block1[0] = 7; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_XOR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - status = H5Sclose(memspace); - CHECK(status, FAIL, "H5Sclose"); + sel_type = H5Sget_select_type(space_id); + VERIFY(sel_type, H5S_SEL_NONE, "H5Sget_select_type"); - status = H5Fclose(file); - CHECK(status, FAIL, "H5Fclose"); -} /* test_select_hyper_chunk_offset2() */ + /* + * Test various conditions that break the fast algorithm + */ -/**************************************************************** -** -** test_select_bounds(): Tests selection bounds on dataspaces, -** both with and without offsets. -** -****************************************************************/ -static void -test_select_bounds(void) -{ - hid_t sid; /* Dataspace ID */ - const hsize_t dims[SPACE11_RANK] = {SPACE11_DIM1, SPACE11_DIM2}; /* Dataspace dimensions */ - hsize_t coord[SPACE11_NPOINTS][SPACE11_RANK]; /* Coordinates for point selection */ - hsize_t start[SPACE11_RANK]; /* The start of the hyperslab */ - hsize_t stride[SPACE11_RANK]; /* The stride between block starts for the hyperslab */ - hsize_t count[SPACE11_RANK]; /* The number of blocks for the hyperslab */ - hsize_t block[SPACE11_RANK]; /* The size of each block for the hyperslab */ - hssize_t offset[SPACE11_RANK]; /* Offset amount for selection */ - hsize_t low_bounds[SPACE11_RANK]; /* The low bounds for the selection */ - hsize_t high_bounds[SPACE11_RANK]; /* The high bounds for the selection */ - herr_t ret; /* Generic return value */ + /* Create multiple blocks */ + start1[0] = 3; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Output message about test being performed */ - MESSAGE(6, ("Testing selection bounds\n")); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Create dataspace */ - sid = H5Screate_simple (SPACE11_RANK, dims, NULL); - CHECK(sid, FAIL, "H5Screate_simple"); + /* Create single block with start out of phase */ + start1[0] = 8; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for 'all' selection */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set offset for selection */ - offset[0] = 1; offset[1] = 1; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create multiple blocks */ + start1[0] = 3; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for 'all' selection with offset (which should be ignored) */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Reset offset for selection */ - offset[0] = 0; offset[1] = 0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create multiple blocks with start out of phase */ + start1[0] = 8; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Set 'none' selection */ - ret = H5Sselect_none(sid); - CHECK(ret, FAIL, "H5Sselect_none"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Get bounds for 'none' selection */ - H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bo unds"); + /* Create multiple blocks */ + start1[0] = 3; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Set point selection */ - coord[0][0] = 3; coord[0][1] = 3; - coord[1][0] = 3; coord[1][1] = 96; - coord[2][0] = 96; coord[2][1] = 3; - coord[3][0] = 96; coord[3][1] = 96; - ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE11_NPOINTS, (const hsize_t *)coord); - CHECK(ret, FAIL, "H5Sselect_elements"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Get bounds for point selection */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 3, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 3, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], SPACE11_DIM1 - 4, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], SPACE11_DIM2 - 4, "H5Sget_select_bounds"); + /* Create multiple blocks with wrong stride */ + start1[0] = 9; + stride1[0] = 4; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Set bad offset for selection */ - offset[0] = 5; offset[1] = -5; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Get bounds for hyperslab selection with negative offset */ - H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bounds"); + /* Create single block */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Set valid offset for selection */ - offset[0] = 2; offset[1] = -2; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Get bounds for point selection with offset */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 5, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 1, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], SPACE11_DIM1 - 2, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], SPACE11_DIM2 - 6, "H5Sget_select_bounds"); + /* Create single block with wrong size */ + start1[0] = 6; + count1[0] = 1; + block1[0] = 1; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Reset offset for selection */ - offset[0] = 0; offset[1] = 0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set "regular" hyperslab selection */ - start[0] = 2; start[1] = 2; - stride[0] = 10; stride[1] = 10; - count[0] = 4; count[1] = 4; - block[0] = 5; block[1] = 5; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + /* Create single block */ + start1[0] = 3; + count1[0] = 1; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, NULL, count1, block1); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for hyperslab selection */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], 36, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], 36, "H5Sget_select_bounds"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set bad offset for selection */ - offset[0] = 5; offset[1] = -5; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create multiple blocks with wrong size */ + start1[0] = 6; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 1; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for hyperslab selection with negative offset */ - H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bounds"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set valid offset for selection */ - offset[0] = 5; offset[1] = -2; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create multiple blocks */ + start1[0] = 3; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for hyperslab selection with offset */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], 41, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], 34, "H5Sget_select_bounds"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Reset offset for selection */ - offset[0] = 0; offset[1] = 0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create single block with wrong size */ + start1[0] = 9; + count1[0] = 1; + block1[0] = 1; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, NULL, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Make "irregular" hyperslab selection */ - start[0] = 20; start[1] = 20; - stride[0] = 20; stride[1] = 20; - count[0] = 2; count[1] = 2; - block[0] = 10; block[1] = 10; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Create multiple blocks */ + start1[0] = 3; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start1, stride1, count1, block1); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for hyperslab selection */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], 49, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], 49, "H5Sget_select_bounds"); + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set bad offset for selection */ - offset[0] = 5; offset[1] = -5; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create multiple blocks with wrong size */ + start1[0] = 9; + stride1[0] = 3; + count1[0] = 2; + block1[0] = 1; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start1, stride1, count1, block1); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Get bounds for hyperslab selection with negative offset */ - H5E_BEGIN_TRY { - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Sget_select_bounds"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ - /* Set valid offset for selection */ - offset[0] = 5; offset[1] = -2; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + ret = H5Sclose(space_id); + CHECK(ret, FAIL, "H5Sclose"); - /* Get bounds for hyperslab selection with offset */ - ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); - VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); - VERIFY(high_bounds[0], 54, "H5Sget_select_bounds"); - VERIFY(high_bounds[1], 47, "H5Sget_select_bounds"); - /* Reset offset for selection */ - offset[0] = 0; offset[1] = 0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + MESSAGE(7, ("Testing functionality to update 3-D hyperslab dimension info\n")); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); -} /* test_select_bounds() */ + /* Create 3-D dataspace */ + space_id = H5Screate_simple(3, dims3, NULL); + + /* Create multiple blocks */ + start3[0] = 0; + start3[1] = 1; + start3[2] = 2; + stride3[0] = 2; + stride3[1] = 3; + stride3[2] = 4; + count3[0] = 4; + count3[1] = 3; + count3[2] = 2; + block3[0] = 1; + block3[1] = 2; + block3[2] = 3; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Add blocks with same values in all dimensions */ + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Add blocks with same values in two dimensions */ + start3[0] = 8; + stride3[0] = 1; + count3[0] = 1; + block3[0] = 1; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Create multiple blocks */ + start3[0] = 0; + start3[1] = 1; + start3[2] = 2; + stride3[0] = 2; + stride3[1] = 3; + stride3[2] = 4; + count3[0] = 4; + count3[1] = 3; + count3[2] = 2; + block3[0] = 1; + block3[1] = 2; + block3[2] = 3; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Add blocks with same values in one dimension */ + start3[0] = 8; + start3[1] = 10; + stride3[0] = 1; + stride3[1] = 1; + count3[0] = 1; + count3[1] = 1; + block3[0] = 1; + block3[1] = 2; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Create multiple blocks */ + start3[0] = 0; + start3[1] = 1; + start3[2] = 2; + stride3[0] = 2; + stride3[1] = 3; + stride3[2] = 4; + count3[0] = 4; + count3[1] = 3; + count3[2] = 2; + block3[0] = 1; + block3[1] = 2; + block3[2] = 3; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_SET, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* diminfo_valid should be YES */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_YES) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + /* Add blocks with same values in no dimensions */ + start3[0] = 8; + start3[1] = 10; + start3[2] = 10; + stride3[0] = 1; + stride3[1] = 1; + stride3[2] = 1; + count3[0] = 1; + count3[1] = 1; + count3[2] = 1; + block3[0] = 1; + block3[1] = 2; + block3[2] = 3; + ret = H5Sselect_hyperslab(space_id, H5S_SELECT_OR, start3, stride3, count3, block3); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + /* diminfo_valid should be NO */ + ret = H5S__get_diminfo_status_test(space_id, &diminfo_valid); + CHECK(ret, FAIL, "H5S__get_diminfo_status_test"); + if(diminfo_valid != H5S_DIMINFO_VALID_NO) { + ret = FAIL; + CHECK(ret, FAIL, "H5S_hyper_update_diminfo"); + } /* end if */ + + ret = H5Sclose(space_id); + CHECK(ret, FAIL, "H5Sclose"); +} /* end test_space_update_diminfo() */ + /**************************************************************** ** -** test_hyper_regular(): Tests query operations on regular hyperslabs +** test_select_hyper_chunk_offset(): Tests selections on dataspace, +** verify that offsets for hyperslab selections are working in +** chunked datasets. ** ****************************************************************/ static void -test_hyper_regular(void) +test_select_hyper_chunk_offset(void) { + hid_t fid; /* File ID */ hid_t sid; /* Dataspace ID */ - const hsize_t dims[SPACE13_RANK] = {SPACE13_DIM1, SPACE13_DIM2, SPACE13_DIM3}; /* Dataspace dimensions */ - hsize_t coord[SPACE13_NPOINTS][SPACE13_RANK]; /* Coordinates for point selection */ - hsize_t start[SPACE13_RANK]; /* The start of the hyperslab */ - hsize_t stride[SPACE13_RANK]; /* The stride between block starts for the hyperslab */ - hsize_t count[SPACE13_RANK]; /* The number of blocks for the hyperslab */ - hsize_t block[SPACE13_RANK]; /* The size of each block for the hyperslab */ - hsize_t t_start[SPACE13_RANK]; /* Temporary start of the hyperslab */ - hsize_t t_count[SPACE13_RANK]; /* Temporary number of blocks for the hyperslab */ - hsize_t q_start[SPACE13_RANK]; /* The queried start of the hyperslab */ - hsize_t q_stride[SPACE13_RANK]; /* The queried stride between block starts for the hyperslab */ - hsize_t q_count[SPACE13_RANK]; /* The queried number of blocks for the hyperslab */ - hsize_t q_block[SPACE13_RANK]; /* The queried size of each block for the hyperslab */ - htri_t is_regular; /* Whether a hyperslab selection is regular */ - unsigned u; /* Local index variable */ + hid_t msid; /* Memory dataspace ID */ + hid_t did; /* Dataset ID */ + const hsize_t mem_dims[1] = { SPACE10_DIM1 }; /* Dataspace dimensions for memory */ + const hsize_t dims[1] = { 0 }; /* Dataspace initial dimensions */ + const hsize_t maxdims[1] = { H5S_UNLIMITED }; /* Dataspace mam dims */ + int *wbuf; /* Buffer for writing data */ + int *rbuf; /* Buffer for reading data */ + hid_t dcpl; /* Dataset creation property list ID */ + hsize_t chunks[1]={SPACE10_CHUNK_SIZE }; /* Chunk size */ + hsize_t start[1] = { 0 }; /* The start of the hyperslab */ + hsize_t count[1] = { SPACE10_CHUNK_SIZE }; /* The size of the hyperslab */ + int i,j; /* Local index */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ - MESSAGE(6, ("Testing queries on regular hyperslabs\n")); + MESSAGE(6, ("Testing hyperslab selections using offsets in chunked datasets\n")); - /* Create dataspace */ - sid = H5Screate_simple(SPACE13_RANK, dims, NULL); - CHECK(sid, FAIL, "H5Screate_simple"); + /* Allocate buffers */ + wbuf = (int *)HDmalloc(sizeof(int) * SPACE10_DIM1); + CHECK_PTR(wbuf, "HDmalloc"); + rbuf = (int *)HDcalloc(sizeof(int), SPACE10_DIM1); + CHECK_PTR(rbuf, "HDcalloc"); - /* Query if 'all' selection is regular hyperslab (should fail) */ - H5E_BEGIN_TRY { - is_regular = H5Sis_regular_hyperslab(sid); - } H5E_END_TRY; - VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + /* Initialize the write buffer */ + for(i=0; i=((2*SPACE10_CHUNK_SIZE)/3)) + if(wbuf[i+j]!=rbuf[((SPACE10_DIM1-i)-SPACE10_CHUNK_SIZE)+j]) + TestErrPrintf("Line: %d - Error! i=%d, j=%d, rbuf=%d, wbuf=%d\n",__LINE__,i,j,rbuf[((SPACE10_DIM1-i)-SPACE10_CHUNK_SIZE)+j],wbuf[i+j]); + + /* Close the memory dataspace */ + ret=H5Sclose (msid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the dataset */ + ret=H5Dclose (did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the file */ + ret=H5Fclose (fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Free the buffers */ + HDfree(wbuf); + HDfree(rbuf); +} /* test_select_hyper_chunk_offset() */ + +/**************************************************************** +** +** test_select_hyper_chunk_offset2(): Tests selections on dataspace, +** another test to verify that offsets for hyperslab selections are +** working in chunked datasets. +** +****************************************************************/ +static void +test_select_hyper_chunk_offset2(void) +{ + hid_t file, dataset; /* handles */ + hid_t dataspace; + hid_t memspace; + hid_t dcpl; /* Dataset creation property list */ + herr_t status; + unsigned data_out[SPACE12_DIM0]; /* output buffer */ + unsigned data_in[SPACE12_CHUNK_DIM0]; /* input buffer */ + hsize_t dims[SPACE12_RANK]={SPACE12_DIM0}; /* Dimension size */ + hsize_t chunk_dims[SPACE12_RANK]={SPACE12_CHUNK_DIM0}; /* Chunk size */ + hsize_t start[SPACE12_RANK]; /* Start of hyperslab */ + hsize_t count[SPACE12_RANK]; /* Size of hyperslab */ + hssize_t offset[SPACE12_RANK]; /* hyperslab offset in the file */ + unsigned u, v; /* Local index variables */ + + /* Output message about test being performed */ + MESSAGE(6, ("Testing more hyperslab selections using offsets in chunked datasets\n")); + + /* Initialize data to write out */ + for (u = 0; u < SPACE12_DIM0; u++) + data_out[u] = u; + + /* Create the file */ + file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(file, FAIL, "H5Fcreate"); + + /* Create dataspace */ + dataspace = H5Screate_simple(SPACE12_RANK, dims, NULL); + CHECK(dataspace, FAIL, "H5Screate_simple"); + + /* Create dataset creation property list */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + + /* Set chunk sizes */ + status = H5Pset_chunk(dcpl, SPACE12_RANK, chunk_dims); + CHECK(status, FAIL, "H5Pset_chunk"); + + /* Create dataset */ + dataset = H5Dcreate2(file, DATASETNAME, H5T_NATIVE_UINT, dataspace, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(dataset, FAIL, "H5Dcreate2"); + + /* Close DCPL */ + status = H5Pclose(dcpl); + CHECK(status, FAIL, "H5Pclose"); + + /* Write out entire dataset */ + status = H5Dwrite(dataset, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_out); + CHECK(status, FAIL, "H5Dclose"); + + /* Create memory dataspace (same size as a chunk) */ + memspace = H5Screate_simple(SPACE12_RANK, chunk_dims, NULL); + CHECK(dataspace, FAIL, "H5Screate_simple"); + + /* + * Define hyperslab in the file dataspace. + */ + start[0] = 0; + count[0] = SPACE12_CHUNK_DIM0; + status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, start, NULL, count, NULL); + CHECK(status, FAIL, "H5Sselect_hyperslab"); + + /* Loop through retrieving data from file, checking it against data written */ + for(u = 0; u < SPACE12_DIM0; u += SPACE12_CHUNK_DIM0) { + /* Set the offset of the file selection */ + offset[0] = u; + status = H5Soffset_simple(dataspace, offset); + CHECK(status, FAIL, "H5Soffset_simple"); + + /* Read in buffer of data */ + status = H5Dread(dataset, H5T_NATIVE_UINT, memspace, dataspace, + H5P_DEFAULT, data_in); + CHECK(status, FAIL, "H5Dread"); + + /* Check data read in */ + for(v = 0; v < SPACE12_CHUNK_DIM0; v++) + if(data_out[u + v] != data_in[v]) + TestErrPrintf("Error! data_out[%u]=%u, data_in[%u]=%u\n",(unsigned)(u + v), data_out[u + v], v, data_in[v]); + } /* end for */ + + status = H5Dclose(dataset); + CHECK(status, FAIL, "H5Dclose"); + + status = H5Sclose(dataspace); + CHECK(status, FAIL, "H5Sclose"); + + status = H5Sclose(memspace); + CHECK(status, FAIL, "H5Sclose"); + + status = H5Fclose(file); + CHECK(status, FAIL, "H5Fclose"); +} /* test_select_hyper_chunk_offset2() */ + +/**************************************************************** +** +** test_select_bounds(): Tests selection bounds on dataspaces, +** both with and without offsets. +** +****************************************************************/ +static void +test_select_bounds(void) +{ + hid_t sid; /* Dataspace ID */ + const hsize_t dims[SPACE11_RANK] = {SPACE11_DIM1, SPACE11_DIM2}; /* Dataspace dimensions */ + hsize_t coord[SPACE11_NPOINTS][SPACE11_RANK]; /* Coordinates for point selection */ + hsize_t start[SPACE11_RANK]; /* The start of the hyperslab */ + hsize_t stride[SPACE11_RANK]; /* The stride between block starts for the hyperslab */ + hsize_t count[SPACE11_RANK]; /* The number of blocks for the hyperslab */ + hsize_t block[SPACE11_RANK]; /* The size of each block for the hyperslab */ + hssize_t offset[SPACE11_RANK]; /* Offset amount for selection */ + hsize_t low_bounds[SPACE11_RANK]; /* The low bounds for the selection */ + hsize_t high_bounds[SPACE11_RANK]; /* The high bounds for the selection */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(6, ("Testing selection bounds\n")); + + /* Create dataspace */ + sid = H5Screate_simple (SPACE11_RANK, dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Get bounds for 'all' selection */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); + + /* Set offset for selection */ + offset[0] = 1; offset[1] = 1; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for 'all' selection with offset (which should be ignored) */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 0, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 1, "H5Sget_select_bounds"); + + /* Reset offset for selection */ + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Set 'none' selection */ + ret = H5Sselect_none(sid); + CHECK(ret, FAIL, "H5Sselect_none"); + + /* Get bounds for 'none' selection */ + H5E_BEGIN_TRY { + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bo unds"); + + /* Set point selection */ + coord[0][0] = 3; coord[0][1] = 3; + coord[1][0] = 3; coord[1][1] = 96; + coord[2][0] = 96; coord[2][1] = 3; + coord[3][0] = 96; coord[3][1] = 96; + ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE11_NPOINTS, (const hsize_t *)coord); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Get bounds for point selection */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 3, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 3, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 4, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 4, "H5Sget_select_bounds"); + + /* Set bad offset for selection */ + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for hyperslab selection with negative offset */ + H5E_BEGIN_TRY { + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bounds"); + + /* Set valid offset for selection */ + offset[0] = 2; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for point selection with offset */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 5, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 1, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], SPACE11_DIM1 - 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], SPACE11_DIM2 - 6, "H5Sget_select_bounds"); + + /* Reset offset for selection */ + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Set "regular" hyperslab selection */ + start[0] = 2; start[1] = 2; + stride[0] = 10; stride[1] = 10; + count[0] = 4; count[1] = 4; + block[0] = 5; block[1] = 5; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Get bounds for hyperslab selection */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 36, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 36, "H5Sget_select_bounds"); + + /* Set bad offset for selection */ + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for hyperslab selection with negative offset */ + H5E_BEGIN_TRY { + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bounds"); + + /* Set valid offset for selection */ + offset[0] = 5; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for hyperslab selection with offset */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 41, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 34, "H5Sget_select_bounds"); + + /* Reset offset for selection */ + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Make "irregular" hyperslab selection */ + start[0] = 20; start[1] = 20; + stride[0] = 20; stride[1] = 20; + count[0] = 2; count[1] = 2; + block[0] = 10; block[1] = 10; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Get bounds for hyperslab selection */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 2, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 2, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 49, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 49, "H5Sget_select_bounds"); + + /* Set bad offset for selection */ + offset[0] = 5; offset[1] = -5; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for hyperslab selection with negative offset */ + H5E_BEGIN_TRY { + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_select_bounds"); + + /* Set valid offset for selection */ + offset[0] = 5; offset[1] = -2; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Get bounds for hyperslab selection with offset */ + ret = H5Sget_select_bounds(sid, low_bounds, high_bounds); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(low_bounds[0], 7, "H5Sget_select_bounds"); + VERIFY(low_bounds[1], 0, "H5Sget_select_bounds"); + VERIFY(high_bounds[0], 54, "H5Sget_select_bounds"); + VERIFY(high_bounds[1], 47, "H5Sget_select_bounds"); + + /* Reset offset for selection */ + offset[0] = 0; offset[1] = 0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* test_select_bounds() */ + + +/**************************************************************** +** +** test_hyper_regular(): Tests query operations on regular hyperslabs +** +****************************************************************/ +static void +test_hyper_regular(void) +{ + hid_t sid; /* Dataspace ID */ + const hsize_t dims[SPACE13_RANK] = {SPACE13_DIM1, SPACE13_DIM2, SPACE13_DIM3}; /* Dataspace dimensions */ + hsize_t coord[SPACE13_NPOINTS][SPACE13_RANK]; /* Coordinates for point selection */ + hsize_t start[SPACE13_RANK]; /* The start of the hyperslab */ + hsize_t stride[SPACE13_RANK]; /* The stride between block starts for the hyperslab */ + hsize_t count[SPACE13_RANK]; /* The number of blocks for the hyperslab */ + hsize_t block[SPACE13_RANK]; /* The size of each block for the hyperslab */ + hsize_t t_start[SPACE13_RANK]; /* Temporary start of the hyperslab */ + hsize_t t_count[SPACE13_RANK]; /* Temporary number of blocks for the hyperslab */ + hsize_t q_start[SPACE13_RANK]; /* The queried start of the hyperslab */ + hsize_t q_stride[SPACE13_RANK]; /* The queried stride between block starts for the hyperslab */ + hsize_t q_count[SPACE13_RANK]; /* The queried number of blocks for the hyperslab */ + hsize_t q_block[SPACE13_RANK]; /* The queried size of each block for the hyperslab */ + htri_t is_regular; /* Whether a hyperslab selection is regular */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(6, ("Testing queries on regular hyperslabs\n")); + + /* Create dataspace */ + sid = H5Screate_simple(SPACE13_RANK, dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Query if 'all' selection is regular hyperslab (should fail) */ + H5E_BEGIN_TRY { + is_regular = H5Sis_regular_hyperslab(sid); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + + /* Query regular hyperslab selection info (should fail) */ + H5E_BEGIN_TRY { + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* Set 'none' selection */ + ret = H5Sselect_none(sid); + CHECK(ret, FAIL, "H5Sselect_none"); + + /* Query if 'none' selection is regular hyperslab (should fail) */ + H5E_BEGIN_TRY { + is_regular = H5Sis_regular_hyperslab(sid); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + + /* Query regular hyperslab selection info (should fail) */ + H5E_BEGIN_TRY { + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* Set point selection */ + coord[0][0] = 3; coord[0][1] = 3; coord[0][2] = 3; + coord[1][0] = 3; coord[1][1] = 48; coord[1][2] = 48; + coord[2][0] = 48; coord[2][1] = 3; coord[2][2] = 3; + coord[3][0] = 48; coord[3][1] = 48; coord[3][2] = 48; + ret = H5Sselect_elements(sid, H5S_SELECT_SET, (size_t)SPACE13_NPOINTS, (const hsize_t *)coord); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Query if 'point' selection is regular hyperslab (should fail) */ + H5E_BEGIN_TRY { + is_regular = H5Sis_regular_hyperslab(sid); + } H5E_END_TRY; + VERIFY(is_regular, FAIL, "H5Sis_regular_hyperslab"); + + /* Query regular hyperslab selection info (should fail) */ + H5E_BEGIN_TRY { + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* Set "regular" hyperslab selection */ + start[0] = 2; start[1] = 2; start[2] = 2; + stride[0] = 5; stride[1] = 5; stride[2] = 5; + count[0] = 3; count[1] = 3; count[2] = 3; + block[0] = 4; block[1] = 4; block[2] = 4; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Query if 'hyperslab' selection is regular hyperslab (should be TRUE) */ + is_regular = H5Sis_regular_hyperslab(sid); + VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); + + /* Retrieve the hyperslab parameters */ + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + CHECK(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* Verify the hyperslab parameters */ + for(u = 0; u < SPACE13_RANK; u++) { + if(start[u] != q_start[u]) + ERROR("H5Sget_regular_hyperslab, start"); + if(stride[u] != q_stride[u]) + ERROR("H5Sget_regular_hyperslab, stride"); + if(count[u] != q_count[u]) + ERROR("H5Sget_regular_hyperslab, count"); + if(block[u] != q_block[u]) + ERROR("H5Sget_regular_hyperslab, block"); + } /* end for */ + + /* 'OR' in another point */ + t_start[0] = 0; t_start[1] = 0; t_start[2] = 0; + t_count[0] = 1; t_count[1] = 1; t_count[2] = 1; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, t_start, NULL, t_count, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Query if 'hyperslab' selection is regular hyperslab (should be FALSE) */ + is_regular = H5Sis_regular_hyperslab(sid); + VERIFY(is_regular, FALSE, "H5Sis_regular_hyperslab"); + + /* Query regular hyperslab selection info (should fail) */ + H5E_BEGIN_TRY { + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* 'XOR' in the point again, to remove it, which should make it regular again */ + t_start[0] = 0; t_start[1] = 0; t_start[2] = 0; + t_count[0] = 1; t_count[1] = 1; t_count[2] = 1; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, t_start, NULL, t_count, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Query if 'hyperslab' selection is regular hyperslab (should be TRUE) */ + is_regular = H5Sis_regular_hyperslab(sid); + VERIFY(is_regular, TRUE, "H5Sis_regular_hyperslab"); + + /* Retrieve the hyperslab parameters */ + ret = H5Sget_regular_hyperslab(sid, q_start, q_stride, q_count, q_block); + CHECK(ret, FAIL, "H5Sget_regular_hyperslab"); + + /* Verify the hyperslab parameters */ + for(u = 0; u < SPACE13_RANK; u++) { + if(start[u] != q_start[u]) + ERROR("H5Sget_regular_hyperslab, start"); + if(stride[u] != q_stride[u]) + ERROR("H5Sget_regular_hyperslab, stride"); + if(count[u] != q_count[u]) + ERROR("H5Sget_regular_hyperslab, count"); + if(block[u] != q_block[u]) + ERROR("H5Sget_regular_hyperslab, block"); + } /* end for */ + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* test_hyper_regular() */ + +/**************************************************************** +** +** test_hyper_unlim(): Tests unlimited hyperslab selections +** +****************************************************************/ +static void +test_hyper_unlim_check(hid_t sid, hsize_t *dims, hssize_t enpoints, + hssize_t enblocks, hsize_t *eblock1, hsize_t *eblock2) +{ + hid_t lim_sid; + hsize_t start[3]; + H5S_sel_type sel_type; + hssize_t npoints; + hssize_t nblocks; + hsize_t blocklist[12]; + herr_t ret; + + HDassert(enblocks <= 2); + + /* Copy sid to lim_sid */ + lim_sid = H5Scopy(sid); + CHECK(lim_sid, FAIL, "H5Scopy"); + + /* "And" lim_sid with dims to create limited selection */ + HDmemset(start, 0, sizeof(start)); + ret = H5Sselect_hyperslab(lim_sid, H5S_SELECT_AND, start, NULL, dims, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check number of elements */ + npoints = H5Sget_select_npoints(lim_sid); + CHECK(npoints, FAIL, "H5Sget_select_npoints"); + VERIFY(npoints, enpoints, "H5Sget_select_npoints"); + + /* Get selection type */ + sel_type = H5Sget_select_type(lim_sid); + CHECK(sel_type, H5S_SEL_ERROR, "H5Sget_select_type"); + + /* Only examine blocks for hyperslab selection */ + if(sel_type == H5S_SEL_HYPERSLABS) { + /* Get number of blocks */ + nblocks = H5Sget_select_hyper_nblocks(lim_sid); + CHECK(nblocks, FAIL, "H5Sget_select_hyper_nblocks"); + VERIFY(nblocks, enblocks, "H5Sget_select_hyper_nblocks"); + + if(nblocks > 0) { + /* Get blocklist */ + ret = H5Sget_select_hyper_blocklist(lim_sid, (hsize_t)0, (hsize_t)nblocks, blocklist); + CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + + /* Verify blocklist */ + if(nblocks == (hssize_t)1) { + if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end if */ + else { + HDassert(nblocks == (hssize_t)2); + if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) { + if(HDmemcmp(blocklist, eblock2, 6 * sizeof(eblock2[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + if(HDmemcmp(&blocklist[6], eblock1, 6 * sizeof(eblock1[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end if */ + else + if(HDmemcmp(&blocklist[6], eblock2, 6 * sizeof(eblock2[0]))) + ERROR("H5Sget_select_hyper_blocklist"); + } /* end else */ + } /* end if */ + } /* end if */ + else + if(sel_type != H5S_SEL_NONE) + ERROR("H5Sget_select_type"); + + /* Close the limited dataspace */ + ret = H5Sclose(lim_sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* end test_hyper_unlim_check() */ + +static void +test_hyper_unlim(void) +{ + hid_t sid; + hsize_t dims[3] = {4, 4, 7}; + hsize_t mdims[3] = {4, H5S_UNLIMITED, 7}; + hsize_t start[3] = {1, 2, 1}; + hsize_t stride[3] = {1, 1, 3}; + hsize_t count[3] = {1, 1, 2}; + hsize_t block[3] = {2, H5S_UNLIMITED, 2}; + hsize_t start2[3]; + hsize_t count2[3]; + hsize_t eblock1[6] = {1, 2, 1, 2, 3, 2}; + hsize_t eblock2[6] = {1, 2, 4, 2, 3, 5}; + hssize_t offset[3] = {0, -1, 0}; + hssize_t ssize_out; + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(6, ("Testing unlimited hyperslab selections\n")); + + /* Create dataspace */ + sid = H5Screate_simple(3, dims, mdims); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Select unlimited hyperslab */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check with unlimited dimension clipped to 4 */ + test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 3 */ + dims[1] = 3; + eblock1[4] = 2; + eblock2[4] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 2 */ + dims[1] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 1 */ + dims[1] = 1; + test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 7 */ + dims[1] = 7; + eblock1[4] = 6; + eblock2[4] = 6; + test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + + /* Reset offset of selection */ + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* + * Now try with multiple blocks in unlimited dimension + */ + stride[1] = 3; + stride[2] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 1; + block[1] = 2; + + /* Select unlimited hyperslab */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + + /* Check with new selection */ + eblock1[1] = 2; + eblock1[4] = 3; + eblock2[1] = 5; + eblock2[2] = 1; + eblock2[4] = 6; + eblock2[5] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 3 */ + dims[1] = 3; + eblock1[4] = 2; + test_hyper_unlim_check(sid, dims, (hssize_t)4, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 4 */ + dims[1] = 4; + eblock1[4] = 3; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 5 */ + dims[1] = 5; + eblock1[4] = 3; + test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + + /* Check with unlimited dimension clipped to 6 */ + dims[1] = 6; + eblock1[4] = 3; + eblock2[4] = 5; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + offset[1] = (hssize_t)-1; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Set offset of selection */ + offset[1] = (hssize_t)3; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* Check with adjusted offset (should not affect result) */ + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Reset offset of selection */ + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); + CHECK(ret, FAIL, "H5Soffset_simple"); + + /* + * Now try invalid operations + */ + H5E_BEGIN_TRY { + /* Try multiple unlimited dimensions */ + start[0] = 1; + start[1] = 2; + start[2] = 1; + stride[0] = 1; + stride[1] = 3; + stride[2] = 3; + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = H5S_UNLIMITED; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + + /* Try unlimited count and block */ + count[2] = 2; + block[1] = H5S_UNLIMITED; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* Try operations with two unlimited selections */ + block[1] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, NULL, count, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* Try invalid combination operations */ + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, block, NULL); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL, block, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + H5E_BEGIN_TRY { + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, stride, count, block); + VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + } H5E_END_TRY + + /* + * Now test valid combination operations + */ + /* unlim AND non-unlim */ + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + start2[0] = 2; + start2[1] = 2; + start2[2] = 0; + count2[0] = 5; + count2[1] = 4; + count2[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 2; + eblock1[3] = 2; + eblock1[1] = 2; + eblock1[4] = 3; + eblock1[2] = 1; + eblock1[5] = 1; + eblock2[0] = 2; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 5; + eblock2[2] = 1; + eblock2[5] = 1; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); + + /* unlim NOTA non-unlim */ + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + start2[0] = 1; + start2[1] = 5; + start2[2] = 2; + count2[0] = 2; + count2[1] = 2; + count2[2] = 6; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 1; + eblock1[3] = 2; + eblock1[1] = 5; + eblock1[4] = 6; + eblock1[2] = 3; + eblock1[5] = 3; + eblock2[0] = 1; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 6; + eblock2[2] = 6; + eblock2[5] = 7; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* non-unlim AND unlim */ + start2[0] = 2; + start2[1] = 2; + start2[2] = 0; + count2[0] = 5; + count2[1] = 4; + count2[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 2; + eblock1[3] = 2; + eblock1[1] = 2; + eblock1[4] = 3; + eblock1[2] = 1; + eblock1[5] = 1; + eblock2[0] = 2; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 5; + eblock2[2] = 1; + eblock2[5] = 1; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); + + /* non-unlim NOTB unlim */ + start2[0] = 1; + start2[1] = 5; + start2[2] = 2; + count2[0] = 2; + count2[1] = 2; + count2[2] = 6; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + count[0] = 1; + count[1] = H5S_UNLIMITED; + count[2] = 2; + block[0] = 2; + block[1] = 2; + block[2] = 2; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + eblock1[0] = 1; + eblock1[3] = 2; + eblock1[1] = 5; + eblock1[4] = 6; + eblock1[2] = 3; + eblock1[5] = 3; + eblock2[0] = 1; + eblock2[3] = 2; + eblock2[1] = 5; + eblock2[4] = 6; + eblock2[2] = 6; + eblock2[5] = 7; + dims[0] = 50; + dims[1] = 50; + dims[2] = 50; + test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + + /* Test H5Sget_select_npoints() */ + ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); + ssize_out = H5Sget_select_npoints(sid); + VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + + /* Test H5Sget_select_hyper_nblocks() */ + ssize_out = H5Sget_select_hyper_nblocks(sid); + VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_hyper_nblocks"); + + /* Test H5Sget_select_bounds() */ + ret = H5Sget_select_bounds(sid, start2, count2); + CHECK(ret, FAIL, "H5Sget_select_bounds"); + VERIFY(start2[0], start[0], "H5Sget_select_bounds"); + VERIFY(start2[1], start[1], "H5Sget_select_bounds"); + VERIFY(start2[2], start[2], "H5Sget_select_bounds"); + VERIFY(count2[0], (long)(start[0] + (stride[0] * (count[0] - 1)) + block[0] - 1), "H5Sget_select_bounds"); + VERIFY(count2[1], H5S_UNLIMITED, "H5Sget_select_bounds"); + VERIFY(count2[2], (long)(start[2] + (stride[2] * (count[2] - 1)) + block[2] - 1), "H5Sget_select_bounds"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* end test_hyper_unlim() */ + +/**************************************************************** +** +** test_internal_consistency(): Tests selections on dataspace, then +** verify that internal states of data structures of selections are +** consistent. +** +****************************************************************/ +static void +test_internal_consistency(void) +{ + hid_t all_sid; /* Dataspace ID with "all" selection */ + hid_t none_sid; /* Dataspace ID with "none" selection */ + hid_t single_pt_sid; /* Dataspace ID with single point selection */ + hid_t mult_pt_sid; /* Dataspace ID with multiple point selection */ + hid_t single_hyper_sid; /* Dataspace ID with single block hyperslab selection */ + hid_t single_hyper_all_sid; /* Dataspace ID with single block hyperslab + * selection that is the entire dataspace + */ + hid_t single_hyper_pt_sid; /* Dataspace ID with single block hyperslab + * selection that is the same as the single + * point selection + */ + hid_t regular_hyper_sid; /* Dataspace ID with regular hyperslab selection */ + hid_t irreg_hyper_sid; /* Dataspace ID with irregular hyperslab selection */ + hid_t none_hyper_sid; /* Dataspace ID with "no hyperslabs" selection */ + hid_t scalar_all_sid; /* ID for scalar dataspace with "all" selection */ + hid_t scalar_none_sid; /* ID for scalar dataspace with "none" selection */ + hid_t tmp_sid; /* Temporary dataspace ID */ + hsize_t dims[] = {SPACE9_DIM1, SPACE9_DIM2}; + hsize_t coord1[1][SPACE2_RANK]; /* Coordinates for single point selection */ + hsize_t coord2[SPACE9_DIM2][SPACE9_RANK]; /* Coordinates for multiple point selection */ + hsize_t start[SPACE9_RANK]; /* Hyperslab start */ + hsize_t stride[SPACE9_RANK]; /* Hyperslab stride */ + hsize_t count[SPACE9_RANK]; /* Hyperslab block count */ + hsize_t block[SPACE9_RANK]; /* Hyperslab block size */ + htri_t check; /* Shape comparison return value */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(6, ("Testing Consistency of Internal States\n")); + assert(SPACE9_DIM2>=POINT1_NPOINTS); + + /* Create dataspace for "all" selection */ + all_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(all_sid, FAIL, "H5Screate_simple"); + + /* Select entire extent for dataspace */ + ret = H5Sselect_all(all_sid); + CHECK(ret, FAIL, "H5Sselect_all"); + + /* Create dataspace for "none" selection */ + none_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(none_sid, FAIL, "H5Screate_simple"); + + /* Un-Select entire extent for dataspace */ + ret = H5Sselect_none(none_sid); + CHECK(ret, FAIL, "H5Sselect_none"); + + /* Create dataspace for single point selection */ + single_pt_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(single_pt_sid, FAIL, "H5Screate_simple"); + + /* Select sequence of ten points for multiple point selection */ + coord1[0][0] = 2; coord1[0][1] = 2; + ret = H5Sselect_elements(single_pt_sid, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord1); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Create dataspace for multiple point selection */ + mult_pt_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(mult_pt_sid, FAIL, "H5Screate_simple"); + + /* Select sequence of ten points for multiple point selection */ + coord2[0][0]=2; coord2[0][1]=2; + coord2[1][0]=7; coord2[1][1]=2; + coord2[2][0]=1; coord2[2][1]=4; + coord2[3][0]=2; coord2[3][1]=6; + coord2[4][0]=0; coord2[4][1]=8; + coord2[5][0]=3; coord2[5][1]=2; + coord2[6][0]=4; coord2[6][1]=4; + coord2[7][0]=1; coord2[7][1]=0; + coord2[8][0]=5; coord2[8][1]=1; + coord2[9][0]=9; coord2[9][1]=3; + ret = H5Sselect_elements(mult_pt_sid, H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord2); + CHECK(ret, FAIL, "H5Sselect_elements"); + + /* Create dataspace for single hyperslab selection */ + single_hyper_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(single_hyper_sid, FAIL, "H5Screate_simple"); + + /* Select 10x10 hyperslab for single hyperslab selection */ + start[0]=1; start[1]=1; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=(SPACE9_DIM1-2); block[1]=(SPACE9_DIM2-2); + ret = H5Sselect_hyperslab(single_hyper_sid,H5S_SELECT_SET,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); -} /* test_hyper_regular() */ + /* Create dataspace for single hyperslab selection with entire extent selected */ + single_hyper_all_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(single_hyper_all_sid, FAIL, "H5Screate_simple"); -/**************************************************************** -** -** test_hyper_unlim(): Tests unlimited hyperslab selections -** -****************************************************************/ -static void -test_hyper_unlim_check(hid_t sid, hsize_t *dims, hssize_t enpoints, - hssize_t enblocks, hsize_t *eblock1, hsize_t *eblock2) -{ - hid_t lim_sid; - hsize_t start[3]; - H5S_sel_type sel_type; - hssize_t npoints; - hssize_t nblocks; - hsize_t blocklist[12]; - herr_t ret; + /* Select entire extent for hyperslab selection */ + start[0]=0; start[1]=0; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=SPACE9_DIM1; block[1]=SPACE9_DIM2; + ret = H5Sselect_hyperslab(single_hyper_all_sid,H5S_SELECT_SET,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - HDassert(enblocks <= 2); + /* Create dataspace for single hyperslab selection with single point selected */ + single_hyper_pt_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(single_hyper_pt_sid, FAIL, "H5Screate_simple"); - /* Copy sid to lim_sid */ - lim_sid = H5Scopy(sid); - CHECK(lim_sid, FAIL, "H5Scopy"); + /* Select entire extent for hyperslab selection */ + start[0]=2; start[1]=2; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=1; block[1]=1; + ret = H5Sselect_hyperslab(single_hyper_pt_sid,H5S_SELECT_SET,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* "And" lim_sid with dims to create limited selection */ - HDmemset(start, 0, sizeof(start)); - ret = H5Sselect_hyperslab(lim_sid, H5S_SELECT_AND, start, NULL, dims, NULL); + /* Create dataspace for regular hyperslab selection */ + regular_hyper_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(regular_hyper_sid, FAIL, "H5Screate_simple"); + + /* Select regular, strided hyperslab selection */ + start[0]=2; start[1]=2; + stride[0]=2; stride[1]=2; + count[0]=5; count[1]=2; + block[0]=1; block[1]=1; + ret = H5Sselect_hyperslab(regular_hyper_sid,H5S_SELECT_SET,start,stride,count,block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Check number of elements */ - npoints = H5Sget_select_npoints(lim_sid); - CHECK(npoints, FAIL, "H5Sget_select_npoints"); - VERIFY(npoints, enpoints, "H5Sget_select_npoints"); + /* Create dataspace for irregular hyperslab selection */ + irreg_hyper_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(irreg_hyper_sid, FAIL, "H5Screate_simple"); - /* Get selection type */ - sel_type = H5Sget_select_type(lim_sid); - CHECK(sel_type, H5S_SEL_ERROR, "H5Sget_select_type"); + /* Create irregular hyperslab selection by OR'ing two blocks together */ + start[0]=2; start[1]=2; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=1; block[1]=1; + ret = H5Sselect_hyperslab(irreg_hyper_sid,H5S_SELECT_SET,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Only examine blocks for hyperslab selection */ - if(sel_type == H5S_SEL_HYPERSLABS) { - /* Get number of blocks */ - nblocks = H5Sget_select_hyper_nblocks(lim_sid); - CHECK(nblocks, FAIL, "H5Sget_select_hyper_nblocks"); - VERIFY(nblocks, enblocks, "H5Sget_select_hyper_nblocks"); + start[0]=4; start[1]=4; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=3; block[1]=3; + ret = H5Sselect_hyperslab(irreg_hyper_sid,H5S_SELECT_OR,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - if(nblocks > 0) { - /* Get blocklist */ - ret = H5Sget_select_hyper_blocklist(lim_sid, (hsize_t)0, (hsize_t)nblocks, blocklist); - CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); + /* Create dataspace for "no" hyperslab selection */ + none_hyper_sid = H5Screate_simple(SPACE9_RANK, dims, NULL); + CHECK(none_hyper_sid, FAIL, "H5Screate_simple"); - /* Verify blocklist */ - if(nblocks == (hssize_t)1) { - if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) - ERROR("H5Sget_select_hyper_blocklist"); - } /* end if */ - else { - HDassert(nblocks == (hssize_t)2); - if(HDmemcmp(blocklist, eblock1, 6 * sizeof(eblock1[0]))) { - if(HDmemcmp(blocklist, eblock2, 6 * sizeof(eblock2[0]))) - ERROR("H5Sget_select_hyper_blocklist"); - if(HDmemcmp(&blocklist[6], eblock1, 6 * sizeof(eblock1[0]))) - ERROR("H5Sget_select_hyper_blocklist"); - } /* end if */ - else - if(HDmemcmp(&blocklist[6], eblock2, 6 * sizeof(eblock2[0]))) - ERROR("H5Sget_select_hyper_blocklist"); - } /* end else */ - } /* end if */ - } /* end if */ - else - if(sel_type != H5S_SEL_NONE) - ERROR("H5Sget_select_type"); + /* Create "no" hyperslab selection by XOR'ing same blocks together */ + start[0]=2; start[1]=2; + stride[0]=1; stride[1]=1; + count[0]=1; count[1]=1; + block[0]=1; block[1]=1; + ret = H5Sselect_hyperslab(none_hyper_sid,H5S_SELECT_SET,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Close the limited dataspace */ - ret = H5Sclose(lim_sid); - CHECK(ret, FAIL, "H5Sclose"); -} /* end test_hyper_unlim_check() */ + ret = H5Sselect_hyperslab(none_hyper_sid,H5S_SELECT_XOR,start,stride,count,block); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); -static void -test_hyper_unlim(void) -{ - hid_t sid; - hsize_t dims[3] = {4, 4, 7}; - hsize_t mdims[3] = {4, H5S_UNLIMITED, 7}; - hsize_t start[3] = {1, 2, 1}; - hsize_t stride[3] = {1, 1, 3}; - hsize_t count[3] = {1, 1, 2}; - hsize_t block[3] = {2, H5S_UNLIMITED, 2}; - hsize_t start2[3]; - hsize_t count2[3]; - hsize_t eblock1[6] = {1, 2, 1, 2, 3, 2}; - hsize_t eblock2[6] = {1, 2, 4, 2, 3, 5}; - hssize_t offset[3] = {0, -1, 0}; - hssize_t ssize_out; - herr_t ret; + /* Create scalar dataspace for "all" selection */ + scalar_all_sid = H5Screate(H5S_SCALAR); + CHECK(scalar_all_sid, FAIL, "H5Screate"); - /* Output message about test being performed */ - MESSAGE(6, ("Testing unlimited hyperslab selections\n")); + /* Create scalar dataspace for "none" selection */ + scalar_none_sid = H5Screate(H5S_SCALAR); + CHECK(scalar_none_sid, FAIL, "H5Screate"); - /* Create dataspace */ - sid = H5Screate_simple(3, dims, mdims); - CHECK(sid, FAIL, "H5Screate_simple"); + /* Un-Select entire extent for dataspace */ + ret = H5Sselect_none(scalar_none_sid); + CHECK(ret, FAIL, "H5Sselect_none"); - /* Select unlimited hyperslab */ - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); + /* Test all the selections created */ - /* Check with unlimited dimension clipped to 4 */ - test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + /* Test the copy of itself */ + tmp_sid=H5Scopy(all_sid); + CHECK(tmp_sid, FAIL, "H5Scopy"); - /* Check with unlimited dimension clipped to 3 */ - dims[1] = 3; - eblock1[4] = 2; - eblock2[4] = 2; - test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)2, eblock1, eblock2); + check = H5S__internal_consistency_test(tmp_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 2 */ - dims[1] = 2; - test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + ret = H5Sclose(tmp_sid); + CHECK(ret, FAIL, "H5Sclose"); - /* Check with unlimited dimension clipped to 1 */ - dims[1] = 1; - test_hyper_unlim_check(sid, dims, (hssize_t)0, (hssize_t)0, eblock1, eblock2); + /* Test "none" selection */ + check = H5S__internal_consistency_test(none_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 7 */ - dims[1] = 7; - eblock1[4] = 6; - eblock2[4] = 6; - test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + /* Test single point selection */ + check = H5S__internal_consistency_test(single_pt_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Set offset of selection */ - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Test multiple point selection */ + check = H5S__internal_consistency_test(mult_pt_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with adjusted offset (should not affect result) */ - test_hyper_unlim_check(sid, dims, (hssize_t)40, (hssize_t)2, eblock1, eblock2); + /* Test "plain" single hyperslab selection */ + check = H5S__internal_consistency_test(single_hyper_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Reset offset of selection */ - offset[1] = (hssize_t)0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Test "all" single hyperslab selection */ + check = H5S__internal_consistency_test(single_hyper_all_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* - * Now try with multiple blocks in unlimited dimension - */ - stride[1] = 3; - stride[2] = 1; - count[1] = H5S_UNLIMITED; - count[2] = 1; - block[1] = 2; + /* Test "single point" single hyperslab selection */ + check = H5S__internal_consistency_test(single_hyper_pt_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Select unlimited hyperslab */ - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); + /* Test regular, strided hyperslab selection */ + check = H5S__internal_consistency_test(regular_hyper_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with new selection */ - eblock1[1] = 2; - eblock1[4] = 3; - eblock2[1] = 5; - eblock2[2] = 1; - eblock2[4] = 6; - eblock2[5] = 2; - test_hyper_unlim_check(sid, dims, (hssize_t)16, (hssize_t)2, eblock1, eblock2); + /* Test irregular hyperslab selection */ + check = H5S__internal_consistency_test(irreg_hyper_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 3 */ - dims[1] = 3; - eblock1[4] = 2; - test_hyper_unlim_check(sid, dims, (hssize_t)4, (hssize_t)1, eblock1, eblock2); + /* Test "no" hyperslab selection */ + check = H5S__internal_consistency_test(none_hyper_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 4 */ - dims[1] = 4; - eblock1[4] = 3; - test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + /* Test scalar "all" hyperslab selection */ + check = H5S__internal_consistency_test(scalar_all_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 5 */ - dims[1] = 5; - eblock1[4] = 3; - test_hyper_unlim_check(sid, dims, (hssize_t)8, (hssize_t)1, eblock1, eblock2); + /* Test scalar "none" hyperslab selection */ + check = H5S__internal_consistency_test(scalar_none_sid); + VERIFY(check, TRUE, "H5S__internal_consistency_test"); - /* Check with unlimited dimension clipped to 6 */ - dims[1] = 6; - eblock1[4] = 3; - eblock2[4] = 5; - test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + /* Close dataspaces */ + ret = H5Sclose(all_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(none_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(single_pt_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(mult_pt_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(single_hyper_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(single_hyper_all_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(single_hyper_pt_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(regular_hyper_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(irreg_hyper_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(none_hyper_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(scalar_all_sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(scalar_none_sid); + CHECK(ret, FAIL, "H5Sclose"); +} /* test_internal_consistency() */ - /* Set offset of selection */ - offset[1] = (hssize_t)-1; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); +/**************************************************************** +** +** test_irreg_io(): Tests unusual selections on datasets, to stress the +** new hyperslab code. +** +****************************************************************/ +static void +test_irreg_io(void) +{ + hid_t fid; /* File ID */ + hid_t did; /* Dataset ID */ + hid_t dcpl_id; /* Dataset creation property list ID */ + hid_t sid; /* File dataspace ID */ + hid_t mem_sid; /* Memory dataspace ID */ + hsize_t dims[] = {6, 12}; /* Dataspace dimensions */ + hsize_t chunk_dims[] = {2, 2}; /* Chunk dimensions */ + hsize_t mem_dims[] = {32}; /* Memory dataspace dimensions */ + hsize_t start[2]; /* Hyperslab start */ + hsize_t stride[2]; /* Hyperslab stride */ + hsize_t count[2]; /* Hyperslab block count */ + hsize_t block[2]; /* Hyperslab block size */ + unsigned char wbuf[72]; /* Write buffer */ + unsigned char rbuf[32]; /* Read buffer */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ - /* Check with adjusted offset (should not affect result) */ - test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + /* Output message about test being performed */ + MESSAGE(6, ("Testing Irregular Hyperslab I/O\n")); - /* Set offset of selection */ - offset[1] = (hssize_t)3; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Create file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); - /* Check with adjusted offset (should not affect result) */ - test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); + /* Create dataspace for dataset */ + sid = H5Screate_simple(2, dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); - /* Reset offset of selection */ - offset[1] = (hssize_t)0; - ret = H5Soffset_simple(sid, offset); - CHECK(ret, FAIL, "H5Soffset_simple"); + /* Set chunk dimensions for dataset */ + dcpl_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl_id, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl_id, 2, chunk_dims); + CHECK(ret, FAIL, "H5Pset_chunk"); - /* - * Now try invalid operations - */ - H5E_BEGIN_TRY { - /* Try multiple unlimited dimensions */ - start[0] = 1; - start[1] = 2; - start[2] = 1; - stride[0] = 1; - stride[1] = 3; - stride[2] = 3; - count[0] = 1; - count[1] = H5S_UNLIMITED; - count[2] = H5S_UNLIMITED; - block[0] = 2; - block[1] = 2; - block[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); + /* Create a dataset */ + did = H5Dcreate2(fid, SPACE1_NAME, H5T_NATIVE_UCHAR, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); - /* Try unlimited count and block */ - count[2] = 2; - block[1] = H5S_UNLIMITED; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - } H5E_END_TRY + /* Initialize the write buffer */ + for(u = 0; u < 72; u++) + wbuf[u] = (unsigned char)u; - /* Try operations with two unlimited selections */ - block[1] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - H5E_BEGIN_TRY { - ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, count, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, NULL, count, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, count, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, count, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, NULL, count, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - } H5E_END_TRY + /* Write entire dataset to disk */ + ret = H5Dwrite(did, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf); + CHECK(ret, FAIL, "H5Dwrite"); - /* Try invalid combination operations */ - H5E_BEGIN_TRY { - ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, NULL, block, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, NULL, block, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, NULL, block, NULL); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - } H5E_END_TRY - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL, block, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - H5E_BEGIN_TRY { - ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start, stride, count, block); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start, stride, count, block); - VERIFY(ret, FAIL, "H5Sselect_hyperslab"); - } H5E_END_TRY + /* Close the DCPL */ + ret = H5Pclose(dcpl_id); + CHECK(ret, FAIL, "H5Pclose"); - /* - * Now test valid combination operations - */ - /* unlim AND non-unlim */ - count[0] = 1; - count[1] = H5S_UNLIMITED; - count[2] = 2; - block[0] = 2; - block[1] = 2; - block[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - start2[0] = 2; - start2[1] = 2; - start2[2] = 0; - count2[0] = 5; - count2[1] = 4; - count2[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start2, NULL, count2, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - eblock1[0] = 2; - eblock1[3] = 2; - eblock1[1] = 2; - eblock1[4] = 3; - eblock1[2] = 1; - eblock1[5] = 1; - eblock2[0] = 2; - eblock2[3] = 2; - eblock2[1] = 5; - eblock2[4] = 5; - eblock2[2] = 1; - eblock2[5] = 1; - dims[0] = 50; - dims[1] = 50; - dims[2] = 50; - test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); + /* Create dataspace for memory selection */ + mem_sid = H5Screate_simple(1, mem_dims, NULL); + CHECK(mem_sid, FAIL, "H5Screate_simple"); - /* unlim NOTA non-unlim */ - count[0] = 1; - count[1] = H5S_UNLIMITED; - count[2] = 2; - block[0] = 2; - block[1] = 2; - block[2] = 2; + /* Select 'L'-shaped region within dataset */ + start[0] = 0; start[1] = 10; + stride[0] = 1; stride[1] = 1; + count[0] = 4; count[1] = 2; + block[0] = 1; block[1] = 1; ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - start2[0] = 1; - start2[1] = 5; - start2[2] = 2; - count2[0] = 2; - count2[1] = 2; - count2[2] = 6; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTA, start2, NULL, count2, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - eblock1[0] = 1; - eblock1[3] = 2; - eblock1[1] = 5; - eblock1[4] = 6; - eblock1[2] = 3; - eblock1[5] = 3; - eblock2[0] = 1; - eblock2[3] = 2; - eblock2[1] = 5; - eblock2[4] = 6; - eblock2[2] = 6; - eblock2[5] = 7; - dims[0] = 50; - dims[1] = 50; - dims[2] = 50; - test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); - - /* non-unlim AND unlim */ - start2[0] = 2; - start2[1] = 2; - start2[2] = 0; - count2[0] = 5; - count2[1] = 4; - count2[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - count[0] = 1; - count[1] = H5S_UNLIMITED; - count[2] = 2; - block[0] = 2; - block[1] = 2; - block[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_AND, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - eblock1[0] = 2; - eblock1[3] = 2; - eblock1[1] = 2; - eblock1[4] = 3; - eblock1[2] = 1; - eblock1[5] = 1; - eblock2[0] = 2; - eblock2[3] = 2; - eblock2[1] = 5; - eblock2[4] = 5; - eblock2[2] = 1; - eblock2[5] = 1; - dims[0] = 50; - dims[1] = 50; - dims[2] = 50; - test_hyper_unlim_check(sid, dims, (hssize_t)3, (hssize_t)2, eblock1, eblock2); - /* non-unlim NOTB unlim */ - start2[0] = 1; - start2[1] = 5; - start2[2] = 2; - count2[0] = 2; - count2[1] = 2; - count2[2] = 6; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start2, NULL, count2, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - count[0] = 1; - count[1] = H5S_UNLIMITED; - count[2] = 2; - block[0] = 2; - block[1] = 2; - block[2] = 2; - ret = H5Sselect_hyperslab(sid, H5S_SELECT_NOTB, start, stride, count, block); + start[0] = 4; start[1] = 0; + stride[0] = 1; stride[1] = 1; + count[0] = 2; count[1] = 12; + block[0] = 1; block[1] = 1; + ret = H5Sselect_hyperslab(sid, H5S_SELECT_OR, start, stride, count, block); CHECK(ret, FAIL, "H5Sselect_hyperslab"); - eblock1[0] = 1; - eblock1[3] = 2; - eblock1[1] = 5; - eblock1[4] = 6; - eblock1[2] = 3; - eblock1[5] = 3; - eblock2[0] = 1; - eblock2[3] = 2; - eblock2[1] = 5; - eblock2[4] = 6; - eblock2[2] = 6; - eblock2[5] = 7; - dims[0] = 50; - dims[1] = 50; - dims[2] = 50; - test_hyper_unlim_check(sid, dims, (hssize_t)12, (hssize_t)2, eblock1, eblock2); - /* Test H5Sget_select_npoints() */ - ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - ssize_out = H5Sget_select_npoints(sid); - VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_npoints"); + /* Reset the buffer */ + HDmemset(rbuf, 0, sizeof(rbuf)); - /* Test H5Sget_select_hyper_nblocks() */ - ssize_out = H5Sget_select_hyper_nblocks(sid); - VERIFY(ssize_out, (hssize_t)H5S_UNLIMITED, "H5Sget_select_hyper_nblocks"); + /* Read selection from disk */ + ret = H5Dread(did, H5T_NATIVE_UCHAR, mem_sid, sid, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); - /* Test H5Sget_select_bounds() */ - ret = H5Sget_select_bounds(sid, start2, count2); - CHECK(ret, FAIL, "H5Sget_select_bounds"); - VERIFY(start2[0], start[0], "H5Sget_select_bounds"); - VERIFY(start2[1], start[1], "H5Sget_select_bounds"); - VERIFY(start2[2], start[2], "H5Sget_select_bounds"); - VERIFY(count2[0], (long)(start[0] + (stride[0] * (count[0] - 1)) + block[0] - 1), "H5Sget_select_bounds"); - VERIFY(count2[1], H5S_UNLIMITED, "H5Sget_select_bounds"); - VERIFY(count2[2], (long)(start[2] + (stride[2] * (count[2] - 1)) + block[2] - 1), "H5Sget_select_bounds"); - /* Close the dataspace */ + /* Close everything */ + ret = H5Sclose(mem_sid); + CHECK(ret, FAIL, "H5Sclose"); ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); -} /* end test_hyper_unlim() */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_irreg_io() */ /**************************************************************** ** @@ -13382,6 +14594,8 @@ test_select(void) /* Test "re-build" routine */ test_space_rebuild(); + /* Test "update diminfo" routine */ + test_space_update_diminfo(); /* Test point selections in chunked datasets */ test_select_point_chunk(); @@ -13402,6 +14616,12 @@ test_select(void) /* Test unlimited hyperslab selections */ test_hyper_unlim(); + /* Test the consistency of internal data structures of selection */ + test_internal_consistency(); + + /* Test irregular selection I/O */ + test_irreg_io(); + } /* test_select() */ -- cgit v0.12 From a98747c0f94386f7505210e78cd4b385682b0eba Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Sat, 16 Mar 2019 08:06:52 -0700 Subject: Added an H5MM_memcpy call that checks for buffer overlap. --- src/H5Abtree2.c | 8 +++--- src/H5Aint.c | 20 +++++++------- src/H5B.c | 52 ++++++++++++++++++------------------ src/H5B2.c | 8 +++--- src/H5B2cache.c | 6 ++--- src/H5B2int.c | 74 ++++++++++++++++++++++++++-------------------------- src/H5B2leaf.c | 14 +++++----- src/H5Bcache.c | 2 +- src/H5C.c | 14 +++++----- src/H5CX.c | 12 ++++----- src/H5Cimage.c | 12 ++++----- src/H5Dbtree.c | 4 +-- src/H5Dbtree2.c | 2 +- src/H5Dchunk.c | 42 ++++++++++++++--------------- src/H5Dcompact.c | 10 +++---- src/H5Dcontig.c | 22 ++++++++-------- src/H5Dearray.c | 6 ++--- src/H5Defl.c | 2 +- src/H5Dfill.c | 6 ++--- src/H5Dint.c | 14 +++++----- src/H5Dmpio.c | 20 +++++++------- src/H5Dscatgath.c | 8 +++--- src/H5Dvirtual.c | 6 ++--- src/H5EA.c | 4 +-- src/H5EAcache.c | 12 ++++----- src/H5EAhdr.c | 2 +- src/H5EAstat.c | 2 +- src/H5FA.c | 8 +++--- src/H5FAcache.c | 8 +++--- src/H5FAhdr.c | 2 +- src/H5FAstat.c | 2 +- src/H5FD.c | 4 +-- src/H5FDcore.c | 6 ++--- src/H5FDdirect.c | 10 +++---- src/H5FDfamily.c | 2 +- src/H5FDlog.c | 2 +- src/H5FDmpio.c | 2 +- src/H5FL.c | 4 +-- src/H5FS.c | 2 +- src/H5FScache.c | 4 +-- src/H5Faccum.c | 20 +++++++------- src/H5Fint.c | 2 +- src/H5Fprivate.h | 4 +-- src/H5Fsuper.c | 2 +- src/H5Fsuper_cache.c | 4 +-- src/H5Gbtree2.c | 12 ++++----- src/H5Gcache.c | 2 +- src/H5Gent.c | 2 +- src/H5Gname.c | 2 +- src/H5Gnode.c | 4 +-- src/H5Gtraverse.c | 4 +-- src/H5HF.c | 4 +-- src/H5HFcache.c | 20 +++++++------- src/H5HFhdr.c | 2 +- src/H5HFhuge.c | 4 +-- src/H5HFman.c | 2 +- src/H5HFsection.c | 8 +++--- src/H5HFtest.c | 2 +- src/H5HFtiny.c | 2 +- src/H5HG.c | 6 ++--- src/H5HGcache.c | 4 +-- src/H5HL.c | 2 +- src/H5HLcache.c | 10 +++---- src/H5L.c | 4 +-- src/H5Lexternal.c | 2 +- src/H5MM.c | 42 +++++++++++++++++++++++++---- src/H5MMprivate.h | 1 + src/H5Oalloc.c | 10 +++---- src/H5Oattr.c | 8 +++--- src/H5Oattribute.c | 2 +- src/H5Ocache.c | 6 ++--- src/H5Ocopy.c | 4 +-- src/H5Odrvinfo.c | 10 +++---- src/H5Odtype.c | 8 +++--- src/H5Oefl.c | 4 +-- src/H5Ofill.c | 16 ++++++------ src/H5Oint.c | 4 +-- src/H5Olayout.c | 12 ++++----- src/H5Olink.c | 14 +++++----- src/H5Opline.c | 4 +-- src/H5Oshared.c | 4 +-- src/H5PB.c | 20 +++++++------- src/H5Pdapl.c | 4 +-- src/H5Pdcpl.c | 26 +++++++++--------- src/H5Pdxpl.c | 2 +- src/H5Pfapl.c | 20 +++++++------- src/H5Pint.c | 34 ++++++++++++------------ src/H5Plapl.c | 2 +- src/H5Pocpl.c | 2 +- src/H5Pocpypl.c | 2 +- src/H5S.c | 2 +- src/H5SL.c | 4 +-- src/H5SM.c | 4 +-- src/H5SMbtree2.c | 2 +- src/H5SMcache.c | 4 +-- src/H5SMmessage.c | 4 +-- src/H5Shyper.c | 20 +++++++------- src/H5Spoint.c | 18 ++++++------- src/H5Sselect.c | 16 ++++++------ src/H5T.c | 4 +-- src/H5Tcommit.c | 4 +-- src/H5Tconv.c | 22 ++++++++-------- src/H5Tenum.c | 6 ++--- src/H5Tfields.c | 12 ++++----- src/H5Tnative.c | 2 +- src/H5Tvlen.c | 34 ++++++++++++------------ src/H5VLcallback.c | 2 +- src/H5VLint.c | 2 +- src/H5VM.c | 22 ++++++++-------- src/H5VMprivate.h | 2 +- src/H5Z.c | 4 +-- src/H5Zfletcher32.c | 6 ++--- src/H5Zscaleoffset.c | 24 ++++++++--------- src/H5Zshuffle.c | 4 +-- src/H5Ztrans.c | 4 +-- 115 files changed, 546 insertions(+), 513 deletions(-) diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index 07da8e2..825043b 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -318,7 +318,7 @@ H5A__dense_btree2_name_encode(uint8_t *raw, const void *_nrecord, void H5_ATTR_U FUNC_ENTER_STATIC_NOERR /* Encode the record's fields */ - HDmemcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); raw += H5O_FHEAP_ID_LEN; *raw++ = nrecord->flags; UINT32ENCODE(raw, nrecord->corder) @@ -349,7 +349,7 @@ H5A__dense_btree2_name_decode(const uint8_t *raw, void *_nrecord, void H5_ATTR_U FUNC_ENTER_STATIC_NOERR /* Decode the record's fields */ - HDmemcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); raw += H5O_FHEAP_ID_LEN; nrecord->flags = *raw++; UINT32DECODE(raw, nrecord->corder) @@ -477,7 +477,7 @@ H5A__dense_btree2_corder_encode(uint8_t *raw, const void *_nrecord, void H5_ATTR FUNC_ENTER_STATIC_NOERR /* Encode the record's fields */ - HDmemcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(raw, nrecord->id.id, (size_t)H5O_FHEAP_ID_LEN); raw += H5O_FHEAP_ID_LEN; *raw++ = nrecord->flags; UINT32ENCODE(raw, nrecord->corder) @@ -507,7 +507,7 @@ H5A__dense_btree2_corder_decode(const uint8_t *raw, void *_nrecord, void H5_ATTR FUNC_ENTER_STATIC_NOERR /* Decode the record's fields */ - HDmemcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id.id, raw, (size_t)H5O_FHEAP_ID_LEN); raw += H5O_FHEAP_ID_LEN; nrecord->flags = *raw++; UINT32DECODE(raw, nrecord->corder) diff --git a/src/H5Aint.c b/src/H5Aint.c index 6502fa4..88a4780 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -646,21 +646,21 @@ H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf) HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the attribute data into the buffer for conversion */ - HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); + H5MM_memcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); /* Perform datatype conversion. */ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") /* Copy the converted data into the user's buffer */ - HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts)); + H5MM_memcpy(buf, tconv_buf, (dst_type_size * nelmts)); } /* end if */ /* No type conversion necessary */ else { HDassert(dst_type_size == src_type_size); /* Copy the attribute data into the user's buffer */ - HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts)); + H5MM_memcpy(buf, attr->shared->data, (dst_type_size * nelmts)); } /* end else */ } /* end else */ } /* end if */ @@ -747,7 +747,7 @@ H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf) HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") /* Copy the user's data into the buffer for conversion */ - HDmemcpy(tconv_buf, buf, (src_type_size * nelmts)); + H5MM_memcpy(tconv_buf, buf, (src_type_size * nelmts)); /* Perform datatype conversion */ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf) < 0) @@ -771,7 +771,7 @@ H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the attribute data into the user's buffer */ - HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts)); + H5MM_memcpy(attr->shared->data, buf, (dst_type_size * nelmts)); } /* end else */ /* Modify the attribute in the object header */ @@ -827,7 +827,7 @@ H5A__get_name(H5A_t *attr, size_t buf_size, char *buf) /* Copy all/some of the name */ if(buf && copy_len > 0) { - HDmemcpy(buf, attr->shared->name, copy_len); + H5MM_memcpy(buf, attr->shared->name, copy_len); /* Terminate the string */ buf[copy_len]='\0'; @@ -2240,7 +2240,7 @@ H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_s if(NULL == (buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation NULLed for raw data chunk") - HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size); + H5MM_memcpy(buf, attr_src->shared->data, attr_src->shared->data_size); /* Allocate background memory */ if(H5T_path_bkg(tpath_src_mem) || H5T_path_bkg(tpath_mem_dst)) @@ -2251,7 +2251,7 @@ H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_s if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg_buf) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed") - HDmemcpy(reclaim_buf, buf, buf_size); + H5MM_memcpy(reclaim_buf, buf, buf_size); /* Set background buffer to all zeros */ if(bkg_buf) @@ -2261,14 +2261,14 @@ H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_s if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg_buf) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed") - HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size); + H5MM_memcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size); if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, NULL, "unable to reclaim variable-length data") } /* end if */ else { HDassert(attr_dst->shared->data_size == attr_src->shared->data_size); - HDmemcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size); + H5MM_memcpy(attr_dst->shared->data, attr_src->shared->data, attr_src->shared->data_size); } /* end else */ } /* end if(attr_src->shared->data) */ diff --git a/src/H5B.c b/src/H5B.c index 2772bb9..4cf1f72 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -484,10 +484,10 @@ H5B__split(H5F_t *f, H5B_ins_ud_t *bt_ud, unsigned idx, */ split_bt_ud->cache_flags = H5AC__DIRTIED_FLAG; - HDmemcpy(split_bt_ud->bt->native, + H5MM_memcpy(split_bt_ud->bt->native, bt_ud->bt->native + nleft * shared->type->sizeof_nkey, (nright + 1) * shared->type->sizeof_nkey); - HDmemcpy(split_bt_ud->bt->child, + H5MM_memcpy(split_bt_ud->bt->child, &bt_ud->bt->child[nleft], nright * sizeof(haddr_t)); @@ -612,9 +612,9 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) /* update left and right keys */ if(!lt_key_changed) - HDmemcpy(lt_key, H5B_NKEY(bt_ud.bt,shared,0), type->sizeof_nkey); + H5MM_memcpy(lt_key, H5B_NKEY(bt_ud.bt,shared,0), type->sizeof_nkey); if(!rt_key_changed) - HDmemcpy(rt_key, H5B_NKEY(split_bt_ud.bt,shared,split_bt_ud.bt->nchildren), type->sizeof_nkey); + H5MM_memcpy(rt_key, H5B_NKEY(split_bt_ud.bt,shared,split_bt_ud.bt->nchildren), type->sizeof_nkey); /* * Copy the old root node to some other file location and make the new root @@ -657,11 +657,11 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) new_root_bt->nchildren = 2; new_root_bt->child[0] = bt_ud.addr; - HDmemcpy(H5B_NKEY(new_root_bt, shared, 0), lt_key, shared->type->sizeof_nkey); + H5MM_memcpy(H5B_NKEY(new_root_bt, shared, 0), lt_key, shared->type->sizeof_nkey); new_root_bt->child[1] = split_bt_ud.addr; - HDmemcpy(H5B_NKEY(new_root_bt, shared, 1), md_key, shared->type->sizeof_nkey); - HDmemcpy(H5B_NKEY(new_root_bt, shared, 2), rt_key, shared->type->sizeof_nkey); + H5MM_memcpy(H5B_NKEY(new_root_bt, shared, 1), md_key, shared->type->sizeof_nkey); + H5MM_memcpy(H5B_NKEY(new_root_bt, shared, 2), rt_key, shared->type->sizeof_nkey); /* Insert the modified copy of the old root into the file again */ if(H5AC_insert_entry(f, H5AC_BT, addr, new_root_bt, H5AC__NO_FLAGS_SET) < 0) @@ -726,9 +726,9 @@ H5B__insert_child(H5B_t *bt, unsigned *bt_flags, unsigned idx, base = H5B_NKEY(bt, shared, (idx + 1)); if((idx + 1) == bt->nchildren) { /* Make room for the new key */ - HDmemcpy(base + shared->type->sizeof_nkey, base, + H5MM_memcpy(base + shared->type->sizeof_nkey, base, shared->type->sizeof_nkey); /* No overlap possible - memcpy() OK */ - HDmemcpy(base, md_key, shared->type->sizeof_nkey); + H5MM_memcpy(base, md_key, shared->type->sizeof_nkey); /* The MD_KEY is the left key of the new node */ if(H5B_INS_RIGHT == anchor) @@ -741,7 +741,7 @@ H5B__insert_child(H5B_t *bt, unsigned *bt_flags, unsigned idx, /* Make room for the new key */ HDmemmove(base + shared->type->sizeof_nkey, base, (bt->nchildren - idx) * shared->type->sizeof_nkey); - HDmemcpy(base, md_key, shared->type->sizeof_nkey); + H5MM_memcpy(base, md_key, shared->type->sizeof_nkey); /* The MD_KEY is the left key of the new node */ if(H5B_INS_RIGHT == anchor) @@ -915,7 +915,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, * node. This node is not empty (handled above). */ my_ins = H5B_INS_LEFT; - HDmemcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey); + H5MM_memcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey); if((type->new_node)(f, H5B_INS_LEFT, H5B_NKEY(bt, shared, idx), udata, md_key, &new_child_bt_ud.addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") @@ -963,7 +963,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, */ idx = bt->nchildren - 1; my_ins = H5B_INS_RIGHT; - HDmemcpy(md_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + H5MM_memcpy(md_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); if((type->new_node)(f, H5B_INS_RIGHT, md_key, udata, H5B_NKEY(bt, shared, idx + 1), &new_child_bt_ud.addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") @@ -1021,7 +1021,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, *lt_key_changed = FALSE; } /* end if */ else - HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); + H5MM_memcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); } /* end if */ if(*rt_key_changed) { bt_ud->cache_flags |= H5AC__DIRTIED_FLAG; @@ -1031,7 +1031,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, *rt_key_changed = FALSE; } /* end if */ else - HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + H5MM_memcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); } /* end if */ /* @@ -1080,7 +1080,7 @@ H5B__insert_helper(H5F_t *f, H5B_ins_ud_t *bt_ud, const H5B_class_t *type, * by the left and right node). */ if(split_bt_ud->bt) { - HDmemcpy(md_key, H5B_NKEY(split_bt_ud->bt, shared, 0), type->sizeof_nkey); + H5MM_memcpy(md_key, H5B_NKEY(split_bt_ud->bt, shared, 0), type->sizeof_nkey); ret_value = H5B_INS_RIGHT; #ifdef H5B_DEBUG /* @@ -1339,7 +1339,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, /* Don't propagate change out of this B-tree node */ *lt_key_changed = FALSE; else - HDmemcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); + H5MM_memcpy(lt_key, H5B_NKEY(bt, shared, idx), type->sizeof_nkey); } /* end if */ if(*rt_key_changed) { HDassert(type->critical_key == H5B_RIGHT); @@ -1348,7 +1348,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, /* Don't propagate change out of this B-tree node */ *rt_key_changed = FALSE; else - HDmemcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); + H5MM_memcpy(rt_key, H5B_NKEY(bt, shared, idx + 1), type->sizeof_nkey); } /* end if */ /* @@ -1383,7 +1383,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, * in its left neighbor, but only if it is not the critical * key for the right-most child of the left neighbor */ if(type->critical_key == H5B_LEFT) - HDmemcpy(H5B_NKEY(sibling, shared, sibling->nchildren), + H5MM_memcpy(H5B_NKEY(sibling, shared, sibling->nchildren), H5B_NKEY(bt, shared, 1), type->sizeof_nkey); sibling->right = bt->right; @@ -1400,7 +1400,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, * its right neighbor, but only if it is not the critical * key for the left-most child of the right neighbor */ if(type->critical_key == H5B_RIGHT) - HDmemcpy(H5B_NKEY(sibling, shared, 0), + H5MM_memcpy(H5B_NKEY(sibling, shared, 0), H5B_NKEY(bt, shared, 0), type->sizeof_nkey); sibling->left = bt->left; @@ -1442,7 +1442,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, /* Slide all keys down 1, update lt_key */ HDmemmove(H5B_NKEY(bt, shared, 0), H5B_NKEY(bt, shared, 1), bt->nchildren * type->sizeof_nkey); - HDmemcpy(lt_key, H5B_NKEY(bt, shared, 0), type->sizeof_nkey); + H5MM_memcpy(lt_key, H5B_NKEY(bt, shared, 0), type->sizeof_nkey); *lt_key_changed = TRUE; } else /* Slide all but the leftmost 2 keys down, leaving the leftmost @@ -1471,7 +1471,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); else { /* Just update rt_key */ - HDmemcpy(rt_key, H5B_NKEY(bt, shared, bt->nchildren - 1), + H5MM_memcpy(rt_key, H5B_NKEY(bt, shared, bt->nchildren - 1), type->sizeof_nkey); *rt_key_changed = TRUE; } /* end else */ @@ -1516,7 +1516,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, if(NULL == (sibling = (H5B_t *)H5AC_protect(f, H5AC_BT, bt->left, &cache_udata, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to protect node") - HDmemcpy(H5B_NKEY(sibling, shared, sibling->nchildren), + H5MM_memcpy(H5B_NKEY(sibling, shared, sibling->nchildren), H5B_NKEY(bt, shared, 0), type->sizeof_nkey); if(H5AC_unprotect(f, H5AC_BT, bt->left, sibling, H5AC__DIRTIED_FLAG) < 0) @@ -1531,7 +1531,7 @@ H5B__remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, int level, if(NULL == (sibling = (H5B_t *)H5AC_protect(f, H5AC_BT, bt->right, &cache_udata, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, H5B_INS_ERROR, "unable to protect node") - HDmemcpy(H5B_NKEY(sibling, shared, 0), + H5MM_memcpy(H5B_NKEY(sibling, shared, 0), H5B_NKEY(bt, shared, bt->nchildren), type->sizeof_nkey); if(H5AC_unprotect(f, H5AC_BT, bt->right, sibling, H5AC__DIRTIED_FLAG) < 0) @@ -1811,7 +1811,7 @@ H5B__copy(const H5B_t *old_bt) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree root node") /* Copy the main structure */ - HDmemcpy(new_node, old_bt, sizeof(H5B_t)); + H5MM_memcpy(new_node, old_bt, sizeof(H5B_t)); /* Reset cache info */ HDmemset(&new_node->cache_info, 0, sizeof(H5AC_info_t)); @@ -1821,8 +1821,8 @@ H5B__copy(const H5B_t *old_bt) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree root node") /* Copy the other structures */ - HDmemcpy(new_node->native, old_bt->native, shared->sizeof_keys); - HDmemcpy(new_node->child, old_bt->child, (sizeof(haddr_t) * shared->two_k)); + H5MM_memcpy(new_node->native, old_bt->native, shared->sizeof_keys); + H5MM_memcpy(new_node->child, old_bt->child, (sizeof(haddr_t) * shared->two_k)); /* Increment the ref-count on the raw page */ H5UC_INC(new_node->rc_shared); diff --git a/src/H5B2.c b/src/H5B2.c index cf8e4a9..6b0d7a3 100644 --- a/src/H5B2.c +++ b/src/H5B2.c @@ -662,7 +662,7 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) if(hdr->min_native_rec == NULL) if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info") - HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ if(idx == (unsigned)(leaf->nrec - 1)) { @@ -670,7 +670,7 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) if(hdr->max_native_rec == NULL) if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info") - HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ } /* end if */ @@ -1343,7 +1343,7 @@ H5B2_modify(H5B2_t *bt2, void *udata, H5B2_modify_t op, void *op_data) if(hdr->min_native_rec == NULL) if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info") - HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ if(idx == (unsigned)(leaf->nrec - 1)) { @@ -1351,7 +1351,7 @@ H5B2_modify(H5B2_t *bt2, void *udata, H5B2_modify_t op, void *op_data) if(hdr->max_native_rec == NULL) if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info") - HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ } /* end if */ diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 2e1d37b..2a77bd5 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -391,7 +391,7 @@ H5B2__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED le HDassert(hdr); /* Magic number */ - HDmemcpy(image, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -811,7 +811,7 @@ H5B2__cache_int_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED le HDassert(internal->hdr); /* Magic number */ - HDmemcpy(image, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1212,7 +1212,7 @@ H5B2__cache_leaf_serialize(const H5F_t H5_ATTR_UNUSED *f, void *_image, size_t H HDassert(leaf->hdr); /* magic number */ - HDmemcpy(image, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* version # */ diff --git a/src/H5B2int.c b/src/H5B2int.c index b3f855f..a6dfe0e 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -241,17 +241,17 @@ H5B2__split1(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, mid_record = old_node_nrec / 2; /* Copy "upper half" of records to new child */ - HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), + H5MM_memcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, mid_record + (unsigned)1), hdr->cls->nrec_size * (old_node_nrec - (mid_record + (unsigned)1))); /* Copy "upper half" of node pointers, if the node is an internal node */ if(depth > 1) - HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + (unsigned)1]), + H5MM_memcpy(&(right_node_ptrs[0]), &(left_node_ptrs[mid_record + (unsigned)1]), sizeof(H5B2_node_ptr_t) * (size_t)(old_node_nrec - mid_record)); /* Copy "middle" record to internal node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, mid_record), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, mid_record), hdr->cls->nrec_size); /* Mark nodes as dirty */ left_child_flags |= H5AC__DIRTIED_FLAG; @@ -510,14 +510,14 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, uint16_t move_nrec = (uint16_t)(*right_nrec - new_right_nrec); /* Number of records to move from right node to left */ /* Copy record from parent node down into left child */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* See if we need to move records from right node */ if(move_nrec > 1) - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, (*left_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (size_t)(move_nrec - 1)); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, (*left_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (size_t)(move_nrec - 1)); /* Move record from right node into parent node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), hdr->cls->nrec_size); /* Slide records in right node down */ HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, move_nrec), hdr->cls->nrec_size * new_right_nrec); @@ -534,7 +534,7 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, right_moved_nrec -= (hssize_t)moved_nrec; /* Copy node pointers from right node to left */ - HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * move_nrec); + H5MM_memcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * move_nrec); /* Slide node pointers in right node down */ HDmemmove(&(right_node_ptrs[0]), &(right_node_ptrs[move_nrec]), sizeof(H5B2_node_ptr_t) * (new_right_nrec + (unsigned)1)); @@ -569,14 +569,14 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, hdr->cls->nrec_size * (*right_nrec)); /* Copy record from parent node down into right child */ - HDmemcpy(H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(right_native, hdr, (move_nrec - 1)), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* See if we need to move records from left node */ if(move_nrec > 1) - HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, ((*left_nrec - move_nrec) + 1)), hdr->cls->nrec_size * (size_t)(move_nrec - 1)); + H5MM_memcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, ((*left_nrec - move_nrec) + 1)), hdr->cls->nrec_size * (size_t)(move_nrec - 1)); /* Move record from left node into parent node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, (*left_nrec - move_nrec)), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(left_native, hdr, (*left_nrec - move_nrec)), hdr->cls->nrec_size); /* Handle node pointers, if we have an internal node */ if(depth > 1) { @@ -587,7 +587,7 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, HDmemmove(&(right_node_ptrs[move_nrec]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); /* Copy node pointers from left node to right */ - HDmemcpy(&(right_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * move_nrec); + H5MM_memcpy(&(right_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * move_nrec); /* Count the number of records being moved */ for(u = 0; u < move_nrec; u++) @@ -775,16 +775,16 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, uint16_t moved_middle_nrec = 0; /* Number of records moved into left node */ /* Move left parent record down to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Move records from middle node into left node */ if((new_left_nrec - 1) > *left_nrec) { moved_middle_nrec = (uint16_t)(new_left_nrec - (*left_nrec + 1)); - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * moved_middle_nrec); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * moved_middle_nrec); } /* end if */ /* Move record from middle node up to parent node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, moved_middle_nrec), hdr->cls->nrec_size); moved_middle_nrec++; /* Slide records in middle node down */ @@ -798,7 +798,7 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, /* Move middle node pointers into left node */ move_nptrs = (unsigned)(new_left_nrec - *left_nrec); - HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t)*move_nptrs); + H5MM_memcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t)*move_nptrs); /* Count the number of records being moved into the left node */ for(u = 0, moved_nrec = 0; u < move_nptrs; u++) @@ -832,14 +832,14 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, HDmemmove(H5B2_NAT_NREC(right_native, hdr, right_nrec_move), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Move right parent record down to right node */ - HDmemcpy(H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Move records from middle node into right node */ if(right_nrec_move > 1) - HDmemcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, ((curr_middle_nrec - right_nrec_move) + 1)), hdr->cls->nrec_size * (right_nrec_move - 1)); + H5MM_memcpy(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, ((curr_middle_nrec - right_nrec_move) + 1)), hdr->cls->nrec_size * (right_nrec_move - 1)); /* Move record from middle node up to parent node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec - right_nrec_move)), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec - right_nrec_move)), hdr->cls->nrec_size); /* Move node pointers also if this is an internal node */ if(depth > 1) { @@ -850,7 +850,7 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, HDmemmove(&(right_node_ptrs[right_nrec_move]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); /* Move middle node pointers into right node */ - HDmemcpy(&(right_node_ptrs[0]), &(middle_node_ptrs[(curr_middle_nrec - right_nrec_move) + 1]), sizeof(H5B2_node_ptr_t) * right_nrec_move); + H5MM_memcpy(&(right_node_ptrs[0]), &(middle_node_ptrs[(curr_middle_nrec - right_nrec_move) + 1]), sizeof(H5B2_node_ptr_t) * right_nrec_move); /* Count the number of records being moved into the right node */ for(u = 0, moved_nrec = 0; u < right_nrec_move; u++) @@ -881,14 +881,14 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, HDmemmove(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * curr_middle_nrec); /* Move left parent record down to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(middle_native, hdr, left_nrec_move - 1), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Move left records to middle node */ if(left_nrec_move > 1) HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(left_native, hdr, new_left_nrec + 1), hdr->cls->nrec_size * (left_nrec_move - 1)); /* Move left parent record up from left node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(left_native, hdr, new_left_nrec), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(left_native, hdr, new_left_nrec), hdr->cls->nrec_size); /* Move node pointers also if this is an internal node */ if(depth > 1) { @@ -899,7 +899,7 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, HDmemmove(&(middle_node_ptrs[left_nrec_move]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(curr_middle_nrec + 1)); /* Move left node pointers into middle node */ - HDmemcpy(&(middle_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * left_nrec_move); + H5MM_memcpy(&(middle_node_ptrs[0]), &(left_node_ptrs[new_left_nrec + 1]), sizeof(H5B2_node_ptr_t) * left_nrec_move); /* Count the number of records being moved into the left node */ for(u = 0, moved_nrec = 0; u < left_nrec_move; u++) @@ -927,13 +927,13 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, unsigned right_nrec_move = (unsigned)(*right_nrec - new_right_nrec); /* Number of records to move out of right node */ /* Move right parent record down to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, curr_middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(middle_native, hdr, curr_middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Move right records to middle node */ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, (curr_middle_nrec + 1)), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (right_nrec_move - 1)); /* Move right parent record up from right node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx), H5B2_NAT_NREC(right_native, hdr, right_nrec_move - 1), hdr->cls->nrec_size); /* Slide right records down */ HDmemmove(H5B2_NAT_NREC(right_native, hdr, 0), H5B2_NAT_NREC(right_native, hdr, right_nrec_move), hdr->cls->nrec_size * new_right_nrec); @@ -944,7 +944,7 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, unsigned u; /* Local index variable */ /* Move right node pointers into middle node */ - HDmemcpy(&(middle_node_ptrs[curr_middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * right_nrec_move); + H5MM_memcpy(&(middle_node_ptrs[curr_middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * right_nrec_move); /* Count the number of records being moved into the right node */ for(u = 0, moved_nrec = 0; u < right_nrec_move; u++) @@ -1113,14 +1113,14 @@ H5B2__merge2(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, /* Redistribute records into left node */ { /* Copy record from parent node to proper location */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Copy records from right node to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Copy node pointers from right node into left node */ if(depth > 1) - HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); + H5MM_memcpy(&(left_node_ptrs[*left_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); /* Update flush dependencies for grandchildren, if using SWMR */ if(hdr->swmr_write && depth > 1) @@ -1304,13 +1304,13 @@ H5B2__merge3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, middle_moved_nrec = middle_nrec_move; /* Copy record from parent node to proper location in left node */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec), H5B2_INT_NREC(internal, hdr, idx - 1), hdr->cls->nrec_size); /* Copy records from middle node to left node */ - HDmemcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * (middle_nrec_move - 1)); + H5MM_memcpy(H5B2_NAT_NREC(left_native, hdr, *left_nrec + 1), H5B2_NAT_NREC(middle_native, hdr, 0), hdr->cls->nrec_size * (middle_nrec_move - 1)); /* Copy record from middle node to proper location in parent node */ - HDmemcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, (middle_nrec_move - 1)), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_INT_NREC(internal, hdr, idx - 1), H5B2_NAT_NREC(middle_native, hdr, (middle_nrec_move - 1)), hdr->cls->nrec_size); /* Slide records in middle node down */ HDmemmove(H5B2_NAT_NREC(middle_native, hdr, 0), H5B2_NAT_NREC(middle_native, hdr, middle_nrec_move), hdr->cls->nrec_size * (*middle_nrec - middle_nrec_move)); @@ -1320,7 +1320,7 @@ H5B2__merge3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, unsigned u; /* Local index variable */ /* Copy node pointers from middle node into left node */ - HDmemcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * middle_nrec_move); + H5MM_memcpy(&(left_node_ptrs[*left_nrec + 1]), &(middle_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * middle_nrec_move); /* Count the number of records being moved into the left node */ for(u = 0; u < middle_nrec_move; u++) @@ -1348,15 +1348,15 @@ H5B2__merge3(H5B2_hdr_t *hdr, uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, /* Redistribute records into middle node */ { /* Copy record from parent node to proper location in middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec), H5B2_INT_NREC(internal, hdr, idx), hdr->cls->nrec_size); /* Copy records from right node to middle node */ - HDmemcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); + H5MM_memcpy(H5B2_NAT_NREC(middle_native, hdr, *middle_nrec + 1), H5B2_NAT_NREC(right_native, hdr, 0), hdr->cls->nrec_size * (*right_nrec)); /* Move node pointers also if this is an internal node */ if(depth > 1) /* Copy node pointers from right node into middle node */ - HDmemcpy(&(middle_node_ptrs[*middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); + H5MM_memcpy(&(middle_node_ptrs[*middle_nrec + 1]), &(right_node_ptrs[0]), sizeof(H5B2_node_ptr_t) * (size_t)(*right_nrec + 1)); /* Update flush dependencies for grandchildren, if using SWMR */ if(hdr->swmr_write && depth > 1) @@ -1539,7 +1539,7 @@ H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers") /* Copy the node pointers */ - HDmemcpy(node_ptrs, internal->node_ptrs, (sizeof(H5B2_node_ptr_t) * (size_t)(curr_node->node_nrec + 1))); + H5MM_memcpy(node_ptrs, internal->node_ptrs, (sizeof(H5B2_node_ptr_t) * (size_t)(curr_node->node_nrec + 1))); } /* end if */ else { H5B2_leaf_t *leaf; /* Pointer to leaf node */ @@ -1559,7 +1559,7 @@ H5B2__iterate_node(H5B2_hdr_t *hdr, uint16_t depth, const H5B2_node_ptr_t *curr_ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys") /* Copy the native keys */ - HDmemcpy(native, node_native, (hdr->cls->nrec_size * curr_node->node_nrec)); + H5MM_memcpy(native, node_native, (hdr->cls->nrec_size * curr_node->node_nrec)); /* Unlock the node */ if(H5AC_unprotect(hdr->f, curr_node_class, curr_node->addr, node, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0) diff --git a/src/H5B2leaf.c b/src/H5B2leaf.c index 54d40ea..beca40c 100644 --- a/src/H5B2leaf.c +++ b/src/H5B2leaf.c @@ -412,7 +412,7 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_node_ptr, if(hdr->min_native_rec == NULL) if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info") - HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ if(idx == (unsigned)(leaf->nrec - 1)) { @@ -420,7 +420,7 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_node_ptr, if(hdr->max_native_rec == NULL) if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info") - HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ } /* end if */ @@ -561,7 +561,7 @@ H5B2__update_leaf(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_node_ptr, if(hdr->min_native_rec == NULL) if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info") - HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ if(idx == (unsigned)(leaf->nrec - 1)) { @@ -569,7 +569,7 @@ H5B2__update_leaf(H5B2_hdr_t *hdr, H5B2_node_ptr_t *curr_node_ptr, if(hdr->max_native_rec == NULL) if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size))) HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info") - HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); + H5MM_memcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size); } /* end if */ } /* end if */ } /* end if */ @@ -664,9 +664,9 @@ H5B2__swap_leaf(H5B2_hdr_t *hdr, uint16_t depth, H5B2_internal_t *internal, } /* end else */ /* Swap records (use disk page as temporary buffer) */ - HDmemcpy(hdr->page, H5B2_NAT_NREC(child_native, hdr, 0), hdr->cls->nrec_size); - HDmemcpy(H5B2_NAT_NREC(child_native, hdr, 0), swap_loc, hdr->cls->nrec_size); - HDmemcpy(swap_loc, hdr->page, hdr->cls->nrec_size); + H5MM_memcpy(hdr->page, H5B2_NAT_NREC(child_native, hdr, 0), hdr->cls->nrec_size); + H5MM_memcpy(H5B2_NAT_NREC(child_native, hdr, 0), swap_loc, hdr->cls->nrec_size); + H5MM_memcpy(swap_loc, hdr->page, hdr->cls->nrec_size); /* Mark parent as dirty */ *internal_flags_ptr |= H5AC__DIRTIED_FLAG; diff --git a/src/H5Bcache.c b/src/H5Bcache.c index a0a75c8..cce10c9 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -304,7 +304,7 @@ H5B__cache_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len, HDassert(shared->type->encode); /* magic number */ - HDmemcpy(image, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += 4; /* node type and level */ diff --git a/src/H5C.c b/src/H5C.c index 09c5fe8..ad2f762 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -2285,7 +2285,7 @@ H5C_protect(H5F_t * f, if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ if(0 == mpi_rank) if(H5C__generate_image(f, cache_ptr, entry_ptr) < 0) @@ -6042,7 +6042,7 @@ H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags) if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ } /* end if */ @@ -6542,7 +6542,7 @@ H5C_load_entry(H5F_t * f, if(NULL == (image = (uint8_t *)H5MM_malloc(len + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ #ifdef H5_HAVE_PARALLEL @@ -6580,7 +6580,7 @@ H5C_load_entry(H5F_t * f, HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()") image = (uint8_t *)new_image; #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(image + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ } /* end if */ @@ -6624,7 +6624,7 @@ H5C_load_entry(H5F_t * f, HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()") image = (uint8_t *)new_image; #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(image + actual_len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(image + actual_len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ if(actual_len > len) { @@ -8456,7 +8456,7 @@ H5C__serialize_single_entry(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE)) ) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + image_size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)entry_ptr->image_ptr) + image_size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ } /* end if */ @@ -8573,7 +8573,7 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr) if(NULL == (entry_ptr->image_ptr = H5MM_realloc(entry_ptr->image_ptr, new_len + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + new_len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)entry_ptr->image_ptr) + new_len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ /* Update statistics for resizing the entry */ diff --git a/src/H5CX.c b/src/H5CX.c index b56d66d..5a0934a 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -76,7 +76,7 @@ #define H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD) \ /* Check for default property list */ \ if((*head)->ctx.H5_GLUE(PL,_id) == (DEF_PL)) \ - HDmemcpy(&(*head)->ctx.PROP_FIELD, &H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD, sizeof(H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD)); \ + H5MM_memcpy(&(*head)->ctx.PROP_FIELD, &H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD, sizeof(H5_GLUE3(H5CX_def_,PL,_cache).PROP_FIELD)); \ else { \ /* Retrieve the property list */ \ H5CX_RETRIEVE_PLIST(PL, FAIL) \ @@ -776,7 +776,7 @@ H5CX_retrieve_state(H5CX_state_t **api_state) /* Keep a copy of the VOL connector property, if there is one */ if((*head)->ctx.vol_connector_prop_valid && (*head)->ctx.vol_connector_prop.connector_id > 0) { /* Get the connector property */ - HDmemcpy(&(*api_state)->vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t)); + H5MM_memcpy(&(*api_state)->vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t)); /* Check for actual VOL connector property */ if((*api_state)->vol_connector_prop.connector_id) { @@ -852,7 +852,7 @@ H5CX_restore_state(const H5CX_state_t *api_state) /* Restore the VOL connector info */ if(api_state->vol_connector_prop.connector_id) { - HDmemcpy(&(*head)->ctx.vol_connector_prop, &api_state->vol_connector_prop, sizeof(H5VL_connector_prop_t)); + H5MM_memcpy(&(*head)->ctx.vol_connector_prop, &api_state->vol_connector_prop, sizeof(H5VL_connector_prop_t)); (*head)->ctx.vol_connector_prop_valid = TRUE; } /* end if */ @@ -1271,7 +1271,7 @@ H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop) HDassert(head && *head); /* Set the API context value */ - HDmemcpy(&(*head)->ctx.vol_connector_prop, vol_connector_prop, sizeof(H5VL_connector_prop_t)); + H5MM_memcpy(&(*head)->ctx.vol_connector_prop, vol_connector_prop, sizeof(H5VL_connector_prop_t)); /* Mark the value as valid */ (*head)->ctx.vol_connector_prop_valid = TRUE; @@ -1396,7 +1396,7 @@ H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop) /* Check for value that was set */ if((*head)->ctx.vol_connector_prop_valid) /* Get the value */ - HDmemcpy(vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t)); + H5MM_memcpy(vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t)); else HDmemset(vol_connector_prop, 0, sizeof(H5VL_connector_prop_t)); @@ -1601,7 +1601,7 @@ H5CX_get_btree_split_ratios(double split_ratio[3]) H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_BTREE_SPLIT_RATIO_NAME, btree_split_ratio) /* Get the B-tree split ratio values */ - HDmemcpy(split_ratio, &(*head)->ctx.btree_split_ratio, sizeof((*head)->ctx.btree_split_ratio)); + H5MM_memcpy(split_ratio, &(*head)->ctx.btree_split_ratio, sizeof((*head)->ctx.btree_split_ratio)); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Cimage.c b/src/H5Cimage.c index 4684630..db44c7a 100644 --- a/src/H5Cimage.c +++ b/src/H5Cimage.c @@ -2020,11 +2020,11 @@ H5C__decode_cache_image_entry(const H5F_t *f, const H5C_t *cache_ptr, HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)image_ptr) + size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)image_ptr) + size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ /* Copy the entry image from the cache image block */ - HDmemcpy(image_ptr, p, size); + H5MM_memcpy(image_ptr, p, size); p += size; /* Copy data into target */ @@ -2219,7 +2219,7 @@ H5C__encode_cache_image_header(const H5F_t *f, const H5C_t *cache_ptr, p = *buf; /* write signature */ - HDmemcpy(p, H5C__MDCI_BLOCK_SIGNATURE, (size_t)H5C__MDCI_BLOCK_SIGNATURE_LEN); + H5MM_memcpy(p, H5C__MDCI_BLOCK_SIGNATURE, (size_t)H5C__MDCI_BLOCK_SIGNATURE_LEN); p += H5C__MDCI_BLOCK_SIGNATURE_LEN; /* write version */ @@ -2355,7 +2355,7 @@ H5C__encode_cache_image_entry(H5F_t *f, H5C_t *cache_ptr, uint8_t **buf, H5F_addr_encode(f, &p, ie_ptr->fd_parent_addrs[u]); /* Copy entry image */ - HDmemcpy(p, ie_ptr->image_ptr, ie_ptr->size); + H5MM_memcpy(p, ie_ptr->image_ptr, ie_ptr->size); p += ie_ptr->size; /* Update buffer pointer */ @@ -3422,11 +3422,11 @@ H5C__reconstruct_cache_entry(const H5F_t *f, H5C_t *cache_ptr, if(NULL == (pf_entry_ptr->image_ptr = H5MM_malloc(pf_entry_ptr->size + H5C_IMAGE_EXTRA_SPACE))) HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer") #if H5C_DO_MEMORY_SANITY_CHECKS - HDmemcpy(((uint8_t *)pf_entry_ptr->image_ptr) + size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); + H5MM_memcpy(((uint8_t *)pf_entry_ptr->image_ptr) + size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); #endif /* H5C_DO_MEMORY_SANITY_CHECKS */ /* Copy the entry image from the cache image block */ - HDmemcpy(pf_entry_ptr->image_ptr, p, pf_entry_ptr->size); + H5MM_memcpy(pf_entry_ptr->image_ptr, p, pf_entry_ptr->size); p += pf_entry_ptr->size; /* Initialize the rest of the fields in the prefetched entry */ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index b61aed4..e6f0674 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -847,7 +847,7 @@ H5D__btree_shared_create(const H5F_t *f, H5O_storage_chunk_t *store, /* Set up the "local" information for this dataset's chunks */ if(NULL == (my_layout = H5FL_MALLOC(H5O_layout_chunk_t))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk layout") - HDmemcpy(my_layout, layout, sizeof(H5O_layout_chunk_t)); + H5MM_memcpy(my_layout, layout, sizeof(H5O_layout_chunk_t)); shared->udata = my_layout; /* Make shared B-tree info reference counted */ @@ -1087,7 +1087,7 @@ H5D__btree_idx_iterate_cb(H5F_t H5_ATTR_UNUSED *f, const void *_lt_key, HDcompile_assert(sizeof(chunk_rec.filter_mask) == sizeof(lt_key->filter_mask)); /* Compose generic chunk record for callback */ - HDmemcpy(&chunk_rec, lt_key, sizeof(*lt_key)); + H5MM_memcpy(&chunk_rec, lt_key, sizeof(*lt_key)); chunk_rec.chunk_addr = addr; /* Make "generic chunk" callback */ diff --git a/src/H5Dbtree2.c b/src/H5Dbtree2.c index b32f395..f0a1380 100644 --- a/src/H5Dbtree2.c +++ b/src/H5Dbtree2.c @@ -248,7 +248,7 @@ H5D__bt2_crt_context(void *_udata) /* Set up the "local" information for this dataset's chunk dimension sizes */ if(NULL == (my_dim = (uint32_t *)H5FL_BLK_MALLOC(chunk_dim, H5O_LAYOUT_NDIMS * sizeof(uint32_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate chunk dims") - HDmemcpy(my_dim, udata->dim, H5O_LAYOUT_NDIMS * sizeof(uint32_t)); + H5MM_memcpy(my_dim, udata->dim, H5O_LAYOUT_NDIMS * sizeof(uint32_t)); ctx->dim = my_dim; /* diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 27a6125..93b4427 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1688,7 +1688,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t new_chunk_info->mspace_shared = FALSE; /* Copy the chunk's scaled coordinates */ - HDmemcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); + H5MM_memcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); new_chunk_info->scaled[fm->f_ndims] = 0; /* Insert the new chunk into the skip list */ @@ -1948,9 +1948,9 @@ H5D__chunk_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, chunk_info->chunk_points = 0; /* Set the chunk's scaled coordinates */ - HDmemcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); + H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); chunk_info->scaled[fm->f_ndims] = 0; - HDmemcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); + H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims); /* Insert the new chunk into the skip list */ if(H5SL_insert(fm->sel_chunks,chunk_info,&chunk_info->index) < 0) { @@ -2191,11 +2191,11 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HDassert(fm); /* Set up "nonexistent" I/O info object */ - HDmemcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info)); + H5MM_memcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info)); nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT; /* Set up contiguous I/O info object */ - HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); + H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); ctg_io_info.store = &ctg_store; ctg_io_info.layout_ops = *H5D_LOPS_CONTIG; @@ -2203,7 +2203,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size, uint32_t); /* Set up compact I/O info object */ - HDmemcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); + H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); cpt_io_info.store = &cpt_store; cpt_io_info.layout_ops = *H5D_LOPS_COMPACT; @@ -2341,7 +2341,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HDassert(fm); /* Set up contiguous I/O info object */ - HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); + H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); ctg_io_info.store = &ctg_store; ctg_io_info.layout_ops = *H5D_LOPS_CONTIG; @@ -2349,7 +2349,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size, uint32_t); /* Set up compact I/O info object */ - HDmemcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); + H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); cpt_io_info.store = &cpt_store; cpt_io_info.layout_ops = *H5D_LOPS_COMPACT; @@ -2704,7 +2704,7 @@ H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *ud HDassert(udata->common.scaled); /* Stored the information to cache */ - HDmemcpy(last->scaled, udata->common.scaled, sizeof(hsize_t) * udata->common.layout->ndims); + H5MM_memcpy(last->scaled, udata->common.scaled, sizeof(hsize_t) * udata->common.layout->ndims); last->addr = udata->chunk_block.offset; H5_CHECKED_ASSIGN(last->nbytes, uint32_t, udata->chunk_block.length, hsize_t); last->chunk_idx = udata->chunk_idx; @@ -3073,7 +3073,7 @@ H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset) */ if(NULL == (buf = H5MM_malloc(alloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline") - HDmemcpy(buf, ent->chunk, alloc); + H5MM_memcpy(buf, ent->chunk, alloc); } /* end if */ else { /* @@ -3486,7 +3486,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, */ if(NULL == (chunk = H5D__chunk_mem_alloc(chunk_size, pline))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") - HDmemcpy(chunk, ent->chunk, chunk_size); + H5MM_memcpy(chunk, ent->chunk, chunk_size); ent->chunk = (uint8_t *)H5D__chunk_mem_xfree(ent->chunk, old_pline); ent->chunk = (uint8_t *)chunk; chunk = NULL; @@ -3512,7 +3512,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, */ if(NULL == (chunk = H5D__chunk_mem_alloc(chunk_size, pline))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") - HDmemcpy(chunk, ent->chunk, chunk_size); + H5MM_memcpy(chunk, ent->chunk, chunk_size); ent->chunk = (uint8_t *)H5D__chunk_mem_xfree(ent->chunk, old_pline); ent->chunk = (uint8_t *)chunk; @@ -3641,7 +3641,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, (void)H5D__chunk_mem_xfree(tmp_chunk, old_pline); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk") } /* end if */ - HDmemcpy(chunk, tmp_chunk, chunk_size); + H5MM_memcpy(chunk, tmp_chunk, chunk_size); (void)H5D__chunk_mem_xfree(tmp_chunk, old_pline); } /* end if */ } /* end if */ @@ -3722,7 +3722,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, ent->chunk_block.offset = chunk_addr; ent->chunk_block.length = chunk_alloc; ent->chunk_idx = udata->chunk_idx; - HDmemcpy(ent->scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims); + H5MM_memcpy(ent->scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims); H5_CHECKED_ASSIGN(ent->rd_count, uint32_t, chunk_size, size_t); H5_CHECKED_ASSIGN(ent->wr_count, uint32_t, chunk_size, size_t); ent->chunk = (uint8_t *)chunk; @@ -3850,7 +3850,7 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, fake_ent.edge_chunk_state = H5D_RDCC_DISABLE_FILTERS; if(udata->new_unfilt_chunk) fake_ent.edge_chunk_state |= H5D_RDCC_NEWLY_DISABLED_FILTERS; - HDmemcpy(fake_ent.scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims); + H5MM_memcpy(fake_ent.scaled, udata->common.scaled, sizeof(hsize_t) * layout->u.chunk.ndims); HDassert(layout->u.chunk.size > 0); fake_ent.chunk_idx = udata->chunk_idx; fake_ent.chunk_block.offset = udata->chunk_block.offset; @@ -4137,7 +4137,7 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_ if(has_unfilt_edge_chunks) { if(NULL == (unfilt_fill_buf = H5D__chunk_mem_alloc(orig_chunk_size, &def_pline))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk") - HDmemcpy(unfilt_fill_buf, fb_info.fill_buf, orig_chunk_size); + H5MM_memcpy(unfilt_fill_buf, fb_info.fill_buf, orig_chunk_size); } /* end if */ /* Retrieve filter settings from API context */ @@ -5671,7 +5671,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) if(udata->chunk_in_cache && udata->chunk) { HDassert(!H5F_addr_defined(chunk_rec->chunk_addr)); - HDmemcpy(buf, udata->chunk, nbytes); + H5MM_memcpy(buf, udata->chunk, nbytes); udata->chunk = NULL; } else { @@ -5705,7 +5705,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) HDassert(H5F_addr_defined(ent->chunk_block.offset)); H5_CHECKED_ASSIGN(nbytes, size_t, shared_fo->layout.u.chunk.size, uint32_t); - HDmemcpy(buf, ent->chunk, nbytes); + H5MM_memcpy(buf, ent->chunk, nbytes); } else { /* read chunk data from the source file */ @@ -5739,7 +5739,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed") /* Copy into another buffer, to reclaim memory later */ - HDmemcpy(reclaim_buf, buf, reclaim_buf_size); + H5MM_memcpy(reclaim_buf, buf, reclaim_buf_size); /* Set background buffer to all zeros */ HDmemset(bkg, 0, buf_size); @@ -5770,7 +5770,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) } /* end if */ /* After fix ref, copy the new reference elements to the buffer to write out */ - HDmemcpy(buf, bkg, buf_size); + H5MM_memcpy(buf, bkg, buf_size); } /* end if */ /* Set up destination chunk callback information for insertion */ @@ -6070,7 +6070,7 @@ H5D__chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, for(ent = shared_fo->cache.chunk.head; ent; ent = next) { if(!H5F_addr_defined(ent->chunk_block.offset)) { - HDmemcpy(chunk_rec.scaled, ent->scaled, sizeof(chunk_rec.scaled)); + H5MM_memcpy(chunk_rec.scaled, ent->scaled, sizeof(chunk_rec.scaled)); udata.chunk = ent->chunk; udata.chunk_in_cache = TRUE; if(H5D__chunk_copy_cb(&chunk_rec, &udata) < 0) diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index 651aaf4..df61856 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -529,7 +529,7 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDmemcpy(buf, storage_src->buf, storage_src->size); + H5MM_memcpy(buf, storage_src->buf, storage_src->size); /* allocate temporary bkg buff for data conversion */ if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size))) @@ -540,7 +540,7 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") /* Copy into another buffer, to reclaim memory later */ - HDmemcpy(reclaim_buf, buf, buf_size); + H5MM_memcpy(reclaim_buf, buf, buf_size); /* Set background buffer to all zeros */ HDmemset(bkg, 0, buf_size); @@ -549,7 +549,7 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") - HDmemcpy(storage_dst->buf, buf, storage_dst->size); + H5MM_memcpy(storage_dst->buf, buf, storage_dst->size); if(H5D_vlen_reclaim(tid_mem, buf_space, reclaim_buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") @@ -574,11 +574,11 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds } /* end if */ else /* Type conversion not necessary */ - HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size); + H5MM_memcpy(storage_dst->buf, storage_src->buf, storage_src->size); } /* end if */ else /* Type conversion not necessary */ - HDmemcpy(storage_dst->buf, storage_src->buf, storage_src->size); + H5MM_memcpy(storage_dst->buf, storage_src->buf, storage_src->size); /* Mark destination buffer as dirty */ storage_dst->dirty = TRUE; diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index c2e9bfc..adf6719 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -776,7 +776,7 @@ H5D__contig_readvv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "block read failed") /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(buf, dset_contig->sieve_buf, len); + H5MM_memcpy(buf, dset_contig->sieve_buf, len); /* Reset sieve buffer dirty flag */ dset_contig->sieve_dirty = FALSE; @@ -796,7 +796,7 @@ H5D__contig_readvv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, unsigned char *base_sieve_buf = dset_contig->sieve_buf + (addr - sieve_start); /* Grab the data out of the buffer */ - HDmemcpy(buf, base_sieve_buf, len); + H5MM_memcpy(buf, base_sieve_buf, len); } /* end if */ /* Entire request is not within this data sieve buffer */ else { @@ -860,7 +860,7 @@ H5D__contig_readvv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "block read failed") /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(buf, dset_contig->sieve_buf, len); + H5MM_memcpy(buf, dset_contig->sieve_buf, len); /* Reset sieve buffer dirty flag */ dset_contig->sieve_dirty = FALSE; @@ -1058,7 +1058,7 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, } /* end if */ /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(dset_contig->sieve_buf, buf, len); + H5MM_memcpy(dset_contig->sieve_buf, buf, len); /* Set sieve buffer dirty flag */ dset_contig->sieve_dirty = TRUE; @@ -1078,7 +1078,7 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, unsigned char *base_sieve_buf = dset_contig->sieve_buf + (addr - sieve_start); /* Put the data into the sieve buffer */ - HDmemcpy(base_sieve_buf, buf, len); + H5MM_memcpy(base_sieve_buf, buf, len); /* Set sieve buffer dirty flag */ dset_contig->sieve_dirty = TRUE; @@ -1121,7 +1121,7 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, HDmemmove(dset_contig->sieve_buf + len, dset_contig->sieve_buf, dset_contig->sieve_size); /* Copy in new information (must be first in sieve buffer) */ - HDmemcpy(dset_contig->sieve_buf, buf, len); + H5MM_memcpy(dset_contig->sieve_buf, buf, len); /* Adjust sieve location */ dset_contig->sieve_loc = addr; @@ -1130,7 +1130,7 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, /* Append to existing sieve buffer */ else { /* Copy in new information */ - HDmemcpy(dset_contig->sieve_buf + sieve_size, buf, len); + H5MM_memcpy(dset_contig->sieve_buf + sieve_size, buf, len); } /* end else */ /* Adjust sieve size */ @@ -1184,7 +1184,7 @@ H5D__contig_writevv_sieve_cb(hsize_t dst_off, hsize_t src_off, size_t len, } /* end if */ /* Grab the data out of the buffer (must be first piece of data in buffer ) */ - HDmemcpy(dset_contig->sieve_buf, buf, len); + H5MM_memcpy(dset_contig->sieve_buf, buf, len); /* Set sieve buffer dirty flag */ dset_contig->sieve_dirty = TRUE; @@ -1539,7 +1539,7 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, if(try_sieve && (addr_src >= sieve_start) && ((addr_src + src_nbytes -1) < sieve_end)) { unsigned char *base_sieve_buf = shared_fo->cache.contig.sieve_buf + (addr_src - sieve_start); - HDmemcpy(buf, base_sieve_buf, src_nbytes); + H5MM_memcpy(buf, base_sieve_buf, src_nbytes); } else /* Read raw data from source file */ if(H5F_block_read(f_src, H5FD_MEM_DRAW, addr_src, src_nbytes, buf) < 0) @@ -1552,7 +1552,7 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") /* Copy into another buffer, to reclaim memory later */ - HDmemcpy(reclaim_buf, buf, mem_nbytes); + H5MM_memcpy(reclaim_buf, buf, mem_nbytes); /* Set background buffer to all zeros */ HDmemset(bkg, 0, buf_size); @@ -1578,7 +1578,7 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") /* After fix ref, copy the new reference elements to the buffer to write out */ - HDmemcpy(buf, bkg, buf_size); + H5MM_memcpy(buf, bkg, buf_size); } /* end if */ else /* Reset value to zero */ diff --git a/src/H5Dearray.c b/src/H5Dearray.c index a8fffbc..8f6fae4 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -1197,11 +1197,11 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) hsize_t swizzled_max_chunks[H5O_LAYOUT_NDIMS]; /* Swizzled form of max # of chunks in each dimension */ /* Get the swizzled chunk dimensions */ - HDmemcpy(layout->u.earray.swizzled_dim, layout->dim, (layout->ndims - 1) * sizeof(layout->dim[0])); + H5MM_memcpy(layout->u.earray.swizzled_dim, layout->dim, (layout->ndims - 1) * sizeof(layout->dim[0])); H5VM_swizzle_coords(uint32_t, layout->u.earray.swizzled_dim, layout->u.earray.unlim_dim); /* Get the swizzled number of chunks in each dimension */ - HDmemcpy(swizzled_chunks, layout->chunks, (layout->ndims - 1) * sizeof(swizzled_chunks[0])); + H5MM_memcpy(swizzled_chunks, layout->chunks, (layout->ndims - 1) * sizeof(swizzled_chunks[0])); H5VM_swizzle_coords(hsize_t, swizzled_chunks, layout->u.earray.unlim_dim); /* Get the swizzled "down" sizes for each dimension */ @@ -1209,7 +1209,7 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") /* Get the swizzled max number of chunks in each dimension */ - HDmemcpy(swizzled_max_chunks, layout->max_chunks, (layout->ndims - 1) * sizeof(swizzled_max_chunks[0])); + H5MM_memcpy(swizzled_max_chunks, layout->max_chunks, (layout->ndims - 1) * sizeof(swizzled_max_chunks[0])); H5VM_swizzle_coords(hsize_t, swizzled_max_chunks, layout->u.earray.unlim_dim); /* Get the swizzled max "down" sizes for each dimension */ diff --git a/src/H5Defl.c b/src/H5Defl.c index 42b3947..19f3a00 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -227,7 +227,7 @@ H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNU { FUNC_ENTER_STATIC_NOERR - HDmemcpy(&io_info->store->efl, &(io_info->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t)); + H5MM_memcpy(&io_info->store->efl, &(io_info->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__efl_io_init() */ diff --git a/src/H5Dfill.c b/src/H5Dfill.c index 619f699..1c501ce 100644 --- a/src/H5Dfill.c +++ b/src/H5Dfill.c @@ -300,7 +300,7 @@ H5D__fill(const void *fill, const H5T_t *fill_type, void *buf, HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer") /* Copy the user's data into the buffer for conversion */ - HDmemcpy(elem_ptr, fill, src_type_size); + H5MM_memcpy(elem_ptr, fill, src_type_size); /* If there's no VL type of data, do conversion first then fill the data into * the memory buffer. */ @@ -577,7 +577,7 @@ H5D__fill_refill_vl(H5D_fill_buf_info_t *fb_info, size_t nelmts) HDassert(fb_info->fill_buf); /* Make a copy of the (disk-based) fill value into the buffer */ - HDmemcpy(fb_info->fill_buf, fb_info->fill->buf, fb_info->file_elmt_size); + H5MM_memcpy(fb_info->fill_buf, fb_info->fill->buf, fb_info->file_elmt_size); /* Reset first element of background buffer, if necessary */ if(H5T_path_bkg(fb_info->fill_to_mem_tpath)) @@ -603,7 +603,7 @@ H5D__fill_refill_vl(H5D_fill_buf_info_t *fb_info, size_t nelmts) if(!buf) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary fill buffer") - HDmemcpy(buf, fb_info->fill_buf, fb_info->fill_buf_size); + H5MM_memcpy(buf, fb_info->fill_buf, fb_info->fill_buf_size); /* Type convert the dataset buffer, to copy any VL components */ if(H5T_convert(fb_info->mem_to_dset_tpath, fb_info->mem_tid, fb_info->file_tid, nelmts, (size_t)0, (size_t)0, fb_info->fill_buf, fb_info->bkg_buf) < 0) diff --git a/src/H5Dint.c b/src/H5Dint.c index 874e845..6fc02de 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -470,7 +470,7 @@ H5D__new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the default dataset information */ - HDmemcpy(new_dset, &H5D_def_dset, sizeof(H5D_shared_t)); + H5MM_memcpy(new_dset, &H5D_def_dset, sizeof(H5D_shared_t)); /* If we are using the default dataset creation property list, during creation * don't bother to copy it, just increment the reference count @@ -774,7 +774,7 @@ H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr) /* Shallow copy the fill value property */ /* guards against shared component modification */ - HDmemcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop)); + H5MM_memcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop)); if (H5O_msg_reset_share(H5O_FILL_ID, &old_fill_prop) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't reset the copied fill property") @@ -1000,7 +1000,7 @@ H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id) /* Shallow copy the fill value property */ /* (we only want to make certain that the shared component isn't modified) */ - HDmemcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop)); + H5MM_memcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop)); /* Reset shared component info */ H5O_msg_reset_share(H5O_FILL_ID, &old_fill_prop); @@ -1642,7 +1642,7 @@ H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id) dset->shared->append_flush.ndims = info.ndims; dset->shared->append_flush.func = info.func; dset->shared->append_flush.udata = info.udata; - HDmemcpy(dset->shared->append_flush.boundary, info.boundary, sizeof(info.boundary)); + H5MM_memcpy(dset->shared->append_flush.boundary, info.boundary, sizeof(info.boundary)); } /* end if */ } /* end if */ } /* end if */ @@ -2778,7 +2778,7 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size) /* Keep the current dataspace dimensions for later */ HDcompile_assert(sizeof(curr_dims) == sizeof(dset->shared->curr_dims)); - HDmemcpy(curr_dims, dset->shared->curr_dims, H5S_MAX_RANK * sizeof(curr_dims[0])); + H5MM_memcpy(curr_dims, dset->shared->curr_dims, H5S_MAX_RANK * sizeof(curr_dims[0])); /* Modify the size of the dataspace */ if((changed = H5S_set_extent(dset->shared->space, size)) < 0) @@ -3063,7 +3063,7 @@ H5D__format_convert(H5D_t *dataset) idx_info.storage = &dataset->shared->layout.storage.u.chunk; /* Copy the current layout info to the new layout */ - HDmemcpy(newlayout, &dataset->shared->layout, sizeof(H5O_layout_t)); + H5MM_memcpy(newlayout, &dataset->shared->layout, sizeof(H5O_layout_t)); /* Set up info for version 1 B-tree in the new layout */ newlayout->version = H5O_LAYOUT_VERSION_3; @@ -3114,7 +3114,7 @@ H5D__format_convert(H5D_t *dataset) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") /* Copy the new layout to the dataset's layout */ - HDmemcpy(&dataset->shared->layout, newlayout, sizeof(H5O_layout_t)); + H5MM_memcpy(&dataset->shared->layout, newlayout, sizeof(H5O_layout_t)); break; diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 2a6c05f..d23cb63 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -1427,7 +1427,7 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in for (i = 0, offset = 0; i < (size_t) mpi_rank; i++) offset += num_chunks_selected_array[i]; - HDmemcpy(chunk_list, &collective_chunk_list[offset], num_chunks_selected_array[mpi_rank] * sizeof(H5D_filtered_collective_io_info_t)); + H5MM_memcpy(chunk_list, &collective_chunk_list[offset], num_chunks_selected_array[mpi_rank] * sizeof(H5D_filtered_collective_io_info_t)); /* Create single MPI type encompassing each selection in the dataspace */ if (H5D__mpio_filtered_collective_write_type(chunk_list, chunk_list_num_entries, @@ -1553,7 +1553,7 @@ if(H5DEBUG(D)) HGOTO_ERROR(H5E_DATASET, H5E_CANTRECV, FAIL, "unable to obtain MPIO mode") /* Set up contiguous I/O info object */ - HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); + H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); ctg_io_info.store = &ctg_store; ctg_io_info.layout_ops = *H5D_LOPS_CONTIG; @@ -1561,7 +1561,7 @@ if(H5DEBUG(D)) ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size; /* Set up compact I/O info object */ - HDmemcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); + H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info)); cpt_io_info.store = &cpt_store; cpt_io_info.layout_ops = *H5D_LOPS_COMPACT; @@ -1788,7 +1788,7 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list") /* Set up contiguous I/O info object */ - HDmemcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); + H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info)); ctg_io_info.store = &ctg_store; ctg_io_info.layout_ops = *H5D_LOPS_CONTIG; @@ -1893,7 +1893,7 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i /* Collect the new chunk info back to the local copy, since only the record in the * collective array gets updated by the chunk re-allocation */ - HDmemcpy(&chunk_list[i].chunk_states.new_chunk, &collective_chunk_list[offset].chunk_states.new_chunk, sizeof(chunk_list[i].chunk_states.new_chunk)); + H5MM_memcpy(&chunk_list[i].chunk_states.new_chunk, &collective_chunk_list[offset].chunk_states.new_chunk, sizeof(chunk_list[i].chunk_states.new_chunk)); H5_CHECKED_ASSIGN(mpi_type_count, int, chunk_list[i].chunk_states.new_chunk.length, hsize_t); @@ -2517,8 +2517,8 @@ H5D__obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, /* merge buffer io_mode info and chunk addr into one */ - HDmemcpy(mergebuf, assign_io_mode, total_chunks); - HDmemcpy(tempbuf, chunk_addr, sizeof(haddr_t) * total_chunks); + H5MM_memcpy(mergebuf, assign_io_mode, total_chunks); + H5MM_memcpy(tempbuf, chunk_addr, sizeof(haddr_t) * total_chunks); H5MM_free(nproc_per_chunk); } /* end if */ @@ -2527,8 +2527,8 @@ H5D__obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, if(MPI_SUCCESS != (mpi_code = MPI_Bcast(mergebuf, ((sizeof(haddr_t) + 1) * total_chunks), MPI_BYTE, root, comm))) HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code) - HDmemcpy(assign_io_mode, mergebuf, total_chunks); - HDmemcpy(chunk_addr, tempbuf, sizeof(haddr_t) * total_chunks); + H5MM_memcpy(assign_io_mode, mergebuf, total_chunks); + H5MM_memcpy(chunk_addr, tempbuf, sizeof(haddr_t) * total_chunks); #ifdef H5_HAVE_INSTRUMENTED_LIBRARY { @@ -2630,7 +2630,7 @@ H5D__construct_filtered_io_info_list(const H5D_io_info_t *io_info, const H5D_typ local_info_array[i].async_info.receive_buffer_array = NULL; local_info_array[i].async_info.receive_requests_array = NULL; - HDmemcpy(local_info_array[i].scaled, chunk_info->scaled, sizeof(chunk_info->scaled)); + H5MM_memcpy(local_info_array[i].scaled, chunk_info->scaled, sizeof(chunk_info->scaled)); if ((select_npoints = H5S_GET_SELECT_NPOINTS(chunk_info->mspace)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "dataspace is invalid") diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 266f5f5..7498e63 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -117,7 +117,7 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, HDassert(_buf); /* Set up temporary I/O info object */ - HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); + H5MM_memcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); tmp_io_info.op_type = H5D_IO_OP_WRITE; tmp_io_info.u.wbuf = _buf; @@ -220,7 +220,7 @@ H5D__gather_file(const H5D_io_info_t *_io_info, HDassert(_buf); /* Set up temporary I/O info object */ - HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); + H5MM_memcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); tmp_io_info.op_type = H5D_IO_OP_READ; tmp_io_info.u.rbuf = _buf; @@ -337,7 +337,7 @@ H5D__scatter_mem (const void *_tscat_buf, const H5S_t *space, /* Get the number of bytes in sequence */ curr_len = len[curr_seq]; - HDmemcpy(buf + off[curr_seq], tscat_buf, curr_len); + H5MM_memcpy(buf + off[curr_seq], tscat_buf, curr_len); /* Advance offset in destination buffer */ tscat_buf += curr_len; @@ -425,7 +425,7 @@ H5D__gather_mem(const void *_buf, const H5S_t *space, /* Get the number of bytes in sequence */ curr_len = len[curr_seq]; - HDmemcpy(tgath_buf, buf + off[curr_seq], curr_len); + H5MM_memcpy(tgath_buf, buf + off[curr_seq], curr_len); /* Advance offset in gather buffer */ tgath_buf += curr_len; diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index a803cca..6c0cfba 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -493,11 +493,11 @@ H5D__virtual_store_layout(H5F_t *f, H5O_layout_t *layout) /* Encode each entry */ for(i = 0; i < layout->storage.u.virt.list_nused; i++) { /* Source file name */ - HDmemcpy((char *)heap_block_p, layout->storage.u.virt.list[i].source_file_name, str_size[2 * i]); + H5MM_memcpy((char *)heap_block_p, layout->storage.u.virt.list[i].source_file_name, str_size[2 * i]); heap_block_p += str_size[2 * i]; /* Source dataset name */ - HDmemcpy((char *)heap_block_p, layout->storage.u.virt.list[i].source_dset_name, str_size[(2 * i) + 1]); + H5MM_memcpy((char *)heap_block_p, layout->storage.u.virt.list[i].source_dset_name, str_size[(2 * i) + 1]); heap_block_p += str_size[(2 * i) + 1]; /* Source selection */ @@ -1109,7 +1109,7 @@ H5D__virtual_str_append(const char *src, size_t src_len, char **p, char **buf, /* Copy string to *p. Note that since src in not NULL terminated, we must * use memcpy */ - (void)HDmemcpy(*p, src, src_len); + (void)H5MM_memcpy(*p, src, src_len); /* Advance *p */ *p += src_len; diff --git a/src/H5EA.c b/src/H5EA.c index 9ceb144..5621d33 100644 --- a/src/H5EA.c +++ b/src/H5EA.c @@ -693,7 +693,7 @@ H5EA_set(const H5EA_t *ea, hsize_t idx, const void *elmt)) HDassert(thing_unprot_func); /* Set element in thing's element buffer */ - HDmemcpy(thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); thing_cache_flags |= H5AC__DIRTIED_FLAG; /* Update max. element set in array, if appropriate */ @@ -765,7 +765,7 @@ H5EA_get(const H5EA_t *ea, hsize_t idx, void *elmt)) } /* end if */ else /* Get element from thing's element buffer */ - HDmemcpy(elmt, thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(elmt, thing_elmt_buf + (hdr->cparam.cls->nat_elmt_size * thing_elmt_idx), hdr->cparam.cls->nat_elmt_size); } /* end else */ CATCH diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 8138991..9e908e7 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -479,7 +479,7 @@ H5EA__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED le HDassert(hdr); /* Magic number */ - HDmemcpy(image, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -867,7 +867,7 @@ H5EA__cache_iblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED /* Get temporary pointer to serialized info */ /* Magic number */ - HDmemcpy(image, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1179,7 +1179,7 @@ H5EA__cache_sblock_deserialize(const void *_image, size_t len, size_t tot_page_init_size = sblock->ndblks * sblock->dblk_page_init_size; /* Compute total size of 'page init' buffer */ /* Retrieve the 'page init' bitmasks */ - HDmemcpy(sblock->page_init, image, tot_page_init_size); + H5MM_memcpy(sblock->page_init, image, tot_page_init_size); image += tot_page_init_size; } /* end if */ @@ -1276,7 +1276,7 @@ H5EA__cache_sblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED HDassert(sblock->hdr); /* Magic number */ - HDmemcpy(image, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1298,7 +1298,7 @@ H5EA__cache_sblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED size_t tot_page_init_size = sblock->ndblks * sblock->dblk_page_init_size; /* Compute total size of 'page init' buffer */ /* Store the 'page init' bitmasks */ - HDmemcpy(image, sblock->page_init, tot_page_init_size); + H5MM_memcpy(image, sblock->page_init, tot_page_init_size); image += tot_page_init_size; } /* end if */ @@ -1690,7 +1690,7 @@ H5EA__cache_dblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED HDassert(dblock->hdr); /* Magic number */ - HDmemcpy(image, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index 62a23b8..a0bea79 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -407,7 +407,7 @@ H5EA__hdr_create(H5F_t *f, const H5EA_create_t *cparam, void *ctx_udata)) hdr->idx_blk_addr = HADDR_UNDEF; /* Set the creation parameters for the array */ - HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); + H5MM_memcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); /* Finish initializing extensible array header */ if(H5EA__hdr_init(hdr, ctx_udata) < 0) diff --git a/src/H5EAstat.c b/src/H5EAstat.c index 72c4d14..6c55d7e 100644 --- a/src/H5EAstat.c +++ b/src/H5EAstat.c @@ -108,7 +108,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(stats); /* Copy extensible array statistics */ - HDmemcpy(stats, &ea->hdr->stats, sizeof(ea->hdr->stats)); + H5MM_memcpy(stats, &ea->hdr->stats, sizeof(ea->hdr->stats)); END_FUNC(PRIV) /* end H5EA_get_stats() */ diff --git a/src/H5FA.c b/src/H5FA.c index 61aaa53..03616ad 100644 --- a/src/H5FA.c +++ b/src/H5FA.c @@ -371,7 +371,7 @@ H5FA_set(const H5FA_t *fa, hsize_t idx, const void *elmt)) /* Check for paging data block */ if(!dblock->npages) { /* Set element in data block */ - HDmemcpy(((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), elmt, hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), elmt, hdr->cparam.cls->nat_elmt_size); dblock_cache_flags |= H5AC__DIRTIED_FLAG; } /* end if */ else { /* paging */ @@ -410,7 +410,7 @@ H5FA_set(const H5FA_t *fa, hsize_t idx, const void *elmt)) H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) /* Set the element in the data block page */ - HDmemcpy(((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); dblk_page_cache_flags |= H5AC__DIRTIED_FLAG; } /* end else */ @@ -474,7 +474,7 @@ H5FA_get(const H5FA_t *fa, hsize_t idx, void *elmt)) /* Check for paged data block */ if(!dblock->npages) /* Retrieve element from data block */ - HDmemcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), hdr->cparam.cls->nat_elmt_size); else { /* paging */ size_t page_idx; /* Index of page within data block */ @@ -512,7 +512,7 @@ H5FA_get(const H5FA_t *fa, hsize_t idx, void *elmt)) H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) /* Retrieve element from data block */ - HDmemcpy(elmt, ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size); + H5MM_memcpy(elmt, ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size); } /* end else */ } /* end else */ } /* end else */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 1f199e9..2726bff 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -409,7 +409,7 @@ H5FA__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED le HDassert(hdr); /* Magic number */ - HDmemcpy(image, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -693,7 +693,7 @@ H5FA__cache_dblock_deserialize(const void *_image, size_t len, /* Page initialization flags */ if(dblock->npages > 0) { - HDmemcpy(dblock->dblk_page_init, image, dblock->dblk_page_init_size); + H5MM_memcpy(dblock->dblk_page_init, image, dblock->dblk_page_init_size); image += dblock->dblk_page_init_size; } /* end if */ @@ -797,7 +797,7 @@ H5FA__cache_dblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED HDassert(dblock->hdr); /* Magic number */ - HDmemcpy(image, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -812,7 +812,7 @@ H5FA__cache_dblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED /* Page init flags */ if(dblock->npages > 0) { /* Store the 'page init' bitmasks */ - HDmemcpy(image, dblock->dblk_page_init, dblock->dblk_page_init_size); + H5MM_memcpy(image, dblock->dblk_page_init, dblock->dblk_page_init_size); image += dblock->dblk_page_init_size; } /* end if */ diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index 2e3db0b..5a6283f 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -207,7 +207,7 @@ H5FA__hdr_create(H5F_t *f, const H5FA_create_t *cparam, void *ctx_udata)) hdr->dblk_addr = HADDR_UNDEF; /* Set the creation parameters for the array */ - HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); + H5MM_memcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); /* Finish initializing fixed array header */ if(H5FA__hdr_init(hdr, ctx_udata) < 0) diff --git a/src/H5FAstat.c b/src/H5FAstat.c index 3c06855..e70fcb8 100644 --- a/src/H5FAstat.c +++ b/src/H5FAstat.c @@ -105,7 +105,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC); HDassert(stats); /* Copy fixed array statistics */ - HDmemcpy(stats, &fa->hdr->stats, sizeof(fa->hdr->stats)); + H5MM_memcpy(stats, &fa->hdr->stats, sizeof(fa->hdr->stats)); END_FUNC(PRIV) /* end H5FA_get_stats() */ diff --git a/src/H5FD.c b/src/H5FD.c index 5585f37..61969b6 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -293,7 +293,7 @@ H5FD_register(const void *_cls, size_t size, hbool_t app_ref) /* Copy the class structure so the caller can reuse or free it */ if(NULL == (saved = (H5FD_class_t *)H5MM_malloc(size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_INVALID_HID, "memory allocation failed for file driver class struct") - HDmemcpy(saved, cls, size); + H5MM_memcpy(saved, cls, size); /* Create the new class ID */ if((ret_value = H5I_register(H5I_VFL, saved, app_ref)) < 0) @@ -1367,7 +1367,7 @@ H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map) } /* end if */ else /* Copy class's default free space type mapping */ - HDmemcpy(type_map, file->cls->fl_map, sizeof(file->cls->fl_map)); + H5MM_memcpy(type_map, file->cls->fl_map, sizeof(file->cls->fl_map)); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDcore.c b/src/H5FDcore.c index d1a17cd..6db8af6 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -848,7 +848,7 @@ H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, NULL, "image_memcpy callback failed") } /* end if */ else - HDmemcpy(file->mem, file_image_info.buffer, size); + H5MM_memcpy(file->mem, file_image_info.buffer, size); } /* end if */ /* Read in existing data from the file if there is no image */ else { @@ -1300,7 +1300,7 @@ H5FD__core_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNU nbytes = MIN(size,(size_t)(file->eof-addr)); #endif /* NDEBUG */ - HDmemcpy(buf, file->mem + addr, nbytes); + H5MM_memcpy(buf, file->mem + addr, nbytes); size -= nbytes; addr += nbytes; buf = (char *)buf + nbytes; @@ -1386,7 +1386,7 @@ H5FD__core_write(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UN } /* Write from BUF to memory */ - HDmemcpy(file->mem + addr, buf, size); + H5MM_memcpy(file->mem + addr, buf, size); /* Mark memory buffer as modified */ file->dirty = TRUE; diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 10c368a..33a0ef4 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -422,7 +422,7 @@ H5FD_direct_fapl_copy(const void *_old_fa) HDassert(new_fa); /* Copy the general information */ - HDmemcpy(new_fa, old_fa, sizeof(H5FD_direct_fapl_t)); + H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_direct_fapl_t)); FUNC_LEAVE_NOAPI(new_fa) } /* end H5FD_direct_fapl_copy() */ @@ -976,12 +976,12 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UN * next section of data. */ p2 = (unsigned char*)copy_buf + copy_offset; if((copy_size + copy_offset) <= alloc_size) { - HDmemcpy(buf, p2, copy_size); + H5MM_memcpy(buf, p2, copy_size); buf = (unsigned char *)buf + copy_size; copy_size = 0; } /* end if */ else { - HDmemcpy(buf, p2, alloc_size - copy_offset); + H5MM_memcpy(buf, p2, alloc_size - copy_offset); buf = (unsigned char*)buf + alloc_size - copy_offset; copy_size -= alloc_size - copy_offset; copy_offset = 0; @@ -1189,11 +1189,11 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_U */ p1 = (unsigned char *)copy_buf + copy_offset; if((copy_size + copy_offset) <= alloc_size) { - HDmemcpy(p1, p3, copy_size); + H5MM_memcpy(p1, p3, copy_size); copy_size = 0; } /* end if */ else { - HDmemcpy(p1, p3, alloc_size - copy_offset); + H5MM_memcpy(p1, p3, alloc_size - copy_offset); p3 = (const unsigned char *)p3 + (alloc_size - copy_offset); copy_size -= alloc_size - copy_offset; copy_offset = 0; diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 4d40cf3..047fb25 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -411,7 +411,7 @@ H5FD_family_fapl_copy(const void *_old_fa) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the fields of the structure */ - HDmemcpy(new_fa, old_fa, sizeof(H5FD_family_fapl_t)); + H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_family_fapl_t)); /* Deep copy the property list objects in the structure */ if(old_fa->memb_fapl_id==H5P_FILE_ACCESS_DEFAULT) { diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 655d7d3..06a0e61 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -405,7 +405,7 @@ H5FD_log_fapl_copy(const void *_old_fa) HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL") /* Copy the general information */ - HDmemcpy(new_fa, old_fa, sizeof(H5FD_log_fapl_t)); + H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_log_fapl_t)); /* Deep copy the log file name */ if(old_fa->logfile != NULL) diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 3ab90aa..d5aa170 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -745,7 +745,7 @@ if(H5FD_mpio_Debug[(int)'t']) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the general information */ - HDmemcpy(new_fa, old_fa, sizeof(H5FD_mpio_fapl_t)); + H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_mpio_fapl_t)); /* Duplicate communicator and Info object. */ if(H5FD_mpi_comm_info_dup(old_fa->comm, old_fa->info, &new_fa->comm, &new_fa->info) < 0) diff --git a/src/H5FL.c b/src/H5FL.c index 21bbf02..a662713 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -1142,7 +1142,7 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_ if((ret_value=H5FL_blk_malloc(head,new_size H5FL_TRACK_INFO_INT))==NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block") blk_size=MIN(new_size,temp->size); - HDmemcpy(ret_value,block,blk_size); + H5MM_memcpy(ret_value,block,blk_size); H5FL_blk_free(head,block); } /* end if */ else { @@ -1630,7 +1630,7 @@ H5FL_arr_realloc(H5FL_arr_head_t *head, void * obj, size_t new_elem) /* Copy the appropriate amount of elements */ blk_size = head->list_arr[MIN(temp->nelem, new_elem)].size; - HDmemcpy(ret_value, obj, blk_size); + H5MM_memcpy(ret_value, obj, blk_size); /* Free the old block */ H5FL_arr_free(head, obj); diff --git a/src/H5FS.c b/src/H5FS.c index 8fee634..b71734d 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -615,7 +615,7 @@ H5FS__new(const H5F_t *f, uint16_t nclasses, const H5FS_section_class_t *classes HDassert(u == classes[u]->type); /* Copy the class information into the free space manager */ - HDmemcpy(&fspace->sect_cls[u], classes[u], sizeof(H5FS_section_class_t)); + H5MM_memcpy(&fspace->sect_cls[u], classes[u], sizeof(H5FS_section_class_t)); /* Call the class initialization routine, if there is one */ if(fspace->sect_cls[u].init_cls) diff --git a/src/H5FScache.c b/src/H5FScache.c index ac0874e..b0b282a 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -707,7 +707,7 @@ H5FS__cache_hdr_serialize(const H5F_t *f, void *_image, size_t len, (fspace->alloc_sect_size == (size_t)fspace->sect_size))); /* Magic number */ - HDmemcpy(image, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1265,7 +1265,7 @@ H5FS__cache_sinfo_serialize(const H5F_t *f, void *_image, size_t len, HDassert(fspace->sect_cls); /* Magic number */ - HDmemcpy(image, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index 0b33f8e..053aad2 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -198,7 +198,7 @@ H5F__accum_read(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, } /* end if */ /* Copy the data out of the buffer */ - HDmemcpy(buf, accum->buf + (addr - new_addr), size); + H5MM_memcpy(buf, accum->buf + (addr - new_addr), size); /* Adjust the accumulator address & size */ accum->loc = new_addr; @@ -250,7 +250,7 @@ H5F__accum_read(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, } /* end else */ /* Copy the dirty region to buffer */ - HDmemcpy((unsigned char *)buf + buf_off, (unsigned char *)accum->buf + accum->dirty_off + dirty_off, overlap_size); + H5MM_memcpy((unsigned char *)buf + buf_off, (unsigned char *)accum->buf + accum->dirty_off + dirty_off, overlap_size); } /* end if */ } /* end else */ } /* end if */ @@ -457,7 +457,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, HDmemmove(accum->buf + size, accum->buf, accum->size); /* Copy the new metadata at the front */ - HDmemcpy(accum->buf, buf, size); + H5MM_memcpy(accum->buf, buf, size); /* Set the new size & location of the metadata accumulator */ accum->loc = addr; @@ -479,7 +479,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") /* Copy the new metadata to the end */ - HDmemcpy(accum->buf + accum->size, buf, size); + H5MM_memcpy(accum->buf + accum->size, buf, size); /* Adjust the dirty region and mark accumulator dirty */ if(accum->dirty) @@ -502,7 +502,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, size_t dirty_off = (size_t)(addr - accum->loc); /* Copy the new metadata to the proper location within the accumulator */ - HDmemcpy(accum->buf + dirty_off, buf, size); + H5MM_memcpy(accum->buf + dirty_off, buf, size); /* Adjust the dirty region and mark accumulator dirty */ if(accum->dirty) { @@ -545,7 +545,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, HDmemmove(accum->buf + size, accum->buf + old_offset, (accum->size - old_offset)); /* Copy the new metadata at the front */ - HDmemcpy(accum->buf, buf, size); + H5MM_memcpy(accum->buf, buf, size); /* Set the new size & location of the metadata accumulator */ accum->loc = addr; @@ -582,7 +582,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, dirty_off = (size_t)(addr - accum->loc); /* Copy the new metadata to the end */ - HDmemcpy(accum->buf + dirty_off, buf, size); + H5MM_memcpy(accum->buf + dirty_off, buf, size); /* Set the new size of the metadata accumulator */ accum->size += add_size; @@ -625,7 +625,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, } /* end if */ /* Copy the new metadata to the buffer */ - HDmemcpy(accum->buf, buf, size); + H5MM_memcpy(accum->buf, buf, size); /* Set the new size & location of the metadata accumulator */ accum->loc = addr; @@ -688,7 +688,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, accum->size = size; /* Store the piece of metadata in the accumulator */ - HDmemcpy(accum->buf, buf, size); + H5MM_memcpy(accum->buf, buf, size); /* Adjust the dirty region and mark accumulator dirty */ accum->dirty_off = 0; @@ -721,7 +721,7 @@ H5F__accum_write(H5F_t *f, H5FD_mem_t map_type, haddr_t addr, accum->size = size; /* Store the piece of metadata in the accumulator */ - HDmemcpy(accum->buf, buf, size); + H5MM_memcpy(accum->buf, buf, size); /* Adjust the dirty region and mark accumulator dirty */ accum->dirty_off = 0; diff --git a/src/H5Fint.c b/src/H5Fint.c index 8a7019d..5775275 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -3254,7 +3254,7 @@ H5F_get_metadata_read_retry_info(H5F_t *file, H5F_retry_info_t *info) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the information */ - HDmemcpy(info->retries[j], file->shared->retries[i], tot_size); + H5MM_memcpy(info->retries[j], file->shared->retries[i], tot_size); } /* Increment location in info->retries[] array */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 5f7a1b2..94f66c6 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -134,7 +134,7 @@ typedef struct H5F_t H5F_t; \ HDcompile_assert(sizeof(double) == 8); \ HDcompile_assert(sizeof(double) == sizeof(uint64_t)); \ - HDmemcpy(&_n, &n, sizeof(double)); \ + H5MM_memcpy(&_n, &n, sizeof(double)); \ for(_u = 0; _u < sizeof(uint64_t); _u++, _n >>= 8) \ *_p++ = (uint8_t)(_n & 0xff); \ (p) = (uint8_t *)(p) + 8; \ @@ -240,7 +240,7 @@ typedef struct H5F_t H5F_t; (p) += 8; \ for(_u = 0; _u < sizeof(uint64_t); _u++) \ _n = (_n << 8) | *(--p); \ - HDmemcpy(&(n), &_n, sizeof(double)); \ + H5MM_memcpy(&(n), &_n, sizeof(double)); \ (p) += 8; \ } diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 489cc21..3c225a2 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -555,7 +555,7 @@ H5F__super_read(H5F_t *f, H5P_genplist_t *fa_plist, hbool_t initial_read) /* Set the B-tree internal node values, etc */ if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, udata.btree_k) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes") - HDmemcpy(sblock->btree_k, udata.btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); + H5MM_memcpy(sblock->btree_k, udata.btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); } /* end if */ else { /* Get the (default) B-tree internal node values, etc */ diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 361f8a1..125d6cf 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -269,7 +269,7 @@ H5F__drvrinfo_prefix_decode(H5O_drvinfo_t *drvrinfo, char *drv_name, /* Driver name and/or version */ if(drv_name) { - HDmemcpy(drv_name, (const char *)image, (size_t)8); + H5MM_memcpy(drv_name, (const char *)image, (size_t)8); drv_name[8] = '\0'; image += 8; /* advance past name/version */ } /* end if */ @@ -682,7 +682,7 @@ H5F__cache_superblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNU HDassert(sblock->cache_info.flush_me_last); /* Encode the common portion of the file superblock for all versions */ - HDmemcpy(image, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN); + H5MM_memcpy(image, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN); image += H5F_SIGNATURE_LEN; *image++ = (uint8_t)sblock->super_vers; diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index 721d591..425cc14 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -206,7 +206,7 @@ H5G_dense_btree2_name_store(void *_nrecord, const void *_udata) /* Copy user information info native record */ nrecord->hash = udata->common.name_hash; - HDmemcpy(nrecord->id, udata->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id, udata->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_name_store() */ @@ -305,7 +305,7 @@ H5G_dense_btree2_name_encode(uint8_t *raw, const void *_nrecord, void H5_ATTR_UN /* Encode the record's fields */ UINT32ENCODE(raw, nrecord->hash) - HDmemcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_name_encode() */ @@ -333,7 +333,7 @@ H5G_dense_btree2_name_decode(const uint8_t *raw, void *_nrecord, void H5_ATTR_UN /* Decode the record's fields */ UINT32DECODE(raw, nrecord->hash) - HDmemcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_name_decode() */ @@ -393,7 +393,7 @@ H5G_dense_btree2_corder_store(void *_nrecord, const void *_udata) /* Copy user information info native record */ nrecord->corder = udata->common.corder; - HDmemcpy(nrecord->id, udata->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id, udata->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_corder_store() */ @@ -469,7 +469,7 @@ H5G_dense_btree2_corder_encode(uint8_t *raw, const void *_nrecord, void H5_ATTR_ /* Encode the record's fields */ INT64ENCODE(raw, nrecord->corder) - HDmemcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(raw, nrecord->id, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_corder_encode() */ @@ -497,7 +497,7 @@ H5G_dense_btree2_corder_decode(const uint8_t *raw, void *_nrecord, void H5_ATTR_ /* Decode the record's fields */ INT64DECODE(raw, nrecord->corder) - HDmemcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); + H5MM_memcpy(nrecord->id, raw, (size_t)H5G_DENSE_FHEAP_ID_LEN); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5G_dense_btree2_corder_decode() */ diff --git a/src/H5Gcache.c b/src/H5Gcache.c index b447cad..7387eae 100644 --- a/src/H5Gcache.c +++ b/src/H5Gcache.c @@ -287,7 +287,7 @@ H5G__cache_node_serialize(const H5F_t *f, void *_image, size_t len, HDassert(len == sym->node_size); /* magic number */ - HDmemcpy(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* version number */ diff --git a/src/H5Gent.c b/src/H5Gent.c index baee35c..276da73 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -331,7 +331,7 @@ H5G__ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5_copy_depth_t depth) HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ - HDmemcpy(dst, src, sizeof(H5G_entry_t)); + H5MM_memcpy(dst, src, sizeof(H5G_entry_t)); /* Deep copy the names */ if(depth == H5_COPY_DEEP) { diff --git a/src/H5Gname.c b/src/H5Gname.c index 2aece2b..fa0a925 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -522,7 +522,7 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth) HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ - HDmemcpy(dst, src, sizeof(H5G_name_t)); + H5MM_memcpy(dst, src, sizeof(H5G_name_t)); /* Deep copy the names */ if(depth == H5_COPY_DEEP) { diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 72b3633..b79b7d2 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -672,7 +672,7 @@ H5G__node_insert(H5F_t *f, haddr_t addr, void H5_ATTR_UNUSED *_lt_key, if(NULL == (snrt = (H5G_node_t *)H5AC_protect(f, H5AC_SNODE, *new_node_p, f, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node") - HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f), + H5MM_memcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f), H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t)); snrt->nsyms = H5F_SYM_LEAF_K(f); snrt_flags |= H5AC__DIRTIED_FLAG; @@ -1262,7 +1262,7 @@ H5G__node_copy(H5F_t *f, const void H5_ATTR_UNUSED *_lt_key, haddr_t addr, char *link_name; /* Pointer to value of soft link */ /* Make a temporary copy, so that it will not change the info in the cache */ - HDmemcpy(&tmp_src_ent, src_ent, sizeof(H5G_entry_t)); + H5MM_memcpy(&tmp_src_ent, src_ent, sizeof(H5G_entry_t)); /* Set up group location for soft link to start in */ H5G_name_reset(&grp_path); diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index d029bea..492b5b9 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -555,7 +555,7 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, * Copy the component name into a null-terminated buffer so * we can pass it down to the other symbol table functions. */ - HDmemcpy(comp, name, nchars); + H5MM_memcpy(comp, name, nchars); comp[nchars] = '\0'; /* @@ -670,7 +670,7 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Only keep the creation order information from the parent * group's link info */ - HDmemcpy(&tmp_linfo, &def_linfo, sizeof(H5O_linfo_t)); + H5MM_memcpy(&tmp_linfo, &def_linfo, sizeof(H5O_linfo_t)); tmp_linfo.track_corder = par_linfo.track_corder; tmp_linfo.index_corder = par_linfo.index_corder; linfo = &tmp_linfo; diff --git a/src/H5HF.c b/src/H5HF.c index 3df7e7b..77ea6f8 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -104,7 +104,7 @@ H5HF_op_read(const void *obj, size_t obj_len, void *op_data) FUNC_ENTER_NOAPI_NOINIT_NOERR /* Perform "read", using memcpy() */ - HDmemcpy(op_data, obj, obj_len); + H5MM_memcpy(op_data, obj, obj_len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_op_read() */ @@ -129,7 +129,7 @@ H5HF_op_write(const void *obj, size_t obj_len, void *op_data) FUNC_ENTER_NOAPI_NOINIT_NOERR /* Perform "write", using memcpy() */ - HDmemcpy((void *)obj, op_data, obj_len); /* Casting away const OK -QAK */ + H5MM_memcpy((void *)obj, op_data, obj_len); /* Casting away const OK -QAK */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_op_write() */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 0c5d3aa..2d1c1f2 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -772,7 +772,7 @@ H5HF__cache_hdr_serialize(const H5F_t *f, void *_image, size_t len, hdr->f = f; /* Magic number */ - HDmemcpy(image, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1362,7 +1362,7 @@ H5HF__cache_iblock_serialize(const H5F_t *f, void *_image, size_t len, hdr->f = f; /* Magic number */ - HDmemcpy(image, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -1677,7 +1677,7 @@ H5HF__cache_dblock_verify_chksum(const void *_image, size_t len, void *_udata) /* Set up parameters for filter pipeline */ nbytes = len; filter_mask = udata->filter_mask; - HDmemcpy(read_buf, image, len); + H5MM_memcpy(read_buf, image, len); /* Push direct block data through I/O filter pipeline */ if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_ENABLE_EDC, filter_cb, &nbytes, &len, &read_buf) < 0) @@ -1724,7 +1724,7 @@ H5HF__cache_dblock_verify_chksum(const void *_image, size_t len, void *_udata) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy un-filtered data into block's buffer */ - HDmemcpy(udata->dblk, read_buf, len); + H5MM_memcpy(udata->dblk, read_buf, len); } /* end if */ done: @@ -1829,7 +1829,7 @@ H5HF__cache_dblock_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed for pipeline buffer") /* Copy compressed image into buffer */ - HDmemcpy(read_buf, image, len); + H5MM_memcpy(read_buf, image, len); /* Push direct block data through I/O filter pipeline */ nbytes = len; @@ -1841,7 +1841,7 @@ H5HF__cache_dblock_deserialize(const void *_image, size_t len, void *_udata, HDassert(nbytes == dblock->size); /* Copy un-filtered data into block's buffer */ - HDmemcpy(dblock->blk, read_buf, dblock->size); + H5MM_memcpy(dblock->blk, read_buf, dblock->size); } /* end if */ } /* end if */ else { @@ -1856,7 +1856,7 @@ H5HF__cache_dblock_deserialize(const void *_image, size_t len, void *_udata, /* Copy image to dblock->blk */ HDassert(dblock->size == len); - HDmemcpy(dblock->blk, image, dblock->size); + H5MM_memcpy(dblock->blk, image, dblock->size); } /* end else */ /* Start decoding direct block */ @@ -2146,7 +2146,7 @@ H5HF__cache_dblock_pre_serialize(H5F_t *f, void *_thing, image = dblock->blk; /* Magic number */ - HDmemcpy(image, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Version # */ @@ -2201,7 +2201,7 @@ H5HF__cache_dblock_pre_serialize(H5F_t *f, void *_thing, HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") /* Copy the direct block's image into the buffer to compress */ - HDmemcpy(write_buf, dblock->blk, write_size); + H5MM_memcpy(write_buf, dblock->blk, write_size); /* Push direct block data through I/O filter pipeline */ nbytes = write_size; @@ -2460,7 +2460,7 @@ H5HF__cache_dblock_serialize(const H5F_t *f, void *image, size_t len, HDassert(dblock->write_size == len); /* Copy the image from *(dblock->write_buf) to *image */ - HDmemcpy(image, dblock->write_buf, dblock->write_size); + H5MM_memcpy(image, dblock->write_buf, dblock->write_size); /* Free *(dblock->write_buf) if it was allocated by the * pre-serialize function diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index b014017..5a9b161 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -387,7 +387,7 @@ H5HF_hdr_create(H5F_t *f, const H5HF_create_t *cparam) /* Set the creation parameters for the heap */ hdr->max_man_size = cparam->max_man_size; hdr->checksum_dblocks = cparam->checksum_dblocks; - HDmemcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); + H5MM_memcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); /* Set root table address to indicate that the heap is empty currently */ hdr->man_dtable.table_addr = HADDR_UNDEF; diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index 6e475ad..d496d62 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -355,7 +355,7 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); write_size = obj_size; if(NULL == (write_buf = H5MM_malloc(write_size))) HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") - HDmemcpy(write_buf, obj, write_size); + H5MM_memcpy(write_buf, obj, write_size); /* Push direct block data through I/O filter pipeline */ nbytes = write_size; @@ -794,7 +794,7 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, /* Copy object to user's buffer if there's filters on heap data */ /* (if there's no filters, the object was read directly into the user's buffer) */ if(hdr->filter_len > 0) - HDmemcpy(op_data, read_buf, (size_t)obj_size); + H5MM_memcpy(op_data, read_buf, (size_t)obj_size); } /* end if */ else { /* Call the user's 'op' callback */ diff --git a/src/H5HFman.c b/src/H5HFman.c index 7f90f49..e5b5cb8 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -183,7 +183,7 @@ H5HF__man_insert(H5HF_hdr_t *hdr, size_t obj_size, const void *obj, void *_id) p = dblock->blk + blk_off; /* Copy the object's data into the heap */ - HDmemcpy(p, obj, obj_size); + H5MM_memcpy(p, obj, obj_size); p += obj_size; /* Sanity check */ diff --git a/src/H5HFsection.c b/src/H5HFsection.c index 36e966e..f5ac8e5 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -3082,7 +3082,7 @@ H5HF__sect_indirect_reduce_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect, HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "allocation failed for row section pointer array") /* Transfer row sections between current & peer sections */ - HDmemcpy(&peer_sect->u.indirect.dir_rows[0], + H5MM_memcpy(&peer_sect->u.indirect.dir_rows[0], §->u.indirect.dir_rows[0], (sizeof(H5HF_free_section_t *) * peer_dir_nrows)); HDmemmove(§->u.indirect.dir_rows[0], @@ -3321,7 +3321,7 @@ H5HF__sect_indirect_reduce(H5HF_hdr_t *hdr, H5HF_free_section_t *sect, HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "allocation failed for indirect section pointer array") /* Transfer child indirect sections between current & peer sections */ - HDmemcpy(&peer_sect->u.indirect.indir_ents[0], + H5MM_memcpy(&peer_sect->u.indirect.indir_ents[0], §->u.indirect.indir_ents[sect->u.indirect.indir_nents - peer_nentries], (sizeof(H5HF_free_section_t *) * peer_nentries)); sect->u.indirect.indir_nents -= (peer_nentries + 1); /* Transferred blocks, plus child entry */ @@ -3636,7 +3636,7 @@ H5HF__sect_indirect_merge_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect1, sect1->u.indirect.dir_rows = new_dir_rows; /* Transfer the second section's rows to first section */ - HDmemcpy(§1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows], + H5MM_memcpy(§1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows], §2->u.indirect.dir_rows[src_row2], (sizeof(H5HF_free_section_t *) * nrows_moved2)); @@ -3682,7 +3682,7 @@ H5HF__sect_indirect_merge_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect1, sect1->u.indirect.indir_ents = new_indir_ents; /* Transfer the second section's entries to first section */ - HDmemcpy(§1->u.indirect.indir_ents[sect1->u.indirect.indir_nents], + H5MM_memcpy(§1->u.indirect.indir_ents[sect1->u.indirect.indir_nents], §2->u.indirect.indir_ents[0], (sizeof(H5HF_free_section_t *) * sect2->u.indirect.indir_nents)); } /* end else */ diff --git a/src/H5HFtest.c b/src/H5HFtest.c index 1b1f688..0ddcb34 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -100,7 +100,7 @@ H5HF_get_cparam_test(const H5HF_t *fh, H5HF_create_t *cparam) else H5_CHECKED_ASSIGN(cparam->id_len, uint16_t, fh->hdr->id_len, unsigned); cparam->max_man_size = fh->hdr->max_man_size; - HDmemcpy(&(cparam->managed), &(fh->hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); + H5MM_memcpy(&(cparam->managed), &(fh->hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); H5O_msg_copy(H5O_PLINE_ID, &(fh->hdr->pline), &(cparam->pline)); FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5HFtiny.c b/src/H5HFtiny.c index 5cf1c08..1407861 100644 --- a/src/H5HFtiny.c +++ b/src/H5HFtiny.c @@ -176,7 +176,7 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); *id++ = enc_obj_size & H5HF_TINY_MASK_EXT_2; } /* end else */ - HDmemcpy(id, obj, obj_size); + H5MM_memcpy(id, obj, obj_size); HDmemset(id + obj_size, 0, (hdr->id_len - ((size_t)1 + (size_t)hdr->tiny_len_extended + obj_size))); /* Update statistics about heap */ diff --git a/src/H5HG.c b/src/H5HG.c index df1c82d..231294b 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -168,7 +168,7 @@ H5HG__create(H5F_t *f, size_t size) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "memory allocation failed") /* Initialize the header */ - HDmemcpy(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC); p = heap->chunk + H5_SIZEOF_MAGIC; *p++ = H5HG_VERSION; *p++ = 0; /*reserved*/ @@ -553,7 +553,7 @@ H5HG_insert(H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/) /* Copy data into the heap */ if(size > 0) { - HDmemcpy(heap->obj[idx].begin + H5HG_SIZEOF_OBJHDR(f), obj, size); + H5MM_memcpy(heap->obj[idx].begin + H5HG_SIZEOF_OBJHDR(f), obj, size); #ifdef OLD_WAY /* Don't bother zeroing out the rest of the info in the heap -QAK */ HDmemset(heap->obj[idx].begin + H5HG_SIZEOF_OBJHDR(f) + size, 0, @@ -618,7 +618,7 @@ H5HG_read(H5F_t *f, H5HG_t *hobj, void *object/*out*/, size_t *buf_size) /* Allocate a buffer for the object read in, if the user didn't give one */ if(!object && NULL == (object = H5MM_malloc(size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(object, p, size); + H5MM_memcpy(object, p, size); /* * Advance the heap in the CWFS list. We might have done this already diff --git a/src/H5HGcache.c b/src/H5HGcache.c index beaea7b..29e88df 100644 --- a/src/H5HGcache.c +++ b/src/H5HGcache.c @@ -271,7 +271,7 @@ H5HG__cache_heap_deserialize(const void *_image, size_t len, void *_udata, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the image buffer into the newly allocate chunk */ - HDmemcpy(heap->chunk, _image, len); + H5MM_memcpy(heap->chunk, _image, len); /* Deserialize the heap's header */ if(H5HG__hdr_deserialize(heap, (const uint8_t *)heap->chunk, f) < 0) @@ -448,7 +448,7 @@ H5HG__cache_heap_serialize(const H5F_t *f, void *image, size_t len, HDassert(heap->chunk); /* copy the image into the buffer */ - HDmemcpy(image, heap->chunk, len); + H5MM_memcpy(image, heap->chunk, len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HG__cache_heap_serialize() */ diff --git a/src/H5HL.c b/src/H5HL.c index 735077c..f290294 100644 --- a/src/H5HL.c +++ b/src/H5HL.c @@ -725,7 +725,7 @@ H5HL_insert(H5F_t *f, H5HL_t *heap, size_t buf_size, const void *buf)) } /* end if */ /* Copy the data into the heap */ - HDmemcpy(heap->dblk_image + offset, buf, buf_size); + H5MM_memcpy(heap->dblk_image + offset, buf, buf_size); /* Set return value */ ret_value = offset; diff --git a/src/H5HLcache.c b/src/H5HLcache.c index 926f787..2841a4c 100644 --- a/src/H5HLcache.c +++ b/src/H5HLcache.c @@ -464,7 +464,7 @@ H5HL__cache_prefix_deserialize(const void *_image, size_t len, void *_udata, image = ((const uint8_t *)_image) + heap->prfx_size; /* Copy the heap data from the speculative read buffer */ - HDmemcpy(heap->dblk_image, image, heap->dblk_size); + H5MM_memcpy(heap->dblk_image, image, heap->dblk_size); /* Build free list */ if(H5HL__fl_deserialize(heap) < 0) @@ -587,7 +587,7 @@ H5HL__cache_prefix_serialize(const H5F_t *f, void *_image, size_t len, heap->free_block = heap->freelist ? heap->freelist->offset : H5HL_FREE_NULL; /* Serialize the heap prefix */ - HDmemcpy(image, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; *image++ = H5HL_VERSION; *image++ = 0; /*reserved*/ @@ -615,7 +615,7 @@ H5HL__cache_prefix_serialize(const H5F_t *f, void *_image, size_t len, H5HL__fl_serialize(heap); /* Copy the heap data block into the cache image */ - HDmemcpy(image, heap->dblk_image, heap->dblk_size); + H5MM_memcpy(image, heap->dblk_image, heap->dblk_size); /* Sanity check */ HDassert((size_t)(image - (uint8_t *)_image) + heap->dblk_size == len); @@ -756,7 +756,7 @@ H5HL__cache_datablock_deserialize(const void *image, size_t len, void *_udata, HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate data block image buffer"); /* copy the datablock from the read buffer */ - HDmemcpy(heap->dblk_image, image, len); + H5MM_memcpy(heap->dblk_image, image, len); /* Build free list */ if(FAIL == H5HL__fl_deserialize(heap)) @@ -851,7 +851,7 @@ H5HL__cache_datablock_serialize(const H5F_t *f, void *image, size_t len, H5HL__fl_serialize(heap); /* Copy the heap's data block into the cache's image */ - HDmemcpy(image, heap->dblk_image, heap->dblk_size); + H5MM_memcpy(image, heap->dblk_image, heap->dblk_size); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HL__cache_datablock_serialize() */ diff --git a/src/H5L.c b/src/H5L.c index 1f45740..da0bc7d 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -1676,7 +1676,7 @@ H5L_register(const H5L_class_t *cls) } /* end if */ /* Copy link class info into table */ - HDmemcpy(H5L_table_g + i, cls, sizeof(H5L_class_t)); + H5MM_memcpy(H5L_table_g + i, cls, sizeof(H5L_class_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -2217,7 +2217,7 @@ H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, /* Fill in UD link-specific information in the link struct*/ if(ud_data_size > 0) { lnk.u.ud.udata = H5MM_malloc((size_t)ud_data_size); - HDmemcpy(lnk.u.ud.udata, ud_data, (size_t) ud_data_size); + H5MM_memcpy(lnk.u.ud.udata, ud_data, (size_t) ud_data_size); } /* end if */ else lnk.u.ud.udata = NULL; diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 0f3296f..d838d77 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -306,7 +306,7 @@ H5L__extern_query(const char H5_ATTR_UNUSED * link_name, const void *_udata, siz buf_size = udata_size; /* Copy the udata verbatim up to buf_size */ - HDmemcpy(buf, udata, buf_size); + H5MM_memcpy(buf, udata, buf_size); } /* end if */ /* Set return value */ diff --git a/src/H5MM.c b/src/H5MM.c index 866dfbe..9e87a2d 100644 --- a/src/H5MM.c +++ b/src/H5MM.c @@ -274,7 +274,7 @@ H5MM_malloc(size_t size) #if defined H5_MEMORY_ALLOC_SANITY_CHECK /* Initialize block list head singleton */ if(!H5MM_init_s) { - HDmemcpy(H5MM_block_head_s.sig, H5MM_block_signature_s, H5MM_SIG_SIZE); + H5MM_memcpy(H5MM_block_head_s.sig, H5MM_block_signature_s, H5MM_SIG_SIZE); H5MM_block_head_s.next = &H5MM_block_head_s; H5MM_block_head_s.prev = &H5MM_block_head_s; H5MM_block_head_s.u.info.size = SIZET_MAX; @@ -291,15 +291,15 @@ H5MM_malloc(size_t size) if(NULL != (block = (H5MM_block_t *)HDmalloc(alloc_size))) { /* Set up block */ - HDmemcpy(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE); + H5MM_memcpy(block->sig, H5MM_block_signature_s, H5MM_SIG_SIZE); block->next = H5MM_block_head_s.next; H5MM_block_head_s.next = block; block->next->prev = block; block->prev = &H5MM_block_head_s; block->u.info.size = size; block->u.info.in_use = TRUE; - HDmemcpy(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE); - HDmemcpy(block->b + H5MM_HEAD_GUARD_SIZE + size, H5MM_block_tail_guard_s, H5MM_TAIL_GUARD_SIZE); + H5MM_memcpy(block->b, H5MM_block_head_guard_s, H5MM_HEAD_GUARD_SIZE); + H5MM_memcpy(block->b + H5MM_HEAD_GUARD_SIZE + size, H5MM_block_tail_guard_s, H5MM_TAIL_GUARD_SIZE); /* Update statistics */ H5MM_total_alloc_bytes_s += size; @@ -417,7 +417,7 @@ H5MM_realloc(void *mem, size_t size) H5MM__sanity_check(mem); ret_value = H5MM_malloc(size); - HDmemcpy(ret_value, mem, MIN(size, old_size)); + H5MM_memcpy(ret_value, mem, MIN(size, old_size)); H5MM_xfree(mem); } /* end if */ else @@ -564,3 +564,35 @@ H5MM_xfree(void *mem) FUNC_LEAVE_NOAPI(NULL) } /* end H5MM_xfree() */ + +/*------------------------------------------------------------------------- + * Function: H5MM_memcpy + * + * Purpose: Like memcpy(3) but with a check for buffer overlap. + * + * Return: Success: pointer to dest + * Failure: NULL + * + * Programmer: Dana Robinson + * Spring 2019 + * + *------------------------------------------------------------------------- + */ +void * +H5MM_memcpy(void *dest, const void *src, size_t n) +{ + void *ret = NULL; + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(dest); + HDassert(src); + HDassert(dest >= src + n || src >= dest + n); + + ret = HDmemcpy(dest, src, n); + + FUNC_LEAVE_NOAPI(ret) + +} /* end H5MM_memcpy() */ + diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h index 0524601..2053215 100644 --- a/src/H5MMprivate.h +++ b/src/H5MMprivate.h @@ -45,6 +45,7 @@ H5_DLL void *H5MM_realloc(void *mem, size_t size); H5_DLL char *H5MM_xstrdup(const char *s); H5_DLL char *H5MM_strdup(const char *s); H5_DLL void *H5MM_xfree(void *mem); +H5_DLL void *H5MM_memcpy(void *dest, const void *src, size_t n); #if defined H5_MEMORY_ALLOC_SANITY_CHECK H5_DLL void H5MM_sanity_check_all(void); H5_DLL void H5MM_final_sanity_check(void); diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 23dd928..090df18 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -949,7 +949,7 @@ H5O__alloc_chunk(H5F_t *f, H5O_t *oh, size_t size, size_t found_null, * # at the beginning of the chunk image. */ if(oh->version > H5O_VERSION_1) { - HDmemcpy(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(p, H5O_CHK_MAGIC, (size_t)H5_SIZEOF_MAGIC); p += H5_SIZEOF_MAGIC; } /* end if */ @@ -988,7 +988,7 @@ H5O__alloc_chunk(H5F_t *f, H5O_t *oh, size_t size, size_t found_null, HDassert(curr_msg->type->id != H5O_CONT_ID); /* Copy the raw data */ - HDmemcpy(p, curr_msg->raw - (size_t)H5O_SIZEOF_MSGHDR_OH(oh), + H5MM_memcpy(p, curr_msg->raw - (size_t)H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh)); /* Update the message info */ @@ -1044,7 +1044,7 @@ H5O__alloc_chunk(H5F_t *f, H5O_t *oh, size_t size, size_t found_null, null_msg->chunkno = oh->mesg[found_msg->msgno].chunkno; /* Copy the message to move (& its prefix) to its new location */ - HDmemcpy(p, oh->mesg[found_msg->msgno].raw - H5O_SIZEOF_MSGHDR_OH(oh), + H5MM_memcpy(p, oh->mesg[found_msg->msgno].raw - H5O_SIZEOF_MSGHDR_OH(oh), oh->mesg[found_msg->msgno].raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh)); /* Switch moved message to point to new location */ @@ -1519,7 +1519,7 @@ H5O__move_cont(H5F_t *f, H5O_t *oh, unsigned cont_u) move_size = curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh); /* Move message out of deleted chunk */ - HDmemcpy(move_start, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size); + H5MM_memcpy(move_start, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size); curr_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); curr_msg->chunkno = cont_chunkno; chk_dirtied = TRUE; @@ -1791,7 +1791,7 @@ H5O__move_msgs_forward(H5F_t *f, H5O_t *oh) } /* end if */ /* Copy raw data for non-null message to new chunk */ - HDmemcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh)); + H5MM_memcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh)); /* Point non-null message at null message's space */ curr_msg->chunkno = null_msg->chunkno; diff --git a/src/H5Oattr.c b/src/H5Oattr.c index c420046..0a7c4bf 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -208,7 +208,7 @@ H5O_attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace") /* Copy the extent information to the dataspace */ - HDmemcpy(&(attr->shared->ds->extent), extent, sizeof(H5S_extent_t)); + H5MM_memcpy(&(attr->shared->ds->extent), extent, sizeof(H5S_extent_t)); /* Release temporary extent information */ extent = H5FL_FREE(H5S_extent_t, extent); @@ -240,7 +240,7 @@ H5O_attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, if(attr->shared->data_size) { if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, attr->shared->data_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(attr->shared->data, p, attr->shared->data_size); + H5MM_memcpy(attr->shared->data, p, attr->shared->data_size); } /* end if */ /* Increment the reference count for this object header message in cache(compact @@ -336,7 +336,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) *p++ = attr->shared->encoding; /* Write the name including null terminator */ - HDmemcpy(p, attr->shared->name, name_len); + H5MM_memcpy(p, attr->shared->name, name_len); if(attr->shared->version < H5O_ATTR_VERSION_2) { /* Pad to the correct number of bytes */ HDmemset(p + name_len, 0, H5O_ALIGN_OLD(name_len) - name_len); @@ -369,7 +369,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) /* Store attribute data. If there's no data, store 0 as fill value. */ if(attr->shared->data) - HDmemcpy(p, attr->shared->data, attr->shared->data_size); + H5MM_memcpy(p, attr->shared->data, attr->shared->data_size); else HDmemset(p, 0, attr->shared->data_size); diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 6e135c5..57ec9b8 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -862,7 +862,7 @@ H5O__attr_write_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, /* (Needs to occur before updating the shared message, or the hash * value on the old & new messages will be the same) */ - HDmemcpy(((H5A_t *)mesg->native)->shared->data, udata->attr->shared->data, udata->attr->shared->data_size); + H5MM_memcpy(((H5A_t *)mesg->native)->shared->data, udata->attr->shared->data, udata->attr->shared->data_size); } /* end if */ /* Mark the message as modified */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 578cff0..213dd11 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -542,7 +542,7 @@ H5O__cache_serialize(const H5F_t *f, void *image, size_t len, void *_thing) * Can we rework things so that the object header and the cache * share a buffer? */ - HDmemcpy(image, oh->chunk[0].image, len); + H5MM_memcpy(image, oh->chunk[0].image, len); done: FUNC_LEAVE_NOAPI(ret_value) @@ -900,7 +900,7 @@ H5O__cache_chk_serialize(const H5F_t *f, void *image, size_t len, void *_thing) /* copy the chunk into the image -- this is potentially expensive. * Can we rework things so that the chunk and the cache share a buffer? */ - HDmemcpy(image, chk_proxy->oh->chunk[chk_proxy->chunkno].image, len); + H5MM_memcpy(image, chk_proxy->oh->chunk[chk_proxy->chunkno].image, len); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1352,7 +1352,7 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image oh->chunk[chunkno].chunk_proxy = NULL; /* Copy disk image into chunk's image */ - HDmemcpy(oh->chunk[chunkno].image, image, oh->chunk[chunkno].size); + H5MM_memcpy(oh->chunk[chunkno].image, image, oh->chunk[chunkno].size); /* Point into chunk image to decode */ chunk_image = oh->chunk[chunkno].image; diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index a3d4884..9578f95 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -732,7 +732,7 @@ H5O__copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/, * header. This will be written when the header is flushed to disk. */ if(oh_dst->version > H5O_VERSION_1) - HDmemcpy(current_pos, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(current_pos, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); current_pos += H5O_SIZEOF_HDR(oh_dst) - H5O_SIZEOF_CHKSUM_OH(oh_dst); /* Loop through destination messages, updating their "raw" info */ @@ -755,7 +755,7 @@ H5O__copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/, /* Copy each message that wasn't dirtied above */ if(!mesg_dst->dirty) /* Copy the message header plus the message's raw data. */ - HDmemcpy(current_pos, mesg_src->raw - msghdr_size, msghdr_size + mesg_src->raw_size); + H5MM_memcpy(current_pos, mesg_src->raw - msghdr_size, msghdr_size + mesg_src->raw_size); /* Set message's raw pointer to destination chunk's new "image" */ mesg_dst->raw = current_pos + msghdr_size; diff --git a/src/H5Odrvinfo.c b/src/H5Odrvinfo.c index 159c950..eb678e4 100644 --- a/src/H5Odrvinfo.c +++ b/src/H5Odrvinfo.c @@ -101,7 +101,7 @@ H5O_drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message") /* Retrieve driver name */ - HDmemcpy(mesg->name, p, 8); + H5MM_memcpy(mesg->name, p, 8); mesg->name[8] = '\0'; p += 8; @@ -116,7 +116,7 @@ H5O_drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, } /* end if */ /* Copy encoded driver info into buffer */ - HDmemcpy(mesg->buf, p, mesg->len); + H5MM_memcpy(mesg->buf, p, mesg->len); /* Set return value */ ret_value = (void *)mesg; @@ -152,11 +152,11 @@ H5O_drvinfo_encode(H5F_t H5_ATTR_UNUSED *f, hbool_t H5_ATTR_UNUSED disable_share /* Store version, driver name, buffer length, & encoded buffer */ *p++ = H5O_DRVINFO_VERSION; - HDmemcpy(p, mesg->name, 8); + H5MM_memcpy(p, mesg->name, 8); p += 8; HDassert(mesg->len <= 65535); UINT16ENCODE(p, mesg->len); - HDmemcpy(p, mesg->buf, mesg->len); + H5MM_memcpy(p, mesg->buf, mesg->len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_drvinfo_encode() */ @@ -200,7 +200,7 @@ H5O_drvinfo_copy(const void *_mesg, void *_dest) dest = (H5O_drvinfo_t *)H5MM_xfree(dest); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") } /* end if */ - HDmemcpy(dest->buf, mesg->buf, mesg->len); + H5MM_memcpy(dest->buf, mesg->buf, mesg->len); /* Set return value */ ret_value = dest; diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 28970d1..39d8bac 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -250,7 +250,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p HDassert(0 == (z & 0x7)); /*must be aligned*/ if(NULL == (dt->shared->u.opaque.tag = (char *)H5MM_malloc(z + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDmemcpy(dt->shared->u.opaque.tag, *pp, z); + H5MM_memcpy(dt->shared->u.opaque.tag, *pp, z); dt->shared->u.opaque.tag[z] = '\0'; *pp += z; break; @@ -483,7 +483,7 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p } /* end for */ /* Values */ - HDmemcpy(dt->shared->u.enumer.value, *pp, + H5MM_memcpy(dt->shared->u.enumer.value, *pp, dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size); *pp += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size; break; @@ -882,7 +882,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) z = HDstrlen(dt->shared->u.opaque.tag); aligned = (z + 7) & (H5T_OPAQUE_TAG_MAX - 8); flags = (unsigned)(flags | aligned); - HDmemcpy(*pp, dt->shared->u.opaque.tag, MIN(z,aligned)); + H5MM_memcpy(*pp, dt->shared->u.opaque.tag, MIN(z,aligned)); for(n = MIN(z, aligned); n < aligned; n++) (*pp)[n] = 0; *pp += aligned; @@ -997,7 +997,7 @@ H5O_dtype_encode_helper(const H5F_t *f, uint8_t **pp, const H5T_t *dt) } /* end for */ /* Values */ - HDmemcpy(*pp, dt->shared->u.enumer.value, dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size); + H5MM_memcpy(*pp, dt->shared->u.enumer.value, dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size); *pp += dt->shared->u.enumer.nmembs * dt->shared->parent->shared->size; break; diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 6a81a46..b18d819 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -461,7 +461,7 @@ H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_d HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy the "top level" information */ - HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t)); + H5MM_memcpy(efl_dst, efl_src, sizeof(H5O_efl_t)); /* Determine size needed for destination heap */ heap_size = H5HL_ALIGN(1); /* "empty" name */ @@ -488,7 +488,7 @@ H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_d HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* copy content from the source. Need to update later */ - HDmemcpy(efl_dst->slot, efl_src->slot, size); + H5MM_memcpy(efl_dst->slot, efl_src->slot, size); } /* end if */ /* copy the name from the source */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index fd50cb9..ebd885c 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -232,7 +232,7 @@ H5O_fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "destination buffer too small") if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") - HDmemcpy(fill->buf, p, (size_t)fill->size); + H5MM_memcpy(fill->buf, p, (size_t)fill->size); } /* end if */ } /* end if */ else @@ -270,7 +270,7 @@ H5O_fill_new_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") - HDmemcpy(fill->buf, p, (size_t)fill->size); + H5MM_memcpy(fill->buf, p, (size_t)fill->size); /* Set the "defined" flag */ fill->fill_defined = TRUE; @@ -353,7 +353,7 @@ H5O_fill_old_decode(H5F_t *f, H5O_t *open_oh, if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") - HDmemcpy(fill->buf, p, (size_t)fill->size); + H5MM_memcpy(fill->buf, p, (size_t)fill->size); fill->fill_defined = TRUE; } /* end if */ else @@ -420,7 +420,7 @@ H5O_fill_new_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *_fill) if(fill->size > 0) if(fill->buf) { H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); - HDmemcpy(p, fill->buf, (size_t)fill->size); + H5MM_memcpy(p, fill->buf, (size_t)fill->size); } /* end if */ } /* end if */ } /* end if */ @@ -459,7 +459,7 @@ H5O_fill_new_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *_fill) /* Encode the fill value */ HDassert(fill->buf); H5_CHECK_OVERFLOW(fill->size, ssize_t, size_t); - HDmemcpy(p, fill->buf, (size_t)fill->size); + H5MM_memcpy(p, fill->buf, (size_t)fill->size); } /* end if */ else { /* Flags */ @@ -499,7 +499,7 @@ H5O_fill_old_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p, const void *_fill) UINT32ENCODE(p, fill->size); if(fill->buf) - HDmemcpy(p, fill->buf, (size_t)fill->size); + H5MM_memcpy(p, fill->buf, (size_t)fill->size); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_fill_old_encode() */ @@ -551,7 +551,7 @@ H5O_fill_copy(const void *_src, void *_dst) H5_CHECK_OVERFLOW(src->size, ssize_t, size_t); if(NULL == (dst->buf = H5MM_malloc((size_t)src->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value") - HDmemcpy(dst->buf, src->buf, (size_t)src->size); + H5MM_memcpy(dst->buf, src->buf, (size_t)src->size); /* Check for needing to convert/copy fill value */ if(src->type) { @@ -1025,7 +1025,7 @@ H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type, hbool_t *fill_changed) else { if(NULL == (buf = H5MM_malloc(H5T_get_size(dset_type)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") - HDmemcpy(buf, fill->buf, H5T_get_size(fill->type)); + H5MM_memcpy(buf, fill->buf, H5T_get_size(fill->type)); } /* end else */ /* Use CALLOC here to clear the buffer in case later the library thinks there's diff --git a/src/H5Oint.c b/src/H5Oint.c index d3a409c..8a10d04 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -496,7 +496,7 @@ H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t ini /* Put magic # for object header in first chunk */ if(H5O_VERSION_1 < oh->version) - HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); /* Create the message list */ oh->nmesgs = 1; @@ -1921,7 +1921,7 @@ H5O_loc_copy(H5O_loc_t *dst, H5O_loc_t *src, H5_copy_depth_t depth) HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ - HDmemcpy(dst, src, sizeof(H5O_loc_t)); + H5MM_memcpy(dst, src, sizeof(H5O_loc_t)); /* Deep copy the names */ if(depth == H5_COPY_DEEP) { diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 86f4c46..138f219 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -189,7 +189,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, if(mesg->storage.u.compact.size > 0) { if(NULL == (mesg->storage.u.compact.buf = H5MM_malloc(mesg->storage.u.compact.size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for compact data buffer") - HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); + H5MM_memcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; } /* end if */ } /* end if */ @@ -210,7 +210,7 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed for compact data buffer") /* Compact data */ - HDmemcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); + H5MM_memcpy(mesg->storage.u.compact.buf, p, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; } /* end if */ @@ -425,14 +425,14 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, tmp_size = HDstrlen((const char *)heap_block_p) + 1; if(NULL == (mesg->storage.u.virt.list[i].source_file_name = (char *)H5MM_malloc(tmp_size))) HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source file name") - (void)HDmemcpy(mesg->storage.u.virt.list[i].source_file_name, heap_block_p, tmp_size); + (void)H5MM_memcpy(mesg->storage.u.virt.list[i].source_file_name, heap_block_p, tmp_size); heap_block_p += tmp_size; /* Source dataset name */ tmp_size = HDstrlen((const char *)heap_block_p) + 1; if(NULL == (mesg->storage.u.virt.list[i].source_dset_name = (char *)H5MM_malloc(tmp_size))) HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate memory for source dataset name") - (void)HDmemcpy(mesg->storage.u.virt.list[i].source_dset_name, heap_block_p, tmp_size); + (void)H5MM_memcpy(mesg->storage.u.virt.list[i].source_dset_name, heap_block_p, tmp_size); heap_block_p += tmp_size; /* Source selection */ @@ -581,7 +581,7 @@ H5O__layout_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, /* Raw data */ if(mesg->storage.u.compact.size > 0) { if(mesg->storage.u.compact.buf) - HDmemcpy(p, mesg->storage.u.compact.buf, mesg->storage.u.compact.size); + H5MM_memcpy(p, mesg->storage.u.compact.buf, mesg->storage.u.compact.size); else HDmemset(p, 0, mesg->storage.u.compact.size); p += mesg->storage.u.compact.size; @@ -742,7 +742,7 @@ H5O__layout_copy(const void *_mesg, void *_dest) HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset") /* Copy over the raw data */ - HDmemcpy(dest->storage.u.compact.buf, mesg->storage.u.compact.buf, dest->storage.u.compact.size); + H5MM_memcpy(dest->storage.u.compact.buf, mesg->storage.u.compact.buf, dest->storage.u.compact.size); } /* end if */ else HDassert(dest->storage.u.compact.buf == NULL); diff --git a/src/H5Olink.c b/src/H5Olink.c index 55e1aee..4bd952b 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -202,7 +202,7 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, /* Get the link's name */ if(NULL == (lnk->name = (char *)H5MM_malloc(len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(lnk->name, p, len); + H5MM_memcpy(lnk->name, p, len); lnk->name[len] = '\0'; p += len; @@ -220,7 +220,7 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid link length") if(NULL == (lnk->u.soft.name = (char *)H5MM_malloc((size_t)len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(lnk->u.soft.name, p, len); + H5MM_memcpy(lnk->u.soft.name, p, len); lnk->u.soft.name[len] = '\0'; p += len; break; @@ -240,7 +240,7 @@ H5O__link_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, { if(NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(lnk->u.ud.udata, p, len); + H5MM_memcpy(lnk->u.ud.udata, p, len); p += len; } else @@ -349,7 +349,7 @@ H5O_link_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, con } /* end switch */ /* Store the link's name */ - HDmemcpy(p, lnk->name, (size_t)len); + H5MM_memcpy(p, lnk->name, (size_t)len); p += len; /* Store the appropriate information for each type of link */ @@ -364,7 +364,7 @@ H5O_link_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, con len = (uint16_t)HDstrlen(lnk->u.soft.name); HDassert(len > 0); UINT16ENCODE(p, len) - HDmemcpy(p, lnk->u.soft.name, (size_t)len); + H5MM_memcpy(p, lnk->u.soft.name, (size_t)len); p += len; break; @@ -380,7 +380,7 @@ H5O_link_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, con UINT16ENCODE(p, len) if(len > 0) { - HDmemcpy(p, lnk->u.ud.udata, (size_t)len); + H5MM_memcpy(p, lnk->u.ud.udata, (size_t)len); p+=len; } break; @@ -437,7 +437,7 @@ H5O_link_copy(const void *_mesg, void *_dest) if(lnk->u.ud.size > 0) { if(NULL == (dest->u.ud.udata = H5MM_malloc(lnk->u.ud.size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(dest->u.ud.udata, lnk->u.ud.udata, lnk->u.ud.size); + H5MM_memcpy(dest->u.ud.udata, lnk->u.ud.udata, lnk->u.ud.size); } /* end if */ } /* end if */ diff --git a/src/H5Opline.c b/src/H5Opline.c index 1fae1b8..85a95b7 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -318,7 +318,7 @@ H5O_pline_encode(H5F_t H5_ATTR_UNUSED *f, uint8_t *p/*out*/, const void *mesg) /* Encode name, if there is one to encode */ if(name_length > 0) { /* Store name, with null terminator */ - HDmemcpy(p, name, name_length); + H5MM_memcpy(p, name, name_length); p += name_length; /* Pad out name to alignment, in older versions */ @@ -409,7 +409,7 @@ H5O_pline_copy(const void *_src, void *_dst/*out*/) if(NULL == (dst->filter[i].cd_values = (unsigned *)H5MM_malloc(src->filter[i].cd_nelmts* sizeof(unsigned)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(dst->filter[i].cd_values, src->filter[i].cd_values, + H5MM_memcpy(dst->filter[i].cd_values, src->filter[i].cd_values, src->filter[i].cd_nelmts * sizeof(unsigned)); } /* end if */ else diff --git a/src/H5Oshared.c b/src/H5Oshared.c index 4fc0488..eec1a84 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -358,7 +358,7 @@ H5O__shared_decode(H5F_t *f, H5O_t *open_oh, unsigned *ioflags, const uint8_t *b */ if(sh_mesg.type == H5O_SHARE_TYPE_SOHM) { HDassert(version >= H5O_SHARED_VERSION_3); - HDmemcpy(&sh_mesg.u.heap_id, buf, sizeof(sh_mesg.u.heap_id)); + H5MM_memcpy(&sh_mesg.u.heap_id, buf, sizeof(sh_mesg.u.heap_id)); } /* end if */ else { /* The H5O_COMMITTED_FLAG should be set if this message @@ -426,7 +426,7 @@ H5O__shared_encode(const H5F_t *f, uint8_t *buf/*out*/, const H5O_shared_t *sh_m * object header that holds it. */ if(sh_mesg->type == H5O_SHARE_TYPE_SOHM) - HDmemcpy(buf, &(sh_mesg->u.heap_id), sizeof(sh_mesg->u.heap_id)); + H5MM_memcpy(buf, &(sh_mesg->u.heap_id), sizeof(sh_mesg->u.heap_id)); else H5F_addr_encode(f, &buf, sh_mesg->u.loc.oh_addr); diff --git a/src/H5PB.c b/src/H5PB.c index 88a6151..b4a39a7 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -609,7 +609,7 @@ H5PB_update_entry(H5PB_t *page_buf, haddr_t addr, size_t size, const void *buf) HDassert(addr + size <= page_addr + page_buf->page_size); offset = addr - page_addr; - HDmemcpy((uint8_t *)page_entry->page_buf_ptr + offset, buf, size); + H5MM_memcpy((uint8_t *)page_entry->page_buf_ptr + offset, buf, size); /* move to top of LRU list */ H5PB__MOVE_TO_TOP_LRU(page_buf, page_entry) @@ -818,7 +818,7 @@ H5PB_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/ offset = addr - first_page_addr; HDassert(page_buf->page_size > offset); - HDmemcpy(buf, (uint8_t *)page_entry->page_buf_ptr + offset, + H5MM_memcpy(buf, (uint8_t *)page_entry->page_buf_ptr + offset, page_buf->page_size - (size_t)offset); /* move to top of LRU list */ @@ -829,7 +829,7 @@ H5PB_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/ offset = (num_touched_pages-2)*page_buf->page_size + (page_buf->page_size - (addr - first_page_addr)); - HDmemcpy((uint8_t *)buf + offset, page_entry->page_buf_ptr, + H5MM_memcpy((uint8_t *)buf + offset, page_entry->page_buf_ptr, (size_t)((addr + size) - last_page_addr)); /* move to top of LRU list */ @@ -839,7 +839,7 @@ H5PB_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/ else { offset = i*page_buf->page_size; - HDmemcpy((uint8_t *)buf+(i*page_buf->page_size) , page_entry->page_buf_ptr, + H5MM_memcpy((uint8_t *)buf+(i*page_buf->page_size) , page_entry->page_buf_ptr, page_buf->page_size); } /* end else */ } /* end if */ @@ -872,7 +872,7 @@ H5PB_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/ buf_offset = (0 == i ? 0 : size - access_size); /* copy the requested data from the page into the input buffer */ - HDmemcpy((uint8_t *)buf + buf_offset, (uint8_t *)page_entry->page_buf_ptr + offset, access_size); + H5MM_memcpy((uint8_t *)buf + buf_offset, (uint8_t *)page_entry->page_buf_ptr + offset, access_size); /* Update LRU */ H5PB__MOVE_TO_TOP_LRU(page_buf, page_entry) @@ -937,7 +937,7 @@ H5PB_read(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*out*/ /* Copy the requested data from the page into the input buffer */ offset = (0 == i ? addr - search_addr : 0); buf_offset = (0 == i ? 0 : size - access_size); - HDmemcpy((uint8_t *)buf + buf_offset, (uint8_t *)new_page_buf + offset, access_size); + H5MM_memcpy((uint8_t *)buf + buf_offset, (uint8_t *)new_page_buf + offset, access_size); /* Create the new PB entry */ if(NULL == (page_entry = H5FL_CALLOC(H5PB_entry_t))) @@ -1102,7 +1102,7 @@ H5PB_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, HDassert(page_buf->page_size > offset); /* Update page's data */ - HDmemcpy((uint8_t *)page_entry->page_buf_ptr + offset, buf, page_buf->page_size - (size_t)offset); + H5MM_memcpy((uint8_t *)page_entry->page_buf_ptr + offset, buf, page_buf->page_size - (size_t)offset); /* Mark page dirty and push to top of LRU */ page_entry->is_dirty = TRUE; @@ -1121,7 +1121,7 @@ H5PB_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, (page_buf->page_size - (addr - first_page_addr)); /* Update page's data */ - HDmemcpy(page_entry->page_buf_ptr, (const uint8_t *)buf + offset, + H5MM_memcpy(page_entry->page_buf_ptr, (const uint8_t *)buf + offset, (size_t)((addr + size) - last_page_addr)); /* Mark page dirty and push to top of LRU */ @@ -1173,7 +1173,7 @@ H5PB_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, buf_offset = (0 == i ? 0 : size - access_size); /* Copy the requested data from the input buffer into the page */ - HDmemcpy((uint8_t *)page_entry->page_buf_ptr + offset, (const uint8_t *)buf + buf_offset, access_size); + H5MM_memcpy((uint8_t *)page_entry->page_buf_ptr + offset, (const uint8_t *)buf + buf_offset, access_size); /* Mark page dirty and push to top of LRU */ page_entry->is_dirty = TRUE; @@ -1289,7 +1289,7 @@ H5PB_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, } /* end else */ /* Copy the requested data from the page into the input buffer */ - HDmemcpy((uint8_t *)new_page_buf + offset, (const uint8_t *)buf+buf_offset, access_size); + H5MM_memcpy((uint8_t *)new_page_buf + offset, (const uint8_t *)buf+buf_offset, access_size); /* Page is dirty now */ page_entry->is_dirty = TRUE; diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index 00e598f..9279615 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -341,7 +341,7 @@ H5P__dapl_vds_file_pref_enc(const void *value, void **_pp, size_t *size) /* encode the prefix */ if(NULL != vds_file_pref) { - HDmemcpy(*(char **)pp, vds_file_pref, len); + H5MM_memcpy(*(char **)pp, vds_file_pref, len); *pp += len; } /* end if */ } /* end if */ @@ -589,7 +589,7 @@ H5P__dapl_efile_pref_enc(const void *value, void **_pp, size_t *size) /* encode the prefix */ if(NULL != efile_pref) { - HDmemcpy(*(char **)pp, efile_pref, len); + H5MM_memcpy(*(char **)pp, efile_pref, len); *pp += len; } /* end if */ } /* end if */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index b85f105..41d7c78 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -439,13 +439,13 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size) for(u = 0; u < layout->storage.u.virt.list_nused; u++) { /* Source file name */ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1; - (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_file_name, tmp_size); + (void)H5MM_memcpy(*pp, layout->storage.u.virt.list[u].source_file_name, tmp_size); *pp += tmp_size; *size += tmp_size; /* Source dataset name */ tmp_size = HDstrlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1; - (void)HDmemcpy(*pp, layout->storage.u.virt.list[u].source_dset_name, tmp_size); + (void)H5MM_memcpy(*pp, layout->storage.u.virt.list[u].source_dset_name, tmp_size); *pp += tmp_size; *size += tmp_size; @@ -615,14 +615,14 @@ H5P__dcrt_layout_dec(const void **_pp, void *value) tmp_size = HDstrlen((const char *)*pp) + 1; if(NULL == (tmp_layout.storage.u.virt.list[u].source_file_name = (char *)H5MM_malloc(tmp_size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source file name") - (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_file_name, *pp, tmp_size); + (void)H5MM_memcpy(tmp_layout.storage.u.virt.list[u].source_file_name, *pp, tmp_size); *pp += tmp_size; /* Source dataset name */ tmp_size = HDstrlen((const char *)*pp) + 1; if(NULL == (tmp_layout.storage.u.virt.list[u].source_dset_name = (char *)H5MM_malloc(tmp_size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate memory for source dataset name") - (void)HDmemcpy(tmp_layout.storage.u.virt.list[u].source_dset_name, *pp, tmp_size); + (void)H5MM_memcpy(tmp_layout.storage.u.virt.list[u].source_dset_name, *pp, tmp_size); *pp += tmp_size; /* Source selection */ @@ -687,7 +687,7 @@ H5P__dcrt_layout_dec(const void **_pp, void *value) } /* end switch */ /* Set the value */ - HDmemcpy(value, layout, sizeof(H5O_layout_t)); + H5MM_memcpy(value, layout, sizeof(H5O_layout_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1036,7 +1036,7 @@ H5P__dcrt_fill_value_enc(const void *value, void **_pp, size_t *size) /* Encode the fill value & datatype */ if(fill->size > 0) { /* Encode the fill value itself */ - HDmemcpy(*pp, (uint8_t *)fill->buf, (size_t)fill->size); + H5MM_memcpy(*pp, (uint8_t *)fill->buf, (size_t)fill->size); *pp += fill->size; /* Encode fill value datatype */ @@ -1133,7 +1133,7 @@ H5P__dcrt_fill_value_dec(const void **_pp, void *_value) /* Allocate fill buffer and copy the contents in it */ if(NULL == (fill->buf = H5MM_malloc((size_t)fill->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for fill value buffer") - HDmemcpy((uint8_t *)fill->buf, *pp, (size_t)fill->size); + H5MM_memcpy((uint8_t *)fill->buf, *pp, (size_t)fill->size); *pp += fill->size; enc_size = *(*pp)++; @@ -1448,7 +1448,7 @@ H5P__dcrt_ext_file_list_enc(const void *value, void **_pp, size_t *size) UINT64ENCODE_VAR(*pp, enc_value, enc_size); /* Encode name */ - HDmemcpy(*pp, (uint8_t *)(efl->slot[u].name), len); + H5MM_memcpy(*pp, (uint8_t *)(efl->slot[u].name), len); *pp += len; /* Encode offset */ @@ -2035,7 +2035,7 @@ H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]) #endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */ /* Verify & initialize property's chunk dims */ - HDmemcpy(&chunk_layout, &H5D_def_layout_chunk_g, sizeof(H5D_def_layout_chunk_g)); + H5MM_memcpy(&chunk_layout, &H5D_def_layout_chunk_g, sizeof(H5D_def_layout_chunk_g)); HDmemset(&chunk_layout.u.chunk.dim, 0, sizeof(chunk_layout.u.chunk.dim)); chunk_nelmts = 1; for(u = 0; u < (unsigned)ndims; u++) { @@ -2204,7 +2204,7 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release layout message") /* Copy the default virtual layout */ - HDmemcpy(&virtual_layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); + H5MM_memcpy(&virtual_layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); /* Sanity check */ HDassert(virtual_layout.storage.u.virt.list_nalloc == 0); @@ -3243,7 +3243,7 @@ H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) fill.size = (ssize_t)H5T_get_size(type); if(NULL == (fill.buf = H5MM_malloc((size_t)fill.size))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for fill value") - HDmemcpy(fill.buf, value, (size_t)fill.size); + H5MM_memcpy(fill.buf, value, (size_t)fill.size); /* Set up type conversion function */ if(NULL == (tpath = H5T_path_find(type, type))) @@ -3351,7 +3351,7 @@ H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, void *value/*out*/) if(H5T_path_bkg(tpath) && NULL == (bkg = H5MM_malloc(H5T_get_size(fill.type)))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for type conversion") } /* end else */ - HDmemcpy(buf, fill.buf, H5T_get_size(fill.type)); + H5MM_memcpy(buf, fill.buf, H5T_get_size(fill.type)); /* Do the conversion */ if((dst_id = H5I_register(H5I_DATATYPE, H5T_copy(type, H5T_COPY_TRANSIENT), FALSE)) < 0) @@ -3359,7 +3359,7 @@ H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, void *value/*out*/) if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, buf, bkg) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "datatype conversion failed") if(buf != value) - HDmemcpy(value, buf, H5T_get_size(type)); + H5MM_memcpy(value, buf, H5T_get_size(type)); done: if(buf != value) diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 8338d84..df9cf4e 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -695,7 +695,7 @@ H5P__dxfr_xform_enc(const void *value, void **_pp, size_t *size) HDassert(pexp); /* Copy the expression into the buffer */ - HDmemcpy(*pp, (const uint8_t *)pexp, len); + H5MM_memcpy(*pp, (const uint8_t *)pexp, len); *pp += len; *pp[0] = '\0'; } /* end if */ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index bfb52ff..57b20d7 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -1064,7 +1064,7 @@ H5P__file_driver_copy(void *value) else if(driver->fapl_size > 0) { if(NULL == (new_pl = H5MM_malloc(driver->fapl_size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "driver info allocation failed") - HDmemcpy(new_pl, info->driver_info, driver->fapl_size); + H5MM_memcpy(new_pl, info->driver_info, driver->fapl_size); } /* end else-if */ else HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "no way to copy driver info") @@ -2597,7 +2597,7 @@ H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed") } /* end if */ else - HDmemcpy(image_info.buffer, buf_ptr, buf_len); + H5MM_memcpy(image_info.buffer, buf_ptr, buf_len); } /* end if */ else image_info.buffer = NULL; @@ -2691,7 +2691,7 @@ H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "image_memcpy callback failed") } /* end if */ else - HDmemcpy(copy_ptr, image_info.buffer, image_info.size); + H5MM_memcpy(copy_ptr, image_info.buffer, image_info.size); } /* end if */ *buf_ptr_ptr = copy_ptr; @@ -2894,7 +2894,7 @@ H5P__file_image_info_copy(void *value) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "image_memcpy callback failed") } /* end if */ else - HDmemcpy(info->buffer, old_buffer, info->size); + H5MM_memcpy(info->buffer, old_buffer, info->size); } /* end if */ /* Copy udata if it exists */ @@ -3089,7 +3089,7 @@ H5P__facc_cache_image_config_dec(const void **_pp, void *_value) HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t)); /* Set property to default value */ - HDmemcpy(config, &H5F_def_mdc_initCacheImageCfg_g, sizeof(H5AC_cache_image_config_t)); + H5MM_memcpy(config, &H5F_def_mdc_initCacheImageCfg_g, sizeof(H5AC_cache_image_config_t)); /* Decode type sizes */ enc_size = *(*pp)++; @@ -3480,7 +3480,7 @@ H5P__facc_cache_config_enc(const void *value, void **_pp, size_t *size) H5_ENCODE_UNSIGNED(*pp, config->close_trace_file); - HDmemcpy(*pp, (const uint8_t *)(config->trace_file_name), (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + 1)); + H5MM_memcpy(*pp, (const uint8_t *)(config->trace_file_name), (size_t)(H5AC__MAX_TRACE_FILE_NAME_LEN + 1)); *pp += H5AC__MAX_TRACE_FILE_NAME_LEN + 1; H5_ENCODE_UNSIGNED(*pp, config->evictions_enabled); @@ -3615,7 +3615,7 @@ H5P__facc_cache_config_dec(const void **_pp, void *_value) HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t)); /* Set property to default value */ - HDmemcpy(config, &H5F_def_mdc_initCacheCfg_g, sizeof(H5AC_cache_config_t)); + H5MM_memcpy(config, &H5F_def_mdc_initCacheCfg_g, sizeof(H5AC_cache_config_t)); /* Decode type sizes */ enc_size = *(*pp)++; @@ -4195,7 +4195,7 @@ H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, /* Copy log location to output buffer */ if(location_ptr && location) - HDmemcpy(location, location_ptr, *location_size); + H5MM_memcpy(location, location_ptr, *location_size); /* Get location size, including terminating NULL */ if(location_size) { @@ -4250,7 +4250,7 @@ H5P_facc_mdc_log_location_enc(const void *value, void **_pp, size_t *size) /* encode the prefix */ if(NULL != log_location) { - HDmemcpy(*(char **)pp, log_location, len); + H5MM_memcpy(*(char **)pp, log_location, len); *pp += len; } /* end if */ } /* end if */ @@ -4536,7 +4536,7 @@ H5P__encode_coll_md_read_flag_t(const void *value, void **_pp, size_t *size) if(NULL != *pp) { /* Encode the value */ - HDmemcpy(*pp, coll_md_read_flag, sizeof(H5P_coll_md_read_flag_t)); + H5MM_memcpy(*pp, coll_md_read_flag, sizeof(H5P_coll_md_read_flag_t)); *pp += sizeof(H5P_coll_md_read_flag_t); } /* end if */ diff --git a/src/H5Pint.c b/src/H5Pint.c index e2ae792..e1b20a5 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -631,7 +631,7 @@ H5P__do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) /* Allocate space for a temporary copy of the property value */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value") - HDmemcpy(tmp_value, prop->value, prop->size); + H5MM_memcpy(tmp_value, prop->value, prop->size); /* Call "type 1" callback ('create', 'copy' or 'close') */ if(cb(prop->name, prop->size, tmp_value) < 0) @@ -642,7 +642,7 @@ H5P__do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") /* Copy the changed value into the new property */ - HDmemcpy(pcopy->value, tmp_value, prop->size); + H5MM_memcpy(pcopy->value, tmp_value, prop->size); /* Insert the changed property into the property list */ if(H5P__add_prop(slist, pcopy) < 0) @@ -990,7 +990,7 @@ H5P__dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Copy basic property information */ - HDmemcpy(prop, oprop, sizeof(H5P_genprop_t)); + H5MM_memcpy(prop, oprop, sizeof(H5P_genprop_t)); /* Check if we should duplicate the name or share it */ @@ -1030,7 +1030,7 @@ H5P__dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) HDassert(prop->size > 0); if(NULL == (prop->value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(prop->value, oprop->value, prop->size); + H5MM_memcpy(prop->value, oprop->value, prop->size); } /* end if */ /* Set return value */ @@ -1117,7 +1117,7 @@ H5P__create_prop(const char *name, size_t size, H5P_prop_within_t type, if(value != NULL) { if(NULL == (prop->value = H5MM_malloc (prop->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(prop->value, value, prop->size); + H5MM_memcpy(prop->value, value, prop->size); } /* end if */ else prop->value = NULL; @@ -2727,7 +2727,7 @@ H5P__poke_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") /* Overwrite value in property */ - HDmemcpy(prop->value, udata->value, prop->size); + H5MM_memcpy(prop->value, udata->value, prop->size); done: FUNC_LEAVE_NOAPI(ret_value) @@ -2779,7 +2779,7 @@ H5P__poke_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop if(NULL == (pcopy = H5P__dup_prop(prop, H5P_PROP_WITHIN_LIST))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") - HDmemcpy(pcopy->value, udata->value, pcopy->size); + H5MM_memcpy(pcopy->value, udata->value, pcopy->size); /* Insert the changed property into the property list */ if(H5P__add_prop(plist->props, pcopy) < 0) @@ -2888,7 +2888,7 @@ H5P__set_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, /* Make a copy of the current value, in case the callback fails */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value, udata->value, prop->size); + H5MM_memcpy(tmp_value, udata->value, prop->size); /* Call user's callback */ if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0) @@ -2909,7 +2909,7 @@ H5P__set_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, } /* end if */ /* Copy new [possibly unchanged] value into property value */ - HDmemcpy(prop->value, prp_value, prop->size); + H5MM_memcpy(prop->value, prp_value, prop->size); done: /* Free the temporary value buffer */ @@ -2968,7 +2968,7 @@ H5P__set_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, /* Make a copy of the current value, in case the callback fails */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value, udata->value, prop->size); + H5MM_memcpy(tmp_value, udata->value, prop->size); /* Call user's callback */ if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0) @@ -2985,7 +2985,7 @@ H5P__set_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, if(NULL == (pcopy = H5P__dup_prop(prop, H5P_PROP_WITHIN_LIST))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") - HDmemcpy(pcopy->value, prp_value, pcopy->size); + H5MM_memcpy(pcopy->value, prp_value, pcopy->size); /* Insert the changed property into the property list */ if(H5P__add_prop(plist->props, pcopy) < 0) @@ -4234,7 +4234,7 @@ H5P__peek_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") /* Make a (shallow) copy of the value */ - HDmemcpy(udata->value, prop->value, prop->size); + H5MM_memcpy(udata->value, prop->value, prop->size); done: FUNC_LEAVE_NOAPI(ret_value) @@ -4334,18 +4334,18 @@ H5P__get_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, /* Make a copy of the current value, in case the callback fails */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value, prop->value, prop->size); + H5MM_memcpy(tmp_value, prop->value, prop->size); /* Call user's callback */ if((*(prop->get))(plist->plist_id, name, prop->size, tmp_value) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") /* Copy new [possibly unchanged] value into return value */ - HDmemcpy(udata->value, tmp_value, prop->size); + H5MM_memcpy(udata->value, tmp_value, prop->size); } /* end if */ /* No 'get' callback, just copy value */ else - HDmemcpy(udata->value, prop->value, prop->size); + H5MM_memcpy(udata->value, prop->value, prop->size); done: /* Free the temporary value buffer */ @@ -4518,7 +4518,7 @@ H5P__del_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, /* Allocate space for a temporary copy of the property value */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value") - HDmemcpy(tmp_value, prop->value, prop->size); + H5MM_memcpy(tmp_value, prop->value, prop->size); /* Call user's callback */ if((*(prop->del))(plist->plist_id, name, prop->size, tmp_value) < 0) @@ -4967,7 +4967,7 @@ H5P_close(void *_plist) /* Allocate space for a temporary copy of the property value */ if(NULL==(tmp_value=H5MM_malloc(tmp->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") - HDmemcpy(tmp_value,tmp->value,tmp->size); + H5MM_memcpy(tmp_value,tmp->value,tmp->size); /* Call the 'close' callback */ (tmp->close)(tmp->name,tmp->size,tmp_value); diff --git a/src/H5Plapl.c b/src/H5Plapl.c index bedeed9..7a7cc23 100644 --- a/src/H5Plapl.c +++ b/src/H5Plapl.c @@ -715,7 +715,7 @@ H5P__lacc_elink_pref_enc(const void *value, void **_pp, size_t *size) /* encode the prefix */ if(NULL != elink_pref) { - HDmemcpy(*(char **)pp, elink_pref, len); + H5MM_memcpy(*(char **)pp, elink_pref, len); *pp += len; } /* end if */ } /* end if */ diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index c2bf6cb..a60c593 100644 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -1501,7 +1501,7 @@ H5P__ocrt_pipeline_enc(const void *value, void **_pp, size_t *size) *(*pp)++ = (uint8_t)TRUE; /* encode filter name */ - HDmemcpy(*pp, (uint8_t *)(pline->filter[u].name), H5Z_COMMON_NAME_LEN); + H5MM_memcpy(*pp, (uint8_t *)(pline->filter[u].name), H5Z_COMMON_NAME_LEN); *pp += H5Z_COMMON_NAME_LEN; } /* end if */ else diff --git a/src/H5Pocpypl.c b/src/H5Pocpypl.c index 666a945..2dc92f9 100644 --- a/src/H5Pocpypl.c +++ b/src/H5Pocpypl.c @@ -384,7 +384,7 @@ H5P__ocpy_merge_comm_dt_list_enc(const void *value, void **_pp, size_t *size) /* Encode merge committed dtype list */ if(*pp) { - HDmemcpy(*(char **)pp, dt_list->path, len); + H5MM_memcpy(*(char **)pp, dt_list->path, len); *pp += len; } /* end if */ diff --git a/src/H5S.c b/src/H5S.c index 3a917bc..47c436d 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -1359,7 +1359,7 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, * same as the dimension */ space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank); if(max != NULL) - HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank); + H5MM_memcpy(space->extent.max, max, sizeof(hsize_t) * rank); else for(u = 0; u < space->extent.rank; u++) space->extent.max[u] = dims[u]; diff --git a/src/H5SL.c b/src/H5SL.c index c0934ca..5f00fb8 100644 --- a/src/H5SL.c +++ b/src/H5SL.c @@ -240,7 +240,7 @@ /* Allocate space for new forward pointers */ \ if(NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \ HGOTO_ERROR(H5E_SLIST, H5E_CANTALLOC, ERR, "memory allocation failed") \ - HDmemcpy((void *)_tmp, (const void *)X->forward, (LVL + 1) * sizeof(H5SL_node_t *)); \ + H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL + 1) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc-1], (void *)X->forward); \ X->forward = _tmp; \ } /* end if */ \ @@ -262,7 +262,7 @@ /* Allocate space for new forward pointers */ \ if(NULL == (_tmp = (H5SL_node_t **)H5FL_FAC_MALLOC(H5SL_fac_g[X->log_nalloc]))) \ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed") \ - HDmemcpy((void *)_tmp, (const void *)X->forward, (LVL) * sizeof(H5SL_node_t *)); \ + H5MM_memcpy((void *)_tmp, (const void *)X->forward, (LVL) * sizeof(H5SL_node_t *)); \ X->forward = (H5SL_node_t **)H5FL_FAC_FREE(H5SL_fac_g[X->log_nalloc+1], (void *)X->forward); \ X->forward = _tmp; \ } /* end if */ \ diff --git a/src/H5SM.c b/src/H5SM.c index 0fa3489..3946f51 100644 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -2318,7 +2318,7 @@ H5SM__read_iter_op(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned sequence, HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") /* Copy the encoded message into the buffer to return */ - HDmemcpy(udata->encoding_buf, mesg->raw, udata->buf_size); + H5MM_memcpy(udata->encoding_buf, mesg->raw, udata->buf_size); /* Found the message we were looking for */ ret_value = H5_ITER_STOP; @@ -2356,7 +2356,7 @@ H5SM__read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata) HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "memory allocation failed") /* Copy the message from the heap */ - HDmemcpy(udata->encoding_buf, obj, obj_len); + H5MM_memcpy(udata->encoding_buf, obj, obj_len); udata->buf_size = obj_len; done: diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index f0c4963..0c4224b 100644 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -248,7 +248,7 @@ H5SM_bt2_convert_to_list_op(const void * record, void *op_data) /* Insert this message at the end of the list */ HDassert(list->messages[mesg_idx].location == H5SM_NO_LOC); HDassert(message->location != H5SM_NO_LOC); - HDmemcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t)); + H5MM_memcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_bt2_convert_to_list_op() */ diff --git a/src/H5SMcache.c b/src/H5SMcache.c index f0b469a..49ce2b4 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -388,7 +388,7 @@ H5SM__cache_table_serialize(const H5F_t *f, void *_image, size_t len, HDassert(H5F_SOHM_VERS(f) == HDF5_SHAREDHEADER_VERSION); /* Encode magic number */ - HDmemcpy(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* Encode each index header */ @@ -710,7 +710,7 @@ H5SM__cache_list_serialize(const H5F_t *f, void *_image, size_t len, HDassert(list->header->list_size == len); /* Encode magic number */ - HDmemcpy(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC); + H5MM_memcpy(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC); image += H5_SIZEOF_MAGIC; /* serialize messages from the messages array */ diff --git a/src/H5SMmessage.c b/src/H5SMmessage.c index ad84b24..3e50fe5 100644 --- a/src/H5SMmessage.c +++ b/src/H5SMmessage.c @@ -302,7 +302,7 @@ H5SM__message_encode(uint8_t *raw, const void *_nrecord, void *_ctx) if(message->location == H5SM_IN_HEAP) { UINT32ENCODE(raw, message->u.heap_loc.ref_count); - HDmemcpy(raw, message->u.heap_loc.fheap_id.id, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(raw, message->u.heap_loc.fheap_id.id, (size_t)H5O_FHEAP_ID_LEN); } /* end if */ else { HDassert(message->location == H5SM_IN_OH); @@ -343,7 +343,7 @@ H5SM__message_decode(const uint8_t *raw, void *_nrecord, void *_ctx) if(message->location == H5SM_IN_HEAP) { UINT32DECODE(raw, message->u.heap_loc.ref_count); - HDmemcpy(message->u.heap_loc.fheap_id.id, raw, (size_t)H5O_FHEAP_ID_LEN); + H5MM_memcpy(message->u.heap_loc.fheap_id.id, raw, (size_t)H5O_FHEAP_ID_LEN); } /* end if */ else { HDassert(message->location == H5SM_IN_OH); diff --git a/src/H5Shyper.c b/src/H5Shyper.c index c9fab38..96f3894 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -554,10 +554,10 @@ H5S__hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords) HDassert(v < 0); } /* end if */ else - HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank); + H5MM_memcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank); } /* end if */ else - HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank); + H5MM_memcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5S__hyper_iter_coords() */ @@ -3819,18 +3819,18 @@ H5S__hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[], /* Copy previous starting points */ for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &start[u], sizeof(hsize_t)); + H5MM_memcpy(*buf, &start[u], sizeof(hsize_t)); /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->low, sizeof(hsize_t)); + H5MM_memcpy(*buf, &curr->low, sizeof(hsize_t)); (*buf)++; /* Copy previous ending points */ for(u = 0; u < rank; u++, (*buf)++) - HDmemcpy(*buf, &end[u], sizeof(hsize_t)); + H5MM_memcpy(*buf, &end[u], sizeof(hsize_t)); /* Copy starting point for this span */ - HDmemcpy(*buf, &curr->high, sizeof(hsize_t)); + H5MM_memcpy(*buf, &curr->high, sizeof(hsize_t)); (*buf)++; /* Decrement the number of blocks processed */ @@ -3943,11 +3943,11 @@ H5S__get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblo /* Check if we should copy this block information */ if(startblock == 0) { /* Copy the starting location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); + H5MM_memcpy(buf, offset, sizeof(hsize_t) * ndims); buf += ndims; /* Compute the ending location */ - HDmemcpy(buf, offset, sizeof(hsize_t) * ndims); + H5MM_memcpy(buf, offset, sizeof(hsize_t) * ndims); for(u = 0; u < ndims; u++) buf[u] += (diminfo[u].block - 1); buf += ndims; @@ -6029,7 +6029,7 @@ H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection") /* Copy the selection offset over */ - HDmemcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); + H5MM_memcpy(space->select.offset, old_offset, sizeof(hssize_t) * space->extent.rank); done: FUNC_LEAVE_NOAPI(ret_value) @@ -7255,7 +7255,7 @@ H5S__hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_sla if(!H5S__hyper_rebuild_helper(span->down->head, span_slab_info, rank - 1)) HGOTO_DONE(FALSE) - HDmemcpy(canon_down_span_slab_info, span_slab_info, sizeof(H5S_hyper_dim_t) * rank); + H5MM_memcpy(canon_down_span_slab_info, span_slab_info, sizeof(H5S_hyper_dim_t) * rank); } /* end if */ /* Assign the initial starting point & block size */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 6411b94..e62b48d 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -203,7 +203,7 @@ H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords) HDassert(coords); /* Copy the offset of the current point */ - HDmemcpy(coords, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); + H5MM_memcpy(coords, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5S__point_iter_coords() */ @@ -233,8 +233,8 @@ H5S__point_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end) HDassert(end); /* Copy the current point as a block */ - HDmemcpy(start, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); - HDmemcpy(end, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); + H5MM_memcpy(start, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); + H5MM_memcpy(end, iter->u.pnt.curr->pnt, sizeof(hsize_t) * iter->rank); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5S__point_iter_block() */ @@ -581,7 +581,7 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information") /* Copy over the coordinates */ - HDmemcpy(new_node->pnt, coord + (u * space->extent.rank), (space->extent.rank * sizeof(hsize_t))); + H5MM_memcpy(new_node->pnt, coord + (u * space->extent.rank), (space->extent.rank * sizeof(hsize_t))); /* Link into list */ if(top == NULL) @@ -799,7 +799,7 @@ H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selec } /* end if */ /* Copy over the point's coordinates */ - HDmemcpy(new_node->pnt, curr->pnt, (src->extent.rank * sizeof(hsize_t))); + H5MM_memcpy(new_node->pnt, curr->pnt, (src->extent.rank * sizeof(hsize_t))); /* Keep the order the same when copying */ if(NULL == new_tail) @@ -1165,7 +1165,7 @@ H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, /* Iterate through the node, copying each point's information */ while(node != NULL && numpoints > 0) { - HDmemcpy(buf, node->pnt, sizeof(hsize_t) * rank); + H5MM_memcpy(buf, node->pnt, sizeof(hsize_t) * rank); buf += rank; numpoints--; node = node->next; @@ -1649,7 +1649,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of /* Calculate offset of selection in projected buffer */ HDmemset(block, 0, sizeof(block)); - HDmemcpy(block, base_space->select.sel_info.pnt_lst->head->pnt, sizeof(hsize_t) * rank_diff); + H5MM_memcpy(block, base_space->select.sel_info.pnt_lst->head->pnt, sizeof(hsize_t) * rank_diff); *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block); /* Iterate through base space's point nodes, copying the point information */ @@ -1666,7 +1666,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of } /* end if */ /* Copy over the point's coordinates */ - HDmemcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t))); + H5MM_memcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t))); /* Keep the order the same when copying */ if(NULL == prev_node) @@ -1704,7 +1704,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of /* Copy over the point's coordinates */ HDmemset(new_node->pnt, 0, sizeof(hsize_t) * rank_diff); - HDmemcpy(&new_node->pnt[rank_diff], base_node->pnt, (new_space->extent.rank * sizeof(hsize_t))); + H5MM_memcpy(&new_node->pnt[rank_diff], base_node->pnt, (new_space->extent.rank * sizeof(hsize_t))); /* Keep the order the same when copying */ if(NULL == prev_node) diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 24586de..ef38746 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -114,7 +114,7 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset) HDassert(offset); /* Copy the offset over */ - HDmemcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank); + H5MM_memcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank); /* Indicate that the offset was changed */ space->select.offset_changed = TRUE; @@ -1538,7 +1538,7 @@ H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space, if(ndims > 0) { /* Copy the size of the space */ HDassert(space->extent.size); - HDmemcpy(space_size, space->extent.size, ndims * sizeof(hsize_t)); + H5MM_memcpy(space_size, space->extent.size, ndims * sizeof(hsize_t)); } /* end if */ space_size[ndims] = elmt_size; @@ -2192,16 +2192,16 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, rank_diff = new_space_rank - base_space_rank; H5VM_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff); H5VM_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff); - HDmemcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank); - HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank); + H5MM_memcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank); + H5MM_memcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank); } /* end if */ else { /* new_space_rank < base_space_rank */ /* we must copy the fastest changing dimension of the * base space into the dimensions of the new space. */ rank_diff = base_space_rank - new_space_rank; - HDmemcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank); - HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank); + H5MM_memcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank); + H5MM_memcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank); } /* end else */ /* now have the new space rank and dimensions set up -- @@ -2232,10 +2232,10 @@ H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) { if(new_space_rank > base_space_rank) { HDmemset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff); - HDmemcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank); + H5MM_memcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank); } /* end if */ else - HDmemcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank); + H5MM_memcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank); /* Propagate the offset changed flag into the new dataspace. */ new_space->select.offset_changed = TRUE; diff --git a/src/H5T.c b/src/H5T.c index ad36492..1c4acb9 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -3338,7 +3338,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method) if (NULL == new_dt->shared->u.compnd.memb) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, + H5MM_memcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); } /* end if */ @@ -3404,7 +3404,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method) (uint8_t *)H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size); if(NULL == new_dt->shared->u.enumer.value) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, + H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, new_dt->shared->u.enumer.nmembs * new_dt->shared->size); for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) { s = old_dt->shared->u.enumer.name[i]; diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 712b264..c6b85a5 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -1211,7 +1211,7 @@ H5T_save_refresh_state(hid_t tid, H5O_shared_t *cached_H5O_shared) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, FAIL, "can't increment object count") /* Cache the H5O_shared_t data */ - HDmemcpy(cached_H5O_shared, &(vol_dt->sh_loc), sizeof(H5O_shared_t)); + H5MM_memcpy(cached_H5O_shared, &(vol_dt->sh_loc), sizeof(H5O_shared_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1245,7 +1245,7 @@ H5T_restore_refresh_state(hid_t tid, H5O_shared_t *cached_H5O_shared) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "tid is not not a named datatype ID") /* Restore the H5O_shared_t data */ - HDmemcpy(&(vol_dt->sh_loc), cached_H5O_shared, sizeof(H5O_shared_t)); + H5MM_memcpy(&(vol_dt->sh_loc), cached_H5O_shared, sizeof(H5O_shared_t)); /* Decrement the ref. count for this object in the top file */ if(H5FO_top_decr(vol_dt->sh_loc.file, vol_dt->sh_loc.u.loc.oh_addr) < 0) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 9a1105b..7d47483 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -828,7 +828,7 @@ done: \ /* Macro defining action on source data which needs to be aligned (before main action) */ #define H5T_CONV_LOOP_PRE_SALIGN(ST) { \ - HDmemcpy(&src_aligned, src, sizeof(ST)); \ + H5MM_memcpy(&src_aligned, src, sizeof(ST)); \ } /* Macro defining action on source data which doesn't need to be aligned (before main action) */ @@ -854,7 +854,7 @@ done: \ /* Macro defining action on destination data which needs to be aligned (after main action) */ #define H5T_CONV_LOOP_POST_DALIGN(DT) { \ - HDmemcpy(dst, &dst_aligned, sizeof(DT)); \ + H5MM_memcpy(dst, &dst_aligned, sizeof(DT)); \ } /* Macro defining action on destination data which doesn't need to be aligned (after main action) */ @@ -1797,7 +1797,7 @@ H5T__conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * should copy the value to the true destination buffer. */ if(d == dbuf) - HDmemcpy(dp, d, dst->shared->size); + H5MM_memcpy(dp, d, dst->shared->size); if(buf_stride) { sp += direction * (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ dp += direction * (ssize_t)buf_stride; /* Note that cast is checked with H5_CHECK_OVERFLOW, above */ @@ -2852,7 +2852,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, else if(except_ret == H5T_CONV_ABORT) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") } else - HDmemcpy(d, + H5MM_memcpy(d, dst->shared->u.enumer.value + (unsigned)priv->src2dst[n] * dst->shared->size, dst->shared->size); } /* end if */ @@ -2888,7 +2888,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end if */ else { HDassert(priv->src2dst[md] >= 0); - HDmemcpy(d, + H5MM_memcpy(d, dst->shared->u.enumer.value + (unsigned)priv->src2dst[md] * dst->shared->size, dst->shared->size); } /* end else */ @@ -3846,7 +3846,7 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * should copy the value to the true destination buffer. */ if(d==dbuf) - HDmemcpy(dp, d, dst->shared->size); + H5MM_memcpy(dp, d, dst->shared->size); /* Advance source & destination pointers by delta amounts */ sp += src_delta; @@ -4432,7 +4432,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, */ next: if(d == dbuf) - HDmemcpy(dp, d, dst_p->shared->size); + H5MM_memcpy(dp, d, dst_p->shared->size); /* Advance source & destination pointers by delta amounts */ sp += src_delta; @@ -4604,7 +4604,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, --nchars; nchars = MIN(dst->shared->size, nchars); if(d != s) - HDmemcpy(d, s, nchars); + H5MM_memcpy(d, s, nchars); break; case H5T_STR_RESERVED_3: @@ -4666,7 +4666,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * should copy the value to the true destination buffer. */ if(d == dbuf) - HDmemcpy(dp, d, dst->shared->size); + H5MM_memcpy(dp, d, dst->shared->size); /* Advance source & destination pointers by delta amounts */ sp += src_delta; @@ -8825,7 +8825,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * should copy the value to the true destination buffer. */ if (d==dbuf) - HDmemcpy (dp, d, dst_p->shared->size); + H5MM_memcpy (dp, d, dst_p->shared->size); if (buf_stride) { sp += direction * (ssize_t) buf_stride; dp += direction * (ssize_t) buf_stride; @@ -9235,7 +9235,7 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * should copy the value to the true destination buffer. */ if (d==dbuf) - HDmemcpy (dp, d, dst_p->shared->size); + H5MM_memcpy (dp, d, dst_p->shared->size); if (buf_stride) { sp += direction * (ssize_t) buf_stride; dp += direction * (ssize_t) buf_stride; diff --git a/src/H5Tenum.c b/src/H5Tenum.c index 0ed1775..ff88fab 100644 --- a/src/H5Tenum.c +++ b/src/H5Tenum.c @@ -223,7 +223,7 @@ H5T__enum_insert(const H5T_t *dt, const char *name, const void *value) dt->shared->u.enumer.sorted = H5T_SORT_NONE; i = dt->shared->u.enumer.nmembs++; dt->shared->u.enumer.name[i] = H5MM_xstrdup(name); - HDmemcpy(dt->shared->u.enumer.value+i*dt->shared->size, value, dt->shared->size); + H5MM_memcpy(dt->shared->u.enumer.value+i*dt->shared->size, value, dt->shared->size); done: FUNC_LEAVE_NOAPI(ret_value) @@ -298,7 +298,7 @@ H5T__get_member_value(const H5T_t *dt, unsigned membno, void *value/*out*/) HDassert(dt); HDassert(value); - HDmemcpy(value, dt->shared->u.enumer.value + membno*dt->shared->size, dt->shared->size); + H5MM_memcpy(value, dt->shared->u.enumer.value + membno*dt->shared->size, dt->shared->size); FUNC_LEAVE_NOAPI(SUCCEED) } @@ -569,7 +569,7 @@ H5T_enum_valueof(const H5T_t *dt, const char *name, void *value/*out*/) if (cmp!=0) HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "string doesn't exist in the enumeration type") - HDmemcpy(value, copied_dt->shared->u.enumer.value+md*copied_dt->shared->size, copied_dt->shared->size); + H5MM_memcpy(value, copied_dt->shared->u.enumer.value+md*copied_dt->shared->size, copied_dt->shared->size); done: if(copied_dt) diff --git a/src/H5Tfields.c b/src/H5Tfields.c index be62d85..8202c2c 100644 --- a/src/H5Tfields.c +++ b/src/H5Tfields.c @@ -351,10 +351,10 @@ H5T__sort_value(const H5T_t *dt, int *map) dt->shared->u.enumer.name[j + 1] = tmp; /* Swap values */ - HDmemcpy(tbuf, dt->shared->u.enumer.value + (j * size), size); - HDmemcpy(dt->shared->u.enumer.value + (j * size), + H5MM_memcpy(tbuf, dt->shared->u.enumer.value + (j * size), size); + H5MM_memcpy(dt->shared->u.enumer.value + (j * size), dt->shared->u.enumer.value + ((j + 1) * size), size); - HDmemcpy(dt->shared->u.enumer.value + ((j + 1) * size), tbuf, size); + H5MM_memcpy(dt->shared->u.enumer.value + ((j + 1) * size), tbuf, size); /* Swap map */ if(map) { @@ -457,10 +457,10 @@ H5T__sort_name(const H5T_t *dt, int *map) dt->shared->u.enumer.name[j+1] = tmp; /* Swap values */ - HDmemcpy(tbuf, dt->shared->u.enumer.value+j*size, size); - HDmemcpy(dt->shared->u.enumer.value+j*size, + H5MM_memcpy(tbuf, dt->shared->u.enumer.value+j*size, size); + H5MM_memcpy(dt->shared->u.enumer.value+j*size, dt->shared->u.enumer.value+(j+1)*size, size); - HDmemcpy(dt->shared->u.enumer.value+(j+1)*size, tbuf, size); + H5MM_memcpy(dt->shared->u.enumer.value+(j+1)*size, tbuf, size); /* Swap map */ if (map) { diff --git a/src/H5Tnative.c b/src/H5Tnative.c index c9ad01a..3554f75 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -369,7 +369,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name") if(H5T__get_member_value(dtype, u, tmp_memb_value) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value") - HDmemcpy(memb_value, tmp_memb_value, H5T_get_size(super_type)); + H5MM_memcpy(memb_value, tmp_memb_value, H5T_get_size(super_type)); if(H5T_convert(tpath, super_type_id, nat_super_type_id, (size_t)1, (size_t)0, (size_t)0, memb_value, NULL) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value") diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 841637d..bafb47f 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -302,7 +302,7 @@ H5T_vlen_seq_mem_getlen(const void *_vl) FUNC_LEAVE_NOAPI((ssize_t)vl->len) #else HDassert(_vl); - HDmemcpy(&vl, _vl, sizeof(hvl_t)); + H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); FUNC_LEAVE_NOAPI((ssize_t)vl.len) #endif @@ -339,7 +339,7 @@ H5T_vlen_seq_mem_getptr(void *_vl) FUNC_LEAVE_NOAPI(vl->p) #else HDassert(_vl); - HDmemcpy(&vl, _vl, sizeof(hvl_t)); + H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); FUNC_LEAVE_NOAPI(vl.p) #endif @@ -376,7 +376,7 @@ H5T_vlen_seq_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) FUNC_LEAVE_NOAPI((vl->len==0 || vl->p==NULL) ? TRUE : FALSE) #else HDassert(_vl); - HDmemcpy(&vl, _vl, sizeof(hvl_t)); + H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); FUNC_LEAVE_NOAPI((vl.len==0 || vl.p==NULL) ? TRUE : FALSE) #endif @@ -411,13 +411,13 @@ H5T_vlen_seq_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) #ifdef H5_NO_ALIGNMENT_RESTRICTIONS HDassert(vl && vl->p); - HDmemcpy(buf,vl->p,len); + H5MM_memcpy(buf,vl->p,len); #else HDassert(_vl); - HDmemcpy(&vl, _vl, sizeof(hvl_t)); + H5MM_memcpy(&vl, _vl, sizeof(hvl_t)); HDassert(vl.p); - HDmemcpy(buf,vl.p,len); + H5MM_memcpy(buf,vl.p,len); #endif FUNC_LEAVE_NOAPI(SUCCEED) @@ -463,7 +463,7 @@ H5T_vlen_seq_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_ } /* end else */ /* Copy the data into the newly allocated buffer */ - HDmemcpy(vl.p,buf,len); + H5MM_memcpy(vl.p,buf,len); } /* end if */ else @@ -473,7 +473,7 @@ H5T_vlen_seq_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_ vl.len=seq_len; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(_vl,&vl,sizeof(hvl_t)); + H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); done: FUNC_LEAVE_NOAPI(ret_value) @@ -507,7 +507,7 @@ H5T_vlen_seq_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED vl.p=NULL; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(_vl,&vl,sizeof(hvl_t)); + H5MM_memcpy(_vl,&vl,sizeof(hvl_t)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5T_vlen_seq_mem_setnull() */ @@ -541,7 +541,7 @@ H5T_vlen_str_mem_getlen(const void *_vl) HDassert(s); #else HDassert(_vl); - HDmemcpy(&s, _vl, sizeof(char *)); + H5MM_memcpy(&s, _vl, sizeof(char *)); #endif FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(s)) @@ -576,7 +576,7 @@ H5T_vlen_str_mem_getptr(void *_vl) HDassert(s); #else HDassert(_vl); - HDmemcpy(&s, _vl, sizeof(char *)); + H5MM_memcpy(&s, _vl, sizeof(char *)); #endif FUNC_LEAVE_NOAPI(s) @@ -607,7 +607,7 @@ H5T_vlen_str_mem_isnull(const H5F_t H5_ATTR_UNUSED *f, void *_vl) FUNC_ENTER_NOAPI_NOINIT_NOERR #ifndef H5_NO_ALIGNMENT_RESTRICTIONS - HDmemcpy(&s, _vl, sizeof(char *)); + H5MM_memcpy(&s, _vl, sizeof(char *)); #endif FUNC_LEAVE_NOAPI(s==NULL ? TRUE : FALSE) @@ -644,10 +644,10 @@ H5T_vlen_str_mem_read(H5F_t H5_ATTR_UNUSED *f, void *_vl, void *buf, size_t len) HDassert(s); #else HDassert(_vl); - HDmemcpy(&s, _vl, sizeof(char *)); + H5MM_memcpy(&s, _vl, sizeof(char *)); #endif - HDmemcpy(buf,s,len); + H5MM_memcpy(buf,s,len); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -690,11 +690,11 @@ H5T_vlen_str_mem_write(H5F_t H5_ATTR_UNUSED *f, const H5T_vlen_alloc_info_t *vl_ } /* end else */ len=(seq_len*base_size); - HDmemcpy(t,buf,len); + H5MM_memcpy(t,buf,len); t[len]='\0'; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(_vl,&t,sizeof(char *)); + H5MM_memcpy(_vl,&t,sizeof(char *)); done: FUNC_LEAVE_NOAPI(ret_value) /*lint !e429 The pointer in 't' has been copied */ @@ -721,7 +721,7 @@ H5T_vlen_str_mem_setnull(H5F_t H5_ATTR_UNUSED *f, void *_vl, void H5_ATTR_UNUSED FUNC_ENTER_NOAPI_NOINIT_NOERR /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(_vl,&t,sizeof(char *)); + H5MM_memcpy(_vl,&t,sizeof(char *)); FUNC_LEAVE_NOAPI(SUCCEED) /*lint !e429 The pointer in 't' has been copied */ } /* end H5T_vlen_str_mem_setnull() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 5a5d9ee..2d5b7d8 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -355,7 +355,7 @@ H5VL_copy_connector_info(const H5VL_class_t *connector, void **dst_info, else if(connector->info_cls.size > 0) { if(NULL == (new_connector_info = H5MM_malloc(connector->info_cls.size))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "connector info allocation failed") - HDmemcpy(new_connector_info, src_info, connector->info_cls.size); + H5MM_memcpy(new_connector_info, src_info, connector->info_cls.size); } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "no way to copy connector info") diff --git a/src/H5VLint.c b/src/H5VLint.c index 7aeea02..9d9dc94 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -681,7 +681,7 @@ H5VL_register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) /* Copy the class structure so the caller can reuse or free it */ if (NULL == (saved = H5FL_CALLOC(H5VL_class_t))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "memory allocation failed for VOL connector class struct") - HDmemcpy(saved, cls, sizeof(H5VL_class_t)); + H5MM_memcpy(saved, cls, sizeof(H5VL_class_t)); if(NULL == (saved->name = H5MM_strdup(cls->name))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "memory allocation failed for VOL connector name") diff --git a/src/H5VM.c b/src/H5VM.c index 452d378..3e57ce8 100644 --- a/src/H5VM.c +++ b/src/H5VM.c @@ -732,7 +732,7 @@ H5VM_stride_copy(unsigned n, hsize_t elmt_size, const hsize_t *size, /* Copy an element */ H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ + H5MM_memcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ /* Decrement indices and advance pointers */ for (j=(int)(n-1), carry=TRUE; j>=0 && carry; --j) { @@ -749,7 +749,7 @@ H5VM_stride_copy(unsigned n, hsize_t elmt_size, const hsize_t *size, } } else { H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ + H5MM_memcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ } FUNC_LEAVE_NOAPI(SUCCEED) @@ -801,7 +801,7 @@ H5VM_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *size, /* Copy an element */ H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ + H5MM_memcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ /* Decrement indices and advance pointers */ for (j=(int)(n-1), carry=TRUE; j>=0 && carry; --j) { @@ -818,7 +818,7 @@ H5VM_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *size, } } else { H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ + H5MM_memcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ } FUNC_LEAVE_NOAPI(SUCCEED) @@ -877,7 +877,7 @@ H5VM_stride_copy2(hsize_t nelmts, hsize_t elmt_size, /* Copy an element */ H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ + H5MM_memcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ /* Decrement indices and advance pointers */ for (j=(int)(dst_n-1), carry=TRUE; j>=0 && carry; --j) { @@ -936,7 +936,7 @@ H5VM_array_fill(void *_dst, const void *src, size_t size, size_t count) HDassert(size < SIZET_MAX && size > 0); HDassert(count < SIZET_MAX && count > 0); - HDmemcpy(dst, src, size); /* copy first item */ + H5MM_memcpy(dst, src, size); /* copy first item */ /* Initialize counters, etc. while compensating for first element copied */ copy_size = size; @@ -947,7 +947,7 @@ H5VM_array_fill(void *_dst, const void *src, size_t size, size_t count) /* copy until we've copied at least half of the items */ while (items_left >= copy_items) { - HDmemcpy(dst, _dst, copy_size); /* copy the current chunk */ + H5MM_memcpy(dst, _dst, copy_size); /* copy the current chunk */ dst += copy_size; /* move the offset for the next chunk */ items_left -= copy_items; /* decrement the number of items left */ @@ -955,7 +955,7 @@ H5VM_array_fill(void *_dst, const void *src, size_t size, size_t count) copy_items *= 2; /* increase the count of items we are copying */ } /* end while */ if (items_left > 0) /* if there are any items left to copy */ - HDmemcpy(dst, _dst, items_left * size); + H5MM_memcpy(dst, _dst, items_left * size); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5VM_array_fill() */ @@ -1623,7 +1623,7 @@ src_smaller: acc_len = 0; do { /* Copy data */ - HDmemcpy(dst, src, tmp_src_len); + H5MM_memcpy(dst, src, tmp_src_len); /* Accumulate number of bytes copied */ acc_len += tmp_src_len; @@ -1666,7 +1666,7 @@ dst_smaller: acc_len = 0; do { /* Copy data */ - HDmemcpy(dst, src, tmp_dst_len); + H5MM_memcpy(dst, src, tmp_dst_len); /* Accumulate number of bytes copied */ acc_len += tmp_dst_len; @@ -1709,7 +1709,7 @@ equal: acc_len = 0; do { /* Copy data */ - HDmemcpy(dst, src, tmp_dst_len); + H5MM_memcpy(dst, src, tmp_dst_len); /* Accumulate number of bytes copied */ acc_len += tmp_dst_len; diff --git a/src/H5VMprivate.h b/src/H5VMprivate.h index decac7e..28248c0 100644 --- a/src/H5VMprivate.h +++ b/src/H5VMprivate.h @@ -41,7 +41,7 @@ typedef herr_t (*H5VM_opvv_func_t)(hsize_t dst_off, hsize_t src_off, /* Other functions */ #define H5VM_vector_cpy(N,DST,SRC) { \ HDassert(sizeof(*(DST))==sizeof(*(SRC))); \ - if (SRC) HDmemcpy (DST, SRC, (N)*sizeof(*(DST))); \ + if (SRC) H5MM_memcpy (DST, SRC, (N)*sizeof(*(DST))); \ else HDmemset (DST, 0, (N)*sizeof(*(DST))); \ } diff --git a/src/H5Z.c b/src/H5Z.c index 0e2a7ba..b703958 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -322,7 +322,7 @@ H5Z_register (const H5Z_class2_t *cls) /* Initialize */ i = H5Z_table_used_g++; - HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t)); + H5MM_memcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t)); #ifdef H5Z_DEBUG HDmemset(H5Z_stat_table_g+i, 0, sizeof(H5Z_stats_t)); #endif /* H5Z_DEBUG */ @@ -330,7 +330,7 @@ H5Z_register (const H5Z_class2_t *cls) /* Filter already registered */ else { /* Replace old contents */ - HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t)); + H5MM_memcpy(H5Z_table_g+i, cls, sizeof(H5Z_class2_t)); } /* end else */ done: diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c index 4cd77ef..4d75d14 100644 --- a/src/H5Zfletcher32.c +++ b/src/H5Zfletcher32.c @@ -108,7 +108,7 @@ H5Z_filter_fletcher32 (unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts, const un * system. We'll check both the correct checksum and the wrong * checksum to be consistent with Release 1.6.2 and before. */ - HDmemcpy(c, &fletcher, (size_t)4); + H5MM_memcpy(c, &fletcher, (size_t)4); tmp = c[1]; c[1] = c[0]; @@ -118,7 +118,7 @@ H5Z_filter_fletcher32 (unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts, const un c[3] = c[2]; c[2] = tmp; - HDmemcpy(&reversed_fletcher, c, (size_t)4); + H5MM_memcpy(&reversed_fletcher, c, (size_t)4); /* Verify computed checksum matches stored checksum */ if(stored_fletcher != fletcher && stored_fletcher != reversed_fletcher) @@ -140,7 +140,7 @@ H5Z_filter_fletcher32 (unsigned flags, size_t H5_ATTR_UNUSED cd_nelmts, const un dst = (unsigned char *) outbuf; /* Copy raw data */ - HDmemcpy((void*)dst, (void*)(*buf), nbytes); + H5MM_memcpy((void*)dst, (void*)(*buf), nbytes); /* Append checksum to raw data for storage */ dst += nbytes; diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 0026749..d3e8fc0 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -141,7 +141,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* end if */ \ \ /* Copy the value */ \ - HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + H5MM_memcpy(&_cd_value, _fv_p, _copy_size); \ (cd_values)[_i] = (unsigned)_cd_value; \ \ /* Next field */ \ @@ -158,7 +158,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ _fv_p = ((char *)&(fill_val)) + sizeof(type) - MIN(4, _size_rem); \ while(_size_rem >= 4) { \ /* Copy the value */ \ - HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + H5MM_memcpy(&_cd_value, _fv_p, _copy_size); \ (cd_values)[_i] = (unsigned)_cd_value; \ \ /* Next field */ \ @@ -176,7 +176,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ * _cd_value as it will not be fully overwritten and copy to the end \ * of _cd value as it is BE. */ \ _cd_value = (uint32_t)0; \ - HDmemcpy((char *)&_cd_value + 4 - _size_rem, _fv_p, _size_rem); \ + H5MM_memcpy((char *)&_cd_value + 4 - _size_rem, _fv_p, _size_rem); \ (cd_values)[_i] = (unsigned)_cd_value; \ } /* end if */ \ } /* end else */ \ @@ -269,7 +269,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ \ /* Copy the value */ \ _cd_value = (uint32_t)(cd_values)[_i]; \ - HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + H5MM_memcpy(_fv_p, &_cd_value, _copy_size); \ \ /* Next field */ \ _i++; \ @@ -286,7 +286,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ while(_size_rem >= 4) { \ /* Copy the value */ \ _cd_value = (uint32_t)(cd_values)[_i]; \ - HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + H5MM_memcpy(_fv_p, &_cd_value, _copy_size); \ \ /* Next field */ \ _i++; \ @@ -303,7 +303,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ * _cd_value as it will not be fully overwritten and copy to the end \ * of _cd value as it is BE. */ \ _cd_value = (uint32_t)(cd_values)[_i]; \ - HDmemcpy(_fv_p, (char *)&_cd_value + 4 - _size_rem, _size_rem); \ + H5MM_memcpy(_fv_p, (char *)&_cd_value + 4 - _size_rem, _size_rem); \ } /* end if */ \ } /* end else */ \ } @@ -529,10 +529,10 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ * account for offset in BE if sizes differ \ */ \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(minval, &min, sizeof(type)); \ + H5MM_memcpy(minval, &min, sizeof(type)); \ else { \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - HDmemcpy(((char *)minval) + (sizeof(long long) - sizeof(type)), \ + H5MM_memcpy(((char *)minval) + (sizeof(long long) - sizeof(type)), \ &min, sizeof(type)); \ } /* end else */ \ else \ @@ -604,10 +604,10 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ * account for offset in BE if sizes differ \ */ \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(&min, &minval, sizeof(type)); \ + H5MM_memcpy(&min, &minval, sizeof(type)); \ else { \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - HDmemcpy(&min, ((char *)&minval) + (sizeof(long long) \ + H5MM_memcpy(&min, ((char *)&minval) + (sizeof(long long) \ - sizeof(type)), sizeof(type)); \ } /* end else */ \ else \ @@ -1173,7 +1173,7 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* special case: minbits equal to full precision */ if(minbits == p.size * 8) { - HDmemcpy(outbuf, (unsigned char*)(*buf)+buf_offset, size_out); + H5MM_memcpy(outbuf, (unsigned char*)(*buf)+buf_offset, size_out); /* free the original buffer */ H5MM_xfree(*buf); @@ -1273,7 +1273,7 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* special case: minbits equal to full precision */ if(minbits == p.size * 8) { - HDmemcpy(outbuf + buf_offset, *buf, nbytes); + H5MM_memcpy(outbuf + buf_offset, *buf, nbytes); /* free the original buffer */ H5MM_xfree(*buf); diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c index 1fef1c1..e70ef33 100644 --- a/src/H5Zshuffle.c +++ b/src/H5Zshuffle.c @@ -210,7 +210,7 @@ H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[], if(leftover>0) { /* Adjust back to end of shuffled bytes */ _dest -= (bytesoftype - 1); /*lint !e794 _dest is initialized */ - HDmemcpy((void*)_dest, (void*)_src, leftover); + H5MM_memcpy((void*)_dest, (void*)_src, leftover); } } /* end if */ else { @@ -268,7 +268,7 @@ H5Z_filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[], if(leftover>0) { /* Adjust back to end of shuffled bytes */ _src -= (bytesoftype - 1); /*lint !e794 _src is initialized */ - HDmemcpy((void*)_dest, (void*)_src, leftover); + H5MM_memcpy((void*)_dest, (void*)_src, leftover); } } /* end else */ diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index f8fc325..6d07513 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -1078,7 +1078,7 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size if(NULL == (data_xform_prop->dat_val_pointers->ptr_dat_val[i] = (void*)H5MM_malloc(array_size * H5T_get_size((H5T_t *)H5I_object(array_type))))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "Ran out of memory trying to allocate space for data in data transform") - HDmemcpy(data_xform_prop->dat_val_pointers->ptr_dat_val[i], array, array_size * H5T_get_size((H5T_t *)H5I_object(array_type))); + H5MM_memcpy(data_xform_prop->dat_val_pointers->ptr_dat_val[i], array, array_size * H5T_get_size((H5T_t *)H5I_object(array_type))); } /* end for */ } /* end else */ @@ -1086,7 +1086,7 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") if(data_xform_prop->dat_val_pointers->num_ptrs > 1) - HDmemcpy(array, res.value.dat_val, array_size * H5T_get_size((H5T_t *)H5I_object(array_type))); + H5MM_memcpy(array, res.value.dat_val, array_size * H5T_get_size((H5T_t *)H5I_object(array_type))); /* Free the temporary arrays we used */ if(data_xform_prop->dat_val_pointers->num_ptrs > 1) -- cgit v0.12 From 5c80d3d91284bdcd048d9325b1a601d0ddfca8bd Mon Sep 17 00:00:00 2001 From: Dana Robinson Date: Sat, 16 Mar 2019 16:02:06 -0700 Subject: - Added H5MMprivate.h #includes where needed - Added casts to quiet H5MM_memcpy warnings - Removed char * casts from HDmemcpy --- src/H5Abtree2.c | 1 + src/H5B.c | 1 + src/H5B2int.c | 1 + src/H5Bcache.c | 1 + src/H5Dbtree.c | 1 + src/H5Dbtree2.c | 1 + src/H5Dcontig.c | 1 + src/H5Dearray.c | 1 + src/H5Dfill.c | 1 + src/H5Dscatgath.c | 1 + src/H5EA.c | 1 + src/H5EAcache.c | 1 + src/H5EAhdr.c | 1 + src/H5EAstat.c | 1 + src/H5FA.c | 1 + src/H5FAcache.c | 1 + src/H5FAhdr.c | 1 + src/H5FAstat.c | 1 + src/H5FS.c | 1 + src/H5FScache.c | 1 + src/H5Faccum.c | 1 + src/H5Fprivate.h | 1 + src/H5Gbtree2.c | 1 + src/H5Gcache.c | 1 + src/H5Gent.c | 1 + src/H5HF.c | 2 ++ src/H5HFhdr.c | 1 + src/H5HFtest.c | 2 ++ src/H5HFtiny.c | 1 + src/H5HLcache.c | 1 + src/H5MM.c | 6 ++++-- src/H5Oalloc.c | 1 + src/H5Ocache.c | 1 + src/H5Oint.c | 2 -- src/H5Oshared.c | 1 + src/H5PB.c | 1 + src/H5Pdapl.c | 2 +- src/H5S.c | 1 + src/H5SMbtree2.c | 1 + src/H5SMmessage.c | 1 + src/H5Shyper.c | 1 + src/H5VM.c | 1 + src/H5VMprivate.h | 1 + src/H5private.h | 6 +----- 44 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index 825043b..3377aa2 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Apkg.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ #include "H5SMprivate.h" /* Shared object header messages */ diff --git a/src/H5B.c b/src/H5B.c index 4cf1f72..2a34fae 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -107,6 +107,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ diff --git a/src/H5B2int.c b/src/H5B2int.c index a6dfe0e..9940cd7 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5B2pkg.h" /* v2 B-trees */ #include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ diff --git a/src/H5Bcache.c b/src/H5Bcache.c index cce10c9..c2c7a80 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Bpkg.h" /* B-link trees */ #include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index e6f0674..c13c36a 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -39,6 +39,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File space management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ #include "H5Sprivate.h" /* Dataspaces */ #include "H5VMprivate.h" /* Vector and array functions */ diff --git a/src/H5Dbtree2.c b/src/H5Dbtree2.c index f0a1380..d25e0f0 100644 --- a/src/H5Dbtree2.c +++ b/src/H5Dbtree2.c @@ -32,6 +32,7 @@ #include "H5Dpkg.h" /* Datasets */ #include "H5FLprivate.h" /* Free Lists */ #include "H5MFprivate.h" /* File space management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vector and array functions */ diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index adf6719..ed12a6a 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -40,6 +40,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5FOprivate.h" /* File objects */ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ diff --git a/src/H5Dearray.c b/src/H5Dearray.c index 8f6fae4..b23ac46 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -37,6 +37,7 @@ #include "H5EAprivate.h" /* Extensible arrays */ #include "H5FLprivate.h" /* Free Lists */ #include "H5MFprivate.h" /* File space management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vector functions */ diff --git a/src/H5Dfill.c b/src/H5Dfill.c index 1c501ce..69f4ff8 100644 --- a/src/H5Dfill.c +++ b/src/H5Dfill.c @@ -38,6 +38,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vector and array functions */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 7498e63..0e0edf7 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -27,6 +27,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5EA.c b/src/H5EA.c index 5621d33..d0bf474 100644 --- a/src/H5EA.c +++ b/src/H5EA.c @@ -46,6 +46,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ #include "H5FLprivate.h" /* Free Lists */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vector functions */ diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 9e908e7..da67e6b 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -41,6 +41,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5EAhdr.c b/src/H5EAhdr.c index a0bea79..18d642f 100644 --- a/src/H5EAhdr.c +++ b/src/H5EAhdr.c @@ -41,6 +41,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ diff --git a/src/H5EAstat.c b/src/H5EAstat.c index 6c55d7e..509d3f8 100644 --- a/src/H5EAstat.c +++ b/src/H5EAstat.c @@ -40,6 +40,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5FA.c b/src/H5FA.c index 03616ad..8c86193 100644 --- a/src/H5FA.c +++ b/src/H5FA.c @@ -41,6 +41,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FApkg.h" /* Fixed Arrays */ #include "H5FLprivate.h" /* Free Lists */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vector functions */ diff --git a/src/H5FAcache.c b/src/H5FAcache.c index 2726bff..f440efe 100644 --- a/src/H5FAcache.c +++ b/src/H5FAcache.c @@ -41,6 +41,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FApkg.h" /* Fixed Arrays */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index 5a6283f..8f29b83 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -39,6 +39,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FApkg.h" /* Fixed Arrays */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5FAstat.c b/src/H5FAstat.c index e70fcb8..49a56a9 100644 --- a/src/H5FAstat.c +++ b/src/H5FAstat.c @@ -38,6 +38,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5FApkg.h" /* Fixed Arrays */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5FS.c b/src/H5FS.c index b71734d..dbcb6b5 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FSpkg.h" /* File free space */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5FScache.c b/src/H5FScache.c index b0b282a..7525a9a 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -38,6 +38,7 @@ #include "H5Fprivate.h" /* File */ #include "H5FSpkg.h" /* File free space */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index 053aad2..8d7852b 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -38,6 +38,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 94f66c6..e3860a0 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -28,6 +28,7 @@ typedef struct H5F_t H5F_t; #include "H5FDpublic.h" /* File drivers */ /* Private headers needed by this file */ +#include "H5MMprivate.h" /* Memory management */ #ifdef H5_HAVE_PARALLEL #include "H5Pprivate.h" /* Property lists */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c index 425cc14..71e0b2d 100644 --- a/src/H5Gbtree2.c +++ b/src/H5Gbtree2.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5Gcache.c b/src/H5Gcache.c index 7387eae..0ffdc53 100644 --- a/src/H5Gcache.c +++ b/src/H5Gcache.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5Gent.c b/src/H5Gent.c index 276da73..19aef10 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -32,6 +32,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5HF.c b/src/H5HF.c index 77ea6f8..5d52ca4 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -42,6 +42,8 @@ #include "H5FOprivate.h" /* File objects */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ + /****************/ /* Local Macros */ diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 5a9b161..5750a03 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ /****************/ diff --git a/src/H5HFtest.c b/src/H5HFtest.c index 0ddcb34..6f174bb 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -32,6 +32,8 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5HFpkg.h" /* Fractal heaps */ +#include "H5MMprivate.h" /* Memory management */ + /****************/ /* Local Macros */ diff --git a/src/H5HFtiny.c b/src/H5HFtiny.c index 1407861..0c27180 100644 --- a/src/H5HFtiny.c +++ b/src/H5HFtiny.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5HFpkg.h" /* Fractal heaps */ +#include "H5MMprivate.h" /* Memory management */ /****************/ diff --git a/src/H5HLcache.c b/src/H5HLcache.c index 2841a4c..8b04b47 100644 --- a/src/H5HLcache.c +++ b/src/H5HLcache.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5HLpkg.h" /* Local Heaps */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5MM.c b/src/H5MM.c index 9e87a2d..6f65e06 100644 --- a/src/H5MM.c +++ b/src/H5MM.c @@ -568,7 +568,8 @@ H5MM_xfree(void *mem) /*------------------------------------------------------------------------- * Function: H5MM_memcpy * - * Purpose: Like memcpy(3) but with a check for buffer overlap. + * Purpose: Like memcpy(3) but with sanity checks on the parameters, + * particularly buffer overlap. * * Return: Success: pointer to dest * Failure: NULL @@ -588,7 +589,8 @@ H5MM_memcpy(void *dest, const void *src, size_t n) HDassert(dest); HDassert(src); - HDassert(dest >= src + n || src >= dest + n); + HDassert(n > 0); + HDassert((char *)dest >= (const char *)src + n || (const char *)src >= (char *)dest + n); ret = HDmemcpy(dest, src, n); diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 090df18..c1f90cb 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ /****************/ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 213dd11..683d155 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -36,6 +36,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5Oint.c b/src/H5Oint.c index 8a10d04..570f94e 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -38,9 +38,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MFprivate.h" /* File memory management */ -#ifdef H5O_ENABLE_BOGUS #include "H5MMprivate.h" /* Memory management */ -#endif /* H5O_ENABLE_BOGUS */ #include "H5Opkg.h" /* Object headers */ #include "H5VLprivate.h" /* Virtual Object Layer */ diff --git a/src/H5Oshared.c b/src/H5Oshared.c index eec1a84..67ca76f 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -39,6 +39,7 @@ #include "H5Fprivate.h" /* File access */ #include "H5Gprivate.h" /* Groups */ #include "H5HFprivate.h" /* Fractal heap */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ #include "H5WBprivate.h" /* Wrapped Buffers */ diff --git a/src/H5PB.c b/src/H5PB.c index b4a39a7..25c5f43 100644 --- a/src/H5PB.c +++ b/src