In this blog post I wanted to clarify the usage of ReadString and WriteString methods of MQMessage.NET class. I have seen some confusion around the usage of these methods with the CCSID of character data in the message and on the lines of usage of different Read and Write methods. Hope this post will throw some light around it.

Have you ever bump into MQRC_UNEXPECTED_ERROR error when using ReadString method to retrieve message ?

ReadString method is used to retrieve a message from the MQMessage object. ReadString method converts the character data in the message to Unicode (1200 CCSID). ReadString method should ideally be used with messages of format string. However you need to exercise a caution when using ReadString method. Since ReadString method would convert the character data in the message to Unicode, the message payload can contain only characters that can be converted to Unicode else MQRC_UNEXPECTED_ERROR (2195) error will be reported by ReadString method.

Consider for example that the message to the queue is put with CCSID 1208. When ReadString is used to retrieve the message, the message will be converted from 1208 CCSID to 1200 CCSID. With 1200 CCSID, each character will be represented with double bytes. With 1208 CCISD, each character can be represented with single / double / triple / four bytes. Conversion between 1208 and 1200 is possible only if the messages with CCSID 1208 contains either SBCS or DBCS. If the message payload contains characters that are represented with triple or four bytes, those messages cannot be converted to Unicode since it can accommodate only 2 bytes per character. If the message with CCSID 1208 contain a character that is represented with triple or four bytes (Example: emoticon is represented as F0 9F 98 82 with CCSID 1208) then the ReadString method will fail with MQRC_UNEXPECTED_ERROR.


Sample MQ trace points :-

(01)--{  MQMessage.ReadString(int)
charCount = 953
(02)---{  xcsConvertString
fromCCSID:1208 toCCSID:1200, in length:953, out length:1906 options: 00000000

!! - Conversion failed: source character too long
Data:-
 0x0388EC38 43 6F 6E 76 65 72 73 69 6F 6E 20 66 61 69 6C 65 : Conversion faile
 0x0388EC48 64 20 64 75 65 20 74 6F 20 44 42 43 53 20 65 72 : d due to DBCS er
 0x0388EC58 72 6F 72 20 69 6E 20 69 6E 70 75 74 20 73 74 72 : ror in input str
 0x0388EC68 69 6E 67 20 61 74 20 62 79 74 65 20 39 35 33 20 : ing at byte 953 
 0x0388EC78 69 6E 20 73 74 72 69 6E 67                      : in string
translated out length:1272 
(02)---}! xcsConvertString (rc=xecX_E_DBCS_ERR)
MQException CompCode: 2 Reason: 2195
(01)--}! MQMessage.ReadString(int) (rc=MQRC_UNEXPECTED_ERROR)

Characters in the message payload should contain either SBCS/DBCS which has a corresponding mapping in Unicode codepage or ReadBytes method can be used. ReadBytes/WriteBytes methods transfer bytes between the application and the message buffer without alteration (i.e) does not convert the message to 1200 code page. Hence WriteBytes method can be used to put the message if you don’t want to represent them in 1200 CharacterSet and ReadBytes methods can be used to get the message as such without any conversion.

Why does WriteString method include a null character between characters in the message payload ?

WriteString method is used to write a message to the MQMessage object. The WriteString method converts from Unicode to the character set encoded in CharacterSet. If CharacterSet is set to its default value, MQC.MQCCSI_Q_MGR, which is 0, no conversion takes place and CharacterSet is set to 1200, in which case each character will be represented with double bytes. It should be noted here that each character will be represented with double bytes, hence a simple string might be put with a null character inserted between each characters. For example, if you put a message with payload as “TestMessage”, it will be put to the queue as “T e s t M e s s a g e”

Typically Write and Reads are used in combination, WriteString and ReadString, WriteUTF and ReadUTF, WriteBytes and ReadBytes if the producer and consumer both are dot net application.

Note: .NET applications always run in Unicode, whereas in other environments applications run in the same character set as the queue manager is running under.

FOOTNOTES:-
https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.ref.dev.doc/q111220_.htm

Join The Discussion

Your email address will not be published.