Райдеры (rider), т. е. считыватели и записыватели (reader и writer) могут быть либо последовательными (не позиционируемые), либо с произвольным доступом (позиционируемые). Программист может испытать затруднение при описании их типов, а именно не ясно стоит ли каждый раз заводить по два разных типа райдеров (позиционируемые и не позиционируемые) или же включить методы позиционирования (GetPosition, SetPosition,...) в один тип, но например выставлять некий булевский флаг возможности их использования. В первом случае получается слишком много типов (по 2 reader и по 2 writer), а во втором случае методы позиционирования иногда будут лишними, а тип громоздким.
Предлагаю иное решение. Вместо того чтобы включать методы позиционирования в типы reader и writer можно обзавестись типом скроллер (scroller), который и будет нести ответственность за прокрутку райдеров:
Код:
Rider = POINTER TO ABSTRACT RECORD
(r: Rider) Available (): LONGINT, NEW, ABSTRACT
END;
Scroller = POINTER TO ABSTRACT RECORD
(s: Scroller) MinPosition (): LONGINT, NEW, ABSTRACT;
(s: Scroller) MaxPosition (): LONGINT, NEW, ABSTRACT;
(s: Scroller) GetPosition (r: Rider): LONGINT, NEW, ABSTRACT;
(s: Scroller) SetPosition (r: Rider; position: LONGINT), NEW, EMPTY
END;
где метод Available (): LONGINT показывает сколько позиций доступно для продвижения вперёд, т. е. для reader - сколько доступно для считывания и для writer - сколько доступно для записи. Бинарные считыватель и записыватель, при этом, есть просто:
Код:
Reader = POINTER TO ABSTRACT RECORD (Rider)
(r: Reader) ReadByte (OUT a: BYTE), NEW, ABSTRACT;
(r: Reader) ReadBytes (OUT a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT
END;
Writer = POINTER TO ABSTRACT RECORD (Rider)
(w: Writer) WriteByte (a: BYTE), NEW, ABSTRACT;
(w: Writer) WriteBytes (IN a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT
END;
Рассмотрим тип объекта-буфера. Кроме считывателей и записывателей буфер должен будет предоставлять ещё и скроллер:
Код:
Buffer = POINTER TO ABSTRACT RECORD
(b: Buffer) NewReader (old: Reader): Reader, NEW, ABSTRACT;
(b: Buffer) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
(b: Buffer) Scroller (): Scroller, NEW, ABSTRACT
END;
А вот, например, тип канал (channel) скроллера своих райдеров предоставлять не будет - они же у него не позиционируемые:
Код:
Channel = POINTER TO ABSTRACT RECORD
(c: Channel) Reader (): Reader, NEW, ABSTRACT;
(c: Channel) Writer (): Writer, NEW, ABSTRACT;
END;
Позиционируемость райдера зависит от его носителя (carrier).
Носитель либо предоставляет скроллер для своих райдеров либо не предоставляет, вот и всё.