AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherung von Sets... ?!?

Ein Thema von Kedariodakon · begonnen am 28. Feb 2005 · letzter Beitrag vom 5. Mai 2009
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Kedariodakon
Kedariodakon

Registriert seit: 10. Sep 2004
Ort: Mönchengladbach
833 Beiträge
 
Delphi 7 Enterprise
 
#1

Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 14:28
Wie speichert man Sets (z.b. als wert oder ka wie)?
Und wie speichert das Delphi im Speicher???

Ich hab folgendes:
Delphi-Quellcode:
Type
  TWeekday = ( wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday );
  TWeekdays = Set Of TWeekday;
Wenn ich nun so ein set habe: [wdMonday, wdWednesday, wdFriday ]
muss das doch wie gespeichert sein, nur wie?



Bye
Christian
  Mit Zitat antworten Zitat
xineohp

Registriert seit: 29. Jan 2004
Ort: Heusenstamm
420 Beiträge
 
Delphi 2005 Professional
 
#2

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 14:34
moin,

meines Wissens sind Sets ordinale Typen, d.h. jedes Element entspricht einer Zahl. Deswegen kann man sie auch in Case-Abfragen verwenden.
Peter Enenkel
blubb
  Mit Zitat antworten Zitat
Benutzerbild von Binärbaum
Binärbaum

Registriert seit: 19. Jan 2005
Ort: Elstra
764 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 14:42
Ja, Sets gibt es nur für ordinale Typen. Deswegen könnte man auch die Ordinalwerte der im Set vorhandenen Elemente in einer Datei speichern un diese auch wieder laden.
In deinem Beispiel entspricht wdMonday dem Wert 0, wdTuesday entspricht 2, ..., wdSunday entspricht 6.
Man könnte damit sogar rechenen:
Delphi-Quellcode:
var test1: TWeekday;
begin
  test1:= wdTuesday;
  test1:= TWeekday(Ord(test1) + Ord(wdTuesday)+ Ord(wdFriday));
  //test1 ist jetzt wdSunday
end;
MfG
Binärbaum
There are exactly 10 kinds of people: those who understand binary, and those who don't.
---
"Software reift beim Kunden. Bei Hardware ist es anders: Hardware fault beim Kunden." - Rainer G. Spallek
  Mit Zitat antworten Zitat
Benutzerbild von Kedariodakon
Kedariodakon

Registriert seit: 10. Sep 2004
Ort: Mönchengladbach
833 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:21
Ich glaun ich habs raus...


cmd1 = TButton
txt1 = TMemo

Delphi-Quellcode:
Procedure TfrmMain.cmd1Click(Sender: TObject);

   Function   GetValue( Const WD: TQWeekdays ):   Cardinal;
   Begin
      Case   SizeOf( wd )   Of
         1:   Result   := Cardinal( (@wd)^ ) And $000000ff;
         2:   Result   := Cardinal( (@wd)^ ) And $0000ffff;
         3:   Result   := Cardinal( (@wd)^ ) And $00ffffff;
         4:   Result   := Cardinal( (@wd)^ ) And $ffffffff;
      Else Result   := 0;
      End;
   End;

   Function InfoStr( Const WD: TQWeekdays ): String;
   Begin
      Result   :=   #9'Size:'#9      + IntToStr( SizeOf(   WD ) )   + #13#10 +
                        #9'Value:'#9   + IntToStr( GetValue(   WD ) );
   End;

Begin
   txt1.Clear;

   txt1.Lines.Append(   '[ ]'#13#10
                                 +   InfoStr( [ ] ) );

   txt1.Lines.Append(   '[ wdMonday ]'#13#10
                                 +   InfoStr( [ wdMonday ] ) );

   txt1.Lines.Append(   '[ wdTuesday ]'#13#10
                                 +   InfoStr( [ wdTuesday ] ) );

   txt1.Lines.Append(   '[ wdWednesday ]'#13#10
                                 +   InfoStr( [ wdWednesday ] ) );

   txt1.Lines.Append(   '[ wdThursday ]'#13#10
                                 +   InfoStr( [ wdThursday ] ) );

   txt1.Lines.Append(   '[ wdFriday ]'#13#10
                                 +   InfoStr( [ wdFriday ] ) );

   txt1.Lines.Append(   '[ wdSaturday ]'#13#10
                                 +   InfoStr( [ wdSaturday ] ) );

   txt1.Lines.Append(   '[ wdSunday ]'#13#10
                                 +   InfoStr( [ wdSunday ] ) );


   txt1.Lines.Append( #13#10#13#10 );


   txt1.Lines.Append(   '[ wdMonday, wdTuesday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday ] ) );

   txt1.Lines.Append(   '[ wdMonday, wdTuesday, wdWednesday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday , wdWednesday ] ) );

   txt1.Lines.Append(   '[ wdMonday, wdTuesday, wdWednesday, wdThursday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday, wdWednesday, wdThursday ] ) );

   txt1.Lines.Append(   '[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday ] ) );

   txt1.Lines.Append(   '[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday ] ) );

   txt1.Lines.Append(   '[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday ]'#13#10
                                 +   InfoStr( [ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday ] ) );
End;
Ergebniss:
Code:
[  ]
   Size:   1
   Value:   0
[ wdMonday ]
   Size:   1
   Value:   1
[ wdTuesday ]
   Size:   1
   Value:   2
[ wdWednesday ]
   Size:   1
   Value:   4
[ wdThursday ]
   Size:   1
   Value:   8
[ wdFriday ]
   Size:   1
   Value:   16
[ wdSaturday ]
   Size:   1
   Value:   32
[ wdSunday ]
   Size:   1
   Value:   64



[ wdMonday, wdTuesday ]
   Size:   1
   Value:   3
[ wdMonday, wdTuesday, wdWednesday ]
   Size:   1
   Value:   7
[ wdMonday, wdTuesday, wdWednesday, wdThursday ]
   Size:   1
   Value:   15
[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday ]
   Size:   1
   Value:   31
[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday ]
   Size:   1
   Value:   63
[ wdMonday, wdTuesday, wdWednesday, wdThursday, wdFriday, wdSaturday, wdSunday ]
   Size:   1
   Value:   127
Scheinbar macht es Delphi so..
lieg ich da richtig?

Dann könnt ich das eigendlich so spiechern oder?

Bye


Edit:

Bei der Funktion GetValue
Greif ich atm auf speicher zu der mir nix angeht, jedenfalls wenn Size <> 4 ist...
Könnte ich da Probleme bekommen?
Christian
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#5

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:25
Ja, ordinal geht es prima, aber am schönsten mit strings. Die unit TypeInfo hat zwei funktionen die das konvertieren von set-properties beherrschen. Leider ist das auf auf properties spezialisiert. Ich hatte das mal entspezialisiert, sodass es mit normalen typeInfos geht:

Delphi-Quellcode:
uses typInfo, RTLConsts;
...

function SetToStr(SetTypeInfo:PTypeInfo;value:integer;Brackets:boolean=true):string;
var
  S: TIntSet;
  TypeInfo: PTypeInfo;
  compTypeDate: PTypeData;
  I: Integer;
begin
   Result := '';
  Integer(S) := Value;
  TypeInfo := GetTypeData(SetTypeInfo)^.CompType^;
  compTypeDate := GetTypeData(TypeInfo);
  for I := compTypeDate.MinValue to compTypeDate.MaxValue do
    if I in s then
    begin
      if Result <> 'then
        Result := Result + ',';
      Result := Result + GetEnumName(TypeInfo, I);
    end;
  if Brackets then Result := '[' + Result + ']';
end;


function StrToSet(SetTypeInfo:PTypeInfo; const Value: string): Integer;
var
  P: PChar;
  EnumName: string;
  EnumValue: Longint;
  EnumInfo: PTypeInfo;

  // grab the next enum name
  function NextWord(var P: PChar): string;
  var
    i: Integer;
  begin
    i := 0;

    // scan til whitespace
    while not (P[i] in [',', ' ', #0,']']) do
      Inc(i);

    SetString(Result, P, i);

    // skip whitespace
    while P[i] in [',', ' ',']'] do
      Inc(i);

    Inc(P, i);
  end;

begin
   Result := 0;
  if Value = 'then Exit;
  P := PChar(Value);

  // skip leading bracket and whitespace
   while P^ in ['[',' '] do
      Inc(P);

   EnumInfo := GetTypeData(SetTypeInfo)^.CompType^;
   EnumName := NextWord(P);
  while EnumName <> 'do
  begin
    EnumValue := GetEnumValue(EnumInfo, EnumName);
    if EnumValue < 0 then
         raise EPropertyConvertError.CreateResFmt(@SInvalidPropertyElement, [EnumName]);
    Include(TIntegerSet(Result), EnumValue);
    EnumName := NextWord(P);
  end;
end;
Damit kann man super leicht konverieren:

Delphi-Quellcode:
type
  T8BitSet = set of (bit_0, bit_1, bit_2, bit_3, bit_4, bit_5, bit_6, bit_7);
...
var
   Bits:T8BitSet;
   s:string;
begin
   Bits := [bit_2, bit_4, bit_7];
   ...
  s := setToStr(typeInfo(T8BitSet), PInteger(@Bits)^, true);
  ..
   PInteger(@Bits)^ := strToSet(typeInfo(T8BitSet), s);
end;
Entsprechend leicht dürfte das speichern in eine datei sein -> stringStream oder so.

Und wenn es hier nicht gebraucht wird, dann sicher später von jemand anderem!


//edit:
PS:@Kedariodakon: Du hast quasi gerade entdeckt, dass jeder eintrag in einem set einem bit entspricht...was auch logisch und effizient ist.
//edit2: blöde pointer
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
Benutzerbild von Kedariodakon
Kedariodakon

Registriert seit: 10. Sep 2004
Ort: Mönchengladbach
833 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:31
öhm sieht ja mega kompliziert aus

Ich glaub ich mach das so wie es auch delphi macht...
Auslesen ist ja nicht soooo schwer, wie oben in meinem Test bewiesen, aber beim Speichern weiß ich noch nicht wie ich das mach...


Kann man einfach für den Pointer der SetVariable Speicher hollen mit GetMem ???
Oder ist die Variable von sich aus schon so groß wie das max Set?


Bye
Christian
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#7

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:35
Zitat von maximov:
Ja
...Damit kann man super leicht konverieren:

Delphi-Quellcode:
type
  T8BitSet = set of (bit_0, bit_1, bit_2, bit_3, bit_4, bit_5, bit_6, bit_7);
...
var
   Bits:T8BitSet;
   s:string;
begin
   Bits := [bit_2, bit_4, bit_7];
   ...
  s := setToStr(typeInfo(T8BitSet), PInteger(@Bits)^, true);
  ..
   PInteger(@Bits)^ := strToSet(typeInfo(T8BitSet), s);
end;
Entsprechend leicht dürfte das speichern in eine datei sein -> stringStream oder so.
...

das findest du komplzier? Das musst du mir erklären? Ich würde eher sagen dein gelöt von oben ist kompliziert, bzw. redundant.

Übrigens ist das die delphi-lösung, die auch das DFM-Streaming-system verwendet!


PS: Die beiden funktionen oben SetToStr und StrToSet sind komplett implementiert und können ohne jegliches verständnis benutzt werden
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
Benutzerbild von Kedariodakon
Kedariodakon

Registriert seit: 10. Sep 2004
Ort: Mönchengladbach
833 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:45
Zitat von maximov:
Übrigens ist das die delphi-lösung, die auch das DFM-Streaming-system verwendet
KA was das ist

Ich find es in der hinsicht kompliziert, dass ich zum speichern eines Sets von Wochentagen auf sowas "komplizertes" soll/muß/kann...

Warum z.b. muß ich zum speichern/laden eines Sets in der RTTI rumwusseln, wenn jedes Element eines Types ein Bit darstellt

Aber nichts für ungut, ich werd mich mit dem Codeschnippsel heut abend mal beschäftigen, vielleicht lern ich was daraus

Bye

Edit: DFM-Streaming-system = Das speichern/laden von Published OBjectPropertys als String. Richtig?
Christian
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#9

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:52
Zitat von Kedariodakon:
...Warum z.b. muß ich zum speichern/laden eines Sets in der RTTI rumwusseln, wenn jedes Element eines Types ein Bit darstellt
...
Weil die RTTI ein segen ist Bei den wochentagen ist es evtl nicht wichtig, weil keine mehr dazu kommen können, aber in einem anderen set könnte es passieren, das elemente eingefügt werden. Läd man die daten dann wieder binär, haben element ihren wert verloren, da alles verrutscht ist. Wenn allerdings jedes element eindeutig benannt ist, so ist dies kein problem. Deshalb auch RTTI, denn dort die namen der elemente

@DFM-Streaming: DFM dateien? schon mal gesehen ...da werdenn auch sets gespeichert, die du zB. im OI eingestellt hast.
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#10

Re: Speicherung von Sets... ?!?

  Alt 28. Feb 2005, 15:54
PS:
wenn dir das egal ist und du es dennoch binär speichern willst, dann kannst du es so als integer machen:
i := PInteger(@Bits)^;
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz