OberonCore
https://forum.oberoncore.ru/

Использование Stores
https://forum.oberoncore.ru/viewtopic.php?f=23&t=6513
Страница 1 из 1

Автор:  Александр К [ Пятница, 13 Декабрь, 2019 16:49 ]
Заголовок сообщения:  Использование Stores

Как при помощи модуля Stores сохранить два списка (один вложен в другой)? Как я понимаю придётся циклически перебирать оба списка и сохранять их поля, а потом аналогичным способом восстанавливать при загрузке. Надо ли использовать Stores.Writer.WriteStore? Из модуля ObxStores непонятно, как использовать WriteStore для списков.
Код:
TYPE
   myKey = POINTER TO RECORD
      day, month, year: BYTE;
      price: SHORTREAL;
      next: myKey;
   END;
   turn = POINTER TO RECORD (Stores.Store)
      name: ARRAY 256 OF CHAR;
      key: myKey;
      firstKey: myKey;
      next: turn;
   END;

PROCEDURE (t: turn) Externalize (VAR w: Stores.Writer);
VAR
   auxiliaryNames: turn;
   auxiliaryKeys: myKey;
BEGIN
   StdLog.String ("Сохраняю");
   auxiliaryNames := t;
   WHILE auxiliaryNames # NIL DO
      w.WriteString (auxiliaryNames.name);
      auxiliaryKeys := auxiliaryNames.firstKey;
      WHILE auxiliaryKeys # NIL DO
         w.WriteByte (auxiliaryKeys.day);
         w.WriteByte (auxiliaryKeys.month);
         w.WriteByte (auxiliaryKeys.year);
         w.WriteSReal (auxiliaryKeys.price);
         auxiliaryKeys := auxiliaryKeys.next
      END;
      auxiliaryNames := auxiliaryNames.next
   END
END Externalize;

Автор:  adimetrius [ Пятница, 13 Декабрь, 2019 18:33 ]
Заголовок сообщения:  Re: Использование Stores

Stores гарантирует, что можно многократно сохранять один и тот же Store, а в выходной файл попадет только 1 экземпляр данных; при это при многократном чтении будет возвращаться один и тот же указатель. Но для этого нужно, чтобы MyKey был расширением Stores.Store. Иначе вам придется самостоятельно обеспечивать "недублирование" - т.е. по сути делать тот же Stores, но только для своего списка. Я бы сделал на базе Stores вот так:

Код:
TYPE MyKey = POINTER TO RECORD (Stores.Store) ... END;

PROCEDURE WriteList (t: Turn; w: Stores.Writer);
BEGIN
  WHILE t # NIL DO w.WriteStore(t); t := t.next END;
  w.WriteStore(NIL)
END WriteList;

PROCEDURE WriteKeys(k: MyKey; wr: Stores.Writer);
BEGIN
  WHILE k # NIL DO wr.WriteStore(k); k := k.next END;
  wr.WriteStore(NIL)
END WriteKeys;

PROCEDURE (t: Turn) Externalize (VAR w: Stores.Writer);
  VAR auxiliaryKeys: MyKey;
BEGIN
  w.WriteString (t.name); WriteKeys(t.firstKey, w)
END Externalize;

PROCEDURE (k: MyKey) Externalize (VAR wr: Stores.Writer);
BEGIN
  w.WriteByte (auxiliaryKeys.day);
  w.WriteByte (auxiliaryKeys.month);
  w.WriteByte (auxiliaryKeys.year);
  w.WriteSReal (auxiliaryKeys.price)
END Externalize;


Тогда чтение можно организовать по такой схеме:

Код:
REPEAT rd.ReadStore(st);
  IF st # NIL THEN ASSERT(st IS Turn, 20);
    (* append store to the end of list *)
  END
UNTIL st = NIL

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/