Files
MEDDFN/meddfn/meddfnbld.rpgle
T
2026-08-14 17:10:38 +02:00

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;