Files
lazarus-ccr/applications/cactusjukebox/source/functions.pas

468 lines
11 KiB
ObjectPascal
Raw Normal View History

{
some helper functions/procedures
written by Sebastian Kraft
sebastian_kraft@gmx.de
This software is free under the GNU Public License
(c)2005-2008
}
Unit functions;
{$mode objfpc}{$H+}
Interface
Uses
Classes, SysUtils, math, config;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function crc32(path: String): longint;
Function crc32_math(path: String): int64;
Function DirectoryIsEmpty(Directory: String): Boolean;
Function EraseDirectory(Directory: String): Boolean; //delete directory and all subdirectories/files in it
Function UTF8toLatin1(utfstring: ansistring): ansistring;
Function Latin1toUTF8(latin1string: ansistring): ansistring;
Function rmZeroChar(s: ansistring): ansistring;
Function FileCopy(Const FromFile, ToFile: String): boolean;
Function FreeSpaceOnDAP: int64;
Function ByteToFmtString(bytes: int64; d1, d2: byte): string;
// converts i.e. 1024 to 1,0 KB
// d1, d2 sets amount of digits before and after ','
Function SecondsToFmtStr(seconds: longint): string;//converts integer to mm:ss time format
Function MSecondsToFmtStr(MSeconds: longint): string;
function MakeValidFilename(Filename: String): string;
procedure BubbleSort(var Items: TStrings);
function IntTodB(i, ref: longint):integer;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Implementation
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function crc32(path: String): longint;
//creates an very, very basic checksum to identify files
Var fhandle: THandle;
buf: array [0..63] Of word;
z: byte;
i, eofile: longint;
l: longint;
Begin
{$Q-}
fhandle := sysutils.fileopen(path, fmOpenRead);
l := 0;
i := 0;
z := 0;
eofile := 0;
While (eofile<>-1) And (i<256) Do
Begin
eofile := FileRead(fhandle, buf, sizeof(buf));
If (eofile<>-1) Then For z:=0 To high(buf) Do begin
L := L+buf[z];
end;
inc(i);
End;
FileClose(fhandle);
result := l;
{$Q+}
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function crc32_math(path: String): int64;
//creates an very, very basic checksum to identify files
Var fhandle: THandle;
buf: array [0..63] Of int64;
z: byte;
i, eofile: longint;
l: int64;
Begin
fhandle := sysutils.fileopen(path, fmOpenRead);
l := 0;
i := 0;
z := 0;
eofile := 0;
While (eofile<>-1) And (i<256) Do
Begin
eofile := FileRead(fhandle, buf, high(buf));
l := l+sumInt(buf);
inc(i);
End;
FileClose(fhandle);
result := l;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function EraseDirectory(Directory: String): Boolean;
Var Srec: TSearchRec;
Begin
result := false;
If DirectoryExists(Directory)Then
Begin
Try
FindFirst(IncludeTrailingPathDelimiter(Directory) + '*', faAnyFile, Srec);
Repeat
Begin
If (Srec.Name <> '.') And (Srec.Name <> '..') Then
DeleteFile(Directory+DirectorySeparator+Srec.Name);
End;
Until FindNext(Srec)<>0;
FindClose(Srec);
result := RemoveDir(Directory);
Except
result := false;
End;
End;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function UTF8toLatin1(utfstring: ansistring): ansistring;
Var i: integer;
tmps: string;
utf16: boolean;
Begin
i := 0;
tmps := '';
utf16 := false;
If length(utfstring)>0 Then
Begin
Repeat
Begin
inc(i);
Case byte(utfstring[i]) Of
$ff: If byte(utfstring[i+1])=$fe Then utf16 := true;
$c3:
Begin
Delete(utfstring, i, 1);
utfstring[i] := char(byte(utfstring[i])+64);
End;
$c2:
Begin
Delete(utfstring, i, 1);
dec(i);
End;
End;
End;
Until (i>=length(utfstring)-1) Or utf16;
//if utf16 detected
If utf16 Then
Begin
i := i+2;
writeln('utf16');
Repeat
Begin
inc(i);
If byte(utfstring[i])<>0 Then tmps := tmps+utfstring[i];
End;
Until (i>=length(utfstring));
End;
End;
If Not utf16 Then result := utfstring
Else Result := tmps;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function rmZeroChar(s: ansistring): ansistring;
Var i: integer;
Begin
i := 0;
If s<>'' Then
Begin
Repeat
Begin
inc(i);
If byte(s[i])=0 Then
Begin
Delete(s, i, 1);
dec(i);
End;
End;
Until i>=length(s)-1;
End;
Result := s;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function Latin1toUTF8(latin1string: ansistring): ansistring;
Var i: integer;
c: char;
tmps: string;
utf16: boolean;
Begin
i := 0;
utf16 := false;
If length(latin1string)>0 Then
Begin
Repeat
Begin
inc(i);
Case byte(latin1string[i]) Of
$ff: If byte(latin1string[i+1])=$fe Then utf16 := true;
$00..$1f:
Begin
Delete(latin1string, i, 1);
dec(i);
End;
$c0..$fd:
Begin
//c0..ff ist der gesamte wertebereich!!
If (byte(latin1string[i])=$c3) And (byte(latin1string[i+1])<$C0) Then inc(i)
Else
Begin
latin1string[i] := char(byte(latin1string[i])-64);
insert(char($c3), latin1string, i);
inc(i);
End;
End;
{ $a1..$bf: begin
c:=latin1string[i];
insert(char($c2), latin1string, i);
// utfstring[i]:=char(byte(utfstring[i])+64);
inc(i);
end;}
End;
End;
Until (i>=length(latin1string)-1) Or utf16;
//if utf16 detected
If utf16 Then
Begin
//latin1string:=AnsiToUtf8(latin1string); may also work instead of following own utf16->utf8 routine
inc(i);
Repeat
Begin
inc(i);
If byte(latin1string[i])>$1f Then
If byte(latin1string[i])<$c0 Then
tmps := tmps+char(byte(latin1string[i]))
Else
tmps := tmps+char($c3)+char(byte(latin1string[i])-64);
End;
Until (i>=length(latin1string));
End;
End;
If Not utf16 Then result := latin1string
Else Result := tmps;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{ Function to copy a file FromFile -> ToFile , mainly used while upload to player device}
Function FileCopy(Const FromFile, ToFile: String): boolean;
Var
FromF, ToF: file;
NumRead, NumWritten: Word;
Buf: array[1..4096] Of byte;
Begin
Try
AssignFile(FromF, FromFile);
Reset(FromF, 1); { Record size = 1 }
AssignFile(ToF, ToFile); { Open output file }
Rewrite(ToF, 1); { Record size = 1 }
Repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
BlockWrite(ToF, Buf, NumRead, NumWritten);
Until (NumRead = 0) Or (NumWritten <> NumRead);
CloseFile(FromF);
CloseFile(ToF);
result := true;
Except
result := false;
End;
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function FreeSpaceOnDAP: int64;
Var tmps: string;
Begin
tmps := GetCurrentDir;
// get free memory on player, format string
SetCurrentDir(CactusConfig.DAPPath);
result := DiskFree(0);
writeln('------>');
writeln(DiskFree(0));
SetCurrentDir(tmps);
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function ByteToFmtString(bytes: int64; d1, d2: byte): string;
Var r: real;
count: byte;
comma, prefix, s1, s2: string;
subzero:boolean;
Begin
count := 0;
if bytes>=0 then subzero:=false else subzero:=true;
r := abs(bytes);
While (r>=power(10, d1)) Do
Begin
r := r / 1024;
inc(count);
End;
Case count Of
0: prefix := 'Byte';
1: prefix := 'KB';
2: prefix := 'MB';
3: prefix := 'GB';
4: prefix := 'TB';
5: prefix := 'PB';
End;
str(round (r*power(10, d2)) , s2);
If r >= 1 Then
Begin
s1 := copy(s2, 0, length(s2)-d2);
s2 := copy(s2, length(s2)-d2+1, d2);
End
Else s1 := '0';
If d2<>0 Then comma := ','
Else
Begin
comma := '';
s2 := '';
End;
if subzero=false then result := s1+comma+s2+' '+prefix else result := '- ' + s1+comma+s2+' '+prefix
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function SecondsToFmtStr(seconds: longint): string;
Var min, sec: longint;
s, s2: string;
Begin
if seconds>0 then begin
min := seconds Div 60;
sec := seconds Mod 60;
str(min, s);
str(sec, s2);
If min<10 Then s := '0'+s;
If sec<10 Then s2 := '0'+s2;
result := s+':'+s2;
end else Result:='00:00';
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function MSecondsToFmtStr(MSeconds: longint): string;
Begin
if MSeconds>1000 then result := SecondsToFmtStr(MSeconds Div 1000)
else Result:='00:00';
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function DirectoryIsEmpty(Directory: String): Boolean;
Var
SeR: TSearchRec;
i: Integer;
Begin
Result := False;
FindFirst(IncludeTrailingPathDelimiter(Directory) + '*', faAnyFile, SeR);
For i := 1 To 2 Do
If (SeR.Name = '.') Or (SeR.Name = '..') Then
Result := FindNext(SeR) <> 0;
FindClose(SeR);
End;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function MakeValidFilename(Filename: String): string;
var
I: integer;
{ for long file names } // FIXME taken from code for win32 - list correct/complete??
LongForbiddenChars : set of Char = ['<', '>', '|', '"', '\', '/', ':', '*', '?'];
begin
for I := 1 to Length(Filename) do
if (Filename[I] in LongForbiddenChars) then
Filename[I] := ' ';
result := Filename;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure BubbleSort(var Items: TStrings);
var
done: boolean;
i, n: integer;
Dummy: string;
begin
n := Items.Count;
repeat
done := true;
for i := 0 to n - 2 do
if Items[i] > Items[i + 1] then
begin
Dummy := Items[i];
Items[i] := Items[i + 1];
Items[i + 1] := Dummy;
done := false;
end;
until done;
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function IntTodB(i, ref: longint): integer;
var dB: Real;
begin
if i=0 then db:=0.001 else dB:=i;
dB:= 20*log10(dB/ref);
result:=round(dB);
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
End.