private Object getValue(final TypedCircularMessage message, final String name) {
    final Object value = message.getValue(name);
    if (value == null) {
      Logger.err("WARNING: No such value: " + name);
      return null;
    }
    if (value instanceof IPointer) {
      final IPointer p = (IPointer) value;

      if (p.getValue() == null) {
        if (!name.equals(SRLEventReader.FN_RECEIVER_ACTOR_INSTANCE)
            && !name.equals(SRLEventReader.FN_SENDER_ACTOR_INSTANCE)) {
          Logger.err(
              "Note: value of '"
                  + name
                  + "' on '"
                  + message.getStruct().getName()
                  + "' is an unresolved pointer value (NULL). Will use pointer ("
                  + p.getPointer()
                  + ")");
        }
        if (name.equals(SRLEventReader.FN_STATE) && p.getPointer() == 0L) {
          return null;
        }
        return p.getPointer();
      }
      return p.getValue();
    }

    if (value.getClass().isArray()) {
      final Object[] arr = (Object[]) value;
      return Arrays.asList(arr);
    }
    return value;
  }
 private long findReceiveTime(
     final TypedCircularMessage message, final List<TypedCircularMessage> copy, final int begin) {
   Long my = (Long) getValue(message, SRLEventReader.FN_MSG_ADDR);
   if (my == null) {
     my = (Long) getValue(message, SRLEventReader.SIGNAL_INSTANCE_ID);
   }
   final int size = copy.size();
   for (int i = begin; i < size; i++) {
     final TypedCircularMessage other = copy.get(i);
     if (other.getStruct().getId() != Message.ROSE_RECEIVE.srlTypeId()
         && other.getStruct().getId() != Message.UML_RECEIVE.srlTypeId()) {
       continue;
     }
     Long their = (Long) getValue(other, SRLEventReader.FN_MSG_ADDR);
     if (their == null) {
       their = (Long) getValue(other, SRLEventReader.SIGNAL_INSTANCE_ID);
     }
     if (their == null) {
       continue;
     }
     if (!their.equals(my)) {
       continue;
     }
     return ((CircularMessage) other.getMessage()).getTs();
   }
   return -1;
 }
  private void getRoseSend(TypedCircularMessage message, long receivedAt, long ts) {
    final UmlStateMachine sendMachine =
        getStatemachineByName(getValue(message, SRLEventReader.FN_SENDER_ACTOR).toString());
    final UmlStateMachine receiveMachine =
        getStatemachineByName(
            getValue(message, SRLEventReader.FN_RECEIVER_ACTOR.toString()).toString());
    final Long msgAddr = (Long) getValue(message, SRLEventReader.FN_MSG_ADDR);

    SRLSend srlSendEvent = new SRLSend();

    srlSendEvent.setSenderId(sendMachine.getId());
    srlSendEvent.setSenderInstance(
        ((Long) getValue(message, SRLEventReader.FN_SENDER_ACTOR_INSTANCE)).intValue());
    srlSendEvent.setSenderReplicatioIndex(
        ((Long) getValue(message, SRLEventReader.FN_SENDER_REPLICATION_INDEX)).intValue());
    srlSendEvent.setReceiverId(receiveMachine.getId());
    srlSendEvent.setReceiverInstance(
        ((Long) getValue(message, SRLEventReader.FN_RECEIVER_ACTOR_INSTANCE)).intValue());
    srlSendEvent.setReceiverReplicationIndex(
        ((Long) getValue(message, SRLEventReader.FN_RECEIVER_REPLICATION_INDEX)).intValue());
    srlSendEvent.setSignal(getValue(message, SRLEventReader.FN_SIGNAL).toString());
    srlSendEvent.setPort(getValue(message, SRLEventReader.FN_PORT).toString());
    srlSendEvent.setPortIndex((Long) getValue(message, SRLEventReader.FN_PORT_INDEX));
    srlSendEvent.setMessageAddress(msgAddr);
    srlSendEvent.setReceivedAt(resolveTimeStamp(receivedAt));
    srlSendEvent.setTs(resolveTimeStamp(((CircularMessage) message.getMessage()).getTs()));

    getSRLSend(srlSendEvent, ts);
  }
  public void getUMLSend(TypedCircularMessage message, long receivedAt, long ts) {

    UmlSend umlSend = new UmlSend(message);

    MentorIndex mentorIndex = blackbox.getMentorIndex();

    long senderClassId = umlSend.getSenderClassId();
    String senderStateMachine = mentorIndex.getClazz((int) senderClassId);
    final UmlStateMachine sendMachine = getStatemachineByName(senderStateMachine);

    long receiverClassId = umlSend.getReceiverClassId();
    String receiverStateMachine = mentorIndex.getClazz((int) receiverClassId);
    final UmlStateMachine receiveMachine = getStatemachineByName(receiverStateMachine);

    SRLSend srlSendEvent = new SRLSend();

    srlSendEvent.setSenderId(sendMachine.getId());
    srlSendEvent.setSenderInstance((int) umlSend.getSenderInstanceId());
    srlSendEvent.setSenderReplicatioIndex(0);
    srlSendEvent.setReceiverId(receiveMachine.getId());
    srlSendEvent.setReceiverInstance((int) umlSend.getReceiverInstanceId());
    srlSendEvent.setReceiverReplicationIndex(0);

    long signalId = umlSend.getSignalId();
    String signal = mentorIndex.getSignal((int) signalId);
    srlSendEvent.setSignal(signal);
    srlSendEvent.setMessageAddress(umlSend.getSignalInstanceId());
    srlSendEvent.setPort("");
    srlSendEvent.setPortIndex(Long.valueOf(0));
    srlSendEvent.setReceivedAt(resolveTimeStamp(receivedAt));
    srlSendEvent.setTs(resolveTimeStamp(((CircularMessage) message.getMessage()).getTs()));
    getSRLSend(srlSendEvent, ts);
  }
  /**
   * A hack to fix the problem with swapped ids in SRL in the mentor delivery 08032?
   *
   * @param typedCircularMessages
   */
  private void correctMessageIds(final Collection<TypedCircularMessage> typedCircularMessages) {
    for (TypedCircularMessage typedCircularMessage : typedCircularMessages) {
      Struct struct = typedCircularMessage.getStruct();

      /*
       * Detect id - name mismatch
       */
      if (struct.getId() == Message.UML_SEND.srlTypeId()) {
        if (struct.getName().equals("srl_UmlSignalReceive")) {
          struct.setId(Message.UML_RECEIVE.srlTypeId());
        }
      } else if (struct.getId() == Message.UML_RECEIVE.srlTypeId()) {
        if (struct.getName().equals("srl_UmlSignalSend")) {
          struct.setId(Message.UML_SEND.srlTypeId());
        }
      }
    }
  }
 private void preProcessTimeRef(final Collection<TypedCircularMessage> typedCircularMessages) {
   ticksPerNano = -1;
   long timeClock1 = -1;
   long timeClock2 = -1;
   long timeTicks1 = -1;
   long timeTicks2 = -1;
   long timeClocksPerSec = -1;
   for (final TypedCircularMessage msg : typedCircularMessages) {
     if (msg.getStruct().getId() != Message.TIME_REF.srlTypeId()) {
       continue;
     }
     final Long secondsSince1970 = (Long) msg.getValue("secondsSince1970");
     if (secondsSince1970 != null) {
       // TODO: save timebase in header?
     }
     final Long clock = (Long) msg.getValue("clock");
     if (clock == null) {
       continue;
     }
     final Long clocksPerSec = (Long) msg.getValue("clocksPerSec");
     if (clocksPerSec == null || clocksPerSec < 1) {
       continue;
     }
     if (timeClock1 == -1) {
       timeClock1 = clock;
       timeTicks1 = ((CircularMessage) msg.getMessage()).getTs();
       timeClock2 = -1;
       continue;
     }
     if (timeClock2 == -1) {
       timeClock2 = clock;
       timeTicks2 = ((CircularMessage) msg.getMessage()).getTs();
       timeClocksPerSec = clocksPerSec;
       break;
     }
   }
   if (timeClock1 == -1 || timeClock2 == -1) {
     return;
   }
   if (timeTicks1 == -1 || timeTicks2 == -1) {
     return;
   }
   if (timeClock1 > timeClock2) {
     long temp = timeClock2;
     timeClock2 = timeClock1;
     timeClock1 = temp;
     temp = timeTicks2;
     timeTicks2 = timeTicks1;
     timeTicks1 = temp;
   }
   if (timeClock1 >= timeClock2 || timeTicks1 >= timeTicks2) {
     return;
   }
   final double temp1 = timeClocksPerSec * (timeTicks2 - timeTicks1);
   final double temp2 = NANO_PER_SEC * (timeClock2 - timeClock1);
   ticksPerNano = temp1 / temp2;
 }
  private void getUserEvent(TypedCircularMessage message, long ts) {
    Struct struct = message.getStruct();
    userStructs.add(struct);

    int structId = struct.getId();
    FieldValues values = new FieldValues();
    List<Field> fields = struct.getFields();
    for (Field field : fields) {
      String fieldName = field.getName();
      Object value = message.getValue(fieldName);
      Type type = field.getType();
      if (field.isNullTerminated()) {
        if (type.getId() == Type.Srl.t_char.getId()) {
          String s = (String) value;
          values.addStringValue(s);
        } else {
          throw new UnsupportedOperationException(
              "Only null terminated 'char' sequences are currently supported, type is " + type);
        }
      } else if (field.getNumElements() == 1) {
        Srl srlType = Srl.valueOf(type.getId());
        switch (srlType) {
          case t_srl_I32:
          case t_srl_U32:
            Long i = (Long) value;
            values.addLongValue(i);
            break;
          default:
            throw new UnsupportedOperationException("Unsupported type: " + type);
        }

      } else {
        throw new UnsupportedOperationException(
            "Arrays are currently not supported, type is " + type);
      }
    }
    client.eventRead(new GenericEventInfo(ts, structId, values));
  }
 private String getFunctionName(final TypedCircularMessage message) {
   Object functionPointer = message.getValue(FUNCTION_FIELD);
   TypedLinearMessage functionMessage = functionMap.get(functionPointer);
   String functionName = null;
   if (functionMessage == null) {
     if (functionPointer instanceof Pointer) {
       Pointer ptr = (Pointer) functionPointer;
       functionName = Long.toHexString(ptr.getPointer());
     } else {
       throw new IllegalStateException("function field is not a pointer!");
     }
   } else {
     functionName = (String) functionMessage.getValue(FN_NAME);
   }
   return functionName;
 }
 UmlSend(final TypedCircularMessage message) {
   senderClassId = (Long) message.getValue("senderClassId");
   senderInstanceId = (Long) message.getValue("senderInstanceId");
   receiverClassId = (Long) message.getValue(RECEIVER_CLASS_ID);
   receiverInstanceId = (Long) message.getValue(RECEIVER_INSTANCE_ID);
   signalId = (Long) message.getValue(SIGNAL_ID);
   Object value = message.getValue(SIGNAL_INSTANCE_ID);
   if (value == null) {
     signalInstanceId = 0;
   } else {
     signalInstanceId = (Long) value;
   }
 }
 UmlReceive(final TypedCircularMessage message) {
   receiverClassId = (Long) message.getValue(RECEIVER_CLASS_ID);
   receiverInstanceId = (Long) message.getValue(RECEIVER_INSTANCE_ID);
   signalId = (Long) message.getValue(SIGNAL_ID);
   nextStateId = (Long) message.getValue("nextStateId");
   finishHi = (Long) message.getValue(FINISH_HI);
   finishLo = (Long) message.getValue(FINISH_LO);
   Object value = message.getValue(SIGNAL_INSTANCE_ID);
   if (value == null) {
     signalInstanceId = 0;
   } else {
     signalInstanceId = (Long) value;
   }
 }
  private void getEvents(final Collection<TypedCircularMessage> events) {
    final List<TypedCircularMessage> cmList = new ArrayList<TypedCircularMessage>(events);
    sort(cmList);
    boolean isFirstFunction = true;
    int functionIndex = 0;
    for (int i = 0; i < cmList.size(); i++) {
      final TypedCircularMessage message = cmList.get(i);
      final long ts = resolveTimeStamp(((CircularMessage) message.getMessage()).getTs());
      final int id = message.getStruct().getId();
      if (dummyRun && (id >= 0)) {
        continue;
      }
      if (id == Message.ROSE_RECEIVE.srlTypeId()) {
        getRoseReceive(message, ts);
      } else if (id == Message.ROSE_SEND.srlTypeId()) {
        final long receivedAt = findReceiveTime(message, cmList, i);
        getRoseSend(message, receivedAt, ts);
      } else if (id == Message.TASK_SWITCH.srlTypeId()) {
        getTaskSwitch(message, ts);
      } else if (id == Message.INT_BEGIN.srlTypeId()) {
        handleInterruptBegin(message, ts);
      } else if (id == Message.INT_END.srlTypeId()) {
        handleInterruptEnd(message, ts);
      } else if (id == Message.TASK_COMPLETE.srlTypeId()) {
        if (getTaskCompletion(message, ts)) {}
      } else if (id == Message.TASK_RELEASE.srlTypeId()) {
        if (getTaskRelease(message, cmList, i, ts)) {}
      } else if (id == Message.TIME_REF.srlTypeId()) {
        // nothing todo
      } else if (id == Message.UML_SEND.srlTypeId()) {
        final long receivedAt = findReceiveTime(message, cmList, i);
        getUMLSend(message, receivedAt, ts);
      } else if (id == Message.UML_RECEIVE.srlTypeId()) {
        getUMLreceive(message, ts);
      } else if (id == Message.FUNCTION_ENTER.srlTypeId()) {
        long endTime = -1;
        if (isFirstRun) {
          if (!isFirstFunction) {
            functionTimestamps.add(ts);
          } else {
            isFirstFunction = false;
          }
        } else {
          if (functionIndex < functionTimestamps.size()) {
            endTime = functionTimestamps.get(functionIndex++);
          }
        }
        getFunctionEnter(message, endTime, ts);
      } else if (id == Message.FUNCTION_EXIT.srlTypeId()) {
        long endTime = -1;
        if (isFirstRun) {
          if (!isFirstFunction) {
            functionTimestamps.add(ts);
          } else {
            isFirstFunction = false;
          }
        } else {
          if (functionIndex < functionTimestamps.size()) {
            endTime = functionTimestamps.get(functionIndex++);
          }
        }
        getFunctionExit(message, endTime, ts);
      } else if (id == Message.UML_EXAMPLE_DATA.srlTypeId()) {

      } else if (id < 0) {
        getUserEvent(message, ts);
      } else {
        throw new UnsupportedOperationException("Can not handle id = " + id);
      }
    }
  }
 private Object getValue(final TypedCircularMessage message, final int i) {
   final Field f = message.getStruct().getFields().get(i);
   final String name = f.getName();
   return getValue(message, name);
 }