home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Oberon / examples.lha / Examples / Oberon0 / AsciiTexts.Mod < prev    next >
Encoding:
Text File  |  1995-04-15  |  3.1 KB  |  116 lines

  1. MODULE AsciiTexts; (*HM Mar-25-92*)
  2. IMPORT OS, Viewers0;
  3.  
  4. CONST minBufLen = 32;
  5.  
  6. TYPE
  7.   Buffer = POINTER TO ARRAY OF CHAR;
  8.   Text* = POINTER TO TextDesc;
  9.   TextDesc* = RECORD (OS.ObjectDesc)
  10.     len-: LONGINT;
  11.     pos-: LONGINT;  (*read/write position*)
  12.     buf: Buffer;
  13.     gap: LONGINT (*index of first byte in gap*)
  14.   END;
  15.   NotifyInsMsg* = RECORD (OS.Message) t*: Text; beg*, end*: LONGINT END;
  16.   NotifyDelMsg* = RECORD (OS.Message) t*: Text; beg*, end*: LONGINT END;
  17.  
  18. PROCEDURE (t: Text) MoveGap (to: LONGINT);
  19.   VAR n, gapLen: LONGINT;
  20. BEGIN
  21.   n := ABS(to - t.gap); gapLen := LEN(t.buf^) - t.len;
  22.   IF to > t.gap THEN
  23.     OS.Move(t.buf^, t.gap + gapLen, t.buf^, t.gap, n)
  24.   ELSIF to < t.gap THEN
  25.     OS.Move(t.buf^, t.gap - n, t.buf^, t.gap + gapLen - n, n)
  26.   END;
  27.   t.gap := to
  28. END MoveGap;
  29.  
  30. PROCEDURE (t: Text) Grow (size: LONGINT);
  31.   VAR bufLen: LONGINT; old: Buffer;
  32. BEGIN
  33.   bufLen := LEN(t.buf^);
  34.   IF size > bufLen THEN t.MoveGap(t.len);
  35.     WHILE bufLen < size DO bufLen := 2*bufLen END;
  36.     old := t.buf; NEW(t.buf, bufLen); OS.Move(old^, 0, t.buf^, 0, t.len)
  37.   END
  38. END Grow;
  39.  
  40. PROCEDURE (t: Text) Shrink;
  41.   VAR bufLen: LONGINT; old: Buffer;
  42. BEGIN
  43.   bufLen := LEN(t.buf^); t.MoveGap(t.len);
  44.   WHILE (bufLen >= 2*t.len) & (bufLen > minBufLen) DO
  45.     bufLen := bufLen DIV 2
  46.   END;
  47.   old := t.buf; NEW(t.buf, bufLen); OS.Move(old^, 0, t.buf^, 0, t.len)
  48. END Shrink;
  49.  
  50. PROCEDURE (t: Text) Clear*;
  51. BEGIN
  52.   NEW(t.buf, minBufLen); t.gap := 0; t.pos := 0; t.len := 0
  53. END Clear;
  54.  
  55. PROCEDURE (t: Text) Insert* (at: LONGINT; t1: Text; beg, end: LONGINT);
  56.   VAR len: LONGINT; m: NotifyInsMsg; t0: Text;
  57. BEGIN
  58.   IF t = t1 THEN
  59.     NEW(t0); t0.Clear; t0.Insert(0, t1, beg, end);
  60.     t.Insert(at, t0, 0, t0.len)
  61.   ELSE
  62.     len := end - beg;
  63.     IF t.len + len > LEN(t.buf^) THEN t.Grow(t.len + len) END;
  64.     t.MoveGap(at); t1.MoveGap(end);
  65.     OS.Move(t1.buf^, beg, t.buf^, t.gap, len);
  66.     INC(t.gap, len); INC(t.len, len);
  67.     m.t := t; m.beg := at; m.end := at + len; Viewers0.Broadcast(m)
  68.   END
  69. END Insert;
  70.  
  71. PROCEDURE (t: Text) Delete* (beg, end: LONGINT);
  72.   VAR m: NotifyDelMsg;
  73. BEGIN
  74.   t.MoveGap(end); t.gap := beg; DEC(t.len, end-beg);
  75.   IF (t.len * 2 < LEN(t.buf^)) & (LEN(t.buf^) > minBufLen) THEN
  76.     t.Shrink
  77.   END;
  78.   m.t := t; m.beg := beg; m.end := end; Viewers0.Broadcast(m)
  79. END Delete;
  80.  
  81. PROCEDURE (t: Text) SetPos* (pos: LONGINT);
  82. BEGIN
  83.   t.pos := pos
  84. END SetPos;
  85.  
  86. PROCEDURE (t: Text) Read* (VAR ch: CHAR);
  87.   VAR i: LONGINT;
  88. BEGIN
  89.   i := t.pos;
  90.   IF t.pos >= t.gap THEN INC(i, LEN(t.buf^) - t.len) END;
  91.   IF t.pos < t.len THEN ch := t.buf[i]; INC(t.pos) ELSE ch := 0X END
  92. END Read;
  93.  
  94. PROCEDURE (t: Text) Write* (ch: CHAR);
  95.   VAR m: NotifyInsMsg;
  96. BEGIN
  97.   IF t.len = LEN(t.buf^) THEN t.Grow(t.len + 1) END;
  98.   IF t.pos # t.gap THEN t.MoveGap(t.pos) END;
  99.   t.buf[t.gap] := ch; INC(t.gap); INC(t.pos); INC(t.len);
  100.   m.t := t; m.beg := t.gap-1; m.end := t.gap; Viewers0.Broadcast(m)
  101. END Write;
  102.  
  103. PROCEDURE (t: Text) Load* (VAR r: OS.Rider);
  104.   VAR len: LONGINT;
  105. BEGIN
  106.   t.Clear; r.ReadLInt(len); t.Grow(len); r.ReadChars(t.buf^, len);
  107.   t.gap := len; t.len := len
  108. END Load;
  109.  
  110. PROCEDURE (t: Text) Store* (VAR r: OS.Rider);
  111. BEGIN
  112.   t.MoveGap(t.len); r.WriteLInt(t.len); r.WriteChars(t.buf^, t.len)
  113. END Store;
  114.  
  115. END AsciiTexts.รพ
  116.