unit numlist;
{$I define.pas}
{ $I nodebug.pas}
interface
uses mytype;

procedure StringToSetOfByte(AString:String; var ASet:SetOfByte; ADelimitors:SetOfChar);
procedure SetOfByteToString(ASet:SetOfByte; var AString:string; ADelimitor:Char);
function NumberIsInList(ANumber:longint; AList:string):boolean;

implementation
uses
  strstrm, stru;

function NumberIsInList(ANumber:longint; AList:string):boolean;
var
  s: TStringStream;
  s1,s2: string[15];
  i1, i2:longint;
  b: longint;
  st: string;
  code:integer;
begin
  NumberIsInList := false;
  s.init(AList);
  s.SetDelimitors([' ',',']);
  while s.readstring(st) do begin
    b := pos('-',st);
    if b = 0 then begin
      if st <> ''  then begin
        val(st, b, code);
        NumberIsInList := (code = 0) and (b = ANumber);
      end;
    end else begin
      s1 := copy(st, 1, b - 1);
      s2 := copy(st, b + 1, 255);
      val(s1, i1, code);
      val(s2, i2, code);
      if s1 = '' then
        i1 := 0;
      if s2 = '' then
        i2 := MaxLongint;
      NumberIsInList := (ANumber >= i1) and (ANumber <= i2);
    end;
  end;
  s.done;
end;


procedure StringToSetOfByte(AString:String; var ASet:SetOfByte; ADelimitors:SetOfChar);
var
  s:TStringStream;
  s1,s2:string[3];
  i1,i2:integer;
  b:byte;
  st:string;
begin
  s.init(AString);
  s.SetDelimitors(ADelimitors{[' ',',']});
  ASet := [];
  while s.readstring(st) do begin
    b := pos('-',st);
    if b = 0 then begin
      if st <> ''  then begin
        b := StrToInt(st);
        ASet := ASet + [b];
      end;
    end else begin
      s1 := copy(st, 1, b - 1);
      s2 := copy(st, b + 1, 255);
      i1 := StrToInt(s1);
      i2 := StrToInt(s2);
      if (i1 < 0) then
        i1 := 0;
      if i1 > 255 then
        i1 := 255;
      if i2 < 0 then
        i2 := 0;
      if i2 > 255 then
        i2 := 255;
      if s1 = '' then
        i1 := 0;
      if s2 = '' then
        i2 := 255;
      for b := i1 to i2 do
        ASet := ASet + [b];
    end;
  end;
  s.done;
end;

procedure SetOfByteToString(ASet:SetOfByte; var AString:string; ADelimitor:Char);
var
  s:TStringStream;
  i:byte;
  CountInRow:byte;
  FirstInRow:integer;

  procedure WriteCount;
  begin
    if CountInRow > 1 then begin
      s.WriteString(IntToStr(FirstInRow) + '-' + IntToStr(FirstInRow + CountInRow - 1));
    end else if CountInRow = 1 then
      s.WriteInteger(FirstInRow);
  end;

begin
  s.init('');
  s.setDelimitor(ADelimitor);
  FirstInRow := -1;
  CountInRow := 0;
  for i := 0 to 255  do begin
    if i in ASet then begin
      if FirstInRow = -1 then begin
        FirstInRow := i;
        CountInRow := 1;
      end else begin
        if i > FirstInRow + CountInRow then begin
          WriteCount;
          FirstInRow := i;
          CountInRow := 1;
        end else begin
          inc(CountInRow);
        end;
      end;
    end;
  end;
  WriteCount;
  AString := s.GetBuffer;
  s.Done;{strstrm}
end;

end.
