Как использовать бит / бит-оператор для управления состоянием объекта? - PullRequest
5 голосов
/ 05 февраля 2009

Я хочу создать пакет данных легких объектов для передачи между клиентскими и серверными приложениями.

Это настолько простая задача, что я могу управлять только 1 байтом, поэтому каждый бит в байте будет иметь различное значение,

Использование только бита

0 = False 
1 = True

Itens мне нужно сейчас:

1 - Loaded from database 
2 - Persisted
3 - Changed
4 - Marked to Delete
5 -
6 - 
7 - Null Value 
8 - Read Only


1) How do I use bit operators in Delphi to check each bit value? 
2) How do I set the bit Values?

Решение

После того, как все поможет, я буду использовать следующий набор

  TStateType = (
    stLoaded    = 0,   // loaded from persistance
    stNative    = 2,   // value loaded and converted to native type
    stPersisted = 3,   // saved
    stChanged   = 4,   // object or member changed
    stToDelete  = 5,   // marked to delete
    stReadOnly  = 6,   // read only object, will not allow changes
    stNull      = 7    // value is null
  );
  TState = Set of TStateType;

А для потока -> персистентность, это будет запись, которая будет использоваться:

  TDataPackage = record
    Data: TBytes;
    TypeInfo: TMetaInfo;
    State: Byte;
    Instance: TBuffer;
  end;

Спасибо ребята, за все ответы и комментарии.

Ответы [ 3 ]

7 голосов
/ 05 февраля 2009

Я бы действительно использовал набор для этого. Тем не менее, я вижу, вы действительно хотите байт. Повсюду используйте наборы, а в конце введите тип байта.

Это решение потребует гораздо меньшего набора текста, имеет поддержку стандартных операторов delphi и действительно не несет потери производительности, как отметил Барри Келли.

procedure Test;
type
  TSetValues = (
    TSetValue1   = 0,
    TSetValue2   = 1,
    TSetValue4   = 2,
    TSetValue8   = 3,
    TSetValue16  = 4,
    TSetValue32  = 5,
    TSetValue64  = 6,
    TSetValue128 = 7
  );

  TMySet = set of TSetValues;
var
  myValue: byte;
  mySet: TMySet;
begin
  mySet := [TSetValue2, TSetValue16, TSetValue128];
  myValue := byte(mySet);
  ShowMessage(IntToStr(myValue)); // <-- shows 146
end;
6 голосов
/ 05 февраля 2009

Я бы использовал для этого набор:

type
    TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...);
    TMyData = set of TMyDatum;

var
  Foo: TMyData;
begin 
  Foo := [mdLoaded, mdChanged];
  if (mdPersisted in Foo) then ...

Они реализованы как целые числа, поэтому вы можете легко их передать. И я нахожу код намного, намного более читабельным, чем побитовые операторы.

1 голос
/ 05 февраля 2009

Эта страница описывает операторы Delphi, включая побитовые операторы.

Похоже, вам нужно использовать оператор и. Например:

const
  LOADED_FROM_DATABASE = 1;
  PERSISTED = 2;
  CHANGED = 4;
  // etc...

//...

if (bitFlags and LOADED_FROM_DATABASE) <> 0 then
begin
  // handle LOADED FROM DATABASE
end;

if (bitFlags and PERSISTED) <> 0 then
begin
  // handle PERSISTED
end;

// etc...

Чтобы установить флаги, вы можете использовать ИЛИ:

bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED;
...