Example #1
1
Trigger* DatabaseManager::getTrigger(const QString& id) {

	SDPASSERT(Logger::instancePtr());
	Trigger* trig = NULL;

	if ( __db.isOpen() ) {
		Logger::instancePtr()->addMessage(Logger::CRITICAL, __func__,
		    QString("Failed to fetch trigger %1. Database couldn't be opened.")
		        .arg(id), true);
		return trig;
	}

	QSqlQuery query(QString("SELECT data FROM main.Trigger WHERE id LIKE '%1'").arg(id));

	if ( query.next() ) {
		QByteArray data = qUncompress(query.value(0).toByteArray());
		QDataStream stream(&data, QIODevice::ReadOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 8, 0))
		stream.setVersion(QDataStream::Qt_4_8);
#else
		stream.setVersion(QDataStream::Qt_4_6);
#endif
		trig = Trigger::create("");
		trig->fromDataStream(stream);
	}

	return trig;
}
Example #2
0
char *Trigger::getTriggers() {
	std::stringstream ss;
	{
		boost::recursive_mutex::scoped_lock scoped_lock(trigger_list_mutex);
		std::list<Trigger*>::iterator iter = all_triggers.begin();
		while (iter != all_triggers.end()) {
			Trigger *t = *iter++;
			ss << t->getName() << " (" << t->refs;
			if (t->_internals->holders.size()) {
				ss << ":";
				std::list<Action*>::iterator h_iter = t->_internals->holders.begin();
				while (h_iter != t->_internals->holders.end()) {
					ss << *(*h_iter++) << " ";
				}
			}
			ss <<	")\n";
		}
	}
	if (!ss.str().length()) return 0;
	size_t len = ss.str().length();
	char *res = new char[len+1];
	strncpy(res, ss.str().c_str(), len);
	res[len] = 0;
	return res;
}
void faultcheck_packet_setTriggerAfterIterations(const char *identifier, unsigned long iterations) {
    Trigger *trg = packetTool.trigger(identifier);

    if (trg) {
        trg->setAfterItr(iterations);
    }
}
Example #4
0
DatabaseManager::TriggerList
DatabaseManager::triggers(const QString& detectionID) {

	TriggerList l;

	if ( !__db.isOpen() )
	    return l;

	QSqlQuery query(QString("SELECT data FROM main.Trigger WHERE detection_id LIKE '%1'")
	    .arg(detectionID));

	while ( query.next() ) {
		QByteArray data = qUncompress(query.value(0).toByteArray());
		QDataStream stream(&data, QIODevice::ReadOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 8, 0))
		stream.setVersion(QDataStream::Qt_4_8);
#else
		stream.setVersion(QDataStream::Qt_4_6);
#endif
		Trigger* trig = Trigger::create("");
		trig->fromDataStream(stream);
		l << trig;
	}

	return l;
}
void faultcheck_packet_setDurationAfterTrigger(const char *identifier, int iterations) {
    Trigger *trg = packetTool.trigger(identifier);

    if (trg) {
        trg->setDuration(iterations);
    }
}
Example #6
0
int callback(void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *dataPointer)
{
  Trigger *trigger = static_cast<Trigger *>(dataPointer);
  StkFloat *samples = static_cast<StkFloat *>(inputBuffer);
  trigger->feedMe(samples, nBufferFrames);
  return (0);
}
void collisionFilter(SceneObject* object,void *key)
{
   SceneContainer::CallbackInfo* info = reinterpret_cast<SceneContainer::CallbackInfo*>(key);
   ShapeBase* ptr = reinterpret_cast<ShapeBase*>(info->key);

   if (object->getTypeMask() & ItemObjectType) {
      // We've hit it's bounding box, that's close enough for items.
      Item* item = static_cast<Item*>(object);
      if (ptr != item->getCollisionObject())
         ptr->queueCollision(item,ptr->getVelocity() - item->getVelocity());
   }
   else
      if (object->getTypeMask() & TriggerObjectType) {
         // We've hit it's bounding box, that's close enough for triggers
         Trigger* pTrigger = static_cast<Trigger*>(object);
         pTrigger->potentialEnterObject(ptr);
      }
      else
         if (object->getTypeMask() & CorpseObjectType)  {
            // Ok, guess it's close enough for corpses too...
            ShapeBase* col = static_cast<ShapeBase*>(object);
            ptr->queueCollision(col,ptr->getVelocity() - col->getVelocity());
         }
         else
            object->buildPolyList(info->context,info->polyList,info->boundingBox,info->boundingSphere);
}
Example #8
0
bool Scenario::read(bool save_triggers)
{
	printf("[R] Reading scenario\n");

	FILE *scx=fopen("scndata.hex", "rb");
	if (scx==NULL)
		return false; //must open scn before reading data

	
	trigger_start = skiptotriggers("scndata.hex");

	long bytes_read = 0;
	SKIP(scx, trigger_start);
	
	int numtriggers;
	READ(&numtriggers, sizeof(long), 1, scx);

	printf("\t[R] numtriggers=%d\n",numtriggers);
	
	long trigger_skip=0;
	bool displayed=0;

	std::vector<Trigger *> scen_triggers;
	for (int i=0; i<numtriggers; i++)
	{
		//printf("[R] TRIGGER %d\n", i);
		Trigger *t = new Trigger;
		t->read(scx);
		scen_triggers.push_back(t);
		//printf("[R] END TRIGGER %d. triggerskip=%d\n", i, ftell(scx)-bytes_read);
	}
	if (save_triggers)
		triggers = scen_triggers;
	
	printf("\t[R] Done reading triggers\n");
	
	trigger_skip = ftell(scx) - bytes_read;
	bytes_read+=trigger_skip;

	//at the end is numtriggers longs representing order of triggers.
	//skip them. they're just the display order, not execution order
	SKIP(scx, 4*numtriggers);

	trigger_end = bytes_read;

	scenario_end = skiptoscenarioend("scndata.hex");

	long filesize=fsize("scndata.hex");
	printf("\t[R] trigger start=%d, trigger end=%d\n", trigger_start, trigger_end);
	printf("\t[R] scenario_end=%d\n", scenario_end);
	printf("\t[R] scndata.hex size: %d, size without triggers: %d\n", filesize, filesize-trigger_skip-4*numtriggers-4);

	printf("\t[R] Read done\n");

	fclose(scx);

	return true;
}
int InstStrategyAutoGenTriggers::process( Node f, Theory::Effort effort, int e ){
  int peffort = f.getNumChildren()==3 ? 2 : 1;
  //int peffort = f.getNumChildren()==3 ? 2 : 1;
  //int peffort = 1;
  if( e<peffort ){
    return STATUS_UNFINISHED;
  }else{
    bool gen = false;
    if( e==peffort ){
      if( d_counter.find( f )==d_counter.end() ){
        d_counter[f] = 0;
        gen = true;
      }else{
        d_counter[f]++;
        gen = d_regenerate && d_counter[f]%d_regenerate_frequency==0;
      }
    }else{
      gen = true;
    }
    if( gen ){
      generateTriggers( f );
    }
    Debug("quant-uf-strategy")  << "Try auto-generated triggers... " << d_tr_strategy << " " << e << std::endl;
    //Notice() << "Try auto-generated triggers..." << std::endl;
    for( std::map< Trigger*, bool >::iterator itt = d_auto_gen_trigger[f].begin(); itt != d_auto_gen_trigger[f].end(); ++itt ){
      Trigger* tr = itt->first;
      if( tr ){
        bool processTrigger = itt->second;
        if( effort!=Theory::EFFORT_LAST_CALL && tr->isMultiTrigger() ){
#ifdef MULTI_TRIGGER_FULL_EFFORT_HALF
          processTrigger = d_counter[f]%2==0;
#endif
        }
        if( processTrigger ){
          //if( tr->isMultiTrigger() )
            Debug("quant-uf-strategy-auto-gen-triggers") << "  Process " << (*tr) << "..." << std::endl;
          InstMatch baseMatch;
          int numInst = tr->addInstantiations( baseMatch );
          //if( tr->isMultiTrigger() )
            Debug("quant-uf-strategy-auto-gen-triggers") << "  Done, numInst = " << numInst << "." << std::endl;
          if( d_tr_strategy==Trigger::TS_MIN_TRIGGER ){
            d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_auto_gen_min += numInst;
          }else{
            d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_auto_gen += numInst;
          }
          if( tr->isMultiTrigger() ){
            d_quantEngine->d_statistics.d_multi_trigger_instantiations += numInst;
          }
          //d_quantEngine->d_hasInstantiated[f] = true;
        }
      }
    }
    Debug("quant-uf-strategy") << "done." << std::endl;
    //Notice() << "done" << std::endl;
  }
  return STATUS_UNKNOWN;
}
Example #10
0
void Etherform::findContact(VectorF *contactNormal)
{
   SceneObject *contactObject = NULL;

   Vector<SceneObject*> overlapObjects;
   _findContact(&contactObject, contactNormal, &overlapObjects );

   // Check for triggers, corpses and items.
   const U32 filterMask = isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask;
   for ( U32 i=0; i < overlapObjects.size(); i++ )
   {
      SceneObject *obj = overlapObjects[i];
      U32 objectMask = obj->getTypeMask();

      if ( !( objectMask & filterMask ) )
         continue;

      // Check: triggers, tactical zones, corpses and items...
      //
      if (objectMask & TriggerObjectType)
      {
         Trigger* pTrigger = static_cast<Trigger*>( obj );
         pTrigger->potentialEnterObject(this);
      }
      else if (objectMask & TacticalZoneObjectType)
      {
         TacticalZone* pZone = static_cast<TacticalZone*>( obj );
         pZone->potentialEnterObject(this);
      }
      else if (objectMask & CorpseObjectType)
      {
         // If we've overlapped the worldbounding boxes, then that's it...
         if ( getWorldBox().isOverlapped( obj->getWorldBox() ) )
         {
            ShapeBase* col = static_cast<ShapeBase*>( obj );
            queueCollision(col,getVelocity() - col->getVelocity());
         }
      }
      else if (objectMask & ItemObjectType)
      {
         // If we've overlapped the worldbounding boxes, then that's it...
         Item* item = static_cast<Item*>( obj );
         if (  getWorldBox().isOverlapped(item->getWorldBox()) &&
               item->getCollisionObject() != this && 
               !item->isHidden() )
            queueCollision(item,getVelocity() - item->getVelocity());
      }
   }

   mContactInfo.clear();
   mContactInfo.contacted = contactObject != NULL;
   mContactInfo.contactObject = contactObject;

   if(mContactInfo.contacted)
      mContactInfo.contactNormal = *contactNormal;
}
Example #11
0
void TrigGeneralWindow::SetIgnoreDefeatDraw(bool ignoreDefeatDraw)
{
    Trigger* trigger;
    if ( CM->getTrigger(trigger, trigIndex) )
    {
        trigger->setIgnoreDefeatDraw(ignoreDefeatDraw);
        CM->notifyChange(false);
        RefreshWindow(trigIndex);
    }
}
Example #12
0
void TrigGeneralWindow::SetPausedTrigger(bool paused)
{
    Trigger* trigger;
    if ( CM->getTrigger(trigger, trigIndex) )
    {
        trigger->setFlagPaused(paused);
        CM->notifyChange(false);
        RefreshWindow(trigIndex);
    }
}
END_TEST

START_TEST ( test_Trigger )
{
  Trigger* t = new Trigger(2, 4);
  
  fail_unless (t->hasRequiredAttributes());

  delete t;
}
Example #14
0
void TrigGeneralWindow::SetIgnoreMiscActionsOnce(bool ignoreMiscActionsOnce)
{
    Trigger* trigger;
    if ( CM->getTrigger(trigger, trigIndex) )
    {
        trigger->setIgnoreMiscActionsOnce(ignoreMiscActionsOnce);
        CM->notifyChange(false);
        RefreshWindow(trigIndex);
    }
}
Example #15
0
void TrigGeneralWindow::SetDisabledTrigger(bool disabled)
{
    Trigger* trigger;
    if ( CM->getTrigger(trigger, trigIndex) )
    {
        trigger->setDisabled(disabled);
        CM->notifyChange(false);
        RefreshWindow(trigIndex);
    }
}
Example #16
0
void TrigGeneralWindow::SetPreserveTrigger(bool preserve)
{
    Trigger* trigger;
    if ( CM->getTrigger(trigger, trigIndex) )
    {
        trigger->setPreserveTriggerFlagged(preserve);
        CM->notifyChange(false);
        RefreshWindow(trigIndex);
    }
}
//
// -- ResetRecursionCounter()
//
// When triggerDB is allocated from the contextHeap (see func heap()),
// then we must make sure that after each statement the recursion counter 
// of every Trigger object is 0. Called from TriggerDB::cleanupPerStatement().
//
// only used when triggers are allocated from the cntext heap. 
// Currently triggers are allocated from the statement heap.
// See method Trigger::Heap() in file Triggers.h for more details
// LCOV_EXCL_START
static void 
ResetRecursionCounter(TriggerList* triggerList)
{
  if (triggerList == NULL)
    return;
  Trigger * trg;
  for (CollIndex i=0; i<triggerList->entries(); i++) 
  {
    trg=(*triggerList)[i];
    trg->resetRecursionCounter();
  }
}
Example #18
0
bool Store::IsItemAvailable(unsigned int slot) const
{
	Game * game = core->GetGame();
	//0     - not infinite, not conditional
	//-1    - infinite
	//other - pst trigger ref

	Trigger *trigger = items[slot]->trigger;
	if (trigger) {
		return trigger->Evaluate(game->GetSelectedPCSingle(false)) != 0;
	}
	return true;
}
Example #19
0
END_TEST


START_TEST (test_WriteL3SBML_Trigger)
{
  const char* expected = "<trigger/>";

  Trigger *t = D->createModel()->createEvent()->createTrigger();
  
  char* tsbml = t->toSBML();
  fail_unless( equals(expected,tsbml) );
  safe_free(tsbml);
}
END_TEST

START_TEST ( test_Trigger )
{
  Trigger* t = new Trigger(2, 4);
  
  fail_unless (!(t->hasRequiredElements()));

  t->setMath(SBML_parseFormula("ar"));

  fail_unless (t->hasRequiredElements());

  delete t;
}
Example #21
0
u32 G_BoxTriggers( const aabb& bb, arraySTD_c<Trigger*>& out )
{
	out.clear();
	// TODO: speed this up with kd tree
	for ( u32 i = 0; i < g_triggers.size(); i++ )
	{
		Trigger* t = g_triggers[i];
		const aabb& tBB = t->getAbsBounds();
		if ( tBB.intersect( bb ) )
		{
			out.push_back( t );
		}
	}
	return out.size();
}
Example #22
0
END_TEST


START_TEST (test_WriteL3SBML_Trigger_persistent)
{
  const char* expected = "<trigger initialValue=\"true\" persistent=\"false\"/>";

  Trigger *t = D->createModel()->createEvent()->createTrigger();
  t->setPersistent(false);
  t->setInitialValue(true);
  
  char* tsbml = t->toSBML();
  fail_unless( equals(expected,tsbml) );
  safe_free(tsbml);
}
Example #23
0
static void callbackRoutineExit(THREADID threadId, PyObject *callback)
{
    if (!analysisTrigger.getState())
        /* Analysis locked */
        return;
    processingPyConf.callbackRoutine(threadId, callback);
}
Example #24
0
static void callbackBefore(IRBuilder *irb, CONTEXT *ctx, BOOL hasEA, ADDRINT ea, THREADID threadId)
{
    /* Some configurations must be applied before processing */
    processingPyConf.applyConfBeforeProcessing(irb);

    if (!analysisTrigger.getState())
        /* Analysis locked */
        return;

    if (hasEA)
        irb->setup(ea);

    /* Update the current context handler */
    ap.updateCurrentCtxH(new PINContextHandler(ctx, threadId));

    /* Setup Information into Irb */
    irb->setThreadID(ap.getThreadID());

    /* Python callback before IR processing */
    processingPyConf.callbackBeforeIRProc(irb, &ap);

    Inst *inst = irb->process(ap);
    ap.addInstructionToTrace(inst);

    /* Export some information from Irb to Inst */
    inst->setOpcode(irb->getOpcode());
    inst->setOpcodeCategory(irb->getOpcodeCategory());
    inst->setOperands(irb->getOperands());

    /* Python callback before instruction processing */
    processingPyConf.callbackBefore(inst, &ap);
}
Example #25
0
double VillageControl::Villain::getTriggerValue(const Trigger& trigger, const VillageControl* self) const {
  double powerMaxProb = 1.0 / 10000; // rather small chance that they attack just because you are strong
  double victimsMaxProb = 1.0 / 500;
  double populationMaxProb = 1.0 / 500;
  double goldMaxProb = 1.0 / 500;
  double stolenMaxProb = 1.0 / 300;
  double entryMaxProb = 1.0 / 20.0;
  switch (trigger.getId()) {
    case AttackTriggerId::TIMER: 
      return collective->getTime() >= trigger.get<int>() ? 0.05 : 0;
    case AttackTriggerId::ROOM_BUILT: 
      return collective->getSquares(trigger.get<SquareType>()).size() *
          getRoomProb(trigger.get<SquareType>().getId());
    case AttackTriggerId::POWER: 
      return powerMaxProb * powerClosenessFun(self->getCollective()->getDangerLevel(), collective->getDangerLevel());
    case AttackTriggerId::SELF_VICTIMS:
      return victimsMaxProb * victimsFun(self->victims.count(collective) ? self->victims.at(collective) : 0, 0);
    case AttackTriggerId::ENEMY_POPULATION:
      return populationMaxProb * populationFun(
          collective->getCreatures(MinionTrait::FIGHTER).size(), trigger.get<int>());
    case AttackTriggerId::GOLD:
      return goldMaxProb * goldFun(collective->numResource(Collective::ResourceId::GOLD), trigger.get<int>());
    case AttackTriggerId::STOLEN_ITEMS:
      return stolenMaxProb 
          * stolenItemsFun(self->stolenItemCount.count(collective) ? self->stolenItemCount.at(collective) : 0);
    case AttackTriggerId::ENTRY:
      return entryMaxProb * self->entries.count(collective);
  }
  return 0;
}
Example #26
0
void Creature::addAttack(string& prt,
                         list<Condition>::iterator s1,
                         list<Condition>::iterator e1,
                         list<Action>::iterator s2,
                         list<Action>::iterator e2)
{
    Trigger trig = Trigger("attack",prt,true);
    list<Condition>::iterator i;
    for(i=s1; i!=e1; ++i) {
        trig.addCondition(*i);
    }
    list<Action>::iterator t;
    for(t=s2; t!=e2; ++t) {
        trig.addAction(*t);
    }
    addTrigger(trig);
}
Example #27
0
int main(int length, char * arguments[])
{
	if (length == 3)
	{
		Trigger trigger;
		trigger.Url = arguments[1];
		trigger.ProjectName = arguments[2];

		trigger.Process();
	}
	else
	{
		fprintf(stdout,"Syntax: dctrigger <url> <project_name>\n");
	}

	return 0;
}
RETCODE World::EntityLoad_Trigger(hQBSP qbsp, const EntityParse & entityDat)
{
	//create new trigger
	Trigger *newObj = new Trigger; assert(newObj);

	///////////////////////////////////////////////////////
	//load up the common stuff
	EntityLoad_CommonObject(qbsp, entityDat, dynamic_cast<Object *>(newObj));

	const char *pStr;
	int			iVal;

	///////////////////////////////////////////////////////
	//can it only be turned on once?
	pStr = entityDat.GetVal("bOnce");
	if(pStr)
		sscanf(pStr, "%d", &iVal);
	else
		iVal = 0;

	newObj->SetFlag(OBJ_FLAG_ONCE_ONLY, iVal ? true : false);

	//get script file
	char scriptPath[MAXCHARBUFF];

	strcpy(scriptPath, m_filePath.c_str());
	strcpy(GetExtension(scriptPath), SCENE_EXT);

	///////////////////////////////////////////////////////
	//check if we want multiple entities to activate the trigger
	pStr = entityDat.GetVal("bAllowMultiple");
	if(pStr)
	{
		sscanf(pStr, "%d", &iVal);
		newObj->AllowMultipleEntities(iVal == 1 ? true : false);
	}

	///////////////////////////////////////////////////////
	//set the script for 'on'
	pStr = entityDat.GetVal("script");
	if(pStr)
		newObj->LoadScript(scriptPath, pStr);

	return RETCODE_SUCCESS;
}
END_TEST


START_TEST ( test_Event_parent_NULL )
{
    SBMLDocument *d = new SBMLDocument(2, 4);
    Model *m = d->createModel();
    Event *c = m->createEvent();
    EventAssignment *ea = c->createEventAssignment();
    Trigger *t = new Trigger(2, 4);
    t->setMath(new ASTNode());
    Delay *dy = new Delay(2, 4);
    dy->setMath(new ASTNode());
    c->setTrigger(t);
    c->setDelay(dy);

    fail_unless(c->getAncestorOfType(SBML_MODEL) == m);
    fail_unless(c->getTrigger()->getParentSBMLObject() == c);
    fail_unless (c->getDelay()->getSBMLDocument() == d);
    fail_unless(ea->getAncestorOfType(SBML_EVENT) == c);

    Event *c1 = c->clone();
    delete d;

    fail_unless(c1->getAncestorOfType(SBML_MODEL) == NULL);
    fail_unless(c1->getParentSBMLObject() == NULL);
    fail_unless (c1->getSBMLDocument() == NULL);

    fail_unless(c1->getEventAssignment(0)->getAncestorOfType(SBML_MODEL) == NULL);
    fail_unless(c1->getEventAssignment(0)->getAncestorOfType(SBML_EVENT) == c1);
    fail_unless(c1->getEventAssignment(0)->getParentSBMLObject() != NULL);
    fail_unless(c1->getEventAssignment(0)->getSBMLDocument() == NULL);

    fail_unless(c1->getTrigger()->getAncestorOfType(SBML_MODEL) == NULL);
    fail_unless(c1->getTrigger()->getAncestorOfType(SBML_EVENT) == c1);
    fail_unless(c1->getTrigger()->getParentSBMLObject() != NULL);
    fail_unless(c1->getTrigger()->getSBMLDocument() == NULL);

    fail_unless(c1->getDelay()->getAncestorOfType(SBML_MODEL) == NULL);
    fail_unless(c1->getDelay()->getAncestorOfType(SBML_EVENT) == c1);
    fail_unless(c1->getDelay()->getParentSBMLObject() != NULL);
    fail_unless(c1->getDelay()->getSBMLDocument() == NULL);

    delete c1;
}
Example #30
0
static void TRACE_Instrumentation(TRACE trace, VOID *programName)
{
    boost::filesystem::path pname(reinterpret_cast<char*>(programName));

    for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) {
        for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) {

            /* ---- Speed up process ---- */
            IMG currentImgName = IMG_FindByAddress(INS_Address(ins));
            if (!IMG_Valid(currentImgName))
                continue;

            boost::filesystem::path pcurrent(IMG_Name(currentImgName));
            if (!analysisTrigger.getState() && strcmp(pname.leaf().c_str(), pcurrent.leaf().c_str()))
                continue;
            /* ---- End of speed up process ---- */

            IRBuilder *irb = createIRBuilder(ins);

            /* Callback before */
            if (INS_MemoryOperandCount(ins) > 0)
                INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) callbackBefore,
                               IARG_PTR, irb,
                               IARG_CONTEXT,
                               IARG_BOOL, true,
                               IARG_MEMORYOP_EA, 0,
                               IARG_THREAD_ID,
                               IARG_END);
            else
                INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) callbackBefore,
                               IARG_PTR, irb,
                               IARG_CONTEXT,
                               IARG_BOOL, false,
                               IARG_ADDRINT, 0,
                               IARG_THREAD_ID,
                               IARG_END);

            /* Callback after */
            /* Syscall after context must be catcher with IDREF.CALLBACK.SYSCALL_EXIT */
            if (INS_IsSyscall(ins) == false) {
                IPOINT where = IPOINT_AFTER;
                if (INS_HasFallThrough(ins) == false)
                    where = IPOINT_TAKEN_BRANCH;
                INS_InsertCall(ins, where, (AFUNPTR)callbackAfter, IARG_CONTEXT, IARG_THREAD_ID, IARG_END);
            }

            /* I/O memory monitoring for snapshot */
            if (INS_OperandCount(ins) > 1 && INS_MemoryOperandIsWritten(ins, 0))
                INS_InsertCall(
                    ins, IPOINT_BEFORE, (AFUNPTR)callbackSnapshot,
                    IARG_MEMORYOP_EA, 0,
                    IARG_UINT32, INS_MemoryWriteSize(ins),
                    IARG_END);

        }
    }
}