(*~\Глагол\Отделы\Обмен\ВводВывод\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                        ОТДЕЛ ВФайл;
(*============================================================================*)
(* НАЗНАЧЕНИЕ:                                                                *)
(*   библиотечный отдел - запись в файл <поток> ВИДа <ДкПотоку>               *)
(* ПРИМЕЧАНИЯ:                                                                *)
(*   Для отложенной записи используется промежуточная память                  *)
(*                              (рПП:РядПромежуточнаяПамять;)                 *)
(*============================================================================*)

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

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

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

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


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)


(*-------------------------------------Общедоступные ЗАДАЧИ-------------------*)
ЗАДАЧА^
        Открыть-(имяфайла-:ЦЕПЬ):ВФайл.ДкПотоку;
ЗАДАЧА^
        Пополнить-(имяфайла-:ЦЕПЬ):ВФайл.ДкПотоку;
ЗАДАЧА^
        Сбросить-(потокД:ВФайл.ДкПотоку);
ЗАДАЧА^
        Закрыть-(потокД+:ВФайл.ДкПотоку);
ЗАДАЧА^
        Позиция-(потокД:ВФайл.ДкПотоку):ЦЕЛ;
ЗАДАЧА^
        СменаПозиции-(потокД:ВФайл.ДкПотоку; поз:ЦЕЛ);
ЗАДАЧА^
        Ячейки-(потокД:ВФайл.ДкПотоку; память-:ОБХОД.Ячейки; размер:ЦЕЛ);
ЗАДАЧА^
        ЗнакЦепи-(потокД:ВФайл.ДкПотоку; знак:ЗНАК);
ЗАДАЧА^
        ВсяЦепь-(потокД:ВФайл.ДкПотоку; цепь-:ЦЕПЬ); (* со всеми знаками '^', но без перехода на новую строку *)
ЗАДАЧА^
        ЦепьЗнаков-(потокД:ВФайл.ДкПотоку; цепь-:ЦЕПЬ); (* без знаков '^', но с переходом на новую строку.
                                                        Действие аналогично задаче  НаЭкран.ВсяЦепь() *)
ЗАДАЧА^
        ДлинаЦепи-(потокД:ВФайл.ДкПотоку; цепь-:ЦЕПЬ);
ЗАДАЧА^
        Цел4числа-(потокД:ВФайл.ДкПотоку; описание-:ЦЕПЬ; ц0,ц1,ц2,ц3:ШИРЦЕЛ);
ЗАДАЧА^
        Вещ4числа-(потокД:ВФайл.ДкПотоку; описание-:ЦЕПЬ; в0,в1,в2,в3:ШИРВЕЩ);
ЗАДАЧА^
        ВремяОтСтартаWindows-(потокД:ВФайл.ДкПотоку; сейчас:ЦЕЛ);
ЗАДАЧА^
        ВремяТекущее-(потокД:ВФайл.ДкПотоку);



(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


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

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

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

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

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

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

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

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

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

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

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

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

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

       ВФайл.ЦепьЗнаков(потокД,      цепочкаТекста);
КОН Цел4числа;

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

       ВФайл.ЦепьЗнаков(потокД,      цепочкаТекста);
КОН Вещ4числа;
<*КОН*>

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
(*
 * Вывод на экран (консоль Win32) времени [мсек] от старта Windows с шагом 15-16 мс,
 *                         однако замечено, что при запущенном AIMP3.exe шаг = 1 мс, хотя и не на всех компьютерах
 *               в приёмник <сейчас> в виде "часы: минуты: сек: сотые:"
 *)
ЗАДАЧА
       ВремяОтСтартаWindows-(потокД:ВФайл.ДкПотоку; сейчас:ЦЕЛ);
(*
       из задачи
                  ЗАДАЧА ОбновитьПоказания(номерЧасов:ЦЕЛ);
    в приложении
                 \Глагол\ПриложенияКОС\Иное\СекундомерКОС+.отд
 *)
ПЕР
(*времяОС,*)(* время в [мс], прошедшее от запуска Windows с шагом 16 мс *)
  сотые,    (*           сейчас ДЕЛИТЬ 10;  *)
  секунды,  (* секунды:= сотые  ДЕЛИТЬ 100; *)
  минуты,   (*  минуты:=секунды ДЕЛИТЬ 60;  *)
  часы:ЦЕЛ; (*    часы:= минуты ДЕЛИТЬ 60;  *)
УКАЗ
  сотые  := сейчас ДЕЛИТЬ 10;
  секунды:=  сотые ДЕЛИТЬ 100;
  минуты :=секунды ДЕЛИТЬ 60;
     часы:= минуты ДЕЛИТЬ 60;

ВФайл.Цел4числа(потокД,"%.2d:%.2d:%.2d.%.2d^",
     часы,
     минуты ОСТАТОК 60,
         секунды ОСТАТОК 60,
               сотые ОСТАТОК 100
              )
КОН ВремяОтСтартаWindows;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
(*
 * Вывод на экран (консоль Win32) текущего времени с шагом 15-16 мс
 *         однако замечено, что при запущенном AIMP3.exe шаг = 1 мс, хотя и не на всех компьютерах
 * из лок.переменной <сейчас> в виде "год:месяц:день: час:минута:сек:мс"
 *)
ЗАДАЧА
       ВремяТекущее-(потокД:ВФайл.ДкПотоку);
ПЕР
                     сейчас:ОС.нСейчас;
УКАЗ
       ОС.КоторыйЧас(сейчас);

ВФайл.Цел4числа(потокД,"%.4d-%.2d-%.2d ",
                     сейчас.год,
                         сейчас.месяц,
                              сейчас.день,
                            0
              );
ВФайл.Цел4числа(потокД,"%.2d:%.2d:%.2d.%.2d^",
                     сейчас.час,
                         сейчас.минута,
                                сейчас.секунда,
                                        сейчас.мсекунда
              )
КОН ВремяТекущее;

КОН ВФайл.
