Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] View of /trunk/sml3d/src/raw-data/c-string.sml
ViewVC logotype

View of /trunk/sml3d/src/raw-data/c-string.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1467 - (download) (annotate)
Sun Aug 31 12:04:48 2014 UTC (5 years, 5 months ago) by jhr
File size: 3223 byte(s)
  Working on core API compilation
(* c-string.sml
 *
 * COPYRIGHT (c) 2006 John Reppy (http://www.cs.uchicago.edu/~jhr)
 * All rights reserved.
 *
 * Utility code for manipulating C strings.  Use these operations
 * with care, since ill-formed C strings can cause bad things (TM)
 * to happen.
 *)

signature C_STRING =
  sig
    type c_string = CPtr.t

    val sub : c_string * int -> char

  (* the length of a null-terminated C string *)
    val strlen : c_string -> int

  (* extract an SML string of the given length from a C string.  Note that this function
   * does _not_ check for overruns, so use with care!!
   *)
    val extract : c_string * int -> string

  (* convert a C string to an ML string; null pointers map to "" *)
    val toString : c_string -> string

  (* given a contiguous sequence of C strings terminated by an empty string,
   * convert them to a list of SML strings.
   *)
    val cstringsToML : c_string -> string list

  (* reader for C strings; returns NONE when the terminating nul is encountered *)
    val getc : c_string -> (char * c_string) option

  (* allocate and initialize a string in the C heap from an ML string *)
    val fromString : string -> c_string

  (* allocate and initialize a string in the C heap from a list of ML strings *)
    val fromStringList : string list -> c_string

  end

structure CString :> C_STRING =
  struct

    type c_string = CPtr.t

    fun getChar (s, i) = Byte.byteToChar (CPtr.getWord8 (s, CPtrDiff.fromInt i))
    fun setChar (s, i, c) = CPtr.setWord8(s, CPtrDiff.fromInt i, Byte.charToByte c)

    val sub = getChar

  (* compute the length of a nul-terminated C string *)
    fun strlen s = let
	  fun lp n = if getChar(s, n) = #"\000" then n else lp(n+1)
	  in
	    lp 0
	  end

    fun extract (s, n) = CharVector.tabulate (n, fn i => getChar (s, i))

  (* convert an C pointer to an SML string value *)
    fun toString (s : c_string) = if (s = CPtr.null)
	  then ""
	  else extract (s, strlen s)

  (* given a contiguous sequence of C strings terminated by an empty string,
   * convert them to a list of SML strings.
   *)
    fun cstringsToML (s : c_string) = let
	  fun lp p = let
		val n = strlen p
		in
		  if (n = 0) then []
		  else extract(p, n) :: lp(CPtr.add(p, CPtrDiff.fromInt(n+1)))
		end
	  in
	    lp s
	  end

  (* reader for C strings; returns NONE when the terminating nul is encountered *)
    fun getc (s : c_string) = (case getChar(s, 0)
	   of #"\000" => NONE
	    | c => SOME(c, CPtr.add(s, 1))
	  (* end case *))

  (* allocate an initialize a string in the C heap *)
    fun fromString s = let
	  val ptr = CAlloc.malloc(CSize.fromInt(size s + 1))
	  in
	    CharVector.appi (fn (i, c) => setChar (ptr, i, c)) s;
	    CPtr.setWord8 (ptr, CPtrDiff.fromInt(size s), 0w0);
	    ptr
	  end

  (* allocate an initialize a string in the C heap from a list of ML strings *)
    fun fromStringList l = let
	  val len = List.foldl (fn (s, n) => size s + 1) 1 l (* length + 1 for \0 *)
	  val ptr = CAlloc.malloc(CSize.fromInt len)
	  fun lp ([], _) = ()
	    | lp (s::r, i) = (
		CharVector.appi (fn (j, c) => setChar(ptr, i+j, c)) s;
		lp (r, i + size s))
	  in
	    lp (l, 0);
	    CPtr.setWord8 (ptr, CPtrDiff.fromInt len, 0w0);
	    ptr
	  end

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0