📄 jvqid3v2base.pas
字号:
nil, { fiMetaCrypto (only in 2.2) }
nil { fiMetaCompressio (only in 2.2) }
);
//=== Local procedures =======================================================
function LengthUTF8Str(const SW: WideString): Integer;
begin
Result := Length(WideStringToUTF8(SW));
end;
function GetStringA(const SP: TJvID3StringPair; const Encoding: TJvID3Encoding): string;
begin
{ Returns a ansi string from the string holder SP, Encoding specifies
whether the result string should be from the unicode or ansi part of SP }
case Encoding of
ienISO_8859_1:
Result := SP.SA;
ienUTF_16, ienUTF_16BE, ienUTF_8:
Result := WideStringToStringEx(SP.SW, CP_ACP);
else
ID3Error(RsEID3UnknownEncoding);
end;
end;
function GetStringW(const SP: TJvID3StringPair; const Encoding: TJvID3Encoding): WideString;
begin
{ Returns a unicode string from the string holder SP, Encoding specifies
whether the result string should be from the unicode or ansi part of SP }
case Encoding of
ienISO_8859_1:
Result := StringToWideStringEx(SP.SA, CP_ACP);
ienUTF_16, ienUTF_16BE, ienUTF_8:
Result := SP.SW;
else
ID3Error(RsEID3UnknownEncoding);
end;
end;
function SameStringPair(const S1, S2: TJvID3StringPair; const Enc1, Enc2: TJvID3Encoding): Boolean;
var
SW1, SW2: WideString;
begin
{ Compares two string pairs, without case sensitivity; it's used to check if
2 frames have the same content descriptor; documentation is not clear whether
this must be done with case sensitivity or not. }
if (Enc1 = Enc2) and (Enc1 = ienISO_8859_1) then
Result := AnsiSameStr(S1.SA, S2.SA)
else
begin
if Enc1 = ienISO_8859_1 then
SW1 := StringToWideStringEx(S1.SA, CP_ACP)
else
SW1 := S1.SW;
if Enc2 = ienISO_8859_1 then
SW2 := StringToWideStringEx(S2.SA, CP_ACP)
else
SW2 := S2.SW;
Result := JclUnicode.StrICompW(PWideChar(SW1), PWideChar(SW2)) = 0;
end;
end;
procedure SetStringA(var SP: TJvID3StringPair; const Encoding: TJvID3Encoding; const S: string);
begin
{ Stores the ansi string S in the string holder SP, Encoding specifies
whether S should be stored in SP as unicode or ansi }
case Encoding of
ienISO_8859_1:
SP.SA := S;
ienUTF_16, ienUTF_16BE, ienUTF_8:
SP.SW := StringToWideStringEx(S, CP_ACP);
else
ID3Error(RsEID3UnknownEncoding);
end;
end;
function GetCharCount(const SP: TJvID3StringPair; const Encoding: TJvID3Encoding): Cardinal;
begin
{ Returns the nr. of characters of a string of a specific encoding }
case Encoding of
ienISO_8859_1:
Result := Length(SP.SA);
ienUTF_16, ienUTF_16BE, ienUTF_8:
Result := Length(SP.SW);
else
Result := 0;
ID3Error(RsEID3UnknownEncoding);
end;
end;
(* make Delphi 5 compiler happy // andreas
function GetByteCount(const SP: TJvID3StringPair; const Encoding: TJvID3Encoding): Cardinal;
begin
{ Returns the nr. of bytes needed to store a string of a specific encoding }
case Encoding of
ienISO_8859_1:
Result := GetCharCount(SP, Encoding);
ienUTF_16:
Result := GetCharCount(SP, Encoding) * 2 + 2 { BOM };
ienUTF_16BE:
Result := GetCharCount(SP, Encoding) * 2;
ienUTF_8:
Result := LengthUTF8Str(GetStringW(SP, Encoding));
else
Result := 0;
ID3Error(RsEID3UnknownEncoding);
end;
end;
*)
function LengthEnc(const S: TJvID3StringPair; const FromEnc, ToEnc: TJvID3Encoding): Cardinal;
begin
{ Calculates the length in bytes needed to store a string in a stream encoded as
ToEnc; the string is encoded as FromEnc in the string pair S;
Very similar to GetByteCount }
case ToEnc of
ienISO_8859_1:
Result := GetCharCount(S, FromEnc);
ienUTF_16:
Result := 2 + 2 * GetCharCount(S, FromEnc);
ienUTF_16BE:
Result := 2 * GetCharCount(S, FromEnc);
ienUTF_8:
Result := LengthUTF8Str(GetStringW(S, FromEnc));
else
Result := 0;
ID3Error(RsEID3UnknownEncoding);
end;
end;
function LengthTerminatorEnc(const Encoding: TJvID3Encoding): Cardinal;
begin
{ Calculates the length in bytes needed to store a terminator in the encoding
specified by Encoding }
case Encoding of
ienISO_8859_1, ienUTF_8:
Result := 1;
ienUTF_16, ienUTF_16BE:
Result := 2;
else
Result := 0;
ID3Error(RsEID3UnknownEncoding);
end;
end;
procedure ClearStringPair(var SP: TJvID3StringPair);
begin
with SP do
begin
SA := '';
SW := '';
end;
end;
procedure CopyStringPair(const Source: TJvID3StringPair; var Dest: TJvID3StringPair);
begin
with Dest do
begin
SA := Source.SA;
SW := Source.SW;
end;
end;
procedure CopyLists(SourceA: TStrings; SourceW: TWideStrings; const SourceEnc: TJvID3Encoding;
DestA: TStrings; DestW: TWideStrings; const DestEnc: TJvID3Encoding);
var
I: Integer;
begin
{ Copies the strings in the stringlist SourceA or SourceW - depending on the
value of SourceEnc - to the stringlist DestA or DestW - depending on the
value of DestEnc }
case SourceEnc of
ienISO_8859_1:
case DestEnc of
ienISO_8859_1:
for I := 0 to SourceA.Count - 1 do
DestA.Add(SourceA[I]);
ienUTF_16, ienUTF_16BE, ienUTF_8:
for I := 0 to SourceA.Count - 1 do
DestW.Add(StringToWideStringEx(SourceA[I], CP_ACP));
else
ID3Error(RsEID3UnknownEncoding);
end;
ienUTF_16, ienUTF_16BE, ienUTF_8:
case DestEnc of
ienISO_8859_1:
for I := 0 to SourceW.Count - 1 do
DestA.Add(WideStringToStringEx(SourceW[I], CP_ACP));
ienUTF_16, ienUTF_16BE, ienUTF_8:
for I := 0 to SourceW.Count - 1 do
DestW.Add(SourceW[I]);
else
ID3Error(RsEID3UnknownEncoding);
end;
else
ID3Error(RsEID3UnknownEncoding);
end;
end;
function CheckIsEmpty(const SP: TJvID3StringPair; const Encoding: TJvID3Encoding): Boolean;
begin
{ Returns True when the string pair SP contains an empty string, otherwise False }
case Encoding of
ienISO_8859_1:
Result := SP.SA = '';
ienUTF_16, ienUTF_16BE, ienUTF_8:
Result := SP.SW = '';
else
Result := False;
ID3Error(RsEID3UnknownEncoding);
end;
end;
function CheckIsURL(Frame: TJvID3Frame; var S: string; const HandleError: TJvID3HandleError): Boolean;
begin
{ Not implemented }
Result := True;
end;
function CheckIsLanguageA(Frame: TJvID3Frame; var S: string; const HandleError: TJvID3HandleError): Boolean;
begin
{ The three byte language field, present in several frames, is used to
describe the language of the frame's content, according to ISO-639-2
[ISO-639-2]. The language should be represented in lower case. If the
language is not known the string "XXX" should be used.
}
Result := (S = cUnknownLanguage) or ISO_639_2IsCode(S);
if not Result then
case HandleError of
heAutoCorrect:
{ Note, don't set Result to True }
S := cUnknownLanguage;
heRaise:
Frame.ErrorFmt(RsEID3InvalidLanguageValue, [S]);
else
Exit;
end
else
if HandleError = heAutoCorrect then
S := AnsiLowerCase(S);
end;
function CheckIsLanguageW(Frame: TJvID3Frame; var S: WideString; const HandleError: TJvID3HandleError): Boolean;
var
SA: string;
begin
{ The three byte language field, present in several frames, is used to
describe the language of the frame's content, according to ISO-639-2
[ISO-639-2]. The language should be represented in lower case. If the
language is not known the string "XXX" should be used.
}
SA := WideStringToStringEx(S, CP_ACP);
Result := CheckIsLanguageA(Frame, SA, HandleError);
if not Result and (HandleError = heAutoCorrect) then
S := StringToWideStringEx(SA, CP_ACP);
end;
function CheckIsID3TimeA(Frame: TJvID3Frame; var S: string; const HandleError: TJvID3HandleError): Boolean;
var
I1, I2: Integer;
begin
{ S must be in HHMM format (H = Hour; M = Minute), and may not be empty }
Result := Length(S) = 4;
if Result then
begin
I1 := StrToIntDef(Copy(S, 1, 2), -1);
I2 := StrToIntDef(Copy(S, 3, 4), -1);
Result := (I1 >= 0) and (I1 < 24) and (I2 >= 0) and (I2 < 60);
end;
if not Result then
case HandleError of
heAutoCorrect:
{ Note, don't set Result to True }
S := '0000';
heRaise:
Frame.ErrorFmt(RsEID3InvalidTimeValue, [S]);
end;
end;
function CheckIsID3Time(Frame: TJvID3Frame; var SP: TJvID3StringPair;
const HandleError: TJvID3HandleError): Boolean;
var
S: string;
begin
S := GetStringA(SP, Frame.Encoding);
Result := CheckIsID3TimeA(Frame, S, HandleError);
if not Result and (HandleError = heAutoCorrect) then
SetStringA(SP, Frame.Encoding, S);
end;
function CheckIsID3DateA(Frame: TJvID3Frame; var S: string; const HandleError: TJvID3HandleError): Boolean;
var
I1, I2: Integer;
begin
{ S must be in DDMM format (D = Day; M = Month), and may not be empty }
Result := Length(S) = 4;
if Result then
begin
I1 := StrToIntDef(Copy(S, 1, 2), -1);
I2 := StrToIntDef(Copy(S, 3, 4), -1);
Result := (I1 >= 1) and (I1 < 32) and (I2 >= 1) and (I2 < 13);
end;
if not Result then
case HandleError of
heAutoCorrect:
{ Note, don't set Result to True }
S := '0101';
heRaise:
Frame.ErrorFmt(RsEID3InvalidDateValue, [S]);
end;
end;
function CheckIsID3Date(Frame: TJvID3Frame; var SP: TJvID3StringPair;
const HandleError: TJvID3HandleError): Boolean;
var
S: string;
begin
S := GetStringA(SP, Frame.Encoding);
Result := CheckIsID3Date
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -