Attachment Layout for WebSphere MQ and MSMQ

Attachments consist of multiple physical messages. The beginning of an attachment is recognized by having a message type of 100000. To identify this message, it will be referred to as the attachment header.
Layout of an attachment header message:
Note: All character strings are null terminated.
   byte[24] - header correlid
(correlationid of this header
                 message)
   long     - original msg type (msg type
provided
by the
                 sending application)
   byte[24] - original msg correlid (msg correlationid
                 provided by the sending application)
   byte[24] - message correlid (generated correlationid for
                 the msg)
   int      - number of attachments
   --------------------------------------------------------
   int      - attachment type
          1 - SAS data set
          2 - External text file
          3 - External binary file
   byte[24] - attachment correlid (correlationid associated
                 with this attachment)
   int      - length of qualifier 1
   char[]   - qualifier 1
              external files: designates the sending file
                 specification "FILENAME" or "FILEREF"
              dataset: designates the sending library name
   int      - length of qualifier 2
   char[]   - qualifier 2
              external files: designates the sending
                 filename or fileref
              dataset: designates the sending member name
   int      - length of attachment description
   char[]   - attachment description
   int      - user specified minor version number
   int      - user specified major version number
   --------------------------------------------------------
   .
   .
   . repeat for each attachment in the list
Other physical messages are also needed to make up a complete attachment. These messages will be called subordinated messages, and they all have a message type of 100001.
The subordinate message that usually follows after the attachment header message is the application message. It can be filtered by using the message correlid located in the attachment header message. It contains the actual application-generated message.
The attachment (external file or SAS data set) subordinate messages follow next. They contain the necessary information to re-create the file or data set.
To locate the subordinate message that contains the number of physical messages that are associated with this attachment, filter it by using the attachment correlid that is located in the attachment header message. The content of this message is a single numeric integer that corresponds to the number of messages that are associated with this attachment, excluding this message. To filter the rest of the messages that are associated with this attachment, use the same attachment correlid that is located in the attachment header message (16 bytes) with a sequence number (4 bytes) added to the end of it. For example, if the attachment correlid was 000102030405060708090A0B0C0D0E0F, you would filter this message to find out how many more messages are associated with this attachment. For example, if three more messages make up this attachment, then you can locate these messages by filtering a correlid of 000102030405060708090A0B0C0D0E0F00000001, 000102030405060708090A0B0C0D0E0F00000002, and 000102030405060708090A0B0C0D0E0F00000003, respectively. The sequenced attachment correlid messages are actually sent to the queue before the non-sequenced attachment correlid message. Therefore, if you are able to receive the non-sequenced attachment correlid message (that is, a message that tells you how many messages make up this attachment), then you can make sure that the complete attachment has been queued.
At this point, attachment processing differs depending on the attachment type.
For external files, the first sequenced attachment correlid message (attachment_correlid+00000001) contains two numeric integers that correspond to the file's logical record length and size, respectively. The rest of the attachment correlid messages make up the file itself. The contents of these messages are as follows:
--------------------------------
   long    - size of logical record
   char[]  - actual record
   --------------------------------
   .
   .
   . repeat until the end of file or 32K limit is reached
These messages are limited to 32K. If a file is too large to fit, then it spans multiple physical messages.
Here is an example of an external file attachment residing on a queue:
   msg type
msg correlid                              msg contents
   --------   ------------

    ------------
   100000     1111111111111111111111111111111100000000
1111111111111111111111111111111100000000
                                                        00000001

0000000000000000000000000000000000000000

2222222222222222222222222222222200000000
                                                        00000001
                                                        00000003

3333333333333333333333333333333300000000
                                                        00000008
                                                        "FILENAME"
                                                        0000000D
                                                        "d:\mytext.txt"
                                                        0000000C
                                                        "Text file..."
                                                        00000000
                                                        00000000
   100001     2222222222222222222222222222222200000000  "This is the actual
application message."
   100001     3333333333333333333333333333333300000001  lrecl|filesize
   100001     3333333333333333333333333333333300000002
len|record|len|record|len|record...
   100001     3333333333333333333333333333333300000003
len|record|len|record|len|record...
   100001     3333333333333333333333333333333300000000  00000003
For data sets, the sequenced attachment correlid messages begin with a type identifier. This identifier signifies the type of information that is in this message. A type identifier of one signifies data set definitions. A type identifier of two signifies variable definitions. A type identifier of three signifies actual observations. Type identifiers four (indexes) and five (integrity constraints) usually have no use and can be ignored.
   Note: All character strings are null
terminated.

   Layout of a data set definition
message:

   int     - type (data set definition=1)
   int     - version (future)
   long    - data set type length
   char[]  - data set type
   long    - data set label length
   char[]  - data set label
   long    - number of observations
   long    - number of variables
   long    - observation length
   long    - length of compress
   char[]  - compress
   char    - reuse
   long    - length of encrypt
   char[]  - encrypt
   long    - number of variables in sort key
   long    - length of sort collating sequence
   char[]  - sort collating sequence
   short   - sort flags
   int     - read password flag
   byte[4] - read password (encrypted)
   int     - write password flag
   byte[4] - write password (encrypted)
   int     - alter password flag
   byte[4] - alter password (encrypted)


   Layout of a variable definition message:

   int     - type (variable definition=2)
   -----------------------------------
   long    - length of variable name
   char[]  - variable name
   long    - length of format name
   char[]  - format name
   long    - length of informat name
   char[]  - informat name
   long    - variable label length
   char[]  - variable label
   char    - variable type  (1=double, otherwise character)
   long    - variable length
   long    - format field length
   long    - format decimal
   long    - informat field length
   long    - informat decimal
   char    - nsort
   -----------------------------------
   .
   .
   . repeat for each variable


   Note: Variable definitions might span multiple physical
      messages if definitions are larger than 32K.


   Layout of an observation message:

   int     - type (observation=3)
   data    - the layout of data is defined by the variable
                definition above


   Note: Observations might span multiple physical messages
      if they are larger than 32K.


   Layout of an index message:

   int     - type (index=4)
   -----------------------------------
   long    - upercmx
   long    - length of index/key name
   char[]  - index/key name
   long    - flags
   long    - number of variables in the index/key
   long    - variable lengths added together
   char[]  - all variables null terminated
   -----------------------------------
   .
   .
   . repeat for each index