1 // Copyright (c) Lawrence Livermore National Security, LLC and other Conduit
2 // Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
3 // other details. No copyright assignment is required to contribute to Conduit.
4
5 //-----------------------------------------------------------------------------
6 ///
7 /// file: conduit_relay_io_handle.cpp
8 ///
9 //-----------------------------------------------------------------------------
10
11 #ifdef CONDUIT_RELAY_IO_MPI_ENABLED
12 // FIXME:
13 #include "conduit_relay_io_handle.hpp"
14 #else
15 #include "conduit_relay_io_handle.hpp"
16 #endif
17
18 #include "conduit_relay_io.hpp"
19
20 #include "conduit_relay_io_handle_sidre.hpp"
21
22 #ifdef CONDUIT_RELAY_IO_HDF5_ENABLED
23 #include "conduit_relay_io_hdf5.hpp"
24 #endif
25
26
27 //-----------------------------------------------------------------------------
28 // standard lib includes
29 //-----------------------------------------------------------------------------
30
31 //-----------------------------------------------------------------------------
32 // -- begin conduit:: --
33 //-----------------------------------------------------------------------------
34 namespace conduit
35 {
36
37 //-----------------------------------------------------------------------------
38 // -- begin conduit::relay --
39 //-----------------------------------------------------------------------------
40 namespace relay
41 {
42
43 #ifdef CONDUIT_RELAY_IO_MPI_ENABLED
44 //-----------------------------------------------------------------------------
45 // -- begin conduit::relay::mpi --
46 //-----------------------------------------------------------------------------
47 namespace mpi
48 {
49 #endif
50
51 //-----------------------------------------------------------------------------
52 // -- begin conduit::relay::<mpi>::io --
53 //-----------------------------------------------------------------------------
54 namespace io
55 {
56
57
58
59
60
61 //-----------------------------------------------------------------------------
62 // BasicHandle -- IO Handle implementation for built-in protocols
63 //-----------------------------------------------------------------------------
64 class BasicHandle: public IOHandle::HandleInterface
65 {
66 public:
67 BasicHandle(const std::string &path,
68 const std::string &protocol,
69 const Node &options);
70 virtual ~BasicHandle();
71
72 void open();
73
74 bool is_open() const;
75
76 // main interface methods
77 void read(Node &node);
78 void read(Node &node, const Node &opts);
79 void read(const std::string &path,
80 Node &node);
81 void read(const std::string &path,
82 Node &node,
83 const Node &opts);
84
85 void write(const Node &node);
86 void write(const Node &node, const Node &opts);
87 void write(const Node &node,
88 const std::string &path);
89 void write(const Node &node,
90 const std::string &path,
91 const Node &opts);
92
93 void remove(const std::string &path);
94
95 void list_child_names(std::vector<std::string> &res);
96 void list_child_names(const std::string &path,
97 std::vector<std::string> &res);
98
99 bool has_path(const std::string &path);
100
101 void close();
102
103 private:
104 Node m_node;
105 bool m_open;
106
107 };
108
109
110 //-----------------------------------------------------------------------------
111 // HDF5Handle -- IO Handle implementation for HDF5
112 //-----------------------------------------------------------------------------
113 #ifdef CONDUIT_RELAY_IO_HDF5_ENABLED
114 //-----------------------------------------------------------------------------
115 class HDF5Handle: public IOHandle::HandleInterface
116 {
117 public:
118 HDF5Handle(const std::string &path,
119 const std::string &protocol,
120 const Node &options);
121 virtual ~HDF5Handle();
122
123 void open();
124
125 bool is_open() const;
126
127 // main interface methods
128 void read(Node &node);
129 void read(Node &node, const Node &opts);
130 void read(const std::string &path,
131 Node &node);
132 void read(const std::string &path,
133 Node &node,
134 const Node &opts);
135
136 void write(const Node &node);
137 void write(const Node &node, const Node &opts);
138 void write(const Node &node,
139 const std::string &path);
140 void write(const Node &node,
141 const std::string &path,
142 const Node &opts);
143
144 void remove(const std::string &path);
145
146 void list_child_names(std::vector<std::string> &res);
147 void list_child_names(const std::string &path,
148 std::vector<std::string> &res);
149
150 bool has_path(const std::string &path);
151
152 void close();
153
154 private:
155 hid_t m_h5_id;
156
157 };
158 //-----------------------------------------------------------------------------
159 #endif
160 //-----------------------------------------------------------------------------
161
162
163 //-----------------------------------------------------------------------------
164 // HandleInterface Implementation
165 //-----------------------------------------------------------------------------
166
167 //-----------------------------------------------------------------------------
HandleInterface(const std::string & path,const std::string & protocol,const Node & options)168 IOHandle::HandleInterface::HandleInterface(const std::string &path,
169 const std::string &protocol,
170 const Node &options)
171 : m_path(path),
172 m_protocol(protocol),
173 m_options(options)
174 {
175 // empty
176 }
177
178 //-----------------------------------------------------------------------------
~HandleInterface()179 IOHandle::HandleInterface::~HandleInterface()
180 {
181 // empty
182 }
183
184
185 //-----------------------------------------------------------------------------
186 void
open()187 IOHandle::HandleInterface::open()
188 {
189 // checks for subpaths, which we don't currently support
190
191 std::string file_path;
192 std::string subpath;
193
194 // check for ":" split
195 conduit::utils::split_file_path(path(),
196 std::string(":"),
197 file_path,
198 subpath);
199 if( !subpath.empty() )
200 {
201 CONDUIT_ERROR("IOHandle does not support opening paths with "
202 "subpaths specified: \"" << path() << "\"");
203 }
204
205 m_open_mode = "rwa"; // default to rw, append
206
207 m_open_mode_read = true;
208 m_open_mode_write = true;
209 m_open_mode_append = true;
210 m_open_mode_truncate = false;
211
212 // check if options includes open mode
213 if(options().has_child("mode") && options()["mode"].dtype().is_string())
214 {
215 std::string opts_mode = options()["mode"].as_string();
216
217 m_open_mode = "";
218
219 m_open_mode_read = false;
220 m_open_mode_write = false;
221 m_open_mode_append = false;
222 m_open_mode_truncate = false;
223
224 if(opts_mode.find("r") != std::string::npos)
225 {
226 m_open_mode += "r";
227 m_open_mode_read = true;
228 }
229
230 if(opts_mode.find("w") != std::string::npos)
231 {
232 m_open_mode += "w";
233 m_open_mode_write = true;
234 }
235
236 // we need at least read or write
237 if(! m_open_mode_read && ! m_open_mode_write)
238 {
239 CONDUIT_ERROR("IOHandle: invalid open mode:"
240 << "\"" << opts_mode << "\"."
241 << " 'mode' string must provide"
242 << " 'r' (read) and/or 'w' (write)."
243 << " Expected string: {rw}{a|t}");
244 }
245
246 // note append and truncate are mut-ex.
247 if(opts_mode.find("a") != std::string::npos)
248 {
249 if( opts_mode.find("t") != std::string::npos )
250 {
251 CONDUIT_ERROR("IOHandle: invalid open mode:"
252 << "\"" << opts_mode << "\"."
253 << " In 'mode' string "
254 << " 'a' (append) and 't' (truncate)"
255 << " cannot be used together."
256 << " Expected string: {rw}{a|t}");
257 }
258 m_open_mode += "a";
259 m_open_mode_append = true;
260 }
261
262 // we checked for both above, so it's safe just check for t here
263 if(opts_mode.find("t") != std::string::npos)
264 {
265 m_open_mode += "t";
266 m_open_mode_truncate = true;
267 }
268
269 if( !m_open_mode_append && !m_open_mode_truncate)
270 {
271 // if neither append or truncate were specified,
272 // default to append
273 m_open_mode += "a";
274 m_open_mode_append = true;
275 }
276 }
277 }
278
279
280 //-----------------------------------------------------------------------------
281 IOHandle::HandleInterface *
create(const std::string & path)282 IOHandle::HandleInterface::create(const std::string &path)
283 {
284 std::string protocol;
285 Node options;
286 return create(path,protocol,options);
287 }
288
289 //-----------------------------------------------------------------------------
290 IOHandle::HandleInterface *
create(const std::string & path,const std::string & protocol)291 IOHandle::HandleInterface::create(const std::string &path,
292 const std::string &protocol)
293 {
294 Node options;
295 return create(path,protocol,options);
296 }
297
298 //-----------------------------------------------------------------------------
299 IOHandle::HandleInterface *
create(const std::string & path,const Node & options)300 IOHandle::HandleInterface::create(const std::string &path,
301 const Node &options)
302 {
303 std::string protocol;
304 return create(path,protocol,options);
305 }
306
307 //-----------------------------------------------------------------------------
308 IOHandle::HandleInterface *
create(const std::string & path,const std::string & protocol_,const Node & options)309 IOHandle::HandleInterface::create(const std::string &path,
310 const std::string &protocol_,
311 const Node &options)
312 {
313 HandleInterface *res = NULL;
314 std::string protocol = protocol_;
315
316 // allow empty protocol to be used for auto detect
317 if(protocol.empty())
318 {
319 conduit::relay::io::identify_protocol(path,protocol);
320 }
321
322 if(protocol == "conduit_bin" ||
323 protocol == "json" ||
324 protocol == "conduit_json" ||
325 protocol == "conduit_base64_json" ||
326 protocol == "yaml" )
327 {
328 res = new BasicHandle(path, protocol, options);
329 }
330 else if( protocol == "sidre_hdf5" )
331 {
332 // magic interface
333 // path is the path to the root file
334 res = new SidreIOHandle(path,protocol,options);
335 }
336 else if( protocol == "hdf5" )
337 {
338 #ifdef CONDUIT_RELAY_IO_HDF5_ENABLED
339 res = new HDF5Handle(path, protocol, options);
340 #else
341 CONDUIT_ERROR("conduit_relay lacks HDF5 support: " <<
342 "Cannot create Relay I/O Handle for HDF5" << path);
343 #endif
344 }
345 else
346 {
347 CONDUIT_ERROR("Relay I/O Handle does not support the protocol: "
348 << protocol);
349 }
350 return res;
351 }
352
353 //-----------------------------------------------------------------------------
354 const std::string &
path() const355 IOHandle::HandleInterface::path() const
356 {
357 return m_path;
358 }
359
360 //-----------------------------------------------------------------------------
361 const std::string &
protocol() const362 IOHandle::HandleInterface::protocol() const
363 {
364 return m_protocol;
365 }
366
367 //-----------------------------------------------------------------------------
368 const std::string &
open_mode() const369 IOHandle::HandleInterface::open_mode() const
370 {
371 return m_open_mode;
372 }
373
374 //-----------------------------------------------------------------------------
375 const Node &
options() const376 IOHandle::HandleInterface::options() const
377 {
378 return m_options;
379 }
380
381
382 //-----------------------------------------------------------------------------
383 // BasicHandle Implementation
384 //-----------------------------------------------------------------------------
BasicHandle(const std::string & path,const std::string & protocol,const Node & options)385 BasicHandle::BasicHandle(const std::string &path,
386 const std::string &protocol,
387 const Node &options)
388 : HandleInterface(path,protocol,options),
389 m_node(),
390 m_open(false)
391 {
392 // empty
393 }
394 //-----------------------------------------------------------------------------
~BasicHandle()395 BasicHandle::~BasicHandle()
396 {
397 close();
398 }
399
400 //-----------------------------------------------------------------------------
401 void
open()402 BasicHandle::open()
403 {
404 close();
405 // call base class method, which does final sanity checks
406 HandleInterface::open();
407
408 // read from file if it already exists, other wise
409 // we start out with a blank slate
410 if( utils::is_file( path() ) )
411 {
412 // read if handle is not 'write' only and we aren't truncating
413 if( open_mode_read() && !open_mode_truncate() )
414 {
415 // read from file
416 io::load(path(),
417 protocol(),
418 options(),
419 m_node);
420 }
421 else
422 {
423 m_node.reset();
424 }
425 }
426 else if( open_mode_read_only() ) // fail on read only if file doesn't exist
427 {
428 CONDUIT_ERROR("path: \""
429 << path()
430 << "\" does not exist, cannot open read only "
431 << "(mode = '" << open_mode() << "')");
432 }
433 else
434 {
435 // make sure we can actually write to this location
436 // we don't want to fail on close if the path
437 // is bogus
438 io::save(m_node,
439 path(),
440 protocol(),
441 options());
442 }
443
444 m_open = true;
445 }
446
447 //-----------------------------------------------------------------------------
448 bool
is_open() const449 BasicHandle::is_open() const
450 {
451 return m_open;
452 }
453
454 //-----------------------------------------------------------------------------
455 void
read(Node & node)456 BasicHandle::read(Node &node)
457 {
458 Node opts;
459 read(node, opts);
460 }
461
462 //-----------------------------------------------------------------------------
463 void
read(Node & node,const Node & opts)464 BasicHandle::read(Node &node, const Node& opts)
465 {
466 CONDUIT_UNUSED(opts);
467 // note: wrong mode errors are handled before dispatch to interface
468
469 node.update(m_node);
470 }
471
472 //-----------------------------------------------------------------------------
473 void
read(const std::string & path,Node & node)474 BasicHandle::read(const std::string &path,
475 Node &node)
476 {
477 Node opts;
478 read(path, node, opts);
479 }
480
481 //-----------------------------------------------------------------------------
482 void
read(const std::string & path,Node & node,const Node & opts)483 BasicHandle::read(const std::string &path,
484 Node &node,
485 const Node &opts)
486 {
487 CONDUIT_UNUSED(opts);
488 // note: wrong mode errors are handled before dispatch to interface
489
490 if(m_node.has_path(path))
491 {
492 node.update(m_node[path]);
493 }
494 }
495
496 //-----------------------------------------------------------------------------
497 void
write(const Node & node)498 BasicHandle::write(const Node &node)
499 {
500 Node opts;
501 write(node, opts);
502 }
503
504 //-----------------------------------------------------------------------------
505 void
write(const Node & node,const Node & opts)506 BasicHandle::write(const Node &node,
507 const Node &opts)
508 {
509 CONDUIT_UNUSED(opts);
510 // note: wrong mode errors are handled before dispatch to interface
511
512 m_node.update(node);
513 }
514
515
516 //-----------------------------------------------------------------------------
517 void
write(const Node & node,const std::string & path)518 BasicHandle::write(const Node &node,
519 const std::string &path)
520 {
521 Node opts;
522 write(node, path, opts);
523 }
524
525 //-----------------------------------------------------------------------------
526 void
write(const Node & node,const std::string & path,const Node & opts)527 BasicHandle::write(const Node &node,
528 const std::string &path,
529 const Node& opts)
530 {
531 CONDUIT_UNUSED(opts);
532 // note: wrong mode errors are handled before dispatch to interface
533
534 m_node[path].update(node);
535 }
536
537 //-----------------------------------------------------------------------------
538 void
list_child_names(std::vector<std::string> & res)539 BasicHandle::list_child_names(std::vector<std::string> &res)
540 {
541 // note: wrong mode errors are handled before dispatch to interface
542
543 res = m_node.child_names();
544 }
545
546 //-----------------------------------------------------------------------------
547 void
list_child_names(const std::string & path,std::vector<std::string> & res)548 BasicHandle::list_child_names(const std::string &path,
549 std::vector<std::string> &res)
550 {
551 // note: wrong mode errors are handled before dispatch to interface
552
553 res.clear();
554 if(m_node.has_path(path))
555 res = m_node[path].child_names();
556 }
557
558 //-----------------------------------------------------------------------------
559 void
remove(const std::string & path)560 BasicHandle::remove(const std::string &path)
561 {
562 // note: wrong mode errors are handled before dispatch to interface
563
564 m_node.remove(path);
565 }
566
567 //-----------------------------------------------------------------------------
568 bool
has_path(const std::string & path)569 BasicHandle::has_path(const std::string &path)
570 {
571 // note: wrong mode errors are handled before dispatch to interface
572
573 return m_node.has_path(path);
574 }
575
576 //-----------------------------------------------------------------------------
577 void
close()578 BasicHandle::close()
579 {
580 if(m_open && !open_mode_read_only() )
581 {
582 // here is where it actually gets realized on disk
583 io::save(m_node,
584 path(),
585 protocol(),
586 options());
587 m_node.reset();
588 m_open = false;
589 }
590 }
591
592
593 //-----------------------------------------------------------------------------
594 // HDF5Handle Implementation
595 //-----------------------------------------------------------------------------
596 //-----------------------------------------------------------------------------
597 //-----------------------------------------------------------------------------
598 #ifdef CONDUIT_RELAY_IO_HDF5_ENABLED
599 //-----------------------------------------------------------------------------
600 //-----------------------------------------------------------------------------
601 //-----------------------------------------------------------------------------
HDF5Handle(const std::string & path,const std::string & protocol,const Node & options)602 HDF5Handle::HDF5Handle(const std::string &path,
603 const std::string &protocol,
604 const Node &options)
605 : HandleInterface(path,protocol,options),
606 m_h5_id(-1)
607 {
608 // empty
609 }
610 //-----------------------------------------------------------------------------
~HDF5Handle()611 HDF5Handle::~HDF5Handle()
612 {
613 close();
614 }
615
616 //-----------------------------------------------------------------------------
617 void
open()618 HDF5Handle::open()
619 {
620 close();
621
622 // call base class method, which does final sanity checks
623 // and processes standard options (mode = "rw", etc)
624 HandleInterface::open();
625
626 if( utils::is_file( path() ) )
627 {
628 // check open mode to select proper hdf5 call
629
630 if( open_mode_read_only() )
631 {
632 m_h5_id = hdf5_open_file_for_read( path() );
633 } // support write with append
634 else if ( open_mode_append() )
635 {
636 m_h5_id = hdf5_open_file_for_read_write( path() );
637 } // support write with truncate
638 else if ( open_mode_truncate() )
639 {
640 m_h5_id = hdf5_create_file( path() );
641 }
642 }
643 else if( open_mode_read_only() )
644 {
645 CONDUIT_ERROR("path: \""
646 << path()
647 << "\" does not exist, cannot open read only (mode = 'r')");
648 }
649 else
650 {
651 m_h5_id = hdf5_create_file( path() );
652 }
653 }
654
655
656 //-----------------------------------------------------------------------------
657 bool
is_open() const658 HDF5Handle::is_open() const
659 {
660 return m_h5_id != -1;
661 }
662
663 //-----------------------------------------------------------------------------
664 void
read(Node & node)665 HDF5Handle::read(Node &node)
666 {
667 Node opts;
668 read(node, opts);
669 }
670
671 //-----------------------------------------------------------------------------
672 void
read(Node & node,const Node & opts)673 HDF5Handle::read(Node &node,
674 const Node &opts)
675 {
676 // note: wrong mode errors are handled before dispatch to interface
677
678 hdf5_read(m_h5_id,opts,node);
679 }
680
681 //-----------------------------------------------------------------------------
682 void
read(const std::string & path,Node & node)683 HDF5Handle::read(const std::string &path,
684 Node &node)
685 {
686 Node opts;
687 read(path, node, opts);
688 }
689
690 //-----------------------------------------------------------------------------
691 void
read(const std::string & path,Node & node,const Node & opts)692 HDF5Handle::read(const std::string &path,
693 Node &node,
694 const Node &opts)
695 {
696 // note: wrong mode errors are handled before dispatch to interface
697
698 hdf5_read(m_h5_id,path,opts,node);
699 }
700
701 //-----------------------------------------------------------------------------
702 void
write(const Node & node)703 HDF5Handle::write(const Node &node)
704 {
705 Node opts;
706 write(node, opts);
707 }
708
709 //-----------------------------------------------------------------------------
710 void
write(const Node & node,const Node & opts)711 HDF5Handle::write(const Node &node,
712 const Node &opts)
713 {
714 // note: wrong mode errors are handled before dispatch to interface
715
716 // Options Push / Pop (only needed for write, since hdf5 only supports
717 // write options
718 Node prev_options;
719 if(options().has_child("hdf5"))
720 {
721 hdf5_options(prev_options);
722 hdf5_set_options(options()["hdf5"]);
723 }
724
725 hdf5_write(node,m_h5_id, opts);
726
727 if(!prev_options.dtype().is_empty())
728 {
729 hdf5_set_options(prev_options);
730 }
731 }
732
733
734
735 //-----------------------------------------------------------------------------
736 void
write(const Node & node,const std::string & path)737 HDF5Handle::write(const Node &node,
738 const std::string &path)
739 {
740 Node opts;
741 write(node, path, opts);
742 }
743
744 //-----------------------------------------------------------------------------
745 void
write(const Node & node,const std::string & path,const Node & opts)746 HDF5Handle::write(const Node &node,
747 const std::string &path,
748 const Node &opts)
749 {
750 // note: wrong mode errors are handled before dispatch to interface
751
752 // Options Push / Pop (only needed for write, since hdf5 only supports
753 // write options
754 Node prev_options;
755 if(options().has_child("hdf5"))
756 {
757 hdf5_options(prev_options);
758 hdf5_set_options(options()["hdf5"]);
759 }
760
761 hdf5_write(node,m_h5_id,path,opts);
762
763 if(!prev_options.dtype().is_empty())
764 {
765 hdf5_set_options(prev_options);
766 }
767 }
768
769 //-----------------------------------------------------------------------------
770 void
list_child_names(std::vector<std::string> & res)771 HDF5Handle::list_child_names(std::vector<std::string> &res)
772 {
773 // note: wrong mode errors are handled before dispatch to interface
774
775 hdf5_group_list_child_names(m_h5_id, "/", res);
776 }
777
778 //-----------------------------------------------------------------------------
779 void
list_child_names(const std::string & path,std::vector<std::string> & res)780 HDF5Handle::list_child_names(const std::string &path,
781 std::vector<std::string> &res)
782 {
783 // note: wrong mode errors are handled before dispatch to interface
784
785 hdf5_group_list_child_names(m_h5_id, path, res);
786 }
787
788 //-----------------------------------------------------------------------------
789 void
remove(const std::string & path)790 HDF5Handle::remove(const std::string &path)
791 {
792 // note: wrong mode errors are handled before dispatch to interface
793
794 hdf5_remove_path(m_h5_id,path);
795 }
796
797 //-----------------------------------------------------------------------------
798 bool
has_path(const std::string & path)799 HDF5Handle::has_path(const std::string &path)
800 {
801 // note: wrong mode errors are handled before dispatch to interface
802
803 return hdf5_has_path(m_h5_id,path);
804 }
805
806
807 //-----------------------------------------------------------------------------
808 void
close()809 HDF5Handle::close()
810 {
811 if(m_h5_id >= 0)
812 {
813 hdf5_close_file(m_h5_id);
814 }
815 m_h5_id = -1;
816 }
817
818 //-----------------------------------------------------------------------------
819 //-----------------------------------------------------------------------------
820 #endif
821 //-----------------------------------------------------------------------------
822 //-----------------------------------------------------------------------------
823
824
825 //-----------------------------------------------------------------------------
826 // IOHandle Implementation
827 //-----------------------------------------------------------------------------
828
829 //-----------------------------------------------------------------------------
IOHandle()830 IOHandle::IOHandle()
831 : m_handle(NULL)
832 {
833
834 }
835
836 //-----------------------------------------------------------------------------
~IOHandle()837 IOHandle::~IOHandle()
838 {
839 close();
840 }
841
842 //-----------------------------------------------------------------------------
843 void
open(const std::string & path)844 IOHandle::open(const std::string &path)
845 {
846 close();
847 m_handle = HandleInterface::create(path);
848 if(m_handle != NULL)
849 {
850 m_handle->open();
851 }
852 }
853
854 //-----------------------------------------------------------------------------
855 void
open(const std::string & path,const std::string & protocol)856 IOHandle::open(const std::string &path,
857 const std::string &protocol)
858 {
859 close();
860 m_handle = HandleInterface::create(path, protocol);
861 if(m_handle != NULL)
862 {
863 m_handle->open();
864 }
865 }
866
867 //-----------------------------------------------------------------------------
868 void
open(const std::string & path,const Node & options)869 IOHandle::open(const std::string &path,
870 const Node &options)
871 {
872 close();
873 m_handle = HandleInterface::create(path, options);
874 if(m_handle != NULL)
875 {
876 m_handle->open();
877 }
878 }
879
880 //-----------------------------------------------------------------------------
881 void
open(const std::string & path,const std::string & protocol,const Node & options)882 IOHandle::open(const std::string &path,
883 const std::string &protocol,
884 const Node &options)
885 {
886 close();
887 m_handle = HandleInterface::create(path, protocol, options);
888 if(m_handle != NULL)
889 {
890 m_handle->open();
891 }
892 }
893
894 //-----------------------------------------------------------------------------
895 bool
is_open() const896 IOHandle::is_open() const
897 {
898 bool res = false;
899
900 if(m_handle != NULL)
901 {
902 res = m_handle->is_open();
903 }
904
905 return res;
906 }
907
908 //-----------------------------------------------------------------------------
909 void
read(Node & node)910 IOHandle::read(Node &node)
911 {
912 Node opts;
913 read(node,opts);
914 }
915
916 //-----------------------------------------------------------------------------
917 void
read(Node & node,const Node & opts)918 IOHandle::read(Node &node,
919 const Node &opts)
920 {
921 if(m_handle != NULL)
922 {
923 if( m_handle->open_mode_write_only() )
924 {
925 CONDUIT_ERROR("IOHandle: cannot read, handle is write only"
926 " (mode = '" << m_handle->open_mode() << "')");
927 }
928
929 m_handle->read(node,opts);
930 }
931 else
932 {
933 CONDUIT_ERROR("Invalid or closed handle.");
934 }
935 }
936
937 //-----------------------------------------------------------------------------
938 void
read(const std::string & path,Node & node)939 IOHandle::read(const std::string &path,
940 Node &node)
941 {
942 Node opts;
943 read(path,node,opts);
944 }
945
946 //-----------------------------------------------------------------------------
947 void
read(const std::string & path,Node & node,const Node & opts)948 IOHandle::read(const std::string &path,
949 Node &node,
950 const Node &opts)
951 {
952 if(m_handle != NULL)
953 {
954 if( m_handle->open_mode_write_only() )
955 {
956 CONDUIT_ERROR("IOHandle: cannot read, handle is write only"
957 " (mode = '" << m_handle->open_mode() << "')");
958 }
959
960 if(path.empty())
961 {
962 m_handle->read(node, opts);
963 }
964 else
965 {
966 m_handle->read(path, node, opts);
967 }
968 }
969 else
970 {
971 CONDUIT_ERROR("Invalid or closed handle.");
972 }
973 }
974
975 //-----------------------------------------------------------------------------
976 void
write(const Node & node)977 IOHandle::write(const Node &node)
978 {
979 Node opts;
980 write(node,opts);
981 }
982
983 //-----------------------------------------------------------------------------
984 void
write(const Node & node,const Node & opts)985 IOHandle::write(const Node &node,
986 const Node &opts)
987 {
988 if(m_handle != NULL)
989 {
990 if( m_handle->open_mode_read_only() )
991 {
992 CONDUIT_ERROR("IOHandle: cannot write, handle is read only"
993 " (mode = '" << m_handle->open_mode() << "')");
994 }
995
996 m_handle->write(node, opts);
997 }
998 else
999 {
1000 CONDUIT_ERROR("Invalid or closed handle.");
1001 }
1002 }
1003
1004 //-----------------------------------------------------------------------------
1005 void
write(const Node & node,const std::string & path)1006 IOHandle::write(const Node &node,
1007 const std::string &path)
1008 {
1009 Node opts;
1010 write(node,path,opts);
1011 }
1012
1013 //-----------------------------------------------------------------------------
1014 void
write(const Node & node,const std::string & path,const Node & opts)1015 IOHandle::write(const Node &node,
1016 const std::string &path,
1017 const Node &opts)
1018 {
1019 if(m_handle != NULL)
1020 {
1021 if( m_handle->open_mode_read_only() )
1022 {
1023 CONDUIT_ERROR("IOHandle: cannot write, handle is read only"
1024 " (mode = '" << m_handle->open_mode() << "')");
1025 }
1026
1027 m_handle->write(node, path, opts);
1028 }
1029 else
1030 {
1031 CONDUIT_ERROR("Invalid or closed handle.");
1032 }
1033
1034 }
1035
1036 //-----------------------------------------------------------------------------
1037 void
remove(const std::string & path)1038 IOHandle::remove(const std::string &path)
1039 {
1040 if(m_handle != NULL)
1041 {
1042 if( m_handle->open_mode_read_only() )
1043 {
1044 CONDUIT_ERROR("IOHandle: cannot remove path, handle is read only"
1045 " (mode = '" << m_handle->open_mode() << "')");
1046 }
1047
1048 m_handle->remove(path);
1049 }
1050 else
1051 {
1052 CONDUIT_ERROR("Invalid or closed handle.");
1053 }
1054 }
1055
1056 //-----------------------------------------------------------------------------
1057 void
list_child_names(std::vector<std::string> & names)1058 IOHandle::list_child_names(std::vector<std::string> &names)
1059 {
1060 names.clear();
1061 if(m_handle != NULL)
1062 {
1063 if( m_handle->open_mode_write_only() )
1064 {
1065 CONDUIT_ERROR("IOHandle: cannot list_child_names, handle is"
1066 " write only"
1067 " (mode = '" << m_handle->open_mode() << "')");
1068 }
1069
1070 return m_handle->list_child_names(names);
1071 }
1072 else
1073 {
1074 CONDUIT_ERROR("Invalid or closed handle.");
1075 }
1076 }
1077
1078
1079 //-----------------------------------------------------------------------------
1080 void
list_child_names(const std::string & path,std::vector<std::string> & names)1081 IOHandle::list_child_names(const std::string &path,
1082 std::vector<std::string> &names)
1083 {
1084 names.clear();
1085 if(m_handle != NULL)
1086 {
1087 if( m_handle->open_mode_write_only() )
1088 {
1089 CONDUIT_ERROR("IOHandle: cannot list_child_names, handle is"
1090 " write only"
1091 " (mode = '" << m_handle->open_mode() << "')");
1092 }
1093
1094 return m_handle->list_child_names(path, names);
1095 }
1096 else
1097 {
1098 CONDUIT_ERROR("Invalid or closed handle.");
1099 }
1100 }
1101
1102 //-----------------------------------------------------------------------------
1103 bool
has_path(const std::string & path)1104 IOHandle::has_path(const std::string &path)
1105 {
1106 if(m_handle != NULL)
1107 {
1108 if( m_handle->open_mode_write_only() )
1109 {
1110 CONDUIT_ERROR("IOHandle: cannot call has_path, handle is write"
1111 " only"
1112 " (mode = '" << m_handle->open_mode() << "')");
1113 }
1114 return m_handle->has_path(path);
1115 }
1116 else
1117 {
1118 CONDUIT_ERROR("Invalid or closed handle.");
1119 }
1120
1121 return false;
1122 }
1123
1124 //-----------------------------------------------------------------------------
1125 void
close()1126 IOHandle::close()
1127 {
1128 if(m_handle != NULL)
1129 {
1130 m_handle->close();
1131 delete m_handle;
1132 m_handle = NULL;
1133 }
1134 // else, ignore ...
1135 }
1136
1137
1138 }
1139 //-----------------------------------------------------------------------------
1140 // -- end conduit::relay::<mpi>::io --
1141 //-----------------------------------------------------------------------------
1142
1143 #ifdef CONDUIT_RELAY_IO_MPI_ENABLED
1144 }
1145 //-----------------------------------------------------------------------------
1146 // -- begin conduit::relay::mpi --
1147 //-----------------------------------------------------------------------------
1148 #endif
1149
1150 }
1151 //-----------------------------------------------------------------------------
1152 // -- end conduit::relay --
1153 //-----------------------------------------------------------------------------
1154
1155 }
1156 //-----------------------------------------------------------------------------
1157 // -- end conduit:: --
1158 //-----------------------------------------------------------------------------
1159