first commit

This commit is contained in:
2024-10-28 23:04:48 +01:00
commit 1ee55157f1
911 changed files with 325331 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

560
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqi.go generated vendored Normal file
View File

@@ -0,0 +1,560 @@
/*
Package ibmmq provides a wrapper to a subset of the IBM MQ
procedural interface (the MQI).
In this initial implementation not all the MQI verbs are
included, but it does have the core operations required to
put and get messages and work with topics.
The verbs are given mixed case names without MQ - Open instead
of MQOPEN etc.
If an MQI call returns MQCC_FAILED or MQCC_WARNING, a custom error
type is returned containing the MQCC/MQRC values as
a formatted string. Use mqreturn:= err(*ibmmq.MQReturn) to access
the particular MQRC or MQCC values.
The build directives for Windows assume the header and library files have
been copied to a temporary location, because the default paths are not
acceptable to Go (it does not like spaces or special characters like ~).
Note: This problem appears to have been fixed in Go 1.9, and once that
is fully available, the directives will be changed to a more reasonable
path in this file. For example
cgo windows CFLAGS -I"c:/Program Files/IBM/MQ/tools/c/include" -m64
The build directives for Linux assume the default MQ installation path
in /opt/mqm. These would need to be changed in this file if you use a
non-default path.
*/
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#cgo !windows CFLAGS: -I/opt/mqm/inc -D_REENTRANT
#cgo windows CFLAGS: -I"C:/Program Files/IBM/MQ/Tools/c/include"
#cgo !windows LDFLAGS: -L/opt/mqm/lib64 -lmqm_r -Wl,-rpath=/opt/mqm/lib64 -Wl,-rpath=/usr/lib64
#cgo windows LDFLAGS: -L "C:/Program Files/IBM/MQ/bin64" -lmqm
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
#include <cmqxc.h>
*/
import "C"
import (
"encoding/binary"
"unsafe"
)
/*
This file contains the C wrappers, calling out to structure-specific
functions where necessary.
Define some basic types to hold the
references to MQ objects - hconn, hobj - and
a simple way to pass the combination of MQCC/MQRC
returned from MQI verbs
The object name is copied into the structures only
for convenience. It's not really needed, but
it can sometimes be nice to print which queue an hObj
refers to during debug.
*/
/*
MQQueueManager contains the connection to the queue manager
*/
type MQQueueManager struct {
hConn C.MQHCONN
Name string
}
/*
MQObject contains a reference to an open object and the associated
queue manager
*/
type MQObject struct {
hObj C.MQHOBJ
qMgr *MQQueueManager
Name string
}
/*
MQReturn holds the MQRC and MQCC values returned from an MQI verb. It
implements the Error() function so is returned as the specific error
from the verbs. See the sample programs for how to access the
MQRC/MQCC values in this returned error.
*/
type MQReturn struct {
MQCC int32
MQRC int32
verb string
}
func (e *MQReturn) Error() string {
return mqstrerror(e.verb, C.MQLONG(e.MQCC), C.MQLONG(e.MQRC))
}
/*
* Copy a Go string into a fixed-size C char array such as MQCHAR12
* Once the string has been copied, it can be immediately freed
* Empty strings have first char set to 0 in MQI structures
*/
func setMQIString(a *C.char, v string, l int) {
if len(v) > 0 {
p := C.CString(v)
C.strncpy(a, p, (C.size_t)(l))
C.free(unsafe.Pointer(p))
} else {
*a = 0
}
}
/*
Conn is the function to connect to a queue manager
*/
func Conn(goQMgrName string) (MQQueueManager, error) {
return Connx(goQMgrName, nil)
}
/*
Connx is the extended function to connect to a queue manager.
*/
func Connx(goQMgrName string, gocno *MQCNO) (MQQueueManager, error) {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqcno C.MQCNO
if (C.MQENC_NATIVE % 2) == 0 { // May be needed for conversion later
endian = binary.LittleEndian
} else {
endian = binary.BigEndian
}
qMgr := MQQueueManager{}
mqQMgrName := unsafe.Pointer(C.CString(goQMgrName))
defer C.free(mqQMgrName)
// Set up a default CNO if not provided.
if gocno == nil {
// Because Go programs are always threaded, and we cannot
// tell on which thread we might get dispatched, allow handles always to
// be shareable.
gocno = NewMQCNO()
gocno.Options = MQCNO_HANDLE_SHARE_NO_BLOCK
} else {
if (gocno.Options & (MQCNO_HANDLE_SHARE_NO_BLOCK |
MQCNO_HANDLE_SHARE_BLOCK)) == 0 {
gocno.Options |= MQCNO_HANDLE_SHARE_NO_BLOCK
}
}
copyCNOtoC(&mqcno, gocno)
C.MQCONNX((*C.MQCHAR)(mqQMgrName), &mqcno, &qMgr.hConn, &mqcc, &mqrc)
if gocno != nil {
copyCNOfromC(&mqcno, gocno)
}
mqreturn := &MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQCONNX",
}
if mqcc != C.MQCC_OK {
return qMgr, mqreturn
}
qMgr.Name = goQMgrName
return qMgr, nil
}
/*
Disc is the function to disconnect from the queue manager
*/
func (x *MQQueueManager) Disc() error {
var mqrc C.MQLONG
var mqcc C.MQLONG
C.MQDISC(&x.hConn, &mqcc, &mqrc)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQDISC",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Open an object such as a queue or topic
*/
func (x *MQQueueManager) Open(good *MQOD, goOpenOptions int32) (MQObject, error) {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqod C.MQOD
var mqOpenOptions C.MQLONG
object := MQObject{
Name: good.ObjectName,
qMgr: x,
}
copyODtoC(&mqod, good)
mqOpenOptions = C.MQLONG(goOpenOptions)
C.MQOPEN(x.hConn,
(C.PMQVOID)(unsafe.Pointer(&mqod)),
mqOpenOptions,
&object.hObj,
&mqcc,
&mqrc)
copyODfromC(&mqod, good)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQOPEN",
}
if mqcc != C.MQCC_OK {
return object, &mqreturn
}
// ObjectName may have changed because it's a model queue
object.Name = good.ObjectName
return object, nil
}
/*
Close the object
*/
func (object *MQObject) Close(goCloseOptions int32) error {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqCloseOptions C.MQLONG
mqCloseOptions = C.MQLONG(goCloseOptions)
C.MQCLOSE(object.qMgr.hConn, &object.hObj, mqCloseOptions, &mqcc, &mqrc)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQCLOSE",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Sub is the function to subscribe to a topic
*/
func (x *MQQueueManager) Sub(gosd *MQSD, qObject *MQObject) (MQObject, error) {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqsd C.MQSD
subObject := MQObject{
Name: gosd.ObjectName,
qMgr: x,
}
copySDtoC(&mqsd, gosd)
C.MQSUB(x.hConn,
(C.PMQVOID)(unsafe.Pointer(&mqsd)),
&qObject.hObj,
&subObject.hObj,
&mqcc,
&mqrc)
copySDfromC(&mqsd, gosd)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQSUB",
}
if mqcc != C.MQCC_OK {
return subObject, &mqreturn
}
qObject.qMgr = x // Force the correct hConn for managed objects
return subObject, nil
}
/*
Cmit is the function to commit an in-flight transaction
*/
func (x *MQQueueManager) Cmit() error {
var mqrc C.MQLONG
var mqcc C.MQLONG
C.MQCMIT(x.hConn, &mqcc, &mqrc)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQCMIT",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Back is the function to backout an in-flight transaction
*/
func (x *MQQueueManager) Back() error {
var mqrc C.MQLONG
var mqcc C.MQLONG
C.MQBACK(x.hConn, &mqcc, &mqrc)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQBACK",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Put a message to a queue or publish to a topic
*/
func (object MQObject) Put(gomd *MQMD,
gopmo *MQPMO, buffer []byte) error {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqmd C.MQMD
var mqpmo C.MQPMO
var ptr C.PMQVOID
bufflen := len(buffer)
copyMDtoC(&mqmd, gomd)
copyPMOtoC(&mqpmo, gopmo)
if bufflen > 0 {
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
} else {
ptr = nil
}
C.MQPUT(object.qMgr.hConn, object.hObj, (C.PMQVOID)(unsafe.Pointer(&mqmd)),
(C.PMQVOID)(unsafe.Pointer(&mqpmo)),
(C.MQLONG)(bufflen),
ptr,
&mqcc, &mqrc)
copyMDfromC(&mqmd, gomd)
copyPMOfromC(&mqpmo, gopmo)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQPUT",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Put1 puts a single messsage to a queue or topic. Typically used for one-shot
replies where it can be cheaper than multiple Open/Put/Close
sequences
*/
func (x *MQQueueManager) Put1(good *MQOD, gomd *MQMD,
gopmo *MQPMO, buffer []byte) error {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqmd C.MQMD
var mqpmo C.MQPMO
var mqod C.MQOD
var ptr C.PMQVOID
copyODtoC(&mqod, good)
copyMDtoC(&mqmd, gomd)
copyPMOtoC(&mqpmo, gopmo)
bufflen := len(buffer)
if bufflen > 0 {
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
} else {
ptr = nil
}
C.MQPUT1(x.hConn, (C.PMQVOID)(unsafe.Pointer(&mqod)),
(C.PMQVOID)(unsafe.Pointer(&mqmd)),
(C.PMQVOID)(unsafe.Pointer(&mqpmo)),
(C.MQLONG)(bufflen),
ptr,
&mqcc, &mqrc)
copyODfromC(&mqod, good)
copyMDfromC(&mqmd, gomd)
copyPMOfromC(&mqpmo, gopmo)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQPUT1",
}
if mqcc != C.MQCC_OK {
return &mqreturn
}
return nil
}
/*
Get a message from a queue
The length of the retrieved message is returned.
*/
func (object MQObject) Get(gomd *MQMD,
gogmo *MQGMO, buffer []byte) (int, error) {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqmd C.MQMD
var mqgmo C.MQGMO
var datalen C.MQLONG
var ptr C.PMQVOID
bufflen := len(buffer)
copyMDtoC(&mqmd, gomd)
copyGMOtoC(&mqgmo, gogmo)
if bufflen > 0 {
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
} else {
ptr = nil
}
C.MQGET(object.qMgr.hConn, object.hObj, (C.PMQVOID)(unsafe.Pointer(&mqmd)),
(C.PMQVOID)(unsafe.Pointer(&mqgmo)),
(C.MQLONG)(bufflen),
ptr,
&datalen,
&mqcc, &mqrc)
godatalen := int(datalen)
copyMDfromC(&mqmd, gomd)
copyGMOfromC(&mqgmo, gogmo)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQGET",
}
if mqcc != C.MQCC_OK {
return 0, &mqreturn
}
return godatalen, nil
}
/*
Inq is the function to inquire on an attribute of an object
Slices are returned containing the integer attributes, and all the
strings concatenated into a single buffer - the caller needs to know
how long each field in that buffer will be.
The caller passes in how many integer selectors are expected to be
returned, as well as the maximum length of the char buffer to be returned
*/
func (object MQObject) Inq(goSelectors []int32, intAttrCount int, charAttrLen int) ([]int32,
[]byte, error) {
var mqrc C.MQLONG
var mqcc C.MQLONG
var mqCharAttrs C.PMQCHAR
var goCharAttrs []byte
var goIntAttrs []int32
var ptr C.PMQLONG
if intAttrCount > 0 {
goIntAttrs = make([]int32, intAttrCount)
ptr = (C.PMQLONG)(unsafe.Pointer(&goIntAttrs[0]))
} else {
ptr = nil
}
if charAttrLen > 0 {
mqCharAttrs = (C.PMQCHAR)(C.malloc(C.size_t(charAttrLen)))
defer C.free(unsafe.Pointer(mqCharAttrs))
} else {
mqCharAttrs = nil
}
// Pass in the selectors directly
C.MQINQ(object.qMgr.hConn, object.hObj,
C.MQLONG(len(goSelectors)),
C.PMQLONG(unsafe.Pointer(&goSelectors[0])),
C.MQLONG(intAttrCount),
ptr,
C.MQLONG(charAttrLen),
mqCharAttrs,
&mqcc, &mqrc)
mqreturn := MQReturn{MQCC: int32(mqcc),
MQRC: int32(mqrc),
verb: "MQINQ",
}
if mqcc != C.MQCC_OK {
return nil, nil, &mqreturn
}
if charAttrLen > 0 {
goCharAttrs = C.GoBytes(unsafe.Pointer(mqCharAttrs), C.int(charAttrLen))
}
return goIntAttrs, goCharAttrs, nil
}

View File

@@ -0,0 +1,210 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
#include <cmqxc.h>
*/
import "C"
import (
"unsafe"
)
/*
MQCD is a structure containing the MQ Channel Definition (MQCD)
Only fields relevant to a client connection are included in the
Go version of this structure.
*/
type MQCD struct {
ChannelName string
ConnectionName string
DiscInterval int32
SecurityExit string
SecurityUserData string
MaxMsgLength int32
HeartbeatInterval int32
SSLCipherSpec string
SSLPeerName string
SSLClientAuth int32
KeepAliveInterval int32
SharingConversations int32
PropertyControl int32
ClientChannelWeight int32
ConnectionAffinity int32
DefReconnect int32
CertificateLabel string
}
/*
NewMQCD fills in default values for the MQCD structure, based on the
MQCD_CLIENT_CONN_DEFAULT
*/
func NewMQCD() *MQCD {
cd := new(MQCD)
cd.ChannelName = ""
cd.DiscInterval = 6000
cd.SecurityExit = ""
cd.SecurityUserData = ""
cd.MaxMsgLength = 4194304
cd.ConnectionName = ""
cd.HeartbeatInterval = 1
cd.SSLCipherSpec = ""
cd.SSLPeerName = ""
cd.SSLClientAuth = int32(C.MQSCA_REQUIRED)
cd.KeepAliveInterval = -1
cd.SharingConversations = 10
cd.PropertyControl = int32(C.MQPROP_COMPATIBILITY)
cd.ClientChannelWeight = 0
cd.ConnectionAffinity = int32(C.MQCAFTY_PREFERRED)
cd.DefReconnect = int32(C.MQRCN_NO)
cd.CertificateLabel = ""
return cd
}
/*
It is expected that copyXXtoC and copyXXfromC will be called as
matching pairs.
Most of the fields in the MQCD structure are not relevant for client
channels, but the default settings of such fields may still not be 0
or NULL (they are just ignored). The values here are taken from
MQ_CLIENT_CONN_DEFAULT structure for consistency.
*/
func copyCDtoC(mqcd *C.MQCD, gocd *MQCD) {
setMQIString((*C.char)(&mqcd.ChannelName[0]), gocd.ChannelName, C.MQ_CHANNEL_NAME_LENGTH)
mqcd.Version = C.MQCD_VERSION_11 // The version this is written to match
mqcd.ChannelType = C.MQCHT_CLNTCONN
mqcd.TransportType = C.MQXPT_TCP
setMQIString((*C.char)(&mqcd.Desc[0]), "", C.MQ_CHANNEL_DESC_LENGTH)
setMQIString((*C.char)(&mqcd.QMgrName[0]), "", C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.XmitQName[0]), "", C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.ShortConnectionName[0]), "", C.MQ_SHORT_CONN_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.MCAName[0]), "", C.MQ_MCA_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.ModeName[0]), "", C.MQ_MODE_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.TpName[0]), "", C.MQ_TP_NAME_LENGTH)
mqcd.BatchSize = 50
mqcd.DiscInterval = 6000
mqcd.ShortRetryCount = 10
mqcd.ShortRetryInterval = 60
mqcd.LongRetryCount = 999999999
mqcd.LongRetryInterval = 1200
setMQIString((*C.char)(&mqcd.SecurityExit[0]), gocd.SecurityExit, C.MQ_EXIT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.MsgExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.SendExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.ReceiveExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
mqcd.SeqNumberWrap = 999999999
mqcd.MaxMsgLength = C.MQLONG(gocd.MaxMsgLength)
mqcd.PutAuthority = C.MQPA_DEFAULT
mqcd.DataConversion = C.MQCDC_NO_SENDER_CONVERSION
setMQIString((*C.char)(&mqcd.SecurityUserData[0]), gocd.SecurityUserData, C.MQ_EXIT_DATA_LENGTH)
setMQIString((*C.char)(&mqcd.MsgUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
setMQIString((*C.char)(&mqcd.SendUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
setMQIString((*C.char)(&mqcd.ReceiveUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
setMQIString((*C.char)(&mqcd.UserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
setMQIString((*C.char)(&mqcd.Password[0]), "", C.MQ_PASSWORD_LENGTH)
setMQIString((*C.char)(&mqcd.MCAUserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
mqcd.MCAType = C.MQMCAT_PROCESS
setMQIString((*C.char)(&mqcd.ConnectionName[0]), gocd.ConnectionName, C.MQ_CONN_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.RemoteUserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
setMQIString((*C.char)(&mqcd.RemotePassword[0]), "", C.MQ_PASSWORD_LENGTH)
setMQIString((*C.char)(&mqcd.MsgRetryExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
setMQIString((*C.char)(&mqcd.MsgRetryUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
mqcd.MsgRetryCount = 10
mqcd.MsgRetryInterval = 1000
mqcd.HeartbeatInterval = 1
mqcd.BatchInterval = 0
mqcd.NonPersistentMsgSpeed = C.MQNPMS_FAST
mqcd.StrucLength = C.MQCD_LENGTH_11
mqcd.ExitNameLength = C.MQ_EXIT_NAME_LENGTH
mqcd.ExitDataLength = C.MQ_EXIT_DATA_LENGTH
mqcd.MsgExitsDefined = 0
mqcd.SendExitsDefined = 0
mqcd.ReceiveExitsDefined = 0
mqcd.MsgExitPtr = C.MQPTR(nil)
mqcd.MsgUserDataPtr = C.MQPTR(nil)
mqcd.SendExitPtr = C.MQPTR(nil)
mqcd.SendUserDataPtr = C.MQPTR(nil)
mqcd.ReceiveExitPtr = C.MQPTR(nil)
mqcd.ReceiveUserDataPtr = C.MQPTR(nil)
mqcd.ClusterPtr = C.MQPTR(nil)
mqcd.ClustersDefined = 0
mqcd.NetworkPriority = 0
mqcd.LongMCAUserIdLength = 0
mqcd.LongRemoteUserIdLength = 0
mqcd.LongMCAUserIdPtr = C.MQPTR(nil)
mqcd.LongRemoteUserIdPtr = C.MQPTR(nil)
C.memset((unsafe.Pointer)(&mqcd.MCASecurityId[0]), 0, C.MQ_SECURITY_ID_LENGTH)
C.memset((unsafe.Pointer)(&mqcd.RemoteSecurityId[0]), 0, C.MQ_SECURITY_ID_LENGTH)
setMQIString((*C.char)(&mqcd.SSLCipherSpec[0]), gocd.SSLCipherSpec, C.MQ_SSL_CIPHER_SPEC_LENGTH)
mqcd.SSLPeerNamePtr = C.MQPTR(nil)
mqcd.SSLPeerNameLength = 0
if gocd.SSLPeerName != "" {
mqcd.SSLPeerNamePtr = C.MQPTR(unsafe.Pointer(C.CString(gocd.SSLPeerName)))
mqcd.SSLPeerNameLength = C.MQLONG(len(gocd.SSLPeerName))
}
mqcd.SSLClientAuth = C.MQLONG(gocd.SSLClientAuth)
mqcd.KeepAliveInterval = C.MQLONG(gocd.KeepAliveInterval)
setMQIString((*C.char)(&mqcd.LocalAddress[0]), "", C.MQ_LOCAL_ADDRESS_LENGTH)
mqcd.BatchHeartbeat = 0
for i := 0; i < 2; i++ {
mqcd.HdrCompList[i] = C.MQCOMPRESS_NOT_AVAILABLE
}
for i := 0; i < 16; i++ {
mqcd.MsgCompList[i] = C.MQCOMPRESS_NOT_AVAILABLE
}
mqcd.CLWLChannelRank = 0
mqcd.CLWLChannelPriority = 0
mqcd.CLWLChannelWeight = 50
mqcd.ChannelMonitoring = C.MQMON_OFF
mqcd.ChannelStatistics = C.MQMON_OFF
mqcd.SharingConversations = C.MQLONG(gocd.SharingConversations)
mqcd.PropertyControl = C.MQLONG(gocd.PropertyControl)
mqcd.MaxInstances = 999999999
mqcd.MaxInstancesPerClient = 999999999
mqcd.ClientChannelWeight = C.MQLONG(gocd.ClientChannelWeight)
mqcd.ConnectionAffinity = C.MQLONG(gocd.ConnectionAffinity)
mqcd.BatchDataLimit = 5000
mqcd.UseDLQ = C.MQUSEDLQ_YES
mqcd.DefReconnect = C.MQLONG(gocd.DefReconnect)
setMQIString((*C.char)(&mqcd.CertificateLabel[0]), gocd.CertificateLabel, C.MQ_CERT_LABEL_LENGTH)
return
}
/*
Most of the parameters in the MQCD are input only.
Just need to clear up anything that was allocated in the copyCDtoC function
*/
func copyCDfromC(mqcd *C.MQCD, gocd *MQCD) {
if mqcd.SSLPeerNamePtr != nil {
C.free(unsafe.Pointer(mqcd.SSLPeerNamePtr))
}
return
}

View File

@@ -0,0 +1,193 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
#include <cmqxc.h>
*/
import "C"
import "unsafe"
/*
MQCNO is a structure containing the MQ Connection Options (MQCNO)
Note that only a subset of the real structure is exposed in this
version.
*/
type MQCNO struct {
Version int32
Options int32
SecurityParms *MQCSP
CCDTUrl string
ClientConn *MQCD
SSLConfig *MQSCO
}
/*
MQCSP is a structure containing the MQ Security Parameters (MQCSP)
*/
type MQCSP struct {
AuthenticationType int32
UserId string
Password string
}
/*
NewMQCNO fills in default values for the MQCNO structure
*/
func NewMQCNO() *MQCNO {
cno := new(MQCNO)
cno.Version = int32(C.MQCNO_VERSION_1)
cno.Options = int32(C.MQCNO_NONE)
cno.SecurityParms = nil
cno.ClientConn = nil
return cno
}
/*
NewMQCSP fills in default values for the MQCSP structure
*/
func NewMQCSP() *MQCSP {
csp := new(MQCSP)
csp.AuthenticationType = int32(C.MQCSP_AUTH_NONE)
csp.UserId = ""
csp.Password = ""
return csp
}
func copyCNOtoC(mqcno *C.MQCNO, gocno *MQCNO) {
var i int
var mqcsp C.PMQCSP
var mqcd C.PMQCD
var mqsco C.PMQSCO
setMQIString((*C.char)(&mqcno.StrucId[0]), "CNO ", 4)
mqcno.Version = C.MQLONG(gocno.Version)
mqcno.Options = C.MQLONG(gocno.Options)
for i = 0; i < C.MQ_CONN_TAG_LENGTH; i++ {
mqcno.ConnTag[i] = 0
}
for i = 0; i < C.MQ_CONNECTION_ID_LENGTH; i++ {
mqcno.ConnectionId[i] = 0
}
mqcno.ClientConnOffset = 0
if gocno.ClientConn != nil {
gocd := gocno.ClientConn
mqcd = C.PMQCD(C.malloc(C.MQCD_LENGTH_11))
copyCDtoC(mqcd, gocd)
mqcno.ClientConnPtr = C.MQPTR(mqcd)
if gocno.Version < 2 {
mqcno.Version = C.MQCNO_VERSION_2
}
} else {
mqcno.ClientConnPtr = nil
}
mqcno.SSLConfigOffset = 0
if gocno.SSLConfig != nil {
gosco := gocno.SSLConfig
mqsco = C.PMQSCO(C.malloc(C.MQSCO_LENGTH_5))
copySCOtoC(mqsco, gosco)
mqcno.SSLConfigPtr = C.PMQSCO(mqsco)
if gocno.Version < 4 {
mqcno.Version = C.MQCNO_VERSION_4
}
} else {
mqcno.SSLConfigPtr = nil
}
mqcno.SecurityParmsOffset = 0
if gocno.SecurityParms != nil {
gocsp := gocno.SecurityParms
mqcsp = C.PMQCSP(C.malloc(C.MQCSP_LENGTH_1))
setMQIString((*C.char)(&mqcsp.StrucId[0]), "CSP ", 4)
mqcsp.Version = C.MQCSP_VERSION_1
mqcsp.AuthenticationType = C.MQLONG(gocsp.AuthenticationType)
mqcsp.CSPUserIdOffset = 0
mqcsp.CSPPasswordOffset = 0
if gocsp.UserId != "" {
mqcsp.AuthenticationType = C.MQLONG(C.MQCSP_AUTH_USER_ID_AND_PWD)
mqcsp.CSPUserIdPtr = C.MQPTR(unsafe.Pointer(C.CString(gocsp.UserId)))
mqcsp.CSPUserIdLength = C.MQLONG(len(gocsp.UserId))
}
if gocsp.Password != "" {
mqcsp.CSPPasswordPtr = C.MQPTR(unsafe.Pointer(C.CString(gocsp.Password)))
mqcsp.CSPPasswordLength = C.MQLONG(len(gocsp.Password))
}
mqcno.SecurityParmsPtr = C.PMQCSP(mqcsp)
if gocno.Version < 5 {
mqcno.Version = C.MQCNO_VERSION_5
}
} else {
mqcno.SecurityParmsPtr = nil
}
mqcno.CCDTUrlOffset = 0
if len(gocno.CCDTUrl) != 0 {
mqcno.CCDTUrlPtr = C.PMQCHAR(unsafe.Pointer(C.CString(gocno.CCDTUrl)))
mqcno.CCDTUrlLength = C.MQLONG(len(gocno.CCDTUrl))
} else {
mqcno.CCDTUrlPtr = nil
mqcno.CCDTUrlLength = 0
}
return
}
func copyCNOfromC(mqcno *C.MQCNO, gocno *MQCNO) {
if mqcno.SecurityParmsPtr != nil {
if mqcno.SecurityParmsPtr.CSPUserIdPtr != nil {
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr.CSPUserIdPtr))
}
// Set memory to 0 for area that held a password
if mqcno.SecurityParmsPtr.CSPPasswordPtr != nil {
C.memset((unsafe.Pointer)(mqcno.SecurityParmsPtr.CSPPasswordPtr), 0, C.size_t(mqcno.SecurityParmsPtr.CSPPasswordLength))
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr.CSPPasswordPtr))
}
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr))
}
if mqcno.ClientConnPtr != nil {
copyCDfromC(C.PMQCD(mqcno.ClientConnPtr), gocno.ClientConn)
C.free(unsafe.Pointer(mqcno.ClientConnPtr))
}
if mqcno.SSLConfigPtr != nil {
copySCOfromC(C.PMQSCO(mqcno.SSLConfigPtr), gocno.SSLConfig)
C.free(unsafe.Pointer(mqcno.SSLConfigPtr))
}
if mqcno.CCDTUrlPtr != nil {
C.free(unsafe.Pointer(mqcno.CCDTUrlPtr))
}
return
}

View File

@@ -0,0 +1,122 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
*/
import "C"
import "bytes"
/*
MQGMO is a structure containing the MQ Get Message Options (MQGMO)
*/
type MQGMO struct {
Version int32
Options int32
WaitInterval int32
Signal1 int32
Signal2 int32
ResolvedQName string
MatchOptions int32
GroupStatus rune
SegmentStatus rune
Segmentation rune
Reserved1 rune
MsgToken []byte
ReturnedLength int32
Reserved2 int32
MsgHandle C.MQHMSG
}
/*
NewMQGMO fills in default values for the MQGMO structure
*/
func NewMQGMO() *MQGMO {
gmo := new(MQGMO)
gmo.Version = int32(C.MQGMO_VERSION_1)
gmo.Options = int32(C.MQGMO_NO_WAIT + C.MQGMO_PROPERTIES_AS_Q_DEF)
gmo.WaitInterval = int32(C.MQWI_UNLIMITED)
gmo.Signal1 = 0
gmo.Signal2 = 0
gmo.ResolvedQName = ""
gmo.MatchOptions = int32(C.MQMO_MATCH_MSG_ID + C.MQMO_MATCH_CORREL_ID)
gmo.GroupStatus = rune(C.MQGS_NOT_IN_GROUP)
gmo.SegmentStatus = rune(C.MQSS_NOT_A_SEGMENT)
gmo.Segmentation = rune(C.MQSEG_INHIBITED)
gmo.Reserved1 = ' '
gmo.MsgToken = bytes.Repeat([]byte{0}, C.MQ_MSG_TOKEN_LENGTH)
gmo.ReturnedLength = int32(C.MQRL_UNDEFINED)
gmo.Reserved2 = 0
gmo.MsgHandle = C.MQHM_NONE
return gmo
}
func copyGMOtoC(mqgmo *C.MQGMO, gogmo *MQGMO) {
var i int
setMQIString((*C.char)(&mqgmo.StrucId[0]), "GMO ", 4)
mqgmo.Version = C.MQLONG(gogmo.Version)
mqgmo.Options = C.MQLONG(gogmo.Options)
mqgmo.WaitInterval = C.MQLONG(gogmo.WaitInterval)
mqgmo.Signal1 = C.MQLONG(gogmo.Signal1)
mqgmo.Signal2 = C.MQLONG(gogmo.Signal2)
setMQIString((*C.char)(&mqgmo.ResolvedQName[0]), gogmo.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
mqgmo.MatchOptions = C.MQLONG(gogmo.MatchOptions)
mqgmo.GroupStatus = C.MQCHAR(gogmo.GroupStatus)
mqgmo.SegmentStatus = C.MQCHAR(gogmo.SegmentStatus)
mqgmo.Segmentation = C.MQCHAR(gogmo.Segmentation)
mqgmo.Reserved1 = C.MQCHAR(gogmo.Reserved1)
for i = 0; i < C.MQ_MSG_TOKEN_LENGTH; i++ {
mqgmo.MsgToken[i] = C.MQBYTE(gogmo.MsgToken[i])
}
mqgmo.ReturnedLength = C.MQLONG(gogmo.ReturnedLength)
mqgmo.Reserved2 = C.MQLONG(gogmo.Reserved2)
mqgmo.MsgHandle = gogmo.MsgHandle
return
}
func copyGMOfromC(mqgmo *C.MQGMO, gogmo *MQGMO) {
var i int
gogmo.Version = int32(mqgmo.Version)
gogmo.Options = int32(mqgmo.Options)
gogmo.WaitInterval = int32(mqgmo.WaitInterval)
gogmo.Signal1 = int32(mqgmo.Signal1)
gogmo.Signal2 = int32(mqgmo.Signal2)
gogmo.ResolvedQName = C.GoStringN((*C.char)(&mqgmo.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
gogmo.MatchOptions = int32(mqgmo.MatchOptions)
gogmo.GroupStatus = rune(mqgmo.GroupStatus)
gogmo.SegmentStatus = rune(mqgmo.SegmentStatus)
gogmo.Segmentation = rune(mqgmo.Segmentation)
gogmo.Reserved1 = rune(mqgmo.Reserved1)
for i = 0; i < C.MQ_MSG_TOKEN_LENGTH; i++ {
gogmo.MsgToken[i] = (byte)(mqgmo.MsgToken[i])
}
gogmo.ReturnedLength = int32(mqgmo.ReturnedLength)
gogmo.Reserved2 = int32(mqgmo.Reserved2)
gogmo.MsgHandle = mqgmo.MsgHandle
return
}

View File

@@ -0,0 +1,196 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
*/
import "C"
import (
"bytes"
)
/*
MQMD is a structure containing the MQ Message Descriptor (MQMD)
*/
type MQMD struct {
Version int32
Report int32
MsgType int32
Expiry int32
Feedback int32
Encoding int32
CodedCharSetId int32
Format string
Priority int32
Persistence int32
MsgId []byte
CorrelId []byte
BackoutCount int32
ReplyToQ string
ReplyToQMgr string
UserIdentifier string
AccountingToken []byte
ApplIdentityData string
PutApplType int32
PutApplName string
PutDate string
PutTime string
ApplOriginData string
GroupId []byte
MsgSeqNumber int32
Offset int32
MsgFlags int32
OriginalLength int32
}
/*
NewMQMD fills in default values for the MQMD structure
*/
func NewMQMD() *MQMD {
md := new(MQMD)
md.Version = int32(C.MQMD_VERSION_1)
md.Report = int32(C.MQRO_NONE)
md.MsgType = int32(C.MQMT_DATAGRAM)
md.Expiry = int32(C.MQEI_UNLIMITED)
md.Feedback = int32(C.MQFB_NONE)
md.Encoding = int32(C.MQENC_NATIVE)
md.CodedCharSetId = int32(C.MQCCSI_Q_MGR)
md.Format = " "
md.Priority = int32(C.MQPRI_PRIORITY_AS_Q_DEF)
md.Persistence = int32(C.MQPER_PERSISTENCE_AS_Q_DEF)
md.MsgId = bytes.Repeat([]byte{0}, C.MQ_MSG_ID_LENGTH)
md.CorrelId = bytes.Repeat([]byte{0}, C.MQ_CORREL_ID_LENGTH)
md.BackoutCount = 0
md.ReplyToQ = ""
md.ReplyToQMgr = ""
md.UserIdentifier = ""
md.AccountingToken = bytes.Repeat([]byte{0}, C.MQ_ACCOUNTING_TOKEN_LENGTH)
md.ApplIdentityData = ""
md.PutApplType = int32(C.MQAT_NO_CONTEXT)
md.PutApplName = ""
md.PutDate = ""
md.PutTime = ""
md.ApplOriginData = ""
md.GroupId = bytes.Repeat([]byte{0}, C.MQ_GROUP_ID_LENGTH)
md.MsgSeqNumber = 1
md.Offset = 0
md.MsgFlags = int32(C.MQMF_NONE)
md.OriginalLength = int32(C.MQOL_UNDEFINED)
return md
}
func copyMDtoC(mqmd *C.MQMD, gomd *MQMD) {
var i int
setMQIString((*C.char)(&mqmd.StrucId[0]), "MD ", 4)
mqmd.Version = C.MQLONG(gomd.Version)
mqmd.Report = C.MQLONG(gomd.Report)
mqmd.MsgType = C.MQLONG(gomd.MsgType)
mqmd.Expiry = C.MQLONG(gomd.Expiry)
mqmd.Feedback = C.MQLONG(gomd.Feedback)
mqmd.Encoding = C.MQLONG(gomd.Encoding)
mqmd.CodedCharSetId = C.MQLONG(gomd.CodedCharSetId)
setMQIString((*C.char)(&mqmd.Format[0]), gomd.Format, C.MQ_FORMAT_LENGTH)
mqmd.Priority = C.MQLONG(gomd.Priority)
mqmd.Persistence = C.MQLONG(gomd.Persistence)
for i = 0; i < C.MQ_MSG_ID_LENGTH; i++ {
mqmd.MsgId[i] = C.MQBYTE(gomd.MsgId[i])
}
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
mqmd.CorrelId[i] = C.MQBYTE(gomd.CorrelId[i])
}
mqmd.BackoutCount = C.MQLONG(gomd.BackoutCount)
setMQIString((*C.char)(&mqmd.ReplyToQ[0]), gomd.ReplyToQ, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqmd.ReplyToQMgr[0]), gomd.ReplyToQMgr, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqmd.UserIdentifier[0]), gomd.UserIdentifier, C.MQ_USER_ID_LENGTH)
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
mqmd.AccountingToken[i] = C.MQBYTE(gomd.AccountingToken[i])
}
setMQIString((*C.char)(&mqmd.ApplIdentityData[0]), gomd.ApplIdentityData, C.MQ_APPL_IDENTITY_DATA_LENGTH)
mqmd.PutApplType = C.MQLONG(gomd.PutApplType)
setMQIString((*C.char)(&mqmd.PutApplName[0]), gomd.PutApplName, C.MQ_PUT_APPL_NAME_LENGTH)
setMQIString((*C.char)(&mqmd.PutDate[0]), gomd.PutDate, C.MQ_PUT_DATE_LENGTH)
setMQIString((*C.char)(&mqmd.PutTime[0]), gomd.PutTime, C.MQ_PUT_TIME_LENGTH)
setMQIString((*C.char)(&mqmd.ApplOriginData[0]), gomd.ApplOriginData, C.MQ_APPL_ORIGIN_DATA_LENGTH)
for i = 0; i < C.MQ_GROUP_ID_LENGTH; i++ {
mqmd.GroupId[i] = C.MQBYTE(gomd.GroupId[i])
}
mqmd.MsgSeqNumber = C.MQLONG(gomd.MsgSeqNumber)
mqmd.Offset = C.MQLONG(gomd.Offset)
mqmd.MsgFlags = C.MQLONG(gomd.MsgFlags)
mqmd.OriginalLength = C.MQLONG(gomd.OriginalLength)
return
}
func copyMDfromC(mqmd *C.MQMD, gomd *MQMD) {
var i int
gomd.Version = int32(mqmd.Version)
gomd.Report = int32(mqmd.Report)
gomd.MsgType = int32(mqmd.MsgType)
gomd.Expiry = int32(mqmd.Expiry)
gomd.Feedback = int32(mqmd.Feedback)
gomd.Encoding = int32(mqmd.Encoding)
gomd.CodedCharSetId = int32(mqmd.CodedCharSetId)
gomd.Format = C.GoStringN((*C.char)(&mqmd.Format[0]), C.MQ_FORMAT_LENGTH)
gomd.Priority = int32(mqmd.Priority)
gomd.Persistence = int32(mqmd.Persistence)
for i = 0; i < C.MQ_MSG_ID_LENGTH; i++ {
gomd.MsgId[i] = (byte)(mqmd.MsgId[i])
}
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
gomd.CorrelId[i] = (byte)(mqmd.CorrelId[i])
}
gomd.BackoutCount = int32(mqmd.BackoutCount)
gomd.ReplyToQ = C.GoStringN((*C.char)(&mqmd.ReplyToQ[0]), C.MQ_OBJECT_NAME_LENGTH)
gomd.ReplyToQMgr = C.GoStringN((*C.char)(&mqmd.ReplyToQMgr[0]), C.MQ_OBJECT_NAME_LENGTH)
gomd.UserIdentifier = C.GoStringN((*C.char)(&mqmd.UserIdentifier[0]), C.MQ_USER_ID_LENGTH)
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
gomd.AccountingToken[i] = (byte)(mqmd.AccountingToken[i])
}
gomd.ApplIdentityData = C.GoStringN((*C.char)(&mqmd.ApplIdentityData[0]), C.MQ_APPL_IDENTITY_DATA_LENGTH)
gomd.PutApplType = int32(mqmd.PutApplType)
gomd.PutApplName = C.GoStringN((*C.char)(&mqmd.PutApplName[0]), C.MQ_PUT_APPL_NAME_LENGTH)
gomd.PutDate = C.GoStringN((*C.char)(&mqmd.PutDate[0]), C.MQ_PUT_DATE_LENGTH)
gomd.PutTime = C.GoStringN((*C.char)(&mqmd.PutTime[0]), C.MQ_PUT_TIME_LENGTH)
gomd.ApplOriginData = C.GoStringN((*C.char)(&mqmd.ApplOriginData[0]), C.MQ_APPL_ORIGIN_DATA_LENGTH)
for i = 0; i < C.MQ_GROUP_ID_LENGTH; i++ {
gomd.GroupId[i] = (byte)(mqmd.GroupId[i])
}
gomd.MsgSeqNumber = int32(mqmd.MsgSeqNumber)
gomd.Offset = int32(mqmd.Offset)
gomd.MsgFlags = int32(mqmd.MsgFlags)
gomd.OriginalLength = int32(mqmd.OriginalLength)
return
}

View File

@@ -0,0 +1,212 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
*/
import "C"
import (
"bytes"
"unsafe"
)
/*
MQOD is a structure containing the MQ Object Descriptor (MQOD)
*/
type MQOD struct {
Version int32
ObjectType int32
ObjectName string
ObjectQMgrName string
DynamicQName string
AlternateUserId string
RecsPresent int32
KnownDestCount int32
UnknownDestCount int32
InvalidDestCount int32
ObjectRecOffset int32
ResponseRecOffset int32
ObjectRecPtr C.MQPTR
ResponseRecPtr C.MQPTR
AlternateSecurityId []byte
ResolvedQName string
ResolvedQMgrName string
ObjectString string
SelectionString string
ResObjectString string
ResolvedType int32
}
/*
NewMQOD fills in default values for the MQOD structure
*/
func NewMQOD() *MQOD {
od := new(MQOD)
od.Version = 1
od.ObjectType = C.MQOT_Q
od.ObjectName = ""
od.ObjectQMgrName = ""
od.DynamicQName = "AMQ.*"
od.AlternateUserId = ""
od.RecsPresent = 0
od.KnownDestCount = 0
od.UnknownDestCount = 0
od.InvalidDestCount = 0
od.ObjectRecOffset = 0
od.ResponseRecOffset = 0
od.ObjectRecPtr = nil
od.ResponseRecPtr = nil
od.AlternateSecurityId = bytes.Repeat([]byte{0}, C.MQ_SECURITY_ID_LENGTH)
od.ResolvedQName = ""
od.ResolvedQMgrName = ""
od.ObjectString = ""
od.SelectionString = ""
od.ResObjectString = ""
od.ResolvedType = C.MQOT_NONE
return od
}
/*
* It is expected that copyXXtoC and copyXXfromC will be called as
* matching pairs. That means that we can handle the MQCHARV type
* by allocating storage in the toC function and freeing it in fromC.
* If the input string for an MQCHARV type is empty, then we allocate
* a fixed length buffer for any potential output.
*
* In the fromC function, that buffer is freed. Conveniently, we can
* free it always, because if we didn't explicitly call malloc(), it was
* allocated by C.CString and still needs to be freed.
*/
func copyODtoC(mqod *C.MQOD, good *MQOD) {
var i int
const vsbufsize = 10240
setMQIString((*C.char)(&mqod.StrucId[0]), "OD ", 4)
mqod.Version = C.MQLONG(good.Version)
mqod.ObjectType = C.MQLONG(good.ObjectType)
setMQIString((*C.char)(&mqod.ObjectName[0]), good.ObjectName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqod.ObjectQMgrName[0]), good.ObjectQMgrName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqod.DynamicQName[0]), good.DynamicQName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqod.AlternateUserId[0]), good.AlternateUserId, C.MQ_USER_ID_LENGTH)
mqod.RecsPresent = C.MQLONG(good.RecsPresent)
mqod.KnownDestCount = C.MQLONG(good.KnownDestCount)
mqod.UnknownDestCount = C.MQLONG(good.UnknownDestCount)
mqod.InvalidDestCount = C.MQLONG(good.InvalidDestCount)
mqod.ObjectRecOffset = C.MQLONG(good.ObjectRecOffset)
mqod.ResponseRecOffset = C.MQLONG(good.ResponseRecOffset)
mqod.ObjectRecPtr = good.ObjectRecPtr
mqod.ResponseRecPtr = good.ResponseRecPtr
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
mqod.AlternateSecurityId[i] = C.MQBYTE(good.AlternateSecurityId[i])
}
setMQIString((*C.char)(&mqod.ResolvedQName[0]), good.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqod.ResolvedQMgrName[0]), good.ResolvedQMgrName, C.MQ_OBJECT_NAME_LENGTH)
mqod.ObjectString.VSLength = (C.MQLONG)(len(good.ObjectString))
mqod.ObjectString.VSCCSID = C.MQCCSI_APPL
if mqod.ObjectString.VSLength == 0 {
mqod.ObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqod.ObjectString.VSBufSize = vsbufsize
} else {
mqod.ObjectString.VSPtr = (C.MQPTR)(C.CString(good.ObjectString))
}
mqod.SelectionString.VSLength = (C.MQLONG)(len(good.SelectionString))
mqod.SelectionString.VSCCSID = C.MQCCSI_APPL
if mqod.SelectionString.VSLength == 0 {
mqod.SelectionString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqod.SelectionString.VSBufSize = vsbufsize
} else {
mqod.SelectionString.VSPtr = (C.MQPTR)(C.CString(good.SelectionString))
}
if mqod.SelectionString.VSLength > 0 || mqod.ObjectString.VSLength > 0 {
if mqod.Version < C.MQOD_VERSION_4 {
mqod.Version = C.MQOD_VERSION_4
}
}
mqod.ResObjectString.VSLength = (C.MQLONG)(len(good.ResObjectString))
mqod.ResObjectString.VSCCSID = C.MQCCSI_APPL
if mqod.ResObjectString.VSLength == 0 {
mqod.ResObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqod.ResObjectString.VSBufSize = vsbufsize
} else {
mqod.ResObjectString.VSPtr = (C.MQPTR)(C.CString(good.ResObjectString))
}
mqod.ResolvedType = C.MQLONG(good.ResolvedType)
return
}
func copyODfromC(mqod *C.MQOD, good *MQOD) {
var i int
good.Version = int32(mqod.Version)
good.ObjectType = int32(mqod.ObjectType)
good.ObjectName = C.GoStringN((*C.char)(&mqod.ObjectName[0]), C.MQ_OBJECT_NAME_LENGTH)
good.ObjectQMgrName = C.GoStringN((*C.char)(&mqod.ObjectQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
good.DynamicQName = C.GoStringN((*C.char)(&mqod.DynamicQName[0]), C.MQ_OBJECT_NAME_LENGTH)
good.AlternateUserId = C.GoStringN((*C.char)(&mqod.AlternateUserId[0]), C.MQ_USER_ID_LENGTH)
good.RecsPresent = int32(mqod.RecsPresent)
good.KnownDestCount = int32(mqod.KnownDestCount)
good.UnknownDestCount = int32(mqod.UnknownDestCount)
good.InvalidDestCount = int32(mqod.InvalidDestCount)
good.ObjectRecOffset = int32(mqod.ObjectRecOffset)
good.ResponseRecOffset = int32(mqod.ResponseRecOffset)
good.ObjectRecPtr = mqod.ObjectRecPtr
good.ResponseRecPtr = mqod.ResponseRecPtr
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
good.AlternateSecurityId[i] = (byte)(mqod.AlternateSecurityId[i])
}
good.ResolvedQName = C.GoStringN((*C.char)(&mqod.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
good.ResolvedQMgrName = C.GoStringN((*C.char)(&mqod.ResolvedQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
good.ObjectString = C.GoStringN((*C.char)(mqod.ObjectString.VSPtr), (C.int)(mqod.ObjectString.VSLength))
C.free(unsafe.Pointer(mqod.ObjectString.VSPtr))
good.SelectionString = C.GoStringN((*C.char)(mqod.SelectionString.VSPtr), (C.int)(mqod.SelectionString.VSLength))
C.free(unsafe.Pointer(mqod.SelectionString.VSPtr))
good.ResObjectString = C.GoStringN((*C.char)(mqod.ResObjectString.VSPtr), (C.int)(mqod.ResObjectString.VSLength))
C.free(unsafe.Pointer(mqod.ResObjectString.VSPtr))
good.ResolvedType = int32(mqod.ResolvedType)
return
}

View File

@@ -0,0 +1,143 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
*/
import "C"
/*
MQPMO is a structure containing the MQ Put MessageOptions (MQPMO)
*/
type MQPMO struct {
Version int32
Options int32
Timeout int32
Context C.MQHOBJ
KnownDestCount int32
UnknownDestCount int32
InvalidDestCount int32
ResolvedQName string
ResolvedQMgrName string
RecsPresent int32
PutMsgRecFields int32
PutMsgRecOffset int32
ResponseRecOffset int32
PutMsgRecPtr C.MQPTR
ResponseRecPtr C.MQPTR
OriginalMsgHandle C.MQHMSG
NewMsgHandle C.MQHMSG
Action int32
PubLevel int32
}
/*
NewMQPMO fills in default values for the MQPMO structure
*/
func NewMQPMO() *MQPMO {
pmo := new(MQPMO)
pmo.Version = int32(C.MQPMO_VERSION_1)
pmo.Options = int32(C.MQPMO_NONE)
pmo.Timeout = -1
pmo.Context = 0
pmo.KnownDestCount = 0
pmo.UnknownDestCount = 0
pmo.InvalidDestCount = 0
pmo.ResolvedQName = ""
pmo.ResolvedQMgrName = ""
pmo.RecsPresent = 0
pmo.PutMsgRecFields = 0
pmo.PutMsgRecOffset = 0
pmo.ResponseRecOffset = 0
pmo.PutMsgRecPtr = nil
pmo.ResponseRecPtr = nil
pmo.OriginalMsgHandle = C.MQHM_NONE
pmo.NewMsgHandle = C.MQHM_NONE
pmo.Action = int32(C.MQACTP_NEW)
pmo.PubLevel = 9
return pmo
}
func copyPMOtoC(mqpmo *C.MQPMO, gopmo *MQPMO) {
setMQIString((*C.char)(&mqpmo.StrucId[0]), "PMO ", 4)
mqpmo.Version = C.MQLONG(gopmo.Version)
mqpmo.Options = C.MQLONG(gopmo.Options)
mqpmo.Timeout = C.MQLONG(gopmo.Timeout)
mqpmo.Context = gopmo.Context
mqpmo.KnownDestCount = C.MQLONG(gopmo.KnownDestCount)
mqpmo.UnknownDestCount = C.MQLONG(gopmo.UnknownDestCount)
mqpmo.InvalidDestCount = C.MQLONG(gopmo.InvalidDestCount)
setMQIString((*C.char)(&mqpmo.ResolvedQName[0]), gopmo.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqpmo.ResolvedQMgrName[0]), gopmo.ResolvedQMgrName, C.MQ_OBJECT_NAME_LENGTH)
mqpmo.RecsPresent = C.MQLONG(gopmo.RecsPresent)
mqpmo.PutMsgRecFields = C.MQLONG(gopmo.PutMsgRecFields)
mqpmo.PutMsgRecOffset = C.MQLONG(gopmo.PutMsgRecOffset)
mqpmo.ResponseRecOffset = C.MQLONG(gopmo.ResponseRecOffset)
mqpmo.PutMsgRecPtr = gopmo.PutMsgRecPtr
mqpmo.ResponseRecPtr = gopmo.ResponseRecPtr
mqpmo.OriginalMsgHandle = gopmo.OriginalMsgHandle
mqpmo.NewMsgHandle = gopmo.NewMsgHandle
mqpmo.Action = C.MQLONG(gopmo.Action)
mqpmo.PubLevel = C.MQLONG(gopmo.PubLevel)
return
}
func copyPMOfromC(mqpmo *C.MQPMO, gopmo *MQPMO) {
gopmo.Version = int32(mqpmo.Version)
gopmo.Options = int32(mqpmo.Options)
gopmo.Timeout = int32(mqpmo.Timeout)
gopmo.Context = mqpmo.Context
gopmo.KnownDestCount = int32(mqpmo.KnownDestCount)
gopmo.UnknownDestCount = int32(mqpmo.UnknownDestCount)
gopmo.InvalidDestCount = int32(mqpmo.InvalidDestCount)
gopmo.ResolvedQName = C.GoStringN((*C.char)(&mqpmo.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
gopmo.ResolvedQMgrName = C.GoStringN((*C.char)(&mqpmo.ResolvedQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
gopmo.RecsPresent = int32(mqpmo.RecsPresent)
gopmo.PutMsgRecFields = int32(mqpmo.PutMsgRecFields)
gopmo.PutMsgRecOffset = int32(mqpmo.PutMsgRecOffset)
gopmo.ResponseRecOffset = int32(mqpmo.ResponseRecOffset)
gopmo.PutMsgRecPtr = mqpmo.PutMsgRecPtr
gopmo.ResponseRecPtr = mqpmo.ResponseRecPtr
gopmo.OriginalMsgHandle = mqpmo.OriginalMsgHandle
gopmo.NewMsgHandle = mqpmo.NewMsgHandle
gopmo.Action = int32(mqpmo.Action)
gopmo.PubLevel = int32(mqpmo.PubLevel)
return
}

View File

@@ -0,0 +1,100 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
#include <cmqxc.h>
*/
import "C"
/*
MQSCO is a structure containing the MQ SSL/TLS Configuration (MQSCO)
options.
*/
type MQSCO struct {
KeyRepository string
CryptoHardware string
KeyResetCount int32
FipsRequired bool
EncryptionPolicySuiteB [4]int32
CertificateValPolicy int32
CertificateLabel string
}
/*
NewMQSCO fills in default values for the MQSCO structure
*/
func NewMQSCO() *MQSCO {
sco := new(MQSCO)
sco.KeyRepository = ""
sco.CryptoHardware = ""
sco.KeyResetCount = int32(C.MQSCO_RESET_COUNT_DEFAULT)
sco.FipsRequired = false
sco.EncryptionPolicySuiteB[0] = int32(C.MQ_SUITE_B_NONE)
for i := 1; i < 4; i++ {
sco.EncryptionPolicySuiteB[i] = int32(C.MQ_SUITE_B_NOT_AVAILABLE)
}
sco.CertificateValPolicy = int32(C.MQ_CERT_VAL_POLICY_DEFAULT)
sco.CertificateLabel = ""
return sco
}
/*
It is expected that copyXXtoC and copyXXfromC will be called as
matching pairs.
*/
func copySCOtoC(mqsco *C.MQSCO, gosco *MQSCO) {
setMQIString((*C.char)(&mqsco.StrucId[0]), "SCO ", 4)
mqsco.Version = C.MQSCO_VERSION_5
setMQIString((*C.char)(&mqsco.KeyRepository[0]), gosco.KeyRepository, C.MQ_SSL_KEY_REPOSITORY_LENGTH)
setMQIString((*C.char)(&mqsco.CryptoHardware[0]), gosco.CryptoHardware, C.MQ_SSL_CRYPTO_HARDWARE_LENGTH)
mqsco.AuthInfoRecCount = 0
mqsco.AuthInfoRecOffset = 0
mqsco.AuthInfoRecPtr = nil
mqsco.KeyResetCount = C.MQLONG(gosco.KeyResetCount)
if gosco.FipsRequired {
mqsco.FipsRequired = C.MQSSL_FIPS_YES
} else {
mqsco.FipsRequired = C.MQSSL_FIPS_NO
}
for i := 0; i < 4; i++ {
mqsco.EncryptionPolicySuiteB[i] = C.MQLONG(gosco.EncryptionPolicySuiteB[i])
}
mqsco.CertificateValPolicy = C.MQLONG(gosco.CertificateValPolicy)
setMQIString((*C.char)(&mqsco.CertificateLabel[0]), gosco.CertificateLabel, C.MQ_CERT_LABEL_LENGTH)
return
}
/*
All of the parameters in the MQSCO are input only.
*/
func copySCOfromC(mqsco *C.MQSCO, gosco *MQSCO) {
return
}

View File

@@ -0,0 +1,216 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
*/
import "C"
import (
"bytes"
"unsafe"
)
/*
MQSD is a structure containing the MQ Subscription Descriptor (MQSD)
*/
type MQSD struct {
Version int32
Options int32
ObjectName string
AlternateUserId string
AlternateSecurityId []byte
SubExpiry int32
ObjectString string
SubName string
SubUserData string
SubCorrelId []byte
PubPriority int32
PubAccountingToken []byte
PubApplIdentityData string
SelectionString string
SubLevel int32
ResObjectString string
}
/*
NewMQSD fills in default values for the MQSD structure
*/
func NewMQSD() *MQSD {
sd := new(MQSD)
sd.Version = int32(C.MQSD_VERSION_1)
sd.Options = 0
sd.ObjectName = ""
sd.AlternateUserId = ""
sd.AlternateSecurityId = bytes.Repeat([]byte{0}, C.MQ_SECURITY_ID_LENGTH)
sd.SubExpiry = int32(C.MQEI_UNLIMITED)
sd.ObjectString = ""
sd.SubName = ""
sd.SubUserData = ""
sd.SubCorrelId = bytes.Repeat([]byte{0}, C.MQ_CORREL_ID_LENGTH)
sd.PubPriority = int32(C.MQPRI_PRIORITY_AS_PUBLISHED)
sd.PubAccountingToken = bytes.Repeat([]byte{0}, C.MQ_ACCOUNTING_TOKEN_LENGTH)
sd.PubApplIdentityData = ""
sd.SelectionString = ""
sd.SubLevel = 1
sd.ResObjectString = ""
return sd
}
/*
It is expected that copyXXtoC and copyXXfromC will be called as
matching pairs. That means that we can handle the MQCHARV type
by allocating storage in the toC function and freeing it in fromC.
If the input string for an MQCHARV type is empty, then we allocate
a fixed length buffer for any potential output.
In the fromC function, that buffer is freed. Conveniently, we can
free it always, because if we didn't explicitly call malloc(), it was
allocated by C.CString and still needs to be freed.
*/
func copySDtoC(mqsd *C.MQSD, gosd *MQSD) {
var i int
const vsbufsize = 10240
setMQIString((*C.char)(&mqsd.StrucId[0]), "SD ", 4)
mqsd.Version = C.MQLONG(gosd.Version)
mqsd.Options = C.MQLONG(gosd.Options)
setMQIString((*C.char)(&mqsd.ObjectName[0]), gosd.ObjectName, C.MQ_OBJECT_NAME_LENGTH)
setMQIString((*C.char)(&mqsd.AlternateUserId[0]), gosd.AlternateUserId, C.MQ_USER_ID_LENGTH)
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
mqsd.AlternateSecurityId[i] = C.MQBYTE(gosd.AlternateSecurityId[i])
}
mqsd.SubExpiry = C.MQLONG(gosd.SubExpiry)
mqsd.ObjectString.VSLength = (C.MQLONG)(len(gosd.ObjectString))
mqsd.ObjectString.VSCCSID = C.MQCCSI_APPL
if mqsd.ObjectString.VSLength == 0 {
mqsd.ObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqsd.ObjectString.VSBufSize = vsbufsize
} else {
mqsd.ObjectString.VSPtr = (C.MQPTR)(C.CString(gosd.ObjectString))
}
mqsd.SubName.VSLength = (C.MQLONG)(len(gosd.SubName))
mqsd.SubName.VSCCSID = C.MQCCSI_APPL
if mqsd.SubName.VSLength == 0 {
mqsd.SubName.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqsd.SubName.VSBufSize = vsbufsize
} else {
mqsd.SubName.VSPtr = (C.MQPTR)(C.CString(gosd.SubName))
}
mqsd.SubUserData.VSLength = (C.MQLONG)(len(gosd.SubUserData))
mqsd.SubUserData.VSCCSID = C.MQCCSI_APPL
if mqsd.SubUserData.VSLength == 0 {
mqsd.SubUserData.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqsd.SubUserData.VSBufSize = vsbufsize
} else {
mqsd.SubUserData.VSPtr = (C.MQPTR)(C.CString(gosd.SubUserData))
}
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
mqsd.SubCorrelId[i] = C.MQBYTE(gosd.SubCorrelId[i])
}
mqsd.PubPriority = C.MQLONG(gosd.PubPriority)
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
mqsd.PubAccountingToken[i] = C.MQBYTE(gosd.PubAccountingToken[i])
}
setMQIString((*C.char)(&mqsd.PubApplIdentityData[0]), gosd.PubApplIdentityData, C.MQ_APPL_IDENTITY_DATA_LENGTH)
mqsd.SelectionString.VSLength = (C.MQLONG)(len(gosd.SelectionString))
mqsd.SelectionString.VSCCSID = C.MQCCSI_APPL
if mqsd.SelectionString.VSLength == 0 {
mqsd.SelectionString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqsd.SelectionString.VSBufSize = vsbufsize
} else {
mqsd.SelectionString.VSPtr = (C.MQPTR)(C.CString(gosd.SelectionString))
}
mqsd.SubLevel = C.MQLONG(gosd.SubLevel)
mqsd.ResObjectString.VSLength = (C.MQLONG)(len(gosd.ResObjectString))
mqsd.ResObjectString.VSCCSID = C.MQCCSI_APPL
if mqsd.ResObjectString.VSLength == 0 {
mqsd.ResObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
mqsd.ResObjectString.VSBufSize = vsbufsize
} else {
mqsd.ResObjectString.VSPtr = (C.MQPTR)(C.CString(gosd.ResObjectString))
}
return
}
func copySDfromC(mqsd *C.MQSD, gosd *MQSD) {
var i int
gosd.Version = int32(mqsd.Version)
gosd.Options = int32(mqsd.Options)
gosd.ObjectName = C.GoStringN((*C.char)(&mqsd.ObjectName[0]), C.MQ_OBJECT_NAME_LENGTH)
gosd.AlternateUserId = C.GoStringN((*C.char)(&mqsd.AlternateUserId[0]), C.MQ_USER_ID_LENGTH)
for i := 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
gosd.AlternateSecurityId[i] = (byte)(mqsd.AlternateSecurityId[i])
}
gosd.SubExpiry = int32(mqsd.SubExpiry)
gosd.ObjectString = C.GoStringN((*C.char)(mqsd.ObjectString.VSPtr), (C.int)(mqsd.ObjectString.VSLength))
C.free(unsafe.Pointer(mqsd.ObjectString.VSPtr))
gosd.SubName = C.GoStringN((*C.char)(mqsd.SubName.VSPtr), (C.int)(mqsd.SubName.VSLength))
C.free(unsafe.Pointer(mqsd.SubName.VSPtr))
gosd.SubUserData = C.GoStringN((*C.char)(mqsd.SubUserData.VSPtr), (C.int)(mqsd.SubUserData.VSLength))
C.free(unsafe.Pointer(mqsd.SubUserData.VSPtr))
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
gosd.SubCorrelId[i] = (byte)(mqsd.SubCorrelId[i])
}
gosd.PubPriority = int32(mqsd.PubPriority)
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
gosd.PubAccountingToken[i] = (byte)(mqsd.PubAccountingToken[i])
}
gosd.PubApplIdentityData = C.GoStringN((*C.char)(&mqsd.PubApplIdentityData[0]), C.MQ_APPL_IDENTITY_DATA_LENGTH)
gosd.SelectionString = C.GoStringN((*C.char)(mqsd.SelectionString.VSPtr), (C.int)(mqsd.SelectionString.VSLength))
C.free(unsafe.Pointer(mqsd.SelectionString.VSPtr))
gosd.SubLevel = int32(mqsd.SubLevel)
gosd.ResObjectString = C.GoStringN((*C.char)(mqsd.ResObjectString.VSPtr), (C.int)(mqsd.ResObjectString.VSLength))
C.free(unsafe.Pointer(mqsd.ResObjectString.VSPtr))
return
}

View File

@@ -0,0 +1,267 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <cmqc.h>
#include <cmqcfc.h>
*/
import "C"
import (
"bytes"
"encoding/binary"
"fmt"
)
/*
MQCFH is a structure containing the MQ PCF Header fields
*/
type MQCFH struct {
Type int32
StrucLength int32
Version int32
Command int32
MsgSeqNumber int32
Control int32
CompCode int32
Reason int32
ParameterCount int32
}
var endian binary.ByteOrder
/*
PCFParameter is a structure containing the data associated with
various types of PCF element. Use the Type field to decide which
of the data fields is relevant.
*/
type PCFParameter struct {
Type int32
Parameter int32
Int64Value []int64 // Always store as 64; cast to 32 when needed
String []string
CodedCharSetId int32
ParameterCount int32
GroupList []*PCFParameter
strucLength int32 // Do not need to expose these
stringLength int32 // lengths
}
/*
NewMQCFH returns a PCF Command Header structure with correct initialisation
*/
func NewMQCFH() *MQCFH {
cfh := new(MQCFH)
cfh.Type = C.MQCFT_COMMAND
cfh.StrucLength = C.MQCFH_STRUC_LENGTH
cfh.Version = C.MQCFH_VERSION_1
cfh.Command = C.MQCMD_NONE
cfh.MsgSeqNumber = 1
cfh.Control = C.MQCFC_LAST
cfh.CompCode = C.MQCC_OK
cfh.Reason = C.MQRC_NONE
cfh.ParameterCount = 0
if (C.MQENC_NATIVE % 2) == 0 {
endian = binary.LittleEndian
} else {
endian = binary.BigEndian
}
return cfh
}
/*
Bytes serialises an MQCFH structure as if it were the corresponding C structure
*/
func (cfh *MQCFH) Bytes() []byte {
buf := make([]byte, cfh.StrucLength)
offset := 0
endian.PutUint32(buf[offset:], uint32(cfh.Type))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.StrucLength))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.Version))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.Command))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.MsgSeqNumber))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.Control))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.CompCode))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.Reason))
offset += 4
endian.PutUint32(buf[offset:], uint32(cfh.ParameterCount))
offset += 4
return buf
}
/*
Bytes serialises a PCFParameter into the C structure
corresponding to its type
*/
func (p *PCFParameter) Bytes() []byte {
var buf []byte
switch p.Type {
case C.MQCFT_INTEGER:
buf = make([]byte, C.MQCFIN_STRUC_LENGTH)
offset := 0
endian.PutUint32(buf[offset:], uint32(p.Type))
offset += 4
endian.PutUint32(buf[offset:], uint32(len(buf)))
offset += 4
endian.PutUint32(buf[offset:], uint32(p.Parameter))
offset += 4
endian.PutUint32(buf[offset:], uint32(p.Int64Value[0]))
offset += 4
case C.MQCFT_STRING:
buf = make([]byte, C.MQCFST_STRUC_LENGTH_FIXED+roundTo4(int32(len(p.String[0]))))
offset := 0
endian.PutUint32(buf[offset:], uint32(p.Type))
offset += 4
endian.PutUint32(buf[offset:], uint32(len(buf)))
offset += 4
endian.PutUint32(buf[offset:], uint32(p.Parameter))
offset += 4
endian.PutUint32(buf[offset:], uint32(C.MQCCSI_DEFAULT))
offset += 4
endian.PutUint32(buf[offset:], uint32(len(p.String[0])))
offset += 4
copy(buf[offset:], []byte(p.String[0]))
}
return buf
}
/*
ReadPCFHeader extracts the MQCFH from an MQ message
*/
func ReadPCFHeader(buf []byte) (*MQCFH, int) {
cfh := new(MQCFH)
fullLen := len(buf)
p := bytes.NewBuffer(buf)
binary.Read(p, endian, &cfh.Type)
binary.Read(p, endian, &cfh.StrucLength)
binary.Read(p, endian, &cfh.Version)
binary.Read(p, endian, &cfh.Command)
binary.Read(p, endian, &cfh.MsgSeqNumber)
binary.Read(p, endian, &cfh.Control)
binary.Read(p, endian, &cfh.CompCode)
binary.Read(p, endian, &cfh.Reason)
binary.Read(p, endian, &cfh.ParameterCount)
bytesRead := fullLen - p.Len()
return cfh, bytesRead
}
/*
ReadPCFParameter extracts the next PCF parameter element from an
MQ message.
*/
func ReadPCFParameter(buf []byte) (*PCFParameter, int) {
var i32 int32
var i64 int64
var mqlong int32
var count int32
pcfParm := new(PCFParameter)
fullLen := len(buf)
p := bytes.NewBuffer(buf)
binary.Read(p, endian, &pcfParm.Type)
binary.Read(p, endian, &pcfParm.strucLength)
switch pcfParm.Type {
// There are more PCF element types but the samples only
// needed a subset
case C.MQCFT_INTEGER:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &i32)
pcfParm.Int64Value = append(pcfParm.Int64Value, int64(i32))
case C.MQCFT_INTEGER_LIST:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &count)
for i := 0; i < int(count); i++ {
binary.Read(p, endian, &i32)
pcfParm.Int64Value = append(pcfParm.Int64Value, int64(i32))
}
case C.MQCFT_INTEGER64:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &mqlong) // Used for alignment
binary.Read(p, endian, &i64)
pcfParm.Int64Value = append(pcfParm.Int64Value, i64)
case C.MQCFT_INTEGER64_LIST:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &count)
for i := 0; i < int(count); i++ {
binary.Read(p, endian, &i64)
pcfParm.Int64Value = append(pcfParm.Int64Value, i64)
}
case C.MQCFT_STRING:
offset := int32(C.MQCFST_STRUC_LENGTH_FIXED)
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &pcfParm.CodedCharSetId)
binary.Read(p, endian, &pcfParm.stringLength)
s := string(buf[offset : pcfParm.stringLength+offset])
pcfParm.String = append(pcfParm.String, s)
p.Next(int(pcfParm.strucLength - offset))
case C.MQCFT_STRING_LIST:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &pcfParm.CodedCharSetId)
binary.Read(p, endian, &count)
binary.Read(p, endian, &pcfParm.stringLength)
for i := 0; i < int(count); i++ {
offset := C.MQCFSL_STRUC_LENGTH_FIXED + i*int(pcfParm.stringLength)
s := string(buf[offset : int(pcfParm.stringLength)+offset])
pcfParm.String = append(pcfParm.String, s)
}
p.Next(int(pcfParm.strucLength - C.MQCFSL_STRUC_LENGTH_FIXED))
case C.MQCFT_GROUP:
binary.Read(p, endian, &pcfParm.Parameter)
binary.Read(p, endian, &pcfParm.ParameterCount)
default:
fmt.Println("mqiPCF.go: Unknown PCF type ", pcfParm.Type)
// Skip the remains of this structure, assuming it really is
// PCF and we just don't know how to process the element type
p.Next(int(pcfParm.strucLength - 8))
}
bytesRead := fullLen - p.Len()
return pcfParm, bytesRead
}
func roundTo4(u int32) int32 {
return ((u) + ((4 - ((u) % 4)) % 4))
}

