* Patch from Andrew Haines to support FPDOC generating CHMs

git-svn-id: trunk@9406 -
This commit is contained in:
michael 2007-12-07 10:51:52 +00:00
parent e6087db326
commit 853c34fda0
5 changed files with 134 additions and 78 deletions

View File

@ -36,6 +36,7 @@ type
TChmProject = class TChmProject = class
private private
FWriter: TChmWriter;
FAutoFollowLinks: Boolean; FAutoFollowLinks: Boolean;
FDefaultFont: String; FDefaultFont: String;
FDefaultPage: String; FDefaultPage: String;
@ -49,6 +50,7 @@ type
FTitle: String; FTitle: String;
protected protected
function GetData(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean; function GetData(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
procedure LastFileAdded(Sender: TObject);
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -93,6 +95,25 @@ begin
if Assigned(FOnProgress) then FOnProgress(Self, DataName); if Assigned(FOnProgress) then FOnProgress(Self, DataName);
end; end;
procedure TChmProject.LastFileAdded(Sender: TObject);
var
IndexStream: TFileStream;
TOCStream: TFileStream;
begin
// Assign the TOC and index files
if (IndexFileName <> '') and FileExists(IndexFileName) then begin
IndexStream := TFileStream.Create(IndexFileName, fmOpenRead);
FWriter.AppendIndex(IndexStream);
IndexStream.Free;
end;
if (TableOfContentsFileName <> '') and FileExists(TableOfContentsFileName) then begin
TOCStream := TFileStream.Create(TableOfContentsFileName, fmOpenRead);
FWriter.AppendTOC(TOCStream);
TOCStream.Free;
end;
end;
constructor TChmProject.Create; constructor TChmProject.Create;
begin begin
FFiles := TStringList.Create; FFiles := TStringList.Create;
@ -174,20 +195,11 @@ begin
Writer := TChmWriter.Create(AOutStream, False); Writer := TChmWriter.Create(AOutStream, False);
// our callback to get data // our callback to get data
Writer.OnGetFileData := @GetData; Writer.OnGetFileData := @GetData;
Writer.OnLastFile := @LastFileAdded;
// give it the list of files // give it the list of files
Writer.FilesToCompress.AddStrings(Files); Writer.FilesToCompress.AddStrings(Files);
// Assign the TOC and index files
if (IndexFileName <> '') and FileExists(IndexFileName) then begin
IndexStream := TFileStream.Create(IndexFileName, fmOpenRead);
Writer.IndexStream := IndexStream;
end;
if (TableOfContentsFileName <> '') and FileExists(TableOfContentsFileName) then begin
TOCStream := TFileStream.Create(TableOfContentsFileName, fmOpenRead);
Writer.TOCStream := TOCStream;
end;
// now some settings in the chm // now some settings in the chm
Writer.DefaultPage := DefaultPage; Writer.DefaultPage := DefaultPage;
Writer.Title := Title; Writer.Title := Title;

View File

@ -671,7 +671,7 @@ var
I: Integer; I: Integer;
begin begin
Result := 0; Result := 0;
WriteLn('Looking for URL : ', Name);
if Name = '' then Exit; if Name = '' then Exit;
if fDirectoryHeader.DirectoryChunkCount = 0 then exit; if fDirectoryHeader.DirectoryChunkCount = 0 then exit;
@ -1117,6 +1117,7 @@ begin
Found := True; Found := True;
end; end;
if not Found then exit; if not Found then exit;
WriteLn('Looking for URL ', URL, ' in ', AFileName);
if CheckOpenFile(AFileName) then if CheckOpenFile(AFileName) then
Result := fLastChm.ObjectExists(URL); Result := fLastChm.ObjectExists(URL);
if Result > 0 then NAme := Url; if Result > 0 then NAme := Url;

View File

@ -39,6 +39,7 @@ type
FComment: String; FComment: String;
FImageNumber: Integer; FImageNumber: Integer;
FIncreaseImageIndex: Boolean; FIncreaseImageIndex: Boolean;
FKeyWord: String;
FLocal: String; FLocal: String;
FOwner: TChmSiteMapItems; FOwner: TChmSiteMapItems;
FSeeAlso: String; FSeeAlso: String;
@ -50,6 +51,7 @@ type
destructor Destroy; override; destructor Destroy; override;
property Children: TChmSiteMapItems read FChildren write SetChildren; property Children: TChmSiteMapItems read FChildren write SetChildren;
property Text: String read FText write FText; // Name for TOC; KeyWord for index property Text: String read FText write FText; // Name for TOC; KeyWord for index
property KeyWord: String read FKeyWord write FKeyWord;
property Local: String read FLocal write FLocal; property Local: String read FLocal write FLocal;
property URL: String read FURL write FURL; property URL: String read FURL write FURL;
property SeeAlso: String read FSeeAlso write FSeeAlso; property SeeAlso: String read FSeeAlso write FSeeAlso;
@ -81,6 +83,7 @@ type
function NewItem: TChmSiteMapItem; function NewItem: TChmSiteMapItem;
function Insert(AItem: TChmSiteMapItem; AIndex: Integer): Integer; function Insert(AItem: TChmSiteMapItem; AIndex: Integer): Integer;
procedure Clear; procedure Clear;
procedure Sort(Compare: TListSortCompare);
property Item[AIndex: Integer]: TChmSiteMapItem read GetItem write SetItem; property Item[AIndex: Integer]: TChmSiteMapItem read GetItem write SetItem;
property Count: Integer read GetCount; property Count: Integer read GetCount;
property ParentItem: TChmSiteMapItem read FParentItem; property ParentItem: TChmSiteMapItem read FParentItem;
@ -338,15 +341,15 @@ var
Item: TChmSiteMapItem; Item: TChmSiteMapItem;
begin begin
for I := 0 to AItems.Count-1 do begin for I := 0 to AItems.Count-1 do begin
Item := AItems.Item[I]; Item := AItems.Item[I];
WriteString('<LI> <OBJECT type="text/sitemap">'); WriteString('<LI> <OBJECT type="text/sitemap">');
Inc(Indent, 8); Inc(Indent, 8);
//Merge
//if (SiteMapType = stIndex) and (Item.Text <> '') then WriteParam('Keyword', Item.Text); if (SiteMapType = stIndex) and (Item.Children.Count > 0) then
WriteParam('Keyword', Item.Text);
//if Item.KeyWord <> '' then WriteParam('Keyword', Item.KeyWord);
if Item.Text <> '' then WriteParam('Name', Item.Text); if Item.Text <> '' then WriteParam('Name', Item.Text);
if Item.Local <> '' then WriteParam('Local', Item.Local); if (Item.Local <> '') or (SiteMapType = stIndex) then WriteParam('Local', Item.Local);
if Item.URL <> '' then WriteParam('URL', Item.URL); if Item.URL <> '' then WriteParam('URL', Item.URL);
if (SiteMapType = stIndex) and (Item.SeeAlso <> '') then WriteParam('See Also', Item.SeeAlso); if (SiteMapType = stIndex) and (Item.SeeAlso <> '') then WriteParam('See Also', Item.SeeAlso);
//if Item.FrameName <> '' then WriteParam('FrameName', Item.FrameName); //if Item.FrameName <> '' then WriteParam('FrameName', Item.FrameName);
@ -367,9 +370,6 @@ var
Dec(Indent, 8); Dec(Indent, 8);
WriteString('</UL>'); WriteString('</UL>');
end; end;
end; end;
end; end;
begin begin
@ -498,5 +498,10 @@ begin
for I := Count-1 downto 0 do Delete(I); for I := Count-1 downto 0 do Delete(I);
end; end;
procedure TChmSiteMapItems.Sort(Compare: TListSortCompare);
begin
FList.Sort(Compare);
end;
end. end.

View File

@ -34,7 +34,7 @@ uses
function WriteSpanInfoToStream(const AStream: TStream; UncompressedSize: QWord): Integer; function WriteSpanInfoToStream(const AStream: TStream; UncompressedSize: QWord): Integer;
function WriteTransformListToStream(const AStream: TStream): Integer; function WriteTransformListToStream(const AStream: TStream): Integer;
function WriteResetTableToStream(const AStream: TStream; ResetTableStream: TMemoryStream): Integer; function WriteResetTableToStream(const AStream: TStream; ResetTableStream: TMemoryStream): Integer;
function WriteContentToStream(const AStream: TStream; ContentStream: TMemoryStream): Integer; function WriteContentToStream(const AStream: TStream; ContentStream: TStream): Integer;
implementation implementation
@ -120,7 +120,7 @@ begin
Result := AStream.CopyFrom(ResetTableStream, ResetTableStream.Size-SizeOf(QWord)); Result := AStream.CopyFrom(ResetTableStream, ResetTableStream.Size-SizeOf(QWord));
end; end;
function WriteContentToStream(const AStream: TStream; ContentStream: TMemoryStream): Integer; function WriteContentToStream(const AStream: TStream; ContentStream: TStream): Integer;
begin begin
// ::DataSpace/Storage/MSCompressed/Content // ::DataSpace/Storage/MSCompressed/Content
ContentStream.Position := 0; ContentStream.Position := 0;

View File

@ -34,17 +34,14 @@ type
// Stream : the file opened with DataName should be written to this stream // Stream : the file opened with DataName should be written to this stream
{ TChmWriter } { TChmWriter }
TChmWriter = class(TObject) TChmWriter = class(TObject)
FOnLastFile: TNotifyEvent;
private private
ForceExit: Boolean; ForceExit: Boolean;
FDefaultFont: String; FDefaultFont: String;
FDefaultPage: String; FDefaultPage: String;
FFullTextSearch: Boolean; FFullTextSearch: Boolean;
@ -56,16 +53,18 @@ type
FStringsStream: TMemoryStream; FStringsStream: TMemoryStream;
FContextStream: TMemoryStream; // the #IVB file FContextStream: TMemoryStream; // the #IVB file
FSection0: TMemoryStream; FSection0: TMemoryStream;
FSection1: TMemoryStream; // Compressed Stream FSection1: TStream; // Compressed Stream
FSection1Size: Int64; FSection1Size: Int64;
FSection1ResetTable: TMemoryStream; // has a list of frame positions NOT window positions FSection1ResetTable: TMemoryStream; // has a list of frame positions NOT window positions
FDirectoryListings: TStream; FDirectoryListings: TStream;
FIndexStream: TStream;
FOutStream: TStream; FOutStream: TStream;
FFileNames: TStrings; FFileNames: TStrings;
FDestroyStream: Boolean; FDestroyStream: Boolean;
FTempStream: TStream;
FPostStream: TStream;
FTitle: String; FTitle: String;
FTOCStream: TStream; FHasTOC: Boolean;
FHasIndex: Boolean;
FWindowSize: LongWord; FWindowSize: LongWord;
FReadCompressedSize: Int64; // Current Size of Uncompressed data that went in Section1 (compressed) FReadCompressedSize: Int64; // Current Size of Uncompressed data that went in Section1 (compressed)
// Linear order of file // Linear order of file
@ -81,12 +80,11 @@ type
// end linear header parts // end linear header parts
procedure InitITSFHeader; procedure InitITSFHeader;
procedure InitHeaderSectionTable; procedure InitHeaderSectionTable;
procedure SetTempRawStream(const AValue: TStream);
procedure WriteHeader(Stream: TStream); procedure WriteHeader(Stream: TStream);
procedure CreateDirectoryListings; procedure CreateDirectoryListings;
procedure WriteDirectoryListings(Stream: TStream); procedure WriteDirectoryListings(Stream: TStream);
procedure StartCompressingStream; procedure StartCompressingStream;
procedure WriteTOC;
procedure WriteIndex;
procedure WriteSYSTEM; procedure WriteSYSTEM;
procedure WriteITBITS; procedure WriteITBITS;
procedure WriteSTRINGS; procedure WriteSTRINGS;
@ -106,19 +104,23 @@ type
constructor Create(OutStream: TStream; FreeStreamOnDestroy: Boolean); constructor Create(OutStream: TStream; FreeStreamOnDestroy: Boolean);
destructor Destroy; override; destructor Destroy; override;
procedure Execute; procedure Execute;
procedure AppendTOC(AStream: TStream);
procedure AppendIndex(AStream: TStream);
procedure AppendSearchDB(AName: String; AStream: TStream);
procedure AddStreamToArchive(AFileName, APath: String; AStream: TStream; Compress: Boolean = True); procedure AddStreamToArchive(AFileName, APath: String; AStream: TStream; Compress: Boolean = True);
procedure PostAddStreamToArchive(AFileName, APath: String; AStream: TStream; Compress: Boolean = True);
procedure AddContext(AContext: DWord; ATopic: String); procedure AddContext(AContext: DWord; ATopic: String);
property WindowSize: LongWord read FWindowSize write FWindowSize default 2; // in $8000 blocks property WindowSize: LongWord read FWindowSize write FWindowSize default 2; // in $8000 blocks
property FrameSize: LongWord read FFrameSize write FFrameSize default 1; // in $8000 blocks property FrameSize: LongWord read FFrameSize write FFrameSize default 1; // in $8000 blocks
property FilesToCompress: TStrings read FFileNames; property FilesToCompress: TStrings read FFileNames;
property OnGetFileData: TGetDataFunc read FOnGetFileData write FOnGetFileData; property OnGetFileData: TGetDataFunc read FOnGetFileData write FOnGetFileData;
property OnLastFile: TNotifyEvent read FOnLastFile write FOnLastFile;
property OutStream: TStream read FOutStream; property OutStream: TStream read FOutStream;
property Title: String read FTitle write FTitle; property Title: String read FTitle write FTitle;
property FullTextSearch: Boolean read FFullTextSearch write FFullTextSearch; property FullTextSearch: Boolean read FFullTextSearch write FFullTextSearch;
property DefaultFont: String read FDefaultFont write FDefaultFont; property DefaultFont: String read FDefaultFont write FDefaultFont;
property DefaultPage: String read FDefaultPage write FDefaultPage; property DefaultPage: String read FDefaultPage write FDefaultPage;
property TOCStream: TStream read FTOCStream write FTOCStream; property TempRawStream: TStream read FTempStream write SetTempRawStream;
property IndexStream: TStream read FIndexStream write FIndexStream;
//property LocaleID: dword read ITSFHeader.LanguageID write ITSFHeader.LanguageID; //property LocaleID: dword read ITSFHeader.LanguageID write ITSFHeader.LanguageID;
end; end;
@ -200,6 +202,18 @@ begin
HeaderSuffix.Offset := NToLE(HeaderSuffix.Offset); HeaderSuffix.Offset := NToLE(HeaderSuffix.Offset);
end; end;
procedure TChmWriter.SetTempRawStream(const AValue: TStream);
begin
if (FCurrentStream.Size > 0) or (FSection1.Size > 0) then
raise Exception.Create('Cannot set the TempRawStream once data has been written to it!');
if AValue = nil then
raise Exception.Create('TempRawStream cannot be nil!');
if FCurrentStream = AValue then
exit;
FCurrentStream.Free;
FCurrentStream := AValue;
end;
procedure TChmWriter.WriteHeader(Stream: TStream); procedure TChmWriter.WriteHeader(Stream: TStream);
begin begin
Stream.Write(ITSFHeader, SizeOf(TITSFHeader)); Stream.Write(ITSFHeader, SizeOf(TITSFHeader));
@ -225,8 +239,7 @@ var
FESize: Integer; FESize: Integer;
FileName: String; FileName: String;
FileNameSize: Integer; FileNameSize: Integer;
LastListIndex, LastListIndex: Integer;
LastIndexIndex: Integer;
FirstListEntry: TFirstListEntry; FirstListEntry: TFirstListEntry;
ChunkIndex: Integer; ChunkIndex: Integer;
ListHeader: TPMGListChunk; ListHeader: TPMGListChunk;
@ -312,7 +325,6 @@ begin
IndexBlock := TPMGIDirectoryChunk.Create(SizeOf(TPMGIIndexChunk)); IndexBlock := TPMGIDirectoryChunk.Create(SizeOf(TPMGIIndexChunk));
ListingBlock := TDirectoryChunk.Create(SizeOf(TPMGListChunk)); ListingBlock := TDirectoryChunk.Create(SizeOf(TPMGListChunk));
LastIndexIndex := -1;
LastListIndex := -1; LastListIndex := -1;
// add files to a pmgl block until it is full. // add files to a pmgl block until it is full.
@ -373,24 +385,9 @@ begin
//TMemoryStream(FDirectoryListings).SaveToFile('dirlistings.pmg'); //TMemoryStream(FDirectoryListings).SaveToFile('dirlistings.pmg');
end; end;
procedure TChmWriter.WriteIndex;
var
Entry: TFileEntryRec;
TmpTitle: String;
begin
if IndexStream = nil then Exit;
if Title <> '' then TmpTitle := Title
else TmpTitle := 'default';
AddStreamToArchive(TmpTitle+'.hhk', '/', IndexStream);
end;
procedure TChmWriter.WriteSystem; procedure TChmWriter.WriteSystem;
var var
Entry: TFileEntryRec; Entry: TFileEntryRec;
EntryCode,
EntryLength: Word;
TmpStr: String; TmpStr: String;
TmpTitle: String; TmpTitle: String;
const const
@ -449,6 +446,7 @@ begin
FSection0.WriteWord(NToLE(Word(3))); FSection0.WriteWord(NToLE(Word(3)));
FSection0.WriteWord(NToLE(Word(Length(FTitle)+1))); FSection0.WriteWord(NToLE(Word(Length(FTitle)+1)));
FSection0.Write(FTitle[1], Length(FTitle)); FSection0.Write(FTitle[1], Length(FTitle));
FSection0.WriteByte(0);
end; end;
// 16 Default Font // 16 Default Font
@ -456,14 +454,15 @@ begin
FSection0.WriteWord(NToLE(Word(16))); FSection0.WriteWord(NToLE(Word(16)));
FSection0.WriteWord(NToLE(Word(Length(FDefaultFont)+1))); FSection0.WriteWord(NToLE(Word(Length(FDefaultFont)+1)));
FSection0.Write(FDefaultFont[1], Length(FDefaultFont)); FSection0.Write(FDefaultFont[1], Length(FDefaultFont));
FSection0.WriteByte(0);
end; end;
// 6 // 6
// unneeded. if output file is : /somepath/OutFile.chm the value here is outfile(lowercase) // unneeded. if output file is : /somepath/OutFile.chm the value here is outfile(lowercase)
// 0 Table of contents filename // 0 Table of contents filename
if TOCStream <> nil then begin if FHasTOC then begin
TmpStr := TmpTitle+'.hhc'; TmpStr := 'default.hhc';
FSection0.WriteWord(0); FSection0.WriteWord(0);
FSection0.WriteWord(NToLE(Word(Length(TmpStr)+1))); FSection0.WriteWord(NToLE(Word(Length(TmpStr)+1)));
FSection0.Write(TmpStr[1], Length(TmpStr)); FSection0.Write(TmpStr[1], Length(TmpStr));
@ -471,8 +470,8 @@ begin
end; end;
// 1 // 1
// hhk Index // hhk Index
if IndexStream <> nil then begin if FHasIndex then begin
TmpStr := TmpTitle+'.hhk'; TmpStr := 'default.hhk';
FSection0.WriteWord(NToLE(Word(1))); FSection0.WriteWord(NToLE(Word(1)));
FSection0.WriteWord(NToLE(Word(Length(TmpStr)+1))); FSection0.WriteWord(NToLE(Word(Length(TmpStr)+1)));
FSection0.Write(TmpStr[1], Length(TmpStr)); FSection0.Write(TmpStr[1], Length(TmpStr));
@ -530,7 +529,7 @@ begin
FSection0.Write(DISCLAIMER_STR, SizeOf(DISCLAIMER_STR)); FSection0.Write(DISCLAIMER_STR, SizeOf(DISCLAIMER_STR));
Entry.DecompressedSize := FSection0.Position - Entry.DecompressedOffset; Entry.DecompressedSize := FSection0.Position - Entry.DecompressedOffset;
Entry.Path := '/'; Entry.Path := '/';
Entry.Name := '_::_README_::_'; //try to use a name that won't conflict with normal names Entry.Name := '_#_README_#_'; //try to use a name that won't conflict with normal names
FInternalFiles.AddEntry(Entry); FInternalFiles.AddEntry(Entry);
end; end;
@ -649,6 +648,19 @@ begin
Inc(FReadCompressedSize, FileEntry.DecompressedSize); Inc(FReadCompressedSize, FileEntry.DecompressedSize);
FCurrentStream.Position := 0; FCurrentStream.Position := 0;
end; end;
// this is intended for programs to add perhaps a file
// after all the other files have been added.
if (AtEndOfData)
and (FCurrentStream <> FPostStream) then
begin
if Assigned(FOnLastFile) then
FOnLastFile(Self);
FCurrentStream.Free;
FCurrentStream := FPostStream;
FCurrentStream.Position := 0;
Inc(FReadCompressedSize, FCurrentStream.Size);
end;
end; end;
end; end;
@ -661,11 +673,11 @@ function TChmWriter.WriteCompressedData(Count: Longint; Buffer: Pointer): LongIn
begin begin
// we allocate a MB at a time to limit memory reallocation since this // we allocate a MB at a time to limit memory reallocation since this
// writes usually 2 bytes at a time // writes usually 2 bytes at a time
if FSection1.Position >= FSection1.Size-1 then begin if (FSection1 is TMemoryStream) and (FSection1.Position >= FSection1.Size-1) then begin
FSection1.Size := FSection1.Size+$100000; FSection1.Size := FSection1.Size+$100000;
end; end;
Inc(FSection1Size, FSection1.Write(Buffer^, Count)); Result := FSection1.Write(Buffer^, Count);
Inc(FSection1Size, Result);
end; end;
procedure _MarkFrame(arg: pointer; UncompressedTotal, CompressedTotal: LongWord); cdecl; procedure _MarkFrame(arg: pointer; UncompressedTotal, CompressedTotal: LongWord); cdecl;
@ -693,7 +705,6 @@ procedure TChmWriter.MarkFrame(UnCompressedTotal, CompressedTotal: LongWord);
procedure UpdateTotalSizes; procedure UpdateTotalSizes;
var var
OldPos: Int64; OldPos: Int64;
Value: DWord;
begin begin
OldPos := FSection1ResetTable.Position; OldPos := FSection1ResetTable.Position;
FSection1ResetTable.Position := $10; FSection1ResetTable.Position := $10;
@ -701,8 +712,6 @@ procedure TChmWriter.MarkFrame(UnCompressedTotal, CompressedTotal: LongWord);
WriteQWord(CompressedTotal); WriteQWord(CompressedTotal);
FSection1ResetTable.Position := OldPos; FSection1ResetTable.Position := OldPos;
end; end;
var
Tmp : QWord;
begin begin
if FSection1ResetTable.Size = 0 then begin if FSection1ResetTable.Size = 0 then begin
// Write the header // Write the header
@ -733,6 +742,7 @@ begin
FSection1 := TMemoryStream.Create; FSection1 := TMemoryStream.Create;
FSection1ResetTable := TMemoryStream.Create; FSection1ResetTable := TMemoryStream.Create;
FDirectoryListings := TMemoryStream.Create; FDirectoryListings := TMemoryStream.Create;
FPostStream := TMemoryStream.Create;;
FDestroyStream := FreeStreamOnDestroy; FDestroyStream := FreeStreamOnDestroy;
FFileNames := TStringList.Create; FFileNames := TStringList.Create;
end; end;
@ -760,8 +770,6 @@ begin
// write any internal files to FCurrentStream that we want in the compressed section // write any internal files to FCurrentStream that we want in the compressed section
WriteIVB; WriteIVB;
WriteTOC;
WriteIndex;
WriteSTRINGS; WriteSTRINGS;
// written to Section0 (uncompressed) // written to Section0 (uncompressed)
@ -798,10 +806,27 @@ begin
WriteSection1; // writes section 1 to FOutStream WriteSection1; // writes section 1 to FOutStream
end; end;
procedure TChmWriter.AppendTOC(AStream: TStream);
begin
FHasTOC := True;
PostAddStreamToArchive('default.hhc', '/', AStream, True);
end;
procedure TChmWriter.AppendIndex(AStream: TStream);
begin
FHasIndex := True;
PostAddStreamToArchive('default.hhk', '/', AStream, True);
end;
procedure TChmWriter.AppendSearchDB(AName: String; AStream: TStream);
begin
PostAddStreamToArchive(AName, '/', AStream);
end;
// this procedure is used to manually add files to compress to an internal stream that is // this procedure is used to manually add files to compress to an internal stream that is
// processed before FileToCompress is called. Files added this way should not be // processed before FileToCompress is called. Files added this way should not be
// in the FilesToCompress property. // duplicated in the FilesToCompress property.
procedure TChmWriter.AddStreamToArchive(AFileName, APath: String; AStream: TStream; Compress: Boolean = True); procedure TChmWriter.AddStreamToArchive(AFileName, APath: String; AStream: TStream; Compress: Boolean = True);
var var
TargetStream: TStream; TargetStream: TStream;
@ -823,6 +848,31 @@ begin
TargetStream.CopyFrom(AStream, AStream.Size); TargetStream.CopyFrom(AStream, AStream.Size);
end; end;
procedure TChmWriter.PostAddStreamToArchive(AFileName, APath: String;
AStream: TStream; Compress: Boolean);
var
TargetStream: TStream;
Entry: TFileEntryRec;
begin
if AStream = nil then Exit;
if Compress then
TargetStream := FPostStream
else
TargetStream := FSection0;
Entry.Name := AFileName;
Entry.Path := APath;
Entry.Compressed := Compress;
if not Compress then
Entry.DecompressedOffset := TargetStream.Position
else
Entry.DecompressedOffset := FReadCompressedSize + TargetStream.Position;
Entry.DecompressedSize := AStream.Size;
FInternalFiles.AddEntry(Entry);
AStream.Position := 0;
TargetStream.CopyFrom(AStream, AStream.Size);
end;
procedure TChmWriter.AddContext(AContext: DWord; ATopic: String); procedure TChmWriter.AddContext(AContext: DWord; ATopic: String);
var var
Offset: DWord; Offset: DWord;
@ -858,16 +908,4 @@ begin
lzx_finish(LZXdata, nil); lzx_finish(LZXdata, nil);
end; end;
procedure TChmWriter.WriteTOC;
var
TmpTitle: String;
begin
if TOCStream = nil then Exit;
if Title <> '' then TmpTitle := Title
else TmpTitle := 'default';
AddStreamToArchive(TmpTitle+'.hhc', '/', TOCStream);
end;
end. end.