xoreos  0.0.5
asbuffer.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/bitstream.h"
27 #include "src/common/debug.h"
28 
33 
35 
36 namespace Aurora {
37 
38 namespace ActionScript {
39 
40 enum Opcodes {
43  kActionStop = 0x07,
48  kActionDivide = 0x0D,
49  kActionEquals = 0x0E,
50  kActionAnd = 0x10,
51  kActionOr = 0x11,
52  kActionNot = 0x12,
54  kActionPop = 0x17,
57  kActionTrace = 0x26,
60  kActionReturn = 0x3E,
63  kActionAdd2 = 0x47,
64  kActionLess2 = 0x48,
75  kActionGetURL = 0x83,
79  kActionPush = 0x96,
80  kActionJump = 0x99,
83  kActionIf = 0x9D
84 };
85 
87  _currentLength(0), _seeked(0), _script(as) {
88 
89  assert(as);
90 }
91 
92 void ASBuffer::run(AVM &avm) {
93  _script->seek(0);
94  execute(avm);
95 }
96 
97 void ASBuffer::setConstantPool(std::vector<Common::UString> constantPool) {
98  _constants = constantPool;
99 }
100 
101 void ASBuffer::execute(AVM &avm) {
102  byte opcode;
103  debugC(kDebugActionScript, 1, "--- Start Actionscript ---");
104  do {
105  _seeked = 0;
106  opcode = _script->readByte();
107 
108  size_t length = 0;
109  if (opcode >= 0x80)
110  length = _script->readUint16LE();
111 
112  _currentLength = length;
113 
114  size_t startPos = _script->pos();
115 
116  switch (opcode) {
117  case kActionStop: actionStop(avm); break;
119  case kActionSubtract: actionSubtract(); break;
120  case kActionMultiply: actionMultiply(); break;
121  case kActionDivide: actionDivide(); break;
122  case kActionAnd: actionAnd(); break;
123  case kActionOr: actionOr(); break;
124  case kActionNot: actionNot(); break;
125  case kActionPop: actionPop(); break;
126  case kActionGetVariable: actionGetVariable(avm); break;
127  case kActionSetVariable: actionSetVariable(avm); break;
128  case kActionTrace: actionTrace(); break;
129  case kActionDefineLocal: actionDefineLocal(avm); break;
131  case kActionReturn: actionReturn(avm); break;
132  case kActionNewObject: actionNewObject(avm); break;
133  case kActionInitArray: actionInitArray(); break;
134  case kActionAdd2: actionAdd2(); break;
135  case kActionLess2: actionLess2(); break;
136  case kActionEquals2: actionEquals2(); break;
138  case kActionToNumber2: actionToNumber2(); break;
139  case kActionGetMember: actionGetMember(); break;
140  case kActionSetMember: actionSetMember(); break;
141  case kActionIncrement: actionIncrement(); break;
142  case kActionCallMethod: actionCallMethod(avm); break;
143  case kActionEnumerate2: actionEnumerate2(); break;
144  case kActionExtends: actionExtends(); break;
145  case kActionGetURL: actionGetURL(avm); break;
146  case kActionStoreRegister: actionStoreRegister(avm); break;
149  case kActionPush: actionPush(avm); break;
150  case kActionJump: actionJump(); break;
151  case kActionGetURL2: actionGetURL2(avm); break;
153  case kActionIf: actionIf(); break;
154  default:
156  if (opcode != 0)
157  warning("Unknown opcode");
158  }
159 
160  if (_script->pos() - startPos != static_cast<size_t>(length + _seeked))
161  throw Common::Exception("Invalid tag");
162  } while (opcode != 0 && _script->pos() != _script->size());
163 
164  debugC(kDebugActionScript, 1, "--- End Actionscript ---");
165 }
166 
168  avm.setStopFlag();
169 
170  debugC(kDebugActionScript, 1, "actionStop");
171 }
172 
174  debugC(kDebugActionScript, 1, "actionToggleQuality");
175 }
176 
178  Variable a = _stack.top();
179  _stack.pop();
180  Variable b = _stack.top();
181  _stack.pop();
182 
183  _stack.push(b - a);
184 
185  debugC(kDebugActionScript, 1, "actionSubtract");
186 }
187 
189  Variable a = _stack.top();
190  _stack.pop();
191  Variable b = _stack.top();
192  _stack.pop();
193 
194  _stack.push(a * b);
195 
196  debugC(kDebugActionScript, 1, "actionMultiply");
197 }
198 
200  Variable a = _stack.top();
201  _stack.pop();
202  Variable b = _stack.top();
203  _stack.pop();
204 
205  _stack.push(b / a);
206 
207  debugC(kDebugActionScript, 1, "actionDivide");
208 }
209 
211  Variable a = _stack.top();
212  _stack.pop();
213  Variable b = _stack.top();
214  _stack.pop();
215 
216  _stack.push(a && b);
217 
218  debugC(kDebugActionScript, 1, "actionAnd");
219 }
220 
222  Variable a = _stack.top();
223  _stack.pop();
224  Variable b = _stack.top();
225  _stack.pop();
226 
227  _stack.push(a || b);
228 
229  debugC(kDebugActionScript, 1, "actionOr");
230 }
231 
233  Variable variable = _stack.top();
234  _stack.pop();
235 
236  _stack.push(!variable);
237 
238  debugC(kDebugActionScript, 1, "actionNot");
239 }
240 
242  if (!_stack.empty())
243  _stack.pop();
244 
245  debugC(kDebugActionScript, 1, "actionPop");
246 }
247 
249  Common::UString name = _stack.top().asString();
250  _stack.pop();
251 
252  std::vector<Common::UString> split;
253  Common::UString::split(name, '.', split);
254 
255  Variable v = avm.getVariable(split[0]);
256  for (size_t i = 1; i < split.size(); ++i) {
257  v = v.asObject()->getMember(split[i]);
258  }
259  _stack.push(v);
260 
261  debugC(kDebugActionScript, 1, "actionGetVariable");
262 }
263 
265  Variable value = _stack.top();
266  _stack.pop();
267  Common::UString name = _stack.top().asString();
268  _stack.pop();
269 
270  avm.setVariable(name, value);
271 
272  debugC(kDebugActionScript, 1, "actionSetVariable");
273 }
274 
276  warning("ActionScript: %s", "Trace");
277 
278  debugC(kDebugActionScript, 1, "actionTrace");
279 }
280 
282  const Variable value = _stack.top();
283  _stack.pop();
284  const Variable name = _stack.top();
285  _stack.pop();
286 
287  if (!name.isString())
288  throw Common::Exception("actionDefineLocal: name is not a string!");
289 
290  // TODO: There is probably a better way, then defining local variables as global persistent variables.
291  avm.setVariable(name.asString(), value);
292 
293  debugC(kDebugActionScript, 1, "actionDefineLocal");
294 }
295 
297  // TODO
298 
299  debugC(kDebugActionScript, 1, "actionCallFunction");
300 }
301 
303  Variable ret = _stack.top();
304  _stack.pop();
305 
306  avm.setReturnValue(ret);
307 
308  debugC(kDebugActionScript, 1, "actionReturn");
309 }
310 
312  const Variable nArgs = _stack.top();
313  _stack.pop();
314 
315  if (!nArgs.isNumber())
316  throw Common::Exception("Value is not a number");
317 
318  std::list<Variable> values;
319  for (int i = 0; i < nArgs.asNumber(); ++i) {
320  values.push_back(_stack.top());
321  _stack.pop();
322  }
323 
324  _stack.push(ObjectPtr(new Array(values)));
325 
326  debugC(kDebugActionScript, 1, "actionInitArray");
327 }
328 
330  Variable a = _stack.top();
331  _stack.pop();
332  Variable b = _stack.top();
333  _stack.pop();
334 
335  _stack.push(a + b);
336 
337  debugC(kDebugActionScript, 1, "actionAdd2");
338 }
339 
341  Common::UString name = _stack.top().asString();
342  _stack.pop();
343  double numArgs = _stack.top().asNumber();
344  _stack.pop();
345 
346  std::vector<Variable> arguments;
347  for (int i = 0; i < numArgs; ++i) {
348  arguments.push_back(_stack.top());
349  _stack.pop();
350  }
351 
352  _stack.push(avm.createNewObject(name, arguments));
353 
354  debugC(kDebugActionScript, 1, "actionNewObject");
355 }
356 
358  Variable a, b;
359  a = _stack.top();
360  _stack.pop();
361  b = _stack.top();
362  _stack.pop();
363 
364  _stack.push(b < a);
365 
366  debugC(kDebugActionScript, 1, "actionLess2");
367 }
368 
370  Variable a = _stack.top();
371  _stack.pop();
372  Variable b = _stack.top();
373  _stack.pop();
374 
375  _stack.push(a == b);
376 
377  debugC(kDebugActionScript, 1, "actionEquals2");
378 }
379 
381  // TODO
382 
383  debugC(kDebugActionScript, 1, "actionToNumber2");
384 }
385 
387  _stack.push(_stack.top());
388 
389  debugC(kDebugActionScript, 1, "actionPushDuplicate");
390 }
391 
393  if (!_stack.top().isString())
394  throw Common::Exception("value is not a string");
395  Common::UString name = _stack.top().asString();
396  _stack.pop();
397  if (!_stack.top().isObject())
398  throw Common::Exception("value is not an object");
399  ObjectPtr object = _stack.top().asObject();
400  _stack.pop();
401 
402  std::vector<Common::UString> split;
403  Common::UString::split(name, '.', split);
404 
405  Variable v = object->getMember(split[0]);
406  for (size_t i = 1; i < split.size(); ++i) {
407  v = v.asObject()->getMember(split[i]);
408  }
409 
410  _stack.push(v);
411 
412  debugC(kDebugActionScript, 1, "actionGetMember");
413 }
414 
416  Variable value = _stack.top();
417  _stack.pop();
418  Common::UString name = _stack.top().asString();
419  _stack.pop();
420  ObjectPtr object = _stack.top().asObject();
421  object->setMember(name, value);
422  _stack.pop();
423 
424  debugC(kDebugActionScript, 1, "actionSetMember");
425 }
426 
428  Variable v = _stack.top();
429  _stack.pop();
430 
431  _stack.push(++v);
432 
433  debugC(kDebugActionScript, 1, "actionIncrement");
434 }
435 
437  Common::UString name;
438  if (_stack.top().isString())
439  name = _stack.top().asString();
440  _stack.pop();
441 
442  ObjectPtr object = _stack.top().asObject();
443  _stack.pop();
444 
445  unsigned int numArgs = _stack.top().asNumber();
446  _stack.pop();
447 
448  std::vector<Variable> arguments;
449  for (unsigned int i = 0; i < numArgs; ++i) {
450  arguments.push_back(_stack.top());
451  _stack.pop();
452  }
453 
454  Function *function;
455  if (name.empty()) {
456  function = dynamic_cast<Function *>(object.get());
457  } else {
458  function = dynamic_cast<Function *>(object->getMember(name).asObject().get());
459  }
460 
461  if (!function)
462  throw Common::Exception("Object is not a function");
463 
464  byte counter = 1;
465  Variable prevThis;
466 
467  if (function->getPreloadRootFlag()) {
468  avm.storeRegister(avm.getVariable("_root"), counter);
469  counter += 1;
470  }
471  if (function->getPreloadThisFlag()) {
472  if (!name.empty()) {
473  prevThis = avm.getRegister(counter);
474  avm.storeRegister(object, counter);
475  }
476  counter += 1;
477  }
478  if (function->getPreloadSuperFlag()) {
479  // TODO: Add super variable
480  counter += 1;
481  }
482 
483  for (size_t i = 0; i < arguments.size(); ++i) {
484  avm.storeRegister(arguments[i], counter);
485  counter += 1;
486  }
487 
488  avm.setReturnValue(Variable());
489  _stack.push((*function)(avm));
490 
491  if (!prevThis.isUndefined())
492  avm.storeRegister(prevThis, 1);
493 
494  debugC(kDebugActionScript, 1, "actionCallMethod");
495 }
496 
498  if (!_stack.top().isObject())
499  throw Common::Exception("actionEnumerate2: not an object");
500 
501  const ObjectPtr object = _stack.top().asObject();
502  _stack.pop();
503 
504  // Push null as the end of the enumeration.
505  _stack.push(Variable::Null());
506 
507  // Go through every slot and push the name to the stack.
508  std::vector<Common::UString> slotNames = object->getSlots();
509  for (size_t i = 0; i < slotNames.size(); ++i) {
510  _stack.push(slotNames[i]);
511  }
512 
513  debugC(kDebugActionScript, 1, "actionEnumerate2");
514 }
515 
517  ObjectPtr superClass = _stack.top().asObject();
518  _stack.pop();
519  ObjectPtr subClass = _stack.top().asObject();
520  _stack.pop();
521 
522  ObjectPtr scriptObject(new Object(superClass->getMember("prototype").asObject().get()));
523  scriptObject->setMember("constructor", superClass);
524 
525  subClass->setMember("prototype", scriptObject);
526 
527  debugC(kDebugActionScript, 1, "actionExtends");
528 }
529 
531  const Variable url = _stack.top();
532  if (!url.isString())
533  throw Common::Exception("actionGetURL: url is not a string");
534  _stack.pop();
535  const Variable target = _stack.top();
536  if (!target.isString())
537  throw Common::Exception("actionGetURL: target is not a string");
538  _stack.pop();
539 
540  const Common::UString urlString = url.asString();
541  const Common::UString targetString = target.asString();
542 
543  avm.fsCommand(urlString, targetString);
544 
545  debugC(kDebugActionScript, 1, "actionGetURL \"%s\" \"%s\"", urlString.c_str(), targetString.c_str());
546 }
547 
549  byte registerNumber = _script->readByte();
550  avm.storeRegister(_stack.top(), registerNumber);
551 
552  debugC(kDebugActionScript, 1, "actionStoreRegister %i", registerNumber);
553 }
554 
556  uint16 count = _script->readUint16LE();
557  _constants.resize(count);
558  for (int i = 0; i < count; ++i) {
559  Common::UString constant = readString();
560  _constants[i] = constant;
561  }
562 
563  debugC(kDebugActionScript, 1, "actionConstantPool");
564 }
565 
567  Common::UString functionName = readString();
568  int numParams = _script->readUint16LE();
569  int registerCount = _script->readByte();
570 
571  Common::BitStream8MSB bitstream(_script);
572 
573  bool preloadParentFlag = bitstream.getBit() != 0;
574  bool preloadRootFlag = bitstream.getBit() != 0;
575  bool suppressSuperFlag = bitstream.getBit() != 0;
576  bool preloadSuperFlag = bitstream.getBit() != 0;
577  bool suppressArgumentsFlag = bitstream.getBit() != 0;
578  bool preloadArgumentsFlag = bitstream.getBit() != 0;
579  bool suppressThisFlag = bitstream.getBit() != 0;
580  bool preloadThisFlag = bitstream.getBit() != 0;
581 
582  unsigned int reserved = bitstream.getBits(7);
583  assert(reserved == 0);
584 
585  bool preloadGlobalFlag = bitstream.getBit() != 0;
586 
587  for (int i = 0; i < numParams; ++i) {
588  _script->readByte();
589  readString();
590  }
591 
592  unsigned short codeSize = _script->readUint16LE();
593  _seeked = codeSize;
594 
595  _stack.push(
596  ObjectPtr(
597  new ScriptedFunction(
599  _constants,
600  preloadThisFlag,
601  preloadSuperFlag,
602  preloadRootFlag
603  )
604  )
605  );
606 
608 
609 
610  debugC(
612  1,
613  "actionDefineFunction2 \"%s\" %d %d %s %s %s %s %s %s %s %s %s",
614  functionName.c_str(),
615  numParams,
616  registerCount,
617  preloadParentFlag ? "true" : "false",
618  preloadRootFlag ? "true" : "false",
619  suppressSuperFlag ? "true" : "false",
620  preloadSuperFlag ? "true" : "false",
621  suppressArgumentsFlag ? "true" : "false",
622  preloadArgumentsFlag ? "true" : "false",
623  suppressThisFlag ? "true" : "false",
624  preloadThisFlag ? "true" : "false",
625  preloadGlobalFlag ? "true" : "false"
626  );
627 }
628 
630  unsigned short length = _currentLength;
631 
632  while (length != 0) {
633  byte type = _script->readByte();
634  length -= 1;
635 
636  switch (type) {
637  case 0: {
638  Common::UString string = readString();
639  _stack.push(string);
640  debugC(kDebugActionScript, 1, "actionPush \"%s\"", string.c_str());
641  length -= string.size() + 1;
642  break;
643  }
644  case 1: {
645  float floatValue = _script->readIEEEFloatLE();
646  _stack.push(floatValue);
647  debugC(kDebugActionScript, 1, "actionPush %f", floatValue);
648  length -= 4;
649  break;
650  }
651  case 2: {
652  // null
653  debugC(kDebugActionScript, 1, "actionPush null");
654  _stack.push(Variable::Null());
655  break;
656  }
657  case 3: {
658  // undefined
659  debugC(kDebugActionScript, 1, "actionPush undefined");
660  _stack.push(Variable());
661  break;
662  }
663  case 4: {
664  byte registerNumber = _script->readByte();
665  debugC(kDebugActionScript, 1, "actionPush register%d", registerNumber);
666  _stack.push(avm.getRegister(registerNumber));
667  length -= 1;
668  break;
669  }
670  case 5: {
671  bool boolValue = (_script->readByte() != 0);
672  debugC(kDebugActionScript, 1, "actionPush %s", boolValue ? "true" : "false");
673  _stack.push(boolValue);
674  length -= 1;
675  break;
676  }
677  case 6: {
678  double doubleValue = _script->readIEEEDoubleLE();
679  _stack.push(doubleValue);
680  debugC(kDebugActionScript, 1, "actionPush %f", doubleValue);
681  length -= 8;
682  break;
683  }
684  case 7: {
685  unsigned int uintValue = _script->readUint32LE();
686  _stack.push(uintValue);
687  debugC(kDebugActionScript, 1, "actionPush %u", uintValue);
688  length -= 4;
689  break;
690  }
691  // constant pool index 8bit
692  case 8: {
693  byte byteValue = _script->readByte();
694  _stack.push(_constants[byteValue]);
695  debugC(kDebugActionScript, 1, "actionPush \"%s\"", _constants[byteValue].c_str());
696  length -= 1;
697  break;
698  }
699  // constant pool index 16bit
700  case 9: {
701  unsigned short shortValue = _script->readUint16LE();
702  _stack.push(_constants[shortValue]);
703  debugC(kDebugActionScript, 1, "actionPush \"%s\"", _constants[shortValue].c_str());
704  length -= 2;
705  break;
706  }
707  default:
708  throw Common::Exception("invalid type byte in actionscript");
709  }
710  }
711 }
712 
714  int16 offset = _script->readSint16LE();
715 
717  _seeked = offset;
718 
719  debugC(kDebugActionScript, 1, "actionJump %d", offset);
720 }
721 
723  Common::BitStream8MSB bitstream(_script);
724 
725  byte sendVarsMethodId = bitstream.getBits(2);
726 
727  byte reserved = bitstream.getBits(4);
728  assert(reserved == 0);
729 
730  byte loadTargetFlag = bitstream.getBit();
731  byte loadVariablesFlag = bitstream.getBit();
732 
733  Common::UString sendVarsMethod;
734  switch (sendVarsMethodId) {
735  case 1:
736  sendVarsMethod = "GET";
737  break;
738  case 2:
739  sendVarsMethod = "POST";
740  break;
741  default:
742  sendVarsMethod = "None";
743  }
744 
745  Common::UString target = _stack.top().asString();
746  _stack.pop();
747  Common::UString url = _stack.top().asString();
748  _stack.pop();
749 
750  avm.fsCommand(target, url);
751 
752  debugC(
754  1,
755  "actionGetURL2 %s %i %i",
756  sendVarsMethod.c_str(),
757  loadTargetFlag,
758  loadVariablesFlag
759  );
760 }
761 
763  Common::UString functionName = readString();
764 
765  uint16 numParams = _script->readUint16LE();
766  for (int i = 0; i < numParams; ++i) {
767  Common::UString param = readString();
768  }
769 
770  uint16 codeSize = _script->readUint16LE();
771  _stack.push(ObjectPtr(new ScriptedFunction(_script->readStream(codeSize), _constants, false, false, false)));
772 
773  _seeked = codeSize;
774 
775  debugC(
777  1,
778  "actionDefineFunction %s",
779  functionName.c_str()
780  );
781 }
782 
784  short branchOffset = _script->readSint16LE();
785 
786  Variable variable = _stack.top();
787  _stack.pop();
788 
789  if (variable.asBoolean()) {
791  _seeked = branchOffset;
792  }
793 
794  debugC(kDebugActionScript, 1, "actionIf %i", branchOffset);
795 }
796 
798  Common::UString string;
799 
800  uint32 character = _script->readChar();
801  while (character != 0) {
802  string += character;
803  character = _script->readChar();
804  }
805  return string;
806 }
807 
808 } // End of namespace ActionScript
809 
810 } // End of namespace Aurora
ASBuffer(Common::SeekableReadStream *as)
Definition: asbuffer.cpp:86
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:122
std::stack< Variable > _stack
Definition: asbuffer.h:104
Common::SeekableReadStream * _script
Definition: asbuffer.h:107
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
void setReturnValue(Variable returnValue=Variable())
Definition: avm.cpp:156
void debugC(Common::DebugChannel channel, uint32 level, const char *s,...)
Definition: debug.cpp:34
A class holding an UTF-8 string.
Definition: ustring.h:48
void storeRegister(Variable value, byte index)
Definition: avm.cpp:69
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
Utility functions for debug output.
A variable used in the execution context.
"GActionScript", actionscript interpreter
Definition: debugman.h:62
MemoryReadStream * readStream(size_t dataSize)
Read the specified amount of data into a new[]&#39;ed buffer which then is wrapped into a MemoryReadStrea...
Definition: readstream.cpp:67
Variable getVariable(const Common::UString &name)
Definition: avm.cpp:96
void fsCommand(const Common::UString &name, const Common::UString &value)
fscommand is used for communicating with the host program.
Definition: avm.cpp:77
Implementing the reading stream interfaces for plain memory blocks.
Buffer for handling actionscript byte code.
void actionNewObject(AVM &avm)
Definition: asbuffer.cpp:340
uint32 getBit()
Read a bit from the bit stream.
Definition: bitstream.h:153
uint32 getBits(size_t n)
Read a multi-bit value from the bit stream.
Definition: bitstream.h:178
Variable createNewObject(const Common::UString &name, std::vector< Variable > arguments=std::vector< Variable >())
Definition: avm.cpp:107
void actionDefineLocal(AVM &avm)
Definition: asbuffer.cpp:281
int16_t int16
Definition: types.h:201
Exception that provides a stack of explanations.
Definition: error.h:36
Implementation for an actionscript Array class.
void setConstantPool(std::vector< Common::UString > constantPool)
Definition: asbuffer.cpp:97
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
const Common::UString & asString() const
Definition: variable.cpp:137
uint16_t uint16
Definition: types.h:202
Function objects for ActionScript.
static Variable Null()
Definition: variable.cpp:33
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
StackException Exception
Definition: error.h:59
FORCEINLINE int16 readSint16LE()
Read a signed 16-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:188
void warning(const char *s,...)
Definition: util.cpp:33
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
A bit stream.
Seek from the current position of the stream.
Definition: readstream.h:270
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:230
void actionGetVariable(AVM &avm)
Definition: asbuffer.cpp:248
An action script variable.
Definition: variable.h:44
uint32_t uint32
Definition: types.h:204
FORCEINLINE double readIEEEDoubleLE()
Read a 64-bit IEEE double stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:244
uint32 readChar()
Reads the next character from stream and returns it as an unsigned char cast to an uint32...
Definition: readstream.h:108
void actionStoreRegister(AVM &avm)
Definition: asbuffer.cpp:548
A template implementing a bit stream for different data memory layouts.
Definition: bitstream.h:85
void split(iterator splitPoint, UString &left, UString &right, bool remove=false) const
Definition: ustring.cpp:621
void actionCallMethod(AVM &avm)
Definition: asbuffer.cpp:436
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Definition: readstream.h:359
std::vector< Common::UString > _constants
Definition: asbuffer.h:101
void actionSetVariable(AVM &avm)
Definition: asbuffer.cpp:264
boost::shared_ptr< Object > ObjectPtr
Definition: object.h:43
Variable getRegister(byte index)
Definition: avm.cpp:73
void setVariable(const Common::UString &name, Variable value)
Set a specific variable.
Definition: avm.cpp:92
Interface for a seekable & readable data stream.
Definition: readstream.h:265
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
uint8 byte
Definition: types.h:209
Common::UString readString()
Definition: asbuffer.cpp:797
The Action script virtual machine (AVM).
Definition: avm.h:46