m3core/src/text/String8.m3


 Copyright 1996-2000, Critical Mass, Inc.  All rights reserved. 
 See file COPYRIGHT-CMASS for details. 

UNSAFE MODULE String8;

IMPORT Cstring, Word;

TYPE Ptr = UNTRACED REF CHAR;

PROCEDURE Equal (a, b: ADDRESS;  len: CARDINAL): BOOLEAN =
  BEGIN
    IF (len = 0) THEN RETURN TRUE; END;
    IF (a = NIL) OR (b = NIL) THEN RETURN FALSE; END;
    RETURN Cstring.memcmp (a, b, len) = 0;
  END Equal;

PROCEDURE Compare (a: ADDRESS;  len_a: CARDINAL;
                   b: ADDRESS;  len_b: CARDINAL): [-1..1] =
  VAR i: INTEGER;
  BEGIN
    i := Cstring.memcmp (a, b, MIN (len_a, len_b));
    IF    (i < 0)         THEN  RETURN -1;
    ELSIF (i > 0)         THEN  RETURN +1;
    ELSIF (len_a < len_b) THEN  RETURN -1;
    ELSIF (len_a > len_b) THEN  RETURN +1;
    ELSE                        RETURN 0;
    END;
  END Compare;

PROCEDURE Hash (a: ADDRESS;  len: CARDINAL;  initial: INTEGER): INTEGER =
  VAR p := LOOPHOLE (a, Ptr);  result := initial;
  BEGIN
    IF (p = NIL) THEN RETURN result; END;
    WHILE (len > 0) DO
      result := Word.Xor (Word.LeftRotate (result, 13), ORD (p^));
      INC (p, ADRSIZE (p^));  DEC (len);
    END;
    RETURN result;
  END Hash;

PROCEDURE FindChar (a: ADDRESS;  len: CARDINAL;  c: CHAR): INTEGER =
  VAR p := LOOPHOLE (a, Ptr);  cnt := len;
  BEGIN
    IF (p = NIL) THEN RETURN -1; END;
    WHILE (cnt > 0) DO
      IF (p^ = c) THEN RETURN len - cnt; END;
      INC (p, ADRSIZE (p^));  DEC (cnt);
    END;
    RETURN -1;
  END FindChar;

PROCEDURE FindCharR (a: ADDRESS;  len: CARDINAL;  c: CHAR): INTEGER =
  VAR p := LOOPHOLE (a, Ptr);
  BEGIN
    IF (p = NIL) THEN RETURN -1; END;
    INC (p, len * ADRSIZE (p^));
    WHILE (len > 0) DO
      DEC (p, ADRSIZE (p^));  DEC (len);
      IF (p^ = c) THEN RETURN len; END;
    END;
    RETURN -1;
  END FindCharR;

PROCEDURE ArrayStart (READONLY a: ARRAY OF CHAR): ADDRESS =
  BEGIN
    IF NUMBER (a) < 1 THEN RETURN NIL; END;
    RETURN ADR (a[0]);
  END ArrayStart;

BEGIN
END String8.