Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: sorry if wrong place to post - help needed



Permlink Replies: 2 - Last Post: Apr 11, 2016 2:12 PM Last Post By: Remy Lebeau (Te...
Adam Allen

Posts: 10
Registered: 4/26/01
sorry if wrong place to post - help needed
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 10, 2016 9:44 AM
I have this code porting from Delphi 2006 to Delphi XE 10,
but I get error on line
raise Exception.Create('Some Find parameters missing.');

I really appreciate any help
Thank you

function TSortList.FindKey(const Values:array of const):boolean;
var
I:integer;
P:byte;
S:ShortString;
d:double;
OldPos:integer;
ls:boolean;
begin
// Fill scan-string "s"
SetLength(s,FISize); P:=1; ls:=False;
for I := 0 to High(Values) do
with Values[I] do case VType of
vtInteger: // Long integer (small and short integer not supported as index fields)
begin
System.Move(VInteger,S[P],SizeOf(VInteger));
Inc(P,SizeOf(VInteger));
end;
vtCurrency: // Double (default Float type)
begin
System.Move(VCurrency,S[P],SizeOf(VCurrency^));
Inc(P,SizeOf(VCurrency^));
end;
vtExtended: // Extended type not supported, always converted to Double !
begin
d:=VExtended^;
System.Move(d,S[P],SizeOf(d));
Inc(P,SizeOf(d));
end;
vtChar:
begin
System.Move(VChar,S[P],SizeOf(VChar));
Inc(P,SizeOf(VChar));
end;
vtPChar,vtAnsiString: // Long string (only the last field in index can be of ShortString type)
begin
S[P]:=AnsiChar(Length(String(VPChar)));
System.Move(String(VPChar)[1],S[P+1],Length(String(VPChar)));
Inc(P,Length(String(VPChar))+1);
ls:=I=High(Values);
end;
vtString: // Short string (only the last field in index can be of ShortString type)
begin
S[P]:=AnsiChar(Length(VString^));
System.Move(VString^[1],S[P+1],Length(VString^));
Inc(P,Length(VString^)+1);
ls:=I=High(Values);
end;
vtBoolean: // Boolean not recommended as index field
begin
System.Move(VBoolean,S[P],SizeOf(VBoolean));
Inc(P,SizeOf(VBoolean));
end;
end;
if P<=FISize then
begin
if ls then
FillChar(S[P],FISize-P+1,#0) // Clear the rest
else
raise Exception.Create('Some Find parameters missing.');
end
else if P>FISize+1 then
raise Exception.Create('Too many Find parameters.');

// Start searching ...
OldPos:=FRecNo;
if Find(s) then
begin
FEoF:=False;
FBoF:=False;
ReadRecord;
Result:=True;
end
else
begin
FRecNo:=OldPos;
Result:=False;
end;
end;

Linden ROTH

Posts: 467
Registered: 11/3/11
Re: sorry if wrong place to post - help needed
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 10, 2016 1:54 PM   in response to: Adam Allen in response to: Adam Allen
Adam Allen wrote:
I have this code porting from Delphi 2006 to Delphi XE 10,
but I get error on line
raise Exception.Create('Some Find parameters missing.');

I really appreciate any help
Thank you

At the very least can you say what error ... and when compile time / run time

for future reference look at the { code } tags eg

  if P<=FISize then
    begin
      if ls then
        FillChar(S[P],FISize-P+1,#0) // Clear the rest
      else
        raise Exception.Create('Some Find parameters missing.');
      end


--
Linden
"Mango" was Cool but "Wasabi" was Hotter but remember it's all in the "source"
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sorry if wrong place to post - help needed
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 11, 2016 2:12 PM   in response to: Adam Allen in response to: Adam Allen
Adam wrote:

but I get error on line
raise Exception.Create('Some Find parameters missing.');

What kind of error exactly? Please be more specific.

If it is a compile-time error, the only way that line can fail to compile
is if you do not have the SysUtils unit in your 'uses' clause.

If it is a run-time error, you do realize that you are actually raising an
exception, don't you? It is supposed to be reported as an error.

Or, is your REAL question asking what conditions can make your code reach
that line in the first place? If so, your case statements are not handling
Unicode data at all. You need to add case statements for vtWideChar, vtPWideChar,
and vtUnicodeString (and optionally vtWideString). Remember that Delphi's
native String type switched from Ansi to Unicode in D2009.

There are other mistakes in your existing case statements, in particular
in regards to AnsiString values.

Try something more like this instead:

function TSortList.FindKey(const Values: array of const): Boolean;
var
  I: Integer;
  P, Len: Integer;
  S: ShortString;
  Tmp: AnsiString;
  d: Double;
  OldPos: Integer;
  ls: Boolean;
 
  procedure CheckSizeAvailable(Needed: Integer);
  begin
    if (P+Needed) > FISize then
      raise Exception.Create('Too many Find parameters.');
  end;
 
begin
  // Fill scan-string "s"
  SetLength(s, FISize);
  P := 1;
  ls := False;
 
  for I := Low(Values) to High(Values) do
  begin
    with Values[I] do
    begin
      case VType of
        vtInteger:    // Long integer (small and short integer not supported 
as index fields)
        begin 
          CheckSizeAvailable(SizeOf(VInteger));
          System.Move(VInteger, S[P], SizeOf(VInteger));
          Inc(P, SizeOf(VInteger));
        end;
        vtBoolean:    // Boolean not recommended as index field
        begin
          CheckSizeAvailable(SizeOf(VBoolean));
          System.Move(VBoolean, S[P], SizeOf(VBoolean));
          Inc(P, SizeOf(VBoolean));
        end;
        vtChar:  // Single AnsiChar
        begin
          CheckSizeAvailable(SizeOf(VChar));
          System.Move(VChar, S[P], SizeOf(VChar));
          Inc(P, SizeOf(VChar));
        end;
        vtExtended:    // Extended type not supported, always converted to 
Double !
        begin
          CheckSizeAvailable(SizeOf(d));
          d := VExtended^;
          System.Move(d, S[P], SizeOf(d));
          Inc(P, SizeOf(d));
        end;
        vtString:    // Short string (only the last field in index can be 
of ShortString type)
        begin
          Len := Min(Length(VString^), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          if Len > 0 then System.Move(VString^[1], S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtPChar:    // Null-terminated Long string (only the last field in 
index can be of ShortString type)
        begin
          Len := Min(StrLen(VPChar), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(VPChar^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtWideChar:   // Single WideChar
        begin
          // how do you want to handle Unicode?  Store it as-is, or convert 
it to Ansi? This code
          // is converting to Ansi to maintain compatibility with your other 
statements...
          Tmp := AnsiString(UnicodeString(VWideChar));
          Len := Min(Length(Tmp), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(PAnsiChar(Tmp)^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtPWideChar:    // Null-terminated Unicode string (only the last 
field in index can be of ShortString type)
        begin
          // how do you want to handle Unicode?  Store it as-is, or convert 
it to Ansi? This code
          // is converting to Ansi to maintain compatibility with your other 
statements...
          Tmp := AnsiString(UnicodeString(VPWideChar));
          Len := Min(Length(Tmp), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(PAnsiChar(Tmp)^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtAnsiString:    // Long string (only the last field in index can 
be of ShortString type)
        begin
          Len := Min(Length(PAnsiString(VAnsiString)^), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(PAnsiChar(PAnsiString(VAnsiString)^)^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtCurrency:    // Double (default Float type)
        begin
          CheckSizeAvailable(SizeOf(VCurrency^));
          System.Move(VCurrency, S[P], SizeOf(VCurrency^));
          Inc(P, SizeOf(VCurrency^));
        end;
        vtWideString:
        begin
          // how do you want to handle Unicode?  Store it as-is, or convert 
it to Ansi? This code
          // is converting to Ansi to maintain compatibility with your other 
statements...
          Tmp := AnsiString(PWideString(VWideString)^);
          Len := Min(Length(Tmp), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(PAnsiChar(Tmp)^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
        vtInt64:
        begin
          CheckSizeAvailable(SizeOf(VInt64));
          System.Move(VInt64, S[P], SizeOf(VInt64));
          Inc(P, SizeOf(VInt64));
        end;
        vtUnicodeString:
        begin
          // how do you want to handle Unicode?  Store it as-is, or convert 
it to Ansi? This code
          // is converting to Ansi to maintain compatibility with your other 
statements...
          Tmp := AnsiString(PUnicodeString(VUnicodeString)^);
          Len := Min(Length(Tmp), 255);
          CheckSizeAvailable(1+Len);
          S[P] := AnsiChar(Len);
          System.Move(PAnsiChar(Tmp)^, S[P+1], Len);
          Inc(P, 1+Len);
          ls := (I = High(Values));
        end;
      end;
    end;
  end;
 
  if ls then
    FillChar(S[P], FISize-P+1, #0)    // Clear the rest
  else
    raise Exception.Create('Some Find parameters missing.');
 
  // Start searching ...
  OldPos := FRecNo;
  if Find(s) then
  begin
    FEoF := False;
    FBoF := False;
    ReadRecord;
    Result := True;
  end
  else
  begin
    FRecNo := OldPos;
    Result := False;
  end;
end;


That being said, I really question the overall design of this code in general.
Why use ShortString at all? How does Find() know what kind of values are
passed in so it can read them correctly, given that you are simply dumping
the raw bytes of the Values into the ShortString without any type descriptors?

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02