2
0

Shared.SetupEntFunc.pas 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. unit Shared.SetupEntFunc;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Functions for handling records with embedded long strings
  8. }
  9. interface
  10. uses
  11. Compression.Base;
  12. procedure SEFreeRec(const P: Pointer; const NumStrings, NumAnsiStrings: Integer);
  13. procedure SEDuplicateRec(OldP, NewP: Pointer; Bytes: Cardinal;
  14. const NumStrings, NumAnsiStrings: Integer);
  15. procedure SECompressedBlockWrite(const W: TCompressedBlockWriter; var Buf;
  16. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  17. procedure SECompressedBlockRead(const R: TCompressedBlockReader; var Buf;
  18. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  19. implementation
  20. uses
  21. UnsignedFunc;
  22. procedure SEFreeRec(const P: Pointer; const NumStrings, NumAnsiStrings: Integer);
  23. var
  24. AnsiP: Pointer;
  25. begin
  26. if P = nil then Exit;
  27. if NumStrings > 0 then { Finalize in Delphi versions < 5 can't be called with zero count }
  28. Finalize(String(P^), NumStrings);
  29. if NumAnsiStrings > 0 then begin
  30. AnsiP := P;
  31. Inc(PByte(AnsiP), NumStrings*SizeOf(Pointer));
  32. Finalize(AnsiString(AnsiP^), NumAnsiStrings);
  33. end;
  34. FreeMem(P);
  35. end;
  36. procedure SEDuplicateRec(OldP, NewP: Pointer; Bytes: Cardinal;
  37. const NumStrings, NumAnsiStrings: Integer);
  38. var
  39. I: Integer;
  40. begin
  41. for I := 1 to NumStrings do begin
  42. String(NewP^) := String(OldP^);
  43. Inc(PByte(OldP), SizeOf(Pointer));
  44. Inc(PByte(NewP), SizeOf(Pointer));
  45. Dec(Bytes, SizeOf(Pointer));
  46. end;
  47. for I := 1 to NumAnsiStrings do begin
  48. AnsiString(NewP^) := AnsiString(OldP^);
  49. Inc(PByte(OldP), SizeOf(Pointer));
  50. Inc(PByte(NewP), SizeOf(Pointer));
  51. Dec(Bytes, SizeOf(Pointer));
  52. end;
  53. UMove(OldP^, NewP^, Bytes);
  54. end;
  55. procedure SECompressedBlockWrite(const W: TCompressedBlockWriter; var Buf;
  56. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  57. var
  58. P: Pointer;
  59. I: Integer;
  60. begin
  61. P := @Buf;
  62. for I := 1 to NumStrings do begin
  63. const Len = ULength(String(P^))*SizeOf(Char);
  64. W.Write(Len, SizeOf(Len));
  65. if Len <> 0 then
  66. W.Write(Pointer(P^)^, Len);
  67. Inc(PByte(P), SizeOf(Pointer));
  68. end;
  69. for I := 1 to NumAnsiStrings do begin
  70. const Len = ULength(AnsiString(P^));
  71. W.Write(Len, SizeOf(Len));
  72. if Len <> 0 then
  73. W.Write(Pointer(P^)^, Len);
  74. Inc(PByte(P), SizeOf(Pointer));
  75. end;
  76. W.Write(P^, Count - (Cardinal(NumStrings + NumAnsiStrings) * SizeOf(Pointer)));
  77. end;
  78. procedure SECompressedBlockRead(const R: TCompressedBlockReader; var Buf;
  79. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  80. var
  81. P: Pointer;
  82. I: Integer;
  83. Len: Cardinal;
  84. S: String;
  85. AnsiS: AnsiString;
  86. begin
  87. P := @Buf;
  88. for I := 1 to NumStrings do begin
  89. R.Read(Len, SizeOf(Len));
  90. SetLength(S, Len div SizeOf(Char));
  91. if Len <> 0 then
  92. R.Read(S[1], Len);
  93. String(P^) := S;
  94. Inc(PByte(P), SizeOf(Pointer));
  95. end;
  96. for I := 1 to NumAnsiStrings do begin
  97. R.Read(Len, SizeOf(Len));
  98. SetLength(AnsiS, Len);
  99. if Len <> 0 then
  100. R.Read(AnsiS[1], Len);
  101. AnsiString(P^) := AnsiS;
  102. Inc(PByte(P), SizeOf(Pointer));
  103. end;
  104. const BytesLeft = Count - (Cardinal(NumStrings + NumAnsiStrings) * SizeOf(Pointer));
  105. { Unlike Count, BytesLeft should be the same in both 32-bit and 64-bit builds }
  106. R.Read(P^, BytesLeft);
  107. end;
  108. end.