stringStack.h
Engine/source/console/stringStack.h
Classes:
class
class
Core stack for interpreter operations.
class
Helper class which stores a relative pointer in the StringStack buffer.
Public Typedefs
StringStackPtr
Public Variables
Detailed Description
Public Typedefs
typedef U32 StringStackPtr
Public Variables
ConsoleValueStack CSTK
StringStack STR
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#ifndef _STRINGSTACK_H_ 25#define _STRINGSTACK_H_ 26 27#ifndef _STRINGFUNCTIONS_H_ 28#include "core/strings/stringFunctions.h" 29#endif 30 31#ifndef _STRINGTABLE_H_ 32#include "core/stringTable.h" 33#endif 34 35#ifndef _CONSOLE_H_ 36#include "console/console.h" 37#endif 38 39typedef U32 StringStackPtr; 40struct StringStack; 41 42/// Helper class which stores a relative pointer in the StringStack buffer 43class StringStackPtrRef 44{ 45public: 46 StringStackPtrRef() : mOffset(0) {;} 47 StringStackPtrRef(StringStackPtr offset) : mOffset(offset) {;} 48 49 StringStackPtr mOffset; 50 51 /// Get pointer to string in stack stk 52 inline char *getPtr(StringStack *stk); 53}; 54 55/// Core stack for interpreter operations. 56/// 57/// This class provides some powerful semantics for working with strings, and is 58/// used heavily by the console interpreter. 59struct StringStack 60{ 61 enum { 62 MaxStackDepth = 1024, 63 MaxArgs = 20, 64 ReturnBufferSpace = 512 65 }; 66 char *mBuffer; 67 U32 mBufferSize; 68 const char *mArgV[MaxArgs]; 69 U32 mFrameOffsets[MaxStackDepth]; 70 U32 mStartOffsets[MaxStackDepth]; 71 72 U32 mNumFrames; 73 U32 mArgc; 74 75 U32 mStart; 76 U32 mLen; 77 U32 mStartStackSize; 78 U32 mFunctionOffset; 79 80 U32 mArgBufferSize; 81 char *mArgBuffer; 82 83 void validateBufferSize(U32 size) 84 { 85 if(size > mBufferSize) 86 { 87 mBufferSize = size + 2048; 88 mBuffer = (char *) dRealloc(mBuffer, mBufferSize); 89 } 90 } 91 92 void validateArgBufferSize(U32 size) 93 { 94 if(size > mArgBufferSize) 95 { 96 mArgBufferSize = size + 2048; 97 mArgBuffer = (char *) dRealloc(mArgBuffer, mArgBufferSize); 98 } 99 } 100 101 StringStack() 102 { 103 mBufferSize = 0; 104 mBuffer = NULL; 105 mArgBufferSize = 0; 106 mArgBuffer = NULL; 107 mNumFrames = 0; 108 mStart = 0; 109 mLen = 0; 110 mStartStackSize = 0; 111 mFunctionOffset = 0; 112 validateBufferSize(8192); 113 validateArgBufferSize(2048); 114 dMemset(mBuffer, '\0', mBufferSize); 115 dMemset(mArgBuffer, '\0', mArgBufferSize); 116 } 117 ~StringStack() 118 { 119 if( mBuffer ) 120 dFree( mBuffer ); 121 if( mArgBuffer ) 122 dFree( mArgBuffer ); 123 } 124 125 /// Set the top of the stack to be an integer value. 126 void setIntValue(U32 i) 127 { 128 validateBufferSize(mStart + 32); 129 dSprintf(mBuffer + mStart, 32, "%d", i); 130 mLen = dStrlen(mBuffer + mStart); 131 } 132 133 /// Set the top of the stack to be a float value. 134 void setFloatValue(F64 v) 135 { 136 validateBufferSize(mStart + 32); 137 dSprintf(mBuffer + mStart, 32, "%g", v); 138 mLen = dStrlen(mBuffer + mStart); 139 } 140 141 /// Return a temporary buffer we can use to return data. 142 char* getReturnBuffer(U32 size) 143 { 144 AssertFatal(Con::isMainThread(), "Manipulating return buffer from a secondary thread!"); 145 validateArgBufferSize(size); 146 return mArgBuffer; 147 } 148 149 /// Return a buffer we can use for arguments. 150 /// 151 /// This updates the function offset. 152 char *getArgBuffer(U32 size) 153 { 154 AssertFatal(Con::isMainThread(), "Manipulating console arg buffer from a secondary thread!"); 155 validateBufferSize(mStart + mFunctionOffset + size); 156 char *ret = mBuffer + mStart + mFunctionOffset; 157 mFunctionOffset += size; 158 return ret; 159 } 160 161 /// Clear the function offset. 162 void clearFunctionOffset() 163 { 164 //Con::printf("StringStack mFunctionOffset = 0 (from %i)", mFunctionOffset); 165 mFunctionOffset = 0; 166 } 167 168 /// Set a string value on the top of the stack. 169 void setStringValue(const char *s) 170 { 171 if(!s) 172 { 173 mLen = 0; 174 mBuffer[mStart] = 0; 175 return; 176 } 177 mLen = dStrlen(s); 178 179 validateBufferSize(mStart + mLen + 2); 180 dStrcpy(mBuffer + mStart, s); 181 } 182 183 /// Get the top of the stack, as a StringTableEntry. 184 /// 185 /// @note Don't free this memory! 186 inline StringTableEntry getSTValue() 187 { 188 return StringTable->insert(mBuffer + mStart); 189 } 190 191 /// Get an integer representation of the top of the stack. 192 inline U32 getIntValue() 193 { 194 return dAtoi(mBuffer + mStart); 195 } 196 197 /// Get a float representation of the top of the stack. 198 inline F64 getFloatValue() 199 { 200 return dAtof(mBuffer + mStart); 201 } 202 203 /// Get a string representation of the top of the stack. 204 /// 205 /// @note This returns a pointer to the actual top of the stack, be careful! 206 inline const char *getStringValue() 207 { 208 return mBuffer + mStart; 209 } 210 211 inline const char *getPreviousStringValue() 212 { 213 return mBuffer + mStartOffsets[mStartStackSize-1]; 214 } 215 216 inline StringStackPtr getStringValuePtr() 217 { 218 return (getStringValue() - mBuffer); 219 } 220 221 inline StringStackPtr getPreviousStringValuePtr() 222 { 223 return (getPreviousStringValue() - mBuffer); 224 } 225 226 /// Advance the start stack, placing a zero length string on the top. 227 /// 228 /// @note You should use StringStack::push, not this, if you want to 229 /// properly push the stack. 230 void advance() 231 { 232 mStartOffsets[mStartStackSize++] = mStart; 233 mStart += mLen; 234 mLen = 0; 235 } 236 237 /// Advance the start stack, placing a single character, null-terminated strong 238 /// on the top. 239 /// 240 /// @note You should use StringStack::push, not this, if you want to 241 /// properly push the stack. 242 void advanceChar(char c) 243 { 244 mStartOffsets[mStartStackSize++] = mStart; 245 mStart += mLen; 246 mBuffer[mStart] = c; 247 mBuffer[mStart+1] = 0; 248 mStart += 1; 249 mLen = 0; 250 } 251 252 /// Push the stack, placing a zero-length string on the top. 253 void push() 254 { 255 advanceChar(0); 256 } 257 258 inline void setLen(U32 newlen) 259 { 260 mLen = newlen; 261 } 262 263 /// Pop the start stack. 264 void rewind() 265 { 266 mStart = mStartOffsets[--mStartStackSize]; 267 mLen = dStrlen(mBuffer + mStart); 268 } 269 270 // Terminate the current string, and pop the start stack. 271 void rewindTerminate() 272 { 273 mBuffer[mStart] = 0; 274 mStart = mStartOffsets[--mStartStackSize]; 275 mLen = dStrlen(mBuffer + mStart); 276 } 277 278 /// Compare 1st and 2nd items on stack, consuming them in the process, 279 /// and returning true if they matched, false if they didn't. 280 U32 compare() 281 { 282 // Figure out the 1st and 2nd item offsets. 283 U32 oldStart = mStart; 284 mStart = mStartOffsets[--mStartStackSize]; 285 286 // Compare current and previous strings. 287 U32 ret = !dStricmp(mBuffer + mStart, mBuffer + oldStart); 288 289 // Put an empty string on the top of the stack. 290 mLen = 0; 291 mBuffer[mStart] = 0; 292 293 return ret; 294 } 295 296 void pushFrame() 297 { 298 //Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize); 299 mFrameOffsets[mNumFrames++] = mStartStackSize; 300 mStartOffsets[mStartStackSize++] = mStart; 301 mStart += ReturnBufferSpace; 302 validateBufferSize(0); 303 } 304 305 void popFrame() 306 { 307 //Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize); 308 mStartStackSize = mFrameOffsets[--mNumFrames]; 309 mStart = mStartOffsets[mStartStackSize]; 310 mLen = 0; 311 } 312 313 void clearFrames() 314 { 315 //Con::printf("StringStack clearFrames"); 316 mNumFrames = 0; 317 mStart = 0; 318 mLen = 0; 319 mStartStackSize = 0; 320 mFunctionOffset = 0; 321 } 322 323 /// Get the arguments for a function call from the stack. 324 void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false); 325}; 326 327 328// New console value stack 329class ConsoleValueStack 330{ 331 enum { 332 MaxStackDepth = 1024, 333 MaxArgs = 20, 334 ReturnBufferSpace = 512 335 }; 336 337public: 338 ConsoleValueStack(); 339 ~ConsoleValueStack(); 340 341 void pushVar(ConsoleValue *variable); 342 void pushValue(ConsoleValue &value); 343 ConsoleValue* reserveValues(U32 numValues); 344 bool reserveValues(U32 numValues, ConsoleValueRef *values); 345 ConsoleValue* pop(); 346 347 ConsoleValue *pushString(const char *value); 348 ConsoleValue *pushStackString(const char *value); 349 ConsoleValue *pushStringStackPtr(StringStackPtr ptr); 350 ConsoleValue *pushUINT(U32 value); 351 ConsoleValue *pushFLT(float value); 352 353 void pushFrame(); 354 void popFrame(); 355 356 void resetFrame(); 357 void clearFrames(); 358 359 void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false); 360 361 ConsoleValue mStack[MaxStackDepth]; 362 U32 mStackFrames[MaxStackDepth]; 363 364 U32 mFrame; 365 U32 mStackPos; 366 367 ConsoleValueRef mArgv[MaxArgs]; 368}; 369 370extern StringStack STR; 371extern ConsoleValueStack CSTK; 372 373inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; } 374 375#endif 376
