NCBI C++ ToolKit
macro_edit_fn_base.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: macro_edit_fn_base.cpp 47378 2023-02-27 20:09:44Z asztalos $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Anatoly Osipov, Andrea Asztalos
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
38 
39 /** @addtogroup GUI_MACRO_SCRIPTS_UTIL
40  *
41  * @{
42  */
43 
45 BEGIN_SCOPE(macro)
46 
47 void IEditMacroFunction::x_InitCall(CIRef<IMacroBioDataIter>& data)
48 {
49  m_DataIter = data;
50  m_QualsChangedCount = 0;
51 
52  _ASSERT(m_CmdComposite && m_DataIter);
53  m_Result->SetDataType(CMQueryNodeValue::eNotSet);
54 
55  if (!x_IsNestedFunctionReturnValid()) {
56  return;
57  }
58 
59  if (!x_ValidArguments()) {
60  NCBI_THROW(CMacroExecException, eWrongArguments, "Wrong number or type of arguments passed to '" + m_FuncName + "' function");
61  }
62 
63  x_ResetState();
64 }
65 
67 {
68  m_Result = Ref(dynamic_cast<CMQueryNodeValue*>(qnode->GetUserObject()));
70 
71  m_Args.resize(0);
74  for (; it != it_end; ++it) {
75  CRef<CMQueryNodeValue> arg = Ref(dynamic_cast<CMQueryNodeValue*>((*it)->GetValue().GetUserObject()));
77  if (arg) {
78  m_Args.push_back(arg);
79  }
80  }
81  m_FuncName = qnode->GetOriginalText();
82 }
83 
84 void IEditMacroFunction::x_AssignReturnValue(const CObjectInfo& oi, const string& field_name)
85 {
86  if (m_Nested == eNotNested) { // return a standard type value
88  if ( !GetFieldsByName(&res_oi, oi, field_name) || res_oi.size() != 1) {
89  return;
90  }
91  m_Result->AssignFromObjectInfo(res_oi.front().field);
92 
93  } else {
94  ResolveIdentToObjects(oi, field_name, m_Result.GetNCObject());
95  }
96 }
97 
98 void IEditMacroFunction::x_AssignReturnValueFromContainer(const CObjectInfo& oi, const string& container, const string& field_name)
99 {
100  m_Result->SetNotSet();
101 
102  CMQueryNodeValue::TObs res_oi;
103  GetFieldsByName(&res_oi, oi, container);
104  if (res_oi.empty()) {
105  return;
106  }
107 
108  CObjectInfo mod_obj = res_oi.front().field;
109  if (mod_obj.GetTypeFamily() != eTypeFamilyContainer) {
110  return;
111  }
112 
113  CObjectInfoEI elem = mod_obj.BeginElements();
114  while (elem.Valid()) {
115  CObjectInfo objInfo = elem.GetElement();
116  if (objInfo.GetTypeFamily() == eTypeFamilyPointer) {
117  objInfo = objInfo.GetPointedObject();
118  }
119 
120  _ASSERT(objInfo.GetTypeFamily() == eTypeFamilyClass);
121  TMemberIndex index = 1;
122  CObjectInfo type_oi = objInfo.GetClassMemberIterator(index).GetMember();
123 
124  if (type_oi.GetPrimitiveValueType() == ePrimitiveValueString) {
125  string sValue = type_oi.GetPrimitiveValueString();
126  if (NStr::EqualNocase(sValue, field_name)) {
127  CObjectInfo val_oi = objInfo.GetClassMemberIterator(++index).GetMember();
128  if (m_Nested == eNotNested) {
130  }
131  else {
134  }
135  m_Result->SetObjects().push_back(CMQueryNodeValue::SResolvedField(objInfo, val_oi));
136  }
137  }
138  }
139  else if (type_oi.GetPrimitiveValueType() == ePrimitiveValueEnum) {
140  string sValue;
141  try {
142  sValue = type_oi.GetPrimitiveValueString();
143  }
144  catch (const CException&) {
145  sValue = NStr::NumericToString(type_oi.GetPrimitiveValueInt4());
146  }
147  if (NStr::EqualNocase(sValue, field_name)) {
148  CObjectInfo val_oi = objInfo.GetClassMemberIterator(++index).GetMember();
149  if (m_Nested == eNotNested) {
151  }
152  else {
155  }
156  m_Result->SetObjects().push_back(CMQueryNodeValue::SResolvedField(objInfo, val_oi));
157  }
158  }
159  }
160  ++elem;
161  }
162 }
163 
165 {
166  _ASSERT(index < m_Args.size());
167  if (index < m_Args.size()) {
168  objects.clear();
169 
170  CMQueryNodeValue& objs = m_Args[index].GetNCObject();
171  objs.Dereference();
172  if (objs.GetDataType() != CMQueryNodeValue::eObjects) {
173  return;
174  }
175  objects = objs.GetObjects();
176  }
177 }
178 
179 void IEditMacroFunction::x_GetOptionalArgs(string& delimiter, bool& remove_field, size_t& index)
180 {
181  delimiter.clear();
182  remove_field = false;
183  if (++index < m_Args.size()) {
184  if (m_Args[index]->IsString()) {
185  delimiter = m_Args[index]->GetString();
186  }
187  else if (m_Args[index]->IsBool()) {
188  remove_field = m_Args[index]->GetBool();
189  }
190  }
191  if (++index < m_Args.size()) {
192  remove_field = m_Args[index]->GetBool();
193  }
194 }
195 
196 // IFunctionLog
197 IFunctionLog::IFunctionLog(const string& msg, size_t nr)
198 {
199  m_ChangedQuals[msg] = nr;
200 }
201 
203 {
204  bool merged = false;
205  for (const auto& other_it : log.m_ChangedQuals) {
206  if (auto it = m_ChangedQuals.find(other_it.first); it != m_ChangedQuals.end()) {
207  it->second += other_it.second;
208  merged = true;
209  }
210  else {
211  m_ChangedQuals[other_it.first] = other_it.second;
212  merged = true;
213  }
214  }
215  return merged;
216 }
217 
218 string CDiscrLog::x_Print() const
219 {
220  string msg;
221  for (const auto& rep_it : m_ChangedQuals) {
222  msg += NDiscrepancy::CDiscrepancySet::Format(rep_it.first, (unsigned)rep_it.second);
223  }
224  return msg;
225 }
226 
228 {
229  string msg;
230  for (const auto& it : m_ChangedQuals) {
231  msg += "Changed ";
232  msg += NStr::SizetToString(it.second);
233  msg += " fields during " + it.first + "\n";
234  }
235  msg.pop_back();
236  return msg;
237 }
238 
239 
241 {
242  if (oi.GetTypeFamily() == eTypeFamilyPrimitive) {
246  }
247  }
248  else if (oi.GetTypeFamily() == eTypeFamilyClass) {
249  if (oi.GetName() == "Dbtag") {
250  objects::CDbtag* dbtag = CTypeConverter<objects::CDbtag>::SafeCast(oi.GetObjectPtr());
251  string orig_value;
252  if (dbtag && dbtag->IsSetDb()) {
253  dbtag->GetLabel(&orig_value);
254  }
255  if (!NStr::EqualCase(orig_value, value)) {
256  string db, tag;
257  NStr::SplitInTwo(value, ":", db, tag);
259 
260  if (!db.empty() && !tag.empty()) {
261  dbtag->SetDb(db);
262  dbtag->ResetTag();
263  if (id != 0)
264  dbtag->SetTag().SetId(id);
265  else
266  dbtag->SetTag().SetStr(tag);
268  }
269  }
270  }
271  }
272  return (m_QualsChangedCount > 0);
273 }
274 
275 /// CMacroFunction_TopLevel
276 /// It is the same as CMacroRep::m_TopFuncName
278 void CMacroFunction_TopLevel::TheFunction()
279 {
280 }
281 
283 {
284  return true;
285 }
286 
287 
288 END_SCOPE(macro)
290 
291 /* @} */
Subclass of the IQueryParseUserObject which is held as the user-defined object in each CQueryParseNod...
Definition: macro_exec.hpp:71
class CMacroExecException
Definition: macro_ex.hpp:196
CObjectInfoEI –.
Definition: objectiter.hpp:125
CObjectInfo –.
Definition: objectinfo.hpp:597
definition of a Culling tree
Definition: ncbi_tree.hpp:100
Base class for any user function that performs editing operations on ASN.1 data.
IMacroBioDataIter - common interface of all iterators used in the editing macros The type of the iter...
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
char value[7]
Definition: config.c:431
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
void x_AssignReturnValueFromContainer(const CObjectInfo &oi, const string &container, const string &field_name)
bool SetQualStringValue(CObjectInfo &oi, const string &value)
Functions make the action and collect statistics.
ENestedFunc m_Nested
flag indicating whether the function is nested within another function
list< SResolvedField > TObs
Definition: macro_exec.hpp:92
void AssignFromObjectInfo(const CObjectInfo &objinfo)
Assigns data from objinfo. It is used when storing evaluation result.
Definition: macro_exec.cpp:111
void Dereference()
If it is a reference it is resolved to the first non reference type in the hierarchy.
Definition: macro_exec.cpp:94
const TObs & GetObjects() const
Definition: macro_exec.hpp:144
bool ResolveIdentToObjects(const CObjectInfo &oi, const string &identifier, CMQueryNodeValue &v)
Resolve name to the list of objects.
void SetDataType(EType dt)
Definition: macro_exec.hpp:121
virtual string x_Print() const
void x_AssignReturnValue(const CObjectInfo &oi, const string &field_name)
Assigns value to m_Result. It is mostly useful for functions used in the WHERE clause.
EType GetDataType() const
Definition: macro_exec.hpp:122
void x_GetOptionalArgs(string &delimiter, bool &remove_field, size_t &index)
Int4 m_QualsChangedCount
Number of changed qualifiers during the function call.
bool GetFieldsByName(CMQueryNodeValue::TObs *results, const CObjectInfo &oi_i, const string &field_name)
Resolve existing dot qualified ASN.1 name (field_name) starting from the object information instance ...
void x_GetObjectsFromRef(CMQueryNodeValue::TObs &objects, const size_t &index)
virtual void x_SetUserObjects(CQueryParseTree::TNode &qnode) override
Extracts the function arguments and initializes m_Result member.
CRef< CMQueryNodeValue > m_Result
TChangedQuals m_ChangedQuals
#define DEFINE_MACRO_FUNCNAME(CL_NAME, FN_NAME)
virtual string x_Print() const
string m_FuncName
Name of the function as it's been used in the script.
IFunctionLog(const TChangedQuals &quals)
void SetObjects(const TObs &obs)
Definition: macro_exec.hpp:131
virtual bool x_ValidArguments() const
Tests the number and the type of function arguments.
bool Merge(const IFunctionLog &log)
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:230
static const TObjectType * SafeCast(TTypeInfo type)
Definition: serialutil.hpp:76
@ ePrimitiveValueString
string|char*|const char*
Definition: serialdef.hpp:153
@ ePrimitiveValueEnum
enum
Definition: serialdef.hpp:154
@ eTypeFamilyClass
Definition: serialdef.hpp:140
@ eTypeFamilyContainer
Definition: serialdef.hpp:142
@ eTypeFamilyPointer
Definition: serialdef.hpp:143
@ eTypeFamilyPrimitive
Definition: serialdef.hpp:139
CElementIterator BeginElements(void) const
Create container elements iterator.
CObjectInfo GetPointedObject(void) const
Get data and type information of object to which this type refers.
Definition: objectinfo.cpp:102
CObjectInfo GetElement(void) const
Get element data and type information.
TObjectPtr GetObjectPtr(void) const
Get pointer to object.
void SetPrimitiveValueString(const string &value)
Definition: objectinfo.cpp:282
bool Valid(void) const
Is iterator valid.
CMemberIterator GetClassMemberIterator(TMemberIndex index) const
Create class member iterator that initially points to specified member.
ETypeFamily GetTypeFamily(void) const
Get data type family.
void GetPrimitiveValueString(string &value) const
Get string data.
Definition: objectinfo.cpp:199
Int4 GetPrimitiveValueInt4(void) const
Get data as Int4.
Definition: objectinfo.cpp:174
const string & GetName(void) const
Get type name.
Definition: objectinfo.hpp:106
EPrimitiveValueType GetPrimitiveValueType(void) const
Get type of primitive value.
Definition: objectinfo.cpp:109
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
TObjectType * GetPointerOrNull(void) THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:986
TObjectType & GetNCObject(void) const
Get object.
Definition: ncbiobj.hpp:1187
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
static string SizetToString(size_t value, TNumToStringFlags flags=0, int base=10)
Convert size_t to string.
Definition: ncbistr.cpp:2751
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static bool EqualCase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-sensitive equality of a substring with another string.
Definition: ncbistr.hpp:5324
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3550
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5352
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
@ fConvErr_NoThrow
Do not throw an exception on error.
Definition: ncbistr.hpp:285
TNodeList::iterator TNodeList_I
Definition: ncbi_tree.hpp:109
TNodeList_CI SubNodeBegin(void) const
Return first const iterator on subnode list.
Definition: ncbi_tree.hpp:160
TNodeList_CI SubNodeEnd(void) const
Return last const iterator on subnode list.
Definition: ncbi_tree.hpp:166
Macro engine for macro execution.
Macro exceptions.
Functions that resolve field names described in asn format.
const char * tag
Format
Definition: njn_ioutil.hpp:52
static const char delimiter[]
#define _ASSERT
Modified on Wed Dec 06 07:14:30 2023 by modify_doxy.py rev. 669887