View File

@@ -0,0 +1,98 @@
package ibmmq
/*
Copyright (c) IBM Corporation 2016
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific
Contributors:
Mark Taylor - Initial Contribution
*/
/*
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
#include <cmqstrc.h>
*/
import "C"
import (
"fmt"
)
/*
Convert MQCC/MQRC values into readable text using
the functions introduced in cmqstrc.h in MQ V8004
*/
func mqstrerror(verb string, mqcc C.MQLONG, mqrc C.MQLONG) string {
return fmt.Sprintf("%s: MQCC = %s [%d] MQRC = %s [%d]", verb,
C.GoString(C.MQCC_STR(mqcc)), mqcc,
C.GoString(C.MQRC_STR(mqrc)), mqrc)
}
/*
MQItoString returns a string representation of the MQI #define. Only a few of the
sets of constants are decoded here; see cmqstrc.h for a full set. Some of the
sets are aggregated, so that "RC" will return something from either the MQRC
or MQRCCF sets. These sets are related and do not overlap values.
*/
func MQItoString(class string, value int) string {
s := ""
v := C.MQLONG(value)
switch class {
case "BACF":
s = C.GoString(C.MQBACF_STR(v))
case "CA":
s = C.GoString(C.MQCA_STR(v))
if s == "" {
s = C.GoString(C.MQCACF_STR(v))
}
if s == "" {
s = C.GoString(C.MQCACH_STR(v))
}
if s == "" {
s = C.GoString(C.MQCAMO_STR(v))
}
case "CC":
s = C.GoString(C.MQCC_STR(v))
case "CMD":
s = C.GoString(C.MQCMD_STR(v))
case "IA":
s = C.GoString(C.MQIA_STR(v))
if s == "" {
s = C.GoString(C.MQIACF_STR(v))
}
if s == "" {
s = C.GoString(C.MQIACH_STR(v))
}
if s == "" {
s = C.GoString(C.MQIAMO_STR(v))
}
if s == "" {
s = C.GoString(C.MQIAMO64_STR(v))
}
case "OT":
s = C.GoString(C.MQOT_STR(v))
case "RC":
s = C.GoString(C.MQRC_STR(v))
if s == "" {
s = C.GoString(C.MQRCCF_STR(v))
}
}
return s
}