Files
MEDDFN/meddfnprs.rpgle
T

580 lines
14 KiB
RPGLE

**FREE
//=====================================================================
//
// Media Definition Parser
//
// Parses TAPE0200 data returned by QSRRTVMD.
//
//=====================================================================
ctl-opt
option(*srcstmt:*nodebugio) nomain;
/COPY './meddfn_h.rpgle'
/COPY './meddfnap_h.rpgle'
//=====================================================================
//
// Prototype
//
//=====================================================================
dcl-pr MD_ParseRetrieveBuffer;
ReceiverBuffer
char(32767) const
options(*varsize);
ReceiverLength
int(10) const;
MediaDefinition
likeds(MD_MediaDefinition_T);
Error
likeds(MD_Error_T);
end-pr;
//=====================================================================
//
// MD_ParseRetrieveBuffer
//
// Parses a retrieved TAPE0200 buffer.
//
// Supported:
//
// - TAPE0200 Header
// - Device Definitions
// - Media File Definitions
// - Volume Identifier Arrays
//
// Parser errors are returned in Error.
//
//=====================================================================
dcl-proc MD_ParseRetrieveBuffer export;
dcl-pi *n;
ReceiverBuffer
char(32767) const
options(*varsize);
ReceiverLength
int(10) const;
MediaDefinition
likeds(MD_MediaDefinition_T);
Error
likeds(MD_Error_T);
end-pi;
//==================================================================
// TAPE0200 structures
//==================================================================
dcl-ds Header
likeds(MD_Tape0200Header_T);
dcl-ds Device
likeds(MD_Tape0200DeviceDefinition_T);
dcl-ds MediaFile
likeds(MD_Tape0200MediaFileDefinition_T);
//==================================================================
// Working variables
//==================================================================
dcl-s DeviceOffset
int(10);
dcl-s MediaOffset
int(10);
dcl-s VolumeOffset
int(10);
dcl-s DeviceIndex
int(10);
dcl-s MediaIndex
int(10);
dcl-s VolumeIndex
int(10);
dcl-s RequiredLength
int(10);
//==================================================================
// Initialize
//==================================================================
clear MediaDefinition;
clear Error;
//==================================================================
// Receiver buffer
//==================================================================
if ReceiverLength < %size(Header);
Error.HasError = *on;
Error.MessageID = 'MDF2005';
Error.MessageData = *blanks;
return;
endif;
//==================================================================
// TAPE0200 Header
//==================================================================
Header =
%subst(
ReceiverBuffer :
1 :
%size(Header));
//==================================================================
// Validate Header
//==================================================================
if Header.LengthOfHeader <> %size(Header);
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
if Header.NumberOfDeviceDefinitions < 1
or Header.NumberOfDeviceDefinitions > MD_MaxDeviceDefinitions;
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
if Header.OffsetToFirstDeviceDefinition < %size(Header)
or Header.OffsetToFirstDeviceDefinition >
ReceiverLength - %size(Device);
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
if Header.DeviceAllocation <> MD_DeviceAllocateAll
and Header.DeviceAllocation <> MD_DeviceAllocateOne
and Header.DeviceAllocation <> MD_DeviceAllocateMinimum;
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
if Header.SaveFormat <> MD_SaveFormatAuto
and Header.SaveFormat <> MD_SaveFormatSerial
and Header.SaveFormat <> MD_SaveFormatParallel;
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
if Header.MaximumParallelDeviceResources < 0
or Header.MinimumParallelDeviceResources < 0
or Header.MinimumParallelDeviceResources >
Header.MaximumParallelDeviceResources;
Error.HasError = *on;
Error.MessageID = 'MDF2001';
Error.MessageData = *blanks;
return;
endif;
//==================================================================
// Header -> Media Definition
//==================================================================
MediaDefinition.MaximumParallelResources =
Header.MaximumParallelDeviceResources;
MediaDefinition.MinimumParallelResources =
Header.MinimumParallelDeviceResources;
MediaDefinition.NumberOfDevices =
Header.NumberOfDeviceDefinitions;
MediaDefinition.DeviceAllocation =
Header.DeviceAllocation;
MediaDefinition.SaveFormat =
Header.SaveFormat;
//==================================================================
// Device Definitions
//==================================================================
DeviceOffset =
Header.OffsetToFirstDeviceDefinition;
for DeviceIndex = 1
to Header.NumberOfDeviceDefinitions;
//===============================================================
// Validate Device Offset
//===============================================================
if DeviceOffset < 0
or DeviceOffset > ReceiverLength - %size(Device);
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
//===============================================================
// Read Device Definition
//===============================================================
Device =
%subst(
ReceiverBuffer :
DeviceOffset + 1 :
%size(Device));
//===============================================================
// Validate Device Definition
//===============================================================
if Device.LengthOfDeviceDefinition <> %size(Device);
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
if Device.NumberOfMediaFileDefinitions < 1
or Device.NumberOfMediaFileDefinitions > MD_MaxMediaDefinitions;
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
if %trim(Device.DeviceName) = '';
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
if Device.OffsetToFirstMediaFileDefinition < %size(Device);
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
//===============================================================
// Device -> Media Definition
//===============================================================
MediaDefinition.Device(DeviceIndex).DeviceName =
Device.DeviceName;
MediaDefinition.Device(DeviceIndex).NumberOfMediaFiles =
Device.NumberOfMediaFileDefinitions;
//===============================================================
// Media Files
//===============================================================
MediaOffset =
DeviceOffset
+ Device.OffsetToFirstMediaFileDefinition;
for MediaIndex = 1
to Device.NumberOfMediaFileDefinitions;
//============================================================
// Validate Media Offset
//============================================================
if MediaOffset < 0
or MediaOffset > ReceiverLength - %size(MediaFile);
Error.HasError = *on;
Error.MessageID = 'MDF2003';
Error.MessageData = *blanks;
return;
endif;
//============================================================
// Read Media File Definition
//============================================================
MediaFile =
%subst(
ReceiverBuffer :
MediaOffset + 1 :
%size(MediaFile));
//============================================================
// Validate Media File Definition
//============================================================
if MediaFile.LengthOfMediaFileDefinition <> %size(MediaFile);
Error.HasError = *on;
Error.MessageID = 'MDF2003';
Error.MessageData = *blanks;
return;
endif;
if MediaFile.NumberOfVolumeIdentifiers < 0
or MediaFile.NumberOfVolumeIdentifiers > MD_MaxVolumeIdentifiers;
Error.HasError = *on;
Error.MessageID = 'MDF2003';
Error.MessageData = *blanks;
return;
endif;
if MediaFile.NumberOfVolumeIdentifiers = 0;
if MediaFile.OffsetToVolumeIdentifierArray <> 0
or MediaFile.LengthOfVolumeIdentifier <> 0
or MediaFile.StartingVolumeArrayElement <> 0;
Error.HasError = *on;
Error.MessageID = 'MDF2004';
Error.MessageData = *blanks;
return;
endif;
else;
if MediaFile.OffsetToVolumeIdentifierArray <= 0
or MediaFile.LengthOfVolumeIdentifier <> MD_VOLUME_ID_LENGTH
or MediaFile.StartingVolumeArrayElement < 1;
Error.HasError = *on;
Error.MessageID = 'MDF2004';
Error.MessageData = *blanks;
return;
endif;
RequiredLength =
MediaFile.NumberOfVolumeIdentifiers
* MediaFile.LengthOfVolumeIdentifier;
if MediaFile.OffsetToVolumeIdentifierArray >
ReceiverLength - RequiredLength
or MediaFile.OffsetToVolumeIdentifierArray <
MediaOffset + %size(MediaFile);
Error.HasError = *on;
Error.MessageID = 'MDF2004';
Error.MessageData = *blanks;
return;
endif;
endif;
//============================================================
// Media File -> Media Definition
//============================================================
MediaDefinition.Device(DeviceIndex)
.MediaFile(MediaIndex)
.SequenceNumber =
MediaFile.SequenceNumber;
MediaDefinition.Device(DeviceIndex)
.MediaFile(MediaIndex)
.StartingPositionInFile =
MediaFile.StartingPositionInFile;
MediaDefinition.Device(DeviceIndex)
.MediaFile(MediaIndex)
.NumberOfVolumeIdentifiers =
MediaFile.NumberOfVolumeIdentifiers;
//============================================================
// Volume Identifier Array
//============================================================
if MediaFile.NumberOfVolumeIdentifiers > 0;
VolumeOffset =
MediaFile.OffsetToVolumeIdentifierArray;
for VolumeIndex = 1
to MediaFile.NumberOfVolumeIdentifiers;
MediaDefinition.Device(DeviceIndex)
.MediaFile(MediaIndex)
.VolumeIdentifier(VolumeIndex)
.VolumeIdentifier =
%subst(
ReceiverBuffer :
VolumeOffset
+ ((VolumeIndex - 1)
* MediaFile.LengthOfVolumeIdentifier)
+ 1 :
MediaFile.LengthOfVolumeIdentifier);
endfor;
endif;
//============================================================
// Next Media File
//============================================================
if MediaIndex
< Device.NumberOfMediaFileDefinitions;
if MediaFile.OffsetToNextMediaFileDefinition <=
MediaOffset
or MediaFile.OffsetToNextMediaFileDefinition >
ReceiverLength - %size(MediaFile);
Error.HasError = *on;
Error.MessageID = 'MDF2003';
Error.MessageData = *blanks;
return;
endif;
MediaOffset =
MediaFile.OffsetToNextMediaFileDefinition;
else;
if MediaFile.OffsetToNextMediaFileDefinition <> 0;
Error.HasError = *on;
Error.MessageID = 'MDF2003';
Error.MessageData = *blanks;
return;
endif;
endif;
endfor;
//================================================================
// Next Device
//================================================================
if DeviceIndex < Header.NumberOfDeviceDefinitions;
if Device.OffsetToNextDeviceDefinition <=
DeviceOffset
or Device.OffsetToNextDeviceDefinition >
ReceiverLength - %size(Device);
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
DeviceOffset =
Device.OffsetToNextDeviceDefinition;
else;
if Device.OffsetToNextDeviceDefinition <> 0;
Error.HasError = *on;
Error.MessageID = 'MDF2002';
Error.MessageData = *blanks;
return;
endif;
endif;
endfor;
end-proc;