//-*-c++-*--------------------------------------------------------------
//  descrTst.cpp
//   Tests for the various ISO/UDF descriptors.
//
//      Unpublished Confidential Information of Hewlett-Packard
//      Company. Do not disclose.  Copyright (c) Hewlett-Packard
//      Company 1995. All rights reserved
// 
// The contents of this software are proprietary and confidential to
// the Hewlett- Packard Company, and are limited in distribution to
// those with a direct need to know.  Individuals having access to
// this software are responsible for maintaining the confidentiality
// of the content and for keeping the software secure when not in use.
// Transfer to any party is strictly forbidden other than as expressly
// permitted in writing by Hewlett-Packard Company.  Unauthorized
// transfer to or possession by any unauthorized party may be a
// criminal offense.
//
//                  RESTRICTED RIGHTS LEGEND
//
//      Use,  duplication,  or disclosure by the U. S. Government is
//      subject to restrictions as set forth in subparagraph (c) (1)
//      (ii) in the Rights in Technical Data and Computer Software
//      clause in DFARS 252.227-7013 or any other successor clause.
//
//                      HEWLETT-PACKARD COMPANY
//                      3000 Hanover St.
//                      Palo Alto, CA  94304 U.S.A.
//
//      Rights for non-DOD U.S. Government Departments and Agencies
//      are as set forth in FAR 52.227-19 (c) (1,2) or any other
//      successor clause.
//
//----------------------------------------------------------------------
//
// $Source: /projects/HMS/nsr/udfAncil/descrTst/descrTst.cpp,v $
// $Revision: 1.37 $    $Author: hmgr $
// $State: Exp $        $Locker:  $
// $Date: 96/05/21 15:02:43 $
//
#include "nsrLib.h"

static const int BUFLEN = 8192;

void
setBgnd(BYTE *bp, BYTE val, UINT16 fstart, UINT16 flen)
{
    UINT16 fend = fstart + flen;
    
    memset(bp,val,fstart);
    bp += fend;
    memset(bp,val,BUFLEN-fend);
}

int
chkBgnd(BYTE *bp, BYTE val, UINT16 fstart, UINT16 flen)

{
    UINT16 fend = fstart + flen;
    BYTE *rbp;

    int err = 0;
    int miscompare = 0;
    for ( rbp = bp; rbp < bp + fstart; rbp++ ) {
        miscompare |= ( *rbp != val );
    }
    if ( miscompare )
        err += 1;

    miscompare = 0;
    for ( rbp = bp + fend; rbp < bp + BUFLEN; rbp++ ) {
        miscompare |= ( *rbp != val );
    }
    if ( miscompare )
        err += 2;

    return err;
}

void
clrBuf( BYTE *bp )
{
    memset( bp, 0, BUFLEN);
}

main()
{

  TstStr:
    String tmp1("This is a test");
    String tmp2(" of the operator+=() function.");

    tmp1 += tmp2;
    if (tmp1 != "This is a test of the operator+=() function.") {
        fprintf(stderr,"String::operator+=() bad:\n");
        fprintf(stderr,"  tmp1 = 'This is a test'\n");
        fprintf(stderr,"  tmp2 = '%s'\n",(CONST_CHAR_PTR)tmp2);
        fprintf(stderr,"  (tmp1 += tmp2) = '%s'\n",(CONST_CHAR_PTR)tmp1);
    }
    
    int err = 0;
    
    BYTE *bp;
    bp = new BYTE[BUFLEN];

    static CONST_CHAR_PTR BGERRMSG = "%s corrupted background; err = %d.\n";
    static CONST_CHAR_PTR XCMPERRMSG = "%s corruption: w( %0x ) != r( %0x ).\n";
    static CONST_CHAR_PTR XACMPERRMSG = "%s corruption: element %d: w( %0x ) != r( %0x ).\n";
    static CONST_CHAR_PTR SCMPERRMSG = "%s corruption: w( %s ) != r( %s ).\n";

    UINT16 offs = 1;            // sequence through new one each time

  TstUint16:

    const UINT16 writeval = 0x89ab;
    UINT16 readval;

    clrBuf( bp );

    Uint16 ui16( offs );
    ui16 = writeval;
    ui16.toISO( bp );

    err = chkBgnd ( bp, 0, offs, 2 );
    if (err) fprintf( stderr, BGERRMSG, "toISO", err );
    setBgnd ( bp, 0xff, offs, 2 );

    ui16 = 0;
    ui16.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, 2 );
    if (err) fprintf( stderr, BGERRMSG, "fromISO",err );

    readval = ui16;

    if ( writeval != readval )
        fprintf(stderr, XCMPERRMSG, "Uint16", writeval, readval);

  TstShortAD:

    clrBuf( bp );
    offs = 3;

    const UINT32 wlbn = 0x89abcdef;
    UINT32 rlbn;

    const UINT32 wel = 0x3456789a;
    UINT32 rel;

    const ExtType wet = ext_Unallocated;
    ExtType ret;

    ShortAllocDesc sad( offs );
    sad.logBlockNo(wlbn);
    sad.extLength(wel);
    sad.extType(wet);
    
    sad.toISO( bp );

    err = chkBgnd ( bp, 0, offs, sad.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "toISO", err );
    setBgnd ( bp, 0xff, offs, sad.field.len() );

    sad.clear();
    sad.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, sad.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "fromISO",err );

    rlbn = sad.logBlockNo();
    rel  = sad.extLength();
    ret  = sad.extType();

    if ( wlbn != rlbn )
        fprintf(stderr, XCMPERRMSG, "sad.logBlockNo", wlbn, rlbn);
    if ( wel != rel )
        fprintf(stderr, XCMPERRMSG, "sad.extLength", wel, rel);
    if ( wet != ret )
        fprintf(stderr, XCMPERRMSG, "sad.extType", wet, ret);
    
  TstLongAD:

    clrBuf( bp );
    offs = BUFLEN - 99;

    // WARNING!! Side-effect: Uses same values as shortAD for fields
    // already defined... 

    const UINT16 wprn = 0x6789;
    UINT16 rprn;

    LongAllocDesc lad( offs );

    lad.partRefNo(wprn);
    lad.logBlockNo(wlbn);
    lad.extLength(wel);
    lad.extType(wet);
    lad.markErased();

    lad.toISO( bp );

    err = chkBgnd ( bp, 0, offs, lad.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "lad.toISO", err );
    setBgnd ( bp, 0xff, offs, lad.field.len() );

    lad.clear();
    lad.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, lad.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "lad.fromISO",err );

    rprn = lad.partRefNo();
    rlbn = lad.logBlockNo();
    rel  = lad.extLength();
    ret  = lad.extType();

    if ( wprn != rprn )
        fprintf(stderr, XCMPERRMSG, "lad.partRefNo", wprn, rprn);
    if ( wlbn != rlbn )
        fprintf(stderr, XCMPERRMSG, "lad.logBlockNo", wlbn, rlbn);
    if ( wel != rel )
        fprintf(stderr, XCMPERRMSG, "lad.extLength", wel, rel);
    if ( wet != ret )
        fprintf(stderr, XCMPERRMSG, "lad.extType", wet, ret);
    if ( ! lad.isErased() )
        fprintf(stderr, XCMPERRMSG, "lad.extType", 1, 0);
    
  TstUint32Table:

    unsigned int index;
    UINT32 rv,wv;
    
    clrBuf( bp );
    offs = 490;                 // These arbitrary numbers are GREAT

    Uint32Table ui32t( offs, 20 ); // 20 entries!

    for (index = 0; index < ui32t.num_ents(); index++ )
        ui32t[index] = ~ index;

    for (index = 0; index < ui32t.num_ents(); index++ ) {
        rv = ui32t[index];
        wv =~index;
        if ( wv != rv )
            fprintf(stderr, XACMPERRMSG, "(pre-toISO) Uint32Table", index, wv, rv );
    }
    ui32t.toISO( bp );

    err = chkBgnd ( bp, 0, offs, ui32t.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "ui32t.toISO", err );
    setBgnd ( bp, 0xff, offs, ui32t.field.len() );

    for (index = 0; index < ui32t.num_ents(); index++ )
        ui32t[index] = 0;

    ui32t.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, ui32t.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "ui32t.fromISO",err );

    for (index = 0; index < ui32t.num_ents(); index++ ) {
        rv = ui32t[index];
        wv =~index;
        if ( wv != rv )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) Uint32Table", index, wv, rv );
    }

    ui32t.fitEnts( 34 );
    ui32t.fromISO( bp );

    for (index = 20; index < ui32t.num_ents(); index++ ) {
        rv = ui32t[index];
        wv = 0xffffffff;
        if ( wv != rv )
        if ( wv != rv )
            fprintf(stderr, XACMPERRMSG, "(post-expansion) Uint32Table", index, wv, rv );
    }
    
  TestPartMapTable:

    const UINT8 wpmt = 1;
    const UINT8 wpml = 6;
    UINT8 rpmt, rpml;
    
    UINT16 wvsn, wpn;
    UINT16 rvsn, rpn;
    
    
    clrBuf( bp );
    offs = 101;                // These arbitrary numbers are GREAT

    PartMapTable pmt( offs, 20 ); // 20 entries!

    wvsn = 0x5600;
    wpn  = 0x7800;
    
    for (index = 0; index < pmt.num_ents(); index++ ) {
        pmt[index].volumeSeqNo = wvsn + index;
        pmt[index].partitionNo = wpn  + index + 0x80;
    }

    for (index = 0; index < pmt.num_ents(); index++ ) {

        rvsn = pmt[index].volumeSeqNo;
        if ( rvsn != wvsn + index )
            fprintf(stderr, XACMPERRMSG, "(pre-toISO) PartMapTable.vsNo",
                    index, wvsn + index, rvsn );

        rpn = pmt[index].partitionNo;
        if ( rpn != wpn  + index + 0x80 )
            fprintf(stderr, XACMPERRMSG, "(pre-toISO) PartMapTable.pNo",
                    index, wpn + index + 0x80, rpn );
    }

    pmt.toISO( bp );

    err = chkBgnd ( bp, 0, offs, pmt.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "pmt.toISO", err );
    setBgnd ( bp, 0xff, offs, pmt.field.len() );

    for (index = 0; index < pmt.num_ents(); index++ ) {
        
        pmt[index].partitionMapType   = 0;
        pmt[index].partitionMapLength = 0;
        pmt[index].volumeSeqNo        = 0;
        pmt[index].partitionNo        = 0;
    }

    pmt.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, pmt.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "pmt.fromISO",err );

    for (index = 0; index < pmt.num_ents(); index++ ) {

        rpmt = pmt[index].partitionMapType;
        if ( rpmt != wpmt )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.pmt",
                    index, wpmt, rpmt );
        
        rpml = pmt[index].partitionMapLength;
        if ( rpml != wpml )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.pml",
                    index, wpml, rpml );

        rvsn = pmt[index].volumeSeqNo;
        if ( rvsn != wvsn + index )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.vsNo",
                    index, wvsn + index, rvsn );

        rpn = pmt[index].partitionNo;
        if ( rpn != wpn  + index + 0x80 )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.pNo",
                    index, wpn + index + 0x80, rpn );
    }

    pmt.fitEnts( 34 );
    pmt.fromISO( bp );

    for (index = 20; index < pmt.num_ents(); index++ ) {

        rpmt = pmt[index].partitionMapType;
        if ( rpmt != 0xff )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.pmt",
                    index, 0xff, rpmt );
        
        rpml = pmt[index].partitionMapLength;
        if ( rpml != 0xff )
            fprintf(stderr, XACMPERRMSG, "(post-fromISO) PartMapTable.pml",
                    index, 0xff, rpml );

        rvsn = pmt[index].volumeSeqNo;
        if ( rvsn != 0xffff )
            fprintf(stderr, XACMPERRMSG, "(after fit) PartMapTable.vsNo",
                    index, 0xffff, rvsn );

        rpn = pmt[index].partitionNo;
        if ( rpn != 0xffff )
            fprintf(stderr, XACMPERRMSG, "(after fit) PartMapTable.pNo",
                    index, 0xffff, rpn );
    }

  TstADTable:

    // Needs read and write vars - use same as longAD test...
    
    clrBuf( bp );
    offs = 1501;                // These arbitrary numbers are GREAT

    ADTable adt( offs,20,ad_Long );
    LongAllocDesc *ada;
    
    for (index = 0; index < adt.numADs(); index++ ) {
        ada = adt.longADp();
        ada[index].partRefNo(wprn + index);
        ada[index].logBlockNo(wlbn + index);
        ada[index].extLength(wel + index);
        ada[index].extType(wet);
        ada[index].markErased();
    }

    for (index = 0; index < adt.numADs(); index++ ) {
        ada = adt.longADp();
        rprn = ada[index].partRefNo();
        if ( rprn != wprn + index)
            fprintf(stderr, XACMPERRMSG, "(pre)adt.prn", index, wprn+index, rprn );
        rlbn = ada[index].logBlockNo();
        if ( rlbn != wlbn + index)
            fprintf(stderr, XACMPERRMSG, "(pre)adt.lbn", index, wlbn+index, rlbn );
        rel  = ada[index].extLength();
        if ( rel  != wel + index)
            fprintf(stderr, XACMPERRMSG, "(pre)adt.el", index, wel+index, rel );
        ret  = ada[index].extType();
        if ( ret  != wet)
            fprintf(stderr, XACMPERRMSG, "(pre)adt.et", index, wet, ret );
        if ( ! ada[index].isErased())
            fprintf(stderr, XACMPERRMSG, "(pre)adt.erased", index, 1, 0 );
    }

    adt.toISO( bp );

    err = chkBgnd ( bp, 0, offs, adt.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "adt.toISO", err );
    setBgnd ( bp, 0xff, offs, adt.field.len() );

    adt.clear();

    adt.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, adt.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "adt.fromISO",err );

    for (index = 0; index < adt.numADs(); index++ ) {
        ada = adt.longADp();
        rprn = ada[index].partRefNo();
        if ( rprn != wprn + index)
            fprintf(stderr, XACMPERRMSG, "(post)adt.prn", index, wprn+index, rprn );
        rlbn = ada[index].logBlockNo();
        if ( rlbn != wlbn + index)
            fprintf(stderr, XACMPERRMSG, "(post)adt.lbn", index, wlbn+index, rlbn );
        rel  = ada[index].extLength();
        if ( rel  != wel + index)
            fprintf(stderr, XACMPERRMSG, "(post)adt.el", index, wel+index, rel );
        ret  = ada[index].extType();
        if ( ret  != wet)
            fprintf(stderr, XACMPERRMSG, "(post)adt.et", index, wet, ret );
        if ( ! ada[index].isErased())
            fprintf(stderr, XACMPERRMSG, "(post)adt.erased", index, 1, 0 );
    }
    
    adt.fitToLen( 336 );
    adt.fromISO( bp );

    for (index = 20; index < adt.numADs(); index++ ) {
        ada = adt.longADp();
        rprn = ada[index].partRefNo();
        if ( rprn != 0xffff)
            fprintf(stderr, XACMPERRMSG, "(post-grow)adt.prn",
                    index, 0xffff, rprn );
        rlbn = ada[index].logBlockNo();
        if ( rlbn != 0xffffffff)
            fprintf(stderr, XACMPERRMSG, "(post-grow)adt.lbn",
                    index, 0xffffffff, rlbn );
        rel  = ada[index].extLength();
        if ( rel  != 0x3fffffff)
            fprintf(stderr, XACMPERRMSG, "(post-grow)adt.el",
                    index, 0x3fffffff, rel );
        ret  = ada[index].extType();
        if ( ret  != ad_Embedded )
            fprintf(stderr, XACMPERRMSG, "(post-grow)adt.et",
                    index, 0x3, ret );
        if ( ! ada[index].isErased())
            fprintf(stderr, XACMPERRMSG, "(post-grow)adt.erased",
                    index, 1, 0 );
    }

  TstRegID:

    String ws = "Test Value for RegIDs";
    String rs;

    offs = 1444;

    clrBuf( bp );

    RegID rid( offs );

    rid.id(ws);
    rs = rid.id();
    if ( ws != rs )
        fprintf(stderr, SCMPERRMSG, "RegID(pre-toISO)",
                (CONST_CHAR_PTR)ws,(CONST_CHAR_PTR)rs );

    rid.toISO( bp );

    err = chkBgnd ( bp, 0, offs, rid.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "RegID(post-toISO)", err );
    setBgnd ( bp, 0xff, offs, rid.field.len() );

    rid.id("");
    rid.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, rid.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "RegID(post-toISO)",err );

    rs = rid.id();
    if ( ws != rs )
        fprintf(stderr, SCMPERRMSG, "RegID(post-fromISO)",
                (CONST_CHAR_PTR)ws,(CONST_CHAR_PTR)rs );

  TstImplRegID:

    NSR::ImplRegID::HPID = "Test Value - ImplRegIDs";

    offs = 1444;

    clrBuf( bp );

    ImplRegID irid( offs );

    rs = irid.id();
    if ( NSR::ImplRegID::HPID != rs )
        fprintf(stderr, SCMPERRMSG, "ImplRegID(pre-toISO)",
                (CONST_CHAR_PTR)NSR::ImplRegID::HPID,
                (CONST_CHAR_PTR)rs );

    irid.toISO( bp );

    err = chkBgnd ( bp, 0, offs, irid.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "ImplRegID(post-toISO)", err );
    setBgnd ( bp, 0xff, offs, irid.field.len() );

    irid.fromISO( bp );

    err = chkBgnd ( bp, 0xff, offs, irid.field.len() );
    if (err) fprintf( stderr, BGERRMSG, "ImplRegID(post-toISO)",err );

    rs = irid.id();
    if ( NSR::ImplRegID::HPID != rs )
        fprintf(stderr, SCMPERRMSG, "ImplRegID(post-fromISO)",
                (CONST_CHAR_PTR)NSR::ImplRegID::HPID,
                (CONST_CHAR_PTR)rs );

// Descriptor Testing

    SearchDescriptor           sd;

  TstBitmap:

    const UINT32 numberOfBits = 8*1024;

    // Create an SBD for writing.
    SpaceBitmapDesc wsbd(numberOfBits);
    if ( wsbd.error() != error_None )
        fprintf( stderr, "SpaceBitmap Desc error on construction() : %s.\n",
                 wsbd.error().message());

    // Verify Bit/Byte calculations
    if (wsbd.numBytes() != (numberOfBits+7) / 8) {
        fprintf( stderr, "numBytes = %d, for numBits = %d\n",
                 wsbd.numBytes(),wsbd.numBits());
    }

    // Write it to the buffer
    wsbd.toISO( bp, 0x1234 );
    if ( wsbd.error() != error_None )
        fprintf( stderr, "SpaceBitmap Desc error on toISO() : %s.\n",
                 wsbd.error().message());

    // Now create an empty SBD for reading.
    SpaceBitmapDesc rsbd;

    // Read from bad location
    rsbd.fromISO( bp, 0x5678 );
    if ( rsbd.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "SpaceBitmap Desc had no error at bad address\n");

    // Corrupt a byte and read
    BYTE *corrupt0 = bp+20;     // choose a byte to corrupt
    *corrupt0 = ~(*corrupt0);   // corrupt the byte
    rsbd.clear();               // Clear out the error
    rsbd.fromISO( bp, 0x1234 );
    if ( rsbd.error() != NSR::error_Bad_descr_CRC )
        fprintf( stderr, "SpaceBitmap Desc had no error when contents corrupted\n");
    *corrupt0 = ~(*corrupt0);   // restore the byte

    // Now read it expecting no error.
    rsbd.clear();                // Clear out the error
    rsbd.fromISO( bp, 0x1234 );
    if ( rsbd.error() != error_None )
        fprintf( stderr, "SpaceBitmap Desc error on fromISO() : %s.\n",
                 rsbd.error().message());
        
#ifdef NSR_VERIFY
    if ( rsbd != wsbd )
        fprintf( stderr, "SpaceBitmap Descriptors do not match.\n");
#endif

  TstSBM:

    // Set some constants for testing purposes:
    const UINT16 tstBlockSize      = 512;
    // These numbers are one-based, while the index is
    // zero-based. Therefore, it should work!
    const UINT32 baForBlockPlusOne = ((tstBlockSize -
                                       wsbd.descLen()) *
                                      8 ); 
    const UINT32 baForBlockPlusTwo = (baForBlockPlusOne +
                                      (tstBlockSize * 8));

    const blockAddr = 0x1234;
    
    // Test the SpaceBitmapMap
    SpaceBitmapMap sbm(wsbd,blockAddr,tstBlockSize);

    // First, test the blockNum() stuff, covering corner cases.
    if(sbm.blockNum(baForBlockPlusOne-1) != sbm.blockAbsToRel(blockAddr)) {
        fprintf( stderr, "SBM Error: blockNum(%d) = 0x%x, != 0x%x\n",
                baForBlockPlusOne-1,
                sbm.blockNum(baForBlockPlusOne-1),
                sbm.blockAbsToRel(blockAddr));
    }

    if(sbm.blockNum(baForBlockPlusOne) != sbm.blockAbsToRel(blockAddr) + 1) {
        fprintf( stderr, "SBM Error: blockNum(%d) = 0x%x, != 0x%x\n",
                baForBlockPlusOne,
                sbm.blockNum(baForBlockPlusOne),
                sbm.blockAbsToRel(blockAddr) + 1);
    }

    if(sbm.blockNum(baForBlockPlusTwo-1) != sbm.blockAbsToRel(blockAddr)+1) {
        fprintf( stderr, "SBM Error: blockNum(%d) = 0x%x, != 0x%x\n",
                baForBlockPlusTwo-1,
                sbm.blockNum(baForBlockPlusTwo-1),
                sbm.blockAbsToRel(blockAddr)+1);
    }

    if(sbm.blockNum(baForBlockPlusTwo) != sbm.blockAbsToRel(blockAddr) + 2) {
        fprintf( stderr, "SBM Error: blockNum(%d) = 0x%x, != 0x%x\n",
                baForBlockPlusTwo,
                sbm.blockNum(baForBlockPlusTwo),
                sbm.blockAbsToRel(blockAddr) + 2);
    }

    // The bitmap is held in a ByteArray. Make it 2K to make sure
    // there is lots of room for numberOfBits
    ByteArray bitmap(2048);

    // Now, Zero it all out
    bitmap.clear();
    
    // Write the SpaceBitmapDesc into the array.
    wsbd.toISO(bitmap,blockAddr);
    
    // Verify that SBD is still there.
    rsbd.clear();                // Clear out the error
    rsbd.fromISO( bitmap, 0, blockAddr );
    if ( rsbd.error() != error_None )
        fprintf( stderr, "pre-bitmapMap test: SBD error on fromISO() : %s.\n",
                 rsbd.error().message());
        
#ifdef NSR_VERIFY
    if ( rsbd != wsbd )
        fprintf( stderr, "pre-bitmapMap test: SpaceBitmap Descriptors do not match.\n");
#endif

    // Declare an index for byte address
    UINT32 ba;
    // At this point, all bits in the map should be zero --
    // Set every other bit
    for (ba=0;ba < numberOfBits;ba+=2) {
        *((BYTE_PTR)bitmap+
          (sbm.startByteOffset()+
           sbm.byteComponent(ba)))
            |= sbm.maskBit(ba);
    }

    // Test even bits for not being set
    for (ba=0;ba < numberOfBits;ba+=2) {
        if(*((BYTE_PTR)bitmap+
             (sbm.startByteOffset()+
              sbm.byteComponent(ba))) & sbm.maskBit(ba)==0) {
            fprintf( stderr, "SBD error: Bit incorrectly not set\n" );
            fprintf( stderr, "Bit %d at block 0x%x, offs %d, mask 0x%x, value 0x%x\n,",
                     ba,
                     sbm.blockNum(ba),
                     sbm.startByteOffset()+sbm.byteComponent(ba),
                     sbm.maskBit(ba), 
                     *((BYTE_PTR)bitmap+
                       sbm.startByteOffset()+
                       sbm.byteComponent(ba)));
        }
    }

    // Test odd bits for being set
    for (ba=1;ba < numberOfBits;ba+=2) {
        if((*((BYTE_PTR)bitmap+
              (sbm.startByteOffset()+
               sbm.byteComponent(ba))) & sbm.maskBit(ba))!=0) {
            fprintf( stderr, "SBD error: Bit incorrectly set\n" );
            fprintf( stderr, "Bit %d at block 0x%x, offs %d, mask 0x%x, value 0x%x\n,",
                     ba,
                     sbm.blockNum(ba),
                     sbm.startByteOffset()+sbm.byteComponent(ba),
                     sbm.maskBit(ba), 
                     *((BYTE_PTR)bitmap+
                       sbm.startByteOffset()+
                       sbm.byteComponent(ba)));
        }
    }

    // Verify that SBD is still there.
    rsbd.clear();                // Clear out the error
    rsbd.fromISO( bitmap, 0, blockAddr );
    if ( rsbd.error() != error_None )
        fprintf( stderr, "post-bitmapMap test: SBD error on fromISO() : %s.\n",
                 rsbd.error().message());
        
#ifdef NSR_VERIFY
    if ( rsbd != wsbd )
        fprintf( stderr, "post-bitmapmap test: SpaceBitmap Descriptors do not match.\n");
#endif

  TstFE:

    FileEntry efe(0,ad_Extended);
    FileEntry lfe(0,ad_Long);
    FileEntry sfe(0,ad_Short);
    FileEntry dfe(0,ad_Embedded);

    if (efe.maxADTEnts(512,ad_Extended)  != 16 )
        fprintf( stderr, "Max FE ADT Ents (Extended) (512)  %d != 16 \n",
                efe.maxADTEnts(512,ad_Extended));
    if (efe.maxADTEnts(1024,ad_Extended) != 42 )
        fprintf( stderr, "Max FE ADT Ents (Extended) (1024) %d != 42 \n",
                efe.maxADTEnts(1024,ad_Extended));
    if (lfe.maxADTEnts(512,ad_Long)  != 21 )
        fprintf( stderr, "Max FE ADT Ents (Long)     (512)  %d != 21 \n",
                lfe.maxADTEnts(512,ad_Long));
    if (lfe.maxADTEnts(1024,ad_Long) != 53 )
        fprintf( stderr, "Max FE ADT Ents (Long)     (1024) %d != 53 \n",
                lfe.maxADTEnts(1024,ad_Long));
    if (sfe.maxADTEnts(512,ad_Short)  != 42 )
        fprintf( stderr, "Max FE ADT Ents (Short)    (512)  %d != 42 \n",
                sfe.maxADTEnts(512,ad_Short));
    if (sfe.maxADTEnts(1024,ad_Short) != 106 )
        fprintf( stderr, "Max FE ADT Ents (Short)    (1024) %d != 106\n",
                sfe.maxADTEnts(1024,ad_Short));
    if (dfe.maxADTEnts(512,ad_Embedded)  != 512-176 )
        fprintf( stderr, "Max FE ADT Ents (Embedded) (512)  %d != 512-176 \n",
                sfe.maxADTEnts(512,ad_Embedded));
    if (dfe.maxADTEnts(1024,ad_Embedded) != 1024-176 )
        fprintf( stderr, "Max FE ADT Ents (Embedded) (1024) %d != 1024-176\n",
                sfe.maxADTEnts(1024,ad_Embedded));

    FileEntry wfe(10,ad_Long);// 10 extents
    FileEntry rfe(0,ad_Long); // 0 extents

    clrBuf( bp );

    ada = wfe.longADT();
    
    for (index = 0; index < wfe.numADTEnts(); index++ ) {
        ada[index].partRefNo(wprn + index);
        ada[index].logBlockNo(wlbn + index);
        ada[index].extLength(wel + index);
        ada[index].extType(wet);
        ada[index].markErased();
    }

    Attributes wattr,rattr;

    // Times are important, testing out a previous bug in the TimeStamp.
    wattr.sortedDirectoryBit(True);
    wattr.uid               ( 0x89abcdef );
    wattr.gid               ( 0x89abcdef );
    wattr.unixMode          ( 07631 );  // octal constant
    wattr.linkCount         ( 20 );
    wattr.accessTime        ( 812051630 ); // In Daylight Savings
    wattr.modificationTime  ( 724326181 ); // In normal time     
    wattr.attributeTime     ( 810446160 );
    wattr.fileType          ( file_Unspecified );
    
    wattr.toFileEntry(wfe); // was wfe.setAttributes(wattr);

    wfe.toISO( bp, 0x1234 );
    if ( wfe.error() != error_None )
        fprintf( stderr, "File Entry error on toISO() : %s.\n",
                 wfe.error().message());
        
    rfe.fromISO( bp, 0x5678 );
    if ( rfe.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "File Entry had no error at bad address\n");

    BYTE *corrupt = bp+48;      // choose a byte to corrupt
    *corrupt = ~(*corrupt);     // corrupt the byte
    rfe.clear();                // Clear out the error
    rfe.fromISO( bp, 0x1234 );
    if ( rfe.error() != NSR::error_Bad_descr_CRC )
        fprintf( stderr, "File Entry had no error when contents corrupted\n");
    *corrupt = ~(*corrupt);     // restore the byte

    rfe.clear();                // Clear out the error
    rfe.fromISO( bp, 0x1234 );
    if ( rfe.error() != error_None )
        fprintf( stderr, "File Entry error on fromISO() : %s.\n",
                 rfe.error().message());
        
#ifdef NSR_VERIFY
    if ( rfe != wfe )
        fprintf( stderr, "File Entries do not match.\n");
#endif
    rattr.fromFileEntry(rfe); // was rattr = rfe.getAttributes();

    UINT16 diff = 0;
    
    diff += (wattr != rattr);
#if 0  // We don't need this since we have Attributes::operator==().
    // CSB, 9-18-95
    diff += ( wattr.directory    != rattr.directory    );
    diff += ( wattr.symbolicLink != rattr.symbolicLink );
    diff += ( wattr.uid          != rattr.uid          );
    diff += ( wattr.gid          != rattr.gid          );
    diff += ( wattr.mode         != rattr.mode         );
    diff += ( wattr.linkCount    != rattr.linkCount    );
    diff += ( wattr.atime        != rattr.atime        );
    diff += ( wattr.mtime        != rattr.mtime        );
    diff += ( wattr.ctime        != rattr.ctime        );
#endif

    if ( diff != 0 )
        fprintf( stderr, "File Entry : %d attributes do not match.\n", diff );

    sd.fromISO( bp, 0x5678 );
    if (sd.error() == error_None)
        fprintf( stderr,
                 "FE SearchDescriptor did not err on bad location.\n");

    sd.fromISO( bp, 0x1234 );
    if (sd.error() != error_None)
        fprintf( stderr, "FE SearchDescriptor err: %s.\n",
                 sd.error().message());
    if (sd.type() != tag_FE )
        fprintf( stderr, "FE not recognized by SearchDescriptor\n");

    // NOW test the embedded data.
    UINT16 embDataLen = dfe.maxADTEnts(1024,ad_Embedded);
    
    ByteArray tstData(embDataLen);

    {                           // Local block for own error. May not need this.....
        Error err;
        err = dfe.numADTEnts(1024,embDataLen,ad_Embedded);
        if (err) {
            fprintf( stderr, "Error setting embeddedDataLen to max. err: %s.\n",
                     err.message());
        }
    }

    tstData.clear();
    for (int i=0; i<tstData.length(); i++) {
        *((BYTE *)tstData + i) = 'A' + (i%(26*2));
    }
    tstData.toMem(dfe.embeddedDatap());
    
    wattr.fileType          ( file_Raw );
    wattr.toFileEntry(dfe); // was wfe.setAttributes(wattr);

    dfe.toISO( bp, 0x1234 );
    if ( dfe.error() != error_None )
        fprintf( stderr, "File Entry error on toISO() : %s.\n",
                 dfe.error().message());
        
    rfe.fromISO( bp, 0x5678 );
    if ( rfe.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "File Entry had no error at bad address\n");

    BYTE *corrupt2 = bp+48;      // choose a byte to corrupt
    *corrupt2 = ~(*corrupt2);     // corrupt the byte
    rfe.clear();                // Clear out the error
    rfe.fromISO( bp, 0x1234 );
    if ( rfe.error() != NSR::error_Bad_descr_CRC )
        fprintf( stderr, "File Entry had no error when contents corrupted\n");
    *corrupt2 = ~(*corrupt2);     // restore the byte

    rfe.clear();                // Clear out the error
    rfe.fromISO( bp, 0x1234 );
    if ( rfe.error() != error_None )
        fprintf( stderr, "File Entry error on fromISO() : %s.\n",
                 rfe.error().message());
        
#ifdef NSR_VERIFY
    if ( rfe != dfe )
        fprintf( stderr, "File Entries do not match.\n");
#endif
    
  TstFID:
    
    String fname("WhoAmIStrangeFileName");

    // Try out instantiation

    FileIdentifierDesc wfid(fname);
    FileIdentifierDesc rfid; // empty

    clrBuf( bp );

    // Try out local methods

    if ( wfid.isDir() )
        fprintf( stderr, "isDir was already set.\n");
    if ( wfid.isDel() )
        fprintf( stderr, "isDel was already set.\n");
    
    wfid.markDir();
    wfid.markDel();

    if ( ! wfid.isDir() )
        fprintf( stderr, "isDir did not work.\n");
    if ( ! wfid.isDel() )
        fprintf( stderr, "isDel did not work.\n");

    for (index = 0; index < 19; index++ ) {

        // Try assignment into fileIdentifier field.
        fname.remove(20-index);
        wfid.fileID(fname);

        wfid.icbAddr.partRefNo(wprn + index);
        wfid.icbAddr.logBlockNo(wlbn + index);
        wfid.icbAddr.extLength(wel + index);
        wfid.icbAddr.extType(wet);
        wfid.icbAddr.markErased();
        wfid.toISO( bp, 0x1234 );

        if ( wfid.error() != error_None )
            fprintf( stderr, "FID[%d] error on toISO() : %s.\n",
                     index,wfid.error().message());
        
        rfid.fromISO( bp, 0x5678 );
        if ( rfid.error() != NSR::error_Bad_tag_location )
            fprintf( stderr, "FID[%d] had no error at bad address\n",index);

        rfid.clear();                // Clear out the error
        rfid.fromISO( bp, 0x1234 );
        if ( rfid.error() != error_None )
            fprintf( stderr, "FID[%d] error on fromISO() : %s.\n",
                     index, rfid.error().message());
        
#ifdef NSR_VERIFY
        if ( rfid != wfid )
            fprintf( stderr, "FIDs[%d] do not match.\n",index);
#endif
        ByteArray bashort(bp,60); // Grab the first 60 bytes

        rfid.clear();                // Clear out the error
        rfid.fromISO( bashort, 0, 0x1234 );
        if ( rfid.error() != NSR::error_End_of_buffer )
            fprintf( stderr, "FID[%d] - no End error on fromISO(<shortened>ByteArray) : %s.\n",
                     index, rfid.error().message());

        ByteArray balong(bp,BUFLEN); // Grab the entire buffer

        rfid.clear();                // Clear out the error
        rfid.fromISO( balong, 0, 0x1234 );
        if ( rfid.error() != error_None )
            fprintf( stderr, "FID[%d] error on fromISO(ByteArray) : %s.\n",
                     index, rfid.error().message());

        ByteArray bashifted(bp,BUFLEN); // Make a new buffer

        memmove((BYTE *)bashifted + 40,(BYTE *)bashifted, rfid.descLen());

        rfid.clear();                // Clear out the error
        rfid.fromISO( bashifted, 40, 0x1234 );
        if ( rfid.error() != error_None )
            fprintf( stderr, "FID[%d] error on fromISO(shifted ByteArray) : %s.\n",
                     index, rfid.error().message());
    }
    
    sd.fromISO( bp, 0x5678 );
    if (sd.error() == error_None)
        fprintf( stderr,
                 "FID SearchDescriptor did not err on bad location.\n");

    sd.fromISO( bp, 0x1234 );
    if (sd.error() != error_None)
        fprintf( stderr, "FID SearchDescriptor err: %s.\n",
                 sd.error().message());
    if (sd.type() != tag_FID )
        fprintf( stderr, "FID not recognized by SearchDescriptor\n");

    
  TstAED:

    AllocExtentDesc eaed(0,ad_Extended);
    AllocExtentDesc laed(0,ad_Long);
    AllocExtentDesc saed(0,ad_Short);

    if (eaed.maxADTEnts(512)  != 24 )
        fprintf( stderr, "Max AED ADT Ents (Extended) (512)  %d != 24 \n",
                eaed.maxADTEnts(512));
    if (eaed.maxADTEnts(1024) != 50 )
        fprintf( stderr, "Max AED ADT Ents (Extended) (1024) %d != 50 \n",
                eaed.maxADTEnts(1024));
    if (laed.maxADTEnts(512)  != 30 )
        fprintf( stderr, "Max AED ADT Ents (Long)     (512)  %d != 30 \n",
                laed.maxADTEnts(512));
    if (laed.maxADTEnts(1024) != 62 )
        fprintf( stderr, "Max AED ADT Ents (Long)     (1024) %d != 62 \n",
                laed.maxADTEnts(1024));
    if (saed.maxADTEnts(512)  != 61 )
        fprintf( stderr, "Max AED ADT Ents (Short)    (512)  %d != 61 \n",
                saed.maxADTEnts(512));
    if (saed.maxADTEnts(1024) != 125 )
        fprintf( stderr, "Max AED ADT Ents (Short)    (1024) %d != 125\n",
                saed.maxADTEnts(1024));

    AllocExtentDesc waed(20,ad_Long); // 20 extents
    AllocExtentDesc raed(0,ad_Long); // 0 extents

    clrBuf( bp );

    ada = waed.longADT();
    
    for (index = 0; index < waed.numADTEnts(); index++ ) {
        ada[index].partRefNo(wprn + index);
        ada[index].logBlockNo(wlbn + index);
        ada[index].extLength(wel + index);
        ada[index].extType(wet);
        ada[index].markErased();
    }

    waed.toISO( bp, 0x1234 );
    if ( waed.error() != error_None )
        fprintf( stderr, "AED error on toISO() : %s.\n",
                 waed.error().message());
        
    raed.fromISO( bp, 0x5678 );
    if ( raed.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "AED had no error at bad address\n");

    raed.clear();                // Clear out the error
    raed.fromISO( bp, 0x1234 );
    if ( raed.error() != error_None )
        fprintf( stderr, "AED error on fromISO() : %s.\n",
                 raed.error().message());
        
