OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 25 Апрель, 2024 17:26

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
 Заголовок сообщения: Как оформлять копание в битах?
СообщениеДобавлено: Вторник, 07 Февраль, 2006 11:45 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Предположим, нам надо передававать данные в определенном двочном формате.
Какой вариант вам больше нравится?

1
Код:
IMPORT S:=SYSTEM, ..
TYPE
  Req = RECORD
    opcode : BYTE;
    mode    : BYTE;
    length  : SHORTINT;
    window  : INTEGER;
  END;
  AReq = ARRAY SIZE(Req) OF BYTE;

VAR rq:Req;
  ...
  rq.opcode := opcode;
  rq.mode  := mode;
  rq.length := length;
  rq.window := window;

  stream.WriteBytes(S.VAL(AReq, rq), 0,SIZE(Req),res);


2
Код:
CONST szReq =8;
VAR rq: ARRAY szReq OF BYTE;
    opcode : BYTE;
    mode    : BYTE;
    length  : SHORTINT;
    window  : INTEGER;

  ix:=0;
  S.PUT(S.ADR(rq[0]),opcode);
  S.PUT(S.ADR(rq[1]),mode);
  S.PUT(S.ADR(rq[2]),length);
  S.PUT(S.ADR(rq[4]),window);
  stream.WriteBytes(rq, 0,szReq,res);


3
Код:
CONST szReq =8;

  PROCEDURE WInt8(VAR b:ARRAY OF BYTE; VAR i: INTEGER; x: INTEGER);
  BEGIN
    b[i]:= SHORT(SHORT(x)); INC(i)
  END WInt8;
  ...

  VAR rq: ARRAY szReq OF BYTE;
    ix: INTEGER;

  ix:=0;
  WInt8(rq,ix,opcode);
  WInt8(rq,ix,mode);
  WInt16(rq,ix,length);
  WInt32(rq,ix,window);
  stream.WriteBytes(rq, 0,szReq,res);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как оформлять копание в битах?
СообщениеДобавлено: Вторник, 07 Февраль, 2006 12:39 
Аватара пользователя

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 13:17
Сообщения: 84
Откуда: Россия, Мурманск
Trurl писал(а):
Предположим, нам надо передававать данные в определенном двочном формате.
Какой вариант вам больше нравится?


3- й вариант совсем не нравится. Вот это место: INC(i) внутри процедуры. Нафиг нам побочные эффекты?

Ну вообще 1-й вариант выглядит красивее всех. 2-й хуже из-за обилия дополнительных переменных. Но, хотя с другой стороны, это всё абстрактно, может в реальной задаче все эти переменные уже есть и тогда нет смысла их запихивать в запись.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как оформлять копание в битах?
СообщениеДобавлено: Вторник, 07 Февраль, 2006 14:11 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Я за третий вариант. Только, чуток, подкрутил бы:
Код:
TYPE
  Writer* = RECORD
    offset*: INTEGER
  END;

  PROCEDURE (VAR this: Writer) WriteByte* (VAR dst: ARRAY OF BYTE; value: BYTE), NEW;
  BEGIN dst[this.offset] := value; INC(this.offset)
  END WriteByte;


wr.offset := 12;
wr.WriteByte(buffer, value1);
wr.WriteShort(buffer, value2);
wr.WriteInt(buffer, value3);

Модуль с таким Writer (и соответствующим Reader) можно потом повторно использовать для различных целей...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 07 Февраль, 2006 16:50 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
По мне - первый либо третий.

Первый - проще и наглядней всех остальных.
У второго никаких преимуществ нет, при этом плодятся низкоуровневые VAL, в смещении каждого из которых можно ошибиться (опечататься) - предположим такую возможность :-)

Третий интересен попыткой обобщения.

Однако ни в одном, кроме первого, описание структуры данных явно не фигурирует, что не есть хорошо...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 07 Февраль, 2006 16:51 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
А вообще говоря, обобщать нужно на уровне Writer, чтобы он принимал ANYREC, как это сделано в SqlDB.Exec и Table.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 07 Февраль, 2006 17:44 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Илья Ермаков писал(а):
Writer, чтобы он принимал ANYREC


О! Вот так бы лучше всего!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вторник, 07 Февраль, 2006 18:03 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Илья Ермаков писал(а):
Первый - проще и наглядней всех остальных.

С первым вот какие проблемы.
Разных форматов - порядка 100.
Некоторые имеют поле переменной длины – наглядность теряется.
Надо тщательно следить за выравниванием.

Цитата:
А вообще говоря, обобщать нужно на уровне Writer, чтобы он принимал ANYREC, как это сделано в SqlDB.Exec и Table.

Ну, что-то в этом роде есть
Код:
 PROCEDURE WRec(VAR b:ARRAY OF BYTE; VAR ix: INTEGER; IN r:ANYREC);
 VAR size: INTEGER;
 BEGIN
   S.GET(S.TYP(r),size);
   S.MOVE(S.ADR(r), S.ADR(b[ix]), size);
   INC(ix,size);
 END WRec;
 


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как оформлять копание в битах?
СообщениеДобавлено: Вторник, 07 Февраль, 2006 18:06 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
Сергей Губанов писал(а):
Я за третий вариант. Только, чуток, подкрутил бы:
Код:
TYPE
  Writer* = RECORD
    offset*: INTEGER
  END;

  PROCEDURE (VAR this: Writer) WriteByte* (VAR dst: ARRAY OF BYTE; value: BYTE), NEW;
  BEGIN dst[this.offset] := value; INC(this.offset)
  END WriteByte;



Это было бы хорошо, если бы Writer хранил ссылку на массив. А так - бессмысленно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как оформлять копание в битах?
СообщениеДобавлено: Среда, 08 Февраль, 2006 12:01 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Trurl писал(а):
бессмысленно.


Код:
TYPE
  Packet* = RECORD
    length-: INTEGER;
    pos-: INTEGER;
    buff-: ARRAY 32768 OF BYTE (* столько хватит? *)
  END;

  PROCEDURE (VAR this: Packet) Clear*, NEW;
    VAR i: INTEGER;
  BEGIN this.length := 0; this.pos := 0;
    FOR i := 0 TO LEN(this.buff)-1 DO this.buff[i] := 0 END
  END Clear;

  PROCEDURE (VAR this: Packet) WriteByte* (value: BYTE), NEW;
  BEGIN ASSERT(this.pos < LEN(this.buff));
    this.buff[this.pos] := value; INC(this.pos);
    IF this.length < this.pos THEN this.length := this.pos END
  END WriteByte;

  PROCEDURE (VAR this: Packet) SetPos* (pos: INTEGER), NEW;
  ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как оформлять копание в битах?
СообщениеДобавлено: Четверг, 09 Февраль, 2006 02:27 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 10:37
Сообщения: 875
Откуда: Россия, Владивосток
Ну тогда уж:
Код:
TYPE
  Packet* = RECORD
    pos- : INTEGER; (* оно же length, обойдёмся без Seek() *)
    data- : POINTER TO ARRAY OF BYTE;
  END;

PROCEDURE (VAR p : Packet) Init* (length : INTEGER), NEW;
PROCEDURE (VAR p : Packet) WriteByte* (x : BYTE), NEW;
...
PROCEDURE SendPacket* (stream : Stream; p : Packet);
...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB