void TxOut::unserialize_checked( uint8_t const * ptr, uint32_t size, uint32_t nbytes, TxRef parent, uint32_t idx) { parentTx_ = parent; index_ = idx; uint32_t numBytes = (nbytes==0 ? BtcUtils::TxOutCalcLength(ptr) : nbytes); if (size < numBytes) throw BlockDeserializingException(); dataCopy_.copyFrom(ptr, numBytes); scriptOffset_ = 8 + BtcUtils::readVarIntLength(getPtr()+8); if (dataCopy_.getSize()-scriptOffset_-getScriptSize() > size) throw BlockDeserializingException(); BinaryDataRef scriptRef(dataCopy_.getPtr()+scriptOffset_, getScriptSize()); scriptType_ = BtcUtils::getTxOutScriptType(scriptRef); uniqueScrAddr_ = BtcUtils::getTxOutScrAddr(scriptRef); if(!parentTx_.isInitialized()) { parentHeight_ = UINT32_MAX; parentHash_ = BinaryData(0); } }
void TxOutRef::unserialize(uint8_t const * ptr, uint32_t nbytes, TxRef* parent, int32_t idx) { parentTx_ = parent; index_ = idx; nBytes_ = (nbytes==0 ? BtcUtils::TxOutCalcLength(ptr) : nbytes); self_ = BinaryDataRef(ptr, nBytes_); scriptOffset_ = 8 + BtcUtils::readVarIntLength(getPtr()+8); BinaryDataRef scriptRef(self_.getPtr()+scriptOffset_, getScriptSize()); scriptType_ = BtcUtils::getTxOutScriptType(scriptRef); recipientBinAddr20_ = BtcUtils::getTxOutRecipientAddr(scriptRef, scriptType_); }
void Script::initializeObjectsSci0(SegManager *segMan, SegmentId segmentId) { bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); // We need to make two passes, as the objects in the script might be in the // wrong order (e.g. in the demo of Iceman) - refer to bug #3034713 for (int pass = 1; pass <= 2; pass++) { SciSpan<const byte> seeker = _buf->subspan(oldScriptHeader ? 2 : 0); do { uint16 objType = seeker.getUint16SEAt(0); if (!objType) break; switch (objType) { case SCI_OBJ_OBJECT: case SCI_OBJ_CLASS: { reg_t addr = make_reg(segmentId, seeker - *_buf + 4 - SCRIPT_OBJECT_MAGIC_OFFSET); Object *obj; if (pass == 1) { obj = scriptObjInit(addr); obj->initSpecies(segMan, addr); } else { obj = getObject(addr.getOffset()); if (!obj->initBaseObject(segMan, addr)) { if ((_nr == 202 || _nr == 764) && g_sci->getGameId() == GID_KQ5) { // WORKAROUND: Script 202 of KQ5 French and German // (perhaps Spanish too?) has an invalid object. // This is non-fatal. Refer to bugs #3035396 and // #3150767. // Same happens with script 764, it seems to // contain junk towards its end. _objects.erase(addr.toUint16() - SCRIPT_OBJECT_MAGIC_OFFSET); } else { error("Failed to locate base object for object at %04x:%04x in script %d", PRINT_REG(addr), _nr); } } } } break; default: break; } seeker += seeker.getUint16SEAt(2); } while ((uint32)(seeker - *_buf) < getScriptSize() - 2); } relocateSci0Sci21(segmentId); }
BinaryDataRef TxOut::getScriptRef(void) { return BinaryDataRef( dataCopy_.getPtr()+scriptOffset_, getScriptSize() ); }
BinaryDataRef TxOutRef::getScriptRef(void) { return BinaryDataRef( self_.getPtr()+scriptOffset_, getScriptSize() ); }