/*
 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
 * 
 * The contents of this file constitute Original Code as defined in and are
 * subject to the Apple Public Source License Version 1.2 (the 'License').
 * You may not use this file except in compliance with the License. Please obtain
 * a copy of the License at http://www.apple.com/publicsource and read it before
 * using this file.
 * 
 * This Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
 * specific language governing rights and limitations under the License.
 */


/*
 * file: .../tbl-example/example.c - decodes and prints a given BER
 * PersonnelRecord value and re-encodes it to the file
 * "p-rec.out.ber".  This example would be similar to your user code in
 * that you run "mkchdr" to build a nicely named description of data
 * structure (PersonnelRecord in this case).  The table tools deal with
 * the same data structure in a generic way and don't use/need mkchdr.
 * You must not change the output of mkchdr otherwise the table encoder
 * decoder, etc will not understand it.
 *
 * Mike Sample
 *
 * Copyright (C) 1993 Michael Sample
 *            and the University of British Columbia
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program and the associated libraries are distributed in the hope
 * that they will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License and GNU Library General
 * Public License for more details.
 *
 * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/tbl-example/example.c,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
 * $Log: example.c,v $
 * Revision 1.1.1.1  2001/05/18 23:14:10  mb
 * Move from private repository to open source repository
 *
 * Revision 1.2  2001/05/05 00:59:30  rmurphy
 * Adding darwin license headers
 *
 * Revision 1.1.1.1  1999/03/16 18:06:53  aram
 * Originals from SMIME Free Library.
 *
 * Revision 1.1  1997/02/15 19:33:26  rj
 * first check-in
 *
 */

#include "tbl-incl.h"
#include "exp-buf.h"
#include "sbuf.h"

#include "p-rec.h"  /* include the file we made with mkchdr */


char *outputFileNameG = "p-rec.out.ber";

void Usage PARAMS ((prg),
    char *prg)
{
    fprintf (stderr, "Usage: %s <tt file name> <p-rec ber file> \n\n", prg);
    fprintf (stderr, "E.g.  %s p-rec.tt  p-rec.ber\n\n", prg);
    fprintf (stderr, "The BER values in the file list will be decoded, printed to stdout and then re-encoded to the file \"%s\"\n", outputFileNameG);
}


int
main PARAMS ((argc, argv),
    int argc _AND_
    char **argv)
{
    char *tblFileName;
    char *berFileName;
    TBL *tbl;
    int i;
    char *fileData;
    unsigned long int fsize;
    PersonnelRecord *val;
    unsigned long int bytesDecoded;
    unsigned long int bytesEncoded;
    SBuf sb;  /* use simple buffers for reading in (know sizes) */
    ExpBuf *ebPtr; /* use expanding bufs for enc (usually don't know sizes)*/
    GenBuf gb;
    FILE *outputFile;



    if (argc != 3)
    {
        Usage (argv[0]);
        return 1;
    }

    tblFileName = argv[1];
    berFileName = argv[2];

    /* init mem pool to hold  decoded val */
    InitNibbleMem (1024, 1024);

    /* read in and decode the type table */
    tbl = LoadTblFile (tblFileName);
    if (tbl == NULL)
        return 1;

    fileData = LoadFile (berFileName, &fsize);
    if (fileData == NULL)
        return 1;

    SBufInstallData (&sb, fileData, fsize);
    PutSBufInGenBuf (&sb, &gb);

    fprintf (stdout, "\n\n-- decoded contents of BER PersonnelRecord file: \"%s\"--\n", berFileName);

    val = TblDecode (tbl, NULL, "PersonnelRecord", &gb, &bytesDecoded);

    if (val == NULL)
        fprintf (stdout, "-- Decoding error occured somewhere -- \n");
    else
        TblPrintValue (tbl, NULL, "PersonnelRecord", stdout, val);

    fprintf (stdout, "\n\n -- decoded %d bytes for the above value --\n\n", bytesDecoded, berFileName);

    free (fileData); /* was malloc'd in LoadFile */

    /*
     * process value here
     * (This is where the header file generated by mkchdr is
     * useful - you can access the decoded value in a standard
     * /easier way).
     *
     * Ok, well, the names "field0" etc aren't that nice
     * but what did you expect - they aren't named in the ASN.1
     * spec so mkchdr just makes them up.  To fix this, just
     * add field names to you ASN.1 spec - it will not change the
     * way the values are encoded - so you're not making it
     * incompatible with the original. (not including value notation)
     */
    printf ("The following printout is an example of using the\n");
    printf ("hdr file generated by mkchdr to access the data\n");
    printf ("returned from the table decoder.  Look in \"example.c\"\n\n");


    printf ("***** JQ GUMBY & CO Database *****************************************\n");
    printf ("Employee Name:      %s %s %s\n", val->field0->givenName->octs, val->field0->initial->octs, val->field0->familyName->octs);
    printf ("Title:              %s\n", val->title->octs);
    printf ("Employee Number:    %d\n", *val->field1);
    printf ("Date of Hire:       %s\n", val->dateOfHire->octs);
    printf ("Name of Spouse:     %s %s %s\n", val->nameOfSpouse->givenName->octs, val->nameOfSpouse->initial->octs, val->nameOfSpouse->familyName->octs);
    printf ("Number of Children: %d\n", AsnListCount (val->children));
    printf ("**********************************************************************\n\n");

    /*
     * finished playing with the decoded value.
     * now re-encode the value.  Using an expbuf to hold the encoded val
     * because they can grow and in general you can predict a values
     * encoded size (although we could assume that is would be close to
     * the same size as the one we read in at the beginning of this prg).
     * (note: the size of PersonnelRecord BER value we decoded may be
     * different from the size of the re-encoded version depending on
     * the use of indefinite or definite lengths.  Both are valid BER.)
     */
    fprintf (stdout, "now re-encoding the PersonnelRecord value to \"%s\"\n", outputFileNameG);

    ebPtr = ExpBufAllocBufAndData();
    ExpBufResetInWriteRvsMode (ebPtr); /* set up to hold encoding (= writing) */

    PutExpBufInGenBuf (ebPtr, &gb);

    if (TblEncode (tbl, NULL, "PersonnelRecord", &gb, val, &bytesEncoded) < 0)
        fprintf (stderr, "main: error encoding the PersonnelRecord\n");

    /* copy ExpBuf data to file */
    outputFile = fopen (outputFileNameG, "w");
    if (outputFile == NULL)
    {
        fprintf (stderr, "error - could not open file \"%s\"\n", outputFileNameG);
        perror ("main: fopen:");
    }

    ExpBufCopyToFile (ebPtr, outputFile);

    fclose (outputFile);

    /* free the encoded version */
    ExpBufFreeBufAndDataList (ebPtr);


    return 0;
} /* main */
