简单翻译,帮忙一下成C的语法,只要是后面一句看不懂。 (50分)

W

wukw

Unregistered / Unconfirmed
GUEST, unregistred user!
FExists: Boolean;
property Exists: Boolean read FExists;
{ True if tag found }
(主要是后面一句看不懂,既然是Boolean,为什么还要read FExists;呢?)
以下是所有源代码:
代码:
{ $RCSfile: ID3v2.pas,v $ $Revision: 1.8 $ $Date: 2002/11/12 15:44:29 $ $Author: vlads $ }
{ *************************************************************************** }
{                                                                             }
{ Audio Tools Library (Freeware)                                              }
{ Class TID3v2 - for manipulating with ID3v2 tags                             }
{                                                                             }
{ Copyright (c) 2001,2002 by Jurgen Faul                                      }
{ E-mail: jfaul@gmx.de                                                        }
{ http://jfaul.de/atl                                                         }
{                                                                             }
{ +vlads fix for "Track number as string":                                    }
{ +vlads fix for "Read":                                                      }
{                                                                             }
{ Version 1.7 (2 October 2002)                                                }
{   - Added property TrackString                                              }
{                                                                             }
{ Version 1.6 (29 July 2002)                                                  }
{   - Reading support for Unicode                                             }
{   - Removed limitation for the track number                                 }
{                                                                             }
{ Version 1.5 (23 May 2002)                                                   }
{   - Support for padding                                                     }
{                                                                             }
{ Version 1.4 (24 March 2002)                                                 }
{   - Reading support for ID3v2.2.x &
ID3v2.4.x tags                          }
{                                                                             }
{ Version 1.3 (16 February 2002)                                              }
{   - Fixed bug with property Comment                                         }
{   - Added info: composer, encoder, copyright, language, link                }
{                                                                             }
{ Version 1.2 (17 October 2001)                                               }
{   - Writing support for ID3v2.3.x tags                                      }
{   - Fixed bug with track number detection                                   }
{   - Fixed bug with tag reading                                              }
{                                                                             }
{ Version 1.1 (31 August 2001)                                                }
{   - Added public procedure ResetData                                        }
{                                                                             }
{ Version 1.0 (14 August 2001)                                                }
{   - Reading support for ID3v2.3.x tags                                      }
{   - Tag info: title, artist, album, track, year, genre, comment             }
{                                                                             }
{ *************************************************************************** }
unit ID3v2;
interface
uses
  Classes, SysUtils;
const
  TAG_VERSION_2_2 = 2;
{ Code for ID3v2.2.x tag }
  TAG_VERSION_2_3 = 3;
{ Code for ID3v2.3.x tag }
  TAG_VERSION_2_4 = 4;
{ Code for ID3v2.4.x tag }
type
  { Class TID3v2 }
  TID3v2 = class(TObject)
  private
    { Private declarations }
    FExists: Boolean;
    FVersionID: Byte;
    FSize: Integer;
    FTitle: string;
    FArtist: string;
    FAlbum: string;
    FTrack: Word;
    FTrackString: string;
    FYear: string;
    FGenre: string;
    FComment: string;
    FComposer: string;
    FEncoder: string;
    FCopyright: string;
    FLanguage: string;
    Flink: string;
    procedure FSetTitle(const NewTitle: string);
    procedure FSetArtist(const NewArtist: string);
    procedure FSetAlbum(const NewAlbum: string);
    procedure FSetTrack(const NewTrack: Word);
    { vlads fix: }
    procedure FSetTrackString(const NewTrack: string);
    procedure FSetYear(const NewYear: string);
    procedure FSetGenre(const NewGenre: string);
    procedure FSetComment(const NewComment: string);
    procedure FSetComposer(const NewComposer: string);
    procedure FSetEncoder(const NewEncoder: string);
    procedure FSetCopyright(const NewCopyright: string);
    procedure FSetLanguage(const NewLanguage: string);
    procedure FSetLink(const NewLink: string);
    function ProcessRead(var SourceFile: file): Boolean;
  public
    { Public declarations }
    constructor Create;
{ Create object }
    procedure ResetData;
{ Reset all data }
    { vlads fix: }
    function ReadFromFile(const FileName: string): Boolean;
overload;
{ Load tag }
    function ReadFromFile(var SourceFile: file): Boolean;
overload;
{ Load tag }
    function SaveToFile(const FileName: string): Boolean;
{ Save tag }
    function RemoveFromFile(const FileName: string): Boolean;
{ Delete tag }
    property Exists: Boolean read FExists;
{ True if tag found }
    property VersionID: Byte read FVersionID;
{ Version code }
    property Size: Integer read FSize;
{ Total tag size }
    property Title: string read FTitle write FSetTitle;
{ Song title }
    property Artist: string read FArtist write FSetArtist;
{ Artist name }
    property Album: string read FAlbum write FSetAlbum;
{ Album title }
    property Track: Word read FTrack write FSetTrack;
{ Track number }
    { vlads fix: }
    property TrackString: string read FTrackString write FSetTrackString;
{ Track number as string }
    property Year: string read FYear write FSetYear;
{ Release year }
    property Genre: string read FGenre write FSetGenre;
{ Genre name }
    property Comment: string read FComment write FSetComment;
{ Comment }
    property Composer: string read FComposer write FSetComposer;
{ Composer }
    property Encoder: string read FEncoder write FSetEncoder;
{ Encoder }
    property Copyright: string read FCopyright write FSetCopyright;
{ (c) }
    property Language: string read FLanguage write FSetLanguage;
{ Language }
    property Link: string read Flink write FSetLink;
{ URL link }
  end;
implementation
uses ATLcommon;
{$I+}
const
  { ID3v2 tag ID }
  ID3V2_ID = 'ID3';
  { Max. number of supported tag frames }
  ID3V2_FRAME_COUNT = 16;
  { Names of supported tag frames (ID3v2.3.x &
ID3v2.4.x) }
  ID3V2_FRAME_NEW: array[1..ID3V2_FRAME_COUNT] of string =
  ('TIT2', 'TPE1', 'TALB', 'TRCK', 'TYER', 'TCON', 'COMM', 'TCOM', 'TENC',
    'TCOP', 'TLAN', 'WXXX', 'TDRC', 'TOPE', 'TIT1', 'TOAL');
  { Names of supported tag frames (ID3v2.2.x) }
  ID3V2_FRAME_OLD: array[1..ID3V2_FRAME_COUNT] of string =
  ('TT2', 'TP1', 'TAL', 'TRK', 'TYE', 'TCO', 'COM', 'TCM', 'TEN',
    'TCR', 'TLA', 'WXX', 'TOR', 'TOA', 'TT1', 'TOT');
  { Max. tag size for saving }
  ID3V2_MAX_SIZE = 4096;
  { Unicode ID }
  UNICODE_ID = #1;
type
  { Frame header (ID3v2.3.x &
ID3v2.4.x) }
  FrameHeaderNew = record
    ID: array[1..4] of Char;
{ Frame ID }
    Size: Integer;
{ Size excluding header }
    Flags: Word;
{ Flags }
  end;
  { Frame header (ID3v2.2.x) }
  FrameHeaderOld = record
    ID: array[1..3] of Char;
{ Frame ID }
    Size: array[1..3] of Byte;
{ Size excluding header }
  end;
  { ID3v2 header data - for internal use }
  TagInfo = record
    { Real structure of ID3v2 header }
    ID: array[1..3] of Char;
{ Always "ID3" }
    Version: Byte;
{ Version number }
    Revision: Byte;
{ Revision number }
    Flags: Byte;
{ Flags of tag }
    Size: array[1..4] of Byte;
{ Tag size excluding header }
    { Extended data }
    Filesize: Integer;
{ File size (bytes) }
    Frame: array[1..ID3V2_FRAME_COUNT] of string;
{ Information from frames }
    NeedRewrite: Boolean;
{ Tag should be rewritten }
    PaddingSize: Integer;
{ Padding size (bytes) }
  end;
  { vlads fix: }
  PTagInfo = ^TagInfo;
  Size32 = array[1..4] of Byte;
  { ********************* Auxiliary functions &
procedures ******************** }
function ReadHeader(var SourceFile: file;
var Tag: TagInfo): Boolean;
overload;
var
  Transferred: Integer;
begin
  try
    Result := True;
    Seek(SourceFile, 0);
    { Read header and get file size }
    BlockRead(SourceFile, Tag, 10, Transferred);
    Tag.Filesize := Filesize(SourceFile);
    { if transfer is not complete }
    if Transferred < 10 then
      Result := False;
  except
    { Error }
    Result := False;
  end;
end;
function ReadHeader(const FileName: string;
var Tag: TagInfo): Boolean;
overload;
var
  SourceFile: file;
begin
  try
    { Set read-access and open file }
    AssignFile(SourceFile, FileName);
    FileMode := 0;
    Reset(SourceFile, 1);
    { Read header and get file size }
    Result := ReadHeader(SourceFile, Tag);
    CloseFile(SourceFile);
  except
    { Error }
    Result := False;
  end;
end;
{ --------------------------------------------------------------------------- }
function GetTagSize(const Tag: TagInfo): Integer;
begin
  { Get total tag size }
  Result :=
  Tag.Size[1] * $200000 +
  Tag.Size[2] * $4000 +
  Tag.Size[3] * $80 +
  Tag.Size[4] + 10;
  if Tag.Flags and $10 = $10 then
    Inc(Result, 10);
  if Result > Tag.Filesize then
    Result := 0;
end;
{ --------------------------------------------------------------------------- }
procedure SetTagItem(const ID, Data: string;
var Tag: TagInfo);
var
  Iterator: Byte;
  FrameID: string;
begin
  { Set tag item if supported frame found }
  for Iterator := 1 to ID3V2_FRAME_COUNTdo
  begin
    if Tag.Version > TAG_VERSION_2_2 then
      FrameID := ID3V2_FRAME_NEW[Iterator]
    else
      FrameID := ID3V2_FRAME_OLD[Iterator];
    if (FrameID = ID) and (Data[1] <= UNICODE_ID) then
      Tag.Frame[Iterator] := Data;
  end;
end;
{ --------------------------------------------------------------------------- }
function Swap32(const Figure: Integer): Integer;
overload;
var
  ByteArray: array[1..4] of Byte absolute Figure;
begin
  { Swap 4 bytes }
  Result :=
  ByteArray[1] * $1000000 +
  ByteArray[2] * $10000 +
  ByteArray[3] * $100 +
  ByteArray[4];
end;
function Swap32(const ByteArray: Size32): Integer;
overload;
begin
  { Swap 4 bytes }
  Result :=
  ByteArray[1] * $1000000 +
  ByteArray[2] * $10000 +
  ByteArray[3] * $100 +
  ByteArray[4];
end;
{ --------------------------------------------------------------------------- }
procedure ReadFramesNewSlow(var SourceFile: file;
var Tag: TagInfo);
var
  Frame: FrameHeaderNew;
  Data: array[1..500] of Char;
  DataPosition, DataSize: Integer;
begin
  { Get information from frames (ID3v2.3.x &amp;
ID3v2.4.x) }
  try
    Seek(SourceFile, 10);
    while (FilePos(SourceFile) < GetTagSize(Tag)) and (not EOF(SourceFile))do
    begin
      FillChar(Data, SizeOf(Data), 0);
      { Read frame header and check frame ID }
      BlockRead(SourceFile, Frame, 10);
      if not (Frame.ID[1] in ['A'..'Z']) then
        Break;
      { Note data position and determine significant data size }
      DataPosition := FilePos(SourceFile);
      if Swap32(Frame.Size) > SizeOf(Data) then
        DataSize := SizeOf(Data)
      else
        DataSize := Swap32(Frame.Size);
      { Read frame data and set tag item if frame supported }
      BlockRead(SourceFile, Data, DataSize);
      SetTagItem(Frame.ID, Data, Tag);
      Seek(SourceFile, DataPosition + Swap32(Frame.Size));
    end;
  except
  end;
end;
{orig Read ID3v2      2600 files, 50 folders, 1.302 sec, 0.0005008 sec/per file}
{buff Read ID3v2      2600 files, 50 folders, 1.252 sec, 0.0004815 sec/per file}
procedure ReadFramesNew(var SourceFile: file;
var Tag: TagInfo);
var
  Frame: FrameHeaderNew;
  Data: array[1..500] of Char;
  DataSize: Integer;
  tagSIZE, AmtTransferred: Integer;
  Buffer: PChar;
  BufferPos: Integer;
  Bptr: PChar;
begin
  tagSIZE := GetTagSize(Tag);
  Buffer := AllocMem(tagSIZE);
  { Get information from frames (ID3v2.3.x &amp;
ID3v2.4.x) }
  try
    Seek(SourceFile, 10);
    BlockRead(SourceFile, Buffer^, tagSIZE, AmtTransferred);
    if (tagSIZE <> AmtTransferred) then
      ReadFramesNewSlow(SourceFile, Tag)
    else
    begin
      BufferPos := 0;
      while (BufferPos < tagSIZE) and (BufferPos < AmtTransferred)do
      begin
        FillChar(Data, SizeOf(Data), 0);
        Bptr := Buffer + BufferPos;
        { Read frame header and check frame ID }
        Move(Bptr^, Frame, 10);
        Bptr := Buffer + BufferPos + 10;
        if not (Frame.ID[1] in ['A'..'Z']) then
          Break;
        { Note data position and determine significant data size }
        if Swap32(Frame.Size) > SizeOf(Data) then
          DataSize := SizeOf(Data)
        else
          DataSize := Swap32(Frame.Size);
        { Read frame data and set tag item if frame supported }
        Move(Bptr^, Data, DataSize);
        SetTagItem(Frame.ID, Data, Tag);
        Inc(BufferPos, 10 + Swap32(Frame.Size));
      end;
    end;
  except
  end;
  FreeMem(Buffer);
end;
{ --------------------------------------------------------------------------- }
procedure ReadFramesOld(var SourceFile: file;
var Tag: TagInfo);
var
  Frame: FrameHeaderOld;
  Data: array[1..500] of Char;
  DataPosition, FrameSize, DataSize: Integer;
begin
  { Get information from frames (ID3v2.2.x) }
  try
    { Set read-access, open file }
    Seek(SourceFile, 10);
    while (FilePos(SourceFile) < GetTagSize(Tag)) and (not EOF(SourceFile))do
    begin
      FillChar(Data, SizeOf(Data), 0);
      { Read frame header and check frame ID }
      BlockRead(SourceFile, Frame, 6);
      if not (Frame.ID[1] in ['A'..'Z']) then
        Break;
      { Note data position and determine significant data size }
      DataPosition := FilePos(SourceFile);
      FrameSize := Frame.Size[1] shl 16 + Frame.Size[2] shl 8 + Frame.Size[3];
      if FrameSize > SizeOf(Data) then
        DataSize := SizeOf(Data)
      else
        DataSize := FrameSize;
      { Read frame data and set tag item if frame supported }
      BlockRead(SourceFile, Data, DataSize);
      SetTagItem(Frame.ID, Data, Tag);
      Seek(SourceFile, DataPosition + FrameSize);
    end;
  except
  end;
end;
{ --------------------------------------------------------------------------- }
function GetANSI(const Source: string): string;
var
  Index: Integer;
  FirstByte, SecondByte: Byte;
  UnicodeChar: WideChar;
begin
  { Convert string from unicode if needed and trim spaces }
  if (Length(Source) > 0) and (Source[1] = UNICODE_ID) then
  begin
    Result := '';
    for Index := 1 to ((Length(Source) - 1) div 2)do
    begin
      FirstByte := Ord(Source[Index * 2]);
      SecondByte := Ord(Source[Index * 2 + 1]);
      UnicodeChar := WideChar(FirstByte or (SecondByte shl 8));
      if UnicodeChar = #0 then
        Break;
      if FirstByte < $FF then
        Result := Result + UnicodeChar;
    end;
    Result := Trim(Result);
  end
  else
    Result := Trim(Source);
end;
{ --------------------------------------------------------------------------- }
function GetContent(const Content1, Content2: string): string;
begin
  { Get content preferring the first content }
  Result := GetANSI(Content1);
  if Result = '' then
    Result := GetANSI(Content2);
end;
{ --------------------------------------------------------------------------- }
function ExtractTrack(const TrackString: string): Word;
var
  Track: string;
  Index, Value, Code: Integer;
begin
  { Extract track from string }
  Track := GetANSI(TrackString);
  { Extract track from string like [02/20] }
  Index := Pos('/', Track);
  { vlads fix: Extract track from string like [02 of 20] }
  if Index = 0 then
    Index := Pos(' ', Track);
  if Index = 0 then
    Val(Track, Value, Code)
  else
    Val(Copy(Track, 1, Index - 1), Value, Code);
  if Code = 0 then
    Result := Value
  else
    Result := 0;
end;
{ --------------------------------------------------------------------------- }
function ExtractYear(const YearString, DateString: string): string;
begin
  { Extract year from strings }
  Result := GetANSI(YearString);
  if Result = '' then
    Result := Copy(GetANSI(DateString), 1, 4);
end;
{ --------------------------------------------------------------------------- }
function ExtractGenre(const GenreString: string): string;
begin
  { Extract genre from string }
  Result := GetANSI(GenreString);
  if Pos(')', Result) > 0 then
    Delete(Result, 1, LastDelimiter(')', Result));
end;
{ --------------------------------------------------------------------------- }
function ExtractText(const SourceString: string;
LanguageID: Boolean): string;
var
  Source, Separator: string;
  EncodingID: Char;
begin
  { Extract significant text data from a complex field }
  Source := SourceString;
  Result := '';
  if Length(Source) > 0 then
  begin
    EncodingID := Source[1];
    if EncodingID = UNICODE_ID then
      Separator := #0#0
    else
      Separator := #0;
    if LanguageID then
      Delete(Source, 1, 4)
    else
      Delete(Source, 1, 1);
    Delete(Source, 1, Pos(Separator, Source) + Length(Separator) - 1);
    Result := GetANSI(EncodingID + Source);
  end;
end;
{ --------------------------------------------------------------------------- }
procedure BuildHeader(var Tag: TagInfo);
var
  Iterator, tagSIZE: Integer;
begin
  { Calculate new tag size (without padding) }
  tagSIZE := 10;
  for Iterator := 1 to ID3V2_FRAME_COUNTdo
    if Tag.Frame[Iterator] <> '' then
      Inc(tagSIZE, Length(Tag.Frame[Iterator]) + 11);
  { Check for ability to change existing tag }
  Tag.NeedRewrite :=
  (Tag.ID <> ID3V2_ID) or
  (GetTagSize(Tag) < tagSIZE) or
  (GetTagSize(Tag) > ID3V2_MAX_SIZE);
  { Calculate padding size and set padded tag size }
  if Tag.NeedRewrite then
    Tag.PaddingSize := ID3V2_MAX_SIZE - tagSIZE
  else
    Tag.PaddingSize := GetTagSize(Tag) - tagSIZE;
  Inc(tagSIZE, Tag.PaddingSize);
  { Build tag header }
  Tag.ID := ID3V2_ID;
  Tag.Version := TAG_VERSION_2_3;
  Tag.Revision := 0;
  Tag.Flags := 0;
  { Convert tag size }
  for Iterator := 1 to 4do
    Tag.Size[Iterator] := ((tagSIZE - 10) shr ((4 - Iterator) * 7)) and $7F;
end;
{ --------------------------------------------------------------------------- }
function ReplaceTag(const FileName: string;
TagData: TStream): Boolean;
var
  Destination: TFileStream;
begin
  { Replace old tag with new tag data }
  Result := False;
  if (not FileExistsUnsetReadOnly(FileName)) then
    Exit;
  try
    TagData.Position := 0;
    Destination := TFileStream.Create(FileName, fmOpenReadWrite);
    Destination.CopyFrom(TagData, TagData.Size);
    Destination.Free;
    Result := True;
  except
    { Access error }
  end;
end;
{ --------------------------------------------------------------------------- }
function RebuildFile(const FileName: string;
TagData: TStream): Boolean;
var
  Tag: TagInfo;
  Source, Destination: TFileStream;
  BufferName: string;
begin
  { Rebuild file with old file data and new tag data (optional) }
  Result := False;
  if (not FileExistsUnsetReadOnly(FileName)) then
    Exit;
  if not ReadHeader(FileName, Tag) then
    Exit;
  if (TagData = nil) and (Tag.ID <> ID3V2_ID) then
    Exit;
  try
    { Create file streams }
    BufferName := FileName + '~';
    Source := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive);
    Destination := TFileStream.Create(BufferName, fmCreate);
    { Copy data blocks }
    if Tag.ID = ID3V2_ID then
      Source.Seek(GetTagSize(Tag), soFrombegin
ning);
    if TagData <> nil then
      Destination.CopyFrom(TagData, 0);
    Destination.CopyFrom(Source, Source.Size - Source.Position);
    { Free resources }
    Source.Free;
    Destination.Free;
    { Replace old file and delete temporary file }
    if (DeleteFile(FileName)) and (RenameFile(BufferName, FileName)) then
      Result := True
    else
      raise Exception.Create('');
  except
    { Access error }
    if FileExists(BufferName) then
      DeleteFile(BufferName);
  end;
