/*
 * records.c,v 1.2 1994/01/30 17:10:41 franktor Exp
 */

#include <high/client-structs.h>
#include <malloc.h>

#if 0 /* Moved to ../lib/cli-lib.	-hbf */
octetString *oscpy (octetString *dest, octetString *src);
#endif

#define CopyOctStr(os) oscpy((octetString *) malloc(sizeof(octetString)), (os))


DiagRec *
ConvertFromHlvlDiagRec(HlvlDiagRec *e_diag)
{
  DiagRec *diag = (DiagRec *) malloc(sizeof(DiagRec));
  diag->diagnosticSetId = OID_str2Oid (e_diag->diagnosticSetId);
  if ( !OID_EQ (diag->diagnosticSetId, Oid_DIAGSET_BIB1) )
    LOG(facHigh, llevExceptions, "HlvlDiagRec with unsupported diagnostic set %s", e_diag->diagnosticSetId);
  diag->condition = e_diag->condition;
  if (e_diag->addinfo)
    diag->addinfo = strdup(e_diag->addinfo);
  else
    diag->addinfo = strdup(""); /* Maybe SR is unable to encode NULL here? */
  return diag;
}

NamePlusRecord *
ConvertFromHlvlNamePlusRecord(HlvlNamePlusRecord *e_rec)
{
  NamePlusRecord *rec = (NamePlusRecord *) malloc(sizeof(NamePlusRecord));
  rec->next = NULL;
  switch(e_rec->recKind) {
  case recHlvlRecord:
    rec->nprKind = nprRecord;
    rec->u.databaseRecord = (EXTERN *) malloc(sizeof(EXTERN));
    rec->u.databaseRecord->externEncoding = extEncOctetString;
    rec->u.databaseRecord->octStr = CopyOctStr(&e_rec->u.record.databaseRecord);
    rec->u.databaseRecord->directReference = OID_NULLPTR;
    rec->u.databaseRecord->indirectReference = (int *) NULL;
    rec->u.databaseRecord->dataValueDescriptor = (octetString *) NULL;
    if (e_rec->u.record.databaseName)
      rec->databaseName = strdup(e_rec->u.record.databaseName);
    else
      rec->databaseName = (char *) NULL;
    break;
  case recHlvlSurrogateDiagRec:
    rec->nprKind = nprDiag;
    rec->u.surrogateDiagnostic =
      ConvertFromHlvlDiagRec(e_rec->u.surrogateDiagnostic);
    rec->databaseName = (char *) NULL;
    break;
  }
  rec->next = NULL;
  return rec;
}

Records *
ConvertFromHlvlRecords( HlvlRecords * e_rec)
{
  Records *rec = (Records *) malloc(sizeof(Records));
  switch(e_rec->recKind) {
  case recHlvlNamePlusRecord:
    {
      NamePlusRecord *prev = NULL;
      HlvlNamePlusRecord *tmp;

      rec->recKind = recNamePlusRecord;
      rec->u.databaseOrSurDiagnostics = NULL;
      for (tmp = e_rec->u.databaseOrSurDiagnostics; tmp; tmp = tmp->next)
      {
        NamePlusRecord *npr = ConvertFromHlvlNamePlusRecord(tmp);
        if (prev)
          prev->next = npr;
        else
          rec->u.databaseOrSurDiagnostics = npr;
        prev = npr;
      }
      break;
    }
  case recHlvlNonSurrogateDiagRec:
    rec->recKind = recDiagRec;
    rec->u.nonSurrogateDiagnostic =
      ConvertFromHlvlDiagRec(e_rec->u.nonSurrogateDiagnosticRecord);
    break;
  }
  return rec;
}

Query *
ConvertToHlvlQuery (Query *q)
{
  octetString *os;
  Query *out;
  int not_nullterminated = 0;

  if (q == (Query *) NULL)
    return (Query *) NULL;

  out = (Query *) malloc(sizeof(Query));
  out->kind = q->kind;
  switch(q->kind)
  {
  case queryRpnQuery:
    out->q.rpnQuery = NULL;
    LOG(facHigh, llevExceptions, "RpnQuery not supported yet.");
    break;
  case queryPrivate:
    LOG(facHigh, llevExceptions, "Private query not supported yet.");
    break;
  case queryIso8777Query:
    if (*(q->q.iso8777Query->value + q->q.iso8777Query->len - 1))
      not_nullterminated = 1;
    os = (octetString *) malloc(sizeof(octetString));
    os->len = q->q.iso8777Query->len;
    os->value = (char *) malloc(os->len + not_nullterminated);
    (void) memcpy(os->value, q->q.iso8777Query->value, os->len);
    if (not_nullterminated) /* Add a trailing null-byte to help structcodec */
      * (os->value + os->len++) = '\0';
    out->q.iso8777Query = os;
  }
  return out;
}
