Table of Contents

Interface IFileChannel

Namespace
RDCore.SDK.Runtime.Abstract.Execution
Assembly
RDCore.SDK.dll

One file number that an Open statement associated with an external data file (MS-VBAL §5.4.5), and the processing modes it was opened under.

public interface IFileChannel

Remarks

The association "remains in effect until they are explicitly disassociated using a close-statement" (§5.4.5.1) — so a channel outlives the procedure that opened it and belongs to the session, not to a call frame.

Properties

Access

What later statements may do with the channel. Implied by Mode when the Open declared no Access clause.

VBFileAccessMode Access { get; }

Property Value

VBFileAccessMode

FileNumber

The file number source refers to this channel by — #1's 1.

int FileNumber { get; }

Property Value

int

Input

The channel as a character-input source, for Line Input # and Input #.

IFileChannelInput Input { get; }

Property Value

IFileChannelInput

Remarks

Reads at the same file-pointer-position Output writes at: MS-VBAL §5.4.5 gives a channel one position and not one per direction, which is what makes an Append channel able to read back what it appended.

👉 As with Output, a caller is expected to have asked FileStatementAccess whether the statement is valid on this channel first.

Lock

What the channel locks against other processes. Shared when the Open declared no lock.

VBFileLockMode Lock { get; }

Property Value

VBFileLockMode

Locks

The ranges of this channel's file currently locked against other agents (MS-VBAL §5.4.5.4), in no particular order.

IEnumerable<FileRecordRange> Locks { get; }

Property Value

IEnumerable<FileRecordRange>

Remarks

"Multiple lock ranges established by multiple lock statements can be simultaneously active", and each "remains in effect until it is removed by an Unlock statement... or specifies a record range that evaluates to the same start record and end record" — so which ranges are held is not bookkeeping, it is what decides whether the next Unlock is legal.

Mode

How data is read from and written to the file. Random when the Open declared no For clause (§5.4.5.1).

VBFileMode Mode { get; }

Property Value

VBFileMode

Output

The channel as a character-output target, for Print # and Write #.

IFileChannelOutput Output { get; }

Property Value

IFileChannelOutput

Remarks

The same IRuntimeOutput the session's own output is, so MS-VBAL §5.4.5.8's output rules - print zones, the numeric space, Spc, Tab, a trailing ; - are evaluated once and written wherever they are aimed. A channel counts its own line position, which is what those rules are relative to.

👉 A caller is expected to have asked FileStatementAccess whether the statement is valid on this channel first. Writing to one opened for reading fails rather than corrupting it, but reporting which statement was wrong is the caller's job, not this one's.

Path

The complete path specification the channel was opened on.

string Path { get; }

Property Value

string

Position

The current file-pointer-position, one-based — counted in records when the channel was opened Random and in bytes otherwise (MS-VBAL §5.4.5.3).

long Position { get; }

Property Value

long

RecordLength

The Len = record length, or 0 when the Open declared none. Ignored for Binary, which the specification says to disregard it for.

int RecordLength { get; }

Property Value

int

Methods

LockRange(FileRecordRange)

Locks range of the file against other agents (MS-VBAL §5.4.5.4).

VBRuntimeErrorId? LockRange(FileRecordRange range)

Parameters

range FileRecordRange

The range to lock, or EntireFile. A channel opened Input, Output or Append locks the entire file whatever is asked for, which the specification states outright.

Returns

VBRuntimeErrorId?

The error that stopped it, or null. "Start record MUST be greater than or equal to 1, and less than or equal to end record. If not, an error is raised" — unnamed there, and MS-VBA raises 63.

Seek(long)

Repositions the channel so the next operation happens at position (MS-VBAL §5.4.5.3).

VBRuntimeErrorId? Seek(long position)

Parameters

position long

The new position, in the same units Position is counted in.

Returns

VBRuntimeErrorId?

The error that stopped it, or null. A position of 0 or less is one — the specification says "an error is raised" without naming it, and MS-VBA raises 63, Bad record number.

Remarks

A position past the end of the file extends it — "the extended content of the file is implementation defined and can be undefined" — except on a channel whose access is Read, which the specification exempts.

TryReadRecord(VBType, int, out VBTypedValue?)

Reads one record at the current file-pointer-position — what a Get statement does (MS-VBAL §5.4.5.12).

bool TryReadRecord(VBType declaredType, int currentLength, out VBTypedValue? value)

Parameters

declaredType VBType

The declared type of the variable being read into, which decides how many bytes the record occupies — except for a Variant, where the record's own descriptor decides.

currentLength int

The length of the variable's current value, which is how many bytes a String read from a Binary channel takes.

value VBTypedValue

The value read.

Returns

bool

false at end of file, or for a declared type the format has no row for.

TryReadRecordInto(VBUserDefinedTypeValue)

Reads one record into the fields of userDefinedType, in declaration order — what a Get whose variable is a UDT does (MS-VBAL §5.4.5.12).

bool TryReadRecordInto(VBUserDefinedTypeValue userDefinedType)

Parameters

userDefinedType VBUserDefinedTypeValue

The UDT value whose fields are filled.

Returns

bool

false at end of file, or for a field whose type the format has no row for.

Remarks

Reads into the value rather than producing a new one, because that is what the statement describes and what a UDT variable is: it has location identity, so a Get fills the variable the program already has rather than replacing it. Each field is read by its own row of the format, so a record written by a Put of the same type reads straight back.

TryWriteRecord(VBTypedValue, bool, out int)

Writes one record at the current file-pointer-position, in the byte format MS-VBAL §5.4.5.11's tables define — what a Put statement does.

bool TryWriteRecord(VBTypedValue value, bool isVariant, out int written)

Parameters

value VBTypedValue

The value to write.

isVariant bool

Whether the data expression's declared type is Variant, which the format precedes with a two-byte type descriptor.

written int

How many bytes reached the file, which Put checks against a record length.

Returns

bool

false for a value the format has no row for — an object, or a UDT.

Remarks

Record I/O is bytes rather than characters, so it does not go through Output: a record's width comes from the value's declared type and not from how it prints, and nothing about it is relative to a line.

UnlockRange(FileRecordRange)

Releases a lock this channel holds (MS-VBAL §5.4.5.5).

VBRuntimeErrorId? UnlockRange(FileRecordRange range)

Parameters

range FileRecordRange

The range to release, which "MUST designate a range that is identical to a start record to end record range of a previously executed Lock statement", or EntireFile.

Returns

VBRuntimeErrorId?

The error that stopped it, or null. Asking for a range no Lock established is one, and so is the mismatch the specification names last: "if a record range is provided for only the Lock statement or the Unlock statement designating the same currently open file number".