static RsslRet processSymbolListResponse(SnapshotSession* pSession, RsslMsg* msg, RsslDecodeIterator* dIter) { RsslRet ret = 0; RsslMsgKey* key = 0; RsslMap rsslMap; RsslMapEntry mapEntry; RsslVector rsslVector; RsslVectorEntry vectorEntry; char tempData[1024]; char mapKeyData[32]; RsslBuffer tempBuffer; RsslBuffer fidBufferValue; RsslLocalFieldSetDefDb fieldSetDefDb; RsslLocalElementSetDefDb elemSetDefDb; RsslElementList elemList; RsslElementEntry elemEntry; RsslFieldEntry fieldEntry; RsslFieldList fieldList; RsslBuffer stringBuf; char data[24]; tempBuffer.data = tempData; tempBuffer.length = 1024; switch(msg->msgBase.msgClass) { case RSSL_MC_REFRESH: printf("\n<%s> Received symbol list refresh.\n\n", pSession->name); case RSSL_MC_UPDATE: /* decode symbol list response */ /* get key*/ key = (RsslMsgKey *)rsslGetMsgKey(msg); if(msg->msgBase.msgClass == RSSL_MC_REFRESH) { rsslStateToString(&tempBuffer, &msg->refreshMsg.state); printf("%.*s\n", tempBuffer.length, tempBuffer.data); } rsslClearMap(&rsslMap); if ((ret = rsslDecodeMap(dIter, &rsslMap)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeMap() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if (rsslMap.flags & RSSL_MPF_HAS_SET_DEFS) { /* must ensure it is the correct type - if map contents are element list, this is a field set definition db */ if (rsslMap.containerType == RSSL_DT_FIELD_LIST) { rsslClearLocalFieldSetDefDb(&fieldSetDefDb); if ((ret = rsslDecodeLocalFieldSetDefDb(dIter, &fieldSetDefDb)) < RSSL_RET_SUCCESS) { /* decoding failures tend to be unrecoverable */ printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } } /* decode the map */ while ((ret = rsslDecodeMapEntry(dIter, &mapEntry, mapKeyData)) != RSSL_RET_END_OF_CONTAINER) { if(ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeMapEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } stringBuf.data = data; stringBuf.length = 24; rsslPrimitiveToString(&mapKeyData,rsslMap.keyPrimitiveType,&stringBuf); printf("\nID: %s, ", stringBuf.data); pSession->symbolListEntry[SymbolListCounter] = (SymbolListEntry*)malloc(sizeof(SymbolListEntry)); pSession->symbolListEntry[SymbolListCounter]->id = atoi(stringBuf.data); if ((ret = rsslDecodeFieldList(dIter, &fieldList, &fieldSetDefDb)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeMap() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } /* The following fields are needed to uniquely identify a symbol on the realtime and gap fill streams: FID Name Type 3422 Provider Symbol RMTES_STRING 8746 Provider Symbol 2 RMTES_STRING 32639 Multicast channel(RT) Vector of Element Lists 32640 Multicast Channel(Gapfill) Vector of Element Lists */ while ((ret = rsslDecodeFieldEntry(dIter, &fieldEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeFieldEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if(fieldEntry.fieldId == 8746) { if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS) { //snprintf(&pSession->symbolListEntry[SymbolListCounter]->name[0], 128, "%.*s", fidBufferValue.length, fidBufferValue.data); printf("SYMBOL2: %s", fidBufferValue.data); } else if (ret != RSSL_RET_BLANK_DATA) { printf("<%s> Error: %s (%d) encountered with rsslDecodeBuffer(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } else if (fieldEntry.fieldId == 3422) { if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS) { snprintf(&pSession->symbolListEntry[SymbolListCounter]->name[0], 128, "%.*s", fidBufferValue.length, fidBufferValue.data); printf("SYMBOL: %s", pSession->symbolListEntry[SymbolListCounter]->name); } else if (ret != RSSL_RET_BLANK_DATA) { printf("<%s> Error: %s (%d) encountered with rsslDecodeBuffer(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } else if (fieldEntry.fieldId == 32639) { int countStreamingChan = 0; rsslClearVector(&rsslVector); if ((ret = rsslDecodeVector(dIter, &rsslVector)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeVector() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if (rsslVector.flags & RSSL_VTF_HAS_SET_DEFS) { /* must ensure it is the correct type - if map contents are element list, this is a field set definition db */ if (rsslVector.containerType == RSSL_DT_ELEMENT_LIST) { rsslClearLocalElementSetDefDb(&elemSetDefDb); if ((ret = rsslDecodeLocalElementSetDefDb(dIter, &elemSetDefDb)) < RSSL_RET_SUCCESS) { /* decoding failures tend to be unrecoverable */ printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } } /* decode the vector */ while ((ret = rsslDecodeVectorEntry(dIter, &vectorEntry)) != RSSL_RET_END_OF_CONTAINER) { if(ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeVectorEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } rsslClearElementList(&elemList); if ((ret = rsslDecodeElementList(dIter, &elemList, &elemSetDefDb)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeElementList() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } while ((ret = rsslDecodeElementEntry(dIter, &elemEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeElementEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_CHANNEL_ID)) { if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].channelId)) == RSSL_RET_SUCCESS) { printf(" StreamingChanId: %d", pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].channelId); } else { printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } else if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_DOMAIN)) { if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].domain)) == RSSL_RET_SUCCESS) { printf(" StreamingChanDom: %d", pSession->symbolListEntry[SymbolListCounter]->streamingChannels[countStreamingChan].domain); } else { printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } } countStreamingChan++; } } else if (fieldEntry.fieldId == 32640) { int countGapChan = 0; rsslClearVector(&rsslVector); if ((ret = rsslDecodeVector(dIter, &rsslVector)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeVector() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if (rsslVector.flags & RSSL_VTF_HAS_SET_DEFS) { /* must ensure it is the correct type - if map contents are element list, this is a field set definition db */ if (rsslVector.containerType == RSSL_DT_ELEMENT_LIST) { rsslClearLocalElementSetDefDb(&elemSetDefDb); if ((ret = rsslDecodeLocalElementSetDefDb(dIter, &elemSetDefDb)) < RSSL_RET_SUCCESS) { /* decoding failures tend to be unrecoverable */ printf("<%s> Error %s (%d) encountered with rsslDecodeLocalElementSetDefDb(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } } /* decode the vector */ while ((ret = rsslDecodeVectorEntry(dIter, &vectorEntry)) != RSSL_RET_END_OF_CONTAINER) { if(ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeVectorEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } rsslClearElementList(&elemList); if ((ret = rsslDecodeElementList(dIter, &elemList, &elemSetDefDb)) != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeElementList() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } while ((ret = rsslDecodeElementEntry(dIter, &elemEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) { printf("<%s> rsslDecodeElementEntry() failed with return code: %d\n", pSession->name, ret); return RSSL_RET_FAILURE; } if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_CHANNEL_ID)) { if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].channelId)) == RSSL_RET_SUCCESS) { printf(" GapChanId: %d", pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].channelId); } else { printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } else if (rsslBufferIsEqual(&elemEntry.name, &RSSL_ENAME_DOMAIN)) { if ((ret = rsslDecodeUInt(dIter, &pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].domain)) == RSSL_RET_SUCCESS) { printf(" GapChanlDom: %d", pSession->symbolListEntry[SymbolListCounter]->gapChannels[countGapChan].domain); } else { printf("<%s> Error: %s (%d) encountered with rsslDecodeUInt(). Error Text: %s\n", pSession->name, rsslRetCodeToString(ret), ret, rsslRetCodeInfo(ret)); return ret; } } } } countGapChan++; } } SymbolListCounter++; } break; case RSSL_MC_STATUS: printf("\n<%s> Received Item StatusMsg for stream %i \n", pSession->name, msg->statusMsg.msgBase.streamId); if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE) { rsslStateToString(&tempBuffer, &msg->statusMsg.state); printf(" %.*s\n\n", tempBuffer.length, tempBuffer.data); } break; case RSSL_MC_ACK: /* although this application only posts on MP (Market Price), * ACK handler is provided for other domains to allow user to extend * and post on MBO (Market By Order), MBP (Market By Price), SymbolList, and Yield Curve domains */ printf("\n<%s> Received AckMsg for stream %i \n", pSession->name, msg->msgBase.streamId); /* get key */ key = (RsslMsgKey *)rsslGetMsgKey(msg); /* print out item name from key if it has it */ if (key) { printf("%.*s\nDOMAIN: %s\n", key->name.length, key->name.data, rsslDomainTypeToString(msg->msgBase.domainType)); } printf("\tackId=%u\n", msg->ackMsg.ackId); if (msg->ackMsg.flags & RSSL_AKMF_HAS_SEQ_NUM) printf("\tseqNum=%u\n", msg->ackMsg.seqNum); if (msg->ackMsg.flags & RSSL_AKMF_HAS_NAK_CODE) printf("\tnakCode=%u\n", msg->ackMsg.nakCode); if (msg->ackMsg.flags & RSSL_AKMF_HAS_TEXT) printf("\ttext=%.*s\n", msg->ackMsg.text.length, msg->ackMsg.text.data); break; default: printf("\n<%s> Recieved Unhandled Item Msg Class: %d\n", pSession->name, msg->msgBase.msgClass); break; } return RSSL_RET_SUCCESS; }
RsslRet decodeMBOUpdate(RsslDecodeIterator* pIter, RsslMsg* msg, ProviderThread* pProviderThread) { RsslFieldList fList = RSSL_INIT_FIELD_LIST; RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY; RsslMap Map = RSSL_INIT_MAP; RsslMapEntry mEntry = RSSL_INIT_MAP_ENTRY; RsslRet ret = 0; RsslPrimitive key; RsslDataType dataType; RsslPrimitive primitive; RsslDictionaryEntry* dictionaryEntry = NULL; RsslUInt genMsgTimeTracker = 0; /* decode field list */ if((ret = rsslDecodeMap(pIter, &Map)) == RSSL_RET_SUCCESS) { if(rsslMapCheckHasSetDefs(&Map) == RSSL_TRUE) { rsslClearLocalFieldSetDefDb(&pProviderThread->fListSetDef); pProviderThread->fListSetDef.entries.data = pProviderThread->setDefMemory; pProviderThread->fListSetDef.entries.length = sizeof(pProviderThread->setDefMemory); if((ret = rsslDecodeLocalFieldSetDefDb(pIter, &pProviderThread->fListSetDef)) != RSSL_RET_SUCCESS) return ret; } if(rsslMapCheckHasSummaryData(&Map) == RSSL_TRUE) { if((ret = rsslDecodeFieldList(pIter, &fList, &pProviderThread->fListSetDef)) == RSSL_RET_SUCCESS) { while ((ret = rsslDecodeFieldEntry(pIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) return ret; /* get dictionary entry */ dictionaryEntry = getDictionaryEntry(pProviderThread->pDictionary, fEntry.fieldId); if (!dictionaryEntry) { printf("Error: Decoded field ID %d not present in dictionary.\n", fEntry.fieldId); return RSSL_RET_FAILURE; } /* decode and print out fid value */ dataType = dictionaryEntry->rwfType; switch (dataType) { case RSSL_DT_INT: if((ret = rsslDecodeInt(pIter, &primitive.intType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_UINT: if((ret = rsslDecodeUInt(pIter, &primitive.uintType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_FLOAT: if ((ret = rsslDecodeFloat(pIter, &primitive.floatType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DOUBLE: if ((ret = rsslDecodeDouble(pIter, &primitive.doubleType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_REAL: if ((ret = rsslDecodeReal(pIter, &primitive.realType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DATE: if ((ret = rsslDecodeDate(pIter, &primitive.dateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_TIME: if ((ret = rsslDecodeTime(pIter, &primitive.timeType)) < RSSL_RET_SUCCESS ) return ret; break; case RSSL_DT_DATETIME: if ((ret = rsslDecodeDateTime(pIter, &primitive.dateTimeType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_QOS: if ((ret = rsslDecodeQos(pIter, &primitive.qosType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_STATE: if ((ret = rsslDecodeState(pIter, &primitive.stateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_ENUM: { RsslEnumType *pEnumTypeInfo; if ((ret = rsslDecodeEnum(pIter, &primitive.enumType)) < RSSL_RET_SUCCESS ) return ret; if (ret == RSSL_RET_BLANK_DATA) break; pEnumTypeInfo = getFieldEntryEnumType(dictionaryEntry, primitive.enumType); if (pEnumTypeInfo) primitive.bufferType = pEnumTypeInfo->display; break; } case RSSL_DT_BUFFER: case RSSL_DT_ASCII_STRING: case RSSL_DT_UTF8_STRING: case RSSL_DT_RMTES_STRING: if ((ret = rsslDecodeBuffer(pIter, &primitive.bufferType)) < RSSL_RET_SUCCESS ) return ret; break; default: printf("Error: Unhandled data type %s(%u) in field with ID %u.\n", rsslDataTypeToString(dataType), dataType, fEntry.fieldId); return RSSL_RET_FAILURE; } if (msg->msgBase.msgClass == RSSL_MC_GENERIC && ret != RSSL_RET_BLANK_DATA) { if(fEntry.fieldId == TIM_TRK_3_FID) genMsgTimeTracker = primitive.uintType; } } } else { return ret; } } while((ret = rsslDecodeMapEntry(pIter, &mEntry, &key)) != RSSL_RET_END_OF_CONTAINER) { if (mEntry.action != RSSL_MPEA_DELETE_ENTRY) { if((ret = rsslDecodeFieldList(pIter, &fList, &pProviderThread->fListSetDef)) == RSSL_RET_SUCCESS) { while ((ret = rsslDecodeFieldEntry(pIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER) { if (ret != RSSL_RET_SUCCESS) return ret; /* get dictionary entry */ dictionaryEntry = getDictionaryEntry(pProviderThread->pDictionary, fEntry.fieldId); if (!dictionaryEntry) { printf("Error: Decoded field ID %d not present in dictionary.\n", fEntry.fieldId); return RSSL_RET_FAILURE; } /* decode and print out fid value */ dataType = dictionaryEntry->rwfType; switch (dataType) { case RSSL_DT_INT: if((ret = rsslDecodeInt(pIter, &primitive.intType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_UINT: if((ret = rsslDecodeUInt(pIter, &primitive.uintType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_FLOAT: if ((ret = rsslDecodeFloat(pIter, &primitive.floatType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DOUBLE: if ((ret = rsslDecodeDouble(pIter, &primitive.doubleType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_REAL: if ((ret = rsslDecodeReal(pIter, &primitive.realType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_DATE: if ((ret = rsslDecodeDate(pIter, &primitive.dateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_TIME: if ((ret = rsslDecodeTime(pIter, &primitive.timeType)) < RSSL_RET_SUCCESS ) return ret; break; case RSSL_DT_DATETIME: if ((ret = rsslDecodeDateTime(pIter, &primitive.dateTimeType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_QOS: if ((ret = rsslDecodeQos(pIter, &primitive.qosType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_STATE: if ((ret = rsslDecodeState(pIter, &primitive.stateType)) < RSSL_RET_SUCCESS) return ret; break; case RSSL_DT_ENUM: { RsslEnumType *pEnumTypeInfo; if ((ret = rsslDecodeEnum(pIter, &primitive.enumType)) < RSSL_RET_SUCCESS ) return ret; if (ret == RSSL_RET_BLANK_DATA) break; pEnumTypeInfo = getFieldEntryEnumType(dictionaryEntry, primitive.enumType); if (pEnumTypeInfo) primitive.bufferType = pEnumTypeInfo->display; break; } case RSSL_DT_BUFFER: case RSSL_DT_ASCII_STRING: case RSSL_DT_UTF8_STRING: case RSSL_DT_RMTES_STRING: if ((ret = rsslDecodeBuffer(pIter, &primitive.bufferType)) < RSSL_RET_SUCCESS ) return ret; break; default: printf("Error: Unhandled data type %s(%u) in field with ID %u.\n", rsslDataTypeToString(dataType), dataType, fEntry.fieldId); return RSSL_RET_FAILURE; } } } else { return ret; } } } } else { return ret; } if(genMsgTimeTracker) updateLatencyStats(pProviderThread, genMsgTimeTracker); return RSSL_RET_SUCCESS; }