SetupEnt.pas 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. unit SetupEnt;
  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. $jrsoftware: issrc/Projects/SetupEnt.pas,v 1.6 2009/05/27 10:03:49 mlaan Exp $
  9. }
  10. interface
  11. uses
  12. Compress;
  13. procedure SEFreeRec(const P: Pointer; const NumStrings, NumAnsiStrings: Integer);
  14. procedure SEDuplicateRec(OldP, NewP: Pointer; Bytes: Cardinal;
  15. const NumStrings, NumAnsiStrings: Integer);
  16. procedure SECompressedBlockWrite(const W: TCompressedBlockWriter; var Buf;
  17. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  18. procedure SECompressedBlockRead(const R: TCompressedBlockReader; var Buf;
  19. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  20. implementation
  21. procedure SEFreeRec(const P: Pointer; const NumStrings, NumAnsiStrings: Integer);
  22. var
  23. AnsiP: Pointer;
  24. begin
  25. if P = nil then Exit;
  26. if NumStrings > 0 then { Finalize in Delphi versions < 5 can't be called with zero count }
  27. Finalize(String(P^), NumStrings);
  28. if NumAnsiStrings > 0 then begin
  29. AnsiP := P;
  30. Inc(Cardinal(AnsiP), NumStrings*SizeOf(Pointer));
  31. Finalize(AnsiString(AnsiP^), NumAnsiStrings);
  32. end;
  33. FreeMem(P);
  34. end;
  35. procedure SEDuplicateRec(OldP, NewP: Pointer; Bytes: Cardinal;
  36. const NumStrings, NumAnsiStrings: Integer);
  37. var
  38. I: Integer;
  39. begin
  40. for I := 1 to NumStrings do begin
  41. String(NewP^) := String(OldP^);
  42. Inc(Cardinal(OldP), SizeOf(Pointer));
  43. Inc(Cardinal(NewP), SizeOf(Pointer));
  44. Dec(Bytes, SizeOf(Pointer));
  45. end;
  46. for I := 1 to NumAnsiStrings do begin
  47. AnsiString(NewP^) := AnsiString(OldP^);
  48. Inc(Cardinal(OldP), SizeOf(Pointer));
  49. Inc(Cardinal(NewP), SizeOf(Pointer));
  50. Dec(Bytes, SizeOf(Pointer));
  51. end;
  52. Move(OldP^, NewP^, Bytes);
  53. end;
  54. procedure SECompressedBlockWrite(const W: TCompressedBlockWriter; var Buf;
  55. const Count: Cardinal; const NumStrings, NumAnsiStrings: Integer);
  56. var
  57. P: Pointer;
  58. I: Integer;
  59. Len: Integer;
  60. begin
  61. P := @Buf;
  62. for I := 1 to NumStrings do begin
  63. Len := Length(String(P^))*SizeOf(Char);
  64. W.Write(Len, SizeOf(Len));
  65. if Len <> 0 then
  66. W.Write(Pointer(P^)^, Len);
  67. Inc(Cardinal(P), SizeOf(Pointer));
  68. end;
  69. for I := 1 to NumAnsiStrings do begin
  70. Len := Length(AnsiString(P^));
  71. W.Write(Len, SizeOf(Len));
  72. if Len <> 0 then
  73. W.Write(Pointer(P^)^, Len);
  74. Inc(Cardinal(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: Integer;
  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(Cardinal(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(Cardinal(P), SizeOf(Pointer));
  103. end;
  104. R.Read(P^, Count - (Cardinal(NumStrings + NumAnsiStrings) * SizeOf(Pointer)));
  105. end;
  106. end.