ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

ArrayClass.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 */
40 /* */
41 /* Primitive Array Class */
42 /* */
43 /* */
44 /* This Array class functions in two ways. One as an auto-extending array */
45 /* and as a static array. The static methods are used inside the kernel */
46 /* since we always know the exact size of the array we want and will place */
47 /* those elements into the array, so the static sized methods are optimized. */
48 /* */
49 /* The auto-extending methods are for the OREXX level behaviour. They */
50 /* may also be used inside the kernel if that behaviour is required. */
51 /* */
52 /* Any of the methods can be used on an array. The behaviour of an array */
53 /* depends on the methods used on the array, since there is only one type */
54 /* of array object, and its data is the same irreguardless of the methods */
55 /* used on it. */
56 /* */
57 /* Object creation functions: */
58 /* new_array(s) - Create an array of size s, initial size of array is */
59 /* set to s. This array will be used as a static array */
60 /* new_array(a1) - Create array of size 1 and put a1 in it. */
61 /* same as an array~of(a1) */
62 /* new_array(a1,a2) - Create array of size 2 and put a1 and a2 in it */
63 /* same as an array~of(a1,a2) */
64 /* new_array(a1, a2, a3) Same as new_array2 but 3 elements. */
65 /* new_array(a1, a2, a3, a4) " " " " 4 " */
66 /* */
67 /* */
68 /******************************************************************************/
69 #include <stdlib.h>
70 #include "RexxCore.h"
71 #include "RexxActivity.hpp"
72 #include "IntegerClass.hpp"
73 #include "SupplierClass.hpp"
74 #include "ArrayClass.hpp"
75 #include "MutableBufferClass.hpp"
76 #include "ActivityManager.hpp"
77 #include "ProtectedObject.hpp"
78 
79 #include <deque>
80 
81 
82 // singleton class instance
85 
87 const size_t RexxArray::ARRAY_MIN_SIZE = 4;
88 const size_t RexxArray::ARRAY_DEFAULT_SIZE = 10; // we use a larger default for ooRexx allocated arrays
89 
94 {
95  CLASS_CREATE(Array, "Array", RexxClass);
96  nullArray = new_array((size_t)0); /* set up a null array */
97 }
98 
99 
106 void RexxArray::init(size_t _size, size_t maxSize)
107 {
108  this->arraySize = _size;
109  this->maximumSize = maxSize;
110  this->lastElement = 0; // no elements set yet
111  /* no expansion yet, use ourself */
112  OrefSet(this, this->expansionArray, this);
113 }
114 
121 /******************************************************************************/
122 /* Function: create a copy of array and expansion array. */
123 /******************************************************************************/
124 {
125  /* make a copy of ourself */
126  RexxArray *newArray = (RexxArray *) this->RexxObject::copy();
127  /* this array contain the data? */
128  if (this->expansionArray != OREF_NULL && this->expansionArray != this)
129  {
130  /* no, make sure we get a copy of */
131  /* array containing data. */
132  newArray->setExpansion(this->expansionArray->copy());
133  }
134  else
135  {
136  /* no, make sure we get a copy of */
137  /* array containing data. */
138  newArray->setExpansion(newArray); /* make sure we point to ourself! */
139  }
140  return(RexxObject *)newArray; /* return the new array */
141 }
142 
143 void RexxArray::live(size_t liveMark)
144 /******************************************************************************/
145 /* Function: Normal garbage collection live marking */
146 /******************************************************************************/
147 {
148  RexxObject **arrayPtr;
149  RexxObject **endPtr;
150 
151  memory_mark(this->dimensions);
152  memory_mark(this->objectVariables);
153  /* mark expanded array */
155  for (arrayPtr = this->objects, endPtr = arrayPtr + this->arraySize; arrayPtr < endPtr; arrayPtr++)
156  {
157  memory_mark(*arrayPtr);
158  }
159 }
160 
161 void RexxArray::liveGeneral(int reason)
162 /******************************************************************************/
163 /* Function: Generalized object marking */
164 /******************************************************************************/
165 {
167  memory_mark_general(this->objectVariables);
169 
170  for (RexxObject **arrayPtr = this->objects; arrayPtr < this->objects + this->arraySize; arrayPtr++)
171  {
172  memory_mark_general(*arrayPtr);
173  }
174 }
175 
177 /******************************************************************************/
178 /* Function: Flatten an object */
179 /******************************************************************************/
180 {
182 
183  flatten_reference(newThis->dimensions, envelope);
184  flatten_reference(newThis->objectVariables, envelope);
185  flatten_reference(newThis->expansionArray, envelope);
186  for (size_t i = 0; i < this->arraySize; i++)
187  {
188  flatten_reference(newThis->objects[i], envelope);
189  }
190 
192 }
193 
194 
203 void RexxArray::put(RexxObject * eref, size_t pos)
204 {
205  OrefSet(this->expansionArray, (this->data())[pos - 1], eref);
206  // check the last set element
207  if (pos > lastElement)
208  {
209  lastElement = pos;
210  }
211 }
212 
222 RexxObject *RexxArray::putRexx(RexxObject **arguments, size_t argCount)
223 {
224  size_t position; /* array position */
225 
226  RexxObject *value = arguments[0]; /* get the value to assign */
227  /* no real value? */
228  if (argCount == 0 || value == OREF_NULL)
229  {
230  /* this is an error */
231  missingArgument(ARG_ONE); /* this is an error */
232  }
233  /* go validate the index */
234  /* have array expanded if necessary */
235  this->validateIndex(arguments + 1, argCount - 1, 2, RaiseBoundsInvalid | ExtendUpper | RaiseBoundsTooMany, position);
236 
237  this->put(value, position); /* set the new value */
238  return OREF_NULL; /* Make sure RESULT gets dropped */
239 }
240 
241 
248 {
249  requiredArgument(value, ARG_ONE);
250  // sigh, we have to use OrefSet
251  for (size_t i = 0; i < this->size(); i++)
252  {
253 
254  OrefSet(this, this->objects[i], value);
255  }
256  // the last element is now the size one
257  lastElement = size();
258  return OREF_NULL; // no real return value
259 }
260 
261 
268 {
269  // if not working with an oldspace object (VERY likely), we can just use memset to clear
270  // everything.
271  if (this->isNewSpace())
272  {
273  memset(this->data(), '\0', sizeof(RexxObject *) * this->size());
274  }
275  else
276  {
277  // sigh, we have to use OrefSet
278  for (size_t i = 0; i < this->size(); i++)
279  {
280 
281  OrefSet(this, this->objects[i], OREF_NULL);
282  }
283  }
284  // no element set yet
285  lastElement = 0;
286  return OREF_NULL; // no real return value
287 }
288 
289 
296 {
297  return (items() == 0) ? TheTrueObject : TheFalseObject;
298 }
299 
300 
309 {
310  requiredArgument(value, ARG_ONE);
311 
312  // this is not intended for multi-dimensional arrays since they can't expand
313  if (isMultiDimensional())
314  {
316  }
317 
318  size_t newIndex = lastElement + 1;
319 
320  ensureSpace(newIndex);
321  put(value, newIndex);
322  return new_integer(newIndex);
323 }
324 
325 
339 {
340  /* multidimensional array? */
341  if (isMultiDimensional())
342  {
343  /* this is an error */
345  }
346 
347  size_t position; // array position
348 
349  if (index == TheNilObject)
350  {
351  position = 1; // the insertion point of the item is 1
352  }
353  else if (index == OREF_NULL)
354  {
355  position = size() + 1; // inserting after the last item
356  }
357  else
358  {
359  // validate the index and expand if necessary.
360  this->validateIndex(&index, 1, 2, RaiseBoundsInvalid | RaiseBoundsTooMany, position);
361  position = position + 1; // we insert AFTER the given index, so bump this
362  }
363 
364  // do the actual insertion
365  return new_integer(insert(_value, position));
366 }
367 
368 
380 {
381  /* multidimensional array? */
382  if (isMultiDimensional())
383  {
384  /* this is an error */
386  }
387 
388  size_t position; // array position
389 
390  // validate the index and expand if necessary.
391  this->validateIndex(&index, 1, 1, RaiseBoundsInvalid | RaiseBoundsTooMany, position);
392 
393  // do the actual insertion
394  return deleteItem(position);
395 }
396 
397 
406 void RexxArray::openGap(size_t index, size_t elements)
407 {
408  // is this larger than our current size? If so, we have nothing to move
409  // but do need to expand the array size to accommodate the additional members
410  if (index > size())
411  {
412  ensureSpace(index + elements - 1);
413  }
414  else {
415  // the last element to move. NOTE: we check this BEFORE
416  // expanding the size, otherwise we move too many elements.
417  char *_end = (char *)slotAddress(this->size() + 1);
418 
419  // make sure we have space for the additional elements
420  ensureSpace(size() + elements);
421  /* get the address of first element */
422  char *_start = (char *)slotAddress(index);
423  char *_target = (char *)slotAddress(index + elements);
424  /* shift the array over */
425  memmove(_target, _start, _end - _start);
426 
427  // now null out all of the slots in the gap, using an
428  // explicit assignment rather than put to avoid old-to-new
429  // tracking issues
430  for (size_t i = index - 1; i < index + elements - 1; i++)
431  {
432  this->data()[i] = OREF_NULL;
433  }
434  lastElement += elements; // the position of the last element has now moved.
435  }
436 }
437 
444 void RexxArray::closeGap(size_t index, size_t elements)
445 {
446  // if we're beyond the current size, nothing to do
447  if (index > size())
448  {
449  return;
450  }
451 
452  // cap the number of elements we're shifting.
453  elements = Numerics::minVal(elements, lastElement - index + 1);
454 
455  // explicitly null out the slots of the gap we're closing to
456  // ensure that any oldspace tracking issues are resolved. This
457  // explicitly uses put() to make sure this is done.
458  for (size_t i = index; i < index + elements; i++)
459  {
460  put(OREF_NULL, i);
461  }
462  /* get the address of first element */
463  char *_target = (char *)slotAddress(index);
464  char *_start = (char *)slotAddress(index + elements);
465  // and the end location of the real data
466  char *_end = (char *)slotAddress(lastElement + 1);
467  /* shift the array over */
468  memmove(_target, _start, _end - _start);
469  // adjust the last element position
470  lastElement -= elements;
471  shrink(elements); // adjust the size downward
472 }
473 
474 
483 {
484  size_t newIndex = lastElement + 1;
485 
486  ensureSpace(newIndex);
487  put(value, newIndex);
488  return newIndex;
489 }
490 
491 
492 
503 RexxObject *RexxArray::getRexx(RexxObject **arguments, size_t argCount)
504 {
505  size_t position; /* array position */
506  RexxObject * _result; /* returned result */
507 
508  /* go validate the index */
509  if (!this->validateIndex(arguments, argCount, 1, RaiseBoundsTooMany | RaiseBoundsInvalid, position))
510  {
511  _result = TheNilObject; /* just return .nil */
512  }
513  else
514  { /* return that element */
515  _result = *(this->data() + position - 1);
516  if (_result == OREF_NULL) /* no object there? */
517  {
518  _result = TheNilObject; /* just return .nil */
519  }
520  }
521  return _result; /* return the result */
522 }
523 
524 
533 RexxObject *RexxArray::getApi(size_t position)
534 {
535  /* out of bounds? */
536  if (position > this->size())
537  {
538  return OREF_NULL;
539  }
540  return get(position);
541 }
542 
543 
551 void RexxArray::putApi(RexxObject *o, size_t position)
552 {
553  /* out of bounds? */
554  if (position > this->size())
555  {
556  if (position >= MAX_FIXEDARRAY_SIZE)
557  {
559  }
560  this->extend(position - this->size());
561  }
562  put(o, position);
563 }
564 
565 
574 /******************************************************************************/
575 /* Function: Determine if an element exist for a position */
576 /******************************************************************************/
577 {
578  /* in bounds and here? */
579  if (i > 0 && i <= this->size() && *(this->data()+i-1) != OREF_NULL)
580  {
581  return true; /* this is true */
582  }
583  else
584  {
585  return false; /* nope, don't have it */
586  }
587 }
588 
589 
591 /******************************************************************************/
592 /* Function: Remove an item from the array */
593 /******************************************************************************/
594 {
595  RexxObject *result; /* removed object */
596 
597  /* within the bounds? */
598  if (_index > 0 && _index <= this->size() && *(this->data() + _index - 1) != OREF_NULL)
599  {
600  /* get the item */
601  result = *(this->data() + _index - 1);
602  /* clear it out */
603  OrefSet(this->expansionArray, *(this->data() + _index - 1), OREF_NULL);
604  // if we removed the last element, we need to scan backwards to find
605  // the last one
606  if (_index == lastElement)
607  {
608  // back off at least one position, then scan for the new last one
609  lastElement--;
610  while (lastElement != 0 && *(this->data() + lastElement - 1) == OREF_NULL)
611  {
612  lastElement--;
613  }
614  }
615  return result; /* and return */
616  }
617  else
618  {
619  return OREF_NULL; /* return nothing */
620  }
621 }
622 
623 RexxObject *RexxArray::removeRexx(RexxObject **arguments, size_t argCount)
624 /******************************************************************************/
625 /* Function: Remove an item from the array and return the item. .nil */
626 /* is returned if the item does not exist */
627 /******************************************************************************/
628 {
629  RexxObject *result; /* returned result */
630  size_t position; /* array position */
631 
632  /* go validate the index */
633  if (!this->validateIndex(arguments, argCount, 1, RaiseBoundsTooMany | RaiseBoundsInvalid, position))
634  {
635  result = TheNilObject; /* yup, return .nil. */
636  }
637  else
638  {
639  /* get the current element */
640  result = *(this->data() + position - 1);
641  /* remove the item from the array */
642  OrefSet(this->expansionArray, *(this->data() + position - 1), OREF_NULL);
643  if (position == lastElement)
644  {
645  // back off at least one position, then scan for the new last one
646  lastElement--;
647  while (lastElement != 0 && *(this->data() + lastElement - 1) == OREF_NULL)
648  {
649  lastElement--;
650  }
651  }
652  if (result == OREF_NULL) /* no existing value? */
653  {
654  result = TheNilObject; /* return .nil instead */
655  }
656  }
657  return result; /* return this value */
658 }
659 
661 /******************************************************************************/
662 /* Function: Return count of actual items in an array */
663 /******************************************************************************/
664 {
665  size_t count; /* actual count of items in array */
666  RexxArray *realArray; /* array item pointer */
667 
668  count = 0; /* no items yet */
669  realArray = this->expansionArray; /* Get array with data */
670  /* loop through all array items */
671  for (size_t i = 0; i < realArray->arraySize; i++)
672  {
673  /* have a real item here? */
674  if (realArray->objects[i] != OREF_NULL)
675  {
676  count++; /* bump the item counter */
677  }
678  }
679  return count; /* return the count object */
680 }
681 
683 /******************************************************************************/
684 /* Function: Return count of actual items in an array */
685 /******************************************************************************/
686 {
687  return new_integer(items());
688 }
689 
691 /******************************************************************************/
692 /* Function: Query array dimension information */
693 /******************************************************************************/
694 {
695  if (this->dimensions == OREF_NULL) /* no dimensions array? */
696  {
697  return 1; /* one dimension array */
698  }
699  else
700  {
701  return this->dimensions->size(); /* return size of dimensions array */
702  }
703 }
704 
712 {
713  // if it is a single dimension array, return an array with the size
714  // as a single item
715  if (isSingleDimensional())
716  {
717  return new_array(new_integer(this->size()));
718  }
719  else
720  {
721  // return a copy of the dimensions array
722  return this->dimensions->copy();
723  }
724 }
725 
726 RexxObject *RexxArray::dimension( /* query dimensions of an array */
727  RexxObject *target) /* dimension to query */
728 /******************************************************************************/
729 /* Function: Query array dimension information */
730 /******************************************************************************/
731 {
732  if (target == OREF_NULL)
733  { /* non-specific query? */
734  if (this->dimensions == OREF_NULL)
735  {
736  if (this->size() == 0)
737  {
738  /* unknown dimension */
739  return IntegerZero;
740  }
741  else
742  {
743  /* one dimension array */
744  return IntegerOne;
745  }
746  }
747  else
748  { /* return size of dimensions array */
749  return new_integer(this->dimensions->size());
750  }
751  }
752  else
753  {
754  /* convert to a number */
755  size_t position = target->requiredPositive(ARG_ONE);
756  /* asking for dimension of single? */
757  if (isSingleDimensional())
758  {
759  if (position == 1)
760  { /* first dimension? */
761  /* just give back the size */
762  return new_integer(this->size());
763  }
764  else
765  {
766  /* no size in this dimension */
767  return IntegerZero;
768  }
769  }
770  /* out of range? */
771  else if (position > this->dimensions->size())
772  {
773  /* no size in this dimension */
774  return IntegerZero;
775  }
776  else /* return the specific dimension */
777  {
778  return this->dimensions->get(position);
779  }
780  }
781 }
782 
784 /******************************************************************************/
785 /* Function: create a supplier for this array */
786 /******************************************************************************/
787 {
788  size_t slotCount = this->size(); /* get the array size */
789  size_t itemCount = this->items(); /* and the actual count in the array */
790 
791  RexxArray *values = new_array(itemCount); /* get the values array */
792  RexxArray *indexes = new_array(itemCount); /* and an index array */
793 
794  ProtectedObject v(values);
795  ProtectedObject s(indexes);
796 
797  size_t count = 1; /* next place to add */
798  for (size_t i = 1; i <= slotCount; i++)
799  { /* loop through the array */
800  RexxObject *item = this->get(i); /* get the next item */
801  if (item != OREF_NULL)
802  { /* got an item here */
803  values->put(item, count); /* copy over to the values array */
804 
805  /* add the index location */
806  indexes->put((RexxObject*)convertIndex(i), count);
807  count++; /* step the location */
808  }
809  }
810 
811  return new_supplier(values, indexes);
812 }
813 
814 
816 /******************************************************************************/
817 /* Function: Set a new expansion array item */
818 /******************************************************************************/
819 {
820  OrefSet(this, this->expansionArray, (RexxArray *)expansion);
821 }
822 
824 /******************************************************************************/
825 /* Function: Determine if a position element is "out-of-bounds" */
826 /******************************************************************************/
827 {
828  return (RexxInteger *) ((position < this->size()) ? TheTrueObject : TheFalseObject);
829 }
830 
831 
832 bool RexxArray::validateIndex( /* validate an array index */
833  RexxObject **_index, /* array index (possibly multi-dim) */
834  size_t indexCount, /* size of the index array */
835  size_t _start, /* starting point on the array */
836  size_t bounds_error, /* raise errors on out-of-bounds */
837  stringsize_t &position) // returned position
838 /******************************************************************************/
839 /* Function: Process and validate a potentially multi-dimensional array */
840 /* index. If the index is out of bounds in any dimension it will */
841 /* either return false or raise an error, depending on the bounds */
842 /* checking parameter. */
843 /******************************************************************************/
844 {
845  RexxObject *value; /* individual index value */
846  size_t numsubs; /* number of subscripts */
847  size_t i; /* loop counter */
848  size_t multiplier; /* accumlation factor */
849  size_t offset; /* accumulated offset */
850  size_t _dimension; /* current working dimension */
851  size_t numSize; /* temporary long variable */
852 
853 
854  // do we really have a single index item given as an array?
855  if (indexCount == 1 && _index[0] != OREF_NULL && isOfClass(Array, _index[0]))
856  {
857  // we process this exactly the same way, but swap the count and
858  // pointers around to be the array data.
859  RexxArray *indirect = (RexxArray *)_index[0];
860  indexCount = indirect->items();
861  _index = indirect->data();
862  }
863 
864  /* Is this array one-dimensional? */
865  if (isSingleDimensional())
866  {
867  /* Too many subscripts? Say so. */
868  if (indexCount > 1)
869  {
870  /* should the array be extended? */
871  if ((bounds_error & ExtendUpper) && this->dimensions == OREF_NULL)
872  {
873  /* anytyhing in the array? */
874  /* or explicitly created array with 0*/
875  /* elements (.array~new(0)) */
876  if (this->size() != 0)
877  {
878  /* Yes, number of dims can't change */
879  /* report apropriate bounds */
881  }
882  else
883  {
884  /* its empty, entendarray for new siz*/
885  /* extend the array. */
886  this->extendMulti(_index, indexCount, _start);
887  /* Call us again to get position, now*/
888  /* That the array is extended. */
889  return this->validateIndex(_index, indexCount, _start, bounds_error, position);
890  }
891  }
892 
893  else if (bounds_error & RaiseBoundsTooMany)
894  {
895  /* anytyhing in the array? */
896  /* or explicitly created array with 0*/
897  /* elements (.array~new(0)) */
898  if (this->dimensions != OREF_NULL || this->size() != 0)
899  {
900  /* report apropriate bounds */
902  }
903  else
904  {
905  return false; /* just report not here */
906  }
907  }
908  else
909  {
910  return false; /* not fixed yet, but don't complain */
911  }
912  }
913  /* Too few? subscripts? Say so. */
914  else if (indexCount == 0)
915  {
916  /* report apropriate bounds */
918  }
919  /* validate integer index */
920  position = _index[0]->requiredPositive((int)_start);
921  /* out of bounds? */
922  if (position > this->size() )
923  {
924  if (position >= MAX_FIXEDARRAY_SIZE)
925  {
927  }
928  /* are we to expand the array? */
929  if (bounds_error & ExtendUpper)
930  {
931  /* yes, compute amount to expand */
932  this->extend(position - this->size());
933 
934  }
935  /* need to raise an error? */
936  else if (bounds_error & RaiseBoundsUpper)
937  {
939  }
940  else
941  {
942  return false; /* just return indicator */
943  }
944  }
945  }
946  else
947  { /* multidimensional array */
948  /* get the number of subscripts */
949  numsubs = indexCount;
950  numSize = this->dimensions->size();/* Get the size of dimension */
951  /* right number of subscripts? */
952  if (numsubs == numSize)
953  {
954  multiplier = 1; /* multiply by 1 for first dimension */
955  offset = 0; /* no accumulated offset */
956 
957  for (i = numsubs; i > 0; i--)
958  { /* loop through the dimensions */
959 
960  value = _index[i - 1];
961 
962  if (value == OREF_NULL) /* not given? */
963  {
964  /* this is an error too */
966  }
967  /* validate integer index */
968  position = value->requiredPositive((int)i);
969  /* get the current dimension */
970  _dimension = ((RexxInteger *)this->dimensions->get(i))->getValue();
971  if (position > _dimension)
972  { /* too large? */
973  /* should the array be extended? */
974  if (bounds_error & ExtendUpper)
975  {
976  /* go extend it. */
977  this->extendMulti(_index, indexCount, _start);
978  /* Call us again to get position, now*/
979  /* That the array is extended. */
980  return this->validateIndex(_index, indexCount, _start, bounds_error, position);
981  }
982  /* need to raise an error? */
983  else if (bounds_error & RaiseBoundsUpper)
984  {
986  }
987  else
988  {
989  return false; /* just return indicator */
990  }
991  }
992  /* calculate next offset */
993  offset += multiplier * (position - 1);
994  multiplier *= _dimension; /* step the multiplier */
995  }
996  position = offset + 1; /* get accumulated position */
997  }
998  /* Not enough subscripts? */
999  else if (numsubs < numSize)
1000  {
1002  }
1003  else /* Must be too many subscripts */
1004  /* should the array be extended? */
1005 #ifdef EXTEND_DIMENSIONS
1006  if (bounds_error & ExtendUpper)
1007  {
1008  /* anytyhing in the array? */
1009  if (this->size() != 0)
1010  {
1011  /* Yes, number of dims can't change */
1012  /* report apropriate bounds */
1014  }
1015  else
1016  {
1017  /* array empty, extend the array */
1018  this->extendMuti(_index, indexCount, _start);
1019  /* Call us again to get position, now*/
1020  /* That the array is extended. */
1021  return this->validateIndex(_index, indexCount, _start, bounds_error, position);
1022  }
1023  }
1024  else
1025  {
1027  }
1028 #else
1030 #endif
1031  }
1032  return true; /* return the position */
1033 }
1034 
1035 
1042 void RexxArray::ensureSpace(size_t newSize)
1043 {
1044  /* out of bounds? */
1045  if (newSize > this->size())
1046  {
1047  if (newSize >= MAX_FIXEDARRAY_SIZE)
1048  {
1050  }
1051  /* yes, compute amount to expand */
1052  this->extend(newSize - this->size());
1053 
1054  }
1055 }
1056 
1057 
1058 
1060 /******************************************************************************/
1061 /* Function: Return the array size as an integer object */
1062 /******************************************************************************/
1063 {
1064  return new_integer(this->size());
1065 }
1066 
1075 RexxArray * RexxArray::section(size_t _start, size_t _end)
1076 {
1077  size_t newSize; /* Size for new array. */
1078  RexxArray *newArray; /* The new array. */
1079 
1080  if (_start == 0) /* starting position specified? */
1081  {
1082  _start = 1; /* nope, start at begining */
1083  }
1084 
1085  /* ending position omitted */
1086  /* or, End pos past end of array? */
1087  if (_end == 0 || _end > this->size())
1088  {
1089  _end = this->size(); /* yes, use end of array */
1090  }
1091  if (_start <= _end)
1092  { /* is start before end? */
1093  newSize = _end + 1 - _start; /* yes, compute new size */
1094  /* Get new array, of needed size */
1095  newArray = (RexxArray *)new_array(newSize);
1096  // a new array cannot be oldspace, by definition. It's safe to use
1097  // memcpy to copy the data.
1098  /* yes, we can do a memcpy */
1099  memcpy(newArray->data(), slotAddress(_start), sizeof(RexxObject *) * newSize);
1100  }
1101  else
1102  {
1103  /* return 0 element array */
1104  newArray = (RexxArray *)new_array((size_t)0);
1105  }
1106  return newArray; /* return the newly created array */
1107 }
1108 
1118 {
1119  /* multidimensional array? */
1120  if (isMultiDimensional())
1121  {
1122  /* this is an error */
1124  }
1125 
1126  // the index is required
1127  requiredArgument(_start, ARG_ONE);
1128  size_t nstart; // array position
1129 
1130  // validate the index and expand if necessary.
1131  this->validateIndex(&_start, 1, 1, RaiseBoundsInvalid | RaiseBoundsTooMany, nstart);
1132  size_t nend = 0; ;
1133  if (_end == OREF_NULL) /* If no end position specified, */
1134  {
1135  nend = this->size(); /* Defaults to last element */
1136  }
1137  else
1138  { /* End specified - check it out */
1139  nend = _end->requiredNonNegative(ARG_TWO);
1140  }
1141 
1142  if (!isOfClass(Array, this)) /* actually an array subclass? */
1143  {
1144  /* need to do this the slow way */
1145  return this->sectionSubclass(nstart, nend);
1146  }
1147 
1148  if (nstart > this->size()) /* too big? */
1149  {
1150  // return a zero-size array
1151  return (RexxArray *)(((RexxArray *)TheNullArray)->copy());
1152  }
1153  else
1154  {
1155  /* go past the bounds? */
1156  if (nend > this->size() - nstart + 1)
1157  {
1158  nend = this->size() - nstart + 1;/* truncate to the end */
1159  }
1160  if (nend == 0) /* requesting zero? */
1161  {
1162  /* return zero elements */
1163  return (RexxArray *)(((RexxArray *)TheNullArray)->copy());
1164  }
1165  else
1166  { /* real sectioning to do */
1167  /* create a new array */
1168  RexxArray *rref = (RexxArray *)new_array(nend);
1169  for (size_t i = 1; i <= nend; i++)
1170  { /* loop through the elements */
1171  /* copy an element */
1172  rref->put(this->get(nstart + i - 1), i);
1173  }
1174  return rref; /* return the new array */
1175  }
1176  }
1177 }
1178 
1180  size_t _start, /* starting element */
1181  size_t _end ) /* ending element */
1182 /******************************************************************************/
1183 /* Function: Rexx level section method */
1184 /******************************************************************************/
1185 {
1186  size_t i; /* loop counter */
1187  RexxArray *newArray; /* returned array */
1188  ProtectedObject result;
1189 
1190  if (_start > this->size()) /* too big? */
1191  {
1192  this->behaviour->getOwningClass()->sendMessage(OREF_NEW, IntegerZero, result);
1193  newArray = (RexxArray *)(RexxObject *)result;
1194  }
1195  /* return a zero element one */
1196  else
1197  {
1198  if (_end > this->size() - _start + 1)
1199  {
1200  /* go past the bounds? */
1201  _end = this->size() - _start + 1;/* truncate to the end */
1202  }
1203  if (_end == 0) /* requesting zero? */
1204  {
1205  this->behaviour->getOwningClass()->sendMessage(OREF_NEW, IntegerZero, result);
1206  newArray = (RexxArray *)(RexxObject *)result;
1207  }
1208  /* return a zero element one */
1209  else
1210  { /* real sectioning to do */
1211  /* create a new array */
1212  this->behaviour->getOwningClass()->sendMessage(OREF_NEW, new_integer(_end), result);
1213  newArray = (RexxArray *)(RexxObject *)result;
1214  for (i = 1; i <= _end; i++) /* loop through the elements */
1215  {
1216  /* copy an element */
1217  newArray->sendMessage(OREF_PUT, this->get(_start + i - 1), new_integer(i));
1218  }
1219  }
1220  }
1221  return newArray; /* return the new array */
1222 }
1223 
1225 /******************************************************************************/
1226 /* Function: Retrieve the first element index from the array as an integer */
1227 /* object */
1228 /******************************************************************************/
1229 {
1230  /* get the address of the first */
1231  /*element in the array */
1232  RexxObject **thisObject = this->expansionArray->objects;
1233  size_t _arraySize = this->size(); /* get the size of the array */
1234  /* find first position in the */
1235  /*array with data */
1236 
1237  size_t i;
1238  for (i = 0; i < _arraySize && thisObject[i] == OREF_NULL; i++);
1239 
1240  if (i == _arraySize) /* is array empty */
1241  {
1242  return TheNilObject; /* return nil object */
1243  }
1244  else
1245  {
1246  /* return index of the first entry */
1247  return convertIndex(i + 1);
1248  }
1249 }
1250 
1252 /******************************************************************************/
1253 /* Function: Return the index of the last array item as an integer object */
1254 /******************************************************************************/
1255 {
1256  // for an empy array, the index is .nil
1257  if (lastElement == 0)
1258  {
1259  return TheNilObject;
1260  }
1261 
1262  // return as an object
1263  return (RexxObject *)convertIndex(lastElement);
1264 }
1265 
1273 {
1274  /* get the address of the first */
1275  /*element in the array */
1276  RexxObject **thisObject = this->expansionArray->objects;
1277  size_t _arraySize = this->size(); /* get the size of the array */
1278  /* find first position in the */
1279  /*array with data */
1280 
1281  for (size_t i = 0; i < _arraySize; i++)
1282  {
1283  // if we have a non-nil object, return it
1284  if (thisObject[i] != OREF_NULL)
1285  {
1286  return thisObject[i];
1287  }
1288  }
1289  // not found, return .nil
1290  return TheNilObject;
1291 }
1292 
1299 {
1300  // for an empy array, the item is .nil
1301  if (lastElement == 0)
1302  {
1303  return TheNilObject;
1304  }
1305 
1306  // return the last item
1307  return (RexxObject *)get(lastElement);
1308 }
1309 
1311 /******************************************************************************/
1312 /* Function: Return the index of the last array item as an integer object */
1313 /******************************************************************************/
1314 {
1315  return lastElement; // we've kept track of this
1316 }
1317 
1318 RexxObject *RexxArray::nextRexx(RexxObject **arguments, size_t argCount)
1319 /******************************************************************************/
1320 /* Function: Return the next entry after a given array index */
1321 /******************************************************************************/
1322 {
1323  size_t position;
1324  /* go validate the index */
1325  if (!this->validateIndex(arguments, argCount, 1, RaiseBoundsTooMany | RaiseBoundsInvalid, position))
1326  {
1327  // out of bounds results in the .nil object
1328  return TheNilObject;
1329  }
1330  /* get the address of the first */
1331  /*element in the array */
1332  RexxObject **thisObject = this->data();
1333  size_t _arraySize = this->size(); /* get the size of the array */
1334  /* find next entry in the array with */
1335  /*data */
1336 
1337  size_t i;
1338  for (i = position; i < _arraySize && thisObject[i] == OREF_NULL; i++);
1339 
1340  if (i >= this->size())
1341  {
1342  return TheNilObject; /* return nil object */
1343  }
1344  else
1345  {
1346  /* return index of the next entry */
1347  return convertIndex(i + 1);
1348  }
1349 }
1350 
1351 RexxObject *RexxArray::previousRexx(RexxObject **arguments, size_t argCount)
1352 /******************************************************************************/
1353 /* Function: Return the index preceeding a given index */
1354 /******************************************************************************/
1355 {
1356  size_t position;
1357 
1358  this->validateIndex(arguments, argCount, 1, RaiseBoundsTooMany | RaiseBoundsInvalid, position);
1359  /* get the index object into an */
1360  /*integer object */
1361  size_t i = position;
1362 
1363  size_t _arraySize = this->size(); /* get the size of the array */
1364 
1365  if (i > _arraySize) /* beyond the size of the array? */
1366  {
1367  /* set i to one more than the last */
1368  /*entry */
1369  i = _arraySize;
1370  }
1371  else
1372  {
1373  i = i-1; /* Account for 0 based 'C' arrays */
1374  }
1375 
1376  /* get the address of the first */
1377  /*element in the array */
1378  RexxObject **thisObject = this->expansionArray->objects;
1379  /* find previous entry in the */
1380  /*array with data */
1381  for (; i > 0 && thisObject[i-1] == OREF_NULL; i--);
1382 
1383  if (i == 0)
1384  {
1385  return TheNilObject; /* return nil object */
1386  }
1387  else
1388  {
1389  /* return the index to the */
1390  /*previous entry */
1391  return convertIndex(i);
1392  }
1393 }
1394 
1395 RexxObject *RexxArray::hasIndexRexx(RexxObject ** _index, size_t _indexCount)
1396 /******************************************************************************/
1397 /* Function: True if array has an entry for the index, false otherwise */
1398 /* Note: This routine should not raise an error, regardless of the indices */
1399 /* being used. The only error produced is if no parms were passed. */
1400 /******************************************************************************/
1401 {
1402  stringsize_t position; /* array position */
1403 
1404  /* go validate the index */
1405  if (!this->validateIndex(_index, _indexCount, 1, RaiseBoundsTooMany | RaiseBoundsInvalid, position))
1406  {
1407  /* this is false */
1408  return TheFalseObject;
1409 
1410  }
1411  else /* check the position */
1412  {
1413  /* have a real entry? */
1414  if (*(this->data() + position - 1) != OREF_NULL)
1415  {
1416  /* got a true */
1417  return TheTrueObject;
1418  }
1419  else
1420  {
1421  /* no index here */
1422  return TheFalseObject;
1423  }
1424  }
1425 }
1426 
1427 bool RexxArray::hasIndexNative(size_t _index)
1428 /******************************************************************************/
1429 /* Function: Determine if an element exist for a position */
1430 /******************************************************************************/
1431 {
1432  /* in bounds and here? */
1433  if (_index > 0 && _index <= this->size() && *(this->data() + _index - 1) != OREF_NULL)
1434  {
1435  return true; /* this is true */
1436  }
1437  else
1438  {
1439  return false; /* nope, don't have it */
1440  }
1441 }
1442 
1444 /******************************************************************************/
1445 /* Function: Return a single dimension array of self, with only items that */
1446 /* has values, so it will be of size items. */
1447 /******************************************************************************/
1448 {
1449  // for an array, this is the all items value.
1450  return this->allItems();
1451 }
1452 
1453 
1460 {
1461  // get a result array of the appropriate size
1462  RexxArray *newArray = (RexxArray *)new_array(this->items());
1463 
1464  // we need to fill in based on actual items, not the index.
1465  size_t count = 0;
1466  RexxObject **item = this->data();
1467  // loop through the array, copying all of the items.
1468  for (size_t iterator = 0; iterator < this->size(); iterator++ )
1469  {
1470  // if this is a real array item, copy over to the result
1471  if (item[iterator] != OREF_NULL)
1472  {
1473  newArray->put(item[iterator], ++count);
1474  }
1475  }
1476  return newArray;
1477 }
1478 
1479 
1487 {
1488  // get a result array of the appropriate size
1489  RexxArray *newArray = (RexxArray *)new_array(this->items());
1490  ProtectedObject p(newArray);
1491 
1492  // we need to fill in based on actual items, not the index.
1493  size_t count = 0;
1494  RexxObject **item = this->data();
1495  // loop through the array, copying all of the items.
1496  for (size_t iterator = 0; iterator < this->size(); iterator++ )
1497  {
1498  // if this is a real array item, add an integer index item to the
1499  // result collection.
1500  if (item[iterator] != OREF_NULL)
1501  {
1502  newArray->put(convertIndex(iterator+1), ++count);
1503  }
1504  }
1505  return newArray;
1506 }
1507 
1508 // Temporary bypass for BUG #1700606
1509 #if 0
1511 /******************************************************************************/
1512 /* Function: Handle a REQUEST('STRING') request for a REXX string object */
1513 /******************************************************************************/
1514 {
1515  return this->makeString((RexxString *)OREF_NULL); /* forward to the real makestring method */
1516 }
1517 #endif
1518 
1520 {
1521  return toString(format, separator);
1522 }
1523 
1524 RexxString *RexxArray::toString( /* concatenate array elements to create string object */
1525  RexxString *format, /* format of concatenation (one of: "C", "L") */
1526  RexxString *separator) /* separator to use if "L" is specified for format */
1527 /******************************************************************************/
1528 /* Function: Make a string out of an array */
1529 /******************************************************************************/
1530 {
1531  size_t _items;
1532  size_t i;
1533  RexxArray *newArray; /* New array */
1534  RexxString *newString;
1535  RexxString *line_end_string; /* converted substitution value */
1536  RexxMutableBuffer *mutbuffer;
1537  RexxObject *item; /* inserted value item */
1538  int i_form = 0; /* 1 == line, 2 == char */
1539 
1540  mutbuffer = ((RexxMutableBufferClass*) TheMutableBufferClass)->newRexx(NULL, 0);
1541  ProtectedObject p1(mutbuffer);
1542 
1543  newArray = this->makeArray(); /* maybe multidimensional, make onedimensional */
1544  ProtectedObject p2(newArray);
1545 
1546  _items = newArray->items(); /* and the actual count in the array */
1547 
1548  if (format != OREF_NULL)
1549  {
1550  // a string value is required here
1551  format = stringArgument(format, ARG_ONE);
1552  }
1553 
1554  if (format == OREF_NULL)
1555  {
1556  i_form = 2; /* treat item as LINE by default */
1557  }
1558  else if (toupper((format->getStringData()[0])) == 'C')
1559  {
1560  i_form = 1;
1561  }
1562  else if (toupper((format->getStringData()[0])) == 'L')
1563  {
1564  i_form = 2;
1565  }
1566  else
1567  {
1569  }
1570 
1571  if (i_form == 1) /* character oriented processing */
1572  {
1573  if (separator != OREF_NULL)
1574  {
1576 
1577  }
1578 
1579  for (i = 1; i <=_items ; i++) /* loop through the array */
1580  {
1581  item = newArray->get(i); /* get the next item */
1582  if (item != OREF_NULL)
1583  {
1584  RexxObject * _stringValue = item->requiredString();
1585  if (_stringValue != TheNilObject)
1586  {
1587  mutbuffer->append(_stringValue);
1588  }
1589  }
1590  }
1591  }
1592  else if (i_form == 2) /* line oriented processing */
1593  {
1594  if (separator != OREF_NULL)
1595  {
1596  line_end_string = stringArgument(separator, ARG_TWO);
1597  }
1598  else
1599  {
1600  line_end_string = new_string(line_end);
1601  }
1602 
1603  ProtectedObject p3(line_end_string);
1604  bool first = true;
1605 
1606  for (i = 1; i <= _items; i++) /* loop through the array */
1607  {
1608  item = newArray->get(i); /* get the next item */
1609  if (item != OREF_NULL)
1610  {
1611  // append a linend between the previous item and this one.
1612  if (!first)
1613  {
1614  mutbuffer->append((RexxObject *) line_end_string);
1615  }
1616  RexxObject *_stringValue = item->requiredString();
1617  if (_stringValue != TheNilObject)
1618  {
1619  mutbuffer->append(_stringValue);
1620  }
1621  first = false;
1622  }
1623  }
1624  }
1625 
1626  newString = mutbuffer->makeString();
1627  return newString;
1628 }
1629 
1630 RexxObject *RexxArray::join( /* join two arrays into one */
1631  RexxArray *other) /* array to be appended to self */
1632 /******************************************************************************/
1633 /* Function: Join two arrays into one array */
1634 /******************************************************************************/
1635 {
1636  /* get new array, total size is size */
1637  /* of both arrays. */
1638  RexxArray *newArray = (RexxArray*)new_array(this->size() + other->size());
1639  // it's safe to just copy the references because the newArray will be new space
1640  /* copy first array into new one */
1641  memcpy(newArray->data(), this->data(), this->dataSize());
1642  /* copy 2nd array into the new one */
1643  /* after the first one. */
1644  memcpy((void *)newArray->slotAddress(this->size() + 1), other->data(), other->dataSize());
1645  return newArray; /* All done, return joined array */
1646 
1647 }
1648 
1649 void RexxArray::resize(void) /* resize this array to be a NULLARRA*/
1650 /******************************************************************************/
1651 /* Function: An Array is being expanded so chop off the data (array) */
1652 /* portion of this array. */
1653 /******************************************************************************/
1654 {
1655  size_t i;
1656  /* Has the array already been */
1657  /* expanded ? */
1658  if (this->expansionArray == this)
1659  {
1660  /* no, then we resize the array */
1661  /* is this array in OldSpace ? */
1662  if (this->isOldSpace())
1663  {
1664  /* Old Space, remove any reference */
1665  /* to new space from memory tables */
1666  for (i = 0; i < this->arraySize; i++)
1667  {
1668  OrefSet(this, this->objects[i], OREF_NULL);
1669  }
1670  }
1671  /* resize the array object */
1672  memoryObject.reSize(this, sizeof(RexxArray));
1673  this->arraySize = 0; /* outer array has no elements */
1674  }
1675 }
1676 
1678  size_t amount) /* amount to shrink an array */
1679 /******************************************************************************/
1680 /* Function: Shrink an array without reallocating any elements */
1681 /* Single Dimension ONLY */
1682 /******************************************************************************/
1683 {
1684  size_t _size = this->size(); /* get the size */
1685  size_t newSize = _size - amount; /* get the new size */
1686 
1687  size_t i = newSize + 1; /* address first removed element */
1688  for (i = newSize + 1; i <= _size; i++)/* for all removed elements */
1689  {
1690  this->put(OREF_NULL, i); /* clear out the element */
1691  }
1692  /* adjust the size . */
1693  this->expansionArray->arraySize = newSize;
1694 }
1695 
1697  RexxObject *target) /* target object to locate */
1698 /*****************************************************************************/
1699 /* Function: To search a list in the form of an array for an item, returning*/
1700 /* the index */
1701 /*****************************************************************************/
1702 {
1703  size_t _size = this->size(); /* get the array size */
1704  for (size_t i = 1; i <= _size; i++)
1705  { /* spin through the array */
1706  if (this->get(i) == target) /* is this the one? */
1707  {
1708  return i; /* return the index */
1709  }
1710  }
1711  return 0; /* not found here */
1712 }
1713 
1714 
1715 RexxArray *RexxArray::extend( /* join two arrays into one */
1716  size_t extension) /* number of elements to extend */
1717 /******************************************************************************/
1718 /* Function: Extend an array by a given number of elements */
1719 /* Single Dimension ONLY */
1720 /******************************************************************************/
1721 {
1722  /* do we really need to extend array */
1723  /* or just adjust size. */
1724  if (this->size() + extension <= this->maximumSize)
1725  {
1726  /* adjust the size . */
1727  this->expansionArray->arraySize += extension;
1728  return this;
1729  }
1730 
1731  size_t newSize = this->size() + extension;
1732  size_t extendSize = this->size() / 2;
1733 
1734  /* get a new array, total size is */
1735  /* size of both arrays. */
1736  RexxArray *newArray = (RexxArray *)new_array(newSize + extendSize);
1737  /* If none of the objects are in */
1738  /* OldSpace, we can skip the */
1739  /* OrefSets and just copy */
1740  /* copy ourselves into the new array */
1741  memcpy(newArray->data(), this->data(), this->dataSize());
1742  this->resize(); /* adjust ourself to be null arrayobj*/
1743 
1744  newArray->setExpansion(OREF_NULL); /* clear the new expansion array */
1745  /* set new expansion array */
1746  OrefSet(this, this->expansionArray, newArray);
1747  /* keep max Size value in synch */
1748  /* with expansion. */
1749  this->maximumSize = newArray->maximumSize;
1750  /* make sure size is correct. */
1751  newArray->arraySize = newSize;
1752  return this; /* All done, return array */
1753 }
1754 
1755 
1764 {
1765  for (size_t i = 1; i <= this->size(); i++)
1766  {
1767  RexxObject *test = get(i);
1768 
1769  // if there's an object in the slot, compare it.
1770  if (test != OREF_NULL)
1771  {
1772  // if the items are equal, return the index
1773  if (item->equalValue(test))
1774  {
1775  return i;
1776  }
1777  }
1778  }
1779  return 0;
1780 }
1781 
1782 
1792 {
1793  // single dimension array? This is easy
1794  if (isSingleDimensional())
1795  {
1796  return new_integer(idx);
1797  }
1798  else
1799  {
1800  // compose a composite index
1801  return indexToArray(idx);
1802  }
1803 }
1804 
1805 
1815 {
1816  // work with an origin-origin zero version of the index, which is easier
1817  // do work with.
1818  idx--;
1819  // get the number of dimensions specified.
1820  size_t dims = this->dimensions->size();
1821  // get an array we fill in as we go
1822  RexxArray * _index = new_array(dims);
1823 
1824  ProtectedObject p(_index);
1825 
1826  for (size_t i = dims; i > 0; i--)
1827  {
1828  // get the next dimension size
1829  size_t _dimension = ((RexxInteger *)this->dimensions->get(i))->getValue();
1830  // now get the remainder. This tells us the position within this
1831  // dimension of the array. Make an integer object and store in the
1832  // array.
1833  size_t digit = idx % _dimension;
1834  // the digit is origin-zero, but the Rexx index is origin-one.
1835  _index->put(new_integer(digit + 1), i);
1836  // now strip out that portion of the index.
1837  idx = (idx - digit) / _dimension;
1838  }
1839  return _index;
1840 }
1841 
1842 
1853 {
1854  // we require the index to be there.
1855  requiredArgument(target, ARG_ONE);
1856  // see if we have this item. If not, then
1857  // we return .nil.
1858  size_t _index = findSingleIndexItem(target);
1859 
1860  if (_index == 0)
1861  {
1862  return TheNilObject;
1863  }
1864 
1865  return convertIndex(_index);
1866 }
1867 
1868 
1877 {
1878  // we require the index to be there.
1879  requiredArgument(target, ARG_ONE);
1880  // see if we have this item. If not, then
1881  // we return .nil.
1882  size_t _index = findSingleIndexItem(target);
1883 
1884  if (_index == 0)
1885  {
1886  return TheNilObject;
1887  }
1888  // remove the item at the location
1889  put(OREF_NULL, _index);
1890  return target;
1891 }
1892 
1893 
1903 {
1904  // this is pretty simple. One argument, required, and just search to see
1905  // if we have it.
1906  requiredArgument(target, ARG_ONE);
1907  return findSingleIndexItem(target) == 0 ? TheFalseObject : TheTrueObject;
1908 }
1909 
1910 
1911 
1913  COPYELEMENTPARM *parm,
1914  size_t newDimension)
1915 /******************************************************************************/
1916 /* Function: Recursive routine to copy element from one multiDim array */
1917 /* to another. */
1918 /******************************************************************************/
1919 {
1920  size_t skipAmount; /* amount to skip for increased */
1921  /* dimension. */
1922  size_t newDimSize;
1923  size_t oldDimSize;
1924  size_t oldDimension;
1925  size_t i; /* count for each subscript at */
1926  /* this dimension */
1927 
1928  /* At the point where we can */
1929  /* copy elements? */
1930  /* ending condition for recusion */
1931  if (newDimension == parm->firstChangedDimension)
1932  {
1933  /* is new array in OldSpace? */
1934  if (parm->newArray->isOldSpace())
1935  {
1936  /* Yes,need to do OrefSets */
1937  /* For each element to copy */
1938  for (i = 1; i <= parm->copyElements; i++, parm->startNew++, parm->startOld++ )
1939  {
1940  /* set the newvalue. */
1941  OrefSet(parm->newArray, *parm->startNew, *parm->startOld);
1942  }
1943  }
1944  else
1945  {
1946  /* not old Spcae we can do memcpy */
1947  memcpy(parm->startNew, parm->startOld, sizeof(RexxObject *) * parm->copyElements);
1948  /* update pointers */
1949  parm->startNew += parm->copyElements;
1950  parm->startOld += parm->copyElements;
1951  }
1952  /* now bump past space for */
1953  /* additional size of dimension */
1954  parm->startNew += parm->skipElements;
1955  }
1956  else
1957  {
1958  /* Compute the old dimension num */
1959  oldDimension = newDimension - parm->deltaDimSize;
1960  /* Get size for new Dimension */
1961  newDimSize = ((RexxInteger *)parm->newDimArray->get(newDimension))->getValue();
1962  /* Get size for old Dimension */
1963  oldDimSize = ((RexxInteger *)parm->oldDimArray->get(oldDimension))->getValue();
1964  /* For each subscript at this */
1965  for (i= 1; i <= oldDimSize; i++)
1966  {/* dimension, (of old size) */
1967  /* copy elelments. */
1968  copyElements(parm, newDimension + 1);
1969  }
1970  if (newDimSize > oldDimSize)
1971  { /* Was this dimension expanded? */
1972  /* compute total space need for */
1973  /* block of all lower dimensions */
1974  for (i = parm->newDimArray->size(), skipAmount = 1;
1975  i > newDimension;
1976  skipAmount *= ((RexxInteger *)parm->newDimArray->get(i))->getValue(), i--);
1977  /* multiple by delta add at this */
1978  /* dimension. */
1979  skipAmount *= (newDimSize - oldDimSize);
1980  /* Bump our start pointer past */
1981  /* empty space added for this */
1982  /* dimension. */
1983  parm->startNew += skipAmount;
1984  }
1985  }
1986  /* all done at this level return */
1987  /* to caller. */
1988  return;
1989 }
1990 
1991 
1992 RexxArray *RexxArray::extendMulti( /* Extend multi array */
1993  RexxObject ** _index, /* Dimension array is to be */
1994  size_t _indexCount, /* number of indices in the index */
1995  size_t _start) /* Starting position of dimensions */
1996  /* in index. */
1997 /******************************************************************************/
1998 /* Function: Extend an array by a given number of elements */
1999 /* Multiple Dimensions */
2000 /* Index either has more dimensions that the current array or */
2001 /* is the same number. So expansion array will have same number */
2002 /* of dimensions as index. */
2003 /* So examine size of each dimension and new array will be max */
2004 /* of two sizes. */
2005 /* */
2006 /* NOTE: Even though we don't currently allow for changing the number */
2007 /* of dimensions in an array, the support to do this, is included */
2008 /* in this method. We currently won't be called for this condition */
2009 /* but if we ever are, this method should not need to be changed. */
2010 /* */
2011 /******************************************************************************/
2012 {
2013  size_t currDimSize; /* Current size of Dimension */
2014  size_t additionalDim; /* Number of additional DImension */
2015  size_t newDimSize; /* New size for this Dimension */
2016  size_t newDimension; /* Current dimension */
2017  size_t oldDimension; /* Current dimension */
2018  size_t i;
2019  RexxArray *newArray;
2020  RexxArray *newDimArray; /* Array containing new dimension */
2021  size_t newDimArraySize; /* Size of Dimension Array */
2022  size_t accumSize;
2023  size_t firstDimChanged = 0; /* First Dimension to grow */
2024  COPYELEMENTPARM copyParm; /* Structure for copyElement */
2025  size_t tempSize;
2026 
2027  /* New dimension array size of */
2028  /* index array. */
2029  /* index is actually 1 bigger tha */
2030  /* dimension size, since it */
2031  /* contains the new value at 1st */
2032  /* position */
2033 
2034  /* Compute new Size for DimArray */
2035  newDimArraySize = _indexCount;
2036  newDimArray = new_array(newDimArraySize);
2037  ProtectedObject p(newDimArray);
2038  /* extending from single Dimensio */
2039  /* to a multi Dimensionsal array */
2040  if (this->dimensions == OREF_NULL)
2041  {
2042  /* Get value for 1st dimension */
2043  /* its the last element */
2044  i = newDimArraySize - 1;
2045  newDimSize = _index[i]->requiredPositive((int)i);
2046  /* Yes, is 1st Dimension going to */
2047  /* be bigger than current size? */
2048  if (newDimSize > this->size())
2049  /* Yes, use new size + buffer for */
2050  /* 1st Dimension */
2051  newDimArray->put(new_integer(newDimSize), newDimArraySize);
2052  else
2053  {
2054  /* nope, use same size for Dim */
2055  tempSize = this->size();
2056  newDimArray->put(new_integer(tempSize), newDimArraySize);
2057  }
2058  }
2059  else
2060  {
2061  for (oldDimension = this->dimensions->size(), newDimension = newDimArraySize;
2062  oldDimension > 0 ;
2063  oldDimension--, newDimension--)
2064  {
2065  /* Get current size of this dimension*/
2066  currDimSize = ((RexxInteger *)this->dimensions->get(oldDimension))->getValue();
2067  /* Get indexd size of this dimension*/
2068 
2069  newDimSize = _index[newDimension - 1]->requiredPositive((int)newDimension);
2070  /* does this dimension need to be */
2071  /* expanded. */
2072  if (newDimSize > currDimSize)
2073  {
2074  newDimArray->put((RexxObject *)new_integer(newDimSize), newDimension);
2075  /* has a dimension already been chang*/
2076  if (!firstDimChanged)
2077  {
2078  /* remember the first dimenion chenge*/
2079  firstDimChanged = newDimension;
2080  }
2081  }
2082  else
2083  {
2084  newDimArray->put(this->dimensions->get(oldDimension), newDimension);
2085  }
2086  }
2087  }
2088  /* Was original array single dim */
2089  if (this->dimensions == OREF_NULL)
2090  {
2091  /* additional Dimensions is 1 */
2092  /* minus size, (1st Dimension) */
2093  additionalDim = newDimArraySize - 1;
2094  }
2095  else
2096  {
2097  /* compute number of dimensions added*/
2098  additionalDim = newDimArraySize - this->dimensions->size();
2099  }
2100  /* is index greater than current */
2101  /* dimensions of this array. */
2102  if (additionalDim > 0)
2103  {
2104  /* yes, for remainder of dimensions */
2105  for (newDimension = additionalDim;
2106  newDimension > 0 ;
2107  newDimension--)
2108  {
2109  /* Get indexd size of this dimension*/
2110  newDimSize = ((RexxInteger *)_index[newDimension - 1])->getValue();
2111  /* set up value for this dimension */
2112  newDimArray->put(new_integer(newDimSize), newDimension);
2113  }
2114  }
2115  /* Now create the new array for this */
2116  /* dimension. */
2117  newArray = new (newDimArray->data(), newDimArraySize, TheArrayClass) RexxArray;
2118  ProtectedObject p1(newArray);
2119  /* Anything in original? */
2120  if (this->size())
2121  {
2122  /* Yes, move values into new arra */
2123  /* Extending from single Dimension */
2124  /* or original array was empty */
2125  /* or adding dimensions or increas */
2126  /* last original dimension? */
2127  if (isSingleDimensional() ||
2128  this->size() == 0 ||
2129  !firstDimChanged || firstDimChanged <= additionalDim + 1)
2130  {
2131  /* If none of the objects are in */
2132  /* OldSpace, we can 'cheat' and do */
2133  /* a fast copy (memcpy) */
2134  /* copy ourselves into the new array */
2135  memcpy(newArray->data(), this->data(), sizeof(RexxObject *) * this->size());
2136  }
2137  /* Working with 2 multi-dimensional */
2138  /* Array's. */
2139  else
2140  {
2141  /* Now we need to move all elements */
2142 
2143  /* for all Dimensions before first */
2144  /* to increase. */
2145  for (i = newDimArraySize, accumSize = 1;
2146  i > firstDimChanged ;
2147  accumSize *= ((RexxInteger *)this->dimensions->get(i))->getValue(), i--);
2148  /* Compute lowest largest contig */
2149  /* chunk that can be copied. */
2150  copyParm.copyElements = accumSize * ((RexxInteger *)this->dimensions->get(firstDimChanged))->getValue();
2151  /* Compute amount need to ship */
2152  /* to compete expanded dimension */
2153  copyParm.skipElements = accumSize * (((RexxInteger *)newDimArray->get(firstDimChanged))->getValue() -
2154  ((RexxInteger *)this->dimensions->get(firstDimChanged))->getValue());
2155 
2156  copyParm.startNew = newArray->data();
2157  copyParm.startOld = this->data();
2158  /* Setup parameter structure */
2159  copyParm.firstChangedDimension = firstDimChanged;
2160  copyParm.newArray = newArray;
2161  copyParm.newDimArray = newDimArray;
2162  copyParm.oldDimArray = this->dimensions;
2163  /* Compute delta dimensions size */
2164  copyParm.deltaDimSize = newDimArraySize - this->dimensions->size();
2165  /* do the copy. starting w/ */
2166  /* Highest Dimension */
2167  copyElements(&copyParm, newDimArraySize - this->dimensions->size() + 1);
2168  }
2169  } /* end, if anything in original */
2170 
2171 
2172  this->resize();
2173  /* Set dimensions to be new dimension*/
2174  OrefSet(this, this->dimensions, newDimArray);
2175  newArray->setExpansion(OREF_NULL);
2176  /* update expansion array. */
2177  OrefSet(this, this->expansionArray, newArray);
2178  /* keep max Size value in synch */
2179  /* with expansion. */
2180  this->maximumSize = newArray->maximumSize;
2181  return this; /* All done, return array */
2182 }
2183 
2184 
2198 size_t RexxArray::insert(RexxObject *value, size_t _index)
2199 {
2200  openGap(_index, 1); // open an appropriate sized gap in the array
2201  this->put(value, _index); // add the inserted element */
2202  return _index; // return the index of the insertion
2203 }
2204 
2205 
2217 {
2218  RexxObject *result = get(_index); // save the return value
2219  closeGap(_index, 1); // close up the gap for the deleted item
2220  // return .nil if there's nothing at that position
2221  return result == OREF_NULL ? TheNilObject : result;
2222 }
2223 
2224 
2225 void * RexxArray::operator new(size_t size,
2226  size_t items, /* items in the array */
2227  RexxObject **first ) /* array of items to fill array */
2228 /******************************************************************************/
2229 /* Quick creation of an argument array */
2230 /******************************************************************************/
2231 {
2232  RexxArray *newArray = new_array(items); /* get a new array */
2233  if (items != 0) /* not a null array? */
2234  {
2235  /* copy the references in */
2236  memcpy(newArray->data(), first, (sizeof(RexxObject *) * items));
2237  // we need to make sure the lastElement field is set to the
2238  // new arg position.
2239  for (;items > 0; items--)
2240  {
2241  if (newArray->get(items) != OREF_NULL)
2242  {
2243  newArray->lastElement = items;
2244  break;
2245  }
2246  }
2247  }
2248  return newArray; /* return the new array */
2249 }
2250 
2251 void *RexxArray::operator new(size_t size, RexxObject **args, size_t argCount, RexxClass *arrayClass)
2252 /******************************************************************************/
2253 /* Function: Rexx level creation of an ARRAY object */
2254 /******************************************************************************/
2255 {
2256  if (argCount == 0)
2257  {
2258  /* If no argument is passed */
2259  /* create an empty array. */
2260  RexxArray *temp = new ((size_t)0, ARRAY_DEFAULT_SIZE, arrayClass) RexxArray;
2261  ProtectedObject p(temp);
2262  temp->sendMessage(OREF_INIT); /* call any rexx init's */
2263  return temp;
2264  }
2265 
2266  /* Special case for 1-dimensional */
2267  if (argCount == 1)
2268  {
2269  RexxObject *current_dim = args[0];
2270  // specified as an array of dimensions?
2271  // this gets special handling
2272  if (current_dim != OREF_NULL && isOfClass(Array, current_dim))
2273  {
2274  return RexxArray::createMultidimensional(((RexxArray *)current_dim)->data(), ((RexxArray *)current_dim)->items(), arrayClass);
2275  }
2276  /* Make sure it's an integer */
2277  wholenumber_t total_size = current_dim->requiredNonNegative(ARG_ONE, number_digits());
2278  if (total_size < 0)
2279  {
2281  }
2282 
2283  if ((size_t)total_size >= MAX_FIXEDARRAY_SIZE)
2284  {
2286  }
2287 
2288  /* Note: The following will leave the dimension field set to OREF_NULL, */
2289  /* which is what we want (it will be done by array_init above). */
2290  /* Create new array of approp. size. */
2291 
2292  RexxArray *temp = (RexxArray *)new_externalArray(total_size, arrayClass);
2293  ProtectedObject p(temp);
2294  if (total_size == 0)
2295  { /* Creating 0 sized array? */
2296  /* Yup, setup a Dimension array */
2297  /* single Dimension, Mark so */
2298  /* can't change Dimensions. */
2299  OrefSet(temp, temp->dimensions, new_array(IntegerZero));
2300  }
2301  temp->sendMessage(OREF_INIT); /* call any rexx init's */
2302  return temp; /* Return the new array. */
2303  }
2304 
2305  return RexxArray::createMultidimensional(args, argCount, arrayClass);
2306 }
2307 
2317 {
2318  /* Working with a multi-dimension */
2319  /* array, so get a dimension arr */
2320  RexxArray *dim_array = (RexxArray *)new_array(count);
2321  ProtectedObject d(dim_array);
2322  size_t total_size = 1; /* Set up for multiplication */
2323  for (size_t i = 0; i < count; i++)
2324  {
2325  /* make sure current parm is inte */
2326  RexxObject *current_dim = (RexxInteger *)dims[i];
2327  if (current_dim == OREF_NULL) /* was this one omitted? */
2328  {
2329  missingArgument(i+1); /* must have this value */
2330  }
2331  /* get the long value */
2332  size_t cur_size = current_dim->requiredNonNegative((int)(i+1));
2333  /* going to do an overflow? */
2334  if (cur_size != 0 && ((MAX_FIXEDARRAY_SIZE / cur_size) < total_size))
2335  {
2336  /* this is an error */
2338  }
2339  total_size *= cur_size; /* keep running total size */
2340  /* Put integer object into curren */
2341  /* dimension array position */
2342  dim_array->put(new_integer(cur_size), i+1);
2343  }
2344  /* Make sure flattened array isn't */
2345  /* too big. */
2346  if (total_size >= MAX_FIXEDARRAY_SIZE)
2347  {
2349  }
2350  /* Create the new array */
2351  RexxArray *temp = (RexxArray *)new_externalArray(total_size, arrayClass);
2352  /* put dimension array in new arr */
2353  OrefSet(temp, temp->dimensions, dim_array);
2354  ProtectedObject p(temp);
2355  temp->sendMessage(OREF_INIT); /* call any rexx init's */
2356  return temp;
2357 }
2358 
2359 
2371 void RexxArray::mergeSort(BaseSortComparator &comparator, RexxArray *working, size_t left, size_t right)
2372 {
2373  size_t len = right - left + 1; // total size of the range
2374  // use insertion sort for small arrays
2375  if (len <= 7) {
2376  for (size_t i = left + 1; i <= right; i++) {
2377  RexxObject *current = get(i);
2378  RexxObject *prev = get(i - 1);
2379  if (comparator.compare(current, prev) < 0) {
2380  size_t j = i;
2381  do {
2382  put(prev, j--);
2383  } while (j > left && comparator.compare(current, prev = get(j - 1)) < 0);
2384  put(current, j);
2385  }
2386  }
2387  return;
2388  }
2389 
2390  size_t mid = (right + left) / 2;
2391  mergeSort(comparator, working, left, mid);
2392  mergeSort(comparator, working, mid + 1, right);
2393  merge(comparator, working, left, mid + 1, right);
2394 }
2395 
2396 
2407 void RexxArray::merge(BaseSortComparator &comparator, RexxArray *working, size_t left, size_t mid, size_t right)
2408 {
2409  size_t leftEnd = mid - 1;
2410  // merging
2411 
2412  // if arrays are already sorted - no merge
2413  if (comparator.compare(get(leftEnd), get(mid)) <= 0) {
2414  return;
2415  }
2416 
2417  size_t leftCursor = left;
2418  size_t rightCursor = mid;
2419  size_t workingPosition = left;
2420 
2421  // use merging with exponential search
2422  do
2423  {
2424  RexxObject *fromVal = get(leftCursor);
2425  RexxObject *rightVal = get(rightCursor);
2426  // if the left value is the smaller one, so we try to find the
2427  // insertion point of the right value into the left side of the
2428  // the array
2429  if (comparator.compare(fromVal, rightVal) <= 0)
2430  {
2431  // try to find an insertion point in the remaining left-hand elements
2432  size_t leftInsertion = find(comparator, rightVal, -1, leftCursor + 1, leftEnd);
2433  // we start copying with the left-hand bound up to the insertion point
2434  size_t toCopy = leftInsertion - leftCursor + 1;
2435  arraycopy(this, leftCursor, working, workingPosition, toCopy);
2436  workingPosition += toCopy;
2437  // add the inserted position
2438  working->put(rightVal, workingPosition++);
2439  // now we've added this
2440  rightCursor++;
2441  // step over the section we just copied...which might be
2442  // all of the remaining section
2443  leftCursor = leftInsertion + 1;
2444  }
2445  else
2446  {
2447  // find the insertion point of the left value into the remaining right
2448  // hand section
2449  size_t rightInsertion = find(comparator, fromVal, 0, rightCursor + 1, right);
2450  size_t toCopy = rightInsertion - rightCursor + 1;
2451  arraycopy(this, rightCursor, working, workingPosition, toCopy);
2452  workingPosition += toCopy;
2453  // insert the right-hand value
2454  working->put(fromVal, workingPosition++);
2455  leftCursor++;
2456  rightCursor = rightInsertion + 1;
2457  }
2458  } while (right >= rightCursor && mid > leftCursor);
2459 
2460  // copy rest of array. If we've not used up the left hand side,
2461  // we copy that. Otherwise, there are items on the right side
2462  if (leftCursor < mid)
2463  {
2464  arraycopy(this, leftCursor, working, workingPosition, mid - leftCursor);
2465  }
2466  else
2467  {
2468  arraycopy(this, rightCursor, working, workingPosition, right - rightCursor + 1);
2469  }
2470 
2471  // finally, copy everything back into the the target array.
2472  arraycopy(working, left, this, left, right - left + 1);
2473 }
2474 
2475 
2485 void RexxArray::arraycopy(RexxArray *source, size_t start, RexxArray *target, size_t index, size_t count)
2486 {
2487  for (size_t i = start; i < start + count; i++)
2488  {
2489  target->put(source->get(i), index++);
2490  }
2491 }
2492 
2493 
2510 size_t RexxArray::find(BaseSortComparator &comparator, RexxObject *val, int limit, size_t left, size_t right)
2511 {
2512  size_t checkPoint = left;
2513  size_t delta = 1;
2514  while (checkPoint <= right)
2515  {
2516  // if this is too big, then we're moving to the right
2517  if (comparator.compare(val, get(checkPoint)) > limit)
2518  {
2519  // the left bound is at least this
2520  left = checkPoint + 1;
2521  }
2522  else
2523  {
2524  // we've found a right limit. We can stop scanning here
2525  right = checkPoint - 1;
2526  break;
2527  }
2528  // step the delta amount
2529  checkPoint += delta;
2530  // and double the movement amount
2531  delta = delta * 2;
2532  }
2533  // we should have now limited the bounds for the insertion point
2534  // now start in the middle and shrink the range with each comparison
2535  while (left <= right)
2536  {
2537  // start in the middle of the current range
2538  checkPoint = (left + right) / 2;
2539  if (comparator.compare(val, get(checkPoint)) > limit)
2540  {
2541  // pull in the left end of the range
2542  left = checkPoint + 1;
2543  }
2544  else
2545  {
2546  // chop the right range
2547  right = checkPoint - 1;
2548  }
2549  }
2550 
2551  // the left bound is the insertion point
2552  return left - 1;
2553 }
2554 
2555 
2563 {
2564  size_t count = items();
2565  if (count == 0) // if the count is zero, sorting is easy!
2566  {
2567  return this;
2568  }
2569 
2570  // make sure this is a non-sparse array. Checking up front means we don't
2571  // need to check on each compare operation.
2572  for (size_t i = 1; i <= count; i++)
2573  {
2574  if (get(i) == OREF_NULL)
2575  {
2577  }
2578  }
2579 
2580  // the merge sort requires a temporary scratch area for the sort.
2581  RexxArray *working = new_array(count);
2582  ProtectedObject p(working);
2583 
2584  BaseSortComparator comparator;
2585 
2586  // go do the quick sort
2587  mergeSort(comparator, working, 1, count);
2588  return this;
2589 }
2590 
2591 
2599 {
2600  requiredArgument(comparator, ARG_ONE);
2601 
2602  size_t count = items();
2603  if (count <= 1) // if the count is zero, sorting is easy!
2604  {
2605  return this;
2606  }
2607 
2608  // make sure this is a non-sparse array. Checking up front means we don't
2609  // need to check on each compare operation.
2610  for (size_t i = 1; i <= count; i++)
2611  {
2612  if (get(i) == OREF_NULL)
2613  {
2615  }
2616  }
2617 
2618  // the merge sort requires a temporary scratch area for the sort.
2619  RexxArray *working = new_array(count);
2620  ProtectedObject p(working);
2621 
2622  WithSortComparator c(comparator);
2623 
2624  // go do the quick sort
2625  mergeSort(c, working, 1, count);
2626  return this;
2627 }
2628 
2629 
2630 void * RexxArray::operator new(size_t size, RexxObject *first)
2631 /******************************************************************************/
2632 /* Function: Create an array with 1 element (new_array1) */
2633 /******************************************************************************/
2634 {
2635  RexxArray *aref;
2636 
2637  aref = (RexxArray *)new_array(1);
2638  aref->put(first, 1);
2639 
2640  return aref;
2641 }
2642 
2643 void * RexxArray::operator new(size_t size, RexxObject *first, RexxObject *second)
2644 {
2645  RexxArray *aref;
2646 
2647  aref = new_array(2);
2648  aref->put(first, 1);
2649  aref->put(second, 2);
2650  return aref;
2651 }
2652 
2653 void * RexxArray::operator new(size_t size,
2654  RexxObject *first,
2655  RexxObject *second,
2656  RexxObject *third)
2657 /******************************************************************************/
2658 /* Function: Create an array with 3 elements (new_array3) */
2659 /******************************************************************************/
2660 {
2661  RexxArray *aref;
2662 
2663  aref = new_array(3);
2664  aref->put(first, 1);
2665  aref->put(second, 2);
2666  aref->put(third, 3);
2667 
2668  return aref;
2669 }
2670 
2671 void * RexxArray::operator new(size_t size,
2672  RexxObject *first,
2673  RexxObject *second,
2674  RexxObject *third,
2675  RexxObject *fourth)
2676 /******************************************************************************/
2677 /* Function: Create an array with 4 elements (new_array4) */
2678 /******************************************************************************/
2679 {
2680  RexxArray *aref;
2681 
2682  aref = new_array(4);
2683  aref->put(first, 1);
2684  aref->put(second, 2);
2685  aref->put(third, 3);
2686  aref->put(fourth, 4);
2687 
2688  return aref;
2689 }
2690 
2691 void *RexxArray::operator new(size_t newSize, size_t size, size_t maxSize, RexxClass *arrayClass)
2692 /******************************************************************************/
2693 /* Function: Low level array creation */
2694 /******************************************************************************/
2695 {
2696  size_t bytes;
2697  RexxArray *newArray;
2698  /* is hintsize lower than minimal */
2699  if (maxSize <= ARRAY_MIN_SIZE)
2700  { /* allocation array size? */
2701  maxSize = ARRAY_MIN_SIZE; /* yes, we will actually min size */
2702  }
2703  // if the max is smaller than the size, just use the max size.
2704  if (maxSize < size)
2705  {
2706  maxSize = size;
2707  }
2708  /* compute size of new array obj */
2709  bytes = newSize + (sizeof(RexxObject *) * (maxSize - 1));
2710  /* Create the new array */
2711  newArray = (RexxArray *)new_object(bytes);
2712  /* Give it array behaviour. */
2713  newArray->setBehaviour(arrayClass->getInstanceBehaviour());
2714 
2715  newArray->arraySize = size;
2716  newArray->maximumSize = maxSize;
2717  /* no expansion yet, use ourself */
2718  newArray->expansionArray = newArray;
2719  /* moved _after_ setting hashvalue, otherwise the uninit table will not be*/
2720  /* able to find the new array object again later! */
2721  if (arrayClass->hasUninitDefined())
2722  {/* does object have an UNINT method */
2723  ProtectedObject p(newArray);
2724  /* require new REXX objects */
2725  newArray->hasUninit(); /* Make sure everyone is notified. */
2726  }
2727  return newArray; /* return the new array to caller */
2728 }
2729 
2730 RexxObject * RexxArray::newRexx(RexxObject **arguments, size_t argCount)
2731 /******************************************************************************/
2732 /* Function: Exported ARRAY NEW method */
2733 /******************************************************************************/
2734 {
2735  return new (arguments, argCount, (RexxClass *) this) RexxArray;
2736 }
2737 
2738 RexxObject *RexxArray::of(RexxObject **args, size_t argCount)
2739 /******************************************************************************/
2740 /* Function: Exported REXX OF method */
2741 /******************************************************************************/
2742 {
2743  RexxArray *newArray; /* new array item */
2744  size_t i; /* loop index */
2745  RexxObject*item; /* individual array item */
2746 
2747  /* is array obj to be from internal */
2748  if (TheArrayClass != (RexxClass *)this)
2749  {
2750  /* nope, better create properly */
2751  ProtectedObject result;
2752  /* send new to actual class. */
2753  this->sendMessage(OREF_NEW, new_integer(argCount), result);
2754  newArray = (RexxArray *)result;
2755  /* For each argument to of, send a */
2756  /* put message */
2757  for (i = 0; i < argCount; i++)
2758  {
2759  item = args[i]; /* get the item */
2760  if (item != OREF_NULL) /* have a real item here? */
2761  {
2762  /* place it in the target array */
2763  newArray->sendMessage(OREF_PUT, item, new_integer(i+1));
2764  }
2765  }
2766  return newArray;
2767  }
2768  else
2769  {
2770  newArray = new (argCount, args) RexxArray;
2771  if (argCount == 0)
2772  { /* creating 0 sized array? */
2773  /* Yup, setup a Dimension array */
2774  /* single Dimension, Mark so */
2775  /* can't change Dimensions. */
2776  OrefSet(newArray, newArray->dimensions, new_array(IntegerZero));
2777  }
2778  /* argument array is exactly what */
2779  /* we want, so just return it */
2780  return newArray;
2781  }
2782 
2783 }
2784 
2785 
2787 {
2788  return first->compareTo(second);
2789 }
2790 
2791 
2793 {
2794  ProtectedObject result;
2795  comparator->sendMessage(OREF_COMPARE, first, second, result);
2796  if ((RexxObject *)result == OREF_NULL)
2797  {
2799  }
2800 
2801  wholenumber_t comparison;
2802  if (!((RexxObject *)result)->numberValue(comparison, Numerics::DEFAULT_DIGITS))
2803  {
2805  }
2806  return comparison;
2807 }
RexxArray::createMultidimensional
static RexxArray * createMultidimensional(RexxObject **dims, size_t count, RexxClass *)
Definition: ArrayClass.cpp:2316
RexxObject::makeString
RexxString * makeString()
Definition: ObjectClass.cpp:1070
RaiseBoundsTooMany
#define RaiseBoundsTooMany
Definition: ArrayClass.hpp:50
copyElements
void copyElements(COPYELEMENTPARM *parm, size_t newDimension)
Definition: ArrayClass.cpp:1912
RexxArray::hasItem
RexxObject * hasItem(RexxObject *)
Definition: ArrayClass.cpp:1902
RexxObject::copy
RexxObject * copy()
Definition: ObjectClass.cpp:518
TheArrayClass
#define TheArrayClass
Definition: RexxCore.h:148
RexxObject::sendMessage
void sendMessage(RexxString *, RexxArray *, ProtectedObject &)
Definition: ObjectClass.cpp:668
RexxArray::insert
size_t insert(RexxObject *_value, size_t index)
Definition: ArrayClass.cpp:2198
RexxArray::getRexx
RexxObject * getRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:503
RexxArray::getDimension
size_t getDimension()
Definition: ArrayClass.cpp:690
new_array
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:250
RexxArray
Definition: ArrayClass.hpp:100
RexxArray::validateIndex
bool validateIndex(RexxObject **, size_t, size_t, size_t, stringsize_t &)
Definition: ArrayClass.cpp:832
RexxArray::remove
RexxObject * remove(size_t)
Definition: ArrayClass.cpp:590
RexxArray::live
void live(size_t)
Definition: ArrayClass.cpp:143
copyElementParm::startOld
RexxObject ** startOld
Definition: ArrayClass.hpp:64
RexxArray::hasIndexApi
bool hasIndexApi(size_t)
Definition: ArrayClass.cpp:573
Error_Incorrect_method_minsub
#define Error_Incorrect_method_minsub
Definition: RexxErrorCodes.h:477
RexxArray::insertRexx
RexxObject * insertRexx(RexxObject *_value, RexxObject *index)
Definition: ArrayClass.cpp:338
RexxObject::newRexx
RexxObject * newRexx(RexxObject **arguments, size_t argCount)
Definition: ObjectClass.cpp:2299
RexxArray::classInstance
static RexxClass * classInstance
Definition: ArrayClass.hpp:216
TheFalseObject
#define TheFalseObject
Definition: RexxCore.h:184
RaiseBoundsInvalid
#define RaiseBoundsInvalid
Definition: ArrayClass.hpp:49
RexxMutableBuffer::append
RexxMutableBuffer * append(RexxObject *)
Definition: MutableBufferClass.cpp:325
RexxArray::putApi
void putApi(RexxObject *eref, size_t pos)
Definition: ArrayClass.cpp:551
RexxArray::previousRexx
RexxObject * previousRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:1351
new_integer
RexxInteger * new_integer(wholenumber_t v)
Definition: IntegerClass.hpp:198
RexxInternalObject::isNewSpace
bool isNewSpace()
Definition: ObjectClass.hpp:253
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
memoryObject
RexxMemory memoryObject
Definition: RexxMemory.cpp:84
RexxMutableBuffer
Definition: MutableBufferClass.hpp:61
RexxObject::equalValue
bool equalValue(RexxObject *other)
Definition: ObjectClass.hpp:499
RexxArray::copy
RexxObject * copy()
Definition: ArrayClass.cpp:120
RexxInternalObject::behaviour
RexxBehaviour * behaviour
Definition: ObjectClass.hpp:306
RexxArray::dataSize
size_t dataSize()
Definition: ArrayClass.hpp:231
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
Error_Execution_sparse_array
#define Error_Execution_sparse_array
Definition: RexxErrorCodes.h:553
copyElementParm
Definition: ArrayClass.hpp:55
RexxArray::deleteRexx
RexxObject * deleteRexx(RexxObject *index)
Definition: ArrayClass.cpp:379
RexxArray::data
RexxObject ** data()
Definition: ArrayClass.hpp:202
RexxArray::lastItem
RexxObject * lastItem()
Definition: ArrayClass.cpp:1298
RexxArray::objects
RexxObject * objects[1]
Definition: ArrayClass.hpp:241
IntegerClass.hpp
ExtendUpper
#define ExtendUpper
Definition: ArrayClass.hpp:52
RexxArray::sectionSubclass
RexxObject * sectionSubclass(size_t, size_t)
Definition: ArrayClass.cpp:1179
BaseSortComparator
Definition: ArrayClass.hpp:84
ActivityManager.hpp
RexxArray::section
RexxArray * section(size_t, size_t)
Definition: ArrayClass.cpp:1075
SupplierClass.hpp
new_supplier
RexxSupplier * new_supplier(RexxArray *c, RexxArray *f)
Definition: SupplierClass.hpp:80
Error_Incorrect_method_minarg
#define Error_Incorrect_method_minarg
Definition: RexxErrorCodes.h:454
RexxArray::index
RexxObject * index(RexxObject *)
Definition: ArrayClass.cpp:1852
RexxObject::compareTo
virtual wholenumber_t compareTo(RexxObject *)
Definition: ObjectClass.cpp:186
RexxArray::itemsRexx
RexxObject * itemsRexx()
Definition: ArrayClass.cpp:682
requiredArgument
void requiredArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:284
RexxArray::indexOf
size_t indexOf(RexxObject *)
Definition: ArrayClass.cpp:1696
RexxArray::fill
RexxObject * fill(RexxObject *)
Definition: ArrayClass.cpp:247
RexxArray::size
size_t size()
Definition: ArrayClass.hpp:200
RexxArray::dimension
RexxObject * dimension(RexxObject *)
Definition: ArrayClass.cpp:726
RexxArray::mergeSort
void mergeSort(BaseSortComparator &comparator, RexxArray *working, size_t left, size_t right)
Definition: ArrayClass.cpp:2371
RexxArray::findSingleIndexItem
size_t findSingleIndexItem(RexxObject *item)
Definition: ArrayClass.cpp:1763
ARG_TWO
const int ARG_TWO
Definition: RexxCore.h:81
RexxArray::items
size_t items()
Definition: ArrayClass.cpp:660
RexxArray::allIndexes
RexxArray * allIndexes()
Definition: ArrayClass.cpp:1486
Error_Incorrect_method_noarg
#define Error_Incorrect_method_noarg
Definition: RexxErrorCodes.h:457
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxArray::liveGeneral
void liveGeneral(int reason)
Definition: ArrayClass.cpp:161
Error_Incorrect_method_array_dimension
#define Error_Incorrect_method_array_dimension
Definition: RexxErrorCodes.h:503
RexxArray::ARRAY_DEFAULT_SIZE
static const size_t ARRAY_DEFAULT_SIZE
Definition: ArrayClass.hpp:220
Numerics::MAX_WHOLENUMBER
static const wholenumber_t MAX_WHOLENUMBER
Definition: Numerics.hpp:62
RexxArray::allItems
RexxArray * allItems()
Definition: ArrayClass.cpp:1459
RexxArray::extend
RexxArray * extend(size_t)
Definition: ArrayClass.cpp:1715
TheTrueObject
#define TheTrueObject
Definition: RexxCore.h:185
MutableBufferClass.hpp
RexxString::getStringData
const char * getStringData()
Definition: StringClass.hpp:333
RexxArray::isSingleDimensional
bool isSingleDimensional()
Definition: ArrayClass.hpp:210
copyElementParm::newArray
RexxArray * newArray
Definition: ArrayClass.hpp:57
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxObject::requiredString
RexxString * requiredString(size_t)
Definition: ObjectClass.cpp:1220
copyElementParm::copyElements
size_t copyElements
Definition: ArrayClass.hpp:61
IntegerZero
#define IntegerZero
Definition: RexxCore.h:188
RexxArray::openGap
void openGap(size_t index, size_t elements)
Definition: ArrayClass.cpp:406
RexxArray::get
RexxObject * get(size_t pos)
Definition: ArrayClass.hpp:201
RexxArray::ensureSpace
void ensureSpace(size_t newSize)
Definition: ArrayClass.cpp:1042
RexxArray::arraySize
size_t arraySize
Definition: ArrayClass.hpp:236
copyElementParm::deltaDimSize
size_t deltaDimSize
Definition: ArrayClass.hpp:60
RexxArray::removeRexx
RexxObject * removeRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:623
isOfClass
#define isOfClass(t, r)
Definition: RexxCore.h:211
RexxArray::ARRAY_MIN_SIZE
static const size_t ARRAY_MIN_SIZE
Definition: ArrayClass.hpp:219
RexxArray::supplier
RexxObject * supplier()
Definition: ArrayClass.cpp:783
RexxMutableBufferClass
Definition: MutableBufferClass.hpp:54
RexxArray::isEmpty
RexxObject * isEmpty()
Definition: ArrayClass.cpp:295
new_string
RexxString * new_string(const char *s, stringsize_t l)
Definition: StringClass.hpp:524
RexxArray::nullArray
static RexxArray * nullArray
Definition: ArrayClass.hpp:217
WithSortComparator
Definition: ArrayClass.hpp:91
ARG_ONE
const int ARG_ONE
Definition: RexxCore.h:80
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxArray::setExpansion
void setExpansion(RexxObject *expansion)
Definition: ArrayClass.cpp:815
RexxArray::RexxArray
RexxArray()
Definition: ArrayClass.hpp:124
ArrayClass.hpp
Error_Incorrect_method_section
#define Error_Incorrect_method_section
Definition: RexxErrorCodes.h:497
RexxArray::slotAddress
RexxObject ** slotAddress(size_t index)
Definition: ArrayClass.hpp:230
RexxObject::init
RexxObject * init()
Definition: ObjectClass.cpp:2257
RexxObject::primitiveMakeString
RexxString * primitiveMakeString()
Definition: ObjectClass.cpp:1095
RexxArray::put
void put(RexxObject *eref, size_t pos)
Definition: ArrayClass.cpp:203
RexxArray::getDimensions
RexxObject * getDimensions()
Definition: ArrayClass.cpp:711
RexxBehaviour::getOwningClass
RexxClass * getOwningClass()
Definition: RexxBehaviour.hpp:97
copyElementParm::startNew
RexxObject ** startNew
Definition: ArrayClass.hpp:63
RexxArray::maximumSize
size_t maximumSize
Definition: ArrayClass.hpp:237
RexxClass
Definition: ClassClass.hpp:49
RexxArray::dimensions
RexxArray * dimensions
Definition: ArrayClass.hpp:239
RexxInternalObject::setBehaviour
void setBehaviour(RexxBehaviour *b)
Definition: ObjectClass.hpp:265
ProtectedObject.hpp
RexxArray::MAX_FIXEDARRAY_SIZE
static const size_t MAX_FIXEDARRAY_SIZE
Definition: ArrayClass.hpp:234
RexxArray::isMultiDimensional
bool isMultiDimensional()
Definition: ArrayClass.hpp:209
RexxArray::arraycopy
static void arraycopy(RexxArray *source, size_t start, RexxArray *target, size_t index, size_t count)
Definition: ArrayClass.cpp:2485
RexxObject::requiredNonNegative
stringsize_t requiredNonNegative(size_t position, size_t precision=Numerics::ARGUMENT_DIGITS)
Definition: ObjectClass.cpp:1442
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
Error_Incorrect_method_maxsub
#define Error_Incorrect_method_maxsub
Definition: RexxErrorCodes.h:478
ProtectedObject
Definition: ProtectedObject.hpp:46
WithSortComparator::compare
virtual wholenumber_t compare(RexxObject *first, RexxObject *second)
Definition: ArrayClass.cpp:2792
RexxArray::convertIndex
RexxObject * convertIndex(size_t idx)
Definition: ArrayClass.cpp:1791
RexxInternalObject::isOldSpace
bool isOldSpace()
Definition: ObjectClass.hpp:252
Error_Invalid_whole_number_compare
#define Error_Invalid_whole_number_compare
Definition: RexxErrorCodes.h:233
RexxArray::stableSortRexx
RexxArray * stableSortRexx()
Definition: ArrayClass.cpp:2562
Error_Incorrect_method_maxarg
#define Error_Incorrect_method_maxarg
Definition: RexxErrorCodes.h:456
RexxArray::closeGap
void closeGap(size_t index, size_t elements)
Definition: ArrayClass.cpp:444
copyElementParm::oldDimArray
RexxArray * oldDimArray
Definition: ArrayClass.hpp:59
CHAR_APPEND
char CHAR_APPEND[]
WithSortComparator::comparator
RexxObject * comparator
Definition: ArrayClass.hpp:96
RexxArray::flatten
void flatten(RexxEnvelope *)
Definition: ArrayClass.cpp:176
RexxArray::sectionRexx
RexxObject * sectionRexx(RexxObject *, RexxObject *)
Definition: ArrayClass.cpp:1117
RexxArray::getApi
RexxObject * getApi(size_t pos)
Definition: ArrayClass.cpp:533
IntegerOne
#define IntegerOne
Definition: RexxCore.h:189
RexxArray::appendRexx
RexxObject * appendRexx(RexxObject *)
Definition: ArrayClass.cpp:308
Numerics::DEFAULT_DIGITS
static const size_t DEFAULT_DIGITS
Definition: Numerics.hpp:66
Error_Incorrect_method_array
#define Error_Incorrect_method_array
Definition: RexxErrorCodes.h:472
CLASS_CREATE
#define CLASS_CREATE(name, id, className)
Definition: RexxMemory.hpp:445
RexxArray::append
size_t append(RexxObject *)
Definition: ArrayClass.cpp:482
RexxArray::of
RexxObject * of(RexxObject **, size_t)
Definition: ArrayClass.cpp:2738
RexxArray::merge
void merge(BaseSortComparator &comparator, RexxArray *working, size_t left, size_t mid, size_t right)
Definition: ArrayClass.cpp:2407
Numerics::minVal
static wholenumber_t minVal(wholenumber_t n1, wholenumber_t n2)
Definition: Numerics.hpp:116
RexxMutableBuffer::makeString
RexxString * makeString()
Definition: MutableBufferClass.cpp:598
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
RexxArray::toString
RexxString * toString(RexxString *, RexxString *)
Definition: ArrayClass.cpp:1524
Error_No_result_object_message
#define Error_No_result_object_message
Definition: RexxErrorCodes.h:437
line_end
#define line_end
Definition: PlatformDefinitions.h:164
RexxArray::makeArray
RexxArray * makeArray()
Definition: ArrayClass.cpp:1443
RexxArray::join
RexxObject * join(RexxArray *)
Definition: ArrayClass.cpp:1630
missingArgument
void missingArgument(size_t argumentPosition)
Definition: ActivityManager.hpp:246
RexxArray::removeItem
RexxObject * removeItem(RexxObject *)
Definition: ArrayClass.cpp:1876
RexxArray::newRexx
RexxObject * newRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:2730
wholenumber_t
ssize_t wholenumber_t
Definition: rexx.h:229
RexxArray::indexToArray
RexxObject * indexToArray(size_t idx)
Definition: ArrayClass.cpp:1814
RexxArray::sizeRexx
RexxInteger * sizeRexx()
Definition: ArrayClass.cpp:1059
TheNullArray
#define TheNullArray
Definition: RexxCore.h:182
copyElementParm::firstChangedDimension
size_t firstChangedDimension
Definition: ArrayClass.hpp:56
RexxInternalObject::getValue
virtual RexxObject * getValue(RexxActivation *)
Definition: ObjectClass.hpp:270
stringsize_t
size_t stringsize_t
Definition: rexx.h:228
number_digits
size_t number_digits()
Definition: Numerics.hpp:147
RexxArray::lastElement
size_t lastElement
Definition: ArrayClass.hpp:238
RexxArray::hasIndexRexx
RexxObject * hasIndexRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:1395
RexxArray::lastRexx
RexxObject * lastRexx()
Definition: ArrayClass.cpp:1251
RexxArray::deleteItem
RexxObject * deleteItem(size_t index)
Definition: ArrayClass.cpp:2216
RexxArray::shrink
void shrink(size_t)
Definition: ArrayClass.cpp:1677
RexxArray::nextRexx
RexxObject * nextRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:1318
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
TheNilObject
#define TheNilObject
Definition: RexxCore.h:180
RexxObject::start
RexxMessage * start(RexxObject **, size_t)
Definition: ObjectClass.cpp:1761
Error_Incorrect_method_array_too_big
#define Error_Incorrect_method_array_too_big
Definition: RexxErrorCodes.h:507
RexxArray::firstItem
RexxObject * firstItem()
Definition: ArrayClass.cpp:1272
RexxArray::available
RexxInteger * available(size_t position)
Definition: ArrayClass.cpp:823
new_externalArray
RexxArray * new_externalArray(size_t s, RexxClass *c)
Definition: ArrayClass.hpp:245
copyElementParm::newDimArray
RexxArray * newDimArray
Definition: ArrayClass.hpp:58
RexxArray::expansionArray
RexxArray * expansionArray
Definition: ArrayClass.hpp:240
RexxActivity.hpp
Error_Incorrect_method_option
#define Error_Incorrect_method_option
Definition: RexxErrorCodes.h:468
stringArgument
RexxString * stringArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:296
BaseSortComparator::compare
virtual wholenumber_t compare(RexxObject *first, RexxObject *second)
Definition: ArrayClass.cpp:2786
RexxArray::resize
void resize()
Definition: ArrayClass.cpp:1649
RaiseBoundsUpper
#define RaiseBoundsUpper
Definition: ArrayClass.hpp:48
RexxArray::empty
RexxObject * empty()
Definition: ArrayClass.cpp:267
RexxArray::hasIndexNative
bool hasIndexNative(size_t)
Definition: ArrayClass.cpp:1427
RexxCore.h
RexxArray::createInstance
static void createInstance()
Definition: ArrayClass.cpp:93
TheMutableBufferClass
#define TheMutableBufferClass
Definition: RexxCore.h:163
RexxObject::requiredPositive
stringsize_t requiredPositive(size_t position, size_t precision=Numerics::ARGUMENT_DIGITS)
Definition: ObjectClass.cpp:1423
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
RexxArray::extendMulti
RexxArray * extendMulti(RexxObject **, size_t, size_t)
Definition: ArrayClass.cpp:1992
RexxInteger
Definition: IntegerClass.hpp:56
RexxArray::find
size_t find(BaseSortComparator &comparator, RexxObject *val, int bnd, size_t left, size_t right)
Definition: ArrayClass.cpp:2510
RexxArray::stableSortWithRexx
RexxArray * stableSortWithRexx(RexxObject *comparator)
Definition: ArrayClass.cpp:2598
RexxArray::firstRexx
RexxObject * firstRexx()
Definition: ArrayClass.cpp:1224
copyElementParm::skipElements
size_t skipElements
Definition: ArrayClass.hpp:62
RexxMemory::reSize
void reSize(RexxObject *, size_t)
Definition: RexxMemory.cpp:1249
RexxObject
Definition: ObjectClass.hpp:311
RexxString
Definition: StringClass.hpp:119
RexxArray::lastIndex
size_t lastIndex()
Definition: ArrayClass.cpp:1310
RexxArray::putRexx
RexxObject * putRexx(RexxObject **, size_t)
Definition: ArrayClass.cpp:222