1 // Copyright (c) 2017-2021, Lawrence Livermore National Security, LLC and
2 // other Axom Project Developers. See the top-level LICENSE file for details.
3 //
4 // SPDX-License-Identifier: (BSD-3-Clause)
5
6 #include "axom/inlet/inlet_utils.hpp"
7
8 namespace axom
9 {
10 namespace inlet
11 {
setWarningFlag(axom::sidre::Group * root)12 void setWarningFlag(axom::sidre::Group* root)
13 {
14 if(!root->hasView("warningFlag"))
15 {
16 root->createViewScalar("warningFlag", 1);
17 }
18 }
19
setFlag(axom::sidre::Group & target,axom::sidre::Group & root,const std::string & flag,bool value)20 void setFlag(axom::sidre::Group& target,
21 axom::sidre::Group& root,
22 const std::string& flag,
23 bool value)
24 {
25 const int8 bval = value ? 1 : 0;
26 if(target.hasView(flag))
27 {
28 auto flagView = target.getView(flag);
29 if(flagView->getData<int8>() != bval)
30 {
31 const std::string msg =
32 fmt::format("[Inlet] '{0}' value has already been defined for: {1}",
33 flag,
34 target.getName());
35
36 SLIC_WARNING(msg);
37 setWarningFlag(&root);
38 }
39 }
40 else
41 {
42 if(value)
43 {
44 target.createViewScalar(flag, bval);
45 }
46 else
47 {
48 target.createViewScalar(flag, bval);
49 }
50 }
51 }
52
checkFlag(const axom::sidre::Group & target,axom::sidre::Group & root,const std::string & flag)53 bool checkFlag(const axom::sidre::Group& target,
54 axom::sidre::Group& root,
55 const std::string& flag)
56 {
57 if(!target.hasView(flag))
58 {
59 return false;
60 }
61 const axom::sidre::View* valueView = target.getView(flag);
62 const int8 intValue = valueView->getScalar();
63 if(intValue < 0 || intValue > 1)
64 {
65 const std::string msg = fmt::format(
66 "[Inlet] Invalid integer value stored in "
67 " boolean value named {0} for flag '{1}'",
68 target.getName(),
69 flag);
70 SLIC_WARNING(msg);
71 setWarningFlag(&root);
72 return static_cast<bool>(intValue);
73 }
74
75 return static_cast<bool>(intValue);
76 }
77
verifyRequired(const axom::sidre::Group & target,const bool condition,const std::string & type,std::vector<VerificationError> * errors)78 bool verifyRequired(const axom::sidre::Group& target,
79 const bool condition,
80 const std::string& type,
81 std::vector<VerificationError>* errors)
82 {
83 // Assume that it wasn't found
84 ReaderResult status = ReaderResult::NotFound;
85 if(target.hasView("retrieval_status"))
86 {
87 status = static_cast<ReaderResult>(
88 static_cast<int>(target.getView("retrieval_status")->getData()));
89 }
90
91 if(target.hasView("required"))
92 {
93 int8 required = target.getView("required")->getData();
94 // If it wasn't found at all, it's only an error if the object was required and not provided
95 // The retrieval_status will typically (but not always) be NotFound in these cases, but that
96 // information isn't needed here unless it's a collection group - empty collections are permissible,
97 // so they shouldn't impede verification if they existed but were empty (hence Success check)
98 if(required && !condition &&
99 (!isCollectionGroup(target.getPathName()) ||
100 status != ReaderResult::Success))
101 {
102 const std::string msg = fmt::format(
103 "[Inlet] Required {0} not "
104 "specified: {1}",
105 type,
106 target.getPathName());
107 INLET_VERIFICATION_WARNING(target.getPathName(), msg, errors);
108 return false;
109 }
110 }
111
112 // If it was the wrong type or part of a non-homogeneous array, it's always an error,
113 // even if the object wasn't marked as required
114 if(status == ReaderResult::WrongType || status == ReaderResult::NotHomogeneous)
115 {
116 const std::string reason = (status == ReaderResult::WrongType)
117 ? "of the wrong type"
118 : "not homogeneous";
119 const std::string msg =
120 fmt::format("[Inlet] {0} '{1}' was {2}", type, target.getPathName(), reason);
121 INLET_VERIFICATION_WARNING(target.getPathName(), msg, errors);
122 return false;
123 }
124 return true;
125 }
126
markAsStructCollection(axom::sidre::Group & target)127 void markAsStructCollection(axom::sidre::Group& target)
128 {
129 if(target.hasView(detail::STRUCT_COLLECTION_FLAG))
130 {
131 // This flag should only ever be one, so we verify that and error otherwise
132 const sidre::View* flag = target.getView(detail::STRUCT_COLLECTION_FLAG);
133 SLIC_ERROR_IF(
134 !flag->isScalar(),
135 fmt::format(
136 "[Inlet] Struct collection flag of group '{0}' was not a scalar",
137 target.getName()));
138 const int8 value = flag->getScalar();
139 SLIC_ERROR_IF(value != 1,
140 fmt::format("[Inlet] Struct collection flag of group '{0}' "
141 "had a value other than 1",
142 target.getName()));
143 }
144 else
145 {
146 target.createViewScalar(detail::STRUCT_COLLECTION_FLAG, static_cast<int8>(1));
147 }
148 }
149
markRetrievalStatus(axom::sidre::Group & target,const ReaderResult result)150 void markRetrievalStatus(axom::sidre::Group& target, const ReaderResult result)
151 {
152 if(!target.hasView("retrieval_status"))
153 {
154 target.createViewScalar("retrieval_status", static_cast<int>(result));
155 }
156 }
157
collectionRetrievalResult(const bool contains_other_type,const bool contains_requested_type)158 ReaderResult collectionRetrievalResult(const bool contains_other_type,
159 const bool contains_requested_type)
160 {
161 // First check if the collection was entirely the wrong type
162 if(contains_other_type && !contains_requested_type)
163 {
164 return ReaderResult::WrongType;
165 }
166 // Then check if some values were of the correct type, but others weren't
167 else if(contains_other_type)
168 {
169 return ReaderResult::NotHomogeneous;
170 }
171 // Otherwise we mark it as successful - having just an empty collection
172 // counts as success
173 return ReaderResult::Success;
174 }
175
176 } // namespace inlet
177 } // namespace axom
178