Qore Programming Language  1.12.0
typed_hash_decl_private.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  typed_hash_decl_private.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2022 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_INTERN_TYPED_HASH_DECL_PRIVATE_H
33 
34 #define _QORE_INTERN_TYPED_HASH_DECL_PRIVATE_H
35 
36 #include "qore/intern/QoreClassIntern.h"
37 
38 #include <string>
39 
40 class typed_hash_decl_private;
41 
42 class HashDeclMemberInfo : public QoreMemberInfoBase {
43 public:
44  DLLLOCAL HashDeclMemberInfo(const QoreProgramLocation* loc, const QoreTypeInfo* n_typeInfo = nullptr,
45  QoreParseTypeInfo* n_parseTypeInfo = nullptr, QoreValue e = QoreValue())
46  : QoreMemberInfoBase(loc, n_typeInfo, n_parseTypeInfo, e) {
47  }
48 
49  DLLLOCAL HashDeclMemberInfo(const HashDeclMemberInfo& old) : QoreMemberInfoBase(old) {
50  }
51 
52  DLLLOCAL bool equal(const HashDeclMemberInfo& other) const;
53 
54  DLLLOCAL int parseInit(const char* name, bool priv);
55 };
56 
57 typedef QoreMemberMapBase<HashDeclMemberInfo> HashDeclMemberMap;
58 
59 class typed_hash_decl_private {
60 friend class typed_hash_decl_member_iterator;
61 friend class TypedHashDecl;
62 public:
63  DLLLOCAL typed_hash_decl_private(const QoreProgramLocation* loc) : loc(loc), orig(this) {
64  assignModule();
65  }
66 
67  DLLLOCAL typed_hash_decl_private(const QoreProgramLocation* loc, const char* n, const char* p,
68  TypedHashDecl* thd) :
69  loc(loc), name(n), path(p), thd(thd), orig(this),
70  typeInfo(new QoreHashDeclTypeInfo(thd, n, p)),
71  orNothingTypeInfo(new QoreHashDeclOrNothingTypeInfo(thd, n, p)) {
72  assignModule();
73  }
74 
75  DLLLOCAL typed_hash_decl_private(const typed_hash_decl_private& old, TypedHashDecl* thd);
76 
77  DLLLOCAL ~typed_hash_decl_private() {
78  delete typeInfo;
79  delete orNothingTypeInfo;
80  }
81 
82  DLLLOCAL TypedHashDecl* newTypedHashDecl(const char* n) {
83  assert(name.empty());
84  assert(!thd);
85  name = n;
86  path = get_ns_path(n);
87  thd = new TypedHashDecl(this);
88  return thd;
89  }
90 
91  DLLLOCAL bool equal(const typed_hash_decl_private& other) const {
92  if (name != other.name || members.size() != other.members.size())
93  return false;
94 
95  for (HashDeclMemberMap::const_iterator ti = members.member_list.begin(), oi = other.members.member_list.begin(),
96  te = members.member_list.end(); ti != te; ++ti, ++oi) {
97  // if the member's name is different, return false
98  if (strcmp(oi->first, ti->first)) {
99  return false;
100  }
101  // if the member's type is different, return false
102  if (!ti->second->equal(*oi->second)) {
103  return false;
104  }
105  }
106 
107  return true;
108  }
109 
110  DLLLOCAL bool parseEqual(const typed_hash_decl_private& other) const {
111  const_cast<typed_hash_decl_private*>(this)->parseInit();
112  return equal(other);
113  }
114 
115  DLLLOCAL const QoreTypeInfo* getTypeInfo(bool or_nothing = false) const {
116  return or_nothing ? orNothingTypeInfo : typeInfo;
117  }
118 
119  DLLLOCAL bool isPublic() const {
120  return pub;
121  }
122 
123  DLLLOCAL bool isUserPublic() const {
124  return pub && !sys;
125  }
126 
127  DLLLOCAL void setPublic() {
128  assert(!pub);
129  pub = true;
130  }
131 
132  DLLLOCAL void setPrivate() {
133  assert(pub);
134  pub = false;
135  }
136 
137  DLLLOCAL bool isSystem() const {
138  return sys;
139  }
140 
141  DLLLOCAL void ref() const {
142  refs.ROreference();
143  }
144 
145  DLLLOCAL bool deref() {
146  if (refs.ROdereference()) {
147  delete thd;
148  return true;
149  }
150  return false;
151  }
152 
153  DLLLOCAL int parseInit() {
154  if (parse_init_done || sys) {
155  return 0;
156  }
157  parse_init_done = true;
158 
159  int err = 0;
160 
161  // initialize new members
162  for (auto& i : members.member_list) {
163  if (i.second) {
164  if (i.second->parseInit(i.first, true) && !err) {
165  err = -1;
166  }
167  }
168  // check new members for conflicts in base hashdecls
169  //parseCheckMemberInBaseHashDecl(i.first, i.second);
170  }
171  return err;
172  }
173 
174  DLLLOCAL int parseInitHashDeclInitialization(const QoreProgramLocation* loc, QoreParseContext& parse_context,
175  QoreParseListNode* args, bool& runtime_check) const;
176 
177  DLLLOCAL int parseCheckHashDeclInitialization(const QoreProgramLocation* loc, const QoreTypeInfo* expTypeInfo,
178  QoreValue exp, const char* context_action, bool& runtime_check, bool strict_check = true) const;
179 
180  DLLLOCAL int parseCheckHashDeclAssignment(const QoreProgramLocation* loc, const typed_hash_decl_private& hd,
181  const char* context, bool& needs_runtime_check, bool strict_check = true) const;
182 
183  DLLLOCAL int parseCheckHashDeclAssignment(const QoreProgramLocation* loc, QoreValue n, const char* context,
184  bool& needs_runtime_check, bool strict_check = true) const;
185 
186  DLLLOCAL int parseCheckComplexHashAssignment(const QoreProgramLocation* loc, const QoreTypeInfo* vti) const;
187 
188  DLLLOCAL QoreHashNode* newHash(const QoreParseListNode* args, bool runtime_check, ExceptionSink* xsink) const;
189 
190  DLLLOCAL QoreHashNode* newHash(const QoreHashNode* init, bool runtime_check, ExceptionSink* xsink) const;
191 
192  DLLLOCAL int initHash(QoreHashNode* h, const QoreHashNode* init, ExceptionSink* xsink) const;
193 
194  DLLLOCAL int runtimeAssignKey(const char* key, ValueHolder& val, ExceptionSink* xsink) const {
195  const HashDeclMemberInfo* mem = members.find(key);
196  if (!mem) {
197  xsink->raiseException("HASHDECL-KEY-ERROR", "cannot assign unknown key '%s' to hashdecl '%s'", key, name.c_str());
198  return -1;
199  }
200  QoreTypeInfo::acceptInputKey(mem->getTypeInfo(), key, *val, xsink);
201  if (*xsink) {
202  xsink->appendLastDescription(" (while assigning to hashdecl '%s')", name.c_str());
203  return -1;
204  }
205  return 0;
206  }
207 
208  DLLLOCAL int parseCheckMemberAccess(const QoreProgramLocation* loc, const char* mem,
209  const QoreTypeInfo*& memberTypeInfo, int pflag) const;
210 
211  DLLLOCAL const HashDeclMemberInfo* findMember(const char* m) const {
212  return members.find(m);
213  }
214 
215  DLLLOCAL void parseAdd(std::pair<char*, HashDeclMemberInfo*> pair) {
216  members.addNoCheck(pair);
217  }
218 
219  DLLLOCAL bool hasMember(const char* name) const {
220  return members.inList(name);
221  }
222 
223  DLLLOCAL void setSystemPublic() {
224  assert(!sys);
225  assert(!pub);
226  sys = true;
227  pub = true;
228  }
229 
230  DLLLOCAL const char* getName() const {
231  return name.c_str();
232  }
233 
234  DLLLOCAL const char* getPath() const {
235  return path.c_str();
236  }
237 
238  DLLLOCAL const std::string& getNameStr() const {
239  return name;
240  }
241 
242  DLLLOCAL const QoreProgramLocation* getParseLocation() const {
243  return loc;
244  }
245 
246  DLLLOCAL static typed_hash_decl_private* get(TypedHashDecl& hashdecl) {
247  return hashdecl.priv;
248  }
249 
250  DLLLOCAL static const typed_hash_decl_private* get(const TypedHashDecl& hashdecl) {
251  return hashdecl.priv;
252  }
253 
254  DLLLOCAL void addMember(const char* name, const QoreTypeInfo* memberTypeInfo, QoreValue init_val) {
255  assert(!members.find(name));
256  members.addNoCheck(std::make_pair(strdup(name), new HashDeclMemberInfo(&loc_builtin, memberTypeInfo, nullptr, init_val)));
257  }
258 
259  DLLLOCAL void setName(const char* n) {
260  name = n;
261  }
262 
263  DLLLOCAL const HashDeclMemberMap& getMembers() const {
264  return members;
265  }
266 
267  DLLLOCAL const HashDeclMemberInfo* findLocalMember(const char* name) const {
268  return members.find(name);
269  }
270 
271  DLLLOCAL void setNamespace(qore_ns_private* n) {
272  ns = n;
273  }
274 
275  DLLLOCAL const qore_ns_private* getNamespace() const {
276  return ns;
277  }
278 
279  DLLLOCAL const char* getModuleName() const {
280  return from_module.empty() ? nullptr : from_module.c_str();
281  }
282 
283 protected:
284  // references
285  mutable QoreReferenceCounter refs;
286  const QoreProgramLocation* loc;
287  std::string name;
288  std::string path;
289  TypedHashDecl* thd = nullptr;
290  // parent namespace
291  qore_ns_private* ns = nullptr;
292  // the module that defined this class, if any
293  std::string from_module;
294 
295  // original declaration
296  const typed_hash_decl_private* orig;
297 
298  // type information
299  QoreHashDeclTypeInfo* typeInfo = nullptr;
300  QoreHashDeclOrNothingTypeInfo* orNothingTypeInfo = nullptr;
301 
302  // member information
303  HashDeclMemberMap members;
304 
305  bool pub = false;
306  bool sys = false;
307 
308  bool parse_init_done = false;
309 
310  DLLLOCAL void assignModule() {
311  const char* mod_name = get_module_context_name();
312  if (mod_name) {
313  from_module = mod_name;
314  }
315  }
316 
317  DLLLOCAL int initHashIntern(QoreHashNode* h, const QoreHashNode* init, ExceptionSink* xsink) const;
318 };
319 
320 #endif
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition: QoreHashNode.h:50
provides atomic reference counting to Qore objects
Definition: QoreReferenceCounter.h:44
typed hash declaration
Definition: TypedHashDecl.h:44
DLLEXPORT const char * getName() const
returns the name of the typed hash
DLLEXPORT const char * getModuleName() const
Returns the module name the class was loaded from or nullptr if it is a builtin class.
DLLEXPORT bool equal(const TypedHashDecl *other) const
returns true if the hashdecl passed as an arugment is equal to this hashdecl
DLLEXPORT const QoreTypeInfo * getTypeInfo(bool or_nothing=false) const
returns the type info object for the hashdecl
DLLEXPORT const QoreExternalMemberBase * findLocalMember(const char *name) const
Finds the given local member or returns nullptr.
DLLEXPORT bool isPublic() const
returns true if the typed hash has the public (export) flag set
DLLEXPORT const QoreNamespace * getNamespace() const
Returns the namespace owning the typed hash declaration.
DLLEXPORT void addMember(const char *name, const QoreTypeInfo *memberTypeInfo, QoreValue init_val)
adds an element to a built-in hashdecl
DLLEXPORT bool isSystem() const
returns true if the typed hash is a builtin typed hash
holds an object and dereferences it in the destructor
Definition: QoreValue.h:476
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275