2
0

PSStackHelper.pas 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. unit PSStackHelper;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2024 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. ROPS TPSStack helper class
  8. }
  9. interface
  10. {$IFNDEF NOCODE}
  11. uses
  12. Classes,
  13. uPSRuntime;
  14. type
  15. TPSStackHelper = class helper for TPSStack
  16. private
  17. function GetArray(const ItemNo, FieldNo: Longint; out N: Integer): TPSVariantIFC;
  18. function SetArray(const ItemNo, FieldNo: Longint; const N: Integer): TPSVariantIFC; overload;
  19. public
  20. type
  21. TArrayOfInteger = array of Integer;
  22. TArrayOfObject = array of TObject;
  23. TArrayOfString = array of String;
  24. TArrayBuilder = record
  25. Arr: TPSVariantIFC;
  26. I: Integer;
  27. procedure Add(const Data: String);
  28. end;
  29. TArrayEnumerator = record
  30. Arr: TPSVariantIFC;
  31. N, I: Integer;
  32. function HasNext: Boolean;
  33. function Next: String;
  34. end;
  35. function GetChar(const ItemNo: Longint): Char;
  36. function GetClassArray(const ItemNo: Longint; const FieldNo: Longint = -1): TArrayOfObject;
  37. function GetIntArray(const ItemNo: Longint; const FieldNo: Longint = -1): TArrayOfInteger;
  38. function GetProc(const ItemNo: Longint; const Exec: TPSExec): TMethod;
  39. function GetStringArray(const ItemNo: Longint; const FieldNo: Longint = -1): TArrayOfString;
  40. function GetUInt32(const ItemNo: Longint): UInt32;
  41. function InitArrayBuilder(const ItemNo: LongInt; const FieldNo: Longint = -1): TArrayBuilder;
  42. function InitArrayEnumerator(const ItemNo: LongInt; const FieldNo: Longint = -1): TArrayEnumerator;
  43. procedure SetArray(const ItemNo: Longint; const Data: TArray<String>; const FieldNo: Longint = -1); overload;
  44. procedure SetArray(const ItemNo: Longint; const Data: TStrings; const FieldNo: Longint = -1); overload;
  45. procedure SetInt(const ItemNo: Longint; const Data: Integer; const FieldNo: Longint = -1);
  46. end;
  47. {$ENDIF}
  48. implementation
  49. {$IFNDEF NOCODE}
  50. function TPSStackHelper.GetArray(const ItemNo, FieldNo: Longint;
  51. out N: Integer): TPSVariantIFC;
  52. begin
  53. if FieldNo >= 0 then
  54. Result := NewTPSVariantRecordIFC(Items[ItemNo], FieldNo)
  55. else
  56. Result := NewTPSVariantIFC(Items[ItemNo], True);
  57. N := PSDynArrayGetLength(Pointer(Result.Dta^), Result.aType);
  58. end;
  59. function TPSStackHelper.SetArray(const ItemNo, FieldNo: Longint;
  60. const N: Integer): TPSVariantIFC;
  61. begin
  62. if FieldNo >= 0 then
  63. Result := NewTPSVariantRecordIFC(Items[ItemNo], FieldNo)
  64. else
  65. Result := NewTPSVariantIFC(Items[ItemNo], True);
  66. PSDynArraySetLength(Pointer(Result.Dta^), Result.aType, N);
  67. end;
  68. function TPSStackHelper.GetChar(const ItemNo: Longint): Char;
  69. begin
  70. var S := GetString(ItemNo);
  71. if S <> '' then
  72. Result := S[1]
  73. else
  74. Result := #0;
  75. end;
  76. function TPSStackHelper.GetClassArray(const ItemNo, FieldNo: Longint): TArrayOfObject;
  77. begin
  78. var N: Integer;
  79. var Arr := GetArray(ItemNo, FieldNo, N);
  80. SetLength(Result, N);
  81. for var I := 0 to N-1 do
  82. Result[I] := VNGetObject(PSGetArrayField(Arr, I));
  83. end;
  84. function TPSStackHelper.GetIntArray(const ItemNo, FieldNo: Longint): TArrayOfInteger;
  85. begin
  86. var N: Integer;
  87. var Arr := GetArray(ItemNo, FieldNo, N);
  88. SetLength(Result, N);
  89. for var I := 0 to N-1 do
  90. Result[I] := VNGetInt(PSGetArrayField(Arr, I));
  91. end;
  92. function TPSStackHelper.GetProc(const ItemNo: Longint; const Exec: TPSExec): TMethod;
  93. begin
  94. var P := PPSVariantProcPtr(Items[ItemNo]);
  95. { ProcNo 0 means nil was passed by the script and GetProcAsMethod will then return a (nil, nil) TMethod }
  96. Result := Exec.GetProcAsMethod(P.ProcNo);
  97. end;
  98. function TPSStackHelper.GetStringArray(const ItemNo, FieldNo: Longint): TArrayOfString;
  99. begin
  100. var N: Integer;
  101. var Arr := GetArray(ItemNo, FieldNo, N);
  102. SetLength(Result, N);
  103. for var I := 0 to N-1 do
  104. Result[I] := VNGetString(PSGetArrayField(Arr, I));
  105. end;
  106. function TPSStackHelper.GetUInt32(const ItemNo: Longint): UInt32;
  107. begin
  108. Result := UInt32(GetInt(ItemNo));
  109. end;
  110. function TPSStackHelper.InitArrayBuilder(const ItemNo, FieldNo: Longint): TArrayBuilder;
  111. begin
  112. Result.Arr := SetArray(ItemNo, FieldNo, 0);
  113. Result.I := 0;
  114. end;
  115. procedure TPSStackHelper.TArrayBuilder.Add(const Data: String);
  116. begin
  117. PSDynArraySetLength(Pointer(Arr.Dta^), Arr.aType, I+1);
  118. VNSetString(PSGetArrayField(Arr, I), Data);
  119. Inc(I);
  120. end;
  121. function TPSStackHelper.InitArrayEnumerator(const ItemNo, FieldNo: Longint): TArrayEnumerator;
  122. begin
  123. Result.Arr := GetArray(ItemNo, FieldNo, Result.N);
  124. Result.I := 0;
  125. end;
  126. function TPSStackHelper.TArrayEnumerator.HasNext: Boolean;
  127. begin
  128. Result := I < N;
  129. end;
  130. function TPSStackHelper.TArrayEnumerator.Next: String;
  131. begin
  132. Result := VNGetString(PSGetArrayField(Arr, I));
  133. Inc(I);
  134. end;
  135. procedure TPSStackHelper.SetArray(const ItemNo: Longint; const Data: TArray<String>; const FieldNo: Longint);
  136. begin
  137. var N := System.Length(Data);
  138. var Arr := SetArray(ItemNo, FieldNo, N);
  139. for var I := 0 to N-1 do
  140. VNSetString(PSGetArrayField(Arr, I), Data[I]);
  141. end;
  142. procedure TPSStackHelper.SetArray(const ItemNo: Longint; const Data: TStrings; const FieldNo: Longint);
  143. begin
  144. var N := Data.Count;
  145. var Arr := SetArray(ItemNo, FieldNo, N);
  146. for var I := 0 to N-1 do
  147. VNSetString(PSGetArrayField(Arr, I), Data[I]);
  148. end;
  149. procedure TPSStackHelper.SetInt(const ItemNo: Longint; const Data: Integer;
  150. const FieldNo: Longint);
  151. begin
  152. if FieldNo >= 0 then begin
  153. var PSVariantIFC := NewTPSVariantRecordIFC(Items[ItemNo], FieldNo);
  154. VNSetInt(PSVariantIFC, Data);
  155. end else
  156. inherited SetInt(ItemNo, Data)
  157. end;
  158. {$ENDIF}
  159. end.