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)  

MutableBufferClass.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 MutableBuffer Class */
42 /* */
43 /******************************************************************************/
44 #include <ctype.h>
45 #include <stdlib.h>
46 #include <string.h>
47 
48 #include "RexxCore.h"
49 #include "StringClass.hpp"
50 #include "MutableBufferClass.hpp"
51 #include "ProtectedObject.hpp"
52 #include "StringUtil.hpp"
53 
54 
55 // singleton class instance
57 
58 
59 
64 {
65  CLASS_CREATE(MutableBuffer, "MutableBuffer", RexxClass);
66 }
67 
68 
69 #define DEFAULT_BUFFER_LENGTH 256
70 
72 /******************************************************************************/
73 /* Function: Allocate (and initialize) a string object */
74 /******************************************************************************/
75 {
76  RexxString *string;
77  RexxMutableBuffer *newBuffer; /* new mutable buffer object */
78  size_t bufferLength = DEFAULT_BUFFER_LENGTH;
79  size_t defaultSize;
80  if (argc >= 1)
81  {
82  if (args[0] != NULL)
83  {
84  /* force argument to string value */
85  string = stringArgument(args[0], ARG_ONE);
86  }
87  else
88  {
89  string = OREF_NULLSTRING; /* default to empty content */
90  }
91  }
92  else /* minimum buffer size given? */
93  {
94  string = OREF_NULLSTRING;
95  }
96 
97  if (argc >= 2)
98  {
99  bufferLength = optionalLengthArgument(args[1], DEFAULT_BUFFER_LENGTH, ARG_TWO);
100  }
101 
102  defaultSize = bufferLength; /* remember initial default size */
103 
104  /* input string longer than demanded */
105  /* minimum size? expand accordingly */
106  if (string->getLength() > bufferLength)
107  {
108  bufferLength = string->getLength();
109  }
110  /* allocate the new object */
111  newBuffer = new ((RexxClass *)this) RexxMutableBuffer(bufferLength, defaultSize);
112  newBuffer->dataLength = string->getLength();
113  /* copy the content */
114  newBuffer->copyData(0, string->getStringData(), string->getLength());
115 
116  ProtectedObject p(newBuffer);
117  newBuffer->sendMessage(OREF_INIT, args, argc > 2 ? argc - 2 : 0);
118  return newBuffer;
119 }
120 
121 
126 {
127  bufferLength = DEFAULT_BUFFER_LENGTH; /* save the length of the buffer */
128  defaultSize = bufferLength; /* store the default buffer size */
129  // NB: we clear this before we allocate the new buffer because allocating the
130  // new buffer might trigger a garbage collection, causing us to mark bogus
131  // reference.
132  data = OREF_NULL;
134 
135 }
136 
137 
145 {
146  bufferLength = l; /* save the length of the buffer */
147  defaultSize = d; /* store the default buffer size */
148  // NB: As in the default constructor, we clear this before we allocate the
149  // new buffer in case garbage collection is triggered.
150  data = OREF_NULL;
152 }
153 
154 
163 void *RexxMutableBuffer::operator new(size_t size)
164 {
165  return new_object(size, T_MutableBuffer);
166 }
167 
178 void *RexxMutableBuffer::operator new(size_t size, RexxClass *bufferClass)
179 {
180  RexxObject * newObj = new_object(size, T_MutableBuffer);
181  newObj->setBehaviour(bufferClass->getInstanceBehaviour());
182  return newObj;
183 }
184 
185 
186 void RexxMutableBuffer::live(size_t liveMark)
187 /******************************************************************************/
188 /* Function: Normal garbage collection live marking */
189 /******************************************************************************/
190 {
191  memory_mark(this->objectVariables);
192  memory_mark(this->data);
193 }
194 
196 /******************************************************************************/
197 /* Function: Generalized object marking */
198 /******************************************************************************/
199 {
200  memory_mark_general(this->objectVariables);
201  memory_mark_general(this->data);
202 }
203 
204 
206 /******************************************************************************/
207 /* Function: Flatten a mutable buffer */
208 /******************************************************************************/
209 {
211 
212  flatten_reference(newThis->data, envelope);
213  flatten_reference(newThis->objectVariables, envelope);
214 
216 }
217 
219 /******************************************************************************/
220 /* Function: copy an object */
221 /******************************************************************************/
222 {
223 
224  RexxMutableBuffer *newObj = (RexxMutableBuffer *)this->clone();
225 
226  /* see the comments in ::newRexx()!! */
227  newObj->data = new_buffer(bufferLength);
228  newObj->dataLength = this->dataLength;
229  newObj->copyData(0, data->getData(), bufferLength);
230 
231  newObj->defaultSize = this->defaultSize;
232  newObj->bufferLength = this->bufferLength;
233  return newObj;
234 }
235 
236 void RexxMutableBuffer::ensureCapacity(size_t addedLength)
237 /******************************************************************************/
238 /* Function: append to the mutable buffer */
239 /******************************************************************************/
240 {
241  size_t resultLength = this->dataLength + addedLength;
242 
243  if (resultLength > bufferLength)
244  { /* need to enlarge? */
245  bufferLength *= 2; /* double the buffer */
246  if (bufferLength < resultLength)
247  { /* still too small? use new length */
248  bufferLength = resultLength;
249  }
250 
251  RexxBuffer *newBuffer = new_buffer(bufferLength);
252  // copy the data into the new buffer
253  newBuffer->copyData(0, data->getData(), dataLength);
254  // replace the old data buffer
255  OrefSet(this, this->data, newBuffer);
256  }
257 }
258 
259 
273 size_t RexxMutableBuffer::setDataLength(size_t newLength)
274 {
275  // cap the data length at the capacity
276  size_t capacity = this->getCapacity();
277  if (newLength > capacity)
278  {
279  newLength = capacity;
280  }
281 
282  size_t oldLength = this->getLength();
283  // set the new buffer length
284  dataLength = newLength;
285  // do we need to pad?
286  if (newLength > oldLength)
287  {
288  this->setData(oldLength, '\0', newLength - oldLength);
289  }
290 
291  return newLength;
292 }
293 
301 char *RexxMutableBuffer::setCapacity(size_t newLength)
302 {
303  // if the new length is longer than our current,
304  // extend by the delta
305  if (newLength > bufferLength)
306  {
307  ensureCapacity(newLength - bufferLength);
308  }
309  // return a pointer to the current buffer data
310  return getData();
311 }
312 
313 
320 {
321  return new_integer(dataLength);
322 }
323 
324 
326 /******************************************************************************/
327 /* Function: append to the mutable buffer */
328 /******************************************************************************/
329 {
330  RexxString *string = stringArgument(obj, ARG_ONE);
331  ProtectedObject p(string);
332  // make sure we have enough room
333  ensureCapacity(string->getLength());
334 
335  copyData(dataLength, string->getStringData(), string->getLength());
336  this->dataLength += string->getLength();
337  return this;
338 }
339 
340 
342 /******************************************************************************/
343 /* Function: insert string at given position */
344 /******************************************************************************/
345 {
346  // force this into string form
347  RexxString * string = stringArgument(str, ARG_ONE);
348 
349  // we're using optional length because 0 is valid for insert.
350  size_t begin = optionalNonNegative(pos, 0, ARG_TWO);
351  size_t insertLength = optionalLengthArgument(len, string->getLength(), ARG_THREE);
352 
353  char padChar = optionalPadArgument(pad, ' ', ARG_FOUR);
354 
355  size_t copyLength = Numerics::minVal(insertLength, string->getLength());
356  size_t padLength = insertLength - copyLength;
357 
358 
359  // if inserting within the current bounds, we only need to add the length
360  // if inserting beyond the end, we need to make sure we add space for the gap too
361  if (begin < dataLength)
362  {
363  // if inserting a zero length string, this is simple!
364  if (insertLength == 0)
365  {
366  return this; /* do nothing */
367  }
368  ensureCapacity(insertLength);
369  }
370  else
371  {
372  ensureCapacity(insertLength + (begin - dataLength));
373  }
374 
375 
376  /* create space in the buffer */
377  if (begin < dataLength)
378  {
379  openGap(begin, insertLength, dataLength - begin);
380  }
381  else if (begin > this->dataLength)
382  {
383  /* pad before insertion */
384  setData(dataLength, padChar, begin - dataLength);
385  }
386  /* insert string contents */
387  copyData(begin, string->getStringData(), copyLength);
388  // do we need data padding?
389  if (padLength > 0)
390  {
391  setData(begin + string->getLength(), padChar, padLength);
392  }
393  // inserting after the end? the resulting length is measured from the insertion point
394  if (begin > this->dataLength)
395  {
396  this->dataLength = begin + insertLength;
397  }
398  else
399  {
400  // just add in the inserted length
401  this->dataLength += insertLength;
402  }
403  return this;
404 }
405 
406 
408 /******************************************************************************/
409 /* Function: replace characters in buffer contents */
410 /******************************************************************************/
411 {
412  RexxString *string = stringArgument(str, ARG_ONE);
413  size_t begin = optionalPositionArgument(pos, 1, ARG_TWO) - 1;
414  size_t replaceLength = optionalLengthArgument(len, string->getLength(), ARG_THREE);
415 
416  char padChar = optionalPadArgument(pad, ' ', ARG_FOUR);
417 
418  // make sure we have room for this
419  ensureCapacity(begin + replaceLength);
420 
421  // is our start position beyond the current data end?
422  if (begin > dataLength)
423  {
424  // add padding to the gap
425  setData(dataLength, padChar, begin - dataLength);
426  }
427 
428  // now overlay the string data
429  copyData(begin, string->getStringData(), Numerics::minVal(replaceLength, string->getLength()));
430  // do we need additional padding?
431  if (replaceLength > string->getLength())
432  {
433  // pad the section after the overlay
434  setData(begin + string->getLength(), padChar, replaceLength - string->getLength());
435  }
436 
437  // did this add to the size?
438  if (begin + replaceLength > dataLength)
439  {
440  //adjust upward
441  dataLength = begin + replaceLength;
442  }
443  return this;
444 }
445 
446 
466 {
467  RexxString *string = stringArgument(str, ARG_ONE);
468  size_t begin = positionArgument(pos, ARG_TWO) - 1;
469  size_t newLength = string->getLength();
470  size_t replaceLength = optionalLengthArgument(len, newLength, ARG_THREE);
471 
472  char padChar = optionalPadArgument(pad, ' ', ARG_FOUR);
473  size_t finalLength;
474 
475  // if replaceLength extends beyond the end of the string
476  // then we cut it.
477  if (begin > dataLength)
478  {
479  replaceLength = 0;
480  }
481  else if (begin + replaceLength > dataLength)
482  {
483  replaceLength = dataLength - begin;
484  }
485 
486  // We need to add the delta between the excised string and the inserted
487  // replacement string.
488  //
489  // If this extends beyond the end of the string, then we require space for
490  // the position + the replacement string length. Else we find the required
491  // size (may be smaller than before)
492  if (begin > dataLength)
493  {
494  finalLength = begin - replaceLength + newLength;
495  }
496  else
497  {
498  finalLength = dataLength - replaceLength + newLength;
499  }
500 
501  // make sure we have room for this
502  ensureCapacity(finalLength);
503 
504  // is our start position beyond the current data end?
505  // NB: Even though we've adjusted the buffer size, the dataLength is still
506  // the original entry length.
507  if (begin > dataLength)
508  {
509  // add padding to the gap
510  setData(dataLength, padChar, begin - dataLength);
511  // now overlay the string data
512  copyData(begin, string->getStringData(), newLength);
513  }
514  else
515  {
516  // if the strings are of different lengths, we need to adjust the size
517  // of the gap we're copying into. Only adjust if there is a real gap
518  if (replaceLength != newLength && begin + replaceLength < dataLength)
519  {
520  // snip out the original string
521  adjustGap(begin, replaceLength, newLength);
522  }
523  // now overlay the string data
524  copyData(begin, string->getStringData(), newLength);
525  }
526 
527  // and finally adjust the length
528  dataLength = finalLength;
529  // our return value is always the target mutable buffer
530  return this;
531 }
532 
533 
535 /******************************************************************************/
536 /* Function: delete character range in buffer */
537 /******************************************************************************/
538 {
539  size_t begin = positionArgument(_start, ARG_ONE) - 1;
540  size_t range = optionalLengthArgument(len, this->data->getDataLength() - begin, ARG_TWO);
541 
542  // is the begin point actually within the string?
543  if (begin < dataLength)
544  { /* got some work to do? */
545  // deleting from the middle?
546  if (begin + range < dataLength)
547  {
548  // shift everything over
549  closeGap(begin, range, dataLength - (begin + range));
550  dataLength -= range;
551  }
552  else
553  {
554  // we're just truncating
555  dataLength = begin;
556  }
557  }
558  return this;
559 }
560 
561 
563 /******************************************************************************/
564 /* Function: set the size of the buffer */
565 /******************************************************************************/
566 {
567  size_t newsize = lengthArgument(size, ARG_ONE);
568  // has a reset to zero been requested?
569  if (newsize == 0)
570  {
571  // have we increased the buffer size?
573  {
574  // reallocate the buffer
575  OrefSet(this, this->data, new_buffer(defaultSize));
576  // reset the size to the default
578  }
579  dataLength = 0;
580  }
581  // an actual resize?
582  else if (newsize != bufferLength)
583  {
584  // reallocate the buffer
585  RexxBuffer *newBuffer = new_buffer(newsize);
586  // if we're shrinking this, it truncates.
588  newBuffer->copyData(0, data->getData(), dataLength);
589  // replace the old buffer
590  OrefSet(this, this->data, newBuffer);
591  // and update the size....
592  bufferLength = newsize;
593  }
594  return this;
595 }
596 
597 
599 /******************************************************************************/
600 /* Function: Handle a REQUEST('STRING') request for a mutablebuffer object */
601 /******************************************************************************/
602 {
603  return new_string(data->getData(), dataLength);
604 }
605 
612 {
613  // forward to the Rexx version with default arguments
614  return this->makeArrayRexx(OREF_NULL);
615 }
616 
625 {
626  // go straight to the string handler
627  return this->makeString();
628 }
629 
630 
631 /******************************************************************************/
632 /* Arguments: String position for substr */
633 /* requested length of new string */
634 /* pad character to use, if necessary */
635 /* */
636 /* Returned: string, sub string of original. */
637 /******************************************************************************/
639  RexxInteger *arglength,
640  RexxString *pad)
641 {
642  return StringUtil::substr(getStringData(), getLength(), argposition, arglength, pad);
643 }
644 
645 
656 {
657  return StringUtil::posRexx(getStringData(), getLength(), needle, pstart, range);
658 }
659 
660 
672 {
673  return StringUtil::lastPosRexx(getStringData(), getLength(), needle, _start, _range);
674 }
675 
676 
687 {
688  /* force needle to a string */
689  needle = stringArgument(needle, ARG_ONE);
690  /* get the starting position */
691  size_t _start = optionalPositionArgument(pstart, 1, ARG_TWO);
692  size_t _range = optionalLengthArgument(range, getLength() - _start + 1, ARG_THREE);
693  /* pass on to the primitive function */
694  /* and return as an integer object */
695  return new_integer(StringUtil::caselessPos(getStringData(), getLength(), needle , _start - 1, _range));
696 }
697 
698 
710 {
711  /* force needle to a string */
712  needle = stringArgument(needle, ARG_ONE);
713  /* get the starting position */
714  size_t _start = optionalPositionArgument(pstart, getLength(), ARG_TWO);
715  size_t _range = optionalLengthArgument(range, getLength(), ARG_THREE);
716  /* pass on to the primitive function */
717  /* and return as an integer object */
718  return new_integer(StringUtil::caselessLastPos(getStringData(), getLength(), needle , _start, _range));
719 }
720 
721 
736 {
737  return StringUtil::subchar(getStringData(), getLength(), positionArg);
738 }
739 
740 
742 /******************************************************************************/
743 /* Function: Split string into an array */
744 /******************************************************************************/
745 {
747 }
748 
749 
751 /******************************************************************************/
752 /* Function: Count occurrences of one string in another. */
753 /******************************************************************************/
754 {
755  /* force needle to a string */
756  needle = stringArgument(needle, ARG_ONE);
757  // delegate the counting to the string util
759 }
760 
762 /******************************************************************************/
763 /* Function: Count occurrences of one string in another. */
764 /******************************************************************************/
765 {
766  /* force needle to a string */
767  needle = stringArgument(needle, ARG_ONE);
768  // delegate the counting to the string util
770 }
771 
782 {
783  /* force needle to a string */
784  needle = stringArgument(needle, ARG_ONE);
785  /* newneedle must be a string two */
786  newNeedle = stringArgument(newNeedle, ARG_TWO);
787 
788  // we'll only change up to a specified count. If not there, we do everything.
789  size_t count = optionalPositive(countArg, Numerics::MAX_WHOLENUMBER, ARG_THREE);
790  // find the number of matches in the string
791  size_t matches = StringUtil::countStr(getStringData(), getLength(), needle);
792  if (matches > count) // the matches are bounded by the count
793  {
794  matches = count;
795  }
796  // no matches is easy!
797  if (matches == 0)
798  {
799  return this;
800  }
801  size_t needleLength = needle->getLength(); /* get the length of the needle */
802  size_t newLength = newNeedle->getLength(); /* and the replacement length */
803  // calculate the final length and make sure we have enough space
804  size_t resultLength = this->getLength() - (matches * needleLength) + (matches * newLength);
805  ensureCapacity(resultLength);
806 
807  // an inplace update has complications, depending on whether the new string is shorter,
808  // the same length, or longer
809 
810  // simplest case...same length strings. We can just overlay the existing occurrences
811  if (needleLength == newLength)
812  {
813  const char *source = getStringData();
814  size_t sourceLength = getLength();
815  size_t _start = 0; /* set a zero starting point */
816  for (size_t i = 0; i < matches; i++)
817  {
818  // search for the next occurrence...which should be there because we
819  // already know the count
820  size_t matchPos = StringUtil::pos(source, sourceLength, needle, _start, sourceLength);
821  copyData(matchPos - 1, newNeedle->getStringData(), newLength);
822  // step to the next search position
823  _start = matchPos + newLength - 1;
824  }
825  }
826  // this will be a shorter thing, so we can do things in place as if we were using two buffers
827  else if (needleLength > newLength)
828  {
829  // we start building from the beginning
830  size_t copyOffset = 0;
831  size_t _start = 0;
832  // get our string bounds
833  const char *source = getStringData();
834  size_t sourceLength = getLength();
835  const char *newPtr = newNeedle->getStringData();
836  // this is our scan offset
837  for (size_t i = 0; i < matches; i++)
838  {
839  // look for each instance and replace
840  size_t matchPos = StringUtil::pos(source, sourceLength, needle, _start, sourceLength);
841  size_t copyLength = (matchPos - 1) - _start; /* get the next length to copy */
842  // if this skipped over characters, we need to copy those
843  if (copyLength != 0)
844  {
845  copyData(copyOffset, source + _start, copyLength);
846  copyOffset += copyLength;
847  }
848  // replacing with a non-null string, copy the replacement string in
849  if (newLength != 0)
850  {
851  copyData(copyOffset, newPtr, newLength);
852  copyOffset += newLength;
853  }
854  _start = matchPos + needleLength - 1; /* step to the next position */
855  }
856  // we likely have some remainder that needs copying
857  if (_start < sourceLength)
858  {
859  copyData(copyOffset, source + _start, sourceLength - _start);
860  }
861  }
862  // hardest case...the string gets longer. We need to shift all of the data
863  // to the end and then pull the pieces back in as we go
864  else
865  {
866  size_t growth = (newLength - needleLength) * matches;
867 
868  // we start building from the beginning
869  size_t copyOffset = 0;
870  size_t _start = 0;
871  // get our string bounds
872  const char *source = getStringData() + growth;
873  size_t sourceLength = getLength();
874  // this shifts everything to the end of the buffer. From there,
875  // we pull pieces back into place.
876  openGap(0, growth, sourceLength);
877  const char *newPtr = newNeedle->getStringData();
878  // this is our scan offset
879  for (size_t i = 0; i < matches; i++)
880  {
881  // look for each instance and replace
882  size_t matchPos = StringUtil::pos(source, sourceLength, needle, _start, sourceLength);
883  size_t copyLength = (matchPos - 1) - _start; /* get the next length to copy */
884  // if this skipped over characters, we need to copy those
885  if (copyLength != 0)
886  {
887  copyData(copyOffset, source + _start, copyLength);
888  copyOffset += copyLength;
889  }
890  // replacing with a non-null string, copy the replacement string in
891  if (newLength != 0)
892  {
893  copyData(copyOffset, newPtr, newLength);
894  copyOffset += newLength;
895  }
896  _start = matchPos + needleLength - 1; /* step to the next position */
897  }
898  // we likely have some remainder that needs copying
899  if (_start < sourceLength)
900  {
901  copyData(copyOffset, source + _start, sourceLength - _start);
902  }
903  }
904  // update the result length, and return
905  dataLength = resultLength;
906  return this;
907 }
908 
920 {
921  /* force needle to a string */
922  needle = stringArgument(needle, ARG_ONE);
923  /* newneedle must be a string two */
924  newNeedle = stringArgument(newNeedle, ARG_TWO);
925 
926  // we'll only change up to a specified count. If not there, we do everything.
927  size_t count = optionalPositive(countArg, Numerics::MAX_WHOLENUMBER, ARG_THREE);
928  // find the number of matches in the string
929  size_t matches = StringUtil::caselessCountStr(getStringData(), getLength(), needle);
930  if (matches > count) // the matches are bounded by the count
931  {
932  matches = count;
933  }
934  // no matches is easy!
935  if (matches == 0)
936  {
937  return this;
938  }
939  size_t needleLength = needle->getLength(); /* get the length of the needle */
940  size_t newLength = newNeedle->getLength(); /* and the replacement length */
941  // calculate the final length and make sure we have enough space
942  size_t resultLength = this->getLength() - (matches * needleLength) + (matches * newLength);
943  ensureCapacity(resultLength);
944 
945  // an inplace update has complications, depending on whether the new string is shorter,
946  // the same length, or longer
947 
948  // simplest case...same length strings. We can just overlay the existing occurrences
949  if (needleLength == newLength)
950  {
951  const char *source = getStringData();
952  size_t sourceLength = getLength();
953  size_t _start = 0; /* set a zero starting point */
954  for (size_t i = 0; i < matches; i++)
955  {
956  // search for the next occurrence...which should be there because we
957  // already know the count
958  size_t matchPos = StringUtil::caselessPos(source, sourceLength, needle, _start, sourceLength);
959  copyData(matchPos - 1, newNeedle->getStringData(), newLength);
960  // step to the next search position
961  _start = matchPos + newLength - 1;
962  }
963  }
964  // this will be a shorter thing, so we can do things in place as if we were using two buffers
965  else if (needleLength > newLength)
966  {
967  // we start building from the beginning
968  size_t copyOffset = 0;
969  size_t _start = 0;
970  // get our string bounds
971  const char *source = getStringData();
972  size_t sourceLength = getLength();
973  const char *newPtr = newNeedle->getStringData();
974  // this is our scan offset
975  for (size_t i = 0; i < matches; i++)
976  {
977  // look for each instance and replace
978  size_t matchPos = StringUtil::caselessPos(source, sourceLength, needle, _start, sourceLength);
979  size_t copyLength = (matchPos - 1) - _start; /* get the next length to copy */
980  // if this skipped over characters, we need to copy those
981  if (copyLength != 0)
982  {
983  copyData(copyOffset, source + _start, copyLength);
984  copyOffset += copyLength;
985  }
986  // replacing with a non-null string, copy the replacement string in
987  if (newLength != 0)
988  {
989  copyData(copyOffset, newPtr, newLength);
990  copyOffset += newLength;
991  }
992  _start = matchPos + needleLength - 1; /* step to the next position */
993  }
994  // we likely have some remainder that needs copying
995  if (_start < sourceLength)
996  {
997  copyData(copyOffset, source + _start, sourceLength - _start);
998  }
999  }
1000  // hardest case...the string gets longer. We need to shift all of the data
1001  // to the end and then pull the pieces back in as we go
1002  else
1003  {
1004  size_t growth = (newLength - needleLength) * matches;
1005 
1006  // we start building from the beginning
1007  size_t copyOffset = 0;
1008  size_t _start = 0;
1009  // get our string bounds
1010  const char *source = getStringData() + growth;
1011  size_t sourceLength = getLength();
1012  // this shifts everything to the end of the buffer. From there,
1013  // we pull pieces back into place.
1014  openGap(0, growth, sourceLength);
1015  const char *newPtr = newNeedle->getStringData();
1016  // this is our scan offset
1017  for (size_t i = 0; i < matches; i++)
1018  {
1019  // look for each instance and replace
1020  size_t matchPos = StringUtil::caselessPos(source, sourceLength, needle, _start, sourceLength);
1021  size_t copyLength = (matchPos - 1) - _start; /* get the next length to copy */
1022  // if this skipped over characters, we need to copy those
1023  if (copyLength != 0)
1024  {
1025  copyData(copyOffset, source + _start, copyLength);
1026  copyOffset += copyLength;
1027  }
1028  // replacing with a non-null string, copy the replacement string in
1029  if (newLength != 0)
1030  {
1031  copyData(copyOffset, newPtr, newLength);
1032  copyOffset += newLength;
1033  }
1034  _start = matchPos + needleLength - 1; /* step to the next position */
1035  }
1036  // we likely have some remainder that needs copying
1037  if (_start < sourceLength)
1038  {
1039  copyData(copyOffset, source + _start, sourceLength - _start);
1040  }
1041  }
1042  // update the result length, and return
1043  dataLength = resultLength;
1044  return this;
1045 }
1046 
1047 
1059 {
1060  size_t startPos = optionalPositionArgument(_start, 1, ARG_ONE) - 1;
1061  size_t rangeLength = optionalLengthArgument(_length, getLength(), ARG_TWO);
1062 
1063  // if we're starting beyond the end bounds, return unchanged
1064  if (startPos >= getLength())
1065  {
1066  return this;
1067  }
1068 
1069  rangeLength = Numerics::minVal(rangeLength, getLength() - startPos);
1070 
1071  // a zero length value is also a non-change.
1072  if (rangeLength == 0)
1073  {
1074  return this;
1075  }
1076 
1077  char *bufferData = getData() + startPos;
1078  // now uppercase in place
1079  for (size_t i = 0; i < rangeLength; i++)
1080  {
1081  *bufferData = tolower(*bufferData);
1082  bufferData++;
1083  }
1084  return this;
1085 }
1086 
1087 
1099 {
1100  size_t startPos = optionalPositionArgument(_start, 1, ARG_ONE) - 1;
1101  size_t rangeLength = optionalLengthArgument(_length, getLength(), ARG_TWO);
1102 
1103  // if we're starting beyond the end bounds, return unchanged
1104  if (startPos >= getLength())
1105  {
1106  return this;
1107  }
1108 
1109  rangeLength = Numerics::minVal(rangeLength, getLength() - startPos);
1110 
1111  // a zero length value is also a non-change.
1112  if (rangeLength == 0)
1113  {
1114  return this;
1115  }
1116 
1117  char *bufferData = getData() + startPos;
1118  // now uppercase in place
1119  for (size_t i = 0; i < rangeLength; i++)
1120  {
1121  *bufferData = toupper(*bufferData);
1122  bufferData++;
1123  }
1124  return this;
1125 }
1126 
1127 
1140 {
1141  // just a simple uppercase?
1142  if (tableo == OREF_NULL && tablei == OREF_NULL && pad == OREF_NULL)
1143  {
1144  return this->upper(_start, _range);
1145  }
1146  /* validate the tables */
1147  tableo = optionalStringArgument(tableo, OREF_NULLSTRING, ARG_ONE);
1148  size_t outTableLength = tableo->getLength(); /* get the table length */
1149  /* input table too */
1150  tablei = optionalStringArgument(tablei, OREF_NULLSTRING, ARG_TWO);
1151  size_t inTableLength = tablei->getLength(); /* get the table length */
1152  const char *inTable = tablei->getStringData(); /* point at the input table */
1153  const char *outTable = tableo->getStringData(); /* and the output table */
1154  /* get the pad character */
1155  char padChar = optionalPadArgument(pad, ' ', ARG_THREE);
1156  size_t startPos = optionalPositionArgument(_start, 1, ARG_FOUR);
1157  size_t range = optionalLengthArgument(_range, getLength() - startPos + 1, ARG_FOUR);
1158 
1159  // if nothing to translate, we can return now
1160  if (startPos > getLength() || range == 0)
1161  {
1162  return this;
1163  }
1164  // cape the real range
1165  range = Numerics::minVal(range, getLength() - startPos + 1);
1166  char *scanPtr = getData() + startPos - 1; /* point to data */
1167  size_t scanLength = range; /* get the length too */
1168 
1169  while (scanLength--)
1170  { /* spin thru input */
1171  char ch = *scanPtr; /* get a character */
1172  size_t position;
1173 
1174  if (tablei != OREF_NULLSTRING) /* input table specified? */
1175  {
1176  /* search for the character */
1177  position = StringUtil::memPos(inTable, inTableLength, ch);
1178  }
1179  else
1180  {
1181  position = ((size_t)ch) & 0xff; /* position is the character value */
1182  }
1183  if (position != (size_t)(-1))
1184  { /* found in the table? */
1185  if (position < outTableLength) /* in the output table? */
1186  {
1187  /* convert the character */
1188  *scanPtr = *(outTable + position);
1189  }
1190  else
1191  {
1192  *scanPtr = padChar; /* else use the pad character */
1193  }
1194  }
1195  scanPtr++; /* step the pointer */
1196  }
1197  return this;
1198 }
1199 
1200 
1217 {
1218  stringsize_t _start = positionArgument(start_, ARG_ONE);
1219  // the start position must be within the string bounds
1220  if (_start > getLength())
1221  {
1223  }
1224  other = stringArgument(other, ARG_TWO);
1225 
1226  stringsize_t offset = optionalPositionArgument(offset_, 1, ARG_THREE);
1227 
1228  if (offset > other->getLength())
1229  {
1231  }
1232 
1233  stringsize_t len = optionalLengthArgument(len_, other->getLength() - offset + 1, ARG_FOUR);
1234 
1235  if ((offset + len - 1) > other->getLength())
1236  {
1238  }
1239 
1240  return primitiveMatch(_start, other, offset, len) ? TheTrueObject : TheFalseObject;
1241 }
1242 
1243 
1260 {
1261  stringsize_t _start = positionArgument(start_, ARG_ONE);
1262  // the start position must be within the string bounds
1263  if (_start > getLength())
1264  {
1266  }
1267  other = stringArgument(other, ARG_TWO);
1268 
1269  stringsize_t offset = optionalPositionArgument(offset_, 1, ARG_THREE);
1270 
1271  if (offset > other->getLength())
1272  {
1274  }
1275 
1276  stringsize_t len = optionalLengthArgument(len_, other->getLength() - offset + 1, ARG_FOUR);
1277 
1278  if ((offset + len - 1) > other->getLength())
1279  {
1281  }
1282 
1283  return primitiveCaselessMatch(_start, other, offset, len) ? TheTrueObject : TheFalseObject;
1284 }
1285 
1286 
1299 {
1300  _start--; // make the starting point origin zero
1301  offset--;
1302 
1303  // if the match is not possible in the target string, just return false now.
1304  if ((_start + len) > getLength())
1305  {
1306  return false;
1307  }
1308 
1309  return memcmp(getStringData() + _start, other->getStringData() + offset, len) == 0;
1310 }
1311 
1312 
1326 {
1327  _start--; // make the starting point origin zero
1328  offset--;
1329 
1330  // if the match is not possible in the target string, just return false now.
1331  if ((_start + len) > getLength())
1332  {
1333  return false;
1334  }
1335 
1336  return StringUtil::caselessCompare(getStringData() + _start, other->getStringData() + offset, len) == 0;
1337 }
1338 
1339 
1352 {
1353  stringsize_t position = positionArgument(position_, ARG_ONE);
1354  // the start position must be within the string bounds
1355  if (position > getLength())
1356  {
1358  }
1359  matchSet = stringArgument(matchSet, ARG_TWO);
1360 
1361  stringsize_t _setLength = matchSet->getLength();
1362  char _matchChar = getChar(position - 1);
1363 
1364  // iterate through the match set looking for a match
1365  for (stringsize_t i = 0; i < _setLength; i++)
1366  {
1367  if (_matchChar == matchSet->getChar(i))
1368  {
1369  return TheTrueObject;
1370  }
1371  }
1372  return TheFalseObject;
1373 }
1374 
1375 
1388 {
1389  stringsize_t position = positionArgument(position_, ARG_ONE);
1390  // the start position must be within the string bounds
1391  if (position > getLength())
1392  {
1394  }
1395  matchSet = stringArgument(matchSet, ARG_TWO);
1396 
1397  stringsize_t _setLength = matchSet->getLength();
1398  char _matchChar = getChar(position - 1);
1399  _matchChar = toupper(_matchChar);
1400 
1401  // iterate through the match set looking for a match, using a
1402  // caseless compare
1403  for (stringsize_t i = 0; i < _setLength; i++)
1404  {
1405  if (_matchChar == toupper(matchSet->getChar(i)))
1406  {
1407  return TheTrueObject;
1408  }
1409  }
1410  return TheFalseObject;
1411 }
1412 
1413 
1425 {
1426  return StringUtil::verify(getStringData(), getLength(), ref, option, _start, range);
1427 }
1428 
1429 
1439 {
1440  return StringUtil::subWord(getStringData(), getLength(), position, plength);
1441 }
1442 
1443 
1459 {
1460  return StringUtil::subWords(getStringData(), getLength(), position, plength);
1461 }
1462 
1463 
1472 {
1473  return StringUtil::word(getStringData(), getLength(), position);
1474 }
1475 
1476 
1486 {
1487  return StringUtil::wordIndex(getStringData(), getLength(), position);
1488 }
1489 
1490 
1501 {
1502  return StringUtil::wordLength(getStringData(), getLength(), position);
1503 }
1504 
1511 {
1512  size_t tempCount = StringUtil::wordCount(this->getStringData(), this->getLength());
1513  return new_integer(tempCount);
1514 }
1515 
1516 
1526 {
1527  return StringUtil::wordPos(getStringData(), getLength(), phrase, pstart);
1528 }
1529 
1530 
1540 {
1541  return StringUtil::caselessWordPos(getStringData(), getLength(), phrase, pstart);
1542 }
1543 
1544 
1554 {
1555  /* convert position to binary */
1556  size_t _wordPos = positionArgument(position, ARG_ONE);
1557  /* get num of words to delete, the */
1558  /* default is "a very large number" */
1559  size_t count = optionalLengthArgument(plength, Numerics::MAX_WHOLENUMBER, ARG_TWO);
1560 
1561  size_t length = getLength(); /* get string length */
1562  if (length == 0) /* null string? */
1563  {
1564  return this; /* nothing to delete */
1565  }
1566  if (count == 0) /* deleting zero words? */
1567  {
1568  return this; /* also very easy */
1569  }
1570  const char *_word = getStringData(); /* point to the string */
1571  const char *nextSite = NULL;
1572  /* get the first word */
1573  size_t _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1574  while (--_wordPos > 0 && _wordLength != 0)
1575  { /* loop until we reach tArget */
1576  _word = nextSite; /* copy the start pointer */
1577  /* get the next word */
1578  _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1579  }
1580  if (_wordPos != 0) /* run out of words first */
1581  {
1582  return this; /* return the buffer unaltered */
1583  }
1584  // get the deletion point as an offset
1585  size_t deletePosition = _word - this->getStringData();
1586  while (--count > 0 && _wordLength != 0)
1587  { /* loop until we reach tArget */
1588  _word = nextSite; /* copy the start pointer */
1589  /* get the next word */
1590  _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1591  }
1592  if (length != 0) /* didn't use up the string */
1593  {
1594  StringUtil::skipBlanks(&nextSite, &length);/* skip over trailing blanks */
1595  }
1596 
1597  size_t gapSize = dataLength - (deletePosition + length);
1598  // close up the delete part
1599  closeGap(deletePosition, gapSize, length);
1600  // adjust for the deleted data
1601  dataLength -= gapSize;
1602  return this;
1603 }
1604 
1605 
1616 {
1617  size_t count = 0; /* count word interstices in buffer*/
1618 
1619  /* get the spacing count */
1620  const size_t padLength = optionalLengthArgument(space_count, 1, ARG_ONE);
1621  /* get the pad character */
1622  const char padChar = optionalPadArgument(pad, ' ', ARG_TWO);
1623 
1624  // an inplace update has complications, depending on whether the new string
1625  // is shorter or longer than the original.
1626  // first execute padC with padLength == 0,1; later expand padC to padLength
1627  const char padC = ' '; /* intermediate pad: single space */
1628  const size_t padL = 1; /* intermediate pad length: 1 */
1629 
1630  // With padC the new string is not longer, so we can just overlay in place.
1631  // Set write position to start of buffer
1632  // Find first word: start position and length
1633  // While a word is found:
1634  // Copy word to write position
1635  // update write position
1636  // Find next word: start position and length
1637  // if no next word exists then leave
1638  // select spacing count:
1639  // when = 1 then append padChar and update write position
1640  // when = 0 then don't pad
1641  // otherwise append padC and update write position
1642  // increment word interstice count
1643  // iterate
1644  // adjust string dataLength to write position
1645  size_t writePos = 0; /* offset current write position */
1646  const char *_word = getStringData(); /* point to the start of string */
1647  const char *nextSite = NULL; /* start of the next word */
1648  size_t length = getLength(); /* get string data length */
1649 
1650  /* get the first word */
1651  size_t _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1652 
1653  while (_wordLength != 0)
1654  {
1655  /* copy first word to writePos */
1656  copyData(writePos, _word, _wordLength);
1657  writePos += _wordLength; /* update writePos for next word */
1658  _word = nextSite; /* set start pointer to next word */
1659  /* get the next word */
1660  _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1661  if (_wordLength == 0) /* is there no next word coming ? */
1662  {
1663  break; /* don't pad or count last word */
1664  }
1665  switch (padLength) /* handle different padLength */
1666  {
1667  case 1: /* more frequent case goes first */
1668  setData(writePos, padChar, padLength); /* write pad character */
1669  writePos += padLength; /* move write position one byte */
1670  break;
1671  case 0:
1672  break; /* don't write pad character */
1673  default: /* padLength > 1 */
1674  setData(writePos, padC, padL); /* write padC pad character */
1675  writePos += padL; /* move write position one byte */
1676  }
1677  count++; /* increment the word count */
1678  }
1679  this->dataLength = writePos; /* set data length in buffer */
1680 
1681  if ( padLength > 1 ) /* do we need to expand padC ? */
1682  {
1683  size_t growth = count * (padLength-1); /* data grows by so many bytes */
1684  ensureCapacity(growth); /* make sure we have room for this */
1685 
1686  // As the string gets longer, we need to shift all data to the end and
1687  // then pull the pieces back in as we go.
1688  length = getLength(); /* get current string data length */
1689  openGap(0, growth, length); /* shift towards end of the buffer */
1690  writePos = 0;
1691  while (growth>0)
1692  {
1693  setData(writePos, padC, padL); /* fill gap with whitespace */
1694  writePos++;
1695  growth--;
1696  }
1697  dataLength = getLength() + count * (padLength-1);/*adjust data to size*/
1698 
1699  // Now we do the last loop over, using padChar and padLength
1700  writePos = 0; /* offset current write position */
1701  const char *_word = getStringData(); /*point to the start of string*/
1702  const char *nextSite = NULL; /* start of the next word */
1703  length = this->dataLength; /* get current string data length */
1704  /* get the first word */
1705  _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1706 
1707  while (_wordLength != 0) /* while there is a word ... */
1708  {
1709  /* copy first word to writePos */
1710  copyData(writePos, _word, _wordLength);
1711  writePos += _wordLength; /* update writePos for next word */
1712  _word = nextSite; /* set start pointer to next word */
1713  /* get the next word */
1714  _wordLength = StringUtil::nextWord(&_word, &length, &nextSite);
1715  if (_wordLength != 0) /* except for the last word */
1716  {
1717  setData(writePos, padChar, padLength); /* write padChar chars */
1718  writePos += padLength; /* update writePos for next word */
1719  }
1720  }
1721  }
1722  return this; /* return the mutable buffer */
1723 }
StringUtil.hpp
RexxObject::sendMessage
void sendMessage(RexxString *, RexxArray *, ProtectedObject &)
Definition: ObjectClass.cpp:668
RexxMutableBuffer::posRexx
RexxInteger * posRexx(RexxString *needle, RexxInteger *_start, RexxInteger *_range)
Definition: MutableBufferClass.cpp:655
RexxMutableBuffer::upper
RexxMutableBuffer * upper(RexxInteger *_start, RexxInteger *_length)
Definition: MutableBufferClass.cpp:1098
RexxArray
Definition: ArrayClass.hpp:100
RexxMutableBuffer::caselessWordPos
RexxInteger * caselessWordPos(RexxString *, RexxInteger *)
Definition: MutableBufferClass.cpp:1539
RexxMutableBuffer::caselessChangeStr
RexxMutableBuffer * caselessChangeStr(RexxString *needle, RexxString *newNeedle, RexxInteger *countArg)
Definition: MutableBufferClass.cpp:919
RexxMutableBuffer::setCapacity
char * setCapacity(size_t newLength)
Definition: MutableBufferClass.cpp:301
StringUtil::caselessWordPos
static RexxInteger * caselessWordPos(const char *data, size_t length, RexxString *phrase, RexxInteger *pstart)
Definition: StringUtil.cpp:1844
RexxMutableBuffer::classInstance
static RexxClass * classInstance
Definition: MutableBufferClass.hpp:138
TheFalseObject
#define TheFalseObject
Definition: RexxCore.h:184
RexxMutableBuffer::append
RexxMutableBuffer * append(RexxObject *)
Definition: MutableBufferClass.cpp:325
StringUtil::caselessCompare
static int caselessCompare(const char *, const char *, size_t)
Definition: StringUtil.cpp:571
new_integer
RexxInteger * new_integer(wholenumber_t v)
Definition: IntegerClass.hpp:198
RexxMutableBuffer::lengthRexx
RexxObject * lengthRexx()
Definition: MutableBufferClass.cpp:319
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
RexxMutableBuffer
Definition: MutableBufferClass.hpp:61
optionalNonNegative
size_t optionalNonNegative(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:363
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
RexxMutableBuffer::matchChar
RexxInteger * matchChar(RexxInteger *position_, RexxString *matchSet)
Definition: MutableBufferClass.cpp:1351
optionalLengthArgument
size_t optionalLengthArgument(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:336
RexxMutableBuffer::overlay
RexxMutableBuffer * overlay(RexxObject *, RexxObject *, RexxObject *, RexxObject *)
Definition: MutableBufferClass.cpp:407
StringUtil::posRexx
static RexxInteger * posRexx(const char *stringData, size_t length, RexxString *needle, RexxInteger *pstart, RexxInteger *range)
Definition: StringUtil.cpp:130
RexxMutableBuffer::primitiveMatch
bool primitiveMatch(stringsize_t start, RexxString *other, stringsize_t offset, stringsize_t len)
Definition: MutableBufferClass.cpp:1298
RexxInternalObject::clone
RexxObject * clone()
Definition: ObjectClass.cpp:2308
RexxMutableBuffer::flatten
void flatten(RexxEnvelope *envelope)
Definition: MutableBufferClass.cpp:205
RexxMutableBuffer::data
RexxBuffer * data
Definition: MutableBufferClass.hpp:144
StringUtil::wordIndex
static RexxInteger * wordIndex(const char *data, size_t length, RexxInteger *position)
Definition: StringUtil.cpp:1675
RexxMutableBuffer::createInstance
static void createInstance()
Definition: MutableBufferClass.cpp:63
RexxMutableBuffer::replaceAt
RexxMutableBuffer * replaceAt(RexxObject *str, RexxObject *pos, RexxObject *len, RexxObject *pad)
Definition: MutableBufferClass.cpp:465
RexxMutableBuffer::bufferLength
size_t bufferLength
Definition: MutableBufferClass.hpp:141
RexxMutableBuffer::lower
RexxMutableBuffer * lower(RexxInteger *_start, RexxInteger *_length)
Definition: MutableBufferClass.cpp:1058
RexxMutableBuffer::substr
RexxString * substr(RexxInteger *startPosition, RexxInteger *len, RexxString *pad)
Definition: MutableBufferClass.cpp:638
RexxString::getLength
size_t getLength()
Definition: StringClass.hpp:330
RexxMutableBuffer::subchar
RexxString * subchar(RexxInteger *startPosition)
Definition: MutableBufferClass.cpp:735
RexxMutableBuffer::primitiveCaselessMatch
bool primitiveCaselessMatch(stringsize_t start, RexxString *other, stringsize_t offset, stringsize_t len)
Definition: MutableBufferClass.cpp:1325
RexxMutableBuffer::match
RexxInteger * match(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_)
Definition: MutableBufferClass.cpp:1216
RexxMutableBuffer::setDataLength
size_t setDataLength(size_t l)
Definition: MutableBufferClass.cpp:273
StringUtil::skipBlanks
static void skipBlanks(const char **String, size_t *StringLength)
Definition: StringUtil.cpp:1214
StringUtil::wordCount
static size_t wordCount(const char *String, size_t StringLength)
Definition: StringUtil.cpp:1273
StringUtil::makearray
static RexxArray * makearray(const char *start, size_t length, RexxString *separator)
Definition: StringUtil.cpp:491
ARG_TWO
const int ARG_TWO
Definition: RexxCore.h:81
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
RexxMutableBuffer::delWord
RexxMutableBuffer * delWord(RexxInteger *position, RexxInteger *plength)
Definition: MutableBufferClass.cpp:1553
RexxMutableBuffer::RexxMutableBuffer
RexxMutableBuffer()
Definition: MutableBufferClass.cpp:125
RexxMutableBuffer::getChar
char getChar(size_t offset)
Definition: MutableBufferClass.hpp:132
Numerics::MAX_WHOLENUMBER
static const wholenumber_t MAX_WHOLENUMBER
Definition: Numerics.hpp:62
RexxMutableBuffer::insert
RexxMutableBuffer * insert(RexxObject *, RexxObject *, RexxObject *, RexxObject *)
Definition: MutableBufferClass.cpp:341
RexxMutableBuffer::changeStr
RexxMutableBuffer * changeStr(RexxString *needle, RexxString *newNeedle, RexxInteger *countArg)
Definition: MutableBufferClass.cpp:781
RexxMutableBuffer::copyData
void copyData(size_t offset, const char *string, size_t l)
Definition: MutableBufferClass.hpp:126
T_MutableBuffer
Definition: ClassTypeCodes.h:87
StringUtil::word
static RexxString * word(const char *data, size_t length, RexxInteger *position)
Definition: StringUtil.cpp:1608
TheTrueObject
#define TheTrueObject
Definition: RexxCore.h:185
MutableBufferClass.hpp
RexxString::getStringData
const char * getStringData()
Definition: StringClass.hpp:333
RexxMutableBuffer::wordPos
RexxInteger * wordPos(RexxString *, RexxInteger *)
Definition: MutableBufferClass.cpp:1525
RexxString::getChar
char getChar(size_t p)
Definition: StringClass.hpp:338
RexxMutableBuffer::closeGap
void closeGap(size_t offset, size_t _size, size_t tailSize)
Definition: MutableBufferClass.hpp:128
RexxMutableBuffer::setData
void setData(size_t offset, char character, size_t l)
Definition: MutableBufferClass.hpp:130
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxBuffer
Definition: BufferClass.hpp:91
StringUtil::subWord
static RexxString * subWord(const char *data, size_t length, RexxInteger *position, RexxInteger *plength)
Definition: StringUtil.cpp:1496
StringUtil::pos
static size_t pos(const char *stringData, size_t haystack_length, RexxString *needle, size_t _start, size_t _range)
Definition: StringUtil.cpp:154
RexxObject::makeArrayRexx
RexxObject * makeArrayRexx()
Definition: ObjectClass.cpp:2477
StringUtil::wordLength
static RexxInteger * wordLength(const char *data, size_t length, RexxInteger *position)
Definition: StringUtil.cpp:1709
RexxMutableBuffer::caselessCountStrRexx
RexxInteger * caselessCountStrRexx(RexxString *needle)
Definition: MutableBufferClass.cpp:761
StringUtil::wordPos
static RexxInteger * wordPos(const char *data, size_t length, RexxString *phrase, RexxInteger *pstart)
Definition: StringUtil.cpp:1738
StringUtil::subchar
static RexxString * subchar(const char *stringData, size_t stringLength, RexxInteger *positionArg)
Definition: StringUtil.cpp:440
RexxMutableBuffer::dataLength
size_t dataLength
Definition: MutableBufferClass.hpp:143
RexxMutableBuffer::space
RexxMutableBuffer * space(RexxInteger *space_count, RexxString *pad)
Definition: MutableBufferClass.cpp:1615
optionalPositionArgument
size_t optionalPositionArgument(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:344
lengthArgument
stringsize_t lengthArgument(RexxObject *argument, size_t position)
Definition: StringClassUtil.cpp:58
RexxMutableBuffer::makeArray
RexxArray * makeArray()
Definition: MutableBufferClass.cpp:611
new_string
RexxString * new_string(const char *s, stringsize_t l)
Definition: StringClass.hpp:524
RexxMutableBuffer::mydelete
RexxMutableBuffer * mydelete(RexxObject *, RexxObject *)
Definition: MutableBufferClass.cpp:534
RexxMutableBuffer::caselessLastPos
RexxInteger * caselessLastPos(RexxString *needle, RexxInteger *_start, RexxInteger *_range)
Definition: MutableBufferClass.cpp:709
ARG_ONE
const int ARG_ONE
Definition: RexxCore.h:80
optionalStringArgument
RexxString * optionalStringArgument(RexxObject *o, RexxString *d, size_t p)
Definition: RexxCore.h:321
RexxMutableBuffer::subWord
RexxString * subWord(RexxInteger *, RexxInteger *)
Definition: MutableBufferClass.cpp:1438
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
Error_Incorrect_method_position
#define Error_Incorrect_method_position
Definition: RexxErrorCodes.h:476
ARG_THREE
const int ARG_THREE
Definition: RexxCore.h:82
RexxMutableBuffer::caselessMatchChar
RexxInteger * caselessMatchChar(RexxInteger *position_, RexxString *matchSet)
Definition: MutableBufferClass.cpp:1387
RexxClass
Definition: ClassClass.hpp:49
RexxInternalObject::setBehaviour
void setBehaviour(RexxBehaviour *b)
Definition: ObjectClass.hpp:265
ProtectedObject.hpp
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
RexxMutableBuffer::getData
char * getData()
Definition: MutableBufferClass.hpp:125
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
ProtectedObject
Definition: ProtectedObject.hpp:46
StringUtil::substr
static RexxString * substr(const char *, size_t, RexxInteger *, RexxInteger *, RexxString *)
Definition: StringUtil.cpp:66
StringClass.hpp
StringUtil::verify
static RexxInteger * verify(const char *data, size_t stringLen, RexxString *ref, RexxString *option, RexxInteger *_start, RexxInteger *range)
Definition: StringUtil.cpp:1411
RexxMutableBuffer::liveGeneral
void liveGeneral(int reason)
Definition: MutableBufferClass.cpp:195
RexxMutableBuffer::ensureCapacity
void ensureCapacity(size_t addedLength)
Definition: MutableBufferClass.cpp:236
optionalPadArgument
char optionalPadArgument(RexxObject *o, char d, size_t p)
Definition: RexxCore.h:351
RexxMutableBuffer::getLength
size_t getLength()
Definition: MutableBufferClass.hpp:124
RexxMutableBuffer::words
RexxInteger * words()
Definition: MutableBufferClass.cpp:1510
StringUtil::lastPosRexx
static RexxInteger * lastPosRexx(const char *stringData, size_t haystackLen, RexxString *needle, RexxInteger *_start, RexxInteger *_range)
Definition: StringUtil.cpp:254
optionalPositive
size_t optionalPositive(RexxObject *o, size_t d, size_t p)
Definition: RexxCore.h:368
CLASS_CREATE
#define CLASS_CREATE(name, id, className)
Definition: RexxMemory.hpp:445
RexxMutableBuffer::setBufferSize
RexxObject * setBufferSize(RexxInteger *)
Definition: MutableBufferClass.cpp:562
Numerics::minVal
static wholenumber_t minVal(wholenumber_t n1, wholenumber_t n2)
Definition: Numerics.hpp:116
RexxMutableBuffer::caselessPos
RexxInteger * caselessPos(RexxString *needle, RexxInteger *_start, RexxInteger *_range)
Definition: MutableBufferClass.cpp:686
RexxMutableBuffer::makeString
RexxString * makeString()
Definition: MutableBufferClass.cpp:598
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
RexxMutableBufferClass::newRexx
RexxMutableBuffer * newRexx(RexxObject **, size_t)
Definition: MutableBufferClass.cpp:71
RexxMutableBuffer::countStrRexx
RexxInteger * countStrRexx(RexxString *needle)
Definition: MutableBufferClass.cpp:750
RexxMutableBuffer::translate
RexxMutableBuffer * translate(RexxString *tableo, RexxString *tablei, RexxString *pad, RexxInteger *, RexxInteger *)
Definition: MutableBufferClass.cpp:1139
StringUtil::caselessLastPos
static size_t caselessLastPos(const char *stringData, size_t hastackLen, RexxString *needle, size_t _start, size_t range)
Definition: StringUtil.cpp:358
RexxBuffer::getData
virtual char * getData()
Definition: BufferClass.hpp:105
StringUtil::nextWord
static size_t nextWord(const char **String, size_t *StringLength, const char **NextString)
Definition: StringUtil.cpp:1308
RexxMutableBuffer::wordIndex
RexxInteger * wordIndex(RexxInteger *)
Definition: MutableBufferClass.cpp:1485
StringUtil::subWords
static RexxArray * subWords(const char *data, size_t length, RexxInteger *position, RexxInteger *plength)
Definition: StringUtil.cpp:1550
RexxMutableBuffer::subWords
RexxArray * subWords(RexxInteger *, RexxInteger *)
Definition: MutableBufferClass.cpp:1458
RexxMutableBuffer::word
RexxString * word(RexxInteger *)
Definition: MutableBufferClass.cpp:1471
RexxMutableBuffer::lastPos
RexxInteger * lastPos(RexxString *needle, RexxInteger *_start, RexxInteger *_range)
Definition: MutableBufferClass.cpp:671
RexxMutableBuffer::live
void live(size_t)
Definition: MutableBufferClass.cpp:186
new_buffer
RexxBuffer * new_buffer(size_t s)
Definition: BufferClass.hpp:116
stringsize_t
size_t stringsize_t
Definition: rexx.h:228
RexxMutableBuffer::openGap
void openGap(size_t offset, size_t _size, size_t tailSize)
Definition: MutableBufferClass.hpp:127
ARG_FOUR
const int ARG_FOUR
Definition: RexxCore.h:83
StringUtil::caselessCountStr
static size_t caselessCountStr(const char *hayStack, size_t hayStackLength, RexxString *needle)
Definition: StringUtil.cpp:1363
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
RexxMutableBuffer::getCapacity
size_t getCapacity()
Definition: MutableBufferClass.hpp:133
RexxMutableBuffer::caselessMatch
RexxInteger * caselessMatch(RexxInteger *start_, RexxString *other, RexxInteger *offset_, RexxInteger *len_)
Definition: MutableBufferClass.cpp:1259
RexxMutableBuffer::adjustGap
void adjustGap(size_t offset, size_t _size, size_t _newSize)
Definition: MutableBufferClass.hpp:129
RexxMutableBuffer::defaultSize
size_t defaultSize
Definition: MutableBufferClass.hpp:142
RexxMutableBuffer::copy
RexxObject * copy()
Definition: MutableBufferClass.cpp:218
positionArgument
stringsize_t positionArgument(RexxObject *argument, size_t position)
Definition: StringClassUtil.cpp:82
Error_Incorrect_method_length
#define Error_Incorrect_method_length
Definition: RexxErrorCodes.h:475
RexxBufferBase::copyData
void copyData(size_t offset, const char *string, size_t l)
Definition: BufferClass.hpp:57
RexxMutableBuffer::getStringData
const char * getStringData()
Definition: MutableBufferClass.hpp:123
stringArgument
RexxString * stringArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:296
StringUtil::caselessPos
static size_t caselessPos(const char *stringData, size_t haystack_length, RexxString *needle, size_t _start, size_t _range)
Definition: StringUtil.cpp:204
RexxMutableBuffer::primitiveMakeString
RexxString * primitiveMakeString()
Definition: MutableBufferClass.cpp:624
RexxCore.h
RexxBufferBase::getDataLength
size_t getDataLength()
Definition: BufferClass.hpp:53
StringUtil::countStr
static size_t countStr(const char *hayStack, size_t hayStackLength, RexxString *needle)
Definition: StringUtil.cpp:1338
new_object
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:422
StringUtil::memPos
static size_t memPos(const char *string, size_t length, char target)
Definition: StringUtil.cpp:1378
RexxInteger
Definition: IntegerClass.hpp:56
RexxObject
Definition: ObjectClass.hpp:311
RexxMutableBuffer::verify
RexxInteger * verify(RexxString *, RexxString *, RexxInteger *, RexxInteger *)
Definition: MutableBufferClass.cpp:1424
RexxMutableBuffer::wordLength
RexxInteger * wordLength(RexxInteger *)
Definition: MutableBufferClass.cpp:1500
RexxString
Definition: StringClass.hpp:119
DEFAULT_BUFFER_LENGTH
#define DEFAULT_BUFFER_LENGTH
Definition: MutableBufferClass.cpp:69