mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 16:35:33 +00:00
154 lines
4.5 KiB
ObjectPascal
154 lines
4.5 KiB
ObjectPascal
(*
|
|
Name: utilxml
|
|
Copyright: Copyright (C) SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 1 Aug 2006
|
|
|
|
Modified Date: 8 Jun 2012
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 01 Aug 2006 - mcdurdin - Refactor util functions into multiple units
|
|
13 Jul 2007 - mcdurdin - I959 - Fix bug with xml encoding of entities
|
|
20 Jul 2008 - mcdurdin - Raise exception if gettempfilename fails
|
|
30 Jan 2009 - mcdurdin - I1839 - Improve XMLEncode performance
|
|
07 Sep 2009 - mcdurdin - I2092 - Regression on XMLEncode, causes invalid text for short XML strings due to buffer overflow
|
|
18 May 2012 - mcdurdin - I3306 - V9.0 - Remove TntControls + Win9x support
|
|
08 Jun 2012 - mcdurdin - I3310 - V9.0 - Unicode in Delphi fixes
|
|
*)
|
|
unit utilxml; // I3306
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes;
|
|
|
|
function XMLEncode(const s: WideString): WideString;
|
|
function XMLFormat(const Args: array of const): WideString;
|
|
function XMLImageTempName(const ImagePath: string; var TempLockFile: string; References: TStrings): string;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Windows,
|
|
StrUtils,
|
|
SysUtils,
|
|
Unicode;
|
|
|
|
{ I1839 }
|
|
function XMLEncode(const s: WideString): WideString;
|
|
var
|
|
I, J: Integer;
|
|
ls, lr: Integer;
|
|
|
|
procedure DoAppendCh(const v: WideChar);
|
|
begin
|
|
if lr <= J+1 then
|
|
begin
|
|
lr := lr * 2;
|
|
SetLength(Result, lr);
|
|
end;
|
|
Result[J] := v;
|
|
Inc(J);
|
|
end;
|
|
|
|
procedure DoAppend(const v: WideString);
|
|
var
|
|
lv, K: Integer;
|
|
begin
|
|
lv := Length(v);
|
|
while lr <= J+lv do
|
|
begin
|
|
lr := lr * 2;
|
|
SetLength(Result, lr);
|
|
end;
|
|
for K := 1 to lv do
|
|
begin
|
|
Result[J] := v[K];
|
|
Inc(J);
|
|
end;
|
|
end;
|
|
begin
|
|
ls := Length(s);
|
|
lr := ls * 2;
|
|
SetLength(Result, lr);
|
|
J := 1;
|
|
for I := 1 to ls do
|
|
begin
|
|
case s[I] of
|
|
'<': DoAppend('<');
|
|
'>': DoAppend('>');
|
|
'&': DoAppend('&');
|
|
'''': DoAppend(''');
|
|
'"': DoAppend('"');
|
|
else DoAppendCh(s[I]);
|
|
end;
|
|
end;
|
|
SetLength(Result, J-1);
|
|
end;
|
|
|
|
function XMLFormat(const Args: array of const): WideString;
|
|
var
|
|
Value, FTag: WideString;
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to High(Args) div 2 do
|
|
begin
|
|
with Args[I*2] do
|
|
case VType of
|
|
vtPWideChar: FTag := VPWideChar;
|
|
vtString: FTag := String_AtoU(VString^); // I3310
|
|
vtAnsiString: FTag := String_AtoU(AnsiString(VAnsiString)); // I3310
|
|
vtWideString: FTag := WideString(VWideString);
|
|
vtPChar: FTag := String_AtoU(ansistring(VPChar)); // I3310
|
|
vtUnicodeString: FTag := UnicodeString(VUnicodeString); // I3310
|
|
else
|
|
Assert(False, 'Invalid VType');
|
|
end;
|
|
|
|
with Args[I*2+1] do
|
|
case VType of
|
|
vtInteger: Value := IntToStr(VInteger);
|
|
vtBoolean: begin if VBoolean then Result := Result + '<'+FTag+' />'; Continue; end;
|
|
vtChar: Value := String_AtoU(VChar); // I3310
|
|
vtExtended: Value := FloatToStr(VExtended^);
|
|
vtString: Value := String_AtoU(VString^); // I3310
|
|
vtPChar: Value := String_AtoU(ansistring(VPChar)); // I3310
|
|
vtAnsiString: Value := String_AtoU(ansistring(VAnsiString)); // I3310
|
|
vtCurrency: Value := CurrToStr(VCurrency^);
|
|
vtVariant: Value := string(VVariant^);
|
|
vtInt64: Value := IntToStr(VInt64^);
|
|
vtPWideChar: Value := VPWideChar;
|
|
vtWideString: Value := WideString(VWideString);
|
|
vtUnicodeString: Value := UnicodeString(VUnicodeString); // I3310
|
|
else
|
|
Assert(False, 'Unsupported VType');
|
|
end;
|
|
|
|
if Value <> '' then
|
|
if Copy(FTag,1,2) = 'x:'
|
|
then Result := Result + '<'+Copy(FTag,3,Length(FTag))+'>'+Value+'</'+Copy(FTag,3,Length(FTag))+'>'
|
|
else Result := Result + '<'+FTag+'>'+XMLEncode(Value)+'</'+FTag+'>';
|
|
end;
|
|
end;
|
|
|
|
function XMLImageTempName(const ImagePath: string; var TempLockFile: string; References: TStrings): string;
|
|
var
|
|
s: string;
|
|
buf: array[0..260] of char;
|
|
begin
|
|
s := ExcludeTrailingPathDelimiter(ImagePath);
|
|
if GetTempFileName(PChar(s), 'kmn', 0, buf) = 0 then
|
|
RaiseLastOSError;
|
|
TempLockFile := buf;
|
|
Result := ChangeFileExt(TempLockFile, '.bmp');
|
|
References.Add(ExtractFileName(Result));
|
|
end;
|
|
|
|
end.
|