first commit
This commit is contained in:
267
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiPCF.go
generated
vendored
Normal file
267
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiPCF.go
generated
vendored
Normal 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))
|
||||
}
|
||||
Reference in New Issue
Block a user