end;
{ --------------------------------------------------------------------------- }
function SaveTag(const FileName: string;
Tag: TagInfo): Boolean;
var
  TagData: TStringStream;
  Iterator, FrameSize: Integer;
  Padding: array[1..ID3V2_MAX_SIZE] of Byte;
begin
  { Build and write tag header and frames to stream }
  TagData := TStringStream.Create('');
  BuildHeader(Tag);
  TagData.Write(Tag, 10);
  for Iterator := 1 to ID3V2_FRAME_COUNTdo
    if Tag.Frame[Iterator] <> '' then
    begin
      TagData.WriteString(ID3V2_FRAME_NEW[Iterator]);
      FrameSize := Swap32(Length(Tag.Frame[Iterator]) + 1);
      TagData.Write(FrameSize, SizeOf(FrameSize));
      TagData.WriteString(#0#0#0 + Tag.Frame[Iterator]);
    end;
  { Add padding }
  FillChar(Padding, SizeOf(Padding), 0);
  if Tag.PaddingSize > 0 then
    TagData.Write(Padding, Tag.PaddingSize);
  { Rebuild file or replace tag with new tag data }
  if Tag.NeedRewrite then
    Result := RebuildFile(FileName, TagData)
  else
    Result := ReplaceTag(FileName, TagData);
  TagData.Free;
end;
{ ********************** Private functions &amp;
procedures ********************* }
procedure TID3v2.FSetTitle(const NewTitle: string);
begin
  { Set song title }
  FTitle := Trim(NewTitle);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetArtist(const NewArtist: string);
begin
  { Set artist name }
  FArtist := Trim(NewArtist);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetAlbum(const NewAlbum: string);
begin
  { Set album title }
  FAlbum := Trim(NewAlbum);
end;
{ --------------------------------------------------------------------------- }
{ vlads fix: }
procedure TID3v2.FSetTrack(const NewTrack: Word);
begin
  { Set track number }
  { This will set a number value but Sting would be used when stored }
  FTrack := NewTrack;
  FTrackString := IntToStr(FTrack);
end;
{ --------------------------------------------------------------------------- }
{ vlads fix: }
procedure TID3v2.FSetTrackString(const NewTrack: string);
begin
  { Set track number }
  FTrackString := NewTrack;
  { This will set a number value but Sting would be used when stored }
  FTrack := ExtractTrack(FTrackString);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetYear(const NewYear: string);
begin
  { Set release year }
  FYear := Trim(NewYear);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetGenre(const NewGenre: string);
begin
  { Set genre name }
  FGenre := Trim(NewGenre);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetComment(const NewComment: string);
begin
  { Set comment }
  FComment := Trim(NewComment);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetComposer(const NewComposer: string);
begin
  { Set composer name }
  FComposer := Trim(NewComposer);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetEncoder(const NewEncoder: string);
begin
  { Set encoder name }
  FEncoder := Trim(NewEncoder);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetCopyright(const NewCopyright: string);
begin
  { Set copyright information }
  FCopyright := Trim(NewCopyright);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetLanguage(const NewLanguage: string);
begin
  { Set language }
  FLanguage := Trim(NewLanguage);
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.FSetLink(const NewLink: string);
begin
  { Set URL link }
  Flink := Trim(NewLink);
end;
{ ********************** Public functions &amp;
procedures ********************** }
constructor TID3v2.Create;
begin
  { Create object }
  inherited;
  ResetData;
end;
{ --------------------------------------------------------------------------- }
procedure TID3v2.ResetData;
begin
  { Reset all variables }
  FExists := False;
  FVersionID := 0;
  FSize := 0;
  FTitle := '';
  FArtist := '';
  FAlbum := '';
  FTrack := 0;
  FTrackString := '';
  FYear := '';
  FGenre := '';
  FComment := '';
  FComposer := '';
  FEncoder := '';
  FCopyright := '';
  FLanguage := '';
  Flink := '';
end;
{ --------------------------------------------------------------------------- }
function TID3v2.ReadFromFile(const FileName: string): Boolean;
var
  SourceFile: file;
begin
  { Reset data and load header from file to variable }
  ResetData;
  try
    AssignFile(SourceFile, FileName);
    FileMode := 0;
    Reset(SourceFile, 1);
  except
    Result := False;
    Exit;
  end;
  Result := ProcessRead(SourceFile);
  CloseFile(SourceFile);
end;
function TID3v2.ReadFromFile(var SourceFile: file): Boolean;
begin
  { Reset data and load header from file to variable }
  ResetData;
  Result := ProcessRead(SourceFile);
end;
function TID3v2.ProcessRead(var SourceFile: file): Boolean;
var
  Tag: TagInfo;
begin
  Result := ReadHeader(SourceFile, Tag);
  { Process data if loaded and header valid }
  if (Result) and (Tag.ID = ID3V2_ID) then
  begin
    FExists := True;
    { Fill properties with header data }
    FVersionID := Tag.Version;
    FSize := GetTagSize(Tag);
    { Get information from frames if version supported }
    if (FVersionID in [TAG_VERSION_2_2..TAG_VERSION_2_4]) and (FSize > 0) then
    begin
      if FVersionID > TAG_VERSION_2_2 then
        ReadFramesNew(SourceFile, Tag)
      else
        ReadFramesOld(SourceFile, Tag);
      FTitle := TruncateToZerro(GetContent(Tag.Frame[1], Tag.Frame[15]));
      FArtist := TruncateToZerro(GetContent(Tag.Frame[2], Tag.Frame[14]));
      FAlbum := TruncateToZerro(GetContent(Tag.Frame[3], Tag.Frame[16]));
      FTrack := ExtractTrack(Tag.Frame[4]);
      FTrackString := TruncateToZerro(GetANSI(Tag.Frame[4]));
      FYear := TruncateToZerro(ExtractYear(Tag.Frame[5], Tag.Frame[13]));
      FGenre := TruncateToZerro(ExtractGenre(Tag.Frame[6]));
      FComment := TruncateToZerro(ExtractText(Tag.Frame[7], True));
      FComposer := TruncateToZerro(GetANSI(Tag.Frame[8]));
      FEncoder := TruncateToZerro(GetANSI(Tag.Frame[9]));
      FCopyright := TruncateToZerro(GetANSI(Tag.Frame[10]));
      FLanguage := TruncateToZerro(GetANSI(Tag.Frame[11]));
      Flink := TruncateToZerro(ExtractText(Tag.Frame[12], False));
    end;
  end;
end;
{ --------------------------------------------------------------------------- }
function TID3v2.SaveToFile(const FileName: string): Boolean;
var
  Tag: TagInfo;
begin
  { Check for existing tag }
  FillChar(Tag, SizeOf(Tag), 0);
  ReadHeader(FileName, Tag);
  { Prepare tag data and save to file }
  Tag.Frame[1] := FTitle;
  Tag.Frame[2] := FArtist;
  Tag.Frame[3] := FAlbum;
  {vlads fix: Save Track as Sting not as Number}
  // if FTrack > 0 then
 Tag.Frame[4] := IntToStr(FTrack);
  Tag.Frame[4] := FTrackString;
  Tag.Frame[5] := FYear;
  Tag.Frame[6] := FGenre;
  if FComment <> '' then
    Tag.Frame[7] := 'eng' + #0 + FComment;
  Tag.Frame[8] := FComposer;
  Tag.Frame[9] := FEncoder;
  Tag.Frame[10] := FCopyright;
  Tag.Frame[11] := FLanguage;
  if Flink <> '' then
    Tag.Frame[12] := #0 + Flink;
  Result := SaveTag(FileName, Tag);
end;
{ --------------------------------------------------------------------------- }
function TID3v2.RemoveFromFile(const FileName: string): Boolean;
begin
  { Remove tag from file }
  Result := RebuildFile(FileName, nil);
end;
end.
 
C

CathyEagle

Unregistered / Unconfirmed
GUEST, unregistred user!
是这样的,在OO中,FExists是类的成员变量,如果你希望外部访问它,就应该使用
Set/Get方法,这在delphi中有所发展,如下所示,Exists不过是FExists的外部表现
罢了,它并不是真正的变量,它的值来自FExists,所有要read FExists
property Exists: Boolean read FExists;
{ True if tag found }
 

小雨哥

Unregistered / Unconfirmed
GUEST, unregistred user!
你好 wukw ,代码太长,没看完,
FExists: Boolean;
property Exists: Boolean read FExists;
{ True if tag found }
这里表达了 2 个意思,
1.这个属性是对外暴露的,你通过它知道内部发生了什么,这是 oo 思想吧。
2.这个属性是只读的,你不能由外部,有意无意地修改它。
暂时先回答这些,有问题一起聊聊。
 
X

xianjun

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵, 我的意思是说你找不到现在的代码的情况下才自己翻译
你怎么二话不说就直接开干呢? 其实很多东西别人都帮你做好啦:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/massid3lib/mp3tagtools/
 
W

wukw

Unregistered / Unconfirmed
GUEST, unregistred user!
>>呵呵, 我的意思是说你找不到现在的代码的情况下才自己翻译
>>你怎么二话不说就直接开干呢? 其实很多东西别人都帮你做好啦:
>>http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/massid3lib/mp3tagtools/

完了,看到这句话的时候,已经晚了,我已经把所有的代码初步翻译了一遍(累得都想吐血,500多行全部手动敲入),当然里面还有无数的错误。
已经贴在那个帖子里了:
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=1474870
如果可以的话,xianjun大哥帮我从您给的网址里找出那几个关键的Class,好吗?我下载了几个,觉得都不对(居然只能一个一个下载)
如果不行,那就只能麻烦您帮我改错了。
唉,都怪我太笨了,大学里没好好学~~~~~~~~[:(][:(][:(]
 
L

lovinger_2000

Unregistered / Unconfirmed
GUEST, unregistred user!
楼主,能不能提供一下你Audio Tools Library (上面那段代码的完整套件)的链接地址,如果不大的也可以发到我的邮箱里面,谢谢你。我的邮箱是:pc-bird@vip.sina.com
 

Similar threads

I
回复
0
查看
436
import
I
I
回复
0
查看
640
import
I
I
回复
0
查看
789
import
I
I
回复
0
查看
683
import
I
顶部