626 lines
13 KiB
RPGLE
626 lines
13 KiB
RPGLE
**FREE
|
|
//=====================================================================
|
|
//
|
|
// Project......: MEDDFN
|
|
//
|
|
// Member.......: MEDDFNBLD
|
|
//
|
|
// Description..: Media Definition Buffer Builder
|
|
//
|
|
// Builds IBM API request buffers.
|
|
//
|
|
// IBM Release..: IBM i V7R5
|
|
//
|
|
//=====================================================================
|
|
//---------------------------------------------------------------
|
|
// IMPORTANT:
|
|
//
|
|
// All offsets in the TAPE0200 create buffer are ABSOLUTE offsets
|
|
// from the beginning of the API input buffer.
|
|
//
|
|
// This includes:
|
|
//
|
|
// OffsetToFirstDeviceDefinition
|
|
// OffsetToNextDeviceDefinition
|
|
// OffsetToFirstMediaFileDefinition
|
|
// OffsetToNextMediaFileDefinition
|
|
// OffsetToVolumeIdentifierArray
|
|
//
|
|
// Verified against IBM QSRCRTMD on IBM i 7.5.
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ctl-opt
|
|
option(*srcstmt:*nodebugio) nomain ;
|
|
|
|
/COPY GOSCH/MEDDFN,MEDDFN_H
|
|
/COPY GOSCH/MEDDFN,MEDDFNAP_H
|
|
|
|
|
|
//=====================================================================
|
|
// Internal Prototypes
|
|
//=====================================================================
|
|
|
|
dcl-pr MD_InitializeBuilder;
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
end-pr;
|
|
|
|
|
|
dcl-pr MD_AppendStructure;
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
Data char(32767) const options(*varsize);
|
|
DataLength int(10) const;
|
|
end-pr;
|
|
|
|
dcl-pr MD_AppendBytes;
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
Data char(32767) const options(*varsize);
|
|
DataLength int(10) const;
|
|
end-pr;
|
|
|
|
|
|
dcl-pr MD_BuildTape0200Device;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDevice likeds(MD_MediaDevice_T) const;
|
|
|
|
IsLastDevice ind const;
|
|
|
|
end-pr;
|
|
|
|
//=====================================================================
|
|
// Volume Builder
|
|
//=====================================================================
|
|
|
|
dcl-pr MD_BuildTape0200VolumeArray;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaFile likeds(MD_MediaFile_T) const;
|
|
|
|
end-pr;
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Media Builder
|
|
//=====================================================================
|
|
|
|
dcl-pr MD_BuildTape0200Media;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDevice likeds(MD_MediaDevice_T) const;
|
|
|
|
MediaIndex int(10) const;
|
|
end-pr;
|
|
|
|
|
|
//=====================================================================
|
|
// Header Builder
|
|
//=====================================================================
|
|
|
|
dcl-pr MD_BuildTape0200Header;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDefinition likeds(MD_MediaDefinition_T) const;
|
|
|
|
end-pr;
|
|
|
|
|
|
|
|
|
|
//=====================================================================
|
|
// Exported Procedures
|
|
//=====================================================================
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_BuildCreateBuffer
|
|
//
|
|
// Description:
|
|
// Builds a complete TAPE0200 create buffer.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_BuildCreateBuffer export;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDefinition likeds(MD_MediaDefinition_T) const;
|
|
|
|
end-pi;
|
|
|
|
dcl-s DeviceIndex int(10);
|
|
|
|
MD_InitializeBuilder(BuilderContext);
|
|
|
|
MD_BuildTape0200Header(
|
|
BuilderContext :
|
|
MediaDefinition);
|
|
|
|
|
|
for DeviceIndex = 1 to MediaDefinition.NumberOfDevices;
|
|
|
|
|
|
MD_BuildTape0200Device(
|
|
BuilderContext :
|
|
MediaDefinition.Device(DeviceIndex) :
|
|
DeviceIndex = MediaDefinition.NumberOfDevices);
|
|
|
|
endfor;
|
|
|
|
|
|
|
|
end-proc;
|
|
|
|
|
|
//=====================================================================
|
|
// Internal Procedures
|
|
//=====================================================================
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_InitializeBuilder
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_InitializeBuilder;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
end-pi;
|
|
|
|
clear BuilderContext;
|
|
|
|
BuilderContext.BufferLength = 0;
|
|
|
|
end-proc;
|
|
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_AppendStructure
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_AppendStructure;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
Data char(32767) const options(*varsize);
|
|
|
|
DataLength int(10) const;
|
|
|
|
end-pi;
|
|
|
|
%subst(
|
|
BuilderContext.Buffer :
|
|
BuilderContext.BufferLength + 1 :
|
|
DataLength) = %subst(Data : 1 : DataLength);
|
|
|
|
BuilderContext.BufferLength += DataLength;
|
|
|
|
end-proc;
|
|
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_AppendBytes
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_AppendBytes;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
Data char(32767) const options(*varsize);
|
|
|
|
DataLength int(10) const;
|
|
|
|
end-pi;
|
|
|
|
%subst(
|
|
BuilderContext.Buffer :
|
|
BuilderContext.BufferLength + 1 :
|
|
DataLength) = %subst(Data : 1 : DataLength);
|
|
|
|
BuilderContext.BufferLength += DataLength;
|
|
|
|
end-proc;
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_BuildTape0200Header
|
|
//
|
|
// Builds the TAPE0200 header.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_BuildTape0200Header;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDefinition likeds(MD_MediaDefinition_T) const;
|
|
|
|
end-pi;
|
|
|
|
dcl-ds Header0200
|
|
likeds(MD_Tape0200Header_T)
|
|
inz;
|
|
|
|
|
|
Header0200.Reserved1 = 0;
|
|
|
|
Header0200.Reserved2 = 0;
|
|
|
|
Header0200.MaximumParallelDeviceResources =
|
|
MediaDefinition.MaximumParallelResources;
|
|
|
|
Header0200.MinimumParallelDeviceResources =
|
|
MediaDefinition.MinimumParallelResources;
|
|
|
|
Header0200.OffsetToFirstDeviceDefinition =
|
|
%size(MD_Tape0200Header_T);
|
|
|
|
Header0200.NumberOfDeviceDefinitions =
|
|
MediaDefinition.NumberOfDevices;
|
|
|
|
Header0200.LengthOfHeader =
|
|
%size(MD_Tape0200Header_T);
|
|
|
|
Header0200.DeviceAllocation =
|
|
MediaDefinition.DeviceAllocation;
|
|
|
|
Header0200.SaveFormat =
|
|
MediaDefinition.SaveFormat;
|
|
|
|
|
|
MD_AppendStructure(
|
|
BuilderContext :
|
|
Header0200 :
|
|
%size(Header0200));
|
|
|
|
end-proc;
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_BuildTape0200Device
|
|
//
|
|
// Description:
|
|
// Builds one TAPE0200 Device Definition and appends it to the
|
|
// builder buffer.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_BuildTape0200Device;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDevice likeds(MD_MediaDevice_T) const;
|
|
|
|
IsLastDevice ind const;
|
|
|
|
end-pi;
|
|
|
|
|
|
dcl-ds Device0200
|
|
likeds(MD_Tape0200DeviceDefinition_T)
|
|
inz;
|
|
|
|
dcl-s MediaIndex int(10);
|
|
dcl-s NextDeviceOffset int(10);
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Calculate offset to next device definition
|
|
//---------------------------------------------------------------
|
|
|
|
if IsLastDevice;
|
|
|
|
NextDeviceOffset = 0;
|
|
|
|
else;
|
|
|
|
NextDeviceOffset =
|
|
%size(MD_Tape0200DeviceDefinition_T);
|
|
|
|
for MediaIndex = 1
|
|
to MediaDevice.NumberOfMediaFiles;
|
|
|
|
NextDeviceOffset +=
|
|
%size(MD_Tape0200MediaFileDefinition_T);
|
|
|
|
NextDeviceOffset +=
|
|
MD_AlignLength(
|
|
MediaDevice.MediaFile(MediaIndex)
|
|
.NumberOfVolumeIdentifiers
|
|
* MD_VOLUME_ID_LENGTH);
|
|
|
|
endfor;
|
|
|
|
endif;
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Device structure
|
|
//---------------------------------------------------------------
|
|
|
|
// Device0200.OffsetToNextDeviceDefinition =
|
|
// NextDeviceOffset;
|
|
|
|
Device0200.OffsetToNextDeviceDefinition =
|
|
BuilderContext.BufferLength + NextDeviceOffset;
|
|
|
|
Device0200.DeviceName =
|
|
MediaDevice.DeviceName;
|
|
|
|
Device0200.Reserved = x'0000';
|
|
|
|
Device0200.OffsetToFirstMediaFileDefinition =
|
|
BuilderContext.BufferLength
|
|
+ %size(MD_Tape0200DeviceDefinition_T);
|
|
|
|
Device0200.NumberOfMediaFileDefinitions =
|
|
MediaDevice.NumberOfMediaFiles;
|
|
|
|
Device0200.LengthOfDeviceDefinition =
|
|
%size(MD_Tape0200DeviceDefinition_T);
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Append device structure
|
|
//---------------------------------------------------------------
|
|
|
|
MD_AppendStructure(
|
|
BuilderContext :
|
|
Device0200 :
|
|
%size(Device0200));
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Append all media definitions
|
|
//---------------------------------------------------------------
|
|
|
|
for MediaIndex = 1
|
|
to MediaDevice.NumberOfMediaFiles;
|
|
|
|
MD_BuildTape0200Media(
|
|
BuilderContext :
|
|
MediaDevice :
|
|
MediaIndex);
|
|
|
|
MD_BuildTape0200VolumeArray(
|
|
BuilderContext :
|
|
MediaDevice.MediaFile(MediaIndex));
|
|
|
|
endfor;
|
|
|
|
end-proc;
|
|
|
|
|
|
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_BuildTape0200Media
|
|
//
|
|
// Description:
|
|
// Builds one TAPE0200 Media Definition and appends it to the
|
|
// builder buffer.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_BuildTape0200Media;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaDevice likeds(MD_MediaDevice_T) const;
|
|
|
|
MediaIndex int(10) const;
|
|
|
|
end-pi;
|
|
|
|
|
|
dcl-ds Media0200
|
|
likeds(MD_Tape0200MediaFileDefinition_T)
|
|
inz;
|
|
|
|
dcl-ds MediaFile likeds(MD_MediaFile_T) inz;
|
|
|
|
|
|
|
|
MediaFile = MediaDevice.MediaFile(MediaIndex);
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Sequence Number
|
|
//---------------------------------------------------------------
|
|
|
|
Media0200.SequenceNumber =
|
|
MediaFile.SequenceNumber;
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Starting Position in File
|
|
//---------------------------------------------------------------
|
|
|
|
|
|
Media0200.StartingPositionInFile = *ALL'0';
|
|
|
|
// TODO:
|
|
// StartingPositionInFile is currently initialized to *ALL'0'.
|
|
// The business object does not yet expose all valid API options.
|
|
|
|
//---------------------------------------------------------------
|
|
// Volume Information
|
|
//---------------------------------------------------------------
|
|
|
|
Media0200.NumberOfVolumeIdentifiers =
|
|
MediaFile.NumberOfVolumeIdentifiers;
|
|
|
|
|
|
if MediaFile.NumberOfVolumeIdentifiers > 0;
|
|
|
|
Media0200.OffsetToVolumeIdentifierArray =
|
|
BuilderContext.BufferLength
|
|
+ %size(MD_Tape0200MediaFileDefinition_T);
|
|
|
|
Media0200.LengthOfVolumeIdentifier =
|
|
MD_VOLUME_ID_LENGTH;
|
|
|
|
Media0200.StartingVolumeArrayElement = 1;
|
|
|
|
else;
|
|
|
|
Media0200.OffsetToVolumeIdentifierArray =
|
|
0;
|
|
|
|
Media0200.LengthOfVolumeIdentifier =
|
|
0;
|
|
|
|
Media0200.StartingVolumeArrayElement =
|
|
0;
|
|
|
|
endif;
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Structure Length
|
|
//---------------------------------------------------------------
|
|
|
|
Media0200.LengthOfMediaFileDefinition =
|
|
%size(MD_Tape0200MediaFileDefinition_T);
|
|
|
|
|
|
|
|
if MediaIndex < MediaDevice.NumberOfMediaFiles;
|
|
|
|
Media0200.OffsetToNextMediaFileDefinition =
|
|
BuilderContext.BufferLength
|
|
+ %size(MD_Tape0200MediaFileDefinition_T)
|
|
+ (MD_AlignLength(
|
|
MediaFile.NumberOfVolumeIdentifiers
|
|
* MD_VOLUME_ID_LENGTH));
|
|
|
|
else;
|
|
|
|
Media0200.OffsetToNextMediaFileDefinition = 0;
|
|
|
|
endif;
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Append structure to builder buffer
|
|
//---------------------------------------------------------------
|
|
|
|
MD_AppendStructure(
|
|
BuilderContext :
|
|
Media0200 :
|
|
%size(Media0200));
|
|
|
|
end-proc;
|
|
|
|
//=====================================================================
|
|
//
|
|
// MD_BuildTape0200VolumeArray
|
|
//
|
|
// Description:
|
|
// Appends all Volume Identifiers to the builder buffer.
|
|
//
|
|
//=====================================================================
|
|
|
|
dcl-proc MD_BuildTape0200VolumeArray;
|
|
|
|
dcl-pi *n;
|
|
|
|
BuilderContext likeds(MD_BuilderContext_T);
|
|
|
|
MediaFile likeds(MD_MediaFile_T) const;
|
|
|
|
end-pi;
|
|
|
|
|
|
dcl-s VolumeIndex int(10);
|
|
dcl-s Padding int(10) inz(0);
|
|
dcl-s Pad char(4) inz(x'00000000');
|
|
dcl-s VolumeBytes int(10) inz(0);
|
|
|
|
for VolumeIndex = 1
|
|
to MediaFile.NumberOfVolumeIdentifiers;
|
|
|
|
MD_AppendBytes(
|
|
|
|
BuilderContext :
|
|
|
|
MediaFile.VolumeIdentifier(
|
|
VolumeIndex).VolumeIdentifier :
|
|
MD_VOLUME_ID_LENGTH
|
|
);
|
|
|
|
endfor;
|
|
|
|
|
|
VolumeBytes =
|
|
MediaFile.NumberOfVolumeIdentifiers
|
|
* MD_VOLUME_ID_LENGTH;
|
|
|
|
Padding =
|
|
MD_AlignLength(VolumeBytes)
|
|
- VolumeBytes;
|
|
|
|
if Padding > 0;
|
|
|
|
MD_AppendBytes(
|
|
BuilderContext :
|
|
Pad :
|
|
Padding);
|
|
|
|
endif;
|
|
|
|
|
|
end-proc;
|
|
|
|
dcl-proc MD_AlignLength;
|
|
|
|
dcl-pi *n int(10);
|
|
|
|
Length int(10) const;
|
|
|
|
end-pi;
|
|
|
|
dcl-s Result int(10);
|
|
|
|
Result = Length;
|
|
|
|
if %rem(Result : 4) <> 0;
|
|
Result += 4 - %rem(Result : 4);
|
|
endif;
|
|
|
|
return Result;
|
|
|
|
end-proc;
|