Skip to content

Commit eabd2ff

Browse files
committed
Common on PCF parser dealing with CFSTs that are not multiples of 4. See #10
1 parent aa15e2f commit eabd2ff

File tree

6 files changed

+23
-11
lines changed

6 files changed

+23
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Newest updates are at the top of this file.
77
- get_header() function to extract structure (#4)
88
- get_embedded_md() function
99
* Added MQMDE class for if you want to parse MQXQH messages
10+
* Add comments about PCF parser leaving padding on strings that are not rounded to 4 bytes (#10)
1011

1112
## 2025 Oct 16 - V2.0.0
1213
* First production release, based on MQ 9.4.4

code/examples/dis_queues.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@
8080
try:
8181
queue_name = queue_info[mq.CMQC.MQCA_Q_NAME]
8282
depth = queue_info[mq.CMQC.MQIA_CURRENT_Q_DEPTH]
83-
print(f'Found queue {queue_name} depth: {depth}')
83+
lputtime = mq.to_string(queue_info[mq.CMQCFC.MQCACF_LAST_PUT_TIME])
84+
lputdate = mq.to_string(queue_info[mq.CMQCFC.MQCACF_LAST_PUT_DATE])
85+
if lputdate != "":
86+
lput = lputdate + ":" + lputtime
87+
else:
88+
lput = "N/A"
89+
print(f'Found queue {queue_name} depth: {depth} lastPut: {lput}')
8490
except KeyError as e:
8591
print('Failure to decode msg because ', e)
8692

code/ibmmq/mqadmin.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def __init__(self, name=None,
397397
# as there would be no time at all to wait for the response. But we'll allow you to
398398
# find that for yourself.
399399
if response_wait_interval < 0:
400-
response_wait_interval = 60 * 60 * 1000
400+
response_wait_interval = 60 * 60 * 1000
401401
self.__response_wait_interval = response_wait_interval
402402

403403
if model_queue_name and reply_queue_name:
@@ -542,7 +542,10 @@ def unpack(message: bytes) -> tuple[dict, CFH]:
542542
if parameter.StringLength > 1:
543543
parameter = CFST(StringLength=parameter.StringLength)
544544
parameter.unpack(message[cursor:cursor + parameter.StrucLength])
545-
value = parameter.String
545+
# The parameter.String contents might include padding bytes that round up the length.
546+
# Ideally we'd truncate, but this was behaviour in the original library so I'm reluctant
547+
# to fix it.
548+
value = parameter.String # [:parameter.StringLength] - would truncate
546549
elif parameter_type == CMQCFC.MQCFT_STRING_LIST:
547550
parameter = CFSL()
548551
parameter.unpack(message[cursor:cursor + CMQCFC.MQCFSL_STRUC_LENGTH_FIXED])
@@ -551,6 +554,8 @@ def unpack(message: bytes) -> tuple[dict, CFH]:
551554
Count=parameter.Count,
552555
StrucLength=parameter.StrucLength)
553556
parameter.unpack(message[cursor:cursor + parameter.StrucLength])
557+
# CFSL doesn't have the same padding issue as CFST as all supported
558+
# attributes are multiples of 4.
554559
value = parameter.Strings
555560
elif parameter_type == CMQCFC.MQCFT_INTEGER:
556561
parameter = CFIN()

code/ibmmq/mqopts.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,19 @@ def _remove(self, key: str) -> None:
254254
This removes both the attribute and knowledge about how it is formatted
255255
"""
256256
# Have to convert tuples into a list so it can be modified
257-
l = list(self.__list)
257+
tmp_list = list(self.__list)
258258

259-
for item in l:
259+
for item in tmp_list:
260260
if item[0] == key:
261-
l.remove(item)
261+
tmp_list.remove(item)
262262
try:
263-
delattr(self,key)
263+
delattr(self, key)
264264
except AttributeError:
265265
pass
266266
break
267267

268268
# And then convert back to the tuple format
269-
self.__list = tuple(l)
270-
271-
return
269+
self.__list = tuple(tmp_list)
272270

273271
def __str__(self) -> str:
274272
rv = ''

code/ibmmq/mqpcf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ def __init__(self, **kw: Dict[str, Any]):
229229
class CFST(MQOpts):
230230
""" Construct an MQCFST (PCF String) structure with default values as per MQI.
231231
The default values may be overridden by the optional keyword arguments 'kw'.
232+
Note that the "String" may include the padding bytes, so you have to use the
233+
StringLength field to extract the real value.
232234
"""
233235

234236
def __init__(self, **kw: Dict[str, Any]):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# The version should correspond to PEP440 and gets normalised if
1818
# not in the right format. VRM can be followed with a|b|rc with a further numeric
1919
# to indicate alpha/beta/release-candidate versions.
20-
VERSION = '2.0.0'
20+
VERSION = '2.0.1'
2121

2222
# If the MQ SDK is in a non-default location, set MQ_FILE_PATH environment variable.
2323
custom_path = os.environ.get('MQ_FILE_PATH', None)

0 commit comments

Comments
 (0)