-- Copyright (C) 1985, 1986  by Xerox Corporation. All rights reserved. 
-- CStringImpl.mesa
-- NFS   20-Dec-85 15:50:53

DIRECTORY
  Ascii USING [NUL],
  CString USING [CString, IncrBPointer, ReadChar, ToBytePointer, WriteChar],
  Heap USING [MakeNode],
  String USING [MakeMDSString, MakeString];

CStringImpl: PROGRAM IMPORTS CString, String, Heap EXPORTS CString =
  {
  OPEN CString;

  CStringToString: PUBLIC PROCEDURE [cs: CString, z: MDSZone] RETURNS [STRING] = {
    s: STRING ← NIL;
    IF cs.pointer # NIL THEN {
      cs2: CString ← cs;
      nChars: CARDINAL ← 0;
      UNTIL ReadChar[cs2] = Ascii.NUL DO
        nChars ← nChars + 1; cs2 ← IncrBPointer[cs2]; ENDLOOP;
      s ← String.MakeMDSString[z, nChars];
      s.length ← nChars;
      FOR i: CARDINAL IN [0..nChars) DO
        s.text[i] ← ReadChar[cs]; cs ← IncrBPointer[cs]; ENDLOOP;
      };
    RETURN[s];
    };

  CStringToLongString: PUBLIC PROCEDURE [cs: CString, z: UNCOUNTED ZONE]
    RETURNS [LONG STRING] = {
    s: LONG STRING ← NIL;
    IF cs.pointer # NIL THEN {
      cs2: CString ← cs;
      nChars: CARDINAL ← 0;
      UNTIL ReadChar[cs2] = Ascii.NUL DO
        nChars ← nChars + 1; cs2 ← IncrBPointer[cs2]; ENDLOOP;
      s ← String.MakeString[z, nChars];
      s.length ← nChars;
      FOR i: CARDINAL IN [0..nChars) DO
        s.text[i] ← ReadChar[cs]; cs ← IncrBPointer[cs]; ENDLOOP;
      };
    RETURN[s];
    };

  StringToCString: PUBLIC PROCEDURE [s: STRING, z: UNCOUNTED ZONE]
    RETURNS [CString] = {RETURN[LongStringToCString[LONG[s], z]]; };

  LongStringToCString: PUBLIC PROCEDURE [s: LONG STRING, z: UNCOUNTED ZONE]
    RETURNS [CString] = {
    cs, cs2: CString;
    cs.pointer ← NIL;
    IF s # NIL THEN {
      cs ← cs2 ← ToBytePointer[Heap.MakeNode[z, s.length / 2 + 1]];  -- always add 1 because of ending NUL.
      FOR i: CARDINAL IN [0..s.length) DO
        WriteChar[s.text[i], cs2]; cs2 ← IncrBPointer[cs2]; ENDLOOP;
      WriteChar[Ascii.NUL, cs2];
      };
    RETURN[cs];
    };

  }.