static really_inline void rawStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { assert(stream_state); assert(scratch); char *state = getMultiState(stream_state); u8 broken = getBroken(state); if (unlikely(broken)) { assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); scratch->core_info.broken = broken; return; } DEBUG_PRINTF("::: streaming rose ::: offset = %llu len = %zu\n", stream_state->offset, scratch->core_info.len); const struct RoseEngine *rose = stream_state->rose; assert(rose); u8 *rose_state = (u8 *)state; roseStreamExec(rose, rose_state, scratch, selectAdaptor(rose), selectSomAdaptor(rose), scratch); if (!told_to_stop_matching(scratch) && isAllExhausted(rose, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); scratch->core_info.broken = BROKEN_EXHAUSTED; } }
static really_inline void report_eod_matches(hs_stream_t *id, hs_scratch_t *scratch, match_event_handler onEvent, void *context) { DEBUG_PRINTF("--- report eod matches at offset %llu\n", id->offset); assert(onEvent); const struct RoseEngine *rose = id->rose; char *state = getMultiState(id); if (getBroken(state)) { DEBUG_PRINTF("stream is broken, just freeing storage\n"); return; } populateCoreInfo(scratch, rose, state, onEvent, context, NULL, 0, getHistory(state, rose, id->offset), getHistoryAmount(rose, id->offset), id->offset, 0); if (rose->somLocationCount) { loadSomFromStream(scratch, id->offset); } if (!id->offset) { if (rose->boundary.reportZeroEodOffset) { processReportList(rose, rose->boundary.reportZeroEodOffset, 0, scratch); } } else { if (rose->boundary.reportEodOffset) { processReportList(rose, rose->boundary.reportEodOffset, id->offset, scratch); } if (rose->requiresEodCheck) { switch (rose->runtimeImpl) { default: case ROSE_RUNTIME_PURE_LITERAL: assert(0); case ROSE_RUNTIME_FULL_ROSE: rawEodExec(id, scratch); break; case ROSE_RUNTIME_SINGLE_OUTFIX: soleOutfixEodExec(id, scratch); break; } } } if (rose->hasSom && !told_to_stop_matching(scratch)) { int halt = flushStoredSomMatches(scratch, ~0ULL); if (halt) { DEBUG_PRINTF("told to stop matching\n"); scratch->core_info.broken = BROKEN_FROM_USER; DEBUG_PRINTF("broken = %hhd\n", scratch->core_info.broken); } } }
/* doTask() for RescueRobot. */ void RescueRobot::doTask(MapPosition m[XMAP][YMAP],vector<Vehicle*> rf){ if(getBroken() == false){ /* Checking if the robot is broken. */ int broken_x = 0; int broken_y = 0; int cur_vehicle_id = 0; bool is_broken = false; bool fixed_a_vehicle = false; /* Loop that scans the area around the robot, to see if any robot there is broken. */ for (int i = (x-1); i <= (x+1); i++){ for (int j = (y-1); j <= (y+1); j++){ if ( i == x && j == y){ /* Except for the position of the robot. */ continue; } else if (i == XMAP || i == -1){ /* Except for values that point outside the map. */ continue; } else if (j == YMAP || j == -1){ /* Except for values that point outside the map. */ continue; } broken_x = 0; broken_y = 0; is_broken = false; /* If position is taken, check the vehicle in it. */ if(m[i][j].getTaken() == true){ cur_vehicle_id = m[i][j].getCurrentVehicleID(); /* Getting vehicle's information through searching in the vector. */ for(unsigned int k=0; k<rf.size(); k++){ if(cur_vehicle_id == rf[k]->getID()){ is_broken = rf[k]->getBroken(); /* If the vehicle is broken, fix it and exit. */ if(is_broken == true){ broken_x = i; broken_y = j; /* Repairing the vehicle. */ rf[k]->setBroken(false); rf[k]->setRoundsBroken(0); /* Increasing counter of repaired vehicles. */ setNumberOfRepaired(getNumberOfRepaired()+1); fixed_a_vehicle = true; goto end_of_repair; } } } } } } end_of_repair: /* If the robot fixed something, then the message below is printed. */ if(fixed_a_vehicle == true){ cout << " >>> " << getName() << "(#" << getID() << ") just repaired a vehicle at (" << broken_x << "," << broken_y << ")." << endl; } } else { cout << " >>> " << getName() << "(#" << getID() << ") at (" << x << "," << y << ") cannot perform any tasks due to breakdown." << endl; } }
/* doTask() for ResearchRobot. */ void ResearchRobot::doTask(MapPosition m[XMAP][YMAP],vector<Vehicle*> rf){ if(getBroken() == false){ /* Checking if the robot is broken. */ float current_danger = m[x][y].getDanger(); bool is_flag_set = m[x][y].getFlag(); /* If current position is dangerous and has no flag yet, the robot places one. */ if (current_danger > 0.7 && is_flag_set == false) { m[x][y].setFlag(true); m[x][y].setDisplayName((char*) " x "); setNumberOfFlags(getNumberOfFlags()+1); cout << " >>> " << getName() << "(#" << getID() << ") just flagged position (" << x << "," << y << ") as dangerous." << endl; } } else { cout << " >>> " << getName() << "(#" << getID() << ") at (" << x << "," << y << ") cannot perform any tasks due to breakdown." << endl; } }
static really_inline void pureLiteralStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { assert(stream_state); assert(scratch); char *state = getMultiState(stream_state); u8 broken = getBroken(state); if (unlikely(broken)) { assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); scratch->core_info.broken = broken; return; } const struct RoseEngine *rose = stream_state->rose; const struct HWLM *ftable = getFLiteralMatcher(rose); size_t len2 = scratch->core_info.len; u8 *hwlm_stream_state; if (rose->floatingStreamState) { hwlm_stream_state = getFloatingMatcherState(rose, (u8 *)state); } else { hwlm_stream_state = NULL; } DEBUG_PRINTF("::: streaming rose ::: offset = %llu len = %zu\n", stream_state->offset, scratch->core_info.len); // Pure literal cases don't have floatingMinDistance set, so we always // start the match region at zero. const size_t start = 0; hwlmExecStreaming(ftable, scratch, len2, start, selectHwlmAdaptor(rose), scratch, rose->initialGroups, hwlm_stream_state); if (!told_to_stop_matching(scratch) && isAllExhausted(rose, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); scratch->core_info.broken = BROKEN_EXHAUSTED; } }
static really_inline void rawEodExec(hs_stream_t *id, hs_scratch_t *scratch) { const struct RoseEngine *rose = id->rose; char *state = getMultiState(id); u8 broken = getBroken(state); if (broken) { DEBUG_PRINTF("stream already broken\n"); assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); return; } if (isAllExhausted(rose, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); return; } roseEodExec(rose, (u8 *)state, id->offset, scratch, selectAdaptor(rose), selectSomAdaptor(rose), scratch); }
static never_inline void soleOutfixEodExec(hs_stream_t *id, hs_scratch_t *scratch) { const struct RoseEngine *t = id->rose; char *state = getMultiState(id); u8 broken = getBroken(state); if (broken) { DEBUG_PRINTF("stream already broken\n"); assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); return; } if (isAllExhausted(t, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); return; } assert(t->outfixEndQueue == 1); assert(!t->amatcherOffset); assert(!t->ematcherOffset); assert(!t->fmatcherOffset); const struct NFA *nfa = getNfaByQueue(t, 0); struct mq *q = scratch->queues; initQueue(q, 0, t, scratch); if (!scratch->core_info.buf_offset) { DEBUG_PRINTF("buf_offset is zero\n"); return; /* no vacuous engines */ } nfaExpandState(nfa, q->state, q->streamState, q->offset, queue_prev_byte(q, 0)); assert(nfaAcceptsEod(nfa)); nfaCheckFinalState(nfa, q->state, q->streamState, q->offset, q->cb, q->som_cb, scratch); }
static inline hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data, unsigned length, UNUSED unsigned flags, hs_scratch_t *scratch, match_event_handler onEvent, void *context) { if (unlikely(!id || !scratch || !data || !validScratch(id->rose, scratch))) { return HS_INVALID; } const struct RoseEngine *rose = id->rose; char *state = getMultiState(id); u8 broken = getBroken(state); if (broken) { DEBUG_PRINTF("stream is broken, halting scan\n"); if (broken == BROKEN_FROM_USER) { return HS_SCAN_TERMINATED; } else { assert(broken == BROKEN_EXHAUSTED); return HS_SUCCESS; } } // We avoid doing any work if the user has given us zero bytes of data to // scan. Arguably we should define some semantics for how we treat vacuous // cases here. if (unlikely(length == 0)) { DEBUG_PRINTF("zero length block\n"); assert(getBroken(state) != BROKEN_FROM_USER); return HS_SUCCESS; } u32 historyAmount = getHistoryAmount(rose, id->offset); populateCoreInfo(scratch, rose, state, onEvent, context, data, length, getHistory(state, rose, id->offset), historyAmount, id->offset, flags); assert(scratch->core_info.hlen <= id->offset && scratch->core_info.hlen <= rose->historyRequired); prefetch_data(data, length); if (rose->somLocationCount) { loadSomFromStream(scratch, id->offset); } if (!id->offset && rose->boundary.reportZeroOffset) { DEBUG_PRINTF("zero reports\n"); processReportList(rose, rose->boundary.reportZeroOffset, 0, scratch); } switch (rose->runtimeImpl) { default: assert(0); case ROSE_RUNTIME_FULL_ROSE: rawStreamExec(id, scratch); break; case ROSE_RUNTIME_PURE_LITERAL: pureLiteralStreamExec(id, scratch); break; case ROSE_RUNTIME_SINGLE_OUTFIX: soleOutfixStreamExec(id, scratch); } if (rose->hasSom && !told_to_stop_matching(scratch)) { int halt = flushStoredSomMatches(scratch, ~0ULL); if (halt) { setBroken(state, BROKEN_FROM_USER); scratch->core_info.broken = BROKEN_FROM_USER; } } if (likely(!can_stop_matching(scratch))) { maintainHistoryBuffer(id->rose, getMultiState(id), data, length); id->offset += length; /* maintain offset */ if (rose->somLocationCount) { storeSomToStream(scratch, id->offset); } } else if (told_to_stop_matching(scratch)) { return HS_SCAN_TERMINATED; } else { /* exhausted */ setBroken(state, BROKEN_EXHAUSTED); } return HS_SUCCESS; }