Shared.SetupEntFunc.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. unit Shared.SetupEntFunc;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2004 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. procedure SEFreeRec(const P: Pointer; const NumStrings, NumAnsiStrings: Integer);
  21. var
  22. AnsiP: Pointer;
  23. begin
  24. if P = nil then Exit;
  25. if NumStrings > 0 then { Finalize in Delphi versions < 5 can't be called with zero count }
  26. Finalize(String(P^), NumStrings);
  27. if NumAnsiStrings > 0 then begin
  28. AnsiP := P;
  29. Inc(Cardinal(AnsiP), NumStrings*SizeOf(Pointer));
  30. Finalize(AnsiString(AnsiP^), NumAnsiStrings);
  31. end;
  32. FreeMem(P);
  33. end;
  34. procedure SEDuplicateRec(OldP, NewP: Pointer; Bytes: Cardinal;
  35. const NumStrings, NumAnsiStrings: Integer);
  36. var
  37. I: Integer;
  38. begin
  39. for I := 1 to NumStrings do begin
  40. String(NewP^) := String(OldP^);
  41. Inc(Cardinal(OldP), SizeOf(Pointer));
  42. Inc(Cardinal(NewP), SizeOf(Pointer));
  43. Dec(Bytes, SizeOf(Pointer));
  44. end;
  45. for I := 1 to NumAnsiStrings do begin
  46. AnsiString(NewP^) := AnsiString(OldP^);
  47. Inc(Cardinal(OldP), SizeOf(Pointer));
  48. Inc(Cardinal(NewP), SizeOf(Pointer));
  49. Dec(Bytes, SizeOf(Pointer));
  50. end;
  51. Move(OldP^, NewP^, Bytes);
  52. end;
  53. procedure SECompressedBlockWrite(const W: TCompressedBlockWriter; var Buf;
  54. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  55. var
  56. P: Pointer;
  57. I: Integer;
  58. Len: Integer;
  59. begin
  60. P := @Buf;
  61. for I := 1 to NumStrings do begin
  62. Len := Length(String(P^))*SizeOf(Char);
  63. W.Write(Len, SizeOf(Len));
  64. if Len <> 0 then
  65. W.Write(Pointer(P^)^, Len);
  66. Inc(Cardinal(P), SizeOf(Pointer));
  67. end;
  68. for I := 1 to NumAnsiStrings do begin
  69. Len := Length(AnsiString(P^));
  70. W.Write(Len, SizeOf(Len));
  71. if Len <> 0 then
  72. W.Write(Pointer(P^)^, Len);
  73. Inc(Cardinal(P), SizeOf(Pointer));
  74. end;
  75. W.Write(P^, Count - (Cardinal(NumStrings + NumAnsiStrings) * SizeOf(Pointer)));
  76. end;
  77. procedure SECompressedBlockRead(const R: TCompressedBlockReader; var Buf;
  78. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  79. var
  80. P: Pointer;
  81. I: Integer;
  82. Len: Integer;
  83. S: String;
  84. AnsiS: AnsiString;
  85. begin
  86. P := @Buf;
  87. for I := 1 to NumStrings do begin
  88. R.Read(Len, SizeOf(Len));
  89. SetLength(S, Len div SizeOf(Char));
  90. if Len <> 0 then
  91. R.Read(S[1], Len);
  92. String(P^) := S;
  93. Inc(Cardinal(P), SizeOf(Pointer));
  94. end;
  95. for I := 1 to NumAnsiStrings do begin
  96. R.Read(Len, SizeOf(Len));
  97. SetLength(AnsiS, Len);
  98. if Len <> 0 then
  99. R.Read(AnsiS[1], Len);
  100. AnsiString(P^) := AnsiS;
  101. Inc(Cardinal(P), SizeOf(Pointer));
  102. end;
  103. R.Read(P^, Count - (Cardinal(NumStrings + NumAnsiStrings) * SizeOf(Pointer)));
  104. end;
  105. end.