Newbie questions about Pliant

Newbie questions about Pliant

rearding in contents of a text file

Is this the correct way to slurp in text file into a string?
Message posted by maybe Boris Reitman on 2008/03/06 21:36:07
Is the following code a bad idea from memory allocation standpoint ?

  function slurp_text_file filename -> str
    arg Str filename str
    var Stream s
    s open filename in
    str := ""
    if s:is_open
      while not s:atend
        str += s:readline
        if not s:atend
          str += "[lf]"
    s:close
Message posted by maybe Hubert Tonneau on 2008/03/06 22:26:55
Your code can lead to serious memory allocation and memory bus overload problem,
if the file size can be huge.
Here is a better implementation:

function slurp_text_file filename -> lst
  arg Str filename ; arg List:Str lst
  (var Stream s) open filename in
  lst := var List:Str empty_list
  while not s:atend
    lst += s readline
Message posted by maybe Boris Reitman on 2008/03/07 00:16:01
Can I convert the function to return one big string at the end ?

I was using this function to load about 20 html files on every HTTP request,
to generate the output page. It could be the reason why my pliant instance
consumes so much memory.

It would be good to have a way to profile the program and to list
function that take the most time, and which allocate the most memory.

Thanks,
Boris
Message posted by maybe Hubert Tonneau on 2008/03/07 00:32:19
There is.
Look at /pliant/graphic/sample/rip.pli

I know, I have to continue writing articles ...
Message posted by maybe Boris Reitman on 2008/03/07 02:42:23
Is this good ?

function slurp_text_file filename -> text
  arg Str filename ; arg Str text
  var FileInfo info := file_query filename standard
  var Int size := info:size
  var Address address := memory_allocate size null
  var Address cur := address
  (var Stream s) open filename in
  if s:is_open
    while not s:atend
      s read_available (var Address tmp) (var Int received)
      memory_copy tmp cur received
      cur := cur translate Byte received
    s close
  text set address size true
Message posted by maybe Boris Reitman on 2008/03/07 02:45:24
Or this, it has extra check for size:

function slurp_text_file filename -> text
  arg Str filename ; arg Str text
  var FileInfo info := file_query filename standard
  var Int allocated_size := info:size
  var Address address := memory_allocate allocated_size null
  var Address cur := address
  var Int copied := 0
  (var Stream s) open filename in
  if s:is_open
    while not s:atend and copied <= allocated_size
      s read_available (var Address tmp) (var Int received)
      memory_copy tmp cur received
      copied += received
      if copied <= allocated_size
        cur := cur translate Byte received
    s close
  text set address allocated_size true
Message posted by maybe Hubert Tonneau on 2008/03/07 15:16:11
If you really want to load it in a single chunk (string),
then you can make it simpler:

function slurp_text_file filename -> text
  arg Str filename ; arg Str text
  var FileInfo info := file_query filename standard
  if info=success
    text resize info:size
    (var Stream s) open filename in+safe
    s raw_read s:characters s:len
  else
    text := ""