(******************************************************************************)
(**)                        ОТДЕЛ Писать;                                   (**)
(******************************************************************************)
(* НАЗНАЧЕНИЕ: запись в поток                                                 *)
(*                                                                            *)
(* ПРИМЕЧАНИЯ:                                                                *)
(*   Для отложенной записи используется промежуточная память (ПП)             *)
(******************************************************************************)

ИСПОЛЬЗУЕТ 
  ОБХОД,
        (*     \Глагол\                *)
  ОС      ИЗ "..\..\..\Отделы\Обмен\",
  Текст   ИЗ "..\..\..\Отделы\Обмен\",  
        (*     \Глагол\                *)
 оЗнака   ИЗ "..\..\..\Отделы\Иное\";

ПОСТ
                                       (* обработка знаков *)
  знУни-=0; (* заголовок 0FFH,0FEH *)
  знВин-=1; (* по 1251 таблице *)
  знДос-=2; (* по 866  таблице *)
                                       (* размер ПП *)
  Размер=4096; 

ВИД
  ППамять=РЯД Размер ИЗ ОБХОД.Ячейка;

  Поток- =ДОСТУП К ОписаниеПотока;
  ОписаниеПотока=НАБОР
    память:ППамять; (* ячейки ПП             *)
    занято:ЦЕЛ;     (* ячеек занятых данными *)
    фссылка:ЦЕЛ;    (* ссылка на файл в ОС   *)
    фпозиция:ЦЕЛ;   (* позиция в файле       *)
    видЗнаков+:ЦЕЛ; (* обработка знаков      *)
  КОН;

(******************************************************************************)
ЗАДАЧА ОткрытьПополнить(имяфайла-:ЦЕПЬ; пополнить:КЛЮЧ):Поток;
(* Создает (открывает) поток с размером ПП, большим обычного. *)
ПЕР
  поток:Поток;
  фссылка:ЦЕЛ;
УКАЗ
  ЕСЛИ пополнить ТО
    фссылка:=ОС.ФДляПополнения(имяфайла)
  ИНАЧЕ
    фссылка:=ОС.ФДляЗаписи(имяфайла)
  КОН;
  ЕСЛИ фссылка = 0 ТО ВОЗВРАТ ПУСТО КОН;
  СОЗДАТЬ(поток);
  поток.фссылка:=фссылка;
  поток.фпозиция:=0;
  поток.занято:=0;
  поток.видЗнаков:=знВин;
  ВОЗВРАТ поток
КОН ОткрытьПополнить;

(******************************************************************************)
ЗАДАЧА Открыть-(имяфайла-:ЦЕПЬ):Поток;
(* Открывает новый поток для записи данных. *)
УКАЗ
  ВОЗВРАТ ОткрытьПополнить(имяфайла,ОТКЛ)
КОН Открыть;

(******************************************************************************)
ЗАДАЧА Пополнить-(имяфайла-:ЦЕПЬ):Поток;
(* Открывает поток для записи данных в его конец. *)
УКАЗ
  ВОЗВРАТ ОткрытьПополнить(имяфайла,ВКЛ)
КОН Пополнить;

(******************************************************************************)
ЗАДАЧА Сбросить-(поток:Поток);
(* Сбрасывает в файл данные из ПП потока-записи. *)
УКАЗ
  ОС.ПисатьФ(поток.фссылка,поток.память,поток.занято);
  поток.занято:=0
КОН Сбросить;

(******************************************************************************)
ЗАДАЧА Закрыть-(поток+:Поток);
(* Сначала сбрасывает в файл данные из ПП, а потом закрывает поток. *)
УКАЗ
  Сбросить(поток);
  ОС.ЗакрытьФ(поток.фссылка);
  поток:=ПУСТО
КОН Закрыть;

(******************************************************************************)
ЗАДАЧА Позиция-(поток:Поток):ЦЕЛ;
(* Возвращает позицию, отсчитываемую от начала файла. *)
УКАЗ
  ВОЗВРАТ поток.фпозиция
КОН Позиция;

(******************************************************************************)
ЗАДАЧА СменаПозиции-(поток:Поток; поз:ЦЕЛ);
(* Меняет позицию записи на <поз>, отсчитываемую от начала файла. *)
УКАЗ
  Сбросить(поток);
  ОС.СменаПозицииФ(поток.фссылка,поз);
  поток.фпозиция:=поз
КОН СменаПозиции;

(******************************************************************************)
ЗАДАЧА Ячейки-(поток:Поток; память-:ОБХОД.Ячейки; размер:ЦЕЛ);
(* Записывает определенное число ячеек. *)
ПЕР
  выбрано:ЦЕЛ;
УКАЗ
  выбрано:=0;
  ПОКА выбрано < размер ВЫП
    ЕСЛИ поток.занято >= Размер ТО
      Сбросить(поток)
    КОН;
    поток.память[поток.занято]:=память[выбрано];
    УВЕЛИЧИТЬ(поток.занято);
    УВЕЛИЧИТЬ(выбрано);
    УВЕЛИЧИТЬ(поток.фпозиция)
  КОН
КОН Ячейки;

(******************************************************************************)
ЗАДАЧА ЗнакЦепи-(поток:Поток; знак:ЗНАК);
(* Записывает в поток один знак без обработки '^'. *)
ПЕР
  уз:ЯЧЦЕЛ;
УКАЗ
  ЕСЛИ поток.видЗнаков = знУни ТО
    ЕСЛИ поток.фпозиция = 0 ТО
      Ячейки(поток,"#FEFF",2);
    КОН;
    Ячейки(поток,знак,2)
  ИНАЧЕ
    ЕСЛИ поток.видЗнаков = знДос ТО
      уз:=оЗнака.ВДос(знак)
    ИНАЧЕ
      уз:=оЗнака.ВВин(знак)
    КОН;
    Ячейки(поток,уз,1)
  КОН
КОН ЗнакЦепи;

(******************************************************************************)
ЗАДАЧА ЗнакиЦепи-(поток:Поток; цепь-:ЦЕПЬ);
(* Записывает цепочку знаков без обработки '^'. *)
ПЕР
  поз:ЦЕЛ;
  знак:ЗНАК;
УКАЗ
  ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
    знак:=цепь[поз];
    ЕСЛИ знак = 0X ТО ВОЗВРАТ КОН;
    ЗнакЦепи(поток,знак)
  КОН
КОН ЗнакиЦепи;

(******************************************************************************)
ЗАДАЧА ДлинаЦепь-(поток:Поток; цепь-:ЦЕПЬ);
(* Записывает длину и саму цепочку. *)
ПЕР
  длина:ЦЕЛ;
УКАЗ
  длина:=ДЛИНА(цепь);
  Ячейки(поток,длина,4);
  ЗнакиЦепи(поток,цепь)
КОН ДлинаЦепь;

(******************************************************************************)
ЗАДАЧА Цепь-(поток:Поток; цепь-:ЦЕПЬ);
(* Записывает цепочку знаков. '^' обозначает конец строки. *)
ПЕР
  поз:ЦЕЛ;
  знак:ЗНАК;
  былаВолна:КЛЮЧ;
УКАЗ
  былаВолна:=ОТКЛ;
  ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
    знак:=цепь[поз];
    ЕСЛИ знак = 0X ТО ВОЗВРАТ КОН;
    ЕСЛИ былаВолна ТО
      ЗнакЦепи(поток,знак);
      былаВолна:=ОТКЛ
    ИНАЧЕ
      ЕСЛИ знак = '^' ТО
        ЗнакЦепи(поток,0DX);
        ЗнакЦепи(поток,0AX);
        Сбросить(поток)
      АЕСЛИ знак = '~' ТО
        былаВолна:=ВКЛ
      ИНАЧЕ
        ЗнакЦепи(поток,знак)
      КОН
    КОН
  КОН
КОН Цепь;

(******************************************************************************)
ЗАДАЧА ЧЦел-(поток:Поток; описание-:ЦЕПЬ; ц0,ц1,ц2,ц3:ШИРЦЕЛ);
(* Записывает текст из 4-х целых чисел, используя заданное описание *)
ПЕР
  текст:ЦЕПЬ[200];
УКАЗ
  Текст.ИзЧЦел(описание,ц0,ц1,ц2,ц3,текст);
  Цепь(поток,текст);
КОН ЧЦел;

(******************************************************************************)
ЗАДАЧА ЧВещ-(поток:Поток; описание-:ЦЕПЬ; в0,в1,в2,в3:ШИРВЕЩ);
(* Записывает текст из 4-х вещественных чисел, используя заданное описание *)
ПЕР
  текст:ЦЕПЬ[200];
УКАЗ
  Текст.ИзЧВещ(описание,в0,в1,в2,в3,текст);
  Цепь(поток,текст);
КОН ЧВещ;

КОН Писать.
