Patch title: Release 94 bulk changes
Abstract:
File: /pliant/storage/server/client.pli
Key:
    Removed line
    Added line
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "share.pli"
module "stream.pli"
module "resolve.pli"


type StorageRead
  field Stream stream
  field Str part_id
  field CBool selected
  
method s open site_name category object_id part_id -> status
  arg_rw StorageRead s ; arg Str site_name category object_id part_id ; arg ExtendedStatus status
  var Str path := storage_resolve_path site_name category object_id
  if path<>""
    status := s:stream open path+"log" in+safe
    s part_id := part_id
    s selected := false
  else
    status := failure "Failed to find object"

method s read -> command
  arg_rw StorageRead s ; arg Str command
  part read
    command := s:stream readline2
    if (command parse word:"part" (var Str id) any)
      s selected := id=s:part_id
    if not s:selected and not s:stream:atend
      restart read
    
method s blob adr size
  arg_rw StorageRead s ; arg_w Address adr ; arg_w Int size
  adr := s:stream blob_buf
  size := s:stream blob_size


#-----------------------------------------------------------------------


type StorageWrite
  field Link:StorageHandle handle
  field Stream stream
  field Str context

method s open site_name category object_id part_id -> status
  arg_rw StorageWrite s ; arg Str site_name category object_id part_id ; arg ExtendedStatus status
  storage_sem request
  var Pointer:Arrow p :> storage_handles first string:site_name+" "+string:category+" "+string:object_id
  if p=null
    var Str path := storage_resolve_path site_name category object_id
    if path<>""
      s:handle :> new StorageHandle
      status := s:handle:stream open path+"log" append+safe
      if status=success
        storage_handles insert string:site_name+" "+string:category+" "+string:object_id true (addressof s:handle)
    else
      status := failure "Failed to find object"
  else
    s:handle :> p map StorageHandle
    status := success
  storage_sem release

method s write command adr size
  arg_rw StorageWrite s ; arg Str command ; arg Address adr ; arg Int size
  if (exists s:handle)
    s:handle:sem request
    if s:handle:context<>s:context
      s:handle:stream writeline2 s:context
      s:handle context := s context
    s:handle:stream writeline2 command adr size
    s:handle:stream flush anytime
    s:handle:sem release

method s write command
  arg_rw StorageWrite s ; arg Str command
  s write command null 0

function 'cast Status' s -> stat
  arg StorageWrite s ; arg Status stat
  explicit
  stat := cast s:stream Status


method s lock
  arg_rw StorageWrite s
  if (exists s:handle)
    s:handle:sem request
  
method s unlock
  arg_rw StorageWrite s
  if (exists s:handle)
    s:handle:sem release
  

export StorageRead '. read'
export StorageWrite '. write'
export 'cast Status'
export '. lock' '. unlock'