#ifdef NSR_ERROR
    if ( raed != waed )
        fprintf( stderr, "AEDs do not match.\n");
#endif    
    sd.fromISO( bp, 0x5678 );
    if (sd.error() == error_None)
        fprintf( stderr,
                 "AED SearchDescriptor did not err on bad location.\n");

    sd.fromISO( bp, 0x1234 );
    if (sd.error() != error_None)
        fprintf( stderr, "AED SearchDescriptor err: %s.\n",
                 sd.error().message());
    if (sd.type() != tag_AED )
        fprintf( stderr, "AED not recognized by SearchDescriptor\n");

  TstLVID:

    // In order to test the LVID with the ICBTable, we must set the
    // descVersion appropriately.
    // Save off the original values, and restore when done with this
    // test.
    UINT8  saveLVIDvsn = NSR::LogicalVolumeIntegrityDesc::descVersion_;
    NSR::LogicalVolumeIntegrityDesc::descVersion_ = 0;

    LogicalVolumeIntegrityDesc wlvid(32,288);
    
    LogicalVolumeIntegrityDesc rlvid(0); // 0 partitions

    clrBuf( bp );

    wlvid.numFiles            = 0x12345678;
    wlvid.numDirectories      = 0x9abcdef0;

    for (index = 0; index < wlvid.numPartitions; index++ ) {
        wlvid.freeSpaceTable[index] = ~index;
        wlvid.sizeTable[index]      = index;
    }

    if (wlvid.hasICBTable() == True) {

        ada = wlvid.icbTbl();
        for (index = 0; index < wlvid.numEnts(); index++ ) {
            ada[index].partRefNo(wprn + index);
            ada[index].logBlockNo(wlbn + index);
            ada[index].extLength(wel + index);
            ada[index].extType(wet);
            ada[index].markErased();
        }
    }
    
    wlvid.toISO( bp, 0x1234 );
    if ( wlvid.error() != error_None )
        fprintf( stderr, "LVID error on toISO() : %s.\n",
                 wlvid.error().message());
        
    rlvid.fromISO( bp, 0x5678 );
    if ( rlvid.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "LVID had no error at bad address\n");

    rlvid.clear();                // Clear out the error
    rlvid.fromISO( bp, 0x1234 );
    if ( rlvid.error() != error_None )
        fprintf( stderr, "LVID error on fromISO() : %s.\n",
                 rlvid.error().message());
        
#ifdef NSR_VERIFY
    if ( rlvid != wlvid )
        fprintf( stderr, "LVIDs do not match.\n");
#endif    
    sd.fromISO( bp, 0x5678 );
    if (sd.error() == error_None)
        fprintf( stderr,
                 "LVID SearchDescriptor did not err on bad location.\n");

    sd.fromISO( bp, 0x1234 );
    if (sd.error() != error_None)
        fprintf( stderr, "LVID SearchDescriptor err: %s.\n",
                 sd.error().message());
    if (sd.type() != tag_LVID )
        fprintf( stderr, "LVID not recognized by SearchDescriptor\n");

    // Now, restore the saved value.
    NSR::LogicalVolumeIntegrityDesc::descVersion_ = saveLVIDvsn;

TstOSTAVD:
    
    OSTAVolumeDesc wovd, rovd;

    clrBuf( bp );

    wovd.volDescSeqNo = 0x12345678;
    wovd.logicalVolumeID = "This is the identifier field of the OSTAVolumeDescriptor";
    wovd.logicalVolumeInfo1 = "1234567890123456789012345678901234";
    wovd.logicalVolumeInfo2 = "123456789012345678901234567890123";
    wovd.logicalVolumeInfo3 = "12345678901234567890123456789012";
    wovd.implementUse = "This is the Implementation Use area of the OSTAVolumeDescriptor";
    
    wovd.toISO( bp, 0x1234 );
    if ( wovd.error() != error_None )
        fprintf( stderr, "OVD error on toISO() : %s.\n",
                 wovd.error().message());
        
    rovd.fromISO( bp, 0x5678 );
    if ( rovd.error() != NSR::error_Bad_tag_location )
        fprintf( stderr, "OVD had no error at bad address\n");

    rovd.clear();                // Clear out the error
    rovd.fromISO( bp, 0x1234 );
    if ( rovd.error() != error_None )
        fprintf( stderr, "OVD error on fromISO() : %s.\n",
                 rovd.error().message());
        
#ifdef NSR_VERIFY
    if ( rovd != wovd )
        fprintf( stderr, "OVDs do not match.\n");
#endif    
    sd.fromISO( bp, 0x5678 );
    if (sd.error() == error_None)
        fprintf( stderr,
                 "OVD SearchDescriptor did not err on bad location.\n");

    sd.fromISO( bp, 0x1234 );
    if (sd.error() != error_None)
        fprintf( stderr, "OVD SearchDescriptor err: %s.\n",
                 sd.error().message());
    if (sd.type() != tag_IUVD )
        fprintf( stderr, "OVD not recognized by SearchDescriptor\n");
        
  TstLVD:
    
    LogicalVolumeDesc          wlvd(5);
    LogicalVolumeDesc *rlvd = new LogicalVolumeDesc;
    wlvd.toISO(bp,0xcdef);
    if ( wlvd.error() )
        fprintf( stderr, "%s\n",wlvd.error().message());

    rlvd->fromISO(bp,0xcdef);
#ifdef NSR_VERIFY
    if ( *rlvd != wlvd ) {
        fprintf( stderr, "LVDs do not match.\n");
        fprintf( stderr, "RLVD.error is: %s\n",rlvd->error().message());
        fprintf( stderr, "WLVD.error is: %s\n",wlvd.error().message());
    }
#endif
    delete rlvd;

  TstFSD:
    
    FileSetDesc wfsd, rfsd;
    if ( wfsd.writeProtect() != wrprot_None )
        fprintf( stderr, "FSD: new FSD is Write protected.\n");

    wfsd.writeProtect(wrprot_None);
    if ( wfsd.writeProtect() != wrprot_None )
        fprintf( stderr, "FSD: NO write protect not set (pre-toISO).\n");
    wfsd .toISO(bp,0xcdef);
    if ( wfsd.error() )
        fprintf( stderr, "%s\n",wfsd.error().message());
    if ( wfsd.writeProtect() != wrprot_None )
        fprintf( stderr, "FSD: No write protect not set (post-toISO).\n");

    wfsd.clear();
    if ( wfsd.writeProtect() != wrprot_None )
        fprintf( stderr, "FSD: new FSD is Write protected.\n");

    wfsd.writeProtect(wrprot_Soft);
    if ( wfsd.writeProtect() != wrprot_Soft )
        fprintf( stderr, "FSD: Soft write protect not set (pre-toISO).\n");
    wfsd .toISO(bp,0xcdef);
    if ( wfsd.error() )
        fprintf( stderr, "%s\n",wfsd.error().message());
    if ( wfsd.writeProtect() != wrprot_Soft )
        fprintf( stderr, "FSD: Soft write protect not set (post-toISO).\n");

    wfsd.clear();
    if ( wfsd.writeProtect() != wrprot_None )
        fprintf( stderr, "FSD: new FSD is Write protected.\n");

    wfsd.writeProtect(wrprot_Hard);
    if ( wfsd.writeProtect() != wrprot_Hard )
        fprintf( stderr, "FSD: Hard write protect not set (pre-toISO).\n");
    wfsd .toISO(bp,0xcdef);
    if ( wfsd.error() )
        fprintf( stderr, "%s\n",wfsd.error().message());
    if ( wfsd.writeProtect() != wrprot_Hard )
        fprintf( stderr, "FSD: Hard write protect not set (post-toISO).\n");

    rfsd .fromISO(bp,0xcdef);
    if ( rfsd.error() )
        fprintf( stderr, "%s\n",rfsd.error().message());
    
    if ( rfsd != wfsd ) {
        fprintf( stderr, "FSDs do not match.\n");
        fprintf( stderr, "RFSD.error is: %s\n",rfsd.error().message());
        fprintf( stderr, "WFSD.error is: %s\n",wfsd.error().message());
    }

  TstEAHD:

    ExtendedAttrHeaderDesc    eahd;
    eahd.implAttrLocation(0xfedcba98);
    eahd.applAttrLocation(0x01234567);
    eahd.toISO(bp,0x3456);
    if ( eahd.error() )
        fprintf( stderr, "%s\n",eahd.error().message());
    
  TstOthers:

    ImplementUseVolumeDesc     iuvd;
    iuvd .toISO(bp,0xcdef);
    if ( iuvd.error() )
        fprintf( stderr, "%s\n",iuvd.error().message());

    AnchorVolumeDesc           avd;
    avd .toISO(bp,0xcdef);
    if ( avd.error() )
        fprintf( stderr, "%s\n",avd.error().message());
    
    PrimaryVolumeDesc          pvd;
    pvd .toISO(bp,0xcdef);
    if ( pvd.error() )
        fprintf( stderr, "%s\n",pvd.error().message());
    
    PartitionDesc              pd;
    pd  .toISO(bp,0xcdef);
    if ( pd.error() )
        fprintf( stderr, "%s\n",pd.error().message());

    UnallocatedSpaceDesc       usd;
    usd .toISO(bp,0xcdef);
    if ( usd.error() )
        fprintf( stderr, "%s\n",usd.error().message());

    UnallocatedSpaceEntry      use(10); // 10 extents, short ads.
    use .toISO(bp,0xcdef);
    if ( use.error() )
        fprintf( stderr, "%s\n",use.error().message());

    UnallocatedSpaceEntry suse(0);

    if (suse.maxADTEnts(512)  != 59 )
        fprintf( stderr, "Max USE ADT Ents (Short)    (512)  %d != 59 \n",
                suse.maxADTEnts(512));
    if (suse.maxADTEnts(1024) != 123 )
        fprintf( stderr, "Max USE ADT Ents (Short)    (1024) %d != 123\n",
                suse.maxADTEnts(1024));

  ConstructEAVariables:

    EAInspector eaInsp ;        // EA inspector.
    UINT32      mal    ;        // Holds minAttrLen().
    Error       error  ;        // Need one.
    
  TstFileTimesEA:

    // Instantiate one of these.
    FileTimesEA wftea;

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    wftea.fileCreation ( 812051630 ); // In Daylight Savings

    // Make sure minAttrLen() is multiple of 4.
    mal = wftea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "FileTimesEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    wftea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "FileTimesEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Check to see if pads to multiple of 4 bytes.
    wftea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "FileTimesEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    wftea.toISO( bp + 0x12 );
    if ( wftea.error() != error_None )
        fprintf( stderr, "FileTimesEA error on toISO() : %s.\n",
                 wftea.error().message());

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "FileTimesEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != wftea.attrType()) {
        fprintf( stderr, "FileTimesEA.attrType()=%ul\n",wftea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != wftea.attrSubtype()) {
        fprintf( stderr, "FileTimesEA.attrSubtype()=%ul\n",wftea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != wftea.attrLen()) {
        fprintf( stderr, "FileTimesEA.attrLen()=%ul\n",wftea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    if (eaInsp.fixedLen() != wftea.fixedLen()) {
        fprintf( stderr, "FileTimesEA.fixedLen()=%ul\n",wftea.fixedLen());
        fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    }
    // ONLY for implemantationUse and applicationUse EAs.
    //if (eaInsp.attrID() != wftea.attrID()) {
    //    fprintf( stderr, "FileTimesEA.attrID()=%s\n",(CONST_CHAR_PTR)wftea.attrID());
    //    fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    //}
        
  TstFreeEASpaceEA:

    // Instantiate one of these.
    FreeEASpaceEA fsea(56);
    if ( fsea.error() )
        fprintf( stderr, "FreeEASpaceEA error on construction : %s.\n",
                 fsea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.

    // Make sure minAttrLen() is multiple of 4.
    mal = fsea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "FreeEASpaceEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    fsea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "FreeEASpaceEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    fsea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "FreeEASpaceEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Translate it toISO, (looping back automatically)
    fsea.toISO( bp + 0x12 );
    if ( fsea.error() )
        fprintf( stderr, "FreeEASpaceEA error on toISO(), pad = %ul : %s.\n",
                 fsea.error().message(),fsea.attrLen() - mal);

    // Check to see if pads to multiple of 4 bytes.
    fsea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "FreeEASpaceEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    fsea.toISO( bp + 0x12 );
    if ( fsea.error() )
        fprintf( stderr, "FreeEASpaceEA error on toISO(), pad = %ul : %s.\n",
                 fsea.error().message(),fsea.attrLen() - mal);

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "FreeEASpaceEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != fsea.attrType()) {
        fprintf( stderr, "FreeEASpaceEA.attrType()=%ul\n",fsea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != fsea.attrSubtype()) {
        fprintf( stderr, "FreeEASpaceEA.attrSubtype()=%ul\n",fsea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != fsea.attrLen()) {
        fprintf( stderr, "FreeEASpaceEA.attrLen()=%ul\n",fsea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != fsea.fixedLen()) {
    //    fprintf( stderr, "FreeEASpaceEA.fixedLen()=%ul\n",fsea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != fsea.attrID()) {
        fprintf( stderr, "FreeEASpaceEA.attrID()=%s\n",(CONST_CHAR_PTR)fsea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstMacVolumeInfoEA:

    // Instantiate one of these.
    MacVolumeInfoEA mviea;
    if ( mviea.error() )
        fprintf( stderr, "MacVolumeInfoEA error on construction : %s.\n",
                 mviea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    mviea.lastModifyDate  (  812051630 ); // In Daylight Savings
    mviea.lastBackupDate  (  724326181 ); // In normal time
    for (unsigned myindex = 0; myindex < 8; myindex++ ) {
        mviea.volumeFinderInfo()[myindex] = - myindex;  // Suitable filler
    }

    // Make sure minAttrLen() is multiple of 4.
    mal = mviea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "MacVolumeInfoEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    mviea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "MacVolumeInfoEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    mviea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "MacVolumeInfoEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Translate it toISO, (looping back automatically)
    mviea.toISO( bp + 0x12 );
    if ( mviea.error() )
        fprintf( stderr, "MacVolumeInfoEA error on toISO(), pad = %ul : %s.\n",
                 mviea.error().message(),mviea.attrLen() - mal);

    // Check to see if pads to multiple of 4 bytes.
    mviea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "MacVolumeInfoEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    mviea.toISO( bp + 0x12 );
    if ( mviea.error() )
        fprintf( stderr, "MacVolumeInfoEA error on toISO(), pad = %ul : %s.\n",
                 mviea.error().message(),mviea.attrLen() - mal);

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "MacVolumeInfoEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != mviea.attrType()) {
        fprintf( stderr, "MacVolumeInfoEA.attrType()=%ul\n",mviea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != mviea.attrSubtype()) {
        fprintf( stderr, "MacVolumeInfoEA.attrSubtype()=%ul\n",mviea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != mviea.attrLen()) {
        fprintf( stderr, "MacVolumeInfoEA.attrLen()=%ul\n",mviea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != mviea.fixedLen()) {
    //    fprintf( stderr, "MacVolumeInfoEA.fixedLen()=%ul\n",mviea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != mviea.attrID()) {
        fprintf( stderr, "MacVolumeInfoEA.attrID()=%s\n",(CONST_CHAR_PTR)mviea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstMacDirFinderInfoEA:

    // Instantiate one of these.
    MacDirFinderInfoEA mdfiea;
    if ( mdfiea.error() )
        fprintf( stderr, "MacDirFinderInfoEA error on construction : %s.\n",
                 mdfiea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    mdfiea.parentDirID ( 0x6789abcd ); // no meaning

    mdfiea.dirInfo().frRect.top    = 0x6666;
    mdfiea.dirInfo().frRect.left   = 0x7777;
    mdfiea.dirInfo().frRect.bottom = 0x8888;
    mdfiea.dirInfo().frRect.right  = 0x9999;
    
    mdfiea.dirInfo().frFlags       = 0xaaaa;

    mdfiea.dirInfo().frLocation.v  = 0xbbbb;
    mdfiea.dirInfo().frLocation.h  = 0xcccc;

    mdfiea.dirInfo().frView        = 0x1234;

    mdfiea.dirXInfo().frScroll.v   = 0x5678;
    mdfiea.dirXInfo().frScroll.h   = 0x9abc;

    mdfiea.dirXInfo().frOpenChain  = 0x3456789a;
    mdfiea.dirXInfo().frScript     = 0x87;
    mdfiea.dirXInfo().frXflags     = 0xa9;
    mdfiea.dirXInfo().frComment    = 0xedcb;
    mdfiea.dirXInfo().frPutAway    = 0xa9876543;

    // Make sure minAttrLen() is multiple of 4.
    mal = mdfiea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "MacDirFinderInfoEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    mdfiea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "MacDirFinderInfoEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    mdfiea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "MacDirFinderInfoEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Translate it toISO, (looping back automatically)
    mdfiea.toISO( bp + 0x12 );
    if ( mdfiea.error() )
        fprintf( stderr, "MacDirFinderInfoEA error on toISO(), pad = %ul : %s.\n",
                 mdfiea.error().message(),mdfiea.attrLen() - mal);

    // Check to see if pads to multiple of 4 bytes.
    mdfiea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "MacDirFinderInfoEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    mdfiea.toISO( bp + 0x12 );
    if ( mdfiea.error() )
        fprintf( stderr, "MacDirFinderInfoEA error on toISO(), pad = %ul : %s.\n",
                 mdfiea.error().message(),mdfiea.attrLen() - mal);

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "MacDirFinderInfoEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != mdfiea.attrType()) {
        fprintf( stderr, "MacDirFinderInfoEA.attrType()=%ul\n",mdfiea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != mdfiea.attrSubtype()) {
        fprintf( stderr, "MacDirFinderInfoEA.attrSubtype()=%ul\n",mdfiea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != mdfiea.attrLen()) {
        fprintf( stderr, "MacDirFinderInfoEA.attrLen()=%ul\n",mdfiea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != mdfiea.fixedLen()) {
    //    fprintf( stderr, "MacDirFinderInfoEA.fixedLen()=%ul\n",mdfiea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != mdfiea.attrID()) {
        fprintf( stderr, "MacDirFinderInfoEA.attrID()=%s\n",(CONST_CHAR_PTR)mdfiea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstMacFileFinderInfoEA:

    // Instantiate one of these.
    MacFileFinderInfoEA mffiea;
    if ( mffiea.error() )
        fprintf( stderr, "MacFileFinderInfoEA error on construction : %s.\n",
                 mffiea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    mffiea.parentDirID ( 0x6789abcd ); // no meaning

    mffiea.fileInfo().fdType        = 0xaaaabbbb;
    mffiea.fileInfo().fdCreator     = 0xccccdddd;
    mffiea.fileInfo().fdFlags       = 0x148c;

    mffiea.fileInfo().fdLocation.v  = 0x7856;
    mffiea.fileInfo().fdLocation.h  = 0x4321;

    mffiea.fileInfo().fdFldr        = 0x0123;

    mffiea.fileXInfo().fdIconID     = 0x5678;
    mffiea.fileXInfo().fdScript     = 0x87;
    mffiea.fileXInfo().fdXflags     = 0xa9;
    mffiea.fileXInfo().fdComment    = 0xedcb;
    mffiea.fileXInfo().fdPutAway    = 0xa9876543;

    mffiea.resForkDataLen  ( 0xaabbccdd );
    mffiea.resForkAllocLen ( 0xbbccddee );

    // Make sure minAttrLen() is multiple of 4.
    mal = mffiea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "MacFileFinderInfoEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    mffiea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "MacFileFinderInfoEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    mffiea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "MacFileFinderInfoEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Translate it toISO, (looping back automatically)
    mffiea.toISO( bp + 0x12 );
    if ( mffiea.error() )
        fprintf( stderr, "MacFileFinderInfoEA error on toISO(), pad = %ul : %s.\n",
                 mffiea.error().message(),mffiea.attrLen() - mal);

    // Check to see if pads to multiple of 4 bytes.
    mffiea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "MacFileFinderInfoEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    mffiea.toISO( bp + 0x12 );
    if ( mffiea.error() )
        fprintf( stderr, "MacFileFinderInfoEA error on toISO(), pad = %ul : %s.\n",
                 mffiea.error().message(),mffiea.attrLen() - mal);

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "MacFileFinderInfoEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != mffiea.attrType()) {
        fprintf( stderr, "MacFileFinderInfoEA.attrType()=%ul\n",mffiea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != mffiea.attrSubtype()) {
        fprintf( stderr, "MacFileFinderInfoEA.attrSubtype()=%ul\n",mffiea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != mffiea.attrLen()) {
        fprintf( stderr, "MacFileFinderInfoEA.attrLen()=%ul\n",mffiea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != mffiea.fixedLen()) {
    //    fprintf( stderr, "MacFileFinderInfoEA.fixedLen()=%ul\n",mffiea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != mffiea.attrID()) {
        fprintf( stderr, "MacFileFinderInfoEA.attrID()=%s\n",(CONST_CHAR_PTR)mffiea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstMacUniqueIDTableEA:

    // Instantiate one of these.
    MacUniqueIDTableEA muitea(589); // Arbitrary odd number
    if ( muitea.error() )
        fprintf( stderr, "MacUniqueIDTableEA error on construction : %s.\n",
                 muitea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    // In this case, filling it out means filling up all of the
    // SmallADs with some information, and checking it later.
    SmallAD smad;
    // Now Translate the lot of them toISO after putting some simple
    // content into each.
    for ( i = 0; i < muitea.numUIDMaps(); i++ )
    {
        smad.extLength  (i);
        smad.logBlockNo (i+1);
        smad.partRefNo  (i+100);
        smad.toISO(bp + 0x12 + muitea.offsetToUID(i));
    }
        
    // Make sure minAttrLen() is multiple of 4.
    mal = muitea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "MacUniqueIDTableEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    muitea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "MacUniqueIDTableEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    muitea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "MacUniqueIDTableEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Translate it toISO, (looping back automatically)
    muitea.toISO( bp + 0x12 );
    if ( muitea.error() )
        fprintf( stderr, "MacUniqueIDTableEA error on toISO(), pad = %ul : %s.\n",
                 muitea.error().message(),muitea.attrLen() - mal);

    // Check to see if pads to multiple of 4 bytes.
    muitea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "MacUniqueIDTableEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    muitea.toISO( bp + 0x12 );
    if ( muitea.error() )
        fprintf( stderr, "MacUniqueIDTableEA error on toISO(), pad = %ul : %s.\n",
                 muitea.error().message(),muitea.attrLen() - mal);

    // We need to do a separate fromISO on all SmallADs, after doing
    // one on the MacUniqueIDTableEA as well.
    // Construct one for reading.
    MacUniqueIDTableEA readMUIDT(1);
    if (error = readMUIDT.error())
        fprintf( stderr, "MacUniqueIDTableEA error on construction (for read) : %s.\n",
                 error.message());

    // fromISO() on it.
    readMUIDT.fromISO( bp + 0x12 );
    if (error = readMUIDT.error())
        fprintf( stderr, "MacUniqueIDTableEA error on fromISO : %s.\n",
                 error.message());

    if ( readMUIDT != muitea )
        fprintf( stderr, "MacUniqueIDTableEA fromISO != toISO.\n");
        
    for ( i = 0; i < readMUIDT.numUIDMaps(); i++ )
    {
        smad.fromISO(bp + 0x12 + readMUIDT.offsetToUID(i));
        if (smad.extLength()  != i)
            fprintf( stderr, "MacUniqueIDTableEA smad.extLength .fromISO != toISO.\n");
        if (smad.logBlockNo() != i+1)
            fprintf( stderr, "MacUniqueIDTableEA smad.logBlockNo.fromISO != toISO.\n");
        if (smad.partRefNo()  != i+100)
            fprintf( stderr, "MacUniqueIDTableEA smad.partRefNo .fromISO != toISO.\n");
    }
        
    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "MacUniqueIDTableEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != muitea.attrType()) {
        fprintf( stderr, "MacUniqueIDTableEA.attrType()=%ul\n",muitea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != muitea.attrSubtype()) {
        fprintf( stderr, "MacUniqueIDTableEA.attrSubtype()=%ul\n",muitea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != muitea.attrLen()) {
        fprintf( stderr, "MacUniqueIDTableEA.attrLen()=%ul\n",muitea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != muitea.fixedLen()) {
    //    fprintf( stderr, "MacUniqueIDTableEA.fixedLen()=%ul\n",muitea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != muitea.attrID()) {
        fprintf( stderr, "MacUniqueIDTableEA.attrID()=%s\n",(CONST_CHAR_PTR)muitea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstMacResourceForkEA:

    // Instantiate one of these.
    MacResourceForkEA mrfea(0x78);
    if ( mrfea.error() )
        fprintf( stderr, "MacResourceForkEA error on construction : %s.\n",
                 mrfea.error().message());

    // Clear out buffer
    clrBuf( bp );

    // Fill it out.
    // --- No fields to fill out. ---

    // Try changing its dataLen() and watching the attrLen shift!
    UINT32 smallEAL,largerEAL;

    // hold size before growing it.
    smallEAL = mrfea.attrLen();

    // Grow it by 1000
    mrfea.dataLen(mrfea.dataLen() + 1000);

    // hold size after growing it.    
    largerEAL = mrfea.attrLen();

    // Error if did not grow
    if (largerEAL <= smallEAL)
        fprintf( stderr, "MacResourceForkEA attrLen didn't grow: %ul <= %ul.\n",
                 largerEAL, smallEAL);

    // Shrink it
    mrfea.dataLen(mrfea.dataLen() - 1000);
    
    // Error if attr len did not stay the same.
    if (mrfea.attrLen() != largerEAL)
        fprintf( stderr, "MacResourceForkEA datalen shrink: before(%ul)!=after(%ul).\n",
                 largerEAL, mrfea.attrLen());

    // Make sure minAttrLen() is multiple of 4.
    mal = mrfea.minAttrLen();
    if ( mal % 4 != 0 ){
        fprintf( stderr, "MacResourceForkEA minAttrLen() is not multiple of 4 = %ul.\n",
                 mal);
    }

    // Try setting it to a bad length
    mrfea.attrLen(mal+1,error);
    if ( error != NSR::error_EA_Invalid_EA_length ) 
        fprintf( stderr, "MacResourceForkEA - No InvalidEALen error on attrLen(min+1=%ul). Err is : %s\n",
                 mal+1,error.message());

    // Set it to the minimum
    mrfea.attrLen(mal,error);
    if ( error )
        fprintf( stderr, "MacResourceForkEA error on attrLen(min=%ul) : %s.\n",
                 mal,error.message());

    // Now, put a byte at the beginning and end of the data space.
    *(bp + 0x12 + mrfea.offsetToData())                     = 0xaa;
    *(bp + 0x12 + mrfea.offsetToData() + mrfea.dataLen()-1) = 0xee;
    
    // Translate it toISO, (looping back automatically)
    mrfea.toISO( bp + 0x12 );
    if ( mrfea.error() )
        fprintf( stderr, "MacResourceForkEA error on toISO(), pad = %ul : %s.\n",
                 mrfea.error().message(),mrfea.attrLen() - mal);

    // Now, check bytes at beginning and end
    UINT8 bfirst = *(bp + 0x12 + mrfea.offsetToData());
    UINT8 blast  = *(bp + 0x12 + mrfea.offsetToData() + mrfea.dataLen()-1);
    
    if (bfirst  != 0xaa)
        fprintf( stderr, "MacResourceForkEA first byte (%x) corrupted on toISO().\n",
                 bfirst);
    if (blast   != 0xee)
        fprintf( stderr, "MacResourceForkEA last byte (%x) corrupted on toISO().\n",
                 blast);
    
    // Check to see if pads to multiple of 4 bytes.
    mrfea.attrLen(mal+100,error);
    if ( error )
        fprintf( stderr, "MacResourceForkEA error on attrLen(min+100=%ul) : %s.\n",
                 mal+100,error.message());

    // Translate it toISO, (looping back automatically)
    mrfea.toISO( bp + 0x12 );
    if ( mrfea.error() )
        fprintf( stderr, "MacResourceForkEA error on toISO(), pad = %ul : %s.\n",
                 mrfea.error().message(),mrfea.attrLen() - mal);

    // COULD do a fromISO as well, but is redundant...
    // xxx.fromISO(); if (err) ...

    // Now, use the EAInspector
    eaInsp.fromISO( bp + 0x12 );

    // Now, note any error.
    if (eaInsp.error() != error_None)
        fprintf( stderr,
                 "MacResourceForkEA EAInspector had error : %s.\n",
                 eaInsp.error().message());

    // And compare all EAInspector fields with the original.
    if (eaInsp.attrType() != mrfea.attrType()) {
        fprintf( stderr, "MacResourceForkEA.attrType()=%ul\n",mrfea.attrType());
        fprintf( stderr, "EAInspector.attrType()=%ul\n",eaInsp.attrType());
    }
    if (eaInsp.attrSubtype() != mrfea.attrSubtype()) {
        fprintf( stderr, "MacResourceForkEA.attrSubtype()=%ul\n",mrfea.attrSubtype());
        fprintf( stderr, "EAInspector.attrSubtype()=%ul\n",eaInsp.attrSubtype());
    }
    if (eaInsp.attrLen() != mrfea.attrLen()) {
        fprintf( stderr, "MacResourceForkEA.attrLen()=%ul\n",mrfea.attrLen());
        fprintf( stderr, "EAInspector.attrLen()=%ul\n",eaInsp.attrLen());
    }
    // Only for ISO-defined EAs
    //if (eaInsp.fixedLen() != mrfea.fixedLen()) {
    //    fprintf( stderr, "MacResourceForkEA.fixedLen()=%ul\n",mrfea.fixedLen());
    //    fprintf( stderr, "EAInspector.fixedLen()=%ul\n",eaInsp.fixedLen());
    //}
    if (eaInsp.attrID() != mrfea.attrID()) {
        fprintf( stderr, "MacResourceForkEA.attrID()=%s\n",(CONST_CHAR_PTR)mrfea.attrID());
        fprintf( stderr, "EAInspector.attrID()=%s\n",(CONST_CHAR_PTR)eaInsp.attrID());
    }
        
  TstICBTblEA:
    
    ICBTableEA wicbea(288);     // 288 icbTable entries.
    ICBTableEA ricbea(0);       // 0 partitions

    clrBuf( bp );

    ada = wicbea.icbTbl();
    for (index = 0; index < wicbea.numEnts(); index++ ) {
        ada[index].partRefNo(wprn + index);
        ada[index].logBlockNo(wlbn + index);
        ada[index].extLength(wel + index);
        ada[index].extType(wet);
        ada[index].markErased();
    }

    wicbea.toISO( bp + 0x12 );
    if ( wicbea.error() != error_None )
        fprintf( stderr, "ICBTblEA error on toISO() : %s.\n",
                 wicbea.error().message());
        
    ricbea.clear();                // Clear out the error
    ricbea.fromISO( bp + 0x12 );
    if ( ricbea.error() != error_None )
        fprintf( stderr, "ICBTblEA error on fromISO() : %s.\n",
                 ricbea.error().message());
        
#ifdef NSR_VERIFY
    if ( ricbea != wicbea )
        fprintf( stderr, "ICBTblEAs do not match.\n");
#endif    

    SearchEA sea;

    // Test isValid() method.

    // First, read from bad location. Should NOT be valid!
    sea.fromISO( bp + 0x11 );
    if (sea.error( bp + 0x0 ) == error_None)
        fprintf( stderr,
                 "ICBTblEA SearchEA at wrong location is VALID.\n");

    // Now, get it from the proper location.
    sea.fromISO( bp + 0x12 );

    // Removed test for checksum error, since it no longer has a
    // checksum (as of 4/26/96) -DVM
    
    // Now, check for proper operation.
    if (sea.error( bp + 0x12 ) != error_None)
        fprintf( stderr,
                 "ICBTblEA SearchEA was not valid. Err : %s.\n",
                 sea.error( bp + 0x12 ).message());
    if (sea.eaType() != NSR::sea_HPICBTable)
        fprintf( stderr, "ICBTblEA not recognized: ID = '%s'.\n",
                 (CONST_CHAR_PTR)sea.id());
        
  TstEmbEAs: // Next, test out all the embedded EA stuff.

    const UINT16 BlockLen = 1024;
    UINT16 avail = wfe.unusedBytes(BlockLen);
    Error eaerr;

    if ( (eaerr = wfe.setEALen(BlockLen,avail + 1)) != NSR::error_FileEntry_full )
        fprintf(stderr,
                "FE::setEALen(unusedBytes()+1) returned %s",eaerr.message());
    if ( (eaerr = wfe.setEALen(BlockLen,avail - 1)) != NSR::error_EA_Invalid_EA_length )
        fprintf(stderr,
                "FE::setEALen(unusedBytes()-1) returned %s",eaerr.message());
    if ( (eaerr = wfe.setEALen(BlockLen,avail - 2)) != NSR::error_EA_Invalid_EA_length )
        fprintf(stderr,
                "FE::setEALen(unusedBytes()-2) returned %s",eaerr.message());
    if ( (eaerr = wfe.setEALen(BlockLen,avail - 3)) != NSR::error_EA_Invalid_EA_length )
        fprintf(stderr,
                "FE::setEALen(unusedBytes()-3) returned %s",eaerr.message());
    if ( (eaerr = wfe.setEALen(BlockLen,avail)) != error_None )
        fprintf(stderr,
                "FE::setEALen(unusedBytes()) returned %s",eaerr.message());
    // Fill up an ICBEA

    ICBTableEA short_icbea(28);     // 28 icbTable entries.

    ada = short_icbea.icbTbl();
    for (index = 0; index < short_icbea.numEnts(); index++ ) {
        ada[index].partRefNo(wprn + index);
        ada[index].logBlockNo(wlbn + index);
        ada[index].extLength(wel + index);
        ada[index].extType(wet);
        ada[index].markErased();
    }

    // Determine length needed
    UINT16 ealen = eahd.descLen() + short_icbea.attrLen();

    // Reserve just right amount of space for EAs in FE
    if ( (eaerr = wfe.setEALen(BlockLen,ealen)) != error_None )
        fprintf(stderr,
                "FE::setEALen(%d) returned %s",ealen,eaerr.message());

    // Fill in EAHD
    eahd.implAttrLocation(eahd.descLen()); // right after the header
    eahd.applAttrLocation(ealen); // at end... NO appl EAs.

    // Translate EAHD + EA(s) into space in FE.

    BYTE *eamem = (BYTE *)wfe.embeddedEAp();
    eahd.toISO(eamem,0x1234);
    if ( eahd.error() )
        fprintf( stderr, "%s\n",eahd.error().message());
    
    short_icbea.toISO( eamem + eahd.implAttrLocation() );
    if ( short_icbea.error() != error_None )
        fprintf( stderr, "embedded ICBTblEA error on toISO() : %s.\n",
                 short_icbea.error().message());
        
    // FE.toISO
    wfe.toISO( bp, 0x1234 );
    if ( wfe.error() != error_None )
        fprintf( stderr,
                 "File Entry (w/ embedded EAs) error on toISO() : %s.\n",
                 wfe.error().message());

    // FE.fromISO
    rfe.clear();
    rfe.fromISO( bp, 0x1234 );
    if ( rfe.error() != error_None )
        fprintf( stderr,
                 "File Entry (w/ embedded EAs) error on fromISO() : %s.\n",
                 rfe.error().message());

    ExtendedAttrHeaderDesc    reahd;

    reahd.clear();
    reahd.fromISO( (BYTE *)rfe.embeddedEAp(), 0x1234 );
    if ( reahd.error() != error_None )
        fprintf( stderr,
                 "Embedded EAHD error on fromISO() : %s.\n",
                 reahd.error().message());

    if (reahd.applAttrLocation() != rfe.getEALen())
        fprintf( stderr,
                 "Embedded applAttrLocation != end of EA space.\n");

    BYTE * eabuf = (BYTE *)rfe.embeddedEAp() + reahd.implAttrLocation();

    sea.fromISO( eabuf );
    if (sea.error( eabuf ) != error_None)
        fprintf( stderr,
                 "Embedded ICBTblEA SearchEA was not valid. Err : %s.\n",
                 sea.error( eabuf ).message());
    if (sea.eaType() != NSR::sea_HPICBTable)
        fprintf( stderr, "Embedded ICBTblEA not recognized: ID = '%s'.\n",
                 (CONST_CHAR_PTR)sea.id());

    // Now, do full fromISO and compare

    ricbea.clear();                // Clear out the error
    ricbea.fromISO( eabuf );
    if ( ricbea.error() != error_None )
        fprintf( stderr, "Embedded ICBTblEA error on fromISO() : %s.\n",
                 ricbea.error().message());
    
#ifdef NSR_VERIFY
    if ( ricbea != short_icbea )
        fprintf( stderr, "Embedded ICBTblEAs do not match.\n");
#endif    
        
#ifdef REST
#endif

    delete [] bp;

}
