For a deeper look into our Elektron API, look into:

Overview |  Quickstart |  Documentation |  Downloads |  Tutorials |  Articles

question

akrishnan avatar image
23 1 3 5

trailing junk characters in market price data

Reference:

ACT_TP_1 "ACT TYPE 1" 270 ACT_TP_2 ENUMERATED 3 ( 2 ) ENUM 1

similar to
SC_ACT_TP1 "SEC ACT TYPE 1" 280 SC_ACT_TP2 ENUMERATED 3 ( 2 ) ENUM 1

Sample message:
{"RIC":"USDAM3L3Y=","BID":"2.8510","PRIMACT_1":"2.8510","ASK":"2.8610","SEC_ACT_1":"2.8610",

"NETCHNG_1":"0.0019","PCTCHNG":"0.07","ACT_TP_1":"B<DE>(26)","VALUE_DT1":"10 JUL 2018","VALUE_TS1":"20:53:11:000:000:000","SC_ACT_TP1":" A(17)","CTBTR_1":"BROKER ","CTB_LOC1":"GFX","CTB_PAGE1":"BRKR","DLG_CODE1":" "}

SC_ACT_TP1 looks correct whereas ACT_TP_1 contains junk characters


I am doing a simple formatting to parse and print these values:

case RSSL_DT_ENUM:
{
if ((ret = rsslDecodeEnum(dIter, &fidEnumValue)) == RSSL_RET_SUCCESS)
{
RsslEnumType* pEnumType = getFieldEntryEnumType(dictionaryEntry, fidEnumValue);
if (pEnumType)
{
snprintf(m_msg_buf,
sizeof(m_msg_buf),
"\"%.*s(%d)\",",
pEnumType->display.length,
pEnumType->display.data,
fidEnumValue);
m_msg << m_msg_buf;
}

display.length is probably not accurate and hence there is junk trailing characters.
The correct value is B(26) I think

elektronrefinitiv-realtimeelektron-sdkmarket-by-pricelevel-2
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

veerapath.rungruengrayubkul avatar image
11.3k 25 8 13

@akrishnan

According to enumtype.def file, the enumeration values of "ACT_TP_1" field are defined as follows.

!
! ACRONYM    FID
! -------    ---
!
ACT_TP_1     270
...
!
! VALUE      DISPLAY   MEANING
! -----      -------   -------
...
     26       #42DE#   bid price, up or zero up tick
     27       #42FE#   bid price, down or zero down tick

The enum values enclosed in “#” are characters encoded in Reuters Multi-Lingual Text Encoding Standard (RMTES). You need to use RMTES conversion utility to convert the value to UTF-8.

The "#42DE#" value finally will be converted to 0x 42 e2 87 a7 in UTF-8 displayed as "B⇧".

Please see the “11.2.9RMTES Decoding” section in UPA Developers Guide document for more information. Below is the example code modified from the rsslConsumer example application to demonstrate the RMTES conversion.

rsslMarketPriceHandler.c

RsslRet decodeFieldEntry(RsslFieldEntry* fEntry, RsslDecodeIterator *dIter)
{
       …
    case RSSL_DT_ENUM:
       if ((ret = rsslDecodeEnum(dIter, &fidEnumValue)) == RSSL_RET_SUCCESS)
       {
             RsslEnumType *pEnumType = getFieldEntryEnumType(dictionaryEntry, fidEnumValue);
             if (pEnumType)
             {
                    /* create cache buffer for storing RMTES and applying partial updates */
                    RsslRmtesCacheBuffer rmtesCache;
                    char cacheSpace[100];
                    /* create RsslBuffer to convert into */
                    RsslBuffer utf8Buffer;
                    char convertSpace[100];
                    int i = 0;
                    RsslRet retVal = 0;
                    /* populate cache and conversion buffers with created memory */
                    rmtesCache.data = cacheSpace;
                    rmtesCache.length = 0; /* this is the used length, since cache starts out empty it should start at 0 */
                    rmtesCache.allocatedLength = 100;
                    utf8Buffer.data = convertSpace;
                    utf8Buffer.length = 100;
                    /* apply RMTES content to cache, if successful convert to UTF-8 */
                    if ((retVal = rsslRMTESApplyToCache(&(pEnumType->display), &rmtesCache)) < RSSL_RET_SUCCESS)
                    {
                           /* error while applying to cache */
                           printf("Error %s (%d) encountered while applying buffer to RMTES cache. Error Text: %s\n",
                           rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal));
                    }
                    else if ((retVal = rsslRMTESToUTF8(&rmtesCache, &utf8Buffer)) < RSSL_RET_SUCCESS)
                    {
                           /* error when converting */
                           printf("Error %s (%d) encountered while converting from RMTES to UTF-8. Error Text: %s\n",
                           rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal));
                    }
                    else
                    {
                           /* SUCCESS: conversion was successful – application can now use converted content */
                           for (i = 0; i < utf8Buffer.length; i ++) {
                                        printf(" %x", (unsigned char)utf8Buffer.data[i]);
                           }
                           printf("(%d)\n", pEnumType->value);
                    }
             }      
             else
             printf("%d\n", fidEnumValue);
       }
       else if (ret != RSSL_RET_BLANK_DATA)
       {
             printf("rsslDecodeEnum() failed with return code: %d\n", ret);
             return ret;
       }
       break;

utf8.png (52.5 KiB)
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

akrishnan avatar image
23 1 3 5

Hi Veerapath,

Thank you, that resolved the issue.

I also noticed escape literals in alphanumeric fields as follows:

DSPLY_NMLL "LCL LANG DSP NM" 1352 NULL ALPHANUMERIC 32 RMTES_STRING 32

"DSPLY_NMLL":"ESC[0` ESC[31b",

that is,

"DSPLY_NMLL":"\x1b[0` \x1b[31b"

I have in code:

case RSSL_DT_BUFFER:
case RSSL_DT_ASCII_STRING:
case RSSL_DT_UTF8_STRING:

case RSSL_DT_RMTES_STRING:
if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS)
{
snprintf(m_msg_buf, sizeof(m_msg_buf), "\"%.*s\",", fidBufferValue.length, fidBufferValue.data);
m_msg << m_msg_buf;
}
else if (ret != RSSL_RET_BLANK_DATA)
{
std::cerr << "rsslDecodeBuffer() failed with return code: " << ret << std::endl;
return ret;
}
break;

Please can you advise how this needs to be processed?

10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

veerapath.rungruengrayubkul avatar image
11.3k 25 8 13

@akrishnan

The received data could be in Partial Content Update format where only partial content is provided with offset position.

<0x1B5B><offset position><0x60><partial content>

For example, "ESC[0` " will update the existing content at offset position 0 with a space.

To process this data, you can use the RMTES Decoding code, since the rsslRMTESApplyToCache method will apply the partial content update as well. However, you need to store the character buffer for the existing content.

Below is the sample code.

  static char cacheSpaceForPartial[100];
...
case RSSL_DT_RMTES_STRING:
//
if (fEntry->fieldId == 1352)
{
	if ((ret = rsslDecodeBuffer(dIter, &fidBufferValue)) == RSSL_RET_SUCCESS)
	{
		/* create cache buffer for storing RMTES and applying partial updates */
		RsslRmtesCacheBuffer rmtesCache;
		/* create RsslBuffer to convert into */
		RsslBuffer utf8Buffer;
		char convertSpace[100];
		int i = 0;
		RsslRet retVal = 0;
		if (!rsslHasPartialRMTESUpdate(&fidBufferValue))
		{
			/* populate cache and conversion buffers with created memory */
			rmtesCache.data = cacheSpaceForPartial;
			rmtesCache.length = 0; /* this is the used length, since cache starts out empty it should start at 0 */
			rmtesCache.allocatedLength = 100;
		}
		utf8Buffer.data = convertSpace;
		utf8Buffer.length = 100;
		/* apply RMTES content to cache, if successful convert to UTF-8 */
		if ((retVal = rsslRMTESApplyToCache(&fidBufferValue, &rmtesCache)) < RSSL_RET_SUCCESS)
		{
			/* error while applying to cache */
			printf("Error %s (%d) encountered while applying buffer to RMTES cache. Error Text: %s\n",
				rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal));
		}
		else if ((retVal = rsslRMTESToUTF8(&rmtesCache, &utf8Buffer)) < RSSL_RET_SUCCESS)
		{
			/* error when converting */
			printf("Error %s (%d) encountered while converting from RMTES to UTF-8. Error Text: %s\n",
				rsslRetCodeToString(retVal), retVal, rsslRetCodeInfo(retVal));
		}
		else
		{
			/* SUCCESS: conversion was successful – application can now use converted content */
			for (i = 0; i < utf8Buffer.length; i++) {
				printf("%c", (unsigned char)utf8Buffer.data[i]);
			}
			printf("\n");
		}
	}
}
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.