-- File [Ivy]<Nelson>Lupine>LupineMarshalTestImpl.mesa.
-- Last edited by BZM on 18-Mar-82 15:14:04.


DIRECTORY
    Atom USING [MakeAtom],
    ConvertUnsafe USING [ToRope],
  --Environment USING [charsPerWord],
    Inline USING [LongCOPY],
    LupineMarshalTest --USING [ALL]--,
    Rope USING [FromProc, ROPE];


LupineMarshalTestImpl: PROGRAM
  IMPORTS Atom, ConvertUnsafe, Inline, Rope 
  EXPORTS LupineMarshalTest
  = BEGIN OPEN LupineMarshalTest;


  Null: PUBLIC PROC = {NULL};

  One: PUBLIC PROC [one: INTEGER] RETURNS [a: INTEGER] =
      {RETURN[one]};
  Four: PUBLIC PROC [one,two,three,four: INTEGER]
    RETURNS [a,b,c,d: INTEGER] =
      {RETURN[one,two,three,four]};
  Ten: PUBLIC PROC [one,two,three,four,five,six,seven,eight,nine,ten: INTEGER]
    RETURNS [a,b,c,d,e,f,g,h,i,j: INTEGER] =
      {RETURN[one,two,three,four,five,six,seven,eight,nine,ten]};


  Signal: PUBLIC SIGNAL [in: INTEGER] RETURNS [out: INTEGER] = CODE;

  SignalTest: PUBLIC PROC [in: INTEGER, action: SignalAction]
      RETURNS [--out:-- INTEGER] =
    BEGIN
    SELECT action FROM
      signal  => RETURN[ SIGNAL Signal[in] ];
      error   => RETURN[ ERROR  Signal[in] ];
      neither => RETURN[ in ];
      ENDCASE => ERROR;
    END;


  TenArray: PUBLIC PROC [in: Array10] RETURNS [--out:-- Array10] =
    {RETURN[in]};
  FortyArray: PUBLIC PROC [in: Array40] RETURNS [--out:-- Array40] =
    {RETURN[in]};
  HundredArray: PUBLIC PROC [in: Array100] RETURNS [--out:-- Array100] =
    {RETURN[in]};


  SimpleArithmetic: PUBLIC PROC [pad: VARArithmetic] =
    {IF pad # NIL THEN 
	{pad.inPlus1 ← pad.in+1; pad.inTimes2 ← pad.in*2} };

  FillArray: PUBLIC PROC [in: INTEGER, out: RESULTArray] =
    {FOR i: CARDINAL IN [0..LENGTH[out]) DO out[i] ← in-i ENDLOOP};

  ReadPages: PUBLIC PROC [item: Item, buffer: RESULTPages] =
    BEGIN
    IF LENGTH[buffer] > 0 THEN BEGIN
      buffer[0] ← item;
      Inline.LongCOPY[
        to: BASE[buffer]+SIZE[Item],
	from: BASE[buffer],
	nwords: (LENGTH[buffer]-1)*SIZE[Item] ];
      END;
    END;

  CreateList: PUBLIC PROC [in: LONG INTEGER, length: INTEGER]
      RETURNS [out: IntList] =
    {FOR i: INTEGER DECREASING IN [0..length) DO
	out ← CONS[in-i, out] ENDLOOP};

  StringCopy: PUBLIC PROC [in: ReadonlyString, out: VARString] =
    {IF in # NIL AND out # NIL THEN 
	FOR i: CARDINAL IN [0..in.length) DO out[i] ← in[i] ENDLOOP};

  CharToVariantString: PUBLIC PROC [
        char: CHARACTER, length: INTEGER, type: StringType, makeNil: BOOLEAN ]
      RETURNS [StringSelection] =
    BEGIN
    SELECT type FROM
      nil => RETURN[ StringSelection[length, char, nil[]] ];
      rope =>
	BEGIN
        RopeChar: SAFE PROC RETURNS [CHARACTER] = TRUSTED {RETURN[char]};
	rope: Rope.ROPE =
	  IF makeNil THEN NIL ELSE Rope.FromProc[len: length, p: RopeChar];
	RETURN[ StringSelection[length, char, rope[rope: rope]] ];
	END;
      text =>
	BEGIN
	text: REF TEXT;
	IF makeNil
	  THEN text ← NIL
	  ELSE BEGIN
	    text ← NEW[TEXT[length] ← [length: length, text: NULL]];
	    FOR i: INTEGER IN [0..length) DO text[i] ← char; ENDLOOP;
	    END;
	RETURN[ StringSelection[length, char, text[text: text]] ];
	END;
      ENDCASE => ERROR;
    END; 

  BitsToSequence: PUBLIC PROC [in: BitDescriptor]
      RETURNS [--out:-- REF READONLY BitSequence] =
    BEGIN
    out: REF --READONLY-- BitSequence = NEW[BitSequence[LENGTH[in]]];
    FOR i: INTEGER IN [0..LENGTH[in]) DO
      IF i < LENGTH[out.fixed] THEN out.fixed[i+1] ← in[i];
      out.dynamic[i+1] ← in[i];
      ENDLOOP;
    RETURN[out];
    END; 


  PuntStringsToAtoms: PUBLIC SIGNAL = CODE;

  StringsToAtoms: PUBLIC PROC [in: StringList] RETURNS [out: AtomList←NIL] =
    {FOR str: INTEGER DECREASING IN (LENGTH[in]..0] DO
      out ← CONS[Atom.MakeAtom[ConvertUnsafe.ToRope[from: in[str]]], out];
      IF str MOD 47 = 0 THEN SIGNAL PuntStringsToAtoms;
      ENDLOOP;};


END.  -- LupineMarshalTestImpl.







  StringCopy: PUBLIC PROC [in: LONG STRING, out: VARString] =
    {IF in # NIL AND out # NIL THEN 
	FOR i: CARDINAL IN [0..in.length) DO out[i] ← in[i] ENDLOOP};
    {IF in # NIL AND out # NIL 
      THEN Inline.LongCOPY[
	to: BASE[out.text],
	from: BASE[in.text],
	nwords: (MIN[in.length, out.maxlength]+1)/Environment.charsPerWord ]};

  StringDescriptor: PROC [
      string: LONG STRING, text: RESULTTextDescriptor] =
    BEGIN
    IF LENGTH[text] # string.length THEN ERROR;
    Inline.LongCOPY[
      to: BASE[text],
      from: @string.text,
      nwords: string.length/Environment.charsPerWord ];
    END;


    Pattern: PROC [i: INTEGER] RETURNS [Bits] =
      INLINE {RETURN[ i MOD (LAST[Bits]+1) ]};