📄 adxlbmdm.pas
字号:
(***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TurboPower Async Professional
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1991-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ADXLBMDM.PAS 4.06 *}
{*********************************************************}
{* Contains TApdModemCapDetails, which manipulates the *}
{* modemcap detail files. *}
{*********************************************************}
{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}
unit AdXLbMdm;
interface
uses
SysUtils, Classes, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls,
OOMisc, AdXBase, AdXParsr, AdExcept, AdLibMdm;
type
TApdModemCapDetail = class(TApdBaseComponent)
private
DetailStream : TFileStream;
function AtEOF : Boolean;
function ExportDetailXML(Modem : TLmModem) : Integer;
procedure FixupModemcap(var List : TStringList);
function ReadLine : string;
procedure WriteLine(const Str : string);
procedure WriteXMLStr(const Str, sVal : string);
function XMLize(const S : string) : string;
function XMLizeInt(I : Integer) : string;
function XMLizeBool(B : Boolean) : string;
function UnXMLize(const S : string) : string;
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
{ create a new modem detail file with appropriate headers }
function CreateNewDetailFile(const ModemDetailFile : string) : Integer;
{ adds a modem to the modem detail file }
function AddModem(const ModemDetailFile : string; Modem : TLmModem) : Integer;
{ deletes a modem from the modem detail file }
function DeleteModem(const ModemDetailFile, ModemName : string) : Integer;
{ these methods manage the modemcap index }
{ add a modem record to modemcap }
function AddModemRecord(const ModemCapIndex : string;
ModemRecord : TLmModemName) : Integer;
{ delete a modem record from modemcap }
function DeleteModemRecord(const ModemCapIndex : string;
ModemRecord : TLmModemName) : Integer;
end;
implementation
{ TApdModemCapDetail }
{
General assumptions: All ModemDetailFile parameters point to a specific
modemcap modem detail file. ModemDetailFile includes the full path and
file name.
All return values of the public functions are the ecXxx error codes
}
function TApdModemCapDetail.AddModem(const ModemDetailFile: string;
Modem: TLmModem): Integer;
{ adds a modem to the modem detail file }
var
C : Char;
I : Integer;
S : string;
Found : Boolean;
begin
DetailStream := nil;
try
Result := ecFileNotFound;
DetailStream := TFileStream.Create(ModemDetailFile, fmOpenReadWrite);
{ find the space between the last </Modem> and the final </ModemList> }
I := DetailStream.Size;
repeat
dec(I);
DetailStream.Position := I;
DetailStream.ReadBuffer(C, 1);
S := C + S;
Found := Pos('</ModemList>', S) > 0;
until Found or (I = 0);
DetailStream.Position := I - 1;
if not Found then begin
Result := ecInvalidFile;
Exit;
end;
{ now that we've found where we want to insert the new modem... }
ExportDetailXML(Modem);
WriteLine(#13#10'</ModemList>');
Result := ecOK;
finally
DetailStream.Free;
DetailStream := nil;
end;
end;
function TApdModemCapDetail.AddModemRecord(
const ModemCapIndex : string; ModemRecord: TLmModemName): Integer;
{ add a modem record to the master index, for something like this }
{ it's faster to use a TStringList }
var
List : TStringList;
S : string;
I : Integer;
begin
Result := ecFileNotFound;
if FileExists(ModemCapIndex) then begin
Result := ecInvalidFile;
List := nil;
try
List := TStringList.Create;
List.LoadFromFile(ModemCapIndex);
I := pred(List.Count);
{ find the last modem record }
while (Pos('<ModemRecord ModemName = "', List[I]) = 0) and (I > 0) do begin
List.Delete(I);
dec(I);
end;
if I = 0 then
{ must not be modemcap }
Exit;
S := ' <ModemRecord ModemName = "' + ModemRecord.ModemName +
'" Manufacturer = "' + ModemRecord.Manufacturer +
'" Model = "' + ModemRecord.Model +
'" ModemFile = "' + ModemRecord.ModemFile + '"/>';
List.Add(S);
FixupModemCap(List);
List.SaveToFile(ModemCapIndex);
Result := ecOK;
finally
List.Free;
end;
end;
end;
function TApdModemCapDetail.AtEOF: Boolean;
begin
Result := DetailStream.Position >= DetailStream.Size;
end;
constructor TApdModemCapDetail.Create(AOwner: TComponent);
begin
inherited;
DetailStream := nil;
end;
function TApdModemCapDetail.CreateNewDetailFile(
const ModemDetailFile: string): Integer;
var
S : string;
begin
try
{ create a new detail file }
DetailStream := TFileStream.Create(ModemDetailFile, fmCreate);
{ add the appropriate headers }
WriteLine('<?xml version="1.0" encoding="UTF-8"?>');
WriteLine('<!DOCTYPE ModemList SYSTEM "modemdetails.dtd">');
WriteLine('<ModemList');
WriteLine(' Generator = "ApxLibModem"');
WriteLine(' GeneratorVersion = "' + ApVersionStr + '"');
S := FormatDateTime('YYYY.MM.DD', Date);
WriteLine(' GeneratorDate = "' + S + '">');
WriteLine('</ModemList>');
finally
DetailStream.Free;
DetailStream := nil;
end;
Result := ecOK;
end;
function TApdModemCapDetail.DeleteModem(const ModemDetailFile,
ModemName: string): Integer;
{ deletes a modem from the modem detail file }
var
MemStream : TMemoryStream;
S : string;
Found : Boolean;
ModemStart, ModemEnd : Integer;
begin
DetailStream := nil;
MemStream := nil;
try
Result := ecOK;
ModemStart := 0;
ModemEnd := 0;
if not FileExists(ModemDetailFile) then begin
Result := ecFileNotFound;
Exit;
end;
{ load the original detail file in a memory stream so we can write }
{ it out later }
MemStream := TMemoryStream.Create;
MemStream.LoadFromFile(ModemDetailFile);
{ search for the beginning of the modem element }
repeat
S := ReadLine;
{ save the beginning of the entity }
if (Pos('<Modem', S) > 0) and (Pos('<ModemList', S) = 0) then
ModemStart := MemStream.Position - Length(S);
Found := (Pos('FriendlyName =', S) > 0) and
(Pos(ModemName, UnXMLize(S)) > 0);
until Found or (MemStream.Position >= MemStream.Size);
if not Found then begin
Result := ecModemNotFound;
Exit;
end;
{ now, search for the end of the modem element }
repeat
S := ReadLine;
Found := Pos('</Modem>', S) > 0;
if Found then
ModemEnd := MemStream.Position;
until Found or (MemStream.Position >= MemStream.Size);
if not Found then begin
Result := ecDiskRead;
Exit;
end;
{ now we can remove the block between ModemStart and ModemEnd }
try
{ delete the original file }
DeleteFile(ModemDetailFile);
{ create it }
DetailStream := TFileStream.Create(ModemDetailFile, fmCreate);
DetailStream.Position := 0;
MemStream.Position := 0;
{ copy the first part }
DetailStream.CopyFrom(MemStream, ModemStart);
{ copy the latter part }
MemStream.Position := ModemEnd;
DetailStream.CopyFrom(MemStream, MemStream.Size - ModemEnd);
finally
DetailStream.Free;
DetailStream := nil;
end;
Result := ecOK;
finally
MemStream.Free;
end;
end;
function TApdModemCapDetail.DeleteModemRecord(
const ModemCapIndex : string; ModemRecord: TLmModemName): Integer;
{ delete a modem from the modemcap index }
{ again, it's faster to do it with a TStringList }
var
List : TStringList;
I : Integer;
Found : Boolean;
S : string;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -