RelationClass.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel RelationClass.c */
40 /* */
41 /* Primitive Table Class */
42 /* */
43 /******************************************************************************/
44 #include "RexxCore.h"
45 #include "IntegerClass.hpp"
46 #include "ArrayClass.hpp"
47 #include "RelationClass.hpp"
48 #include "SupplierClass.hpp"
49 #include "ProtectedObject.hpp"
50 
51 // singleton class instance
53 
54 
55 /**
56  * Create initial class object at bootstrap time.
57  */
59 {
60  CLASS_CREATE(Relation, "Relation", RexxClass);
61 }
62 
63 
65  RexxObject *_value, /* value part of the tuple */
66  RexxObject *_index) /* item to remove */
67 /******************************************************************************/
68 /* Function: Remove an item from a relation using an index */
69 /******************************************************************************/
70 {
71  return this->contents->removeItem(_value, _index);
72 }
73 
75  RexxObject *_index ) /* optional index */
76 /******************************************************************************/
77 /* Function: Create a supplier for a relation */
78 /******************************************************************************/
79 {
80  RexxArray *itemArray; /* array of returned items */
81  RexxArray *indexArray; /* array of indexes */
82  size_t i; /* loop counter */
83  size_t size; /* size of the array */
84 
85  if (_index == OREF_NULL) /* no index given? */
86  {
87  /* return the entire supplier */
88  return this->contents->supplier();
89  }
90  else
91  { /* partial supplier */
92  /* get all of the items with index */
93  itemArray = this->contents->getAll(_index);
94  size = itemArray->size(); /* get the array size */
95  indexArray = new_array(size); /* get an index array */
96  for (i = 1; i <= size; i++) /* loop through the index array */
97  {
98  /* insert the same index here */
99  indexArray->put(_index, i);
100  }
101  /* turn this into a supplier */
102  return(RexxSupplier *)new_supplier(itemArray, indexArray);
103  }
104 }
105 
107  RexxObject *_index ) /* optional target index */
108 /******************************************************************************/
109 /* Function: Return the count of items associated with the given index, or */
110 /* the entire collection if the index is omitted. */
111 /******************************************************************************/
112 {
113  if (_index == OREF_NULL)
114  { /* no index given? */
115  /* return count for everything */
116  return new_integer(contents->totalEntries());
117  }
118  else
119  {
120  // just search and count
121  return new_integer(contents->countAll(_index));
122  }
123 }
124 
126  RexxObject *_value, /* value part of the tuple */
127  RexxObject *_index) /* item to remove */
128 /******************************************************************************/
129 /* Function: Remove an item from a relation using an index */
130 /******************************************************************************/
131 {
132  RexxObject *item; /* removed item */
133 
134  requiredArgument(_value, OREF_positional, ARG_ONE); /* make sure we have a value */
135 
136  // standard remove form?
137  if (_index == OREF_NULL)
138  {
139  item = this->contents->removeItem(_value);
140  }
141  else // multi-item form
142  {
143  item = this->contents->removeItem(_value, _index);
144  }
145  if (item == OREF_NULL) /* If nothing found, give back .nil */
146  {
147  item = TheNilObject; /* (never return OREF_NULL to REXX) */
148  }
149  return item; /* return removed value */
150 }
151 
153  RexxObject *_value, /* value part of the tuple */
154  RexxObject *_index) /* item to remove */
155 /******************************************************************************/
156 /* Function: Remove an item from a relation using an index */
157 /******************************************************************************/
158 {
159  requiredArgument(_value, OREF_positional, ARG_ONE); /* make sure we have a value */
160  if (_index == OREF_NULL) // just an item search
161  {
162  return this->contents->hasItem(_value);
163  }
164  else // tuple search
165  {
166  return this->contents->hasItem(_value, _index);
167  }
168 }
169 
171  RexxObject *_value) /* value to get */
172 /******************************************************************************/
173 /* Function: return all indices with the same value */
174 /******************************************************************************/
175 {
176  requiredArgument(_value, OREF_positional, ARG_ONE); /* make sure we have a value */
177  /* just get from the hash table */
178  return this->contents->allIndex(_value);
179 }
180 
182  RexxObject *_index) /* index to get */
183 /******************************************************************************/
184 /* Function: return all values with the same index */
185 /******************************************************************************/
186 {
187  requiredArgument(_index, OREF_positional, ARG_ONE); /* make sure we have an index */
188  /* just get from the hash table */
189  return this->contents->allIndex(_index);
190 }
191 
192 
193 /**
194  * Remove all items with a given index.
195  *
196  * @param _index The index to remove.
197  *
198  * @return An array of all removed items. Returns an empty array
199  * if the index is not found.
200  */
202 {
203  requiredArgument(_index, OREF_positional, ARG_ONE); /* make sure we have an index */
204  /* just get from the hash table */
205  return this->contents->removeAll(_index);
206 }
207 
208 
210  RexxObject *_value, /* new value to add */
211  RexxObject *_index) /* index for insertion */
212 /******************************************************************************/
213 /* Arguments: Value, index */
214 /* */
215 /* Returned: Nothing */
216 /******************************************************************************/
217 {
218  requiredArgument(_value, OREF_positional, ARG_ONE); /* make sure we have an value */
219  requiredArgument(_index, OREF_positional, ARG_TWO); /* make sure we have an index */
220  /* try to place in existing hashtab */
221  RexxHashTable *newHash = this->contents->add(_value, _index);
222  if (newHash != OREF_NULL) /* have a reallocation occur? */
223  {
224  /* hook on the new hash table */
225  OrefSet(this, this->contents, newHash);
226  }
227  return OREF_NULL; /* never returns anything */
228 }
229 
231  RexxObject **init_args, /* subclass init arguments */
232  size_t argCount, /* the number of arguments */
233  size_t named_argCount)
234 /******************************************************************************/
235 /* Function: Create an instance of a relation */
236 /******************************************************************************/
237 {
238  // this method is defined on the object class, but this is actually attached
239  // to a class object instance. Therefore, any use of the this pointer
240  // will be touching the wrong data. Use the classThis pointer for calling
241  // any methods on this object from this method.
242  RexxClass *classThis = (RexxClass *)this;
243  classThis->checkAbstract(); // ooRexx5
244 
245  RexxRelation *newObj = new_relation(); /* get a new relation */
246  ProtectedObject p(newObj);
247  /* object parse_assignment behaviour */
248  newObj->setBehaviour(classThis->getInstanceBehaviour());
249 
250  // jlf: was missing, ok to add it?
251  if (classThis->hasUninitDefined())
252  {
253  newObj->hasUninit();
254  }
255 
256  /* Initialize the new list instance */
257  newObj->sendMessage(OREF_INIT, init_args, argCount, named_argCount);
258  return newObj; /* return the new object */
259 }
260 
262 /******************************************************************************/
263 /* Function: Create a new relation item */
264 /******************************************************************************/
265 {
266  /* Get new object */
267  /* get a new object and hash */
269 }
270 
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
@ T_Relation
RexxInteger * new_integer(wholenumber_t v)
RexxRelation * new_relation()
#define OREF_NULL
Definition: RexxCore.h:61
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
const int ARG_TWO
Definition: RexxCore.h:84
#define TheNilObject
Definition: RexxCore.h:191
const int ARG_ONE
Definition: RexxCore.h:83
void requiredArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:303
RexxTable * new_hashCollection(size_t s, size_t s2, size_t t)
#define CLASS_CREATE(name, id, className)
Definition: RexxMemory.hpp:503
RexxSupplier * new_supplier(RexxArray *c, RexxArray *f)
void put(RexxObject *eref, size_t pos)
Definition: ArrayClass.cpp:208
size_t size()
Definition: ArrayClass.hpp:202
void checkAbstract()
RexxBehaviour * getInstanceBehaviour()
Definition: ClassClass.hpp:135
bool hasUninitDefined()
Definition: ClassClass.hpp:125
RexxHashTable * contents
RexxSupplier * supplier()
RexxSupplier * supplier()
size_t countAll(RexxObject *key)
RexxHashTable * add(RexxObject *value, RexxObject *key)
RexxArray * getAll(RexxObject *key)
RexxObject * hasItem(RexxObject *value, RexxObject *key)
RexxObject * removeItem(RexxObject *value, RexxObject *key)
RexxObject * removeAll(RexxObject *key)
size_t totalEntries()
RexxArray * allIndex(RexxObject *key)
void setBehaviour(RexxBehaviour *b)
void sendMessage(RexxString *, RexxArray *, RexxDirectory *, ProtectedObject &)
RexxObject * hasItem(RexxObject *, RexxObject *)
static RexxClass * classInstance
static void createInstance()
RexxObject * removeItemRexx(RexxObject *, RexxObject *)
RexxObject * removeAll(RexxObject *)
RexxObject * put(RexxObject *, RexxObject *)
RexxObject * allAt(RexxObject *)
RexxObject * allIndex(RexxObject *)
static RexxRelation * newInstance()
RexxObject * removeItem(RexxObject *, RexxObject *)
RexxObject * newRexx(RexxObject **, size_t, size_t)
RexxObject * itemsRexx()
Definition: TableClass.cpp:147