OberonCore https://forum.oberoncore.ru/ |
|
Как оформлять копание в битах? https://forum.oberoncore.ru/viewtopic.php?f=2&t=112 |
Страница 1 из 1 |
Автор: | Trurl [ Вторник, 07 Февраль, 2006 11:45 ] |
Заголовок сообщения: | Как оформлять копание в битах? |
Предположим, нам надо передававать данные в определенном двочном формате. Какой вариант вам больше нравится? 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); |
Автор: | sacred [ Вторник, 07 Февраль, 2006 12:39 ] |
Заголовок сообщения: | Re: Как оформлять копание в битах? |
Trurl писал(а): Предположим, нам надо передававать данные в определенном двочном формате.
Какой вариант вам больше нравится? 3- й вариант совсем не нравится. Вот это место: INC(i) внутри процедуры. Нафиг нам побочные эффекты? Ну вообще 1-й вариант выглядит красивее всех. 2-й хуже из-за обилия дополнительных переменных. Но, хотя с другой стороны, это всё абстрактно, может в реальной задаче все эти переменные уже есть и тогда нет смысла их запихивать в запись. |
Автор: | Сергей Губанов [ Вторник, 07 Февраль, 2006 14:11 ] |
Заголовок сообщения: | Re: Как оформлять копание в битах? |
Я за третий вариант. Только, чуток, подкрутил бы: Код: 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 ] |
Заголовок сообщения: | |
По мне - первый либо третий. Первый - проще и наглядней всех остальных. У второго никаких преимуществ нет, при этом плодятся низкоуровневые VAL, в смещении каждого из которых можно ошибиться (опечататься) - предположим такую возможность ![]() Третий интересен попыткой обобщения. Однако ни в одном, кроме первого, описание структуры данных явно не фигурирует, что не есть хорошо... |
Автор: | Илья Ермаков [ Вторник, 07 Февраль, 2006 16:51 ] |
Заголовок сообщения: | |
А вообще говоря, обобщать нужно на уровне Writer, чтобы он принимал ANYREC, как это сделано в SqlDB.Exec и Table. |
Автор: | Сергей Губанов [ Вторник, 07 Февраль, 2006 17:44 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Writer, чтобы он принимал ANYREC
О! Вот так бы лучше всего!!! |
Автор: | Trurl [ Вторник, 07 Февраль, 2006 18:03 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Первый - проще и наглядней всех остальных. С первым вот какие проблемы. Разных форматов - порядка 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; |
Автор: | Trurl [ Вторник, 07 Февраль, 2006 18:06 ] |
Заголовок сообщения: | Re: Как оформлять копание в битах? |
Сергей Губанов писал(а): Я за третий вариант. Только, чуток, подкрутил бы:
Код: 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 хранил ссылку на массив. А так - бессмысленно. |
Автор: | Сергей Губанов [ Среда, 08 Февраль, 2006 12:01 ] |
Заголовок сообщения: | Re: Как оформлять копание в битах? |
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; ... |
Автор: | Иван Горячев [ Четверг, 09 Февраль, 2006 02:27 ] |
Заголовок сообщения: | Re: Как оформлять копание в битах? |
Ну тогда уж: Код: 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); ... |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |