-- JaMStorageImpl.mesa
-- Pilot version
-- Last changed by Doug Wyatt, 13-Oct-81 17:33:49
-- Last changed by Bill Paxton, March 18, 1982 12:13 pm

DIRECTORY
  JaMStorage USING [TextObject],
  UnsafeStorage USING [TrimUZone, NewUZone],
  Inline USING [LongCOPY];

JaMStorageImpl: PROGRAM
IMPORTS UnsafeStorage, Inline
EXPORTS JaMStorage
SHARES JaMStorage = {

zone: UNCOUNTED ZONE = UnsafeStorage.NewUZone[]; 

Zone: PUBLIC PROC RETURNS[UNCOUNTED ZONE] = { RETURN[zone] };

pruning: BOOLEAN ← FALSE; -- can turn this on someday
Prune: PUBLIC PROC = { IF pruning THEN UnsafeStorage.TrimUZone[zone] };

-- Text allocation

TextObject: TYPE = JaMStorage.TextObject;

PrivateTextPut: PUBLIC PROC[t: POINTER TO TextObject, c: CHARACTER] = {
  old: LONG STRING ← t.text;
  new: LONG STRING ← NIL;
  length: CARDINAL ← t.len;
  oldmax: CARDINAL ← t.max;
  maxmax: CARDINAL = t.lim;
  newmax: CARDINAL ← oldmax + MIN[oldmax/2,maxmax-oldmax];
  IF NOT length<newmax THEN RETURN;
  new ← zone.NEW[StringBody[newmax]];
  Inline.LongCOPY[from: @old.text, to: @new.text, nwords: (oldmax+1)/2];
  IF old#t.cache THEN zone.FREE[@old];
  t.text ← new; t.max ← new.maxlength; 
  new[length] ← c; t.len ← length + 1;
  };

PrivateTextFree: PUBLIC PROC[t: POINTER TO TextObject] = {
  IF t.text#t.cache THEN zone.FREE[@t.text];
  };

}.