MODULE SVNUtil;
IMPORT
Files, Strings, MD5,
SVNOutput,
Dates;
TYPE
FSItemSearch* = OBJECT ( Files.Enumerator )
VAR
adding, found: BOOLEAN;
name0 : Files.FileName;
path, mask : Strings.String;
flags0: SET;
time0, date0, size0 : LONGINT;
PROCEDURE &Init*;
BEGIN
found := FALSE;
adding := FALSE;
NEW ( path, 512 );
NEW ( mask, 512 );
END Init;
PROCEDURE Exists* () : BOOLEAN;
BEGIN
RETURN found;
END Exists;
PROCEDURE FileExists* () : BOOLEAN;
BEGIN
RETURN found & (Files.Old ( mask^ ) # NIL);
END FileExists;
PROCEDURE Open(m: ARRAY OF CHAR; flags: SET);
BEGIN
IF Strings.EndsWith ( Files.PathDelimiter, m ) THEN
m[Strings.Length(m)-1] := 0X;
END;
COPY ( m, mask^ );
Files.SplitPath ( mask^, path^, name0 );
Strings.Append ( path^, "/*" );
found := FALSE;
adding := TRUE;
Open^ ( path^, flags );
adding := FALSE;
END Open;
PROCEDURE GetEntry(VAR name: ARRAY OF CHAR; VAR flags: SET; VAR time, date, size: LONGINT): BOOLEAN;
BEGIN
IF found THEN
COPY ( name0, name );
flags := flags0;
time := time0;
date := date0;
size := size0;
END;
RETURN found;
END GetEntry;
PROCEDURE PutEntry(VAR name: ARRAY OF CHAR; flags: SET; time, date, size: LONGINT);
BEGIN
ASSERT(adding);
IF ~found & (name = mask^) THEN
name[0] := name[0];
found := TRUE;
flags := flags0;
time := time0;
date := date0;
size := size0;
END;
END PutEntry;
END FSItemSearch;
PROCEDURE GetChecksum* ( CONST file : ARRAY OF CHAR ) : Strings.String;
CONST
bufSize = 512;
VAR
read, len : LONGINT;
tmp, res : Strings.String;
md5context : MD5.Context;
md5digest : MD5.Digest;
r : Files.Reader;
f : Files.File;
BEGIN
NEW ( tmp, bufSize );
NEW ( res, 35 );
f := Files.Old ( file );
ASSERT ( f # NIL );
Files.OpenReader ( r, f, 0 );
md5context := MD5.New();
read := 0;
LOOP
r.Bytes ( tmp^, read, bufSize, len );
MD5.WriteBytes ( md5context, tmp^, len );
IF len < bufSize THEN EXIT END;
END;
MD5.Close ( md5context, md5digest );
MD5.ToString ( md5digest, res^ );
RETURN res;
END GetChecksum;
PROCEDURE CheckChecksum* ( CONST file, checksum : ARRAY OF CHAR ) : BOOLEAN;
VAR
s : Strings.String;
BEGIN
s := GetChecksum ( file );
RETURN s^ = checksum;
END CheckChecksum;
PROCEDURE GetUUID* () : Strings.String;
VAR
md5context : MD5.Context;
md5digest : MD5.Digest;
tmp : Strings.String;
BEGIN
NEW ( tmp, 40 );
md5context := MD5.New();
Strings.FormatDateTime ( SVNOutput.DateFormat, Dates.Now(), tmp^ );
MD5.WriteBytes ( md5context, tmp^, Strings.Length ( tmp^ ) );
MD5.Close ( md5context, md5digest );
MD5.ToString ( md5digest, tmp^ );
RETURN tmp;
END GetUUID;
PROCEDURE FileExists* ( CONST file : ARRAY OF CHAR ) : BOOLEAN;
BEGIN
RETURN Files.Old ( file ) # NIL;
END FileExists;
PROCEDURE UrlEncode* ( CONST input : ARRAY OF CHAR; VAR output : ARRAY OF CHAR );
CONST
unsafe = " <>#%[]|\^~[]'";
VAR
i, j : LONGINT;
tmp : ARRAY 3 OF CHAR;
BEGIN
i := 0; j := 0;
WHILE input[i] # 0X DO
IF Strings.Find ( unsafe, 0, input[i] ) = -1 THEN
output[j] := input[i];
INC ( j );
ELSE
output[j] := '%'; INC ( j );
Strings.IntToHexStr ( ORD(input[i]), 1, tmp );
output[j] := tmp[0]; INC ( j );
output[j] := tmp[1]; INC ( j );
END;
INC ( i );
END;
output[j] := 0X;
END UrlEncode;
PROCEDURE UrlDecode* (CONST input : ARRAY OF CHAR; VAR output : ARRAY OF CHAR );
VAR
i, j, value, res : LONGINT;
tmp : ARRAY 3 OF CHAR;
BEGIN
i := 0; j := 0;
tmp[2] := 0X;
WHILE input[i] # 0X DO
IF input[i] = '%' THEN
INC ( i );
tmp[0] := input[i]; INC ( i );
tmp[1] := input [i]; INC ( i );
Strings.HexStrToInt ( tmp, value, res ); ASSERT ( res = Strings.Ok );
output[j] := CHR ( value ); INC ( j );
ELSE
output[j] := input[i];
INC ( j ); INC ( i );
END;
END;
output[j] := 0X;
END UrlDecode;
PROCEDURE RemoveFileDelimiterAtEnd* ( VAR s : ARRAY OF CHAR );
BEGIN
IF Strings.EndsWith ( Files.PathDelimiter, s ) THEN
s[Strings.Length(s)-1] := 0X;
END;
END RemoveFileDelimiterAtEnd;
END SVNUtil.