From: leichter@lrw.com (Jerry Leichter)
Newsgroups: comp.os.vms
Subject: re:  Variable length records to tape
Date: 5 Jan 93 12:28:44 GMT
Distribution: world
Organization: The Internet


	Can someone tell me how to write variable length physical blocks to
	tape with VMS, so that the tape can be read again on a foreign system?

	In better detail:

	If my file has record format "Variable length, maximum 2048 bytes",
	and I have a record that is 2100 bytes,

Such a record can't exist.  What do you think "maximum 2048 bytes" means?
*You* may have some convention for considering successive records to be part
of one "unit", but that doesn't make them records.  It's important to keep
the terms straight so we know what we are talking about!

					        then I need the first 2048
	bytes written in one physical block and the next 52 bytes written in
	the next physical block, immediately followed by a physical
	end-of-block.  No leading size- of-block info, no trailing filler to
	complete 2048 bytes; just my data and physical end-of-block markers.
	On disk, my file is stored just as I want it:  logical blocks are
	headed by 2 bytes to indicate their size, but these 2 bytes are not
	included in that size -- just my data.  I need VMS to write this file
	to tape using these 2 bytes to determine how long to make the physical
	block, with no extraneous overhead.  The size of the physical block
	would tell the system reading the tape how long the logical block is.

The "extraneous data" is there whether the file is on disk or on tape.  It's
just a question of how the sizes of the records are described.  For VMS disk
files, the length field describes only the user data, and when you access the
file using record-mode operations, you never see the length, only the data.
For tape files, VMS follows ANSI tape conventions, which specify that the
length field INCLUDES itself in defining the length of a record.

To add to the confusion, VMS disk files use a 2-byte binary length field,
which can take on any value from 0 to 32765; the actual record is padded to
an even length, although the record length may be odd.  ANSI variable-length
tape records use a four-byte decimal length (i.e., the length field contains
ASCII digits specifying a length in decimal), which can take on any value from
4 to 9999 (indicating 0 to 9995 bytes of data).

	VMS will *read* a file this way, but when I use COPY to write one to
	tape and use "dd" to read it back on a UNIX system, each logical block
	is headed by it's size, and this header takes physical space in the
	block.

It ALWAYS takes physical space.  The issue is whether you SEE the length bytes
as data or not.  Were you to read the tape back on VMS, you would not see
the length bytes.  Who knows what dd will give you - it depends on one of the
thousands of obscure options you've specified.

	        The last block in a record is padded to fill 2048 bytes.

Let's step back a moment.  VMS supports ANSI-labeled tapes with two formats:
Fixed length records and variable length records.  (I've described variable
length records above; a fixed-length record contains, as you'd expect just
user data.)  The records are gathered together into blocks (which according
to ANSI spec can be up to 2048 bytes long, though VMS and many other systems
let you go larger).  The blocks themselves are always of fixed length, no
matter what the record format; there is a physical "end of block" indication
on the tape.  The unit of I/O to the tape is this physical block.

The format you are describing - encoding your logical units as one or more
varying-length blocks - is not a supported VMS ANSI format.  You cannot
write such a tape using RMS operations, which also means that you cannot
use any of the standard VMS utilities (like COPY and CONVERT) to write it.
Apparently RMS is much more forgiving when it comes to READING such a tape,
but that doesn't help you.

It is straightforward to write a tape of this format yourself.  If you mount
the tape /FOREIGN and then use QIO's, you can organize the contents of the
tape pretty much any way you like:  The operation you'll use is "write n bytes
as a block".  Of course, if you also want ANSI labels, you'll have to write
them yourself.  But in any case you'll have to write a program to do this.

							-- Jerry

Newsgroups: comp.os.vms