/* Abstract parent class describing blocks of non-Actor memory. */!!

inherit(Struct, #MemoryObject, nil, 2, nil)!!

now(class(MemoryObject))!!

/* Return a new MemoryObject object. */
Def new(self)
{ ^new(self:Behavior);
}!!

now(MemoryObject)!!

/* General copyFrom method. */
Def copyFrom(self, lo, hi | copy)
{ if hi < lo
  then alert(System, self, #rangeError)
  endif;
  copy := new(Struct, hi-lo);
  lock(self);
  do(over(lo, hi),
  {using(idx) putLSB(copy, atLSB(self, idx), idx - lo);
  });
  unlock(self);
  ^copy;
}!!

/* Copy the data at the given Long into self.  Useful for
  getting data back from MS-Windows after it has copied it
  into the area starting at the Long. */
Def copyFromLong(self, lp | sz, i)
{ sz := size(self);
  i := 0;
  loop
  while i < sz
  begin putByte(self, byteAt(lp+i), i);
    i := i + 1;
  endLoop;
}!!

/* Fills receiver Struct with the
  specified word value. */
Def fill(self, val | sz, i)
{ sz := size(self) - 1;
  i := 0;
  loop
  while i < sz
  begin putWord(self, val, i);
    i := i + 2;
  endLoop;
}!!

/* Free the block. Assumes a corresponding lock was done. */
Def freeHandle(self)
{ if not(unlock(self))
  then alert(System, self, #handleError)
  endif;
  free(self);
}!!

/* Return data at self as a struct. */
Def getData(self | string)
{ ^asStruct(self);
}!!

/* Return a string from self with nulls removed. */
Def getText(self)
{ ^setClass(asStruct(self), String);
}!!

/* Call an interrupt routine with the parms in self. */
Def intCall(self, vec | string)
{ ^intCall(asStruct(self), vec);
}!!

/* Return true to inspector's indexed query. */
Def isIdx(self)
{
}!!

/* Evaluates a one-argument block over the keys of
  the receiver.  In an IndexedCollection, the keys are
  the integer indices of the collection, and thus are
  probably of little interest. However, keysDo is
  provided so that any collection can respond to
  keysDo. */
Def keysDo(self, aBlock)
{ ^do(over(0, size(self)),
  {using(idx) eval(aBlock, idx);
  });
}!!

/* Return a Long at the given offset. */
Def longAt(self, idx)
{ ^wordAt(self, idx+2) * 0x10000 + wordAt(self, idx);
}!!

/* Derive a long pointer by locking the block. */
Def lP(self)
{ ^lock(self);
}!!

/* Store a Long at the given offset. */
Def putLong(self, val, idx)
{ putWord(self, val, idx);
  putWord(self, high(asLong(val)), idx+2);
  ^val;
}!!

/* Return species type. */
Def species(self)
{ ^Struct;
}!!
