/* (C) Copyright International Business Machines Corporation 23 January */
/* 1990.  All Rights Reserved. */
/*  */
/* See the file USERAGREEMENT distributed with this software for full */
/* terms and conditions of use. */
#ifndef lint
static char sccsinfo[] = "@(#)hxdr.c	1.10 3/13/90";
#endif

#define _BSD 43

#define HXDR_VERSION 4
				/* change this when there is a change in */
				/*  data formats. */

#include <stdio.h>
#include <rpc/rpc.h>

#include "ops.h"
#include "storage.h"

static XDR xdr_descriptor;

static FILE *f;

XDR *
hxdr_read(fname)
char *fname;
{
    status debug_level();


    f = fopen(fname, "r");
    if (not f) {
#ifdef DEBUG
	if (debug_level(1)) 
	  (void) fprintf(stderr, "Couldn't open '%s'", fname);
#endif DEBUG
	return(nil);
    }

#ifdef DEBUG
    if (debug_level(2))
      (void) fprintf(stderr, "XDR Reading '%s'.\n", fname);
#endif DEBUG

    xdrstdio_create(&xdr_descriptor, f, XDR_DECODE);
    return(&xdr_descriptor);
}

XDR *
hxdr_write(fname)
char *fname;
{
    f = fopen(fname, "w");
    if (not f)
      return(nil);
    xdrstdio_create(&xdr_descriptor, f, XDR_ENCODE);
    return(&xdr_descriptor);
}



xdr_status
xdr_datarep(xdrs, drpp)
XDR *xdrs;
datarep **drpp;
{
    extern datarep *datarepmap[];

    tsdrno drnumber;

    if (xdrs->x_op is XDR_ENCODE)
      drnumber = (*drpp)->number;

    if (!xdr_u_short(xdrs, &drnumber))
      return(XDR_FAIL);

    if (xdrs->x_op is XDR_DECODE)
      *drpp = datarepmap[drnumber];

    return(XDR_OK);
}


xdr_status
hxdr_main(xdrs, obj)
XDR *xdrs;
object *obj;
{
    xdr_status hxdr_object();
    unsigned version;

    version = HXDR_VERSION;

    if (not xdr_u_int(xdrs, &version))
      return(XDR_FAIL);

    if (version isnt HXDR_VERSION) {
	nilerror("hxdr_main", "Attempt to load file with old XDR format");
	return(XDR_FAIL);
    }

    return(hxdr_object(xdrs, obj));
}


xdr_status 
hxdr_object(xdrs, obj)
XDR *xdrs;
object *obj;
{
    return(xdr_datarep(xdrs, & obj->tsdr) and 
	   obj->tsdr->xdr(xdrs, & obj->value));
}


NILOP(o_write)
{
    XDR *xdrs;


    xdrs = hxdr_write(stringval(SrcObj));

    if (not xdrs)
      raise(Depletion);
    else
      if (not hxdr_main(xdrs, DstObj)) 
	raise(Depletion);

    (void) fclose(f);
}


NILOP(o_read)
{
    void re_finalize();
    XDR *xdrs;
    object readObj;
    extern flag cherm_flag;

    xdrs = hxdr_read(stringval(SrcObj));
    
    if (not xdrs)
      raise(Depletion);
    else {
      if (hxdr_main(xdrs, &readObj)) {
          if (not cherm_flag)
	    re_finalize(DstObj, F_DISCARD, args->sched);
				/* finalize the value of the destination; */
          *(DstObj) = readObj;
      }
      else {
	  xdr_free(hxdr_main, &readObj);
	  raise(Depletion);
      }
    }
      
    if (f)
      (void) fclose(f);
}
