Torque3D Documentation / _generateds / stringStack.cpp

stringStack.cpp

Engine/source/console/stringStack.cpp

More...

Public Variables

Detailed Description

Public Variables

ConsoleValue gNothing 
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include <stdio.h>
 25#include "console/consoleInternal.h"
 26#include "console/stringStack.h"
 27
 28StringStack::StringStack()
 29{
 30   mBufferSize = 0;
 31   mBuffer = NULL;
 32   mArgBufferSize = 0;
 33   mArgBuffer = NULL;
 34   for (U32 i = 0; i < MaxArgs; i++)
 35      mArgV[i] = "";
 36   dMemset(mFrameOffsets, 0, sizeof(mFrameOffsets));
 37   dMemset(mStartOffsets, 0, sizeof(mStartOffsets));
 38   mNumFrames = 0;
 39   mArgc = 0;
 40   mStart = 0;
 41   mLen = 0;
 42   mStartStackSize = 0;
 43   mFunctionOffset = 0;
 44   validateBufferSize(8192);
 45   validateArgBufferSize(2048);
 46   dMemset(mBuffer, '\0', mBufferSize);
 47   dMemset(mArgBuffer, '\0', mArgBufferSize);
 48}
 49
 50StringStack::~StringStack()
 51{
 52   if( mBuffer )
 53      dFree( mBuffer );
 54   if( mArgBuffer )
 55      dFree( mArgBuffer );
 56}
 57
 58void StringStack::validateBufferSize(U32 size)
 59{
 60   if(size > mBufferSize)
 61   {
 62      mBufferSize = size + 2048;
 63      mBuffer = (char *) dRealloc(mBuffer, mBufferSize);
 64   }
 65}
 66
 67void StringStack::validateArgBufferSize(U32 size)
 68{
 69   if(size > mArgBufferSize)
 70   {
 71      mArgBufferSize = size + 2048;
 72      mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize);
 73   }
 74}
 75
 76void StringStack::setIntValue(U32 i)
 77{
 78   validateBufferSize(mStart + 32);
 79   dSprintf(mBuffer + mStart, 32, "%d", i);
 80   mLen = dStrlen(mBuffer + mStart);
 81}
 82
 83void StringStack::setFloatValue(F64 v)
 84{
 85   validateBufferSize(mStart + 32);
 86   dSprintf(mBuffer + mStart, 32, "%g", v);
 87   mLen = dStrlen(mBuffer + mStart);
 88}
 89
 90char *StringStack::getReturnBuffer(U32 size)
 91{
 92   if(size > ReturnBufferSpace)
 93   {
 94      AssertFatal(Con::isMainThread(), "Manipulating return buffer from a secondary thread!");
 95      validateArgBufferSize(size);
 96      return mArgBuffer;
 97   }
 98   else
 99   {
100      validateBufferSize(mStart + size);
101      return mBuffer + mStart;
102   }
103}
104
105char *StringStack::getArgBuffer(U32 size)
106{
107   AssertFatal(Con::isMainThread(), "Manipulating console arg buffer from a secondary thread!");
108   validateBufferSize(mStart + mFunctionOffset + size);
109   char *ret = mBuffer + mStart + mFunctionOffset;
110   mFunctionOffset += size;
111   return ret;
112}
113
114void StringStack::clearFunctionOffset()
115{
116   //Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset);
117   mFunctionOffset = 0;
118}
119
120void StringStack::setStringValue(const char *s)
121{
122   if(!s)
123   {
124      mLen = 0;
125      mBuffer[mStart] = 0;
126      return;
127   }
128   mLen = dStrlen(s);
129
130   validateBufferSize(mStart + mLen + 2);
131   dStrcpy(mBuffer + mStart, s, mBufferSize - mStart);
132}
133
134void StringStack::advance()
135{
136   mStartOffsets[mStartStackSize++] = mStart;
137   mStart += mLen;
138   mLen = 0;
139}
140
141void StringStack::advanceChar(char c)
142{
143   mStartOffsets[mStartStackSize++] = mStart;
144   mStart += mLen;
145   mBuffer[mStart] = c;
146   mBuffer[mStart+1] = 0;
147   mStart += 1;
148   mLen = 0;
149}
150
151void StringStack::push()
152{
153   advanceChar(0);
154}
155
156void StringStack::rewind()
157{
158   mStart = mStartOffsets[--mStartStackSize];
159   mLen = dStrlen(mBuffer + mStart);
160}
161
162void StringStack::rewindTerminate()
163{
164   mBuffer[mStart] = 0;
165   mStart = mStartOffsets[--mStartStackSize];
166   mLen   = dStrlen(mBuffer + mStart);
167}
168
169U32 StringStack::compare()
170{
171   // Figure out the 1st and 2nd item offsets.
172   U32 oldStart = mStart;
173   mStart = mStartOffsets[--mStartStackSize];
174
175   // Compare current and previous strings.
176   U32 ret = !dStricmp(mBuffer + mStart, mBuffer + oldStart);
177
178   // Put an empty string on the top of the stack.
179   mLen = 0;
180   mBuffer[mStart] = 0;
181
182   return ret;
183}
184
185void StringStack::pushFrame()
186{
187   //Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
188   mFrameOffsets[mNumFrames++] = mStartStackSize;
189   mStartOffsets[mStartStackSize++] = mStart;
190   mStart += ReturnBufferSpace;
191   validateBufferSize(0);
192}
193
194void StringStack::popFrame()
195{
196   //Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
197   mStartStackSize = mFrameOffsets[--mNumFrames];
198   mStart = mStartOffsets[mStartStackSize];
199   mLen = 0;
200}
201
202void StringStack::clearFrames()
203{
204   //Con::printf("StringStack clearFrames");
205   mNumFrames = 0;
206   mStart = 0;
207   mLen = 0;
208   mStartStackSize = 0;
209   mFunctionOffset = 0;
210}
211
212
213void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame /* = false */)
214{
215   U32 startStack = mStackFrames[mFrame-1];
216   U32 argCount   = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
217
218   *in_argv = mArgv;
219   mArgv[0].value = CSTK.pushStackString(name);
220   
221   for(U32 i = 0; i < argCount; i++) {
222      ConsoleValueRef *ref = &mArgv[i+1];
223      ref->value = &mStack[startStack + i];
224   }
225   argCount++;
226   
227   *argc = argCount;
228
229   if(popStackFrame)
230      popFrame();
231}
232
233ConsoleValueStack::ConsoleValueStack() : 
234mFrame(0),
235mStackPos(0)
236{
237   for (int i=0; i<ConsoleValueStack::MaxStackDepth; i++) {
238      mStack[i].init();
239      mStack[i].type = ConsoleValue::TypeInternalString;
240   }
241   dMemset(mStackFrames, 0, sizeof(mStackFrames));
242}
243
244ConsoleValueStack::~ConsoleValueStack()
245{
246}
247
248void ConsoleValueStack::pushVar(ConsoleValue *variable)
249{
250   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
251      AssertFatal(false, "Console Value Stack is empty");
252      return;
253   }
254
255   switch (variable->type)
256   {
257   case ConsoleValue::TypeInternalInt:
258      mStack[mStackPos++].setIntValue((S32)variable->getIntValue());
259   case ConsoleValue::TypeInternalFloat:
260      mStack[mStackPos++].setFloatValue((F32)variable->getFloatValue());
261   default:
262      mStack[mStackPos++].setStackStringValue(variable->getStringValue());
263   }
264}
265
266void ConsoleValueStack::pushValue(ConsoleValue &variable)
267{
268   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
269      AssertFatal(false, "Console Value Stack is empty");
270      return;
271   }
272
273   switch (variable.type)
274   {
275   case ConsoleValue::TypeInternalInt:
276      mStack[mStackPos++].setIntValue((S32)variable.getIntValue());
277   case ConsoleValue::TypeInternalFloat:
278      mStack[mStackPos++].setFloatValue((F32)variable.getFloatValue());
279   case ConsoleValue::TypeInternalStringStackPtr:
280      mStack[mStackPos++].setStringStackPtrValue(variable.getStringStackPtr());
281   default:
282      mStack[mStackPos++].setStringValue(variable.getStringValue());
283   }
284}
285
286ConsoleValue* ConsoleValueStack::reserveValues(U32 count)
287{
288   U32 startPos = mStackPos;
289   if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
290      AssertFatal(false, "Console Value Stack is empty");
291      return NULL;
292   }
293
294   //Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
295   mStackPos += count;
296   return &mStack[startPos];
297}
298
299bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues)
300{
301   U32 startPos = mStackPos;
302   if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
303      AssertFatal(false, "Console Value Stack is empty");
304      return false;
305   }
306
307   //Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
308   for (U32 i=0; i<count; i++)
309   {
310      outValues[i].value = &mStack[mStackPos+i];
311   }
312   mStackPos += count;
313   return true;
314}
315
316ConsoleValue *ConsoleValueStack::pushString(const char *value)
317{
318   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
319      AssertFatal(false, "Console Value Stack is empty");
320      return NULL;
321   }
322
323   //Con::printf("[%i]CSTK pushString %s", mStackPos, value);
324
325   mStack[mStackPos++].setStringValue(value);
326   return &mStack[mStackPos-1];
327}
328
329ConsoleValue *ConsoleValueStack::pushStackString(const char *value)
330{
331   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
332      AssertFatal(false, "Console Value Stack is empty");
333      return NULL;
334   }
335
336   //Con::printf("[%i]CSTK pushString %s", mStackPos, value);
337
338   mStack[mStackPos++].setStackStringValue(value);
339   return &mStack[mStackPos-1];
340}
341
342ConsoleValue *ConsoleValueStack::pushStringStackPtr(StringStackPtr value)
343{
344   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
345      AssertFatal(false, "Console Value Stack is empty");
346      return NULL;
347   }
348
349   //Con::printf("[%i]CSTK pushStringStackPtr %s", mStackPos, StringStackPtrRef(value).getPtr(&STR));
350
351   mStack[mStackPos++].setStringStackPtrValue(value);
352   return &mStack[mStackPos-1];
353}
354
355ConsoleValue *ConsoleValueStack::pushUINT(U32 value)
356{
357   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
358      AssertFatal(false, "Console Value Stack is empty");
359      return NULL;
360   }
361
362   //Con::printf("[%i]CSTK pushUINT %i", mStackPos, value);
363
364   mStack[mStackPos++].setIntValue(value);
365   return &mStack[mStackPos-1];
366}
367
368ConsoleValue *ConsoleValueStack::pushFLT(float value)
369{
370   if (mStackPos == ConsoleValueStack::MaxStackDepth) {
371      AssertFatal(false, "Console Value Stack is empty");
372      return NULL;
373   }
374
375   //Con::printf("[%i]CSTK pushFLT %f", mStackPos, value);
376
377   mStack[mStackPos++].setFloatValue(value);
378   return &mStack[mStackPos-1];
379}
380
381static ConsoleValue gNothing;
382
383ConsoleValue* ConsoleValueStack::pop()
384{
385   if (mStackPos == 0) {
386      AssertFatal(false, "Console Value Stack is empty");
387      return &gNothing;
388   }
389
390   return &mStack[--mStackPos];
391}
392
393void ConsoleValueStack::pushFrame()
394{
395   //Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos);
396   mStackFrames[mFrame++] = mStackPos;
397}
398
399void ConsoleValueStack::resetFrame()
400{
401   if (mFrame == 0) {
402      mStackPos = 0;
403      return;
404   }
405
406   U32 start = mStackFrames[mFrame-1];
407   //for (U32 i=start; i<mStackPos; i++) {
408      //mStack[i].clear();
409   //}
410   mStackPos = start;
411   //Con::printf("CSTK resetFrame to %i", mStackPos);
412}
413
414void ConsoleValueStack::clearFrames()
415{
416   mStackPos = 0;
417   mFrame = 0;
418}
419
420void ConsoleValueStack::popFrame()
421{
422   //Con::printf("CSTK popFrame");
423   if (mFrame == 0) {
424      // Go back to start
425      mStackPos = 0;
426      return;
427   }
428
429   U32 start = mStackFrames[mFrame-1];
430   //for (U32 i=start; i<mStackPos; i++) {
431      //mStack[i].clear();
432   //}
433   mStackPos = start;
434   mFrame--;
435